Add simplecov:disable / simplecov:enable directive comments#1179
Merged
Conversation
f0888f5 to
3463d22
Compare
ed2b2c1 to
389df23
Compare
Mirror RuboCop's directive style for selectively skipping coverage of specific lines, branches, or methods: # simplecov:disable line (block; closes at matching :enable) # simplecov:disable method, branch # simplecov:disable (no args = all three categories) # simplecov:disable line some reason (any trailing text becomes a reason) # simplecov:enable raise "absurd" # simplecov:disable (inline; just this line) Block directives sit on their own line (possibly indented) and open a region until the matching `# simplecov:enable` for the same category; unclosed disables run to end of file. Inline directives trail real code and only affect that one line. Categories are independently tracked: `# simplecov:disable line` skips those lines from line coverage but leaves any branches and methods on those lines reported normally. The bare form is a shorthand for all three. Trailing text after the directive is treated as a free-form reason and discarded — no `--` separator or other marker is required. As a consequence, an unrecognised category name silently falls into the reason bucket and the bare form takes effect (a deliberate over-disable so typos surface in the report rather than silently disabling nothing). Comment extraction goes through `Ripper.lex`, so directive markers that appear inside string literals or heredocs are correctly ignored. SourceFile collects the per-category disabled ranges from Directive, then applies them in process_skipped_lines, process_skipped_branches, and a new process_skipped_methods. Method gains a direct skipped! flag and overlaps_with? helper paralleling Branch's API. Deprecate `# :nocov:` (and the configurable `SimpleCov.nocov_token`) in favor of the new directives. Each file that still uses `# :nocov:` emits a one-time deprecation warning to stderr at load time pointing at the recommended `# simplecov:disable` / `# simplecov:enable` replacement. The toggle continues to work; it will be removed in a future release.
389df23 to
bb060d0
Compare
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.
Alternative to #1068 implementing the directive shape proposed at #1068 (comment):
Categories are tracked independently.
# simplecov:disable lineskips those lines from line coverage but still reports any branches and methods that overlap them.# simplecov:disable methodflags the method directly without depending on its lines being skipped, which is whyMethodgains askipped!setter and anoverlaps_with?helper alongside the existing inferred-from-linesskipped?.Anything trailing the directive is treated as a free-form reason and discarded. The trade-off is that an unrecognised category name silently falls into the reason bucket and the bare form takes effect, so
# simplecov:disable cyclomaticends up over-disabling instead of being rejected. That's a deliberate fail-mode: over-disabling shows up loud in the report (a whole file with no covered lines), whereas silently disabling nothing wouldn't, so typos are easier to catch.Comment extraction goes through
Ripper.lex. That keeps the parser honest about Ruby syntax: a directive marker sitting inside a double-quoted string, a single-quoted string, an interpolated string, or a heredoc body is not a directive, and we no longer pretend otherwise. The# prefix # simplecov:disable linecase (whole line is one comment, but the directive isn't at the start of it) is treated as inline, since the directive's column doesn't sit at the start of the comment text.The new directives subsume what
# :nocov:did, so it's deprecated (as is the the configurableSimpleCov.nocov_token). The toggle continues to work but each file that uses it now emits a one-time deprecation warning to stderr at load time pointing the user at the# simplecov:disable/# simplecov:enablereplacement. The plan is to remove:nocov:entirely in a future release.The shape of the implementation:
SimpleCov::DirectiveexposesDirective.disabled_ranges(src_lines)which walks the source viaRipper.lex, parses each comment token against a single regex, and returns{ line: [Range, ...], branch: [...], method: [...] }. The Directive value object itself is mostly an internal accumulator fordisabled_ranges; users of the class don't need to reach for it.LinesClassifier#classifyconsults the line ranges so thatSimulateCoverage(used for tracked-but-unloaded files) marks disabled lines asNOT_RELEVANT, matching the behaviour:nocov:already had for that path. Both this file andSourceFilerequire_relative "directive"directly so that requiring either one in isolation doesn't blow up.SourceFilelazily memoises per-category ranges and consumes them in the threeprocess_skipped_*methods. Branches and methods both use overlap-with-range checks, so a directive that sits inside a method body or a branch body still skips the enclosing construct.process_skipped_branchesalso consultsbranch.report_lineso an inline directive on the condition line of a multi-lineif(where the arm body's source range starts on a different line) still skips the arm.SourceFile#warn_no_cov_deprecationis the deprecation hook. It dedupes per-filename via a class-levelSet(SimpleCov::SourceFile.nocov_warned) so noisy projects only see one line per file rather than one per occurrence.