Files
fn_registry/functions/infra/audit_e2e_coverage.md
T
egutierrez 7b0b697b18 feat(0121b): audit_e2e_coverage_go_infra + fn doctor e2e-coverage subcmd
- Crea functions/infra/audit_e2e_coverage.go: AuditE2ECoverage(roots) escanea
  app.md recursivamente, detecta e2e_checks: en frontmatter, retorna
  E2ECoverageReport{total, with_checks, missing, coverage_pct}.
- Crea functions/infra/e2e_coverage_report.go: tipo E2ECoverageReport con
  JSON tags (total, with_checks, missing, coverage_pct).
- Crea types/infra/e2e_coverage_report.md: metadata del tipo para registry.
- Crea functions/infra/audit_e2e_coverage.md: documentacion self-contained
  con Ejemplo, Cuando usarla, Gotchas.
- Crea functions/infra/audit_e2e_coverage_test.go: 3 tests (empty, all-covered,
  partial) — todos pasan.
- Edita cmd/fn/doctor.go: agrega case "e2e-coverage" -> doctorE2ECoverage().
  Output text (tabla tabwriter + lista de apps missing) y --json (E2ECoverageReport).

Acceptance verificado:
  fn doctor e2e-coverage --json -> {total, with_checks, missing, coverage_pct} OK
  fn doctor e2e-coverage        -> tabla text OK
  go test ./functions/infra/... -> 3/3 PASS
  fn show audit_e2e_coverage_go_infra -> indexada OK

task_run: task_d285372493cce2e6 iter 1

Co-authored-by: fn-orquestador <noreply@fn-registry>
2026-05-19 01:45:54 +02:00

58 lines
2.3 KiB
Markdown

---
name: audit_e2e_coverage
kind: function
lang: go
domain: infra
version: "1.0.0"
purity: impure
signature: "func AuditE2ECoverage(roots []string) (E2ECoverageReport, error)"
description: "Escanea directorios en busca de app.md y reporta cuales declaran e2e_checks en su frontmatter YAML. Retorna total, with_checks, missing (paths relativos) y coverage_pct (0-100). Impuro por lectura de filesystem."
tags: [e2e_checks, coverage, audit, doctor, infra]
params:
- name: roots
desc: "lista de directorios raiz a escanear recursivamente buscando app.md (ej. ['apps', 'cpp/apps', 'projects']). Directorios inexistentes se ignoran silenciosamente."
output: "E2ECoverageReport con total/with_checks/missing/coverage_pct. Error no nil solo ante fallo real de I/O."
uses_functions: []
uses_types: ["e2e_coverage_report_go_infra"]
returns: ["e2e_coverage_report_go_infra"]
returns_optional: false
error_type: "error_go_core"
imports: ["fmt", "math", "os", "path/filepath", "strings"]
tested: true
tests:
- "directorio vacio sin app.md retorna Total=0 y CoveragePct=0"
- "todos los app.md con e2e_checks retorna CoveragePct=100"
- "cobertura parcial calcula CoveragePct correcto y puebla Missing"
test_file_path: "functions/infra/audit_e2e_coverage_test.go"
file_path: "functions/infra/audit_e2e_coverage.go"
---
## Ejemplo
```go
report, err := infra.AuditE2ECoverage([]string{"apps", "cpp/apps", "projects"})
if err != nil {
log.Fatal(err)
}
fmt.Printf("Coverage: %.2f%% (%d/%d apps)\n", report.CoveragePct, report.WithChecks, report.Total)
for _, m := range report.Missing {
fmt.Println(" missing:", m)
}
```
## Cuando usarla
Usar como backend de `fn doctor e2e-coverage` para detectar apps sin contrato de validacion.
Tambien util antes de crear proposals `e2e_check_add`: llamar primero para obtener la lista
de apps que necesitan cobertura y priorizar las que mas se usan.
## Gotchas
- Solo detecta `e2e_checks:` como substring en el frontmatter — no valida la estructura YAML
completa del bloque. Un `# e2e_checks:` comentado pasaria como cubierto.
- Los paths en `Missing` son los paths tal como los devuelve `filepath.WalkDir`, que pueden
ser absolutos si los elementos de `roots` son absolutos. Para comparacion reproducible,
pasar roots relativas al cwd.
- Un `app.md` no legible (permisos) se cuenta en `Total` y se añade a `Missing` — no aborta
el scan.