// Copyright (c) 2026 Storm Dragon // Authors: Storm Dragon, Angus Kola // SPDX-License-Identifier: GPL-3.0-or-later package app import ( "bytes" "encoding/json" "errors" "log/slog" "testing" "git.stormux.org/storm/cthulhu/internal/atspi" "git.stormux.org/storm/cthulhu/internal/presentation" "git.stormux.org/storm/cthulhu/internal/review" ) func TestDocumentDiagnosticsSeparateFailureFromWrapping(t *testing.T) { for _, caret := range []bool{true, false} { var output bytes.Buffer logger := slog.New(slog.NewJSONHandler(&output, &slog.HandlerOptions{Level: slog.LevelDebug})) queue := &autocompleteRequestQueue{requests: make(chan speechRequest, 4)} result := review.Result{DocumentEpoch: 7, DocumentFocus: atspi.NewObjectID(":1.42", "/doc"), DocumentWrapped: !caret, Moved: !caret, DocumentTarget: review.DocumentHeading, DocumentDiagnostics: review.DocumentDiagnostics{CaptureAttempts: 2, Attempts: []review.DocumentAttempt{{Recovery: "saved-object-missing", Stage: "move"}}}} if caret { result.Err = errors.New("accessible children require recapture") presentDocumentCaretResult(logger, queue, result, presentation.DefaultOptions()) } else { result.DocumentPosition.Snapshot = atspi.NewSnapshot("/heading", "Example", "heading", "", "") presentDocumentResult(logger, queue, result, presentation.DefaultOptions()) } var record struct { Epoch uint64 `json:"document_epoch"` Focus atspi.ObjectID `json:"focus"` Error string `json:"error"` Wrapped bool `json:"wrapped"` Navigation review.DocumentDiagnostics `json:"navigation"` } if err := json.NewDecoder(&output).Decode(&record); err != nil { t.Fatal(err) } if record.Epoch != 7 || record.Focus != result.DocumentFocus || record.Wrapped != !caret || record.Navigation.CaptureAttempts != 2 || len(record.Navigation.Attempts) != 1 || record.Navigation.Attempts[0].Recovery != "saved-object-missing" { t.Fatalf("missing navigation diagnostics: %+v", record) } if caret && record.Error != result.Err.Error() { t.Fatalf("failed command lost its error: %+v", record) } } }