coverband 4.2.0 → 4.2.2

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.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +29 -9
  3. data/.travis.yml +10 -8
  4. data/CODE_OF_CONDUCT.md +76 -0
  5. data/Gemfile +3 -1
  6. data/Gemfile.rails4 +1 -0
  7. data/README.md +72 -43
  8. data/Rakefile +14 -3
  9. data/changes.md +66 -11
  10. data/coverband.gemspec +2 -5
  11. data/lib/coverband/adapters/base.rb +64 -45
  12. data/lib/coverband/adapters/file_store.rb +15 -9
  13. data/lib/coverband/adapters/hash_redis_store.rb +182 -0
  14. data/lib/coverband/adapters/redis_store.rb +33 -11
  15. data/lib/coverband/at_exit.rb +2 -11
  16. data/lib/coverband/collectors/coverage.rb +34 -40
  17. data/lib/coverband/collectors/delta.rb +34 -28
  18. data/lib/coverband/collectors/view_tracker.rb +124 -0
  19. data/lib/coverband/configuration.rb +96 -32
  20. data/lib/coverband/integrations/background.rb +9 -4
  21. data/lib/coverband/integrations/{middleware.rb → background_middleware.rb} +2 -6
  22. data/lib/coverband/integrations/bundler.rb +8 -0
  23. data/lib/coverband/integrations/report_middleware.rb +15 -0
  24. data/lib/coverband/integrations/resque.rb +3 -5
  25. data/lib/coverband/reporters/base.rb +40 -16
  26. data/lib/coverband/reporters/console_report.rb +1 -0
  27. data/lib/coverband/reporters/html_report.rb +21 -27
  28. data/lib/coverband/reporters/web.rb +19 -21
  29. data/lib/coverband/utils/absolute_file_converter.rb +47 -0
  30. data/lib/coverband/utils/file_hasher.rb +16 -0
  31. data/lib/coverband/utils/file_list.rb +16 -5
  32. data/lib/coverband/utils/html_formatter.rb +37 -8
  33. data/lib/coverband/utils/lines_classifier.rb +5 -0
  34. data/lib/coverband/utils/railtie.rb +20 -9
  35. data/lib/coverband/utils/relative_file_converter.rb +41 -0
  36. data/lib/coverband/utils/result.rb +1 -37
  37. data/lib/coverband/utils/results.rb +51 -0
  38. data/lib/coverband/utils/s3_report.rb +2 -2
  39. data/lib/coverband/utils/source_file.rb +31 -8
  40. data/lib/coverband/utils/tasks.rb +10 -10
  41. data/lib/coverband/version.rb +5 -1
  42. data/lib/coverband.rb +39 -22
  43. data/public/application.css +6 -6
  44. data/public/application.js +27 -0
  45. data/test/benchmarks/benchmark.rake +167 -73
  46. data/test/benchmarks/init_rails.rake +10 -0
  47. data/test/coverband/adapters/base_test.rb +73 -42
  48. data/test/coverband/adapters/file_store_test.rb +48 -37
  49. data/test/coverband/adapters/hash_redis_store_test.rb +190 -0
  50. data/test/coverband/adapters/redis_store_test.rb +92 -59
  51. data/test/coverband/at_exit_test.rb +0 -2
  52. data/test/coverband/collectors/coverage_test.rb +62 -10
  53. data/test/coverband/collectors/delta_test.rb +36 -6
  54. data/test/coverband/collectors/view_tracker_test.rb +77 -0
  55. data/test/coverband/configuration_test.rb +47 -7
  56. data/test/coverband/coverband_test.rb +14 -2
  57. data/test/coverband/integrations/background_middleware_test.rb +44 -0
  58. data/test/coverband/integrations/background_test.rb +1 -3
  59. data/test/coverband/integrations/report_middleware_test.rb +44 -0
  60. data/test/coverband/integrations/resque_worker_test.rb +6 -6
  61. data/test/coverband/integrations/test_resque_job.rb +3 -1
  62. data/test/coverband/reporters/base_test.rb +2 -79
  63. data/test/coverband/reporters/console_test.rb +2 -6
  64. data/test/coverband/reporters/html_test.rb +58 -19
  65. data/test/coverband/reporters/web_test.rb +0 -10
  66. data/test/coverband/utils/absolute_file_converter_test.rb +56 -0
  67. data/test/coverband/utils/file_groups_test.rb +11 -5
  68. data/test/coverband/utils/file_hasher_test.rb +29 -0
  69. data/test/coverband/utils/file_list_test.rb +5 -5
  70. data/test/coverband/utils/html_formatter_test.rb +43 -0
  71. data/test/coverband/utils/relative_file_converter_test.rb +39 -0
  72. data/test/coverband/utils/result_test.rb +6 -47
  73. data/test/coverband/utils/results_test.rb +54 -0
  74. data/test/coverband/utils/s3_report_test.rb +2 -0
  75. data/test/coverband/utils/source_file_test.rb +50 -0
  76. data/test/dog.rb.erb +12 -0
  77. data/test/forked/rails_full_stack_test.rb +106 -0
  78. data/test/forked/rails_rake_full_stack_test.rb +48 -0
  79. data/test/integration/full_stack_test.rb +17 -16
  80. data/test/rails4_dummy/Rakefile +6 -0
  81. data/test/rails4_dummy/config/application.rb +8 -9
  82. data/test/rails4_dummy/config/coverband.rb +5 -3
  83. data/test/rails5_dummy/Rakefile +6 -0
  84. data/test/rails5_dummy/config/application.rb +6 -10
  85. data/test/rails5_dummy/config/coverband.rb +4 -2
  86. data/test/rails_test_helper.rb +22 -5
  87. data/test/test_helper.rb +45 -8
  88. data/test/unique_files.rb +17 -9
  89. data/views/file_list.erb +2 -2
  90. data/views/gem_list.erb +10 -1
  91. data/views/layout.erb +6 -18
  92. data/views/nav.erb +35 -0
  93. data/views/source_file.erb +13 -4
  94. data/views/source_file_loader.erb +1 -1
  95. data/views/view_tracker.erb +37 -0
  96. metadata +59 -25
  97. data/lib/coverband/utils/file_path_helper.rb +0 -57
  98. data/test/coverband/integrations/middleware_test.rb +0 -96
  99. data/test/integration/rails_full_stack_test.rb +0 -95
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  namespace :benchmarks do
3
4
  # https://github.com/evanphx/benchmark-ips
4
5
  # Enable and start GC before each job run. Disable GC afterwards.
@@ -13,11 +14,9 @@ namespace :benchmarks do
13
14
  run_gc
14
15
  end
15
16
 
16
- def warmup_stats(*)
17
- end
17
+ def warmup_stats(*); end
18
18
 
19
- def add_report(*)
20
- end
19
+ def add_report(*); end
21
20
 
22
21
  private
23
22
 
@@ -28,37 +27,14 @@ namespace :benchmarks do
28
27
  end
29
28
  end
30
29
 
31
- def classifier_dir
32
- File.join(File.dirname(__FILE__), 'classifier-reborn')
33
- end
34
-
35
- def clone_classifier
36
- # rubocop:disable Style/IfUnlessModifier
37
- unless Dir.exist? classifier_dir
38
- system "git clone https://github.com/jekyll/classifier-reborn.git #{classifier_dir}"
39
- end
40
- # rubocop:enable Style/IfUnlessModifier
41
- end
42
-
43
30
  # desc 'setup standard benchmark'
44
31
  task :setup do
45
- clone_classifier
46
- $LOAD_PATH.unshift(File.join(classifier_dir, 'lib'))
47
32
  require 'benchmark'
48
33
  require 'benchmark/ips'
49
34
 
50
- # TODO: ok this is interesting and weird
51
- # basically the earlier I require coverage and
52
- # then require files the larger perf impact
53
- # this is somewhat expected but can lead to significant perf diffs
54
- # for example moving `require 'classifier-reborn'` below the coverage.start
55
- # results in 1.5x slower vs "difference falls within error"
56
- # moving from 5 second of time to 12 still shows slower based on when classifier is required
57
- # make sure to be plugged in while benchmarking ;) Otherwise you get very unreliable results
58
- require 'classifier-reborn'
59
- if ENV['COVERAGE']
35
+ if ENV['COVERAGE'] || ENV['ONESHOT']
60
36
  require 'coverage'
61
- ::Coverage.start
37
+ ::Coverage.start(oneshot_lines: !!ENV['ONESHOT'])
62
38
  end
63
39
  require 'redis'
64
40
  require 'coverband'
@@ -79,9 +55,10 @@ namespace :benchmarks do
79
55
  task :setup_redis do
80
56
  Coverband.configure do |config|
81
57
  config.root = Dir.pwd
82
- config.reporting_frequency = 100.0
83
58
  config.logger = $stdout
84
59
  config.store = benchmark_redis_store
60
+ config.use_oneshot_lines_coverage = true if ENV['ONESHOT']
61
+ config.simulate_oneshot_lines_coverage = true if ENV['SIMULATE_ONESHOT']
85
62
  end
86
63
  end
87
64
 
@@ -89,39 +66,13 @@ namespace :benchmarks do
89
66
  task :setup_file do
90
67
  Coverband.configure do |config|
91
68
  config.root = Dir.pwd
92
- config.reporting_frequency = 100.0
93
69
  config.logger = $stdout
94
70
  file_path = '/tmp/benchmark_store.json'
95
71
  config.store = Coverband::Adapters::FileStore.new(file_path)
96
72
  end
97
73
  end
98
74
 
99
- def bayes_classification
100
- b = ClassifierReborn::Bayes.new 'Interesting', 'Uninteresting'
101
- b.train_interesting 'here are some good words. I hope you love them'
102
- b.train_uninteresting 'here are some bad words, I hate you'
103
- b.classify 'I hate bad words and you' # returns 'Uninteresting'
104
- end
105
-
106
- def lsi_classification
107
- lsi = ClassifierReborn::LSI.new
108
- strings = [['This text deals with dogs. Dogs.', :dog],
109
- ['This text involves dogs too. Dogs! ', :dog],
110
- ['This text revolves around cats. Cats.', :cat],
111
- ['This text also involves cats. Cats!', :cat],
112
- ['This text involves birds. Birds.', :bird]]
113
- strings.each { |x| lsi.add_item x.first, x.last }
114
- lsi.search('dog', 3)
115
- lsi.find_related(strings[2], 2)
116
- lsi.classify 'This text is also about dogs!'
117
- end
118
-
119
75
  def work
120
- 5.times do
121
- bayes_classification
122
- lsi_classification
123
- end
124
-
125
76
  # simulate many calls to the same line
126
77
  10_000.times { Dog.new.bark }
127
78
  end
@@ -134,7 +85,7 @@ namespace :benchmarks do
134
85
  x.config(time: 12, warmup: 5, suite: suite)
135
86
  x.report 'coverband' do
136
87
  work
137
- Coverband.report_coverage(true)
88
+ Coverband.report_coverage
138
89
  end
139
90
  x.report 'no coverband' do
140
91
  work
@@ -145,9 +96,11 @@ namespace :benchmarks do
145
96
  Coverband::Collectors::Coverage.instance.reset_instance
146
97
  end
147
98
 
99
+ LINES = 45
100
+ NON_NIL_LINES = 18
148
101
  def fake_line_numbers
149
- 24.times.each_with_object({}) do |line, line_hash|
150
- line_hash[(line + 1).to_s] = rand(5)
102
+ LINES.times.map do |line|
103
+ coverage = (line < NON_NIL_LINES) ? rand(5) : nil
151
104
  end
152
105
  end
153
106
 
@@ -160,6 +113,7 @@ namespace :benchmarks do
160
113
  def adjust_report(report)
161
114
  report.keys.each do |file|
162
115
  next unless rand < 0.15
116
+
163
117
  report[file] = fake_line_numbers
164
118
  end
165
119
  report
@@ -169,12 +123,8 @@ namespace :benchmarks do
169
123
  ###
170
124
  # this is a hack because in the benchmark we don't have real files
171
125
  ###
172
- def store.file_hash(file)
173
- if @file_hash_cache[file]
174
- @file_hash_cache[file]
175
- else
176
- @file_hash_cache[file] = Digest::MD5.file(__FILE__).hexdigest
177
- end
126
+ def store.file_hash(_file)
127
+ @file_hash ||= Digest::MD5.file(__FILE__).hexdigest
178
128
  end
179
129
 
180
130
  def store.full_path_to_relative(file)
@@ -191,7 +141,13 @@ namespace :benchmarks do
191
141
  5.times { store.save_report(report) }
192
142
  Benchmark.ips do |x|
193
143
  x.config(time: 15, warmup: 5)
194
- x.report('store_reports') { store.save_report(report) }
144
+ x.report('store_reports_all') { store.save_report(report) }
145
+ end
146
+ keys_subset = report.keys.first(100)
147
+ report_subset = report.select { |key, _value| keys_subset.include?(key) }
148
+ Benchmark.ips do |x|
149
+ x.config(time: 20, warmup: 5)
150
+ x.report('store_reports_subset') { store.save_report(report_subset) }
195
151
  end
196
152
  end
197
153
 
@@ -214,11 +170,54 @@ namespace :benchmarks do
214
170
  end.pretty_print
215
171
  data = $stdout.string
216
172
  $stdout = previous_out
217
- raise 'leaking memory!!!' unless data.match('Total retained: 0 bytes')
173
+ unless data.match('Total retained: 0 bytes')
174
+ puts data
175
+ raise 'leaking memory!!!'
176
+ end
177
+ ensure
178
+ $stdout = previous_out
179
+ end
180
+
181
+ def measure_memory_report_coverage
182
+ require 'memory_profiler'
183
+ report = fake_report
184
+ store = benchmark_redis_store
185
+ store.clear!
186
+ mock_files(store)
187
+
188
+ # warmup
189
+ 3.times { Coverband.report_coverage }
190
+
191
+ previous_out = $stdout
192
+ capture = StringIO.new
193
+ $stdout = capture
194
+
195
+ MemoryProfiler.report do
196
+ 10.times do
197
+ Coverband.report_coverage
198
+ ###
199
+ # Set to nil not {} as it is easier to verify that no memory is retained when nil gets released
200
+ # don't use Coverband::Collectors::Delta.reset which sets to {}
201
+ # we clear this as this one variable is expected to retain memory and is a false positive
202
+ ###
203
+ Coverband::Collectors::Delta.class_variable_set(:@@previous_coverage, nil)
204
+ end
205
+ end.pretty_print
206
+ data = $stdout.string
207
+ $stdout = previous_out
208
+ unless data.match('Total retained: 0 bytes')
209
+ puts data
210
+ raise 'leaking memory!!!'
211
+ end
218
212
  ensure
219
213
  $stdout = previous_out
220
214
  end
221
215
 
216
+ ###
217
+ # TODO: This currently fails, as it holds a string in redis adapter
218
+ # but really Coverband shouldn't be configured multiple times and the leak is small
219
+ # not including in test suite but we can try to figure it out and fix.
220
+ ###
222
221
  def measure_configure_memory
223
222
  require 'memory_profiler'
224
223
  # warmup
@@ -232,24 +231,79 @@ namespace :benchmarks do
232
231
  10.times do
233
232
  Coverband.configure do |config|
234
233
  redis_url = ENV['CACHE_REDIS_URL'] || ENV['REDIS_URL']
235
- config.store = Coverband::Adapters::RedisStore.new(Redis.new(url: redis_url), redis_namespace: 'coverband_data')
234
+ config.store = Coverband::Adapters::RedisStore.new(Redis.new(url: redis_url), redis_namespace: 'coverband_bench_data')
236
235
  end
237
236
  end
238
237
  end.pretty_print
239
238
  data = $stdout.string
240
239
  $stdout = previous_out
241
- puts data
242
- raise 'leaking memory!!!' unless data.match('Total retained: 0 bytes')
240
+ unless data.match('Total retained: 0 bytes')
241
+ puts data
242
+ raise 'leaking memory!!!'
243
+ end
243
244
  ensure
244
245
  $stdout = previous_out
245
246
  end
246
247
 
248
+ desc 'checks memory of collector'
249
+ task memory_check: [:setup] do
250
+ require 'pry-byebug'
251
+ require 'objspace'
252
+ puts 'memory load check'
253
+ puts(ObjectSpace.memsize_of_all / 2**20)
254
+ data = File.read('./tmp/debug_data.json')
255
+ # about 2mb
256
+ puts(ObjectSpace.memsize_of(data) / 2**20)
257
+
258
+ json_data = JSON.parse(data)
259
+ # this seems to just show the value of the pointer
260
+ # puts(ObjectSpace.memsize_of(json_data) / 2**20)
261
+ # implies json takes 10-12 mb
262
+ puts(ObjectSpace.memsize_of_all / 2**20)
263
+
264
+ json_data = nil
265
+ GC.start
266
+ json_data = JSON.parse(data)
267
+ # this seems to just show the value of the pointer
268
+ # puts(ObjectSpace.memsize_of(json_data) / 2**20)
269
+ # implies json takes 10-12 mb
270
+ puts(ObjectSpace.memsize_of_all / 2**20)
271
+
272
+ json_data = nil
273
+ GC.start
274
+ json_data = JSON.parse(data)
275
+ # this seems to just show the value of the pointer
276
+ # puts(ObjectSpace.memsize_of(json_data) / 2**20)
277
+ # implies json takes 10-12 mb
278
+ puts(ObjectSpace.memsize_of_all / 2**20)
279
+
280
+ json_data = nil
281
+ GC.start
282
+ json_data = JSON.parse(data)
283
+ # this seems to just show the value of the pointer
284
+ # puts(ObjectSpace.memsize_of(json_data) / 2**20)
285
+ # implies json takes 10-12 mb
286
+ puts(ObjectSpace.memsize_of_all / 2**20)
287
+
288
+ json_data = nil
289
+ GC.start
290
+ puts(ObjectSpace.memsize_of_all / 2**20)
291
+ debugger
292
+ puts 'done'
293
+ end
294
+
247
295
  desc 'runs memory reporting on Redis store'
248
296
  task memory_reporting: [:setup] do
249
297
  puts 'runs memory benchmarking to ensure we dont leak'
250
298
  measure_memory
251
299
  end
252
300
 
301
+ desc 'runs memory reporting on report_coverage'
302
+ task memory_reporting_report_coverage: [:setup] do
303
+ puts 'runs memory benchmarking on report_coverage to ensure we dont leak'
304
+ measure_memory_report_coverage
305
+ end
306
+
253
307
  desc 'runs memory reporting on configure'
254
308
  task memory_configure_reporting: [:setup] do
255
309
  puts 'runs memory benchmarking on configure to ensure we dont leak'
@@ -259,7 +313,12 @@ namespace :benchmarks do
259
313
  desc 'runs memory leak check via Rails tests'
260
314
  task memory_rails: [:setup] do
261
315
  puts 'runs memory rails test to ensure we dont leak'
262
- puts `COVERBAND_MEMORY_TEST=true bundle exec m test/unit/rails_full_stack_test.rb:22`
316
+ puts `COVERBAND_MEMORY_TEST=true bundle exec test/forked/rails_full_stack_test.rb`
317
+ end
318
+
319
+ desc 'runs memory leak checks'
320
+ task memory: %i[memory_reporting memory_reporting_report_coverage memory_rails] do
321
+ puts 'done'
263
322
  end
264
323
 
265
324
  desc 'runs benchmarks on reporting large sets of files to redis'
@@ -269,13 +328,36 @@ namespace :benchmarks do
269
328
  end
270
329
 
271
330
  # desc 'runs benchmarks on default redis setup'
272
- task run_redis: [:setup, :setup_redis] do
331
+ task run_redis: %i[setup setup_redis] do
273
332
  puts 'Coverband configured with default Redis store'
274
333
  run_work(true)
275
334
  end
276
335
 
336
+ def run_big
337
+ require 'memory_profiler'
338
+ require './test/unique_files'
339
+
340
+ 4000.times { |index| require_unique_file('dog.rb.erb', dog_number: index) }
341
+ # warmup
342
+ 3.times { Coverband.report_coverage }
343
+ dogs = 400.times.map { |index| Object.const_get("Dog#{index}") }
344
+ MemoryProfiler.report do
345
+ 10.times do
346
+ dogs.each(&:bark)
347
+ Coverband.report_coverage
348
+ end
349
+ end.pretty_print
350
+ end
351
+
352
+ task run_big: %i[setup setup_redis] do
353
+ # ensure we cleared from last run
354
+ benchmark_redis_store.clear!
355
+
356
+ run_big
357
+ end
358
+
277
359
  # desc 'runs benchmarks file store'
278
- task run_file: [:setup, :setup_file] do
360
+ task run_file: %i[setup setup_file] do
279
361
  puts 'Coverband configured with file store'
280
362
  run_work(true)
281
363
  end
@@ -297,6 +379,18 @@ namespace :benchmarks do
297
379
  `open tmp/timeseries.jpg`
298
380
  end
299
381
 
382
+ desc 'benchmark initialization of rails'
383
+ task :init_rails do
384
+ require 'benchmark'
385
+ require 'benchmark/ips'
386
+ Benchmark.ips do |x|
387
+ x.config(time: 60, warmup: 0)
388
+ x.report('init_rails') do
389
+ system('bundle exec rake init_rails -f ./test/benchmarks/init_rails.rake')
390
+ end
391
+ end
392
+ end
393
+
300
394
  desc 'compare Coverband Ruby Coverage with Filestore with normal Ruby'
301
395
  task :compare_file do
302
396
  puts 'comparing Coverage loaded/not, this takes some time for output...'
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails'
4
+ require 'coverband'
5
+
6
+ desc 'Initialize rails'
7
+ task 'init_rails' do
8
+ Coverband.configure("./test/rails#{Rails::VERSION::MAJOR}_dummy/config/coverband.rb")
9
+ require "./test/rails#{Rails::VERSION::MAJOR}_dummy/config/environment"
10
+ end
@@ -3,49 +3,80 @@
3
3
  require File.expand_path('../../test_helper', File.dirname(__FILE__))
4
4
 
5
5
  class AdaptersBaseTest < Minitest::Test
6
- def setup
7
- super
8
- @test_file_path = '/tmp/coverband_filestore_test_path.json'
9
- @store = Coverband::Adapters::FileStore.new(@test_file_path)
10
- mock_file_hash
6
+
7
+ def test_abstract_methods
8
+ abstract_methods = %w(clear! clear_file! migrate! size save_coverage coverage)
9
+ abstract_methods.each do |method|
10
+ assert_raises RuntimeError do
11
+ Coverband::Adapters::Base.new.send(method.to_sym)
12
+ end
13
+ end
14
+ end
15
+
16
+ def test_size_in_mib
17
+ base = Coverband::Adapters::Base.new
18
+ def base.size
19
+ 3.0
20
+ end
21
+ assert_equal "0.00", base.size_in_mib
11
22
  end
12
23
 
13
- def test_covered_merge
14
- old_time = 1541958097
15
- current_time = Time.now.to_i
16
- old_data = {
17
- 'first_updated_at' => old_time,
18
- 'last_updated_at' => current_time,
19
- 'file_hash' => 'abcd',
20
- 'data' => [5, 7, nil]
21
- }
22
- old_report = { '/projects/coverband_demo/config/coverband.rb' => old_data,
23
- '/projects/coverband_demo/config/initializers/assets.rb' => old_data,
24
- '/projects/coverband_demo/config/initializers/cookies_serializer.rb' => old_data }
25
- new_report = { '/projects/coverband_demo/config/coverband.rb' => [5, 7, nil],
26
- '/projects/coverband_demo/config/initializers/filter_logging.rb' => [5, 7, nil],
27
- '/projects/coverband_demo/config/initializers/wrap_parameters.rb' => [5, 7, nil],
28
- '/projects/coverband_demo/app/controllers/application_controller.rb' => [5, 7, nil] }
29
- expected_merge = {
30
- 'first_updated_at' => old_time,
31
- 'last_updated_at' => current_time,
32
- 'file_hash' => 'abcd',
33
- 'data' => [10, 14, nil]
34
- }
35
- new_data = {
36
- 'first_updated_at' => current_time,
37
- 'last_updated_at' => current_time,
38
- 'file_hash' => 'abcd',
39
- 'data' => [5, 7, nil]
40
- }
41
- expected_result = {
42
- '/projects/coverband_demo/app/controllers/application_controller.rb' => new_data,
43
- '/projects/coverband_demo/config/coverband.rb' => expected_merge,
44
- '/projects/coverband_demo/config/initializers/assets.rb' => old_data,
45
- '/projects/coverband_demo/config/initializers/cookies_serializer.rb' => old_data,
46
- '/projects/coverband_demo/config/initializers/filter_logging.rb' => new_data,
47
- '/projects/coverband_demo/config/initializers/wrap_parameters.rb' => new_data
48
- }
49
- assert_equal expected_result, @store.send(:merge_reports, new_report, old_report)
24
+ def test_array_add
25
+ original = [5, 7, nil, nil]
26
+ latest = [3, 4, nil, 1]
27
+ assert_equal [8, 11, nil, nil], Coverband::Adapters::Base.new.send(:array_add, latest, original)
28
+ Coverband.configuration.stubs(:use_oneshot_lines_coverage).returns(true)
29
+ assert_equal [1, 1, nil, nil], Coverband::Adapters::Base.new.send(:array_add, latest, original)
30
+ Coverband.configuration.stubs(:use_oneshot_lines_coverage).returns(false)
31
+ Coverband.configuration.stubs(:simulate_oneshot_lines_coverage).returns(true)
32
+ assert_equal [1, 1, nil, nil], Coverband::Adapters::Base.new.send(:array_add, latest, original)
33
+ end
34
+
35
+ describe 'Coverband::Adapters::Base using file' do
36
+ def setup
37
+ super
38
+ @test_file_path = '/tmp/coverband_filestore_test_path.json'
39
+ @store = Coverband::Adapters::FileStore.new(@test_file_path)
40
+ mock_file_hash
41
+ end
42
+
43
+ def test_covered_merge
44
+ old_time = 1541958097
45
+ current_time = Time.now.to_i
46
+ old_data = {
47
+ 'first_updated_at' => old_time,
48
+ 'last_updated_at' => current_time,
49
+ 'file_hash' => 'abcd',
50
+ 'data' => [5, 7, nil]
51
+ }
52
+ old_report = { '/projects/coverband_demo/config/coverband.rb' => old_data,
53
+ '/projects/coverband_demo/config/initializers/assets.rb' => old_data,
54
+ '/projects/coverband_demo/config/initializers/cookies_serializer.rb' => old_data }
55
+ new_report = { '/projects/coverband_demo/config/coverband.rb' => [5, 7, nil],
56
+ '/projects/coverband_demo/config/initializers/filter_logging.rb' => [5, 7, nil],
57
+ '/projects/coverband_demo/config/initializers/wrap_parameters.rb' => [5, 7, nil],
58
+ '/projects/coverband_demo/app/controllers/application_controller.rb' => [5, 7, nil] }
59
+ expected_merge = {
60
+ 'first_updated_at' => old_time,
61
+ 'last_updated_at' => current_time,
62
+ 'file_hash' => 'abcd',
63
+ 'data' => [10, 14, nil]
64
+ }
65
+ new_data = {
66
+ 'first_updated_at' => current_time,
67
+ 'last_updated_at' => current_time,
68
+ 'file_hash' => 'abcd',
69
+ 'data' => [5, 7, nil]
70
+ }
71
+ expected_result = {
72
+ '/projects/coverband_demo/app/controllers/application_controller.rb' => new_data,
73
+ '/projects/coverband_demo/config/coverband.rb' => expected_merge,
74
+ '/projects/coverband_demo/config/initializers/assets.rb' => old_data,
75
+ '/projects/coverband_demo/config/initializers/cookies_serializer.rb' => old_data,
76
+ '/projects/coverband_demo/config/initializers/filter_logging.rb' => new_data,
77
+ '/projects/coverband_demo/config/initializers/wrap_parameters.rb' => new_data
78
+ }
79
+ assert_equal expected_result, @store.send(:merge_reports, new_report, old_report)
80
+ end
50
81
  end
51
82
  end
@@ -3,45 +3,56 @@
3
3
  require File.expand_path('../../test_helper', File.dirname(__FILE__))
4
4
 
5
5
  class AdaptersFileStoreTest < Minitest::Test
6
- def setup
7
- super
8
- @test_file_path = '/tmp/coverband_filestore_test_path.json'
9
- File.open(@test_file_path, 'w') { |f| f.write(test_data.to_json) }
10
- @store = Coverband::Adapters::FileStore.new(@test_file_path)
11
- end
12
-
13
- def test_covered_lines_for_file
14
- assert_equal @store.covered_lines_for_file('dog.rb')[0], 1
15
- assert_equal @store.covered_lines_for_file('dog.rb')[1], 2
16
- end
17
-
18
- def test_covered_lines_when_null
19
- assert_equal @store.covered_lines_for_file('none.rb'), []
20
- end
21
6
 
22
- def test_covered_files
23
- assert_equal @store.covered_files, ['dog.rb']
7
+ def test_covered_lines_when_no_file
8
+ @store = Coverband::Adapters::FileStore.new('')
9
+ expected = {}
10
+ assert_equal expected, @store.coverage
24
11
  end
25
12
 
26
- def test_clear
27
- @store.clear!
28
- assert_equal false, File.exist?(@test_file_path)
29
- end
30
-
31
- def test_save_report
32
- mock_file_hash
33
- @store.send(:save_report, 'cat.rb' => [0, 1])
34
- assert_equal @store.covered_lines_for_file('cat.rb')[1], 1
35
- end
36
-
37
- private
38
-
39
- def test_data
40
- {
41
- 'dog.rb' => { 'data' => [1, 2, nil],
42
- 'file_hash' => 'abcd',
43
- 'first_updated_at' => 1541968729,
44
- 'last_updated_at' => 1541968729 }
45
- }
13
+ describe 'Coverband::Adapters::FileStore with file' do
14
+ def setup
15
+ super
16
+ @test_file_path = '/tmp/coverband_filestore_test_path.json'
17
+ File.open(@test_file_path, 'w') { |f| f.write(test_data.to_json) }
18
+ @store = Coverband::Adapters::FileStore.new(@test_file_path)
19
+ end
20
+
21
+ def test_size
22
+ assert @store.size > 1
23
+ end
24
+
25
+ def test_coverage
26
+ assert_equal @store.coverage['dog.rb']['data'][0], 1
27
+ assert_equal @store.coverage['dog.rb']['data'][1], 2
28
+ end
29
+
30
+ def test_covered_lines_when_null
31
+ assert_nil @store.coverage['none.rb']
32
+ end
33
+
34
+ def test_covered_files
35
+ assert_equal @store.covered_files, ['dog.rb']
36
+ end
37
+
38
+ def test_clear
39
+ @store.clear!
40
+ assert_equal false, File.exist?(@test_file_path)
41
+ end
42
+
43
+ def test_save_report
44
+ mock_file_hash
45
+ @store.send(:save_report, 'cat.rb' => [0, 1])
46
+ assert_equal @store.coverage['cat.rb']['data'][1], 1
47
+ end
48
+
49
+ def test_data
50
+ {
51
+ 'dog.rb' => { 'data' => [1, 2, nil],
52
+ 'file_hash' => 'abcd',
53
+ 'first_updated_at' => 1541968729,
54
+ 'last_updated_at' => 1541968729 }
55
+ }
56
+ end
46
57
  end
47
58
  end