package uiaselector import ( "testing" "time" ) func fixedReportTime() time.Time { return time.Date(2026, 7, 9, 0, 0, 0, 0, time.UTC) } func loadN14Fixture(t *testing.T) *Node { t.Helper() root, err := LoadDumpFile("testdata/n12r-2026-07-09-uia-redacted.json") if err != nil { t.Fatalf("LoadDumpFile: %v", err) } return root } func TestRunCatalogReportMatchesAllN13Selectors(t *testing.T) { report := RunCatalogReport( "testdata/n12r-2026-07-09-uia-redacted.json", loadN14Fixture(t), DefaultCatalog(), fixedReportTime(), ) if !report.OK { t.Fatalf("report OK=false: %#v", report.Error) } if report.SourceDump != "testdata/n12r-2026-07-09-uia-redacted.json" { t.Fatalf("source_dump = %q", report.SourceDump) } if report.GeneratedAtUTC != "2026-07-09T00:00:00Z" { t.Fatalf("generated_at_utc = %q", report.GeneratedAtUTC) } if report.CatalogSize != 10 { t.Fatalf("catalog_size = %d, want 10", report.CatalogSize) } if report.MatchedCount != 10 { t.Fatalf("matched_count = %d, want 10", report.MatchedCount) } if report.UnmatchedCount != 0 { t.Fatalf("unmatched_count = %d, want 0", report.UnmatchedCount) } if report.AmbiguousCount != 0 { t.Fatalf("ambiguous_count = %d, want 0", report.AmbiguousCount) } if got := StrictExitCode(report); got != StrictExitOK { t.Fatalf("StrictExitCode = %d, want %d", got, StrictExitOK) } } func TestStrictModeClassifiesFailures(t *testing.T) { catalog := []Selector{ { ID: "missing_panel", Description: "missing structural test selector", AllowedUse: AllowedUseReadOnlyLocate, Required: Criteria{AutomationID: "does_not_exist", ControlType: "Pane", FrameworkID: "WinForm"}, StabilityScore: 80, Evidence: Evidence{CaptureID: "unit-test", UIAPath: "root/missing"}, }, } report := RunCatalogReport("fixture.json", loadN14Fixture(t), catalog, fixedReportTime()) if !report.OK { t.Fatalf("report OK=false: %#v", report.Error) } if report.UnmatchedCount != 1 { t.Fatalf("unmatched_count = %d, want 1", report.UnmatchedCount) } if got := StrictExitCode(report); got != StrictExitUnmatched { t.Fatalf("StrictExitCode = %d, want %d", got, StrictExitUnmatched) } } func TestReportRejectsNonReadOnlyCatalogEntries(t *testing.T) { catalog := []Selector{ { ID: "bad_write_selector", Description: "invalid write selector", AllowedUse: "write", Required: Criteria{AutomationID: "frmMain", ControlType: "Window", FrameworkID: "WinForm"}, StabilityScore: 1, Evidence: Evidence{CaptureID: "unit-test", UIAPath: "root"}, }, } report := RunCatalogReport("fixture.json", loadN14Fixture(t), catalog, fixedReportTime()) if report.OK { t.Fatalf("report OK=true for invalid catalog") } if report.Error == nil || report.Error.Code != "INVALID_CATALOG" { t.Fatalf("report error = %#v, want INVALID_CATALOG", report.Error) } if got := StrictExitCode(report); got != StrictExitInvalidCatalog { t.Fatalf("StrictExitCode = %d, want %d", got, StrictExitInvalidCatalog) } }