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.



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

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
66
67
68
# File 'lib/simplecov/directive.rb', line 56

def self.disabled_ranges(src_lines)
  lines = src_lines.to_a
  ranges = CATEGORIES.to_h do |category|
    empty = [] # : Array[Range[Integer]]
    [category, empty]
  end
  open_starts = {} # : Hash[Symbol, Integer]

  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.



155
156
157
158
159
160
161
162
163
164
165
# File 'lib/simplecov/directive.rb', line 155

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)


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

def disabled?
  mode == :disable
end

#inline?Boolean

Returns:

  • (Boolean)


148
149
150
# File 'lib/simplecov/directive.rb', line 148

def inline?
  @inline
end