coverband 4.0.1.alpha → 4.0.1.beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -1
  3. data/.rubocop.yml +5 -15
  4. data/.travis.yml +1 -0
  5. data/LICENSE +1 -1
  6. data/LICENSE.txt +1 -1
  7. data/README.md +19 -2
  8. data/Rakefile +1 -1
  9. data/changes.md +3 -0
  10. data/coverband.gemspec +7 -4
  11. data/lib/coverband.rb +2 -3
  12. data/lib/coverband/configuration.rb +5 -1
  13. data/lib/coverband/integrations/background.rb +19 -10
  14. data/lib/coverband/reporters/html_report.rb +5 -1
  15. data/lib/coverband/reporters/web.rb +6 -59
  16. data/lib/coverband/utils/html_formatter.rb +18 -2
  17. data/lib/coverband/utils/result.rb +1 -0
  18. data/lib/coverband/utils/s3_report.rb +1 -1
  19. data/lib/coverband/utils/source_file.rb +1 -1
  20. data/lib/coverband/version.rb +1 -1
  21. data/public/application.css +37 -3
  22. data/public/application.js +50 -44
  23. data/test/fixtures/app/controllers/sample_controller.rb +10 -0
  24. data/test/fixtures/app/models/user.rb +10 -0
  25. data/test/fixtures/never.rb +2 -0
  26. data/test/fixtures/sample.rb +16 -0
  27. data/test/fixtures/skipped.rb +4 -0
  28. data/test/fixtures/skipped_and_executed.rb +8 -0
  29. data/test/fixtures/utf-8.rb +3 -0
  30. data/test/rails4_dummy/config/coverband.rb +1 -1
  31. data/test/rails4_dummy/config/routes.rb +1 -0
  32. data/test/rails5_dummy/config/coverband.rb +3 -2
  33. data/test/rails5_dummy/config/routes.rb +1 -0
  34. data/test/rails_test_helper.rb +6 -6
  35. data/test/test_helper.rb +50 -2
  36. data/test/unit/adapters_base_test.rb +2 -1
  37. data/test/unit/adapters_file_store_test.rb +2 -1
  38. data/test/unit/adapters_redis_store_test.rb +2 -1
  39. data/test/unit/background_test.rb +12 -7
  40. data/test/unit/collectors_coverage_test.rb +3 -2
  41. data/test/unit/configuration_test.rb +2 -1
  42. data/test/unit/coverband_test.rb +1 -1
  43. data/test/unit/full_stack_test.rb +1 -1
  44. data/test/unit/middleware_test.rb +2 -1
  45. data/test/unit/rack_server_checkout_test.rb +7 -8
  46. data/test/unit/rails_full_stack_test.rb +26 -10
  47. data/test/unit/reports_base_test.rb +1 -1
  48. data/test/unit/reports_console_test.rb +2 -1
  49. data/test/unit/reports_html_test.rb +2 -1
  50. data/test/unit/reports_web_test.rb +3 -2
  51. data/test/unit/utils/file_list_test.rb +54 -0
  52. data/test/unit/utils/lines_classifier_test.rb +109 -0
  53. data/test/unit/utils/result_test.rb +104 -0
  54. data/test/unit/{utils_s3_report_test.rb → utils/s3_report_test.rb} +4 -4
  55. data/test/unit/utils/source_file_line_test.rb +165 -0
  56. data/test/unit/utils/source_file_test.rb +149 -0
  57. data/views/layout.erb +10 -1
  58. metadata +65 -13
  59. data/Gemfile.rails4.lock +0 -164
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: b703432acb6be1cb77cb0e34fd86bc8e0480463d94a9bdb45f20e66ba34e75f1
4
- data.tar.gz: 43c3afcd4f7287463218f53591ebf6182ab1b27a38e3c211663e9b906af39e6b
2
+ SHA1:
3
+ metadata.gz: 287311c05b4d4bc1e85d1a8cc19d9a5630551fa8
4
+ data.tar.gz: f73c312bb5c4eceff8dd48e92d9191e5c57d80e9
5
5
  SHA512:
6
- metadata.gz: 0ddcd44028f889ec0521929a3df8e316a9f66468dbff070a9be8d4a5a80242caf643ea8129eca6bb3affbad07ae500068348a155047af67081a3e5561418ff03
7
- data.tar.gz: 18b93fa61005315692a8ed102deb4143778dbc8560e99bbcc0dc0a08b3ccd7919209444b567c10600d165aca9ee36306357d769175fd9a323f2f248c9cc09e01
6
+ metadata.gz: 2fd7fa9ceae554e6dba27834be7527b2df2a8160b68079124de97f3e986a0141dea24e467832c85881dd3f6753506b1fdc060d72226a0f009daf7c3dde66500c
7
+ data.tar.gz: 55566a5fef66122bcd908b6fb1d488727f55dabff12e0dfa0d73530727555c9bd6b6d7e104b1e14d9ebf5950984c7a82aaaa011e7aba68d32c923646d3a2f071
data/.gitignore CHANGED
@@ -5,7 +5,7 @@
5
5
  .yardoc
6
6
  .idea/
7
7
  .ruby-version
8
- Gemfile.lock
8
+ Gemfile*lock
9
9
  InstalledFiles
10
10
  _yardoc
11
11
  coverage
data/.rubocop.yml CHANGED
@@ -10,8 +10,6 @@ Metrics/LineLength:
10
10
  Max: 120
11
11
  Metrics/BlockNesting:
12
12
  Max: 5
13
- Bundler/OrderedGems:
14
- Enabled: false
15
13
  Metrics/CyclomaticComplexity:
16
14
  Enabled: false
17
15
  Metrics/PerceivedComplexity:
@@ -20,19 +18,13 @@ Metrics/AbcSize:
20
18
  Enabled: false
21
19
  Metrics/ClassLength:
22
20
  Enabled: false
23
- Metrics/BlockLength:
24
- Enabled: false
25
- Metrics/BlockNesting:
26
- Max: 10
27
21
  Metrics/ModuleLength:
28
22
  Enabled: false
29
23
  Metrics/ParameterLists:
30
24
  Max: 10
31
- Naming/AccessorMethodName:
32
- Enabled: false
33
- Naming/PredicateName:
25
+ Style/AccessorMethodName:
34
26
  Enabled: false
35
- Style/FormatStringToken:
27
+ Style/PredicateName:
36
28
  Enabled: false
37
29
  Style/TernaryParentheses:
38
30
  Enabled: false
@@ -52,11 +44,9 @@ Style/ClassAndModuleChildren:
52
44
  Enabled: false
53
45
  Performance/Casecmp:
54
46
  Enabled: false
55
- Layout/EmptyLinesAroundArguments:
56
- Enabled: true
57
- Layout/MultilineMethodCallIndentation:
47
+ Style/MultilineMethodCallIndentation:
58
48
  Enabled: true
59
- Layout/MultilineOperationIndentation:
49
+ Style/MultilineOperationIndentation:
60
50
  Enabled: true
61
51
  Lint/RescueException:
62
52
  Enabled: true
@@ -64,6 +54,6 @@ Lint/ShadowingOuterLocalVariable:
64
54
  Enabled: true
65
55
  Style/FormatString:
66
56
  Enabled: true
67
- Security/Eval:
57
+ Lint/Eval:
68
58
  Enabled: true
69
59
 
data/.travis.yml CHANGED
@@ -3,6 +3,7 @@ rvm:
3
3
  - "2.3"
4
4
  - "2.4"
5
5
  - "2.5"
6
+ - "2.6"
6
7
  gemfile:
7
8
  - Gemfile
8
9
  - Gemfile.rails4
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2013 Dan Mayer
3
+ Copyright (c) 2010-2018 Dan Mayer
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy of
6
6
  this software and associated documentation files (the "Software"), to deal in
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2013 Dan Mayer
1
+ Copyright (c) 2010-2018 Dan Mayer
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # Coverband
2
2
 
3
- Build Status: [![Build Status](https://travis-ci.org/danmayer/coverband.svg?branch=master)](https://travis-ci.org/danmayer/coverband)
3
+ [![Build Status](https://travis-ci.org/danmayer/coverband.svg?branch=master)](https://travis-ci.org/danmayer/coverband)
4
+ [![Coverage Status](https://coveralls.io/repos/github/danmayer/coverband/badge.svg?branch=master)](https://coveralls.io/github/danmayer/coverband?branch=master)
4
5
 
5
6
  <p align="center">
6
7
  <a href="#key-features">Key Features</a> •
@@ -8,7 +9,6 @@ Build Status: [![Build Status](https://travis-ci.org/danmayer/coverband.svg?bran
8
9
  <a href="#configuration">Configuration</a> •
9
10
  <a href="#coverband-demo">Coverband Demo</a> •
10
11
  <a href="#how-to-use">How To Use</a> •
11
- <a href="#usage">Usage</a> •
12
12
  <a href="#license">License</a> •
13
13
  <a href="/changes.md">Change Log / Roadmap</a>
14
14
  </p>
@@ -144,6 +144,23 @@ Below is my Coverband workflow, which hopefully will help other best use this li
144
144
  * After Coverband has been verified to be working on production, I let it run for a few weeks.
145
145
  * Then I view the report and start submitting PRs for the team to review delete large related sets of code that no longer are in use.
146
146
 
147
+ ### Coverband Web Endpoint
148
+
149
+ The web endpoint is a barebones endpoint that you can either expose direct (after authentication) or you can just link to the actions you wish to expose. The index is intended as a example to showcase all the features.
150
+
151
+ ![image](https://raw.github.com/danmayer/coverband/master/docs/coverband_web.png)
152
+ > The web index as available on the Coverband Demo site
153
+
154
+ * __collect data, update report, & view:__ This does everything need to view up to date Coverage
155
+ * it triggers a coverage collection on the current webserver process
156
+ * it generates a new html coverage report and pushes it to S3
157
+ * it then loads that report for you to view
158
+ * __view coverage report:__ Don't need to update the data just view the current report
159
+ * __update coverage data (collect coverage):__ This triggers coverage collection on the current webserver process
160
+ * __update coverage report (rebuild report):__ This will rebuild the HTML report from the latest available data
161
+ * __clear coverage report:__ This will clear the coverage data. This wipes out all collected data (__dangerous__)
162
+ * __reload Coverband files:__ This has Coverband reload files as configured (force reload of some files that might not capture Coverage on boot)
163
+
147
164
  ### Example apps
148
165
 
149
166
  - [Rails 5.2.x App](https://github.com/danmayer/coverage_demo)
data/Rakefile CHANGED
@@ -13,7 +13,7 @@ Rake::TestTask.new(:test) do |test|
13
13
  # exclude benchmark from the tests as the way it functions resets code coverage during executions
14
14
  # test.pattern = 'test/unit/*_test.rb'
15
15
  # using test files opposed to pattern as it outputs which files are run
16
- test.test_files = FileList['test/unit/*_test.rb']
16
+ test.test_files = FileList['test/unit/**/*_test.rb']
17
17
  test.verbose = true
18
18
  end
19
19
 
data/changes.md CHANGED
@@ -36,6 +36,8 @@ Will be the fully modern release that drops maintenance legacy support in favor
36
36
  - add meta data information first seen last recorded to the coverage report views (probably need to drop simplecov for that).
37
37
  - more details in this issue: https://github.com/danmayer/coverband/issues/118
38
38
  - Make good video on setup, install, usage
39
+ - See if we can add support for views / templates
40
+ - using this technique https://github.com/ioquatix/covered
39
41
 
40
42
  ### Coverband_jam_session
41
43
 
@@ -67,6 +69,7 @@ Feature Ideas:
67
69
  - drops simplecov runtime dependency
68
70
  - still used to measure our own code coverage ;)
69
71
  - thanks SimpleCov for all the years of solid HTML reporting, and support!
72
+ - reduced the S3 dependencies to minimal set (not loading all of aws-sdk), ensured they are optional
70
73
 
71
74
  # Released
72
75
 
data/coverband.gemspec CHANGED
@@ -7,7 +7,7 @@ require 'coverband/version'
7
7
  Gem::Specification.new do |spec|
8
8
  spec.name = 'coverband'
9
9
  spec.version = Coverband::VERSION
10
- spec.authors = ['Dan Mayer']
10
+ spec.authors = ['Dan Mayer', 'Karl Baum']
11
11
  spec.email = ['dan@mayerdan.com']
12
12
  spec.description = 'Rack middleware to help measure production code usage (LOC runtime usage)'
13
13
  spec.summary = 'Rack middleware to help measure production code usage (LOC runtime usage)'
@@ -22,21 +22,24 @@ Gem::Specification.new do |spec|
22
22
  # to test support for sdk 1, uncomment this line
23
23
  # spec.add_development_dependency 'aws-sdk', '~> 1'
24
24
  # to test sdk 2 use this one
25
- spec.add_development_dependency 'aws-sdk', '~> 2'
25
+ spec.add_development_dependency 'aws-sdk-s3', '~> 1'
26
26
  spec.add_development_dependency 'benchmark-ips'
27
27
  spec.add_development_dependency 'bundler', '~> 1.3'
28
+ spec.add_development_dependency 'capybara'
28
29
  spec.add_development_dependency 'm'
29
30
  spec.add_development_dependency 'memory_profiler'
30
- spec.add_development_dependency 'mocha', '~> 0.14.0'
31
+ spec.add_development_dependency 'minitest'
32
+ spec.add_development_dependency 'mocha', '~> 1.7.0'
31
33
  spec.add_development_dependency 'rack'
32
34
  spec.add_development_dependency 'rack-test'
33
35
  spec.add_development_dependency 'rake'
34
36
  spec.add_development_dependency 'simplecov'
35
- spec.add_development_dependency 'test-unit'
37
+
36
38
 
37
39
  # TODO: used for benchmarking and tests I think we have other better benchmarking
38
40
  # perhaps time to drop this and refactor.
39
41
  spec.add_development_dependency 'classifier-reborn'
42
+ spec.add_development_dependency 'coveralls'
40
43
  # add when debugging
41
44
  # require 'byebug'; byebug
42
45
  spec.add_development_dependency 'pry-byebug'
data/lib/coverband.rb CHANGED
@@ -34,13 +34,12 @@ module Coverband
34
34
  end
35
35
 
36
36
  def self.configure(file = nil)
37
- configuration_file = file || CONFIG_FILE
38
-
37
+ configuration_file = file || ENV.fetch('COVERBAND_CONFIG', CONFIG_FILE)
39
38
  configuration
40
39
  if block_given?
41
40
  yield(configuration)
42
41
  elsif File.exist?(configuration_file)
43
- require configuration_file
42
+ load configuration_file
44
43
  else
45
44
  configuration.logger&.debug('using default configuration')
46
45
  end
@@ -12,6 +12,10 @@ module Coverband
12
12
  attr_writer :logger, :s3_region, :s3_bucket, :s3_access_key_id, :s3_secret_access_key
13
13
 
14
14
  def initialize
15
+ reset
16
+ end
17
+
18
+ def reset
15
19
  @root = Dir.pwd
16
20
  @root_paths = []
17
21
  @ignore = %w(vendor .erb$ .slim$)
@@ -35,7 +39,7 @@ module Coverband
35
39
  end
36
40
 
37
41
  def logger
38
- @logger ||= if defined?(Rails)
42
+ @logger ||= if defined?(Rails.logger)
39
43
  Rails.logger
40
44
  else
41
45
  Logger.new(STDOUT)
@@ -4,28 +4,37 @@ module Coverband
4
4
  class Background
5
5
  @semaphore = Mutex.new
6
6
 
7
+ def self.stop
8
+ @semaphore.synchronize do
9
+ if @thread
10
+ @thread.exit
11
+ @thread = nil
12
+ end
13
+ end
14
+ end
15
+
7
16
  def self.start
8
- return if @background_reporting_running
17
+ return if @thread
9
18
 
10
19
  logger = Coverband.configuration.logger
11
20
  @semaphore.synchronize do
12
- return if @background_reporting_running
21
+ binding.pry if defined?($debug) && $debug
22
+ return if @thread
13
23
  logger&.debug('Coverband: Starting background reporting')
14
-
15
- @background_reporting_running = true
16
24
  sleep_seconds = Coverband.configuration.background_reporting_sleep_seconds
17
- Thread.new do
25
+ @thread = Thread.new do
18
26
  loop do
19
27
  Coverband::Collectors::Coverage.instance.report_coverage(true)
20
28
  logger&.debug("Coverband: Reported coverage via thread. Sleeping #{sleep_seconds}s") if Coverband.configuration.verbose
21
29
  sleep(sleep_seconds)
22
30
  end
23
31
  end
24
-
25
- at_exit do
26
- Coverband::Collectors::Coverage.instance.report_coverage(true)
27
- logger&.debug('Coverband: Reported coverage before exit')
28
- end
32
+ binding.pry if defined?($debug) && $debug
33
+ end
34
+ at_exit do
35
+ stop
36
+ Coverband::Collectors::Coverage.instance.report_coverage(true)
37
+ logger&.debug('Coverband: Reported coverage before exit')
29
38
  end
30
39
  end
31
40
  end
@@ -7,6 +7,8 @@ module Coverband
7
7
  scov_style_report = super(store, options)
8
8
  open_report = options.fetch(:open_report) { true }
9
9
  html = options.fetch(:html) { false }
10
+ notice = options.fetch(:notice) { nil }
11
+ base_path = options.fetch(:base_path) { nil }
10
12
 
11
13
  # list all files, even if not tracked by Coverband (0% coverage)
12
14
  tracked_glob = "#{current_root}/{app,lib,config}/**/*.{rb}"
@@ -19,7 +21,9 @@ module Coverband
19
21
  end
20
22
 
21
23
  if html
22
- Coverband::Utils::HTMLFormatter.new(filtered_report_files).format_html!
24
+ Coverband::Utils::HTMLFormatter.new(filtered_report_files,
25
+ base_path: base_path,
26
+ notice: notice).format_html!
23
27
  else
24
28
  Coverband::Utils::HTMLFormatter.new(filtered_report_files).format!
25
29
  if open_report
@@ -4,7 +4,6 @@ require 'rack'
4
4
 
5
5
  module Coverband
6
6
  module Reporters
7
- # TODO: move to reports and drop need for S3 allow reading from adapters?
8
7
  class Web
9
8
  attr_reader :request
10
9
 
@@ -20,12 +19,8 @@ module Coverband
20
19
 
21
20
  if request.post?
22
21
  case request.path_info
23
- when %r{\/collect_update_and_view}
24
- collect_update_and_view
25
22
  when %r{\/clear}
26
23
  clear
27
- when %r{\/update_report}
28
- update_report
29
24
  when %r{\/collect_coverage}
30
25
  collect_coverage
31
26
  when %r{\/reload_files}
@@ -37,8 +32,6 @@ module Coverband
37
32
  case request.path_info
38
33
  when /.*\.(css|js|gif|png)/
39
34
  @static.call(env)
40
- when %r{\/show}
41
- [200, { 'Content-Type' => 'text/html' }, [show]]
42
35
  when %r{\/}
43
36
  [200, { 'Content-Type' => 'text/html' }, [index]]
44
37
  else
@@ -47,45 +40,14 @@ module Coverband
47
40
  end
48
41
  end
49
42
 
50
- # TODO: move to file or template
51
43
  def index
52
44
  notice = "<strong>Notice:</strong> #{Rack::Utils.escape_html(request.params['notice'])}<br/>"
53
45
  notice = request.params['notice'] ? notice : ''
54
- %(
55
- <html>
56
- #{notice}
57
- <ul>
58
- <li><a href='#{base_path}'>Coverband Web Admin Index</a></li>
59
- <li>#{button("#{base_path}collect_update_and_view", 'collect data, update report, & view')}</li>
60
- <li><a href='#{base_path}show'>view coverage report</a></li>
61
- <li>#{button("#{base_path}collect_coverage", 'update coverage data (collect coverage)')}</li>
62
- <li>#{button("#{base_path}update_report", 'update coverage report (rebuild report)')}</li>
63
- <li>#{button("#{base_path}clear", 'clear coverage report')}</li>
64
- <li>#{button("#{base_path}reload_files", 'reload Coverband files')}</li>
65
- </ul>
66
- <br/>
67
- version: #{Coverband::VERSION}<br/>
68
- <a href='https://github.com/danmayer/coverband'>Coverband</a>
69
- </html>
70
- )
71
- end
72
-
73
- def show
74
- html = Coverband::Reporters::HTMLReport.report(Coverband.configuration.store,
75
- html: true, open_report: false)
76
- fix_html_paths(html)
77
- end
78
-
79
- def collect_update_and_view
80
- collect_coverage
81
- update_report
82
- [301, { 'Location' => "#{base_path}show" }, []]
83
- end
84
-
85
- def update_report
86
- Coverband::Reporters::HTMLReport.report(Coverband.configuration.store, open_report: false)
87
- notice = 'coverband coverage updated'
88
- [301, { 'Location' => "#{base_path}?notice=#{notice}" }, []]
46
+ Coverband::Reporters::HTMLReport.report(Coverband.configuration.store,
47
+ html: true,
48
+ base_path: base_path,
49
+ notice: notice,
50
+ open_report: false)
89
51
  end
90
52
 
91
53
  def collect_coverage
@@ -112,28 +74,13 @@ module Coverband
112
74
 
113
75
  private
114
76
 
115
- def fix_html_paths(html)
116
- # HACK: the static HTML assets to link to the path where this was mounted
117
- html = html.gsub("src='", "src='#{base_path}")
118
- html = html.gsub("href='", "href='#{base_path}")
119
- html = html.gsub('loading.gif', "#{base_path}loading.gif")
120
- html = html.gsub('/images/', "#{base_path}images/")
121
- html.gsub("./assets/#{Coverband::VERSION}/", '')
122
- end
123
-
124
- def button(url, title)
125
- button = "<form action='#{url}' method='post'>"
126
- button += "<button type='submit'>#{title}</button>"
127
- button + '</form>'
128
- end
129
-
130
77
  # This method should get the root mounted endpoint
131
78
  # for example if the app is mounted like so:
132
79
  # mount Coverband::Web, at: '/coverage'
133
80
  # "/coverage/collect_coverage?" become:
134
81
  # /coverage/
135
82
  def base_path
136
- request.path.match("\/.*\/") ? request.path.match("\/.*\/")[0] : '/'
83
+ request.path =~ %r{\/.*\/} ? request.path.match("\/.*\/")[0] : '/'
137
84
  end
138
85
  end
139
86
  end
@@ -13,7 +13,11 @@ require 'time'
13
13
  module Coverband
14
14
  module Utils
15
15
  class HTMLFormatter
16
- def initialize(report)
16
+ attr_reader :notice, :base_path
17
+
18
+ def initialize(report, options = {})
19
+ @notice = options.fetch(:notice) { nil }
20
+ @base_path = options.fetch(:base_path) { nil }
17
21
  @coverage_result = Coverband::Utils::Result.new(report)
18
22
  end
19
23
 
@@ -58,7 +62,19 @@ module Coverband
58
62
  end
59
63
 
60
64
  def assets_path(name)
61
- File.join('./assets', Coverband::VERSION, name)
65
+ if base_path
66
+ File.join(base_path, name)
67
+ else
68
+ File.join(name)
69
+ end
70
+ end
71
+
72
+ def button(url, title, opts = {})
73
+ delete = opts.fetch(:delete) { false }
74
+ button_css = delete ? 'coveraband-button del' : 'coveraband-button'
75
+ button = "<form action='#{url}' class='coverband-admin-form' method='post'>"
76
+ button += "<button class='#{button_css}' type='submit'>#{title}</button>"
77
+ button + '</form>'
62
78
  end
63
79
 
64
80
  # Returns the html for the given source_file