coverband 4.2.0.beta → 4.2.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
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