coverband 1.5.4 → 2.0.0.alpha

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.travis.yml +3 -0
  4. data/Gemfile +2 -1
  5. data/Rakefile +5 -3
  6. data/coverband.gemspec +27 -23
  7. data/lib/coverband.rb +10 -14
  8. data/lib/coverband/adapters/file_store.rb +6 -7
  9. data/lib/coverband/adapters/memory_cache_store.rb +8 -5
  10. data/lib/coverband/adapters/redis_store.rb +10 -50
  11. data/lib/coverband/baseline.rb +5 -5
  12. data/lib/coverband/collectors/base.rb +140 -0
  13. data/lib/coverband/collectors/coverage.rb +148 -0
  14. data/lib/coverband/collectors/trace.rb +100 -0
  15. data/lib/coverband/configuration.rb +8 -10
  16. data/lib/coverband/middleware.rb +5 -5
  17. data/lib/coverband/reporters/base.rb +26 -31
  18. data/lib/coverband/reporters/console_report.rb +2 -3
  19. data/lib/coverband/reporters/simple_cov_report.rb +5 -6
  20. data/lib/coverband/s3_report_writer.rb +7 -8
  21. data/lib/coverband/s3_web.rb +3 -5
  22. data/lib/coverband/tasks.rb +23 -26
  23. data/lib/coverband/version.rb +3 -1
  24. data/test/benchmarks/benchmark.rake +38 -32
  25. data/test/benchmarks/dog.rb +3 -3
  26. data/test/fake_app/basic_rack.rb +4 -2
  27. data/test/test_helper.rb +17 -11
  28. data/test/unit/adapters_file_store_test.rb +12 -11
  29. data/test/unit/adapters_memory_cache_store_test.rb +3 -4
  30. data/test/unit/adapters_redis_store_test.rb +42 -118
  31. data/test/unit/baseline_test.rb +17 -20
  32. data/test/unit/collectors_base_test.rb +96 -0
  33. data/test/unit/collectors_coverage_test.rb +137 -0
  34. data/test/unit/collectors_trace_test.rb +96 -0
  35. data/test/unit/configuration_test.rb +8 -8
  36. data/test/unit/dog.rb +3 -1
  37. data/test/unit/middleware_test.rb +70 -61
  38. data/test/unit/reports_base_test.rb +62 -62
  39. data/test/unit/reports_console_test.rb +18 -21
  40. data/test/unit/reports_simple_cov_test.rb +23 -26
  41. data/test/unit/s3_report_writer_test.rb +6 -8
  42. data/test/unit/s3_web_test.rb +2 -1
  43. metadata +45 -25
  44. data/lib/coverband/base.rb +0 -210
  45. data/test/unit/base_test.rb +0 -100
@@ -1,37 +1,34 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require File.expand_path('../test_helper', File.dirname(__FILE__))
2
4
 
3
5
  class SimpleCovReportTest < Test::Unit::TestCase
4
6
  BASE_KEY = Coverband::Adapters::RedisStore::BASE_KEY
5
7
 
6
8
  def setup
7
- @fake_redis = fake_redis
8
- @store = Coverband::Adapters::RedisStore.new(@fake_redis, array: true)
9
+ @redis = Redis.new
10
+ @redis.flushdb
11
+ @store = Coverband::Adapters::RedisStore.new(@redis)
12
+ end
13
+
14
+ def example_hash
15
+ {'1' => '1', '2' => '2'}
9
16
  end
10
17
 
11
- test "report data" do
18
+ test 'report data' do
12
19
  Coverband.configure do |config|
13
- config.redis = @fake_redis
20
+ config.redis = @redis
14
21
  config.reporter = 'std_out'
22
+ config.store = @store
15
23
  end
16
-
17
- Coverband::Reporters::ConsoleReport.expects(:current_root).returns('/tmp/root_dir')
18
- @fake_redis.expects(:smembers).with(BASE_KEY).returns(fake_coverband_members)
19
-
20
- fake_coverband_members.each do |key|
21
- File.expects(:exists?).with(key).returns(true)
22
- File.expects(:foreach).with(key).returns(Array.new(4){'LOC'})
23
- @fake_redis.expects(:smembers).with("#{BASE_KEY}.#{key}").returns(["1", "3"])
24
- end
25
-
26
24
  Coverband.configuration.logger.stubs('info')
25
+ Coverband::Reporters::ConsoleReport.expects(:current_root).returns('./test/unit')
27
26
 
28
- report = Coverband::Reporters::ConsoleReport.report(@store)
29
- expected = {"/Users/danmayer/projects/hearno/app/controllers/application_controller.rb"=>
30
- [1, nil, 1, nil],
31
- "/Users/danmayer/projects/hearno/app/models/account.rb"=>[1, nil, 1, nil],
32
- "/Users/danmayer/projects/hearno/script/tester.rb"=>[1, nil, 1, nil]}
27
+ @redis.sadd(BASE_KEY, 'test/unit/dog.rb')
28
+ @store.send(:store_map, "#{BASE_KEY}.test/unit/dog.rb", example_hash)
33
29
 
30
+ report = Coverband::Reporters::ConsoleReport.report(@store)
31
+ expected = {"test/unit/dog.rb"=>[1, 2, nil, nil, nil, nil, nil]}
34
32
  assert_equal(expected, report)
35
33
  end
36
-
37
- end
34
+ end
@@ -1,61 +1,59 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require File.expand_path('../test_helper', File.dirname(__FILE__))
2
4
 
3
5
  class ReportsSimpleCovTest < Test::Unit::TestCase
4
6
  BASE_KEY = Coverband::Adapters::RedisStore::BASE_KEY
5
7
 
6
8
  def setup
7
- @fake_redis = fake_redis
8
- @store = Coverband::Adapters::RedisStore.new(@fake_redis, array: true)
9
+ @redis = Redis.new
10
+ @redis.flushdb
11
+ @store = Coverband::Adapters::RedisStore.new(@redis)
12
+ end
13
+
14
+ def example_hash
15
+ {'1' => '1', '2' => '2'}
9
16
  end
10
17
 
11
- test "generate scov report" do
18
+ test 'generate scov report' do
12
19
  Coverband.configure do |config|
13
- config.redis = @fake_redis
20
+ config.redis = @redis
14
21
  config.reporter = 'scov'
15
22
  config.s3_bucket = nil
16
- config.ignore = ["notsomething.rb"]
23
+ config.store = @store
24
+ config.ignore = ['notsomething.rb']
17
25
  end
26
+ Coverband.configuration.logger.stubs('info')
18
27
 
19
- Coverband::Reporters::SimpleCovReport.expects(:current_root).at_least_once.returns('/tmp/root_dir')
20
- @fake_redis.expects(:smembers).with(BASE_KEY).returns(fake_coverband_members)
28
+ @redis.sadd(BASE_KEY, 'test/unit/dog.rb')
29
+ @store.send(:store_map, "#{BASE_KEY}.test/unit/dog.rb", example_hash)
21
30
 
22
31
  SimpleCov.expects(:track_files)
23
32
  SimpleCov.expects(:add_not_loaded_files).returns({})
24
33
  SimpleCov::Result.any_instance.expects(:format!)
25
34
  SimpleCov.stubs(:root)
26
35
 
27
- fake_coverband_members.each do |key|
28
- File.expects(:exists?).with(key).returns(true)
29
- File.expects(:foreach).with(key).returns(Array.new(60){'LOC'})
30
- @fake_redis.expects(:smembers).with("#{BASE_KEY}.#{key}").returns(["54", "55"])
31
- end
32
-
33
- Coverband.configuration.logger.stubs('info')
34
-
35
36
  Coverband::Reporters::SimpleCovReport.report(@store, open_report: false)
36
37
  end
37
38
 
38
- test "generate scov report with additional data" do
39
+ test 'generate scov report with additional data' do
39
40
  Coverband.configure do |config|
40
- config.redis = @fake_redis
41
+ config.redis = @redis
41
42
  config.reporter = 'scov'
42
43
  config.s3_bucket = nil
43
- config.ignore = ["notsomething.rb"]
44
+ config.store = @store
45
+ config.ignore = ['notsomething.rb']
44
46
  end
45
47
 
46
48
  Coverband::Reporters::SimpleCovReport.expects(:current_root).at_least_once.returns('/tmp/root_dir')
47
- @fake_redis.expects(:smembers).with(BASE_KEY).returns(fake_coverband_members)
48
49
 
50
+ @redis.sadd(BASE_KEY, 'test/unit/dog.rb')
51
+ @store.send(:store_map, "#{BASE_KEY}.test/unit/dog.rb", example_hash)
49
52
  SimpleCov.expects(:track_files)
50
- SimpleCov.expects(:add_not_loaded_files).returns({"fake_file.rb" => [1]})
53
+ SimpleCov.expects(:add_not_loaded_files).returns('fake_file.rb' => [1])
51
54
  SimpleCov::Result.any_instance.expects(:format!)
52
55
  SimpleCov.stubs(:root)
53
56
 
54
- fake_coverband_members.each do |key|
55
- File.expects(:exists?).with(key).returns(true)
56
- File.expects(:foreach).with(key).returns(['a','b','c'])
57
- @fake_redis.expects(:smembers).with("#{BASE_KEY}.#{key}").returns(["54", "55"])
58
- end
59
57
 
60
58
  Coverband.configuration.logger.stubs('info')
61
59
  additional_data = [
@@ -64,5 +62,4 @@ class ReportsSimpleCovTest < Test::Unit::TestCase
64
62
 
65
63
  Coverband::Reporters::SimpleCovReport.report(@store, open_report: false, additional_scov_data: additional_data)
66
64
  end
67
-
68
65
  end
@@ -1,16 +1,16 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require File.expand_path('../test_helper', File.dirname(__FILE__))
2
4
  require 'aws-sdk'
3
5
 
4
6
  module Coverband
5
-
6
7
  class S3ReportWriterTest < Test::Unit::TestCase
7
-
8
8
  def html_version
9
- "#{Gem::Specification.find_by_name('simplecov-html').version.version}"
10
- rescue
11
- "0.10.1"
9
+ Gem::Specification.find_by_name('simplecov-html').version.version.to_s
10
+ rescue StandardError
11
+ '0.10.1'
12
12
  end
13
-
13
+
14
14
  test 'it writes the coverage report to s3' do
15
15
  s3 = mock('s3_resource')
16
16
  bucket = mock('bucket')
@@ -22,7 +22,5 @@ module Coverband
22
22
  Aws::S3::Resource.expects(:new).returns(s3)
23
23
  S3ReportWriter.new('coverage-bucket').persist!
24
24
  end
25
-
26
25
  end
27
-
28
26
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require File.expand_path('../test_helper', File.dirname(__FILE__))
2
4
  require File.expand_path('../../lib/coverband/s3_web', File.dirname(__FILE__))
3
5
  require 'rack/test'
@@ -6,7 +8,6 @@ ENV['RACK_ENV'] = 'test'
6
8
 
7
9
  module Coverband
8
10
  class S3WebTest < Test::Unit::TestCase
9
-
10
11
  include Rack::Test::Methods
11
12
 
12
13
  def app
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: coverband
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.4
4
+ version: 2.0.0.alpha
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Mayer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-14 00:00:00.000000000 Z
11
+ date: 2018-04-17 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: aws-sdk
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bundler
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -25,7 +39,7 @@ dependencies:
25
39
  - !ruby/object:Gem::Version
26
40
  version: '1.3'
27
41
  - !ruby/object:Gem::Dependency
28
- name: rake
42
+ name: classifier-reborn
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
45
  - - ">="
@@ -81,7 +95,7 @@ dependencies:
81
95
  - !ruby/object:Gem::Version
82
96
  version: '0'
83
97
  - !ruby/object:Gem::Dependency
84
- name: test-unit
98
+ name: rake
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
101
  - - ">="
@@ -109,7 +123,7 @@ dependencies:
109
123
  - !ruby/object:Gem::Version
110
124
  version: '0'
111
125
  - !ruby/object:Gem::Dependency
112
- name: classifier-reborn
126
+ name: test-unit
113
127
  requirement: !ruby/object:Gem::Requirement
114
128
  requirements:
115
129
  - - ">="
@@ -123,47 +137,47 @@ dependencies:
123
137
  - !ruby/object:Gem::Version
124
138
  version: '0'
125
139
  - !ruby/object:Gem::Dependency
126
- name: aws-sdk
140
+ name: byebug
127
141
  requirement: !ruby/object:Gem::Requirement
128
142
  requirements:
129
- - - "~>"
143
+ - - ">="
130
144
  - !ruby/object:Gem::Version
131
- version: '2'
145
+ version: '0'
132
146
  type: :development
133
147
  prerelease: false
134
148
  version_requirements: !ruby/object:Gem::Requirement
135
149
  requirements:
136
- - - "~>"
150
+ - - ">="
137
151
  - !ruby/object:Gem::Version
138
- version: '2'
152
+ version: '0'
139
153
  - !ruby/object:Gem::Dependency
140
- name: simplecov
154
+ name: json
141
155
  requirement: !ruby/object:Gem::Requirement
142
156
  requirements:
143
- - - ">"
157
+ - - ">="
144
158
  - !ruby/object:Gem::Version
145
- version: 0.11.1
159
+ version: '0'
146
160
  type: :runtime
147
161
  prerelease: false
148
162
  version_requirements: !ruby/object:Gem::Requirement
149
163
  requirements:
150
- - - ">"
164
+ - - ">="
151
165
  - !ruby/object:Gem::Version
152
- version: 0.11.1
166
+ version: '0'
153
167
  - !ruby/object:Gem::Dependency
154
- name: json
168
+ name: simplecov
155
169
  requirement: !ruby/object:Gem::Requirement
156
170
  requirements:
157
- - - ">="
171
+ - - ">"
158
172
  - !ruby/object:Gem::Version
159
- version: '0'
173
+ version: 0.11.1
160
174
  type: :runtime
161
175
  prerelease: false
162
176
  version_requirements: !ruby/object:Gem::Requirement
163
177
  requirements:
164
- - - ">="
178
+ - - ">"
165
179
  - !ruby/object:Gem::Version
166
- version: '0'
180
+ version: 0.11.1
167
181
  - !ruby/object:Gem::Dependency
168
182
  name: redis
169
183
  requirement: !ruby/object:Gem::Requirement
@@ -200,8 +214,10 @@ files:
200
214
  - lib/coverband/adapters/file_store.rb
201
215
  - lib/coverband/adapters/memory_cache_store.rb
202
216
  - lib/coverband/adapters/redis_store.rb
203
- - lib/coverband/base.rb
204
217
  - lib/coverband/baseline.rb
218
+ - lib/coverband/collectors/base.rb
219
+ - lib/coverband/collectors/coverage.rb
220
+ - lib/coverband/collectors/trace.rb
205
221
  - lib/coverband/configuration.rb
206
222
  - lib/coverband/middleware.rb
207
223
  - lib/coverband/reporters/base.rb
@@ -219,8 +235,10 @@ files:
219
235
  - test/unit/adapters_file_store_test.rb
220
236
  - test/unit/adapters_memory_cache_store_test.rb
221
237
  - test/unit/adapters_redis_store_test.rb
222
- - test/unit/base_test.rb
223
238
  - test/unit/baseline_test.rb
239
+ - test/unit/collectors_base_test.rb
240
+ - test/unit/collectors_coverage_test.rb
241
+ - test/unit/collectors_trace_test.rb
224
242
  - test/unit/configuration_test.rb
225
243
  - test/unit/dog.rb
226
244
  - test/unit/middleware_test.rb
@@ -244,9 +262,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
244
262
  version: '0'
245
263
  required_rubygems_version: !ruby/object:Gem::Requirement
246
264
  requirements:
247
- - - ">="
265
+ - - ">"
248
266
  - !ruby/object:Gem::Version
249
- version: '0'
267
+ version: 1.3.1
250
268
  requirements: []
251
269
  rubyforge_project:
252
270
  rubygems_version: 2.5.1
@@ -262,8 +280,10 @@ test_files:
262
280
  - test/unit/adapters_file_store_test.rb
263
281
  - test/unit/adapters_memory_cache_store_test.rb
264
282
  - test/unit/adapters_redis_store_test.rb
265
- - test/unit/base_test.rb
266
283
  - test/unit/baseline_test.rb
284
+ - test/unit/collectors_base_test.rb
285
+ - test/unit/collectors_coverage_test.rb
286
+ - test/unit/collectors_trace_test.rb
267
287
  - test/unit/configuration_test.rb
268
288
  - test/unit/dog.rb
269
289
  - test/unit/middleware_test.rb
@@ -1,210 +0,0 @@
1
- require 'singleton'
2
- require 'set'
3
-
4
- module Coverband
5
- class Base
6
-
7
- def self.instance
8
- Thread.current[:coverband_instance] ||= Coverband::Base.new
9
- end
10
-
11
- def start
12
- @enabled = true
13
- record_coverage
14
- end
15
-
16
- def stop
17
- @enabled = false
18
- unset_tracer
19
- end
20
-
21
- def sample
22
- configure_sampling
23
- record_coverage
24
- result = yield
25
- report_coverage
26
- result
27
- end
28
-
29
- def save
30
- @enabled = true
31
- report_coverage
32
- @enabled = false
33
- end
34
-
35
- def extended?
36
- false
37
- end
38
-
39
- def reset_instance
40
- @project_directory = File.expand_path(Coverband.configuration.root)
41
- @enabled = false
42
- @disable_on_failure_for = Coverband.configuration.disable_on_failure_for
43
- @tracer_set = false
44
- @file_line_usage = {}
45
- @ignored_files = Set.new
46
- @startup_delay = Coverband.configuration.startup_delay
47
- @ignore_patterns = Coverband.configuration.ignore + ['internal:prelude', 'schema.rb']
48
- @ignore_patterns += ['gems'] unless Coverband.configuration.include_gems
49
- @sample_percentage = Coverband.configuration.percentage
50
- @store = Coverband.configuration.store
51
- @store = Coverband::Adapters::MemoryCacheStore.new(@store) if Coverband.configuration.memory_caching
52
- @stats = Coverband.configuration.stats
53
- @verbose = Coverband.configuration.verbose
54
- @logger = Coverband.configuration.logger
55
- @current_thread = Thread.current
56
- @trace = create_trace_point
57
- self
58
- end
59
-
60
- def configure_sampling
61
- if @startup_delay!=0 || (rand * 100.0) > @sample_percentage
62
- @startup_delay -= 1 if @startup_delay > 0
63
- @enabled = false
64
- else
65
- @enabled = true
66
- end
67
- end
68
-
69
- def record_coverage
70
- if @enabled && !failed_recently?
71
- set_tracer
72
- else
73
- unset_tracer
74
- end
75
- @stats.increment "coverband.request.recorded.#{@enabled}" if @stats
76
- rescue RuntimeError => err
77
- failed!
78
- if @verbose
79
- @logger.info "error stating recording coverage"
80
- @logger.info "error: #{err.inspect} #{err.message}"
81
- end
82
- end
83
-
84
- def report_coverage
85
- unless @enabled
86
- @logger.info "coverage disabled" if @verbose
87
- return
88
- end
89
-
90
- unset_tracer
91
-
92
- if failed_recently?
93
- @logger.info "coverage reporting sanding-by because of recent failure" if @verbose
94
- return
95
- end
96
-
97
- if @verbose
98
- @logger.info "coverband file usage: #{file_usage.inspect}"
99
- if @verbose=="debug"
100
- output_file_line_usage
101
- end
102
- end
103
-
104
- if @store
105
- if @stats
106
- @before_time = Time.now
107
- @stats.count "coverband.files.recorded_files", @file_line_usage.length
108
- end
109
- @store.save_report(@file_line_usage)
110
- if @stats
111
- @time_spent = Time.now - @before_time
112
- @stats.timing "coverband.files.recorded_time", @time_spent
113
- end
114
- @file_line_usage.clear
115
- elsif @verbose
116
- @logger.info "coverage report: "
117
- @logger.info @file_line_usage.inspect
118
- end
119
- rescue RuntimeError => err
120
- failed!
121
- if @verbose
122
- @logger.info "coverage missing"
123
- @logger.info "error: #{err.inspect} #{err.message}"
124
- end
125
- end
126
-
127
- protected
128
-
129
- def track_file? file
130
- !@ignore_patterns.any?{ |pattern| file.include?(pattern) } && file.start_with?(@project_directory)
131
- end
132
-
133
- def set_tracer
134
- unless @tracer_set
135
- @trace.enable
136
- @tracer_set = true
137
- end
138
- end
139
-
140
- def unset_tracer
141
- @trace.disable
142
- @tracer_set = false
143
- end
144
-
145
- def output_file_line_usage
146
- @logger.info "coverband debug coverband file:line usage:"
147
- @file_line_usage.sort_by {|_key, value| value.length}.each do |pair|
148
- file = pair.first
149
- lines = pair.last
150
- @logger.info "file: #{file} => #{lines.sort_by {|_key, value| value}}"
151
- end
152
- end
153
-
154
- private
155
-
156
- def failed_at_thread_key
157
- "__#{self.class.name}__failed_at"
158
- end
159
-
160
- def failed_at
161
- Thread.current[failed_at_thread_key]
162
- end
163
-
164
- def failed_at=(time)
165
- Thread.current[failed_at_thread_key] = time
166
- end
167
-
168
- def failed!
169
- self.failed_at = Time.now
170
- end
171
-
172
- def failed_recently?
173
- return false unless @disable_on_failure_for && failed_at
174
- failed_at + @disable_on_failure_for > Time.now
175
- end
176
-
177
- def file_usage
178
- hash = {}
179
- @file_line_usage.each do |file, lines|
180
- hash[file] = lines.values.inject(0, :+)
181
- end
182
- hash.sort_by {|_key, value| value}
183
- end
184
-
185
- def add_file(file, line)
186
- @file_line_usage[file] = Hash.new(0) unless @file_line_usage.include?(file)
187
- @file_line_usage[file][line] += 1
188
- end
189
-
190
- def create_trace_point
191
- TracePoint.new(*Coverband.configuration.trace_point_events) do |tp|
192
- if Thread.current == @current_thread
193
- file = tp.path
194
- if !@ignored_files.include?(file)
195
- if track_file?(file)
196
- add_file(file, tp.lineno)
197
- else
198
- @ignored_files << file
199
- end
200
- end
201
- end
202
- end
203
- end
204
-
205
- def initialize
206
- reset_instance
207
- end
208
-
209
- end
210
- end