nano-fast-box 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/nano-fast-box.gemspec +12 -0
- data/simplecov-0.22.0/CHANGELOG.md +191 -0
- data/simplecov-0.22.0/LICENSE +20 -0
- data/simplecov-0.22.0/README.md +974 -0
- data/simplecov-0.22.0/doc/alternate-formatters.md +71 -0
- data/simplecov-0.22.0/doc/commercial-services.md +25 -0
- data/simplecov-0.22.0/doc/editor-integration.md +18 -0
- data/simplecov-0.22.0/lib/minitest/simplecov_plugin.rb +15 -0
- data/simplecov-0.22.0/lib/simplecov/combine/branches_combiner.rb +32 -0
- data/simplecov-0.22.0/lib/simplecov/combine/files_combiner.rb +24 -0
- data/simplecov-0.22.0/lib/simplecov/combine/lines_combiner.rb +43 -0
- data/simplecov-0.22.0/lib/simplecov/combine/results_combiner.rb +60 -0
- data/simplecov-0.22.0/lib/simplecov/combine.rb +30 -0
- data/simplecov-0.22.0/lib/simplecov/command_guesser.rb +64 -0
- data/simplecov-0.22.0/lib/simplecov/configuration.rb +500 -0
- data/simplecov-0.22.0/lib/simplecov/coverage_statistics.rb +56 -0
- data/simplecov-0.22.0/lib/simplecov/default_formatter.rb +20 -0
- data/simplecov-0.22.0/lib/simplecov/defaults.rb +53 -0
- data/simplecov-0.22.0/lib/simplecov/exit_codes/exit_code_handling.rb +29 -0
- data/simplecov-0.22.0/lib/simplecov/exit_codes/maximum_coverage_drop_check.rb +83 -0
- data/simplecov-0.22.0/lib/simplecov/exit_codes/minimum_coverage_by_file_check.rb +54 -0
- data/simplecov-0.22.0/lib/simplecov/exit_codes/minimum_overall_coverage_check.rb +53 -0
- data/simplecov-0.22.0/lib/simplecov/exit_codes.rb +15 -0
- data/simplecov-0.22.0/lib/simplecov/file_list.rb +120 -0
- data/simplecov-0.22.0/lib/simplecov/filter.rb +94 -0
- data/simplecov-0.22.0/lib/simplecov/formatter/multi_formatter.rb +32 -0
- data/simplecov-0.22.0/lib/simplecov/formatter/simple_formatter.rb +25 -0
- data/simplecov-0.22.0/lib/simplecov/formatter.rb +10 -0
- data/simplecov-0.22.0/lib/simplecov/last_run.rb +28 -0
- data/simplecov-0.22.0/lib/simplecov/lines_classifier.rb +48 -0
- data/simplecov-0.22.0/lib/simplecov/load_global_config.rb +8 -0
- data/simplecov-0.22.0/lib/simplecov/no_defaults.rb +4 -0
- data/simplecov-0.22.0/lib/simplecov/process.rb +19 -0
- data/simplecov-0.22.0/lib/simplecov/profiles/bundler_filter.rb +5 -0
- data/simplecov-0.22.0/lib/simplecov/profiles/hidden_filter.rb +5 -0
- data/simplecov-0.22.0/lib/simplecov/profiles/rails.rb +18 -0
- data/simplecov-0.22.0/lib/simplecov/profiles/root_filter.rb +10 -0
- data/simplecov-0.22.0/lib/simplecov/profiles/test_frameworks.rb +8 -0
- data/simplecov-0.22.0/lib/simplecov/profiles.rb +35 -0
- data/simplecov-0.22.0/lib/simplecov/result.rb +94 -0
- data/simplecov-0.22.0/lib/simplecov/result_adapter.rb +30 -0
- data/simplecov-0.22.0/lib/simplecov/result_merger.rb +194 -0
- data/simplecov-0.22.0/lib/simplecov/simulate_coverage.rb +29 -0
- data/simplecov-0.22.0/lib/simplecov/source_file/branch.rb +84 -0
- data/simplecov-0.22.0/lib/simplecov/source_file/line.rb +72 -0
- data/simplecov-0.22.0/lib/simplecov/source_file.rb +355 -0
- data/simplecov-0.22.0/lib/simplecov/useless_results_remover.rb +18 -0
- data/simplecov-0.22.0/lib/simplecov/version.rb +5 -0
- data/simplecov-0.22.0/lib/simplecov.rb +470 -0
- metadata +90 -0
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SimpleCov
|
|
4
|
+
#
|
|
5
|
+
# Representation of a source file including it's coverage data, source code,
|
|
6
|
+
# source lines and featuring helpers to interpret that data.
|
|
7
|
+
#
|
|
8
|
+
class SourceFile
|
|
9
|
+
# The full path to this source file (e.g. /User/colszowka/projects/simplecov/lib/simplecov/source_file.rb)
|
|
10
|
+
attr_reader :filename
|
|
11
|
+
# The array of coverage data received from the Coverage.result
|
|
12
|
+
attr_reader :coverage_data
|
|
13
|
+
|
|
14
|
+
def initialize(filename, coverage_data)
|
|
15
|
+
@filename = filename
|
|
16
|
+
@coverage_data = coverage_data
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# The path to this source file relative to the projects directory
|
|
20
|
+
def project_filename
|
|
21
|
+
@filename.delete_prefix(SimpleCov.root)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# The source code for this file. Aliased as :source
|
|
25
|
+
def src
|
|
26
|
+
# We intentionally read source code lazily to
|
|
27
|
+
# suppress reading unused source code.
|
|
28
|
+
@src ||= load_source
|
|
29
|
+
end
|
|
30
|
+
alias source src
|
|
31
|
+
|
|
32
|
+
def coverage_statistics
|
|
33
|
+
@coverage_statistics ||=
|
|
34
|
+
{
|
|
35
|
+
**line_coverage_statistics,
|
|
36
|
+
**branch_coverage_statistics
|
|
37
|
+
}
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Returns all source lines for this file as instances of SimpleCov::SourceFile::Line,
|
|
41
|
+
# and thus including coverage data. Aliased as :source_lines
|
|
42
|
+
def lines
|
|
43
|
+
@lines ||= build_lines
|
|
44
|
+
end
|
|
45
|
+
alias source_lines lines
|
|
46
|
+
|
|
47
|
+
# Returns all covered lines as SimpleCov::SourceFile::Line
|
|
48
|
+
def covered_lines
|
|
49
|
+
@covered_lines ||= lines.select(&:covered?)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Returns all lines that should have been, but were not covered
|
|
53
|
+
# as instances of SimpleCov::SourceFile::Line
|
|
54
|
+
def missed_lines
|
|
55
|
+
@missed_lines ||= lines.select(&:missed?)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Returns all lines that are not relevant for coverage as
|
|
59
|
+
# SimpleCov::SourceFile::Line instances
|
|
60
|
+
def never_lines
|
|
61
|
+
@never_lines ||= lines.select(&:never?)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Returns all lines that were skipped as SimpleCov::SourceFile::Line instances
|
|
65
|
+
def skipped_lines
|
|
66
|
+
@skipped_lines ||= lines.select(&:skipped?)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Returns the number of relevant lines (covered + missed)
|
|
70
|
+
def lines_of_code
|
|
71
|
+
coverage_statistics[:line]&.total
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Access SimpleCov::SourceFile::Line source lines by line number
|
|
75
|
+
def line(number)
|
|
76
|
+
lines[number - 1]
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# The coverage for this file in percent. 0 if the file has no coverage lines
|
|
80
|
+
def covered_percent
|
|
81
|
+
coverage_statistics[:line]&.percent
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def covered_strength
|
|
85
|
+
coverage_statistics[:line]&.strength
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def no_lines?
|
|
89
|
+
lines.length.zero? || (lines.length == never_lines.size)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def relevant_lines
|
|
93
|
+
lines.size - never_lines.size - skipped_lines.size
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
#
|
|
97
|
+
# Return all the branches inside current source file
|
|
98
|
+
def branches
|
|
99
|
+
@branches ||= build_branches
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def no_branches?
|
|
103
|
+
total_branches.empty?
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def branches_coverage_percent
|
|
107
|
+
coverage_statistics[:branch]&.percent
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
#
|
|
111
|
+
# Return the relevant branches to source file
|
|
112
|
+
def total_branches
|
|
113
|
+
@total_branches ||= covered_branches + missed_branches
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
#
|
|
117
|
+
# Return hash with key of line number and branch coverage count as value
|
|
118
|
+
def branches_report
|
|
119
|
+
@branches_report ||= build_branches_report
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
#
|
|
123
|
+
# Select the covered branches
|
|
124
|
+
# Here we user tree schema because some conditions like case may have additional
|
|
125
|
+
# else that is not in declared inside the code but given by default by coverage report
|
|
126
|
+
#
|
|
127
|
+
# @return [Array]
|
|
128
|
+
#
|
|
129
|
+
def covered_branches
|
|
130
|
+
@covered_branches ||= branches.select(&:covered?)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
#
|
|
134
|
+
# Select the missed branches with coverage equal to zero
|
|
135
|
+
#
|
|
136
|
+
# @return [Array]
|
|
137
|
+
#
|
|
138
|
+
def missed_branches
|
|
139
|
+
@missed_branches ||= branches.select(&:missed?)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def branches_for_line(line_number)
|
|
143
|
+
branches_report.fetch(line_number, [])
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
#
|
|
147
|
+
# Check if any branches missing on given line number
|
|
148
|
+
#
|
|
149
|
+
# @param [Integer] line_number
|
|
150
|
+
#
|
|
151
|
+
# @return [Boolean]
|
|
152
|
+
#
|
|
153
|
+
def line_with_missed_branch?(line_number)
|
|
154
|
+
branches_for_line(line_number).select { |_type, count| count.zero? }.any?
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
private
|
|
158
|
+
|
|
159
|
+
# no_cov_chunks is zero indexed to work directly with the array holding the lines
|
|
160
|
+
def no_cov_chunks
|
|
161
|
+
@no_cov_chunks ||= build_no_cov_chunks
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def build_no_cov_chunks
|
|
165
|
+
no_cov_lines = src.map.with_index(1).select { |line_src, _index| LinesClassifier.no_cov_line?(line_src) }
|
|
166
|
+
|
|
167
|
+
# if we have an uneven number of nocovs we assume they go to the
|
|
168
|
+
# end of the file, the source doesn't really matter
|
|
169
|
+
# Can't deal with this within the each_slice due to differing
|
|
170
|
+
# behavior in JRuby: jruby/jruby#6048
|
|
171
|
+
no_cov_lines << ["", src.size] if no_cov_lines.size.odd?
|
|
172
|
+
|
|
173
|
+
no_cov_lines.each_slice(2).map do |(_line_src_start, index_start), (_line_src_end, index_end)|
|
|
174
|
+
index_start..index_end
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def load_source
|
|
179
|
+
lines = []
|
|
180
|
+
# The default encoding is UTF-8
|
|
181
|
+
File.open(filename, "rb:UTF-8") do |file|
|
|
182
|
+
current_line = file.gets
|
|
183
|
+
|
|
184
|
+
if shebang?(current_line)
|
|
185
|
+
lines << current_line
|
|
186
|
+
current_line = file.gets
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
read_lines(file, lines, current_line)
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
SHEBANG_REGEX = /\A#!/.freeze
|
|
194
|
+
def shebang?(line)
|
|
195
|
+
SHEBANG_REGEX.match?(line)
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def read_lines(file, lines, current_line)
|
|
199
|
+
return lines unless current_line
|
|
200
|
+
|
|
201
|
+
set_encoding_based_on_magic_comment(file, current_line)
|
|
202
|
+
lines.concat([current_line], ensure_remove_undefs(file.readlines))
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
RUBY_FILE_ENCODING_MAGIC_COMMENT_REGEX = /\A#\s*(?:-\*-)?\s*(?:en)?coding:\s*(\S+)\s*(?:-\*-)?\s*\z/.freeze
|
|
206
|
+
def set_encoding_based_on_magic_comment(file, line)
|
|
207
|
+
# Check for encoding magic comment
|
|
208
|
+
# Encoding magic comment must be placed at first line except for shebang
|
|
209
|
+
if (match = RUBY_FILE_ENCODING_MAGIC_COMMENT_REGEX.match(line))
|
|
210
|
+
file.set_encoding(match[1], "UTF-8")
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def ensure_remove_undefs(file_lines)
|
|
215
|
+
# invalid/undef replace are technically not really necessary but nice to
|
|
216
|
+
# have and work around a JRuby incompatibility. Also moved here from
|
|
217
|
+
# simplecov-html to have encoding shenaningans in one place. See #866
|
|
218
|
+
# also setting these option on `file.set_encoding` doesn't seem to work
|
|
219
|
+
# properly so it has to be done here.
|
|
220
|
+
file_lines.each do |line|
|
|
221
|
+
if line.encoding == Encoding::UTF_8
|
|
222
|
+
line
|
|
223
|
+
else
|
|
224
|
+
line.encode!("UTF-8", invalid: :replace, undef: :replace)
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
def build_lines
|
|
230
|
+
coverage_exceeding_source_warn if coverage_data["lines"].size > src.size
|
|
231
|
+
lines = src.map.with_index(1) do |src, i|
|
|
232
|
+
SimpleCov::SourceFile::Line.new(src, i, coverage_data["lines"][i - 1])
|
|
233
|
+
end
|
|
234
|
+
process_skipped_lines(lines)
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
def process_skipped_lines(lines)
|
|
238
|
+
# the array the lines are kept in is 0-based whereas the line numbers in the nocov
|
|
239
|
+
# chunks are 1-based and are expected to be like this in other parts (and it's also
|
|
240
|
+
# arguably more understandable)
|
|
241
|
+
no_cov_chunks.each { |chunk| lines[(chunk.begin - 1)..(chunk.end - 1)].each(&:skipped!) }
|
|
242
|
+
|
|
243
|
+
lines
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def lines_strength
|
|
247
|
+
lines.sum { |line| line.coverage.to_i }
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
# Warning to identify condition from Issue #56
|
|
251
|
+
def coverage_exceeding_source_warn
|
|
252
|
+
warn "Warning: coverage data provided by Coverage [#{coverage_data['lines'].size}] exceeds number of lines in #{filename} [#{src.size}]"
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
#
|
|
256
|
+
# Build full branches report
|
|
257
|
+
# Root branches represent the wrapper of all condition state that
|
|
258
|
+
# have inside the branches
|
|
259
|
+
#
|
|
260
|
+
# @return [Hash]
|
|
261
|
+
#
|
|
262
|
+
def build_branches_report
|
|
263
|
+
branches.reject(&:skipped?).each_with_object({}) do |branch, coverage_statistics|
|
|
264
|
+
coverage_statistics[branch.report_line] ||= []
|
|
265
|
+
coverage_statistics[branch.report_line] << branch.report
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
#
|
|
270
|
+
# Call recursive method that transform our static hash to array of objects
|
|
271
|
+
# @return [Array]
|
|
272
|
+
#
|
|
273
|
+
def build_branches
|
|
274
|
+
coverage_branch_data = coverage_data.fetch("branches", {})
|
|
275
|
+
branches = coverage_branch_data.flat_map do |condition, coverage_branches|
|
|
276
|
+
build_branches_from(condition, coverage_branches)
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
process_skipped_branches(branches)
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
def process_skipped_branches(branches)
|
|
283
|
+
return branches if no_cov_chunks.empty?
|
|
284
|
+
|
|
285
|
+
branches.each do |branch|
|
|
286
|
+
branch.skipped! if no_cov_chunks.any? { |no_cov_chunk| branch.overlaps_with?(no_cov_chunk) }
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
branches
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
# Since we are dumping to and loading from JSON, and we have arrays as keys those
|
|
293
|
+
# don't make their way back to us intact e.g. just as a string
|
|
294
|
+
#
|
|
295
|
+
# We should probably do something different here, but as it stands these are
|
|
296
|
+
# our data structures that we write so eval isn't _too_ bad.
|
|
297
|
+
#
|
|
298
|
+
# See #801
|
|
299
|
+
#
|
|
300
|
+
def restore_ruby_data_structure(structure)
|
|
301
|
+
# Tests use the real data structures (except for integration tests) so no need to
|
|
302
|
+
# put them through here.
|
|
303
|
+
return structure if structure.is_a?(Array)
|
|
304
|
+
|
|
305
|
+
# rubocop:disable Security/Eval
|
|
306
|
+
eval structure
|
|
307
|
+
# rubocop:enable Security/Eval
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
def build_branches_from(condition, branches)
|
|
311
|
+
# the format handed in from the coverage data is like this:
|
|
312
|
+
#
|
|
313
|
+
# [:then, 4, 6, 6, 6, 10]
|
|
314
|
+
#
|
|
315
|
+
# which is [type, id, start_line, start_col, end_line, end_col]
|
|
316
|
+
_condition_type, _condition_id, condition_start_line, * = restore_ruby_data_structure(condition)
|
|
317
|
+
|
|
318
|
+
branches.map do |branch_data, hit_count|
|
|
319
|
+
branch_data = restore_ruby_data_structure(branch_data)
|
|
320
|
+
build_branch(branch_data, hit_count, condition_start_line)
|
|
321
|
+
end
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
def build_branch(branch_data, hit_count, condition_start_line)
|
|
325
|
+
type, _id, start_line, _start_col, end_line, _end_col = branch_data
|
|
326
|
+
|
|
327
|
+
SourceFile::Branch.new(
|
|
328
|
+
start_line: start_line,
|
|
329
|
+
end_line: end_line,
|
|
330
|
+
coverage: hit_count,
|
|
331
|
+
inline: start_line == condition_start_line,
|
|
332
|
+
type: type
|
|
333
|
+
)
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
def line_coverage_statistics
|
|
337
|
+
{
|
|
338
|
+
line: CoverageStatistics.new(
|
|
339
|
+
total_strength: lines_strength,
|
|
340
|
+
covered: covered_lines.size,
|
|
341
|
+
missed: missed_lines.size
|
|
342
|
+
)
|
|
343
|
+
}
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
def branch_coverage_statistics
|
|
347
|
+
{
|
|
348
|
+
branch: CoverageStatistics.new(
|
|
349
|
+
covered: covered_branches.size,
|
|
350
|
+
missed: missed_branches.size
|
|
351
|
+
)
|
|
352
|
+
}
|
|
353
|
+
end
|
|
354
|
+
end
|
|
355
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SimpleCov
|
|
4
|
+
#
|
|
5
|
+
# Select the files that related to working scope directory of SimpleCov
|
|
6
|
+
#
|
|
7
|
+
module UselessResultsRemover
|
|
8
|
+
def self.call(coverage_result)
|
|
9
|
+
coverage_result.select do |path, _coverage|
|
|
10
|
+
path =~ root_regx
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.root_regx
|
|
15
|
+
@root_regx ||= /\A#{Regexp.escape(SimpleCov.root + File::SEPARATOR)}/i.freeze
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|