Logosulfite.app
rafagazani/sulfite 999999

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étricaValor
Testes unitários (sulfite_core)1049
Testes unitários (sulfite_studio)982
Testes unitários (sulfite_chat)85
Testes unitários (sulfite_datasources)47
Testes integração/e2e (macOS)92
Total2255
Cobertura sulfite_core~84%
Cobertura sulfite_studio~73%

Por pacote#

sulfite_core — 1049 testes#

ÁreaO 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
ImageCacheCache hit/miss, LRU eviction, base64 decode
SulfiteEngineImpl API pública render(), pipeline completo (parse → process → render)
PdfRendererTodos os tipos de elemento, multi-banda, Header/Detail/Summary/Footer
FontLoaderCarregamento de fontes customizadas, cache, fallback
DataProcessor Separação de rows por band, múltiplos dataSources, __bandId
ParserParsing 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_reportDataProcessor + PdfRenderer com 4 dataSources e 3 gráficos
Multiformat ExportHTML, 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)
GroupBandsgroupHeader/groupFooter, agregação por grupo, renderização intercalada
ReportParameterSerializaçã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 unificationborderRadius, migração automática de roundedRect
Print Filters (param injection)Injeção de parâmetros no ScriptEngine e URLs REST
TablePivotHelper Pivot de dados flat em matriz dinâmica, aggregação (SUM/AVG/COUNT/MIN/MAX), columnSort (alpha/alpha_desc/value_asc/value_desc/natural), columnOrder fixo, totais por linha/coluna
CellStyleResolver Avaliação de CellStyleRule.when , contexto com row + value , first-match-wins, valores truthy
Table Pivot (e2e) Pipeline completo: dados ICMS 8 estados × 12 meses, PDF + HTML, altura dinâmica ( height: 0 ), columnOverrides com formato/largura/align, estilos condicionais por coluna
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:

VolumeProcessHTMLPDF
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:

SULFITE_SKIP_PERF_GUARD=1 flutter test test/stress/nfe_benchmark_test.dart

sulfite_datasources — 47 testes#

ÁreaO 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 — 982 testes#

ÁreaO que cobre
DesignerViewModel addElement, removeElement, updateElement, seleção, multi-select, loadReport
UndoRedoManagerpush, 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
ThemeEditorSegmented button idioma, color swatches, botão Personalizado → picker
SettingsScreen3 abas (Geral, Tema, Avançado), troca idioma, aplica tema
ReportValidatorIDs duplicados, bands sem elementos, dataSources sem referências
BandManagerDialogReorder bands, remover band, integração com undo
AddBandDialog / AddAggregateDialogFormulários de criação, validação de campos
ValidationDialogExibição de erros e warnings com severidade
CanvasInteraction Click para selecionar, drag para mover, Ctrl+Click multi-select, Escape deselect
CanvasRendererPaint, zoom, grid
Ruler / SnapLinesMarcações de régua, guias magnéticas
PropertyField / EditorsColorPickerField, FormatPickerField, RoundingConfigEditor
PageSettingsPanelFormato de página, margens
Toolbar / SpeedDialBotõ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
PrintParamsDialogDelegaçã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
ParameterEditorAdicionar/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
TableEditorDialog (pivot) Toggle pivot, campos rowFields / columnField / valueField , dropdown verb , toggles totais, columnSort , columnOrder , columnOverrides , cellConditionalStyles
CellStyleRulesEditor Add/remove regras, edição de when / textColor / fill / bold / fontSize , validação de expressão, color picker inline
PivotTableWidget Renderização de TableElement em modo pivot no canvas do Studio, aplicação de estilos condicionais, preview em tempo real

sulfite_chat — 85 testes#

ArquivoO 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 &lt;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.

ArquivoTestesO 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.dart9Ctrl+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#

# sulfite_core
cd packages/sulfite_core
fvm flutter test

# sulfite_studio
cd packages/sulfite_studio
fvm flutter test

# sulfite_chat
cd packages/sulfite_chat
flutter test test/

# Integração / E2E (requer macOS)
cd examples/app
flutter test integration_test/all_studio_tests.dart -d macos

# Todos os e2e do example (inclui testes avulsos)
cd examples/app
flutter test integration_test/ -d macos

# RFC-043: permissões por grupo contra Postgres real
cd packages/sulfite_server
RFC043_E2E_ENABLED=1 \
SULFITE_RFC043_E2E_DATABASE_URL="$DATABASE_URL" \
dart test test/rfc043_postgres_e2e_test.dart

O E2E da RFC-043 cria um schema temporário sulfite_rfc043_e2e_*, sobe o server com PostgresReportRepository, PostgresReportGroupRepository e GroupPermissionResolver, valida C3 via HTTP real e remove o schema ao final. Ele fica desligado por padrão para não depender de rede nem de credenciais em CI local.