Skip to content

fix: code quality and test integrity - #3

Closed
tomdavidson wants to merge 1 commit into
mainfrom
fix/code-quality-and-tests
Closed

fix: code quality and test integrity#3
tomdavidson wants to merge 1 commit into
mainfrom
fix/code-quality-and-tests

Conversation

@tomdavidson

Copy link
Copy Markdown
Owner

Addresses the code quality and test integrity issues identified in review.

Bug fixes

linter::lint() — sort was broken across multiple files

The comparator sorted by span.offset() alone, which interleaved diagnostics from different files when their byte offsets collided. Fixed to sort by file_path() first, then span.offset().

// Before
diagnostics.sort_by(|a, b| a.span.offset().cmp(&b.span.offset()));

// After
diagnostics.sort_by(|a, b| {
    a.file_path()
        .cmp(b.file_path())
        .then_with(|| a.span.offset().cmp(&b.span.offset()))
});

is_valid_identifier() — leading hyphen was accepted

GitHub Actions job IDs must start with a letter or underscore; a leading - is invalid. The old check included || c == '-' for the first character. Removed. Two new tests cover this: leading_hyphen_job_id_invalid and hyphen_in_middle_of_job_id_valid.

Code quality

fuzz_regression removed from public API

lib.rs exported fuzz_regression as pub, leaking test infrastructure into the library's public surface. Changed to pub(crate).

Dead job_count variable removed

check_circular_needs computed let job_count = workflow.jobs.len() and then immediately suppressed the warning with let _ = job_count. Both lines removed.

ignore_patterns documented as substring matching

Added doc comment to LintConfig.ignore_patterns making it explicit that these are plain substring matches, not globs. This prevents users from writing node_modules/** and expecting glob semantics.

Test integrity

Magic-number aggregate test replaced

invalid_directory_produces_findings asserted diagnostics.len() >= 15. A rule regression producing 16 diagnostics instead of the expected 18 would silently pass. Replaced with invalid_directory_has_expected_rules which enumerates all 18 expected rule names explicitly.

Severity helper + assertion added

New has_rule_with_severity() helper in the integration test harness. The no_jobs_detected test now asserts the diagnostic is Severity::Error, catching any accidental demotion to Warning. The unit test for no_jobs in jobs.rs does the same.

What is NOT in this PR

The following issues from the review require more context or separate work:

  • deny.toml configuration (licenses + advisories) — needs policy decision
  • Crate description/keywords/categories metadata — needs copy decision
  • #![warn(missing_docs)] enforcement — worthwhile but large surface area
  • Snapshot tests for diagnostic rendering — needs insta added as dev-dependency
  • Glob support for ignore_patterns — needs globset and a semver-visible behaviour change

- Fix sort in linter::lint() to sort by file path then offset (was offset-only,
  causing diagnostics from different files to interleave incorrectly)
- Fix is_valid_identifier() to reject leading hyphen in job IDs (GitHub
  Actions requires job IDs to start with a letter or underscore)
- Remove dead `job_count` variable and its `let _ = job_count` suppression
  in check_circular_needs()
- Move fuzz_regression module from pub to pub(crate) so test infrastructure
  does not leak into the public library API
- Document ignore_patterns as substring matching (not glob) in LintConfig
- Add test for leading-hyphen job ID validation
- Add severity assertions to no_jobs test (must be Error, not Warning)
- Replace magic-number aggregate test (>= 15) with explicit rule enumeration
@tomdavidson
tomdavidson deleted the fix/code-quality-and-tests branch April 30, 2026 22:52
@tomdavidson
tomdavidson restored the fix/code-quality-and-tests branch April 30, 2026 22:52
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.

1 participant