Class: SimpleCov::Directive

Inherits:
Object
  • Object
show all
Defined in:
lib/simplecov/directive.rb

Overview

Parses # simplecov:disable / # simplecov:enable directive comments.

Two forms are supported:

Block form (the directive is the entire comment on its own line) opens a region that runs until the matching # simplecov:enable:

# simplecov:disable line
...
# simplecov:enable line

Inline form (the directive trails real code on the same line) only affects that single line and does not need to be re-enabled:

raise "absurd" # simplecov:disable

Categories are :line, :branch, and :method. They may be combined with commas. Omitting categories targets all three.

Any text after the directive (and the optional category list) is treated as a free-form reason and discarded:

# simplecov:disable line not worth testing this glue

As a consequence, an unrecognised category name silently falls into the reason bucket. # simplecov:disable cyclomatic is parsed as the bare form (disable everything) with reason "cyclomatic" — a deliberate over-disable so the typo is visible in the report rather than silently disabling nothing.

Comment extraction goes through Ripper.lex so directive markers inside string literals or heredocs are correctly ignored.

Constant Summary collapse

CATEGORIES =
%i[line branch method].freeze
CATEGORY_PATTERN =
"(?:#{CATEGORIES.join('|')})".freeze
CATEGORIES_PATTERN =
"(?:#{CATEGORY_PATTERN}(?:\\s*,\\s*#{CATEGORY_PATTERN})*)".freeze
PATTERN =
/
  \#\s*simplecov\s*:\s*
  (?<mode>disable|enable)\b
  (?:\s+(?<categories>#{CATEGORIES_PATTERN}))?
  .*?
  \s*\z
/x

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(line_number:, mode:, categories:, inline:) ⇒ Directive

Returns a new instance of Directive.



132
133
134
135
136
137
# File 'lib/simplecov/directive.rb', line 132

def initialize(line_number:, mode:, categories:, inline:)
  @line_number = line_number
  @mode        = mode
  @categories  = categories
  @inline      = inline
end

Instance Attribute Details

#categoriesObject (readonly)

Returns the value of attribute categories.



51
52
53
# File 'lib/simplecov/directive.rb', line 51

def categories
  @categories
end

#line_numberObject (readonly)

Returns the value of attribute line_number.



51
52
53
# File 'lib/simplecov/directive.rb', line 51

def line_number
  @line_number
end

#modeObject (readonly)

Returns the value of attribute mode.



51
52
53
# File 'lib/simplecov/directive.rb', line 51

def mode
  @mode
end

Class Method Details

.disabled_ranges(src_lines) ⇒ Object

Walk an array of source lines and return the disabled line ranges per category as { line: [Range, ...], branch: [...], method: [...] }. An unclosed disable block extends to the end of the file.



56
57
58
59
60
61
62
63
64
65
# File 'lib/simplecov/directive.rb', line 56

def self.disabled_ranges(src_lines)
  lines = src_lines.to_a
  ranges = CATEGORIES.to_h { |category| [category, []] }
  open_starts = {}

  directives_in(lines).each { |directive| directive.apply(ranges, open_starts) }
  open_starts.each { |category, start| ranges[category] << (start..lines.size) }

  ranges
end

Instance Method Details

#apply(ranges, open_starts) ⇒ Object

Apply this directive's effect to the in-flight per-category state. Inline directives mark just their line; block disables open a region; block enables close one. Re-opening an already-open block is a no-op.



150
151
152
153
154
155
156
157
158
159
160
# File 'lib/simplecov/directive.rb', line 150

def apply(ranges, open_starts)
  categories.each do |category|
    if inline?
      ranges[category] << (line_number..line_number) if disabled?
    elsif disabled?
      open_starts[category] ||= line_number
    elsif (start = open_starts.delete(category))
      ranges[category] << (start..line_number)
    end
  end
end

#disabled?Boolean

Returns:

  • (Boolean)


139
140
141
# File 'lib/simplecov/directive.rb', line 139

def disabled?
  mode == :disable
end

#inline?Boolean

Returns:

  • (Boolean)


143
144
145
# File 'lib/simplecov/directive.rb', line 143

def inline?
  @inline
end