Cobertura de testes
Acreditamos que testes são essenciais para manter a qualidade do projeto. A cobertura atual já cobre boa parte do motor e do editor visual, e está sendo expandida a cada release.
Números gerais
| Métrica | Valor |
|---|---|
| Testes unitários (sulfite_core) | 953 |
| Testes unitários (sulfite_studio) | 896 |
| Testes unitários (sulfite_chat) | 85 |
| Testes unitários (sulfite_datasources) | 30 |
| Testes integração/e2e (macOS) | 92 |
| Total | 2056 |
| Cobertura sulfite_core | ~84% |
| Cobertura sulfite_studio | ~73% |
Por pacote
sulfite_core — 953 testes
| Área | O que cobre |
|---|---|
| ExpressionEvaluator | Aritmética +−×÷^, funções math (sqrt, abs, sin), 6 modos de arredondamento (half_up, half_even, up, down, truncate, half_down), divisão por zero, expressões inválidas |
| ValueFormatter | currency:BRL/USD, date:dd/MM/yyyy, datetime, number:N, integer, null/empty |
| ImageCache | Cache hit/miss, LRU eviction, base64 decode |
| SulfiteEngineImpl | API pública render(), pipeline completo (parse → process → render) |
| PdfRenderer | Todos os tipos de elemento, multi-banda, Header/Detail/Summary/Footer |
| FontLoader | Carregamento de fontes customizadas, cache, fallback |
| DataProcessor | Separação de rows por band, múltiplos dataSources, __bandId |
| Parser | Parsing de ReportDefinition do JSON, campos opcionais |
| ChartRenderer | Bar/Line/Pie em PDF, multi-series, ChartOptions, série vazia |
| ChartElement (model) | Parse JSON bar/line/pie, serialização, ChartSeries, ChartOptions |
| HtmlRenderer (aggregates mode) | HtmlAggregatesSectionMode (always, fallback, never) para evitar duplicação de seção de agregados no HTML |
| invoice_chart_report | DataProcessor + PdfRenderer com 4 dataSources e 3 gráficos |
| Multiformat Export | HTML, CSV (delimitador, header), Excel (.xlsx válido) |
| Models Serialization | fromJson/toJson de todos os tipos de ReportElement, incluindo SpacerElement |
| IO (real / stub) | dart:io — salvar/ler arquivo; stubs para web/mobile |
| rendering_integration | FieldElement binding, AggregateElement (SUM/COUNT/AVG/MIN/MAX), relatório completo |
| ScriptEngine | filter/sort/limit/distinct/addField, AND/OR/NOT, parâmetros injetados, printWhen |
| DataProcessor | Processamento via Stream, GroupBands; transforms replaced by scripts (RFC-016) |
| GroupBands | groupHeader/groupFooter, agregação por grupo, renderização intercalada |
| ReportParameter | Serialização JSON, campos opcionais (lookup, dependsOn, validation) |
| LookupConfig | Round-trip JSON para variante http e db, discriminador "source", fallback backward-compat, LookupOption, ValidationRule, todos os ValidationRuleTypes, campos pageSize/searchOnOpen |
| HttpLookupResolver | Placeholders URL, cache, SSRF (reject + bypass), localhost, 127.0.0.1, https, non-2xx, paginação com fetchPage, leitura de meta.total/page/perPage, heurística items.length >= pageSize |
| RestDataSourceResolver | HTTP GET/POST, expansão de {paramId}, modos strict/resilient |
| Rect/RoundedRect unification | borderRadius, migração automática de roundedRect |
| Print Filters (param injection) | Injeção de parâmetros no ScriptEngine e URLs REST |
| Example Reports (e2e) | 3 exemplos reais (06-grouped-sales, 07-dashboard, 08-hr-report) — 67 testes profundos: parse, geração de arquivos físicos PDF/HTML/CSV/Excel em test_output/, validação de conteúdo (nomes, produtos, valores formatados), estrutura HTML (DOCTYPE, Chart.js, CSS classes), cross-format data consistency, backward compat com 01-invoice |
Guardas de performance automatizadas
O teste test/stress/nfe_benchmark_test.dart agora inclui budgets de tempo para detectar regressões:
| Volume | Process | HTML | |
|---|---|---|---|
| 5.000 itens | <= 1200ms | <= 3000ms | <= 15000ms |
| 10.000 itens | <= 1800ms | <= 5000ms | <= 30000ms |
| 20.000 itens | <= 3000ms | <= 9000ms | <= 60000ms |
Para execução diagnóstica (sem falhar por budget), use:
bash
SULFITE_SKIP_PERF_GUARD=1 flutter test test/stress/nfe_benchmark_test.dartsulfite_datasources — 30 testes
| Área | O que cobre |
|---|---|
| DbLookupResolver | Query parametrizada com placeholders {_search} / {_page} / {_page_size} / {_offset}, substituição de {_schema}, cache por chave composta, fetchPage com hasMore, UnresolvedConnectionException para connectionRef inválido |
| RestDataSourceResolver | HTTP GET/POST, expansão de {paramId}, modos strict/resilient |
| PostgresDataSourceResolver | Conexão, query parametrizada, mapeamento de tipos, erro de conexão |
sulfite_studio — 896 testes
| Área | O que cobre |
|---|---|
| DesignerViewModel | addElement, removeElement, updateElement, seleção, multi-select, loadReport |
| UndoRedoManager | push, undo, redo, pilha vazia, limite de histórico |
| JSON ↔ Canvas sync | Editar JSON reflete no canvas; mover elemento atualiza o JSON editor |
| ChartEditorDialog | Trocar ChartType, add/remove série, drag-reorder, preview em tempo real |
| ChartUI (ViewModel) | Add/remove/reorder series via ViewModel, tipo muda opções disponíveis |
| PreferencesService | get/set themeMode, primaryColor, locale, reset para defaults |
| PreferencesProvider | Notificações Riverpod ao mudar prefs, propagação pelo widget tree |
| SulfiteTheme | buildTheme com cor customizada, modo claro/escuro, 8 presets animados |
| ThemeEditor | Segmented button idioma, color swatches, botão Personalizado → picker |
| SettingsScreen | 3 abas (Geral, Tema, Avançado), troca idioma, aplica tema |
| ReportValidator | IDs duplicados, bands sem elementos, dataSources sem referências |
| BandManagerDialog | Reorder bands, remover band, integração com undo |
| AddBandDialog / AddAggregateDialog | Formulários de criação, validação de campos |
| ValidationDialog | Exibição de erros e warnings com severidade |
| CanvasInteraction | Click para selecionar, drag para mover, Ctrl+Click multi-select, Escape deselect |
| CanvasRenderer | Paint, zoom, grid |
| Ruler / SnapLines | Marcações de régua, guias magnéticas |
| PropertyField / Editors | ColorPickerField, FormatPickerField, RoundingConfigEditor |
| PageSettingsPanel | Formato de página, margens |
| Toolbar / SpeedDial | Botões, estado selecionado, ações |
| chart_integration | Pipeline completo Studio: add element → edita → preview → serializa |
| TransformPipelineEditor | Adicionar/remover/reordenar operações, preview com debounce, IDs únicos |
| PrintParamsDialog | Delegação para SulfiteFilterScreen |
| SulfiteFilterScreen | text/number/date/select, required validation, lookup loading/loaded, confirm/cancel, novos tipos currency/datetime, campo format |
| FilterFields (date/currency) | Campos date com formatos dd/MM/yyyy, yyyy-MM-dd, MM/dd/yyyy; campo currency com máscaras BRL e US; rounding no blur; campo datetime |
| LookupListBody | Estado de loading, erro, lista vazia, hasMore (scroll infinito), awaitingInput, seleção de item |
| SingleSelectLookupDialog | Carregamento inicial, busca com debounce, loading state, erro com retry, seleção confirma, cancelamento, cascata de parâmetros |
| MultiselectLookupDialog | Seleção múltipla, paginação com fetchPage, busca incremental, hasMore, confirmação/cancelamento, estado de loading por página |
| DatasourceInspectorDialog | Renderização dos campos, edição de nome/tipo/source, validação inline |
| BandManagerDialog (integração) | Reorder completo, undo, groupHeader/groupFooter com groupBy |
| ParameterEditor | Adicionar/remover parâmetros, edição inline |
| DartEvalScriptRunner (preview) | runForPreview: captura de mutations via print(), múltiplas chamadas setDatasource, script Pokémon Duel completo (fighters/duel_stats/verdict_ds) |
| DesignerViewModel (preview mutations) | Pipeline ponta a ponta: resolver → dart_eval fallback → apply mutations → processedData com rows preenchidos |
| SulfiteConsumerScreen (dart_eval) | Contrato runForPreview → mutations → payload.addAll quando nenhum handler nativo está registrado |
| RFC-022/023 (ScriptTokenContext) | ScriptTokenContext, ReportIdRegistry, DartScriptValidator, datasource inspector |
sulfite_chat — 85 testes
| Arquivo | O que cobre |
|---|---|
chat_config_test.dart | Construção/defaults, getter color, getter icon (8 iconNames + fallback), copyWith (7 casos), availableModels (5 providers) |
schema_validator_test.dart | JSON válido, JSON mal-formado, campos obrigatórios (reportId, reportName, pageSettings, bands), validação por tipo de elemento (text, field, image, aggregate, line, rect, circle, chart, richText), referências de dataSource, múltiplos erros |
report_generator_test.dart | Extração de JSON de bloco ```json , bloco genérico e JSON bruto; tag <explanation>; auto-correção em 2ª tentativa; falha após maxAttempts; detecção de erros de provedor (rate limit, quota, no authentication); GenerationResult` (success/failure/attempts) |
Integração / E2E (macOS) — 52 testes
Executados via all_studio_tests.dart no app host (example/) com flutter test integration_test/ -d macos.
| Arquivo | Testes | O que cobre |
|---|---|---|
| validation_flow_test.dart | 7 | Validação de relatório, erros/warnings, severidade |
| end_to_end_test.dart | 4 | Pipeline completo: criar → editar → serializar → renderizar |
| designer_workflow_test.dart | 8 | Fluxo do designer: add/move/resize elementos, undo/redo |
| multi_selection_test.dart | 9 | Ctrl+Click, seleção múltipla, operações em lote |
| rfc_features_test.dart | 13 | RFCs 011-015: filtros, lookups, cascata, params REST |
| filter_flow_test.dart | 6 | RFC-015: field types, lookup loading, cascade, validação, cross-field, integração Studio |
| json_editor_perf_test.dart | 5 | Performance do JSON editor: fold/unfold, highlight, edição grande |
| rfc_022_023_test.dart | ~40 | RFC-022/023: script console, datasource inspector, validação de código Dart |
Executando os testes
bash
# sulfite_core
cd packages/sulfite_core
flutter test test/
# sulfite_studio
cd packages/sulfite_studio
flutter test test/
# sulfite_chat
cd packages/sulfite_chat
flutter test test/
# Integração / E2E (requer macOS)
cd example
flutter test integration_test/all_studio_tests.dart -d macos
# Todos os e2e do example (inclui testes avulsos)
cd example
flutter test integration_test/ -d macos