feat(engine): add //nomutant directive for inline mutation suppression#279
Open
matuszeg wants to merge 9 commits intogo-gremlins:mainfrom
Open
feat(engine): add //nomutant directive for inline mutation suppression#279matuszeg wants to merge 9 commits intogo-gremlins:mainfrom
matuszeg wants to merge 9 commits intogo-gremlins:mainfrom
Conversation
Introduces a //nomutant comment directive supporting four scopes: end-of-line, end-of-line typed, block-scope (above a func or single statement), and file-scope (above the package clause). Suppressed mutants are emitted with status SKIPPED so they remain visible in the report. Closes go-gremlins#180
Adds tests for nested directives, directive-vs-coverage precedence, directive coexistence with diff-mode, and adjacent typed filters. Switches block-scope nesting from "innermost wins" to additive composition so inner directives augment rather than replace outer ones. Documents the new nesting semantics.
…l flow Adds tests for: partial typed filters splitting mutator types from a single shared token (e.g. '<' produces both ConditionalsBoundary and ConditionalsNegation), block-scope attachment to an if-statement (verifying largest-span attachment picks the IfStmt, not a sub-expression), and end-of-line directives suppressing every applicable operator on a multi-token line.
Adds the missing YAML front matter to nomutant-directive.md (matching the docs/docs/usage/mutations/*.md convention) and rewraps the new footnote in configuration.md to the 80-character line limit.
The YAML front matter "title" already provides the page heading when rendered by mkdocs-material; keeping a body H1 alongside it produces two top-level headings, which Codacy flags as a markdownlint violation on new files.
Removes the YAML front matter and uses a plain "# Nomutant directive" H1, matching the structure of usage/ci/docker.md and avoiding both the multiple-top-level-headings warning and the MD001 heading-increment warning that arose from omitting an H1 entirely.
Adds YAML front matter with a title that exactly matches the body H1, mirroring the structure used by every recently-added docs page under docs/docs/usage/mutations/. The previous attempt at front matter used a title string that differed from the body H1, which appears to have been why markdownlint MD025 flagged it as "multiple top-level headings" while the mutations pages with identical title/H1 text are not flagged.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #279 +/- ##
==========================================
+ Coverage 87.35% 87.87% +0.51%
==========================================
Files 25 26 +1
Lines 1360 1484 +124
==========================================
+ Hits 1188 1304 +116
- Misses 141 145 +4
- Partials 31 35 +4
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
…code Codecov flagged four uncovered lines in internal/engine/directives.go. Two of them were genuinely missing tests — the nil-receiver guard in isSuppressed and the empty-name "continue" inside parseDirective's comma-split loop — and are now exercised by new unit tests. The other two were a *ast.Comment guard inside both collectTokenLines and largestNodeStartingAtLine that turn out to be unreachable, because the preceding *ast.CommentGroup guard already returns false from the ast.Inspect callback and ast.Inspect therefore never descends into the CommentGroup's *ast.Comment children. Removed both as dead code and noted in a comment why no Comment guard is needed.
Merged
3 tasks
test(engine): cover remaining directives.go branches and remove dead code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Proposed changes
Implements inline
//nomutantdirectives, requested in #180.The directive supports four scopes:
a := b + c //nomutanta := b + c //nomutant:arithmetic-base,invert-bitwise//nomutanton its own line above a func or single statement; applies to that AST node and everything inside it.//nomutantimmediately before the package clause; suppresses every mutation in the file.Suppressed mutants are emitted with status
SKIPPED(the same status diff-mode already uses for unchanged code), so the directive's effect remains visible in the report and users can audit which suppressions fired.Closes #180
Types of changes
Checklist
make all)Further comments
A few design decisions worth flagging for review:
mutator.Skippedrather than introducing a new status. Diff-mode already uses Skipped for "we know this won't run," and an inline directive is semantically the same kind of "explicit skip." Avoiding a new enum value keeps the report layer untouched. If reviewers prefer a distinctSkippedReasonfield onMutatorto disambiguate diff-skipped vs. directive-skipped, happy to add it.//nomutant:arithmetic-baseinside a//nomutant:invert-bitwiseblock (the user's two requests should compose, not have the inner replace the outer). Documented indocs/docs/usage/nomutant-directive.md.//nomutant:with no types, or//nomutant:bogus-type) are ignored with a warning, not panicked or treated as syntax errors. This makes it safe to add or rename directives without breaking builds.configuration.MutantTypeEnabledKeyminus themutants.*.enabledframing), so there is one source of truth — adding a new mutator type automatically makes its config key valid in directives.Self-mutation testing (
gremlins unleash --dry-runon this repo) still passes with 94.47% mutator coverage. Manually inserting a//nomutantininternal/report/report.go:179producesSKIPPEDmutants in the report as expected.