OpenCADIrrigation Abrir o app

Desenvolvimento

Requisitos: Flutter 3.47.9 (Dart 3.13.7), fixado no pubspec.yaml: o flutter pub get recusa outra versão, e o bundle do worker, a saída do formatador e o build do CanvasKit dependem dela. Sem dependências nativas.

git clone https://github.com/videjunior/opencadirrigation.git
cd opencadirrigation
flutter pub get
flutter run -d chrome              # desenvolvimento no navegador
flutter test                       # cerca de 3.000 testes: motor, modelo, formatos, interface
flutter analyze                    # lints
tool/build_worker.sh               # recompila web/design_worker.js após mudar lib/core (o app cai
                                   # para a thread da interface quando o arquivo não existe)
tool/build_web.sh                  # build de publicação: worker + flutter build web com o commit git e a data
                                   # gravados na versão (boas-vindas, barra de status, Ajuda → Sobre, console),
                                   # CanvasKit servido pelo site e o service worker da abertura sem rede
                                   # preenchido (tool/gen_sw.dart); OCI_WEB_OUT=<pasta> grava o build em outro lugar
flutter build web --release        # build simples (sem commit/data, CanvasKit da CDN do Google, sem abertura sem
                                   # rede: o sw.js dele remove a si mesmo; build/web, web/CNAME guarda o domínio)
dart run bin/oci.dart --help       # linha de comando: import, new, set, pack add, design, analyze, check, validate,
                                   # export, bom e schema de projetos .oci.json (docs/API.pt-BR.md)
dart tool/engine_package.dart build/engine   # o motor como pacote sem Flutter (só precisa do SDK do Dart)
dart run tool/gen_version.dart     # regenera lib/app/version.dart após mudar `version:` no pubspec.yaml
dart run tool/gen_site.dart        # páginas do site (index em inglês, /pt/, /es/, /de/, … sitemap, 404, robots, llms.txt)
dart run tool/indexnow.dart        # depois de publicar: pede aos buscadores do IndexNow (Bing…) novo rastreio
dart run tool/gen_catalogs.dart    # valida e normaliza catalogs/*.oci.cat e refaz index.json
dart run tool/gen_examples.dart    # regenera examples/<lang>/*.oci.json a partir de lib/app/examples.dart
dart run tool/gen_brand.dart       # ícones e ativos de marca a partir de web/brand
python3 tool/formats/make_fixtures.py   # regrava test/fixtures/formats com ezdxf, pyshp, tifffile, Pillow, openpyxl e LibreDWG
python3 tool/formats/check_exports.py   # valida build/formats (escrito por flutter test) com leitores independentes
python3 tool/fonts/build_fonts.py       # refaz os subconjuntos Noto de assets/fonts a partir dos textos da interface
python3 tool/fonts/gen_unicode_data.py  # regenera lib/core/io/fonts/unicode_data.dart a partir do Unicode Character Database
python3 tool/fonts/make_shaping_fixtures.py  # regrava test/fixtures/shaping com o HarfBuzz (uharfbuzz)
UPDATE_AI_TOOLS_DOC=1 flutter test test/widget_ai_coverage_test.dart  # regenera docs/AI_TOOLS.md a partir do mapa de cobertura
flutter test --platform chrome test/web          # o código *_web.dart num Chrome de verdade
flutter test --update-goldens test/goldens       # regrava as imagens golden
dart run tool/release.dart status                # o checklist de lançamento (prepare, build, publish, live, verify-build)
dart run tool/i18n_review.dart export <código>   # um idioma em planilha para falantes nativos (e import)
git config core.hooksPath tool/hooks             # o hook de pre-commit: formatação, nomes proibidos, worker velho
npm ci --prefix tool/e2e                         # uma vez: o teste de fumaça de ponta a ponta e o seu playwright-core
npm exec --prefix tool/e2e -- playwright-core install webkit firefox   # uma vez: os builds fixados de WebKit e Firefox
node tool/e2e/smoke.mjs build/web --browser chromium,webkit,firefox     # o teste de fumaça de um build de produção

A linha de comando roda o motor do app na VM do Dart, sem Flutter nem navegador: design dimensiona e analisa um projeto (e grava o projeto dimensionado, os resultados e todas as tabelas dos relatórios), analyze mantém os diâmetros como desenhados, check lista os problemas e termina com código 1 quando há um erro, validate diz o que a leitura do arquivo teve de reparar, export grava qualquer formato de desenho, bom mostra a lista de materiais e schema o JSON Schema do arquivo de projeto, em qualquer um dos 20 idiomas (--lang); import, new, set e pack add fazem e alteram projetos, e os comandos que leem projetos aceitam vários arquivos ou pastas de uma vez, com --out-dir (docs/API.pt-BR.md).

As saídas commitadas da maioria dos geradores têm testes de guarda (as páginas do site, o modelo do service worker, os exemplos, os catálogos, a versão e a tabela de ferramentas da IA): quando uma diverge da fonte, o teste correspondente falha com a instrução de qual comando rodar. Recompile o worker de cálculo (tool/build_worker.sh) depois de mudar lib/core ou a tabela de textos, e os subconjuntos de fontes do PDF (tool/fonts/build_fonts.py) depois de acrescentar caracteres, onde nenhuma guarda avisa. Builds para desktop (flutter run -d macos|windows|linux) usam o isolate para o cálculo. As pastas android/ e ios/ são os modelos de projeto que o Flutter gerou; builds nativos para celular nunca foram compilados nem testados, e celulares e tablets usam o app web (instalável como PWA).

Como estender

  • Nova entidade: classe em entities.dart (JSON, clone, transformar, grips, distância, bounds), EntityType, camada padrão, pintura em painter.dart, propriedades em properties_panel.dart, ferramenta em tools.dart e alias em shortcuts.dart, exportação em plot.dart/cad_export.dart.
  • Novo relatório: tabela em report_tables.dart (os exportadores CSV/TXT/XLSX/PDF e o painel a recebem automaticamente) e textos em i18n.dart.
  • Novo formato: leitor ou escritor em lib/core/io, entrada em importFile do controller ou em DrawingFormat/ReportFormat, e um teste de ida e volta.
  • Nova fórmula: em lib/core/hydraulics, com um teste contra um valor de referência.
  • Nova ferramenta da IA: uma ferramenta em lib/app/ai/agent_tools*.dart (enviada em todo pedido) ou uma operação em lib/app/ai/ops_*.dart (encontrada por find_operations), sobre o controller, com o seu esquema de entrada e o seu efeito (leitura, alteração, exportação ou consulta a outro serviço), e a sua rota em lib/app/ai/ai_coverage.dart. test/widget_ai_tools_test.dart confere nomes e esquemas, test/widget_ai_coverage_test.dart falha quando um comando, ferramenta, item de menu ou diálogo não tem rota, e test/widget_ai_manual_test.dart quando o manual não traz uma chave de item, um parâmetro de projeto ou um código de mensagem.
  • Cores da interface: tire-as de Cad.* (lib/app/theme.dart), acrescentando uma cor às duas paletas quando nenhuma servir; test/widget_theme_test.dart confere o contraste das cores de texto claras (4,5:1 sobre cada superfície clara).

Testes

flutter test roda cerca de 3.000 testes em alguns minutos (o número cresce a cada versão). O que cada grupo garante:

Arquivo Cobertura
core/hydraulics_test.dart Hazen-Williams contra valor de livro-texto; Darcy-Weisbach ≈ Hazen-Williams em PVC liso; fator laminar; Swamee-Jain ≈ Colebrook; continuidade na transição; tabela do fator F de Christiansen e ajuste de Scaloppi; diâmetro equivalente; lei do emissor e ajuste; taxa de aplicação; CU de sobreposição; CU/DU e a EU de Keller-Karmeli (o exemplo resolvido do estudo técnico); ajuste de curva de bomba, ponto de operação, CRF; K → forma de vazão; celeridade em PVC; números sem notação científica
core/network_test.dart Solver esparso; tubo simples; anéis; conservação de massa; emissores dependentes da pressão; bomba; PRV; curva de acessório; convergência em Darcy-Weisbach; rede ramificada grande rápida; comparação com Christiansen; laterais em declive; comprimento máximo; posições de alimentação; emissores acima da carga disponível ficam fechados (sem refluxo)
core/network_robustness_test.dart Bomba perto do shutoff alimentando cem emissores perto de pressão zero (contra uma bisseção independente); bomba que um passo ruim travava fechada; emissores autocompensantes num morro, secos acima da linha piezométrica e famintos abaixo dela; válvula redutora logo acima do ajuste continua aberta; retenção instalada como acessório impede fluxo reverso; 300 redes em árvore aleatórias (bombas, retenções, demandas, todo expoente de emissor) convergem para soluções que satisfazem continuidade e leis de perda de carga; uma linha parada atrás de uma bomba desligada
core/valves_formulas_test.dart, core/pressure_class_test.dart, core/minor_fittings_test.dart, core/mains_frequency_test.dart Leis de Scobey e Manning no solver; a válvula sustentadora mantém o ajuste a montante e a controladora a sua vazão, limitadores de vazão de hidrantes num projeto; bomba com inversor mantém a pressão de saída turno a turno, com curvas de NPSH e de rendimento; redução da classe do PVC e do PE com a temperatura e a classe como restrição do dimensionamento (uma fonte de 95 m nunca recebe PVC PN 80, água quente reprova um tubo que passa a 20 °C); as perdas das conexões desenhadas; bomba de 60 Hz numa rede de 50 Hz e a seleção de bombas na rotação da rede
core/invariance_test.dart Mover o projeto (inclusive para coordenadas UTM), desenhar os tubos no sentido contrário, salvar e reabrir ou trocar o idioma deixam o projeto igual; o terreno por inverso da distância conta cada cota uma vez
core/regressions_1017_test.dart Defeitos corrigidos na varredura de 2026-10-17: curvas de bomba e de acessório digitadas com vazões repetidas, bomba só com carga de shutoff, posições de alimentação de laterais que pedem mais de três vezes a pressão nominal
core/lp_test.dart Simplex: ≤/≥, igualdades, inviável, ilimitado, problema com a forma do dimensionamento
core/design_test.dart, core/sizing_features_test.dart, core/gaps_test.dart Gerador de blocos; grafo conectado; análise e dimensionamento completos; LP não pior que o guloso; telescopagem; conexões; lavagem; golpe de aríete; CU de sobreposição e emissores por planta; agronomia e programa do controlador; seleção de bomba e motor; DEM GeoTIFF; pivô (vãos, custos); linha principal em anel
core/transient_test.dart, core/transient_analysis_test.dart, core/air_valves_test.dart, core/eps_test.dart Método das características: o regime permanente não se move sem um evento, sobrepressão de Joukowsky e o período 4L/a, sobrepressão de Michaud numa parada lenta, amortecimento pelo atrito, separação de coluna, ventosa combinada, desligamento de bomba com retenção, inércia e reservatório hidropneumático, tubos fundidos e agrupados; a linha principal de cada exemplo roda todos os cenários com o regime permanente dentro das envoltórias; posicionamento de ventosas pela prática do AWWA M51 e dimensionamento dos orifícios; período estendido com reservatórios, horários, padrões e controles, e a energia, contra curvas analíticas e cálculos à mão
core/terrain_pivot_test.dart, core/breakline_test.dart, core/slope_map_test.dart TIN de Delaunay exato em planos; TIN vs IDW; geração de curvas; encadeamento de segmentos; geometria de alinhamento e recorte; blocos guiados; hidráulica de pivô (inclusive setorial); verificação de projeto; catálogo Excel e pacotes; linhas de quebra forçadas na triangulação; mapas de declividade e exposição
core/advisor_test.dart Itens soltos ligados (a válvula volta ao início da zona), configurações impossíveis restauradas, pressão do emissor fora da faixa do bocal, zonas fora dos turnos, bomba de superfície em poço fundo → submersa, booster para rede pública sem pressão, turnos divididos pela vazão da fonte, corrigir automaticamente num projeto com vários erros, otimização que nunca aumenta o custo anual
widget_advice_test.dart A aba Mensagens explica e corrige com um clique (um passo de desfazer), cálculo com erros abre Mensagens, corrigir automaticamente num passo do histórico, otimização e itens de menu, fonte ausente com correção de um clique
core/auto_layout_test.dart, core/zoning_test.dart, core/routing_test.dart, core/templates_test.dart, core/field_subdivision_test.dart, core/tree_rings_test.dart, core/pivot_fit_test.dart, core/auto_design_test.dart, core/vegetation_test.dart Layouts de retângulos, formas em L, canteiros curvos e gramados em volta de uma casa com o seu CU, setores com bocais equivalentes; zonas dentro da vazão que nunca misturam classes de precipitação; árvores de tubos de zona e da linha principal contornando edificações; modelos de campo, pista, green, tee e fairway; blocos de mesma área com carreadores; anéis ligados às suas laterais; o maior círculo e o melhor setor de um talhão; gramados, talhões e pomares distribuídos, zoneados e com traçado que projetam sem erros; a vegetação de uma cena aérea sintética (gramados, copas, sombra, piscina, piso) com erro de poucos por cento; cada um bem abaixo de um segundo com milhares de aspersores
core/climate_test.dart, core/climate_online_test.dart, core/crops_test.dart, core/soils_test.dart, core/effective_rain_test.dart, core/irrigation_requirement_test.dart, core/solar_pumping_test.dart, core/wetted_bulb_test.dart, core/water_budget_test.dart Exemplos resolvidos da FAO-56 (pressão, pressão de vapor, radiação, ETo em Bangkok, Uccle e Lyon), curvas de Kc, Anexo 7 e cobertura esparsa; lixiviação da FAO-29 e os citros gotejados do Módulo 9 da FAO; chuva efetiva do NEH 623 e as fórmulas da FAO; a tabela de solos contra o NEH 652, Rawls et al., a Tabela 19 da FAO-56 e a tabela SWAT/EPA; geometria solar contra Duffie & Beckman e o Exemplo 8 da FAO-56; Schwartzman & Zur; orçamentos MWELO e ciclo e infiltração; pedidos, leitura, ritmo, novas tentativas e normais do Open-Meteo e da NASA POWER
core/mechanised_test.dart, core/pivot_package_test.dart, core/corner_arm_test.dart, core/vri_test.dart, core/pivot_electrical_test.dart, core/traveller_test.dart, core/surface_irrigation_test.dart, core/gated_pipe_test.dart Cálculo exemplo 11-18 do NEH 623 (capacidade do sistema, vazão por saída, canhão final, atrito, volta e booster), pacotes regulados com bocais numerados ou do catálogo, temporizador pela transmissão; braço de canto contra casos analíticos; taxa variável por setores e zonas; motores das torres e queda no cabo pela IEC 60364-5-52, tamanho do gerador; cálculo exemplo 11-17 do autopropelido; os exemplos de sulco, faixa e bacia da FAO 45; saídas do tubo janelado
core/network_ops_test.dart, core/on_demand_test.dart, core/tariff_test.dart, core/energy_grouping_test.dart, core/criticality_test.dart, core/calibration_test.dart, core/fertigation_test.dart Vazões de Clément contra o Box 1 da FAO 59 e a verificação por configurações aleatórias (quantis AS 241, sequência de referência do MRG32k3a); a regra brasileira do desconto e o agendador exato contra força bruta; agrupamento por energia 30 % abaixo do primeiro encaixe por vazão; N−1 em árvores e anéis; seção áurea e Levenberg–Marquardt recuperando o C; tempos de chegada, plano e venturi da fertirrigação; tudo sobre um projeto calculado
core/valve_in_head_test.dart, core/two_wire_test.dart, core/wire_routing_test.dart, core/round_1025_test.dart, widget_valve_in_head_test.dart Estações de aspersores com válvula programadas pelos turnos (pressões, 24 horas, fiação, dois fios, EPANET, altura estática da bomba, programa do controlador, transientes, fertirrigação) e os resultados de projetos que nunca as programaram; tensão no par de dois fios à mão, decodificadores e aterramento; rotas pelas valas (menores caminhos, árvore do tipo Steiner), válvulas mestras e relés de bomba; válvula mestra e acessórios na lista de materiais, armazenamento comprimido no navegador, um dispositivo em cada lateral selecionada, links de compartilhamento, comentários e nuvens de revisão, curvas de bocal ajustadas por tabelas coladas
core/dwg_test.dart, core/dwg_writer_test.dart, core/cad_export_test.dart Leitura de amostras R2000–R2018 e R2007, com blocos e cotas expandidos; rejeição de versões desconhecidas; CRC; ida e volta do escritor; validação com LibreDWG quando instalado; DXF e DWG R2000 com entidades nativas, blocos das cotas, camadas com cores verdadeiras e tipos de linha, definições de atributo e blocos do usuário, para cada exemplo da galeria, relidos iguais
core/formats_test.dart, core/formats_app_test.dart Cada formato de importação contra arquivos gravados por outros programas (ezdxf, LibreDWG, pyshp, tifffile, Pillow, openpyxl e KML no estilo do Google Earth; fixtures em test/fixtures/formats, gerados por tool/formats/make_fixtures.py) com posições, elevações, nomes e camadas conferidos; todas as exportações relidas pelos próprios leitores e gravadas em build/formats para tool/formats/check_exports.py, que as valida com ezdxf, LibreDWG, lxml, openpyxl e pypdf; os formatos novos pelo app (GeoJSON, GPX, LAS, DGN, EPANET, zips de shapefiles)
core/epanet_inp_test.dart, core/shp_writer_test.dart, core/gpx_test.dart, core/landxml_test.dart, core/ifc_test.dart, core/geojson_reader_test.dart, core/las_test.dart, core/dgn_test.dart, core/datum_test.dart Arquivos EPANET de projetos calculados batendo com a nossa análise zona a zona e turno a turno, e o leitor; shapefiles, GPX, LandXML e IFC pelas suas especificações e relidos; GeoJSON com todas as geometrias e o crs; formatos 0–10 do LAS, rarefação e recusas; DGN V7 2D e 3D; Mercator transversa, as translações de datum do IBGE e o reconhecimento de sistemas
core/pdf_reader_test.dart, core/pdf_import_test.dart, core/pdf_fonts_test.dart, core/pdf_images_test.dart, core/text_shaping_test.dart, core/sheets_test.dart, widget_sheets_test.dart O leitor de PDF nos nossos arquivos e em estruturas de arquivo, filtros, cores, textos, imagens e camadas de outros programas, plantas importadas em escala; leitura e subconjunto de TrueType, ordem bidirecional, fontes embutidas em todas as escritas da interface; formatação idêntica à do HarfBuzz nos textos da interface (fixtures por tool/fonts/make_shaping_fixtures.py); imagens no PDF e no SVG; conjuntos de folhas, detalhes, gráficos e a tabela de revisões; PNG de uma prancha
core/export_test.dart, core/kml_test.dart UTM ida e volta; georreferência; KML ida e volta; GeoJSON; cena de plotagem; SVG; PDF válido e comprimido; prancha e páginas de relatório; mesmas tabelas em CSV/TXT/XLSX
core/catalog_packs_test.dart Todos os pacotes em catalogs/ carregam, ids únicos sem colidir com o catálogo padrão, arquivos normalizados e índice coerente; formato do pacote; carregadores (assets e URL)
core/examples_test.dart Cada exemplo, nos 20 idiomas, constrói, é conectado, passa na verificação, projeta com zonas dentro da janela e sem déficit, imprime cada célula de relatório como número simples e bate com os arquivos em examples/
core/spatial_index_test.dart Índice contra força bruta, ordem de desenho, casos degenerados, invalidação no controller, seleção e snap, entidades por id e contagem por camada
core/painter_test.dart, core/scene_cache_test.dart Sobreposições de resultados (os mesmos pontos dos emissores em toda sobreposição, recoloridos pela pressão), entidades de desenho, textos sobre as linhas, a cor do item sob o cursor, hairlines numa vista lotada de linhas em tela 2×; uma gravação por cena, cena pesada deslocada com a vista e redesenhada nítida quando ela para
core/geo_parse_test.dart, core/i18n_lang_test.dart Coordenadas coladas (decimais, vírgula, hemisférios, DMS, links); intervalo de curvas; escolha de idioma pelo sistema e pela URL
core/i18n_packs_test.dart Cada pacote de idioma cobre todas as chaves da tabela, do tutorial e dos nomes do catálogo com os mesmos marcadores e não é majoritariamente inglês; pacotes instalados chegam aos textos, ao tutorial e ao catálogo; setLanguage carrega o pacote sob demanda com inglês enquanto isso e repete um carregamento que falhou
core/editing_test.dart, core/model_test.dart, core/workspace_test.dart, core/design_job_test.dart, core/app_io_test.dart, core/entities_roundtrip_test.dart Edição (grips, transformações, aparar, estender, cortar), JSON das entidades, abas e área de transferência, protocolo do worker, HTTP local, armazenamento de projetos, câmera e snap (a área de transferência leva os itens de catálogo dos pivôs e a fiação)
core/blocks_test.dart, core/label_rules_test.dart, core/snapping_extra_test.dart, core/gps_test.dart, core/auto_analysis_test.dart, core/selection_bom_test.dart, core/proposal_test.dart, core/finame_test.dart, core/licensing_test.dart, core/works_schedule_test.dart, core/limits_test.dart Blocos do usuário no arquivo e no histórico; rótulos condicionais; snaps de interseção, perpendicular, tangente, quadrante e extensão e o rastreamento polar, também em curvas de nível longas que se cruzam junto ao cursor; trajetos, marcas e locação pelo GPS; análise automática depois das edições; materiais da seleção; o orçamento (da margem ao frete, valas, retorno, VPL e TIR, setores, alternativas); códigos FINAME; categorias do CONAMA; cronograma de obra; os limites que o app informa ao usuário (BigTIFF, o teto de pixels, a rarefação do TIN, um PDF solto sem o diálogo)
core/cli_test.dart, core/api_examples_test.dart test/core/cli_test.dart executa a linha de comando num exemplo distribuído; test/core/api_examples_test.dart executa cada trecho de docs/API.md e falha quando os documentos mostram código que ele não executa
core/ai_agent_test.dart, core/ai_openai_test.dart, core/ai_formats_test.dart, core/ai_context_test.dart Os pedidos seguem cada API: Anthropic (endpoint, cabeçalhos, streaming, raciocínio adaptativo, sempre ligado no Fable 5.1, esforço, cache, fallback de recusa, orçamento da tarefa, compactação, limpeza de resultados antigos de ferramentas; sem o cabeçalho de navegador no desktop) e OpenAI (API Responses, chave bearer, instruções, ferramentas de função, esforço de raciocínio, sem armazenamento, compactação, imagens mais antigas retiradas); rodadas de ferramentas, entradas inválidas como resultados de erro, os quatro modos e a aprovação do plano, exportações confirmadas, o limite de etapas e o teto de gasto, mensagens escritas enquanto ele trabalha, Parar, novas tentativas e erros que nunca mostram uma chave, a recusa do Fable 5.1 por retenção de dados, recusas e fallbacks cobrados pelo modelo que respondeu, preços de tabela com as regras de pedidos longos; os dois formatos se convertem um no outro sem perda; o contexto do projeto é determinístico, limitado e nunca contém uma chave
widget_ai_agent_test.dart, widget_ai_assistant_test.dart, widget_ai_tools_test.dart, widget_ai_vision_test.dart GPT com a chave da OpenAI, conversa nova quando a empresa muda e nenhuma chave chegando à outra empresa, um modelo Claude assumindo a conversa de outro; um projeto pequeno inteiro feito pelo agente (perguntas, plano, desenho, cálculo, verificação, correções, memorial, lista de tarefas); mensagens escritas enquanto ele trabalha, voltar a um ponto, o teto de gasto e Continuar, comandos rápidos, avisos de compactação, imagens, a conversa em Markdown, o painel encaixado, o seu botão e a folha do celular; chaves na memória a menos que sejam lembradas, nada enviado antes de Enviar, fichas técnicas conferidas antes de entrar no catálogo; a correspondência entre pixel e mundo, a imagem de satélite tirada fora da tela sem mudar a vista nem o mapa do usuário, imagens do Google com chave, geometria proposta, imagens e perfis do terreno contra valores exatos
widget_ai_coverage_test.dart, widget_ai_manual_test.dart, widget_ai_ops_cad_test.dart, widget_ai_ops_eng_test.dart Toda ação, ferramenta, alias, item de menu e diálogo tem rota para a IA e toda rota existe, e docs/AI_TOOLS.md é a tabela do mapa; cada tópico do manual é lido num projeto vazio e num calculado, cada chave de item, parâmetro de projeto e código de mensagem tem a sua explicação, e o exemplo resolvido é refeito; as operações do lado do desenho e da engenharia (edição, anotação, blocos, vista e histórico, arquivos, terreno e local, importações; calculadoras, análises da rede, catálogo e pacotes, exportações, projeto automático), cada uma com as suas aprovações e passos de desfazer. Imitações programadas das duas APIs (test/support/fake_claude.dart, test/support/fake_openai.dart) fazem o papel das empresas: nenhum teste acessa a rede
densogram_test.dart, electrical_test.dart, electrical_io_test.dart, management_test.dart (em core/) Todo perfil de aspersão devolve a vazão inteira, setores, áreas contra a própria média, perfis medidos e vento; rotas, estações, tensão no solenoide à mão, fios mais baratos contra força bruta, catálogo de fios, lista de materiais e relatório Elétrico, códigos da verificação, saída DXF/DWG/GeoJSON e prancha; demandas e turnos automáticos com pivôs e estações
core/import_curves_test.dart NURBS racional e fixada; SPLINE do DXF por pontos de controle ou de ajuste, HATCH com bordas de polilinha, linha, arco (nos dois sentidos), elipse e spline e ilhas, SOLID/TRACE, hachuras dentro de blocos; splines, hachuras, sólidos e a elipse do DWG R2000–R2018 iguais aos lidos pelo LibreDWG
core/controller_extra_test.dart Abrir arquivo ou exemplo descarta marcas, perfil, verificação e histórico antigos; edições de diálogo como um passo de desfazer (mutações incorporadas, unidades mantêm os resultados); desfazer sem nada a desfazer; grips arrastam fios com os nós de tubo; pintura das novas entidades e do densograma
core/regressions_test.dart Cada defeito corrigido na varredura de 2026-09-22, cada um falhando sem a sua correção: lateral cortada sobre um emissor o mantém uma vez só; curvas geradas continuam geradas; arquivos sem o contador de ids; aspersores de setor espelhados e cabeças de 360° com bocal de setor (também no PDF e na tela); arquivos de levantamento com espaço e vírgula decimal; imagens grandes demais para decodificar; arquivos danificados informados como tal; psi, kPa e bar; CU da grade com aspersores próximos; blocos em talhões em L e em U e fileiras guiadas recortadas em dois; telescopagem desenhada nos dois sentidos; números com separador de milhar, preços e curvas de bomba; espaçamentos 0 e valores NaN que travavam ou impediam salvar; trilhas de GPS no KML
core/hotkeys_dispatch_test.dart O despachante de teclado isolado: teclas do aplicativo, de edição e do canvas, coordenadas digitadas, o que diálogos e menus bloqueiam, cada alias de comando digitado
core/engine_speed_test.dart O motor mais rápido dá exatamente os mesmos resultados: o plano de eliminação do solver de rede bit a bit contra o solver por mapas, e as buscas indexadas de trechos e itens de catálogo acompanhando cada edição das suas listas
core/hydraulics_extra_test.dart, core/pump_devices_test.dart Utilitários de atrito (gradientes, número de Reynolds, Blasius contra Colebrook, C de Hazen como rugosidade), perdas localizadas, dispositivos e indicadores dos emissores; cada dispositivo da linha principal do catálogo em série entre um reservatório e uma zona: cada um divide o tubo e informa a sua própria perda, uma redutora só regula acima da regulagem, a bomba segue a curva e as leis de afinidade, uma fonte calculada nunca fica abaixo de zero, altura de sucção
core/design_extra_test.dart, core/area_water_test.dart, core/auto_fix_test.dart Caminhos do projeto que os outros testes não alcançam (zonas vazias e ausentes, o limite de variação da zona, dispositivos dentro da zona, válvulas inalcançáveis, conexões faltando, turnos em horas fixas, pivôs com Darcy-Weisbach); os defeitos achados na conferência da galeria de exemplos (aspersores no contorno da área, uniformidade com precipitação equilibrada, convergência da lavagem, dias escalonados do programa, pivôs na tabela hídrica); cada correção do assistente de projeto no seu caso e num caso em que não tem nada a fazer
core/model_extra_test.dart, core/io_extra_test.dart, core/currency_test.dart Casos-limite de geometria, unidades, terreno e TIN, dividir, estender e deslocar em cada tipo de entidade; importadores e exportadores nas entradas que os testes de formatos não alcançam (listas de catálogo, exceções de fuso UTM, transformações de GeoTIFF, variantes de KMZ, codificações de DBF, blocos e curvas de DXF, páginas de relatório em PDF); moedas por idioma e região, câmbios de referência e a conversão de cada preço
core/basemap_layer_test.dart, core/dem_online_test.dart Blocos de mapa contra um servidor falso: cache e descarte, um zoom mais grosso em vez de um mapa em branco, o ancestral mais próximo de um bloco que falta, o tilemap do ArcGIS e a sessão do Google Map Tiles; a grade de elevação online, os lotes, os downloads simultâneos com novas tentativas e ritmo, e a conferência do datum dos dados do próprio usuário
core/region_trace_test.dart Contornos de talhões em imagens aéreas sintéticas: fileiras de cultura contornadas até as bordas do talhão, árvores dentro preenchidas e informadas, talhões cortados pela borda da imagem sinalizados, todos os talhões de uma imagem encontrados
core/ai_api_fixes_test.dart, core/ai_transport_io_test.dart, core/ai_image_prep_test.dart O assistente contra falhas roteirizadas das APIs (pedidos recusados e grandes demais, erros do serviço, tempos esgotados e transmissões interrompidas, cada um com o que é mantido e reenviado); o transporte do desktop contra um servidor na máquina (envio, transmissão, um cancelamento fecha a conexão); imagens anexadas tipadas pelos bytes, endireitadas, reduzidas aos limites do modelo e recodificadas dentro do tamanho
core/app_logic_test.dart Lógica do app sem widgets: aliases de comando, rótulos traduzidos das ações, navegação do tutorial, o observador de rotas, o executor do cálculo sem workers, arquivos do desktop e assets de idioma
widget_ai_*.dart (os arquivos não citados acima) A tela de início do assistente, a ajuda para iniciantes, o comportamento do chat e o Markdown, as mensagens de erro, as marcas no mapa, a voz, as fotos de campo, colar e soltar, as conversas guardadas, /review, a prévia da prancha e as imagens que ele envia
editorial_names_test.dart A regra editorial: nenhum produto concorrente em nenhum lugar do repositório e nenhum produto de CAD na interface, no site e na documentação, conferidos pelo SHA-256 contra a lista única tool/hooks/banned-names.sha256 (a mesma do hook de pre-commit) para que o teste não cite nenhum
widget_*.dart Interface real: tela inicial e tutorial, galeria, menus e diálogos, painéis, edição no canvas, atalhos, histórico, terreno e layout compacto; gerenciamento com pivôs e turnos automáticos, diálogos fechados por fora, densograma, ferramentas de controlador e fio com a aba Elétrico, cotas de ordenada e de diâmetro, a aba Fios do catálogo, campos numéricos que rejeitam um valor; as propriedades de cada tipo de entidade, edição em lote e os resultados da seleção; a leitura do gráfico de perfil; navegação por roda, trackpad, botão do meio e dois dedos; diálogos de georreferência e de plotagem; menus da linha principal e do celular; o diálogo de turnos; os diálogos de projeto automático, agronomia, máquinas mecanizadas, operação da rede, transientes, importação de PDF, folhas e blocos e vegetação, cada um aplicando num passo de desfazer e cabendo num celular de 390 × 844; o layout da direita para a esquerda do árabe e do urdu, os rótulos condicionais, o indicador do GPS, a ferramenta de linha de quebra e os materiais da seleção
widget_theme_test.dart A paleta escura é o visual original, cor por cor; a paleta clara mantém o contraste WCAG AA dos textos sobre as suas superfícies; Ver → Tema troca no lugar (mesma janela, projeto e seleção), também pelo menu do celular, e as folhas são montadas no tema claro; uma camada branca é desenhada quase preta no canvas claro enquanto as plotagens ficam iguais; a escolha é salva e aplicada na abertura; Seguir o sistema acompanha o brilho da plataforma ao vivo; as imagens para o assistente de IA mantêm o canvas escuro
web_metadata_test.dart, version_test.dart, web_offline_test.dart Páginas do site geradas, SEO, JSON-LD, manifest, ícones, robots, sitemap, 404, llms.txt; as páginas de entrada carregam o app sob demanda; versão do app coerente com o pubspec.yaml, o gerador e o site; test/web_offline_test.dart cobre o gerador do service worker, os templates e o script de build
flutter_test_config.dart Roda em volta de cada arquivo de teste: o arquivo falha quando a interface pediu uma chave de texto que a tabela não tem, e nenhum teste chega à rede (só à interface de loopback)
seams/agronomy_programme_test.dart, seams/paste_merge_test.dart, seams/storage_full_app_test.dart Testes que atravessam módulos: para os 15 exemplos da galeria, a tabela de água, a necessidade da cultura, a tabela FAO-56 e o programa do controlador dão a mesma necessidade por área; um projeto inteiro colado na aba de um vizinho com outra moeda e outra georreferência cai no lugar, com os preços na moeda do destino, calcula igual e sai com um desfazer; o app com o armazenamento do navegador cheio abre espaço com versões e projetos salvos em arquivo, nunca com o trabalho não salvo, e mantém o aviso até uma cópia caber
guards/*_test.dart O pacote do motor traz tudo o que alcança; lib/core não importa Flutter; as imagens geradas da marca e a data do site; os hooks e a lista única de nomes proibidos; nenhuma rede; todo caractere de todo texto do PDF tem fonte; a ferramenta de lançamento; o worker de cálculo refeito byte a byte
core/pump_station_test.dart, core/real_operation_test.dart, core/reservoir_vessel_test.dart, core/sizing_plus_test.dart, core/analysis_control_test.dart, widget_mot_plus_test.dart Estações de bombeamento em paralelo ou em série, em serviço ou de reserva, escalonadas pela vazão, com o ponto, a energia e a lista de cada bomba; a operação real dos setores e os pilotos das válvulas; a curva do reservatório, os seus dias de demanda e o nível em 24 horas, o vaso de ar nos transientes; o golpe na classe de cada tubo, a linha piezométrica sobre os pontos altos, os anéis; análises um passo por vez com os mesmos resultados, canceladas, e os cenários de envelhecimento e entupimento; os seus diálogos no celular
core/soil_water_balance_test.dart, core/agr_plan_test.dart, core/agr_runoff_capacity_test.dart, core/agr_programme_test.dart, core/agr_catch_cans_fert_test.dart, core/inmet_csv_test.dart, widget_agr_plus_test.dart Um balanço hídrico feito à mão, sequeiro com Ky, déficit regulado, intervalo fixo e reposição parcial; o plano agronômico no arquivo; as famílias de infiltração do NRCS, o escoamento por passagem, a capacidade em 24 h e numa janela; ciclo e pausa, uma janela curta e um ajuste sazonal digitado; latas coletoras, CU e DU, fertirrigação por estágio; arquivos horários do INMET e do BDMEP; os seis diálogos no celular, em árabe e com o texto em dobro
core/agb_pump_house_test.dart, core/agb_solar_water_test.dart, core/agb_field_machines_test.dart, widget_agb_test.dart A elétrica da casa de bombas e a alimentação dos pivôs no cálculo, no relatório e na lista; o bombeamento solar e o seu custo de energia; a qualidade da água e o tratamento; dois fios na lista; vários pivôs com a sua linha principal; faixas de carretel e sulcos como demandas; cada diálogo um passo de desfazer
core/prd_*_test.dart, core/permit_test.dart, core/memorial_om_test.dart, core/budget_lcc_test.dart, core/tech_doc_test.dart, core/prb_packages_test.dart, widget_prd_test.dart, widget_deliverables_test.dart O carimbo, o datum dado pelo usuário ou pelo local, a quadrícula de coordenadas, a folha e as classes de declividade, as normas sob cada tabela, os pacotes de documentos; o regime da outorga mês a mês, o memorial e o plano de O&M iguais para o mesmo projeto, o orçamento e o custo do ciclo de vida; os escritores dos documentos (Markdown, CSV, XLSX, PDF)
core/cad_plus_core_test.dart, core/cad_plus_model_test.dart, core/cad_plus_controller_test.dart, widget_cad_plus_test.dart Aparar com cortes só nas pontas, Alongar, o contorno por clique interno; coordenadas de campo digitadas, kgf/cm², o estilo de cota e os estados de camadas no arquivo, referências de bloco com atributos, a comparação de cópias; o texto editado no lugar, a lupa, a entrada dinâmica, os snaps um a um
core/formats_1102_test.dart, core/projections_1102_test.dart, widget_fmt_1102_test.dart GeoTIFF grandes e otimizados para a nuvem por blocos, sobreposições de imagem do KMZ, blocos de levantamento, ida e volta do XDATA, páginas de código CJK, PDF/A-2b e camadas, folhas personalizadas; Albers, Lambert e policônica contra os exemplos resolvidos de Snyder (1987); o assistente de pontos, os pontos para locação, os downloads guardados e a pergunta antes de um link grande
core/area_holes_test.dart, core/area_holes_editor_test.dart, core/project_merge_test.dart, core/pipe_standards_test.dart, core/catalog_units_test.dart, core/new_project_prefs_test.dart, core/cli_projects_test.dart, core/tin_order_test.dart, guards/engine_package_test.dart Ilhas fora da área, da água, do layout e das imagens e levadas pelas exportações; Inserir projeto; os pacotes por norma e os seus preços; o catálogo nas unidades do projeto; com o que os projetos novos começam; a linha de comando fazendo e alterando projetos; um TIN independente da ordem dos itens; o motor como pacote
core/automation_wave2_test.dart, widget_aut_wave2_test.dart, core/ai_ia_plus_test.dart, widget_ai_ia_plus_test.dart, core/ui_wave2_test.dart, widget_ui_wave2_test.dart Um detector de autointerseção e um deslocamento só, o comprimento máximo da lateral, a revisão item a item do Corrigir e do Otimizar, o contorno pela imagem contra blocos sintéticos; os custos por passo, Aplicar o resto da tarefa, o esforço por etapa, as conversas de um projeto; a aba sem nome, a paleta de comandos, o manual e os seus capítulos, as Novidades, o relato de problema
site_manual_test.dart, site_fonts_test.dart, web_js_test.dart, launch_actions_test.dart, data_credits_test.dart, field_map_test.dart, i18n_review_test.dart, web_docs_test.dart As páginas do guia do usuário (âncoras, links, texto, metadados, sitemap), as fontes servidas pelo site, os scripts do service worker e do bootstrap no Node, abrir arquivos com o app instalado, os créditos dos dados de terceiros, o mapa guardado para o campo, os arquivos da revisão de traduções, os links e títulos da documentação

Verificações além da suíte de testes

  • CI (GitHub Actions, .github/workflows/ci.yml, ações fixadas por commit, Flutter lido do pubspec.yaml): análise sem nenhum aviso, formatação, o worker de cálculo byte a byte, os geradores sem diferença, a suíte em quatro fatias com pisos de cobertura por pasta (os testes de tempo, marcados perf, à parte com folga), os testes de navegador no Chrome, um build de produção conferido por tool/release.dart verify-build com o teste de fumaça de ponta a ponta, e um trabalho de formatos com pacotes de Python fixados e o LibreDWG; um trabalho em matriz roda a mesma fumaça no WebKit e no Firefox sobre esse build. O Dependabot propõe atualizações dos pacotes e das ações.
  • Teste de fumaça de ponta a ponta (tool/e2e/smoke.mjs, playwright-core fixado): num build de produção (sh tool/build_web.sh), o app abre um exemplo e o calcula no Web Worker, mostra a versão do build, instala o seu service worker e abre de novo sem rede, envia uma mensagem do assistente de IA com a chave do usuário a uma imitação da API (nada sai da máquina), percebe um worker de cálculo de outro build e carrega o deste, e não mostra nenhum erro de página. --browser chromium,webkit,firefox usa o Chrome instalado e os builds de WebKit e Firefox que a versão fixada determina; uma verificação que um navegador não consegue rodar é informada como pulada, nunca como aprovada.
  • Imagens golden (test/goldens, marca golden): a prancheta clara e escura, linhas finas densas numa tela 2×, um diálogo no celular e o SVG de uma prancha, comparados com tolerância ao serrilhado de outras plataformas.
  • Hooks (git config core.hooksPath tool/hooks): o hook de pre-commit recusa arquivos Dart preparados que não estejam formatados e qualquer nome proibido nas linhas que um commit acrescenta (a lista única tool/hooks/banned-names.sha256, mais uma lista local em texto claro em .git/info/banned-words), e avisa de um worker de cálculo não recompilado.
  • test/seams/ reúne os testes que atravessam módulos (agronomia e programa, colagem entre projetos, armazenamento do navegador cheio), ao lado dos testes de cada módulo.

Armadilhas conhecidas ao escrever testes de widget: o cálculo é assíncrono de verdade e deve rodar dentro de tester.runAsync; títulos de diálogo podem estar em maiúsculas; o canvas precisa de um tamanho de janela definido; o carregamento de assets (catálogos) usa rootBundle e funciona em flutter test.