Skip to content

test: strengthen weak assertions and add presentation layer coverage#586

Merged
carlos-alm merged 3 commits intomainfrom
fix/test-health-improvements
Mar 24, 2026
Merged

test: strengthen weak assertions and add presentation layer coverage#586
carlos-alm merged 3 commits intomainfrom
fix/test-health-improvements

Conversation

@carlos-alm
Copy link
Copy Markdown
Contributor

Summary

  • Strengthen 8 weak assertions across 5 test files — tests that used only toBeDefined() now also validate types, properties, and values
  • Add 56 new presentation layer tests in tests/presentation/ covering 4 new test files:
    • table.test.jsformatTable alignment, padding, truncation; truncEnd edge cases
    • colors.test.js — node/role/community color constant completeness and hex format validation
    • result-formatter.test.js — JSON, NDJSON, CSV, table output dispatch; CSV escaping; object flattening
    • queries-cli.test.jsinspect.js (where, queryName, context, children, explain, implementations, interfaces), path.js, exports.js, overview.js (moduleMap, roles) via mocked domain data
  • False positive cleanup noted: the 3 "leaky temp dir" tests (incr-edge-gap, incremental-edge-parity, resolution/parity) actually use try/finally cleanup — no changes needed

Test plan

  • All 56 new presentation tests pass (npx vitest run tests/presentation/)
  • All 5 modified test files pass with strengthened assertions
  • Full suite: 183/183 pass across touched files; remaining failures are pre-existing WASM grammar issues in non-JS languages

Strengthen 8 tests that used only toBeDefined() as their sole assertion —
add type checks, property assertions, and value validations so regressions
are caught.

Add 56 new tests covering the previously untested presentation layer:
- table.ts: formatTable alignment, padding, truncation, truncEnd edge cases
- colors.ts: node/role/community color constant validation
- result-formatter.js: JSON, NDJSON, CSV, table output dispatch + CSV escaping
- queries-cli: inspect, path, exports, overview modules via mocked domain data
@claude
Copy link
Copy Markdown

claude bot commented Mar 24, 2026

Claude finished @carlos-alm's task —— View job


Code Review Complete ✅

Reviewing PR #586: test improvements and presentation layer coverage.

Root Cause Analysis

Problem Being Solved: This PR addresses test quality issues — 8 tests that used only toBeDefined() as their sole assertion, plus lack of coverage for the presentation layer (table formatting, colors, CLI output formatters).

Why This Approach: The approach is sound — strengthening weak assertions and adding missing test coverage is exactly what should be done. The "false positive cleanup" note about temp dir tests indicates good analysis.

Risk Assessment: Very low risk. Pure test additions with no behavior changes to production code.

Backlog Compliance

  • Zero-dep: ✅ — No new runtime dependencies added
  • Foundation-aligned: ✅ — Pure test improvements, no violations of core principles
  • Problem-fit: 3/5 — Improves code quality and prevents regressions, but doesn't directly address the "lost AI agents" problem
  • Breaking: No — Test-only changes, no API/behavior modifications
  • Tier: 1 (zero-dep ✅ + foundation-aligned ✅)

Review Summary

✅ Strengths

  • Genuine test strengthening: All 8 "strengthened assertions" actually add meaningful validation (expect(def.kind).toBe('function'), type checks, property assertions)
  • Excellent new test coverage: 56 well-architected tests covering previously untested presentation layer
  • High-quality test design: Proper mocking, edge cases, cleanup, Unicode handling
  • No configuration relaxation: Zero tolerance for rule weakening maintained
  • Conservative scope: Test-only changes with no production code modifications

✅ Technical Quality

  • colors.test.js: Validates hex formats, completeness, uniqueness constraints
  • table.test.js: Comprehensive formatting, alignment, truncation edge cases
  • result-formatter.test.js: JSON/NDJSON/CSV output dispatch with proper mocking
  • queries-cli.test.js: Complex CLI presentation layer coverage with controlled test data

🔍 Minor Observations

  • Large test addition (822 lines) but well-organized across focused files
  • Test quality significantly higher than typical "coverage-driven" additions
  • Claims about test numbers are accurate (56 new tests verified)

Final Recommendation

  • Rating: ⭐⭐⭐⭐☆ (4/5)
  • Action: APPROVE
  • Reasoning: High-quality test improvements that strengthen regression protection without any concerning changes. The presentation layer desperately needed this coverage, and the execution is exemplary. Minor deduction only because this doesn't directly advance the core mission of helping AI agents navigate codebases.

This is exactly the kind of foundational quality work that should be approved quickly and serve as a template for future test improvements.


@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 24, 2026

Greptile Summary

This PR strengthens 8 previously weak toBeDefined() assertions across 5 existing test files and adds 56 new unit tests across 4 new tests/presentation/ files, filling a gap in coverage for the table.js, colors.ts, result-formatter.js, and queries-cli/ presentation-layer modules.

Changes by area:

  • Strengthened assertions (cochange, context, dataflow, javascript, embedder-search): each previously bare toBeDefined() now also verifies the type, kind, shape, or numeric value of the returned property — materially improving regression detection.
  • colors.test.js: validates presence, hex-format correctness, and uniqueness of all three color constant exports. Assertions are verified against the live values in colors.ts.
  • table.test.js: pure-function tests for formatTable and truncEnd — alignment, indentation, separator-width math, empty rows, and graceful handling of missing cells all checked and correct.
  • result-formatter.test.js: covers the full outputResult dispatch path (JSON, NDJSON, CSV, table), CSV escaping rules, and nested-object flattening. The config and paginate mocks correctly prevent any disk I/O.
  • queries-cli.test.js: the largest addition (628 lines). All four CLI modules (inspect.js, path.js, exports.js, overview.js) are tested via a shared domain-layer mock. The dual-mock pattern for the result-formatter compat re-export and the canonical path (added in response to a previous review) keeps the tests resilient to future import-path refactors. The error-branch negative assertion on symbolPath is also present.

Confidence Score: 5/5

  • Test-only PR — no production code is modified; safe to merge.
  • All assertions were verified against the actual source implementations (table.ts, colors.ts, result-formatter.js, exports.js, overview.js, inspect.js, path.js). The mock patterns are correct (vi.mock hoisting + dynamic import, dual-path mock, console.log spy), the math in the separator-width test is accurate, and the CSV escaping assertions match the escapeCsv implementation. No production code is touched and the PR description confirms 183/183 tests pass.
  • No files require special attention.

Important Files Changed

Filename Overview
tests/presentation/colors.test.js New tests validating node/role/community color constants for presence, hex format, and uniqueness. All assertions align with the actual colors.ts values.
tests/presentation/table.test.js New tests for formatTable and truncEnd; covers alignment, indentation, empty rows, missing cells, and separator width calculation — all verified against table.ts source.
tests/presentation/result-formatter.test.js New tests for outputResult dispatch (JSON, NDJSON, CSV, table) plus CSV escaping and nested-object flattening; mocks config and paginate to avoid I/O, all assertions match the source implementation.
tests/presentation/queries-cli.test.js Large new test file (628 lines) covering inspect.js, path.js, exports.js, and overview.js. Mocks domain layer correctly; dual-mock pattern (compat re-export + canonical path) is addressed. One observable discrepancy in queryName output labels noted.

Sequence Diagram

sequenceDiagram
    participant T as Test (queries-cli.test.js)
    participant V as Vitest (vi.mock)
    participant CLI as inspect.js / path.js / exports.js / overview.js
    participant DM as domain/queries.js (mocked)
    participant RF as result-formatter.js (mocked)

    Note over T,V: vi.mock hoisted before imports
    V->>DM: register mock (mocks object)
    V->>RF: register mock (outputResult → false)

    T->>CLI: await import(inspect.js)
    CLI->>DM: (resolved via mock)
    CLI->>RF: (resolved via mock)

    T->>T: beforeEach — spy console.log, capture lines[]

    T->>DM: mocks.whereData.mockReturnValue({...})
    T->>CLI: where('foo', '/db')
    CLI->>DM: whereData('foo', '/db', {})
    DM-->>CLI: { mode: 'symbol', results: [...] }
    CLI->>RF: outputResult(data, 'results', {}) → false
    CLI->>CLI: console.log(formatted output)
    CLI-->>T: lines[] captured via spy

    T->>T: expect(output()).toContain(...)
    T->>T: afterEach — vi.restoreAllMocks()
Loading

Reviews (2): Last reviewed commit: "fix: address review feedback — negative ..." | Re-trigger Greptile

Comment on lines +549 to +553
file: 'lib.js',
totalExported: 3,
totalInternal: 0,
totalUnused: 1,
results: [
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 symbolPath error test doesn't assert result returns after printing

The printNotFound/error path in symbolPath uses console.log(data.error) and then an early return, but the test only checks that the error string was printed — it does not assert that subsequent rendering code (path steps, etc.) was not called. This leaves the door open for a future regression where the function continues past the error branch.

Consider adding a negative assertion to pin this:

Suggested change
file: 'lib.js',
totalExported: 3,
totalInternal: 0,
totalUnused: 1,
results: [
it('prints error when present', () => {
mocks.pathData.mockReturnValue({ error: 'Symbol not found' });
symbolPath('x', 'y', '/db');
expect(output()).toContain('Symbol not found');
// ensure we stopped after the error — no path-rendering output
expect(output()).not.toContain('Path from');
});

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added the negative assertion \ to ensure the error branch exits before any path-rendering output. Committed in dd29a60.

Comment on lines +196 to +198
callees: [{ kind: 'function', name: 'ast', file: 'a.js', line: 1, summary: 'parse AST' }],
callers: [{ kind: 'function', name: 'main', file: 'm.js', line: 10 }],
implementors: [],
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Mock targets the compat re-export, not the canonical module

vi.mock('../../src/infrastructure/result-formatter.js', ...) works today because inspect.js, path.js, exports.js, and overview.js all import outputResult from ../../infrastructure/result-formatter.js — which is a thin backward-compat re-export of src/presentation/result-formatter.js.

If a future refactor moves those four files to import directly from the presentation path (the canonical location), this mock will silently stop working and the tests will start hitting real I/O without any indication. Mocking the canonical path is safer:

Suggested change
callees: [{ kind: 'function', name: 'ast', file: 'a.js', line: 1, summary: 'parse AST' }],
callers: [{ kind: 'function', name: 'main', file: 'm.js', line: 10 }],
implementors: [],
vi.mock('../../src/presentation/result-formatter.js', () => ({
outputResult: () => false, // never short-circuit — always render CLI output
}));

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added a second vi.mock targeting the canonical presentation/result-formatter.js path alongside the existing compat re-export mock. This way, if the source files are ever refactored to import from the canonical path directly, the tests will still intercept correctly. Committed in dd29a60.

@carlos-alm
Copy link
Copy Markdown
Contributor Author

Addressed Greptile's feedback in dd29a60:

  1. P1 — symbolPath negative assertion: Added expect(output()).not.toContain('Path from') to verify the error branch suppresses path rendering.
  2. P2 — mock targets compat re-export: Added a second vi.mock for the canonical presentation/result-formatter.js path so tests remain correct if imports are refactored.
  3. P2 — hard-coded palette count: Changed toHaveLength(12) to toBeGreaterThanOrEqual(12) so intentional palette growth won't break the test.

All tests pass locally.

@carlos-alm
Copy link
Copy Markdown
Contributor Author

@greptileai

1 similar comment
@carlos-alm
Copy link
Copy Markdown
Contributor Author

@greptileai

@carlos-alm carlos-alm merged commit 5a97a72 into main Mar 24, 2026
25 checks passed
@carlos-alm carlos-alm deleted the fix/test-health-improvements branch March 24, 2026 07:56
@github-actions github-actions bot locked and limited conversation to collaborators Mar 24, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant