coverband 4.2.0.beta → 4.2.0.rc1

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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +33 -8
  3. data/Rakefile +1 -1
  4. data/changes.md +28 -7
  5. data/coverband.gemspec +2 -0
  6. data/lib/coverband.rb +5 -0
  7. data/lib/coverband/adapters/base.rb +20 -4
  8. data/lib/coverband/adapters/file_store.rb +8 -0
  9. data/lib/coverband/adapters/redis_store.rb +33 -2
  10. data/lib/coverband/at_exit.rb +1 -1
  11. data/lib/coverband/collectors/coverage.rb +11 -1
  12. data/lib/coverband/configuration.rb +18 -2
  13. data/lib/coverband/integrations/background.rb +6 -1
  14. data/lib/coverband/integrations/resque.rb +7 -2
  15. data/lib/coverband/reporters/base.rb +8 -38
  16. data/lib/coverband/reporters/html_report.rb +1 -1
  17. data/lib/coverband/reporters/web.rb +3 -3
  18. data/lib/coverband/utils/file_path_helper.rb +57 -0
  19. data/lib/coverband/utils/html_formatter.rb +9 -1
  20. data/lib/coverband/utils/railtie.rb +1 -1
  21. data/lib/coverband/utils/tasks.rb +9 -0
  22. data/lib/coverband/version.rb +1 -1
  23. data/test/benchmarks/benchmark.rake +36 -1
  24. data/test/benchmarks/coverage_fork.sh +37 -0
  25. data/test/{unit/adapters_base_test.rb → coverband/adapters/base_test.rb} +1 -1
  26. data/test/{unit/adapters_file_store_test.rb → coverband/adapters/file_store_test.rb} +1 -1
  27. data/test/{unit/adapters_redis_store_test.rb → coverband/adapters/redis_store_test.rb} +1 -1
  28. data/test/{unit → coverband}/at_exit_test.rb +0 -0
  29. data/test/{unit/collectors_coverage_test.rb → coverband/collectors/coverage_test.rb} +16 -2
  30. data/test/{unit → coverband}/configuration_test.rb +13 -3
  31. data/test/{unit → coverband}/coverband_test.rb +0 -0
  32. data/test/{unit → coverband/integrations}/background_test.rb +1 -1
  33. data/test/{unit → coverband/integrations}/middleware_test.rb +1 -1
  34. data/test/{unit/rack_server_checkout_test.rb → coverband/integrations/rack_server_check_test.rb} +1 -1
  35. data/test/{unit → coverband/integrations}/resque_worker_test.rb +9 -8
  36. data/test/{unit → coverband/integrations}/test_resque_job.rb +0 -0
  37. data/test/coverband/reporters/base_test.rb +168 -0
  38. data/test/{unit/reports_console_test.rb → coverband/reporters/console_test.rb} +6 -5
  39. data/test/{unit/reports_html_test.rb → coverband/reporters/html_test.rb} +1 -1
  40. data/test/{unit/reports_web_test.rb → coverband/reporters/web_test.rb} +2 -2
  41. data/test/{unit → coverband}/utils/file_groups_test.rb +0 -0
  42. data/test/{unit → coverband}/utils/file_list_test.rb +0 -0
  43. data/test/{unit → coverband}/utils/gem_list_test.rb +0 -0
  44. data/test/{unit → coverband}/utils/lines_classifier_test.rb +0 -0
  45. data/test/{unit → coverband}/utils/result_test.rb +0 -0
  46. data/test/{unit → coverband}/utils/s3_report_test.rb +0 -0
  47. data/test/{unit → coverband}/utils/source_file_line_test.rb +0 -0
  48. data/test/{unit → coverband}/utils/source_file_test.rb +0 -0
  49. data/test/{unit/dog.rb → dog.rb} +0 -0
  50. data/test/{unit → integration}/full_stack_test.rb +4 -2
  51. data/test/{unit → integration}/rails_full_stack_test.rb +4 -3
  52. data/test/{unit → integration}/rails_gems_full_stack_test.rb +2 -1
  53. data/views/layout.erb +1 -1
  54. data/views/settings.erb +35 -0
  55. metadata +78 -59
  56. data/test/unit/reports_base_test.rb +0 -117
@@ -11,7 +11,7 @@ module Coverband
11
11
  base_path = options.fetch(:base_path) { nil }
12
12
 
13
13
  # list all files, even if not tracked by Coverband (0% coverage)
14
- tracked_glob = "#{current_root}/{app,lib,config}/**/*.{rb}"
14
+ tracked_glob = "#{Coverband.configuration.current_root}/{app,lib,config}/**/*.{rb}"
15
15
  report_files = Coverband::Utils::Result.add_not_loaded_files(scov_style_report, tracked_glob)
16
16
  # apply coverband filters
17
17
  filtered_report_files = {}
@@ -36,7 +36,7 @@ module Coverband
36
36
  when /.*\.(css|js|gif|png)/
37
37
  @static.call(env)
38
38
  when %r{\/settings}
39
- [200, { 'Content-Type' => 'text/json' }, [settings]]
39
+ [200, { 'Content-Type' => 'text/html' }, [settings]]
40
40
  when %r{\/debug_data}
41
41
  [200, { 'Content-Type' => 'text/json' }, [debug_data]]
42
42
  when %r{\/$}
@@ -58,7 +58,7 @@ module Coverband
58
58
  end
59
59
 
60
60
  def settings
61
- Coverband.configuration.to_h.to_json
61
+ Coverband::Utils::HTMLFormatter.new(nil, base_path: base_path).format_settings!
62
62
  end
63
63
 
64
64
  def debug_data
@@ -66,7 +66,7 @@ module Coverband
66
66
  end
67
67
 
68
68
  def collect_coverage
69
- Coverband::Collectors::Coverage.instance.report_coverage(true)
69
+ Coverband.report_coverage(true)
70
70
  notice = 'coverband coverage collected'
71
71
  [301, { 'Location' => "#{base_path}?notice=#{notice}" }, []]
72
72
  end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ ####
4
+ # Helper functions for shared logic related to file path manipulation
5
+ ####
6
+ module Coverband
7
+ module Utils
8
+ module FilePathHelper
9
+ ###
10
+ # Takes a full path and converts to a relative path
11
+ ###
12
+ def full_path_to_relative(full_path)
13
+ relative_filename = full_path
14
+ Coverband.configuration.all_root_paths.each do |root|
15
+ relative_filename = relative_filename.gsub(/^#{root}/, './')
16
+ # once we have a relative path break out of the loop
17
+ break if relative_filename.start_with? './'
18
+ end
19
+ relative_filename
20
+ end
21
+
22
+ ###
23
+ # relative_path_to_full code takes:
24
+ # relative_path: which is a full path the same as reported by Coverage
25
+ # roots: if a collection of all possible full app paths
26
+ # EX: [Coverband.configuration.root_paths, "#{current_root}/"]
27
+ # The LAST item should be the current file system root
28
+ # it expands that expands and adds a '/' as that isn't there from Dir.pwd
29
+ #
30
+ # NOTEs on configuration.root_paths usage
31
+ # strings: matching is pretty simple for full string paths
32
+ # regex: to get regex to work for changing deploy directories
33
+ # the regex must be double escaped in double quotes
34
+ # (if using \d for example)
35
+ # or use single qoutes
36
+ # example: '/box/apps/app_name/releases/\d+/'
37
+ # example: '/var/local/company/company.d/[0-9]*/'
38
+ ###
39
+ def relative_path_to_full(relative_path, roots)
40
+ relative_filename = relative_path
41
+ local_filename = relative_filename
42
+ roots.each do |root|
43
+ relative_filename = relative_filename.gsub(/^#{root}/, './')
44
+ end
45
+ # the filename for our reports is expected to be a full path.
46
+ # roots.last should be roots << current_root}/
47
+ # a fully expanded path of config.root
48
+ # filename = filename.gsub('./', roots.last)
49
+ # above only works for app files
50
+ # we need to rethink some of this logic
51
+ # gems aren't at project root and can have multiple locations
52
+ local_root = roots.find { |root| File.exist?(relative_filename.gsub('./', root)) }
53
+ local_root ? relative_filename.gsub('./', local_root) : local_filename
54
+ end
55
+ end
56
+ end
57
+ end
@@ -18,7 +18,7 @@ module Coverband
18
18
  def initialize(report, options = {})
19
19
  @notice = options.fetch(:notice) { nil }
20
20
  @base_path = options.fetch(:base_path) { nil }
21
- @coverage_result = Coverband::Utils::Result.new(report)
21
+ @coverage_result = Coverband::Utils::Result.new(report) if report
22
22
  end
23
23
 
24
24
  def format!
@@ -29,8 +29,16 @@ module Coverband
29
29
  format_html(@coverage_result)
30
30
  end
31
31
 
32
+ def format_settings!
33
+ format_settings
34
+ end
35
+
32
36
  private
33
37
 
38
+ def format_settings
39
+ template('settings').result(binding)
40
+ end
41
+
34
42
  def format(result)
35
43
  Dir[File.join(File.dirname(__FILE__), '../../../public/*')].each do |path|
36
44
  FileUtils.cp_r(path, asset_output_path)
@@ -7,7 +7,7 @@ module Coverband
7
7
  end
8
8
 
9
9
  config.after_initialize do
10
- Coverband::Collectors::Coverage.instance.report_coverage(true)
10
+ Coverband.report_coverage(true)
11
11
  end
12
12
 
13
13
  rake_tasks do
@@ -25,4 +25,13 @@ namespace :coverband do
25
25
  environment
26
26
  Coverband.configuration.store.clear!
27
27
  end
28
+
29
+ ###
30
+ # clear data helpful for development or after configuration issues
31
+ ###
32
+ desc 'upgrade previous Coverband datastore to latest format'
33
+ task :migrate do
34
+ environment
35
+ Coverband.configuration.store.migrate!
36
+ end
28
37
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Coverband
4
- VERSION = '4.2.0.beta'
4
+ VERSION = '4.2.0.rc1'
5
5
  end
@@ -134,7 +134,7 @@ namespace :benchmarks do
134
134
  x.config(time: 12, warmup: 5, suite: suite)
135
135
  x.report 'coverband' do
136
136
  work
137
- Coverband::Collectors::Coverage.instance.report_coverage
137
+ Coverband.report_coverage(true)
138
138
  end
139
139
  x.report 'no coverband' do
140
140
  work
@@ -176,6 +176,10 @@ namespace :benchmarks do
176
176
  @file_hash_cache[file] = Digest::MD5.file(__FILE__).hexdigest
177
177
  end
178
178
  end
179
+
180
+ def store.full_path_to_relative(file)
181
+ file
182
+ end
179
183
  end
180
184
 
181
185
  def reporting_speed
@@ -215,12 +219,43 @@ namespace :benchmarks do
215
219
  $stdout = previous_out
216
220
  end
217
221
 
222
+ def measure_configure_memory
223
+ require 'memory_profiler'
224
+ # warmup
225
+ 3.times { Coverband.configure }
226
+
227
+ previous_out = $stdout
228
+ capture = StringIO.new
229
+ $stdout = capture
230
+
231
+ MemoryProfiler.report do
232
+ 10.times do
233
+ Coverband.configure do |config|
234
+ 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')
236
+ end
237
+ end
238
+ end.pretty_print
239
+ data = $stdout.string
240
+ $stdout = previous_out
241
+ puts data
242
+ raise 'leaking memory!!!' unless data.match('Total retained: 0 bytes')
243
+ ensure
244
+ $stdout = previous_out
245
+ end
246
+
218
247
  desc 'runs memory reporting on Redis store'
219
248
  task memory_reporting: [:setup] do
220
249
  puts 'runs memory benchmarking to ensure we dont leak'
221
250
  measure_memory
222
251
  end
223
252
 
253
+ desc 'runs memory reporting on configure'
254
+ task memory_configure_reporting: [:setup] do
255
+ puts 'runs memory benchmarking on configure to ensure we dont leak'
256
+ measure_configure_memory
257
+ end
258
+
224
259
  desc 'runs memory leak check via Rails tests'
225
260
  task memory_rails: [:setup] do
226
261
  puts 'runs memory rails test to ensure we dont leak'
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # This is a small script to illustrate how previous results get wiped out by forking
4
+ # this has implications of forking processes like Resque...
5
+ # this in the end would cause coverage.array_diff
6
+ # with previous results to add NEGATIVE code hits to the stored Coverage
7
+ # which in turn causes all sorts of crazy issues.
8
+ #
9
+ # ruby test/benchmarks/coverage_fork.rb
10
+ # in parent before fork
11
+ # {"/Users/danmayer/projects/coverband/test/dog.rb"=>[nil, nil, 1, 1, 2, nil, nil]}
12
+ # in child after fork
13
+ # {"/Users/danmayer/projects/coverband/test/dog.rb"=>[nil, nil, 0, 0, 0, nil, nil]}
14
+ # now triggering hits
15
+ # {"/Users/danmayer/projects/coverband/test/dog.rb"=>[nil, nil, 0, 0, 3, nil, nil]}
16
+ #
17
+ # I believe this might be related to CoW and GC... not sure
18
+ # http://patshaughnessy.net/2012/3/23/why-you-should-be-excited-about-garbage-collection-in-ruby-2-0
19
+ #
20
+ # NOTE: That the child now has 0 hits where previously method definitions had 1
21
+ # this causes all sorts of bad things to happen.
22
+ require 'coverage'
23
+ Coverage.start
24
+ load './test/dog.rb'
25
+ Dog.new.bark
26
+ Dog.new.bark
27
+ puts 'in parent before fork'
28
+ puts Coverage.peek_result
29
+ fork do
30
+ puts 'in child after fork'
31
+ puts Coverage.peek_result
32
+ puts 'now triggering hits'
33
+ Dog.new.bark
34
+ Dog.new.bark
35
+ Dog.new.bark
36
+ puts Coverage.peek_result
37
+ end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require File.expand_path('../test_helper', File.dirname(__FILE__))
3
+ require File.expand_path('../../test_helper', File.dirname(__FILE__))
4
4
 
5
5
  class AdaptersBaseTest < Minitest::Test
6
6
  def setup
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require File.expand_path('../test_helper', File.dirname(__FILE__))
3
+ require File.expand_path('../../test_helper', File.dirname(__FILE__))
4
4
 
5
5
  class AdaptersFileStoreTest < Minitest::Test
6
6
  def setup
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require File.expand_path('../test_helper', File.dirname(__FILE__))
3
+ require File.expand_path('../../test_helper', File.dirname(__FILE__))
4
4
 
5
5
  class RedisTest < Minitest::Test
6
6
  REDIS_STORAGE_FORMAT_VERSION = Coverband::Adapters::RedisStore::REDIS_STORAGE_FORMAT_VERSION
File without changes
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require File.expand_path('../test_helper', File.dirname(__FILE__))
4
- require File.expand_path('./dog', File.dirname(__FILE__))
3
+ require File.expand_path('../../test_helper', File.dirname(__FILE__))
4
+ require File.expand_path('../../dog', File.dirname(__FILE__))
5
5
 
6
6
  if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.3.0')
7
7
  class CollectorsCoverageTest < Minitest::Test
@@ -44,5 +44,19 @@ if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.3.0')
44
44
  @coverband.reset_instance
45
45
  @coverband.report_coverage
46
46
  end
47
+
48
+ test 'default tmp ignores' do
49
+ heroku_build_file = '/tmp/build_81feca8c72366e4edf020dc6f1937485/config/initializers/assets.rb'
50
+ assert_equal false, @coverband.send(:track_file?, heroku_build_file)
51
+ end
52
+
53
+ test '#array_diff never returns negative hits' do
54
+ # this can occur if a process forks after initializing the previous results
55
+ # see test/benchmarks/coverage_fork.rb
56
+ latest = [0, nil]
57
+ original = [1, nil]
58
+ expected = [0, nil]
59
+ assert_equal expected, @coverband.send(:array_diff, latest, original)
60
+ end
47
61
  end
48
62
  end
@@ -16,22 +16,32 @@ class BaseTest < Minitest::Test
16
16
  end
17
17
  end
18
18
 
19
- test 'defaults ' do
19
+ test 'defaults' do
20
20
  coverband = Coverband::Collectors::Coverage.instance.reset_instance
21
21
  assert_equal ['vendor', 'internal:prelude', 'schema.rb'], coverband.instance_variable_get('@ignore_patterns')
22
22
  end
23
23
 
24
- test 'gem_paths ' do
24
+ test 'gem_paths' do
25
25
  Coverband::Collectors::Coverage.instance.reset_instance
26
26
  assert Coverband.configuration.gem_paths.first != nil
27
27
  end
28
28
 
29
- test 'groups ' do
29
+ test 'groups' do
30
30
  Coverband::Collectors::Coverage.instance.reset_instance
31
31
  Coverband.configuration.track_gems = true
32
32
  assert_equal %w(App Gems), Coverband.configuration.groups.keys
33
33
  end
34
34
 
35
+ test 'all_root_paths' do
36
+ Coverband::Collectors::Coverage.instance.reset_instance
37
+ current_paths = Coverband.configuration.root_paths.dup
38
+ # verify previous bug fix
39
+ # it would extend the root_paths instance variable on each invokation
40
+ Coverband.configuration.all_root_paths
41
+ Coverband.configuration.all_root_paths
42
+ assert_equal current_paths, Coverband.configuration.root_paths
43
+ end
44
+
35
45
  test 's3 options' do
36
46
  Coverband::Collectors::Coverage.instance.reset_instance
37
47
  Coverband.configure do |config|
File without changes
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require File.expand_path('../test_helper', File.dirname(__FILE__))
3
+ require File.expand_path('../../test_helper', File.dirname(__FILE__))
4
4
 
5
5
  class BackgroundTest < Minitest::Test
6
6
  def setup
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require File.expand_path('../test_helper', File.dirname(__FILE__))
3
+ require File.expand_path('../../test_helper', File.dirname(__FILE__))
4
4
  require 'rack'
5
5
 
6
6
  class MiddlewareTest < Minitest::Test
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require File.expand_path('../test_helper', File.dirname(__FILE__))
3
+ require File.expand_path('../../test_helper', File.dirname(__FILE__))
4
4
 
5
5
  class RackServerCheckTest < Minitest::Test
6
6
  test 'returns true when running in rack server' do
@@ -1,18 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require File.expand_path('../test_helper', File.dirname(__FILE__))
3
+ require File.expand_path('../../test_helper', File.dirname(__FILE__))
4
4
 
5
5
  class ResqueWorkerTest < Minitest::Test
6
6
  def enqueue_and_run_job
7
7
  Resque.enqueue(TestResqueJob)
8
8
  queue = ENV['QUEUE'] ='resque_coverband'
9
- Resque::Worker.new.work_one_job
9
+ worker = Resque::Worker.new
10
+ worker.startup
11
+ worker.work_one_job
10
12
  end
11
13
 
12
14
  def setup
13
15
  super
14
16
  Coverband.configure do |config|
15
17
  config.background_reporting_enabled = false
18
+ config.root_paths = ["#{File.expand_path('../', File.dirname(__FILE__))}/"]
16
19
  end
17
20
  Coverband.start
18
21
  redis = Coverband.configuration.store.send(:redis)
@@ -20,16 +23,14 @@ class ResqueWorkerTest < Minitest::Test
20
23
  end
21
24
 
22
25
  test 'resque job coverage' do
26
+ relative_job_file = './integrations/test_resque_job.rb'
23
27
  resque_job_file = File.expand_path('./test_resque_job.rb', File.dirname(__FILE__))
24
28
  require resque_job_file
25
29
 
26
- #report after loading the file in parent process
27
- Coverband::Collectors::Coverage.instance.report_coverage(true)
28
-
29
30
  enqueue_and_run_job
30
31
 
31
- puts "assert_equal 1, Coverband.configuration.store.coverage['#{resque_job_file}']['data'][4]"
32
- assert_equal 1, Coverband.configuration.store.coverage[resque_job_file]['data'][4]
32
+ assert !Coverband::Background.running?
33
+
34
+ assert_equal 1, Coverband.configuration.store.coverage[relative_job_file]['data'][4]
33
35
  end
34
36
  end
35
-
@@ -0,0 +1,168 @@
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path('../../test_helper', File.dirname(__FILE__))
4
+
5
+ class ReportsBaseTest < Minitest::Test
6
+ test 'relative_path_to_full fix filename from a key with a swappable path' do
7
+ Coverband.configure do |config|
8
+ config.reporter = 'std_out'
9
+ config.root = '/full/remote_app/path'
10
+ end
11
+
12
+ key = '/app/is/a/path.rb'
13
+ # the code takes config.root expands and adds a '/' for the final path in roots
14
+ roots = ['/app/', '/full/remote_app/path/']
15
+
16
+ expected_path = '/full/remote_app/path/is/a/path.rb'
17
+ File.expects(:exist?).with(key).returns(false)
18
+ File.expects(:exist?).with(expected_path).returns(true)
19
+ assert_equal expected_path, Coverband::Reporters::Base.send(:relative_path_to_full, key, roots)
20
+ end
21
+
22
+ test 'relative_path_to_full fix filename a changing deploy path with quotes' do
23
+ Coverband.configure do |config|
24
+ config.reporter = 'std_out'
25
+ config.root = '/full/remote_app/path'
26
+ end
27
+
28
+ expected_path = '/full/remote_app/path/app/models/user.rb'
29
+ key = '/box/apps/app_name/releases/20140725203539/app/models/user.rb'
30
+ roots = ["/box/apps/app_name/releases/\\d+/", '/full/remote_app/path/']
31
+ File.expects(:exist?).with('/box/apps/app_name/releases/\\d+/app/models/user.rb').returns(false)
32
+ File.expects(:exist?).with(expected_path).returns(true)
33
+ assert_equal expected_path, Coverband::Reporters::Base.send(:relative_path_to_full, key, roots)
34
+ File.expects(:exist?).with('/box/apps/app_name/releases/\\d+/app/models/user.rb').returns(false)
35
+ File.expects(:exist?).with(expected_path).returns(true)
36
+ roots = ['/box/apps/app_name/releases/\d+/', '/full/remote_app/path/']
37
+ assert_equal expected_path, Coverband::Reporters::Base.send(:relative_path_to_full, key, roots)
38
+ end
39
+
40
+ test 'relative_path_to_full fix filename a changing deploy path real world examples' do
41
+ current_app_root = '/var/local/company/company.d/79'
42
+ Coverband.configure do |config|
43
+ config.reporter = 'std_out'
44
+ config.root = current_app_root
45
+ end
46
+
47
+ expected_path = '/var/local/company/company.d/79/app/controllers/dashboard_controller.rb'
48
+ key = '/var/local/company/company.d/78/app/controllers/dashboard_controller.rb'
49
+
50
+ File.expects(:exist?).with('/var/local/company/company.d/[0-9]*/app/controllers/dashboard_controller.rb').returns(false)
51
+ File.expects(:exist?).with(expected_path).returns(true)
52
+ roots = ['/var/local/company/company.d/[0-9]*/', "#{current_app_root}/"]
53
+ assert_equal expected_path, Coverband::Reporters::Base.send(:relative_path_to_full, key, roots)
54
+ File.expects(:exist?).with('/var/local/company/company.d/[0-9]*/app/controllers/dashboard_controller.rb').returns(false)
55
+ File.expects(:exist?).with(expected_path).returns(true)
56
+ roots = ["/var/local/company/company.d/[0-9]*/", "#{current_app_root}/"]
57
+ assert_equal expected_path, Coverband::Reporters::Base.send(:relative_path_to_full, key, roots)
58
+ end
59
+
60
+ test 'relative_path_to_full leave filename from a key with a local path' do
61
+ Coverband.configure do |config|
62
+ config.reporter = 'std_out'
63
+ config.root = '/full/remote_app/path'
64
+ end
65
+
66
+ key = '/full/remote_app/path/is/a/path.rb'
67
+ # the code takes config.root expands and adds a '/' for the final path in roots
68
+ roots = ['/app/', '/full/remote_app/path/']
69
+
70
+ expected_path = '/full/remote_app/path/is/a/path.rb'
71
+ assert_equal expected_path, Coverband::Reporters::Base.send(:relative_path_to_full, key, roots)
72
+ end
73
+
74
+ test '#merge_arrays basic merge preserves order and counts' do
75
+ first = [0, 0, 1, 0, 1]
76
+ second = [nil, 0, 1, 0, 0]
77
+ expects = [0, 0, 2, 0, 1]
78
+
79
+ assert_equal expects, Coverband::Reporters::Base.send(:merge_arrays, first, second)
80
+ end
81
+
82
+ test '#merge_arrays basic merge preserves order and counts different lengths' do
83
+ first = [0, 0, 1, 0, 1]
84
+ second = [nil, 0, 1, 0, 0, 0, 0, 1]
85
+ expects = [0, 0, 2, 0, 1, 0, 0, 1]
86
+
87
+ assert_equal expects, Coverband::Reporters::Base.send(:merge_arrays, first, second)
88
+ end
89
+
90
+ test '#merge_arrays basic merge preserves nils' do
91
+ first = [0, 1, 2, nil, nil, nil]
92
+ second = [0, 1, 2, nil, 0, 1, 2]
93
+ expects = [0, 2, 4, nil, 0, 1, 2]
94
+
95
+ assert_equal expects, Coverband::Reporters::Base.send(:merge_arrays, first, second)
96
+ end
97
+
98
+ test "#get_current_scov_data_imp doesn't ignore folders with default ignore keys" do
99
+ @redis = Redis.new
100
+ store = Coverband::Adapters::RedisStore.new(@redis)
101
+ store.clear!
102
+
103
+ Coverband.configure do |config|
104
+ config.reporter = 'std_out'
105
+ config.root = '/full/remote_app/path'
106
+ config.store = store
107
+ end
108
+
109
+ key = '/a_path/that_has_erb_in/thepath.rb'
110
+ roots = ['/app/', '/full/remote_app/path/']
111
+
112
+ lines_hit = [1, 3, 6]
113
+ store.stubs(:coverage).returns(key => lines_hit)
114
+ expected = { key => [1, 3, 6] }
115
+
116
+ assert_equal expected, Coverband::Reporters::Base.send(:get_current_scov_data_imp, store, roots)
117
+ end
118
+
119
+ ###
120
+ # This test uses real world example data which helped uncover a bug
121
+ # The copied data doesn't format easily and isn't worth the effort to meet
122
+ # string style
123
+ # rubocop:disable all
124
+ ###
125
+ test '#get_current_scov_data_imp merges multiples of file data' do
126
+ coverage = {'/base/66/app/controllers/dashboard_controller.rb' =>
127
+ {"first_updated_at"=>1549610119,
128
+ "last_updated_at"=>1549610200,
129
+ "file_hash"=>"14dc84e940e26cbfb9ac79b43862e762",
130
+ "data"=>[1, 1, 1, nil, 1, 1, nil, nil, 1, nil, 1, 26, 26, nil, 26, 26, 26, 26, 26, 26, 26, nil, nil, 1, nil, 1, 26, 19, 0, 0, 0, 0, nil, nil, nil, nil, 0, 0, nil, nil, 1, 26, 26, 26, nil, nil, nil, nil, nil, 1, 26, nil, nil, 1, 26, nil, nil]},
131
+ '/base/78/app/controllers/dashboard_controller.rb' =>
132
+ {"first_updated_at"=>1549658574,
133
+ "last_updated_at"=>1549729830,
134
+ "file_hash"=>"14dc84e940e26cbfb9ac79b43862e762",
135
+ "data"=>[21, 21, 21, nil, 21, 21, nil, nil, 21, nil, 21, 22, 22, nil, 22, 22, 22, 22, 22, 22, 22, nil, nil, 21, nil, 21, 22, 13, 0, 0, 0, 0, nil, nil, nil, nil, 0, 0, nil, nil, 21, 22, 22, 22, nil, nil, nil, nil, nil, 21, 22, nil, nil, 21, 22, nil, nil]},
136
+ '/base/70/app/controllers/dashboard_controller.rb' =>
137
+ {"first_updated_at"=>1549617873,
138
+ "last_updated_at"=>1549618094,
139
+ "file_hash"=>"14dc84e940e26cbfb9ac79b43862e762",
140
+ "data"=>[16, 16, 16, nil, 16, 16, nil, nil, 16, nil, 16, 32, 32, nil, 32, 32, 32, 32, 32, 32, 32, nil, nil, 16, nil, 16, 32, 23, 0, 0, 0, 0, nil, nil, nil, nil, 0, 0, nil, nil, 16, 32, 32, 32, nil, nil, nil, nil, nil, 16, 32, nil, nil, 16, 32, nil, nil]}
141
+ }
142
+ @redis = Redis.new
143
+ store = Coverband::Adapters::RedisStore.new(@redis)
144
+ store.clear!
145
+
146
+ Coverband.configure do |config|
147
+ config.reporter = 'std_out'
148
+ config.root = '/base/78/app/'
149
+ config.store = store
150
+ end
151
+
152
+ key = '/base/78/app/app/controllers/dashboard_controller.rb'
153
+ roots = ['/base/[0-9]*/', '/base/78/app/']
154
+
155
+ lines_hit = [1, 3, 6]
156
+ store.stubs(:coverage).returns(coverage)
157
+ File.expects(:exist?).at_least_once
158
+ .with('/base/[0-9]*/app/controllers/dashboard_controller.rb')
159
+ .returns(false)
160
+ File.expects(:exist?).at_least_once.with(key).returns(true)
161
+
162
+ expected = {"first_updated_at"=>1549617873,
163
+ "last_updated_at"=>1549618094,
164
+ "file_hash"=>"14dc84e940e26cbfb9ac79b43862e762",
165
+ "data"=>[38, 38, 38, nil, 38, 38, nil, nil, 38, nil, 38, 80, 80, nil, 80, 80, 80, 80, 80, 80, 80, nil, nil, 38, nil, 38, 80, 55, 0, 0, 0, 0, nil, nil, nil, nil, 0, 0, nil, nil, 38, 80, 80, 80, nil, nil, nil, nil, nil, 38, 80, nil, nil, 38, 80, nil, nil]}
166
+ assert_equal expected, Coverband::Reporters::Base.send(:get_current_scov_data_imp, store, roots)[key]
167
+ end
168
+ end