Skip to content

test: improve statement coverage from 87.8% to 88.6%#28

Merged
jacoblehr merged 2 commits into
mainfrom
copilot/analyze-test-coverage-one-more-time
May 16, 2026
Merged

test: improve statement coverage from 87.8% to 88.6%#28
jacoblehr merged 2 commits into
mainfrom
copilot/analyze-test-coverage-one-more-time

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 16, 2026

  • Analyze current test coverage (~87.8% total → 88.6% after improvements)
  • Add tests for internal/compare, internal/coverage, internal/output, internal/trace, internal/scoring, internal/renderer, internal/store
  • Apply gofmt to all modified test files (trace_test.go, output_test.go, output_trace_test.go, renderer_test.go, sqlite_extra_test.go)
  • Verify all affected packages still pass after formatting

…, scoring, renderer, store

Agent-Logs-Url: https://github.com/faultline-cli/faultline/sessions/241c234e-ffe6-4982-9a8a-8d7e2c2b8018

Co-authored-by: jacoblehr <16401696+jacoblehr@users.noreply.github.com>
@jacoblehr jacoblehr marked this pull request as ready for review May 16, 2026 00:19
Copilot AI review requested due to automatic review settings May 16, 2026 00:19
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR increases overall Go statement coverage (87.8% → 88.6%) by adding and extending unit tests across core packages (output formatting, trace/compare helpers, scoring feature extraction, coverage robustness calculations, renderer defaults, and store/SQLite behaviors).

Changes:

  • Added new test suites for compare/workflow output formatters and scoring delta-feature extraction.
  • Expanded existing tests in trace/compare/coverage/store/renderer/output to cover previously untested branches and edge cases.
  • Added store (SQLite) coverage for directory creation, migration idempotency, and BeginRun timestamp handling.

Reviewed changes

Copilot reviewed 9 out of 10 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
internal/trace/trace_test.go Adds tests for rule-note helpers and why/unmatched-why builders.
internal/store/sqlite_extra_test.go Adds tests for BeginRun zero timestamp, openSQLite parent dir creation, and migrate idempotency.
internal/scoring/features_test.go New tests for deltaPlaybookFeatures branches (missing/unmatched/matched/default weight/etc.).
internal/renderer/renderer_test.go Adds tests for New() option defaults/preservation.
internal/output/output_workflow_test.go New tests for FormatWorkflowText and FormatWorkflowJSON branches.
internal/output/output_trace_test.go Extends tests for trace history window/section join and CI annotations formatting.
internal/output/output_test.go Extends tests for markdown list parsing, score breakdown formatting, match summary, and AnalysisView helpers.
internal/output/output_compare_test.go New tests for compare formatting (text/markdown/json) and helper sections.
internal/coverage/report_test.go Adds tests for FP/FN risk labeling and robustness score computation.
internal/compare/compare_test.go Adds tests ensuring artifact fix-steps/dominant-signals extraction and propagation via compare Build.
Comments suppressed due to low confidence (1)

internal/store/sqlite_extra_test.go:347

  • TestBeginRunWithZeroTimestampUsesNow currently only asserts that BeginRun returns a non-zero handle ID, but it doesn't actually verify the behavior implied by the name/comment (that StartedAt was auto-populated when zero). Since these tests are in package store, consider type-asserting to *sqliteStore and querying the inserted row's started_at (or otherwise observing it) to make this test meaningful.
// StartedAt zero → should be auto-populated by BeginRun.
ctx := context.Background()
handle, err := st.BeginRun(ctx, BeginRunParams{
Surface:    "analyze",
SourceKind: "log",
Source:     "stdin",
InputHash:  "zero-ts-input",
// StartedAt is zero value
})
if err != nil {
t.Fatalf("BeginRun with zero timestamp: %v", err)
}
if handle.ID == 0 {
t.Error("expected non-zero run handle ID")
}

Comment thread internal/trace/trace_test.go Outdated
Comment on lines +577 to +597
got := allRuleNote(true)
if got != "required rule matched" {
t.Errorf("expected 'required rule matched', got %q", got)
}
}

func TestAllRuleNoteMissing(t *testing.T) {
got := allRuleNote(false)
if got != "required rule was missing" {
t.Errorf("expected 'required rule was missing', got %q", got)
}
}

// ── anyRuleNote ───────────────────────────────────────────────────────────────

func TestAnyRuleNoteMatched(t *testing.T) {
got := anyRuleNote(true)
if got != "trigger rule matched the log" {
t.Errorf("expected 'trigger rule matched the log', got %q", got)
}
}
Comment thread internal/output/output_trace_test.go Outdated
Comment on lines +463 to +481
got := traceHistoryWindow("not-a-date", "2026-01-01T00:00:00Z")
if got != "" {
t.Errorf("expected empty for invalid start, got %q", got)
}
}

func TestTraceHistoryWindowInvalidEndReturnsEmpty(t *testing.T) {
got := traceHistoryWindow("2026-01-01T00:00:00Z", "not-a-date")
if got != "" {
t.Errorf("expected empty for invalid end, got %q", got)
}
}

func TestTraceHistoryWindowEndBeforeStartReturnsEmpty(t *testing.T) {
got := traceHistoryWindow("2026-01-02T00:00:00Z", "2026-01-01T00:00:00Z")
if got != "" {
t.Errorf("expected empty when end is before start, got %q", got)
}
}
Comment thread internal/renderer/renderer_test.go Outdated
Comment on lines +392 to +417
r := New(Options{Width: 0, Plain: true})
if r.opts.Width != defaultWidth {
t.Errorf("expected defaultWidth %d for zero-width option, got %d", defaultWidth, r.opts.Width)
}
}

func TestNewNonZeroWidthPreserved(t *testing.T) {
r := New(Options{Width: 100, Plain: true})
if r.opts.Width != 100 {
t.Errorf("expected width 100 to be preserved, got %d", r.opts.Width)
}
}

func TestNewPlainFlagPreserved(t *testing.T) {
r := New(Options{Plain: true})
if !r.opts.Plain {
t.Error("expected Plain=true to be preserved")
}
}

func TestNewDarkBackgroundPreserved(t *testing.T) {
r := New(Options{DarkBackground: true, Width: 88})
if !r.opts.DarkBackground {
t.Error("expected DarkBackground=true to be preserved")
}
}
Comment thread internal/output/output_test.go Outdated
Comment on lines +1405 to +1426
got := firstMarkdownListItem("- first item\n- second item")
if got != "first item" {
t.Errorf("expected 'first item', got %q", got)
}
}

func TestFirstMarkdownListItemNumbered(t *testing.T) {
got := firstMarkdownListItem("1. numbered item\n2. second item")
if got != "numbered item" {
t.Errorf("expected 'numbered item', got %q", got)
}
}

func TestFirstMarkdownListItemParagraphBeforeList(t *testing.T) {
got := firstMarkdownListItem("Some text.\n\n- the bullet")
if got != "the bullet" {
t.Errorf("expected 'the bullet', got %q", got)
}
}

func TestFirstMarkdownListItemEmpty(t *testing.T) {
got := firstMarkdownListItem("")
Comment thread internal/store/sqlite_extra_test.go Outdated
Comment on lines +326 to +384
path := filepath.Join(t.TempDir(), "faultline.db")
st, _, err := OpenBestEffort(Config{Mode: ModeAuto, Path: path})
if err != nil {
t.Fatalf("OpenBestEffort: %v", err)
}
defer st.Close()

// StartedAt zero → should be auto-populated by BeginRun.
ctx := context.Background()
handle, err := st.BeginRun(ctx, BeginRunParams{
Surface: "analyze",
SourceKind: "log",
Source: "stdin",
InputHash: "zero-ts-input",
// StartedAt is zero value
})
if err != nil {
t.Fatalf("BeginRun with zero timestamp: %v", err)
}
if handle.ID == 0 {
t.Error("expected non-zero run handle ID")
}
}

// ── openSQLite creates the directory if it doesn't exist ─────────────────────

func TestOpenSQLiteCreatesParentDirectory(t *testing.T) {
base := t.TempDir()
// Nested path that doesn't exist yet.
path := filepath.Join(base, "sub", "dir", "faultline.db")
st, err := openSQLite(path)
if err != nil {
t.Fatalf("openSQLite with missing parent dir: %v", err)
}
defer st.Close()

// Verify the file was created.
if _, err := os.Stat(path); err != nil {
t.Errorf("expected db file to exist at %s: %v", path, err)
}
}

// ── migrate is idempotent ─────────────────────────────────────────────────────

func TestMigrateIsIdempotent(t *testing.T) {
path := filepath.Join(t.TempDir(), "faultline.db")
// Open twice — second open will call migrate again on an already-migrated db.
st1, err := openSQLite(path)
if err != nil {
t.Fatalf("first openSQLite: %v", err)
}
st1.Close()

st2, err := openSQLite(path)
if err != nil {
t.Fatalf("second openSQLite (idempotent migrate): %v", err)
}
defer st2.Close()
}
@jacoblehr
Copy link
Copy Markdown
Contributor

@copilot apply changes based on the comments in this thread

Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 16, 2026

@copilot apply changes based on the comments in this thread

Applied gofmt to all five affected files (internal/trace/trace_test.go, internal/output/output_test.go, internal/output/output_trace_test.go, internal/renderer/renderer_test.go, internal/store/sqlite_extra_test.go) in c816dcc. All tests still pass.

Copilot AI requested a review from jacoblehr May 16, 2026 00:25
@jacoblehr jacoblehr merged commit da0dfbc into main May 16, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants