coverband 4.1.0.alpha → 4.1.0.beta
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.
- checksums.yaml +4 -4
- data/Gemfile +2 -0
- data/Gemfile.rails4 +2 -0
- data/changes.md +16 -3
- data/lib/coverband.rb +2 -0
- data/lib/coverband/adapters/base.rb +0 -6
- data/lib/coverband/collectors/coverage.rb +10 -1
- data/lib/coverband/configuration.rb +55 -2
- data/lib/coverband/reporters/base.rb +32 -8
- data/lib/coverband/reporters/web.rb +12 -0
- data/lib/coverband/utils/file_groups.rb +53 -0
- data/lib/coverband/utils/gem_list.rb +31 -0
- data/lib/coverband/utils/html_formatter.rb +31 -7
- data/lib/coverband/utils/result.rb +13 -17
- data/lib/coverband/utils/source_file.rb +18 -1
- data/lib/coverband/version.rb +1 -1
- data/public/application.js +22 -9
- data/test/test_helper.rb +4 -0
- data/test/unit/configuration_test.rb +11 -0
- data/test/unit/full_stack_test.rb +13 -0
- data/test/unit/rails_full_stack_test.rb +2 -2
- data/test/unit/rails_gems_full_stack_test.rb +35 -0
- data/test/unit/reports_base_test.rb +73 -14
- data/test/unit/utils/file_groups_test.rb +55 -0
- data/test/unit/utils/file_list_test.rb +1 -1
- data/test/unit/utils/gem_list_test.rb +48 -0
- data/test/unit/utils/source_file_test.rb +1 -1
- data/views/file_list.erb +24 -20
- data/views/gem_list.erb +54 -0
- data/views/layout.erb +8 -2
- data/views/settings.erb +30 -0
- metadata +13 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 455614fde267b2ba0264e2949996587a342059f0
|
4
|
+
data.tar.gz: 6246b3c559c1d68d895928ceccdd8ebb8211934a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e2c4d201b82e29c772bc201aea5eecc5d3edc79746dbaf0838497b73def8fbb23c8b394b4e218ae9fd6a0e0b9a9df05fd71baa63ecbbf88768afe67fb0259dcb
|
7
|
+
data.tar.gz: ebce43a1554a11de5c8f0c280a32b89a762e44e8a68228e7fb63e3ef1855e0617018bfb6e052492b664708061e0ffc4d6350a2ce02b1f5bed568022b8f3c597f
|
data/Gemfile
CHANGED
data/Gemfile.rails4
CHANGED
data/changes.md
CHANGED
@@ -35,7 +35,8 @@ Will be the fully modern release that drops maintenance legacy support in favor
|
|
35
35
|
- more details in this issue: https://github.com/danmayer/coverband/issues/118
|
36
36
|
- Make good video on setup, install, usage
|
37
37
|
- See if we can add support for views / templates
|
38
|
-
- using this technique https://github.com/ioquatix/covered
|
38
|
+
- using this technique https://github.com/ioquatix/covered
|
39
|
+
- Better default grouping (could use groups features for gems for rails controllers, models, lib, etc)
|
39
40
|
|
40
41
|
### Coverband_jam_session
|
41
42
|
|
@@ -62,9 +63,21 @@ Feature Ideas:
|
|
62
63
|
|
63
64
|
# Alpha
|
64
65
|
|
65
|
-
### Coverband 4.0.
|
66
|
+
### Coverband 4.2.0.alpha
|
67
|
+
|
68
|
+
???
|
69
|
+
|
70
|
+
### Coverband 4.1.0.beta
|
66
71
|
|
67
72
|
- default disabled web clear, add config option to allow it
|
73
|
+
- out of the box support for resque
|
74
|
+
- readme improvements
|
75
|
+
- fix on regression of merging directory changing deployments
|
76
|
+
- pilot release of Gems tracking (disabled by default)
|
77
|
+
- todos
|
78
|
+
- support multiple gem paths (various version managers setup multiple gem paths)
|
79
|
+
- speed up page load by allowing multiple pages
|
80
|
+
- added web settings and debug views
|
68
81
|
|
69
82
|
# Released
|
70
83
|
|
@@ -76,7 +89,7 @@ Feature Ideas:
|
|
76
89
|
- reduced the S3 dependencies to minimal set (not loading all of aws-sdk, only aws-sdk-s3), ensured they are optional
|
77
90
|
- Improved Coverband web admin
|
78
91
|
- Coverage reports include timestamps of Coverage collection
|
79
|
-
- Added Coveralls to the dev process thanks @dondonz
|
92
|
+
- Added Coveralls to the dev process thanks @dondonz
|
80
93
|
- now tested under Ruby 2.6.0 thanks @Kbaum
|
81
94
|
- improved full stack testing for Rails 5 & 4
|
82
95
|
- warning before clear coverage on coverband web
|
data/lib/coverband.rb
CHANGED
@@ -14,7 +14,9 @@ require 'coverband/utils/s3_report'
|
|
14
14
|
require 'coverband/utils/html_formatter'
|
15
15
|
require 'coverband/utils/result'
|
16
16
|
require 'coverband/utils/file_list'
|
17
|
+
require 'coverband/utils/gem_list'
|
17
18
|
require 'coverband/utils/source_file'
|
19
|
+
require 'coverband/utils/file_groups'
|
18
20
|
require 'coverband/utils/lines_classifier'
|
19
21
|
require 'coverband/utils/railtie' if defined? ::Rails::Railtie
|
20
22
|
require 'coverband/collectors/coverage'
|
@@ -90,12 +90,6 @@ module Coverband
|
|
90
90
|
def array_add(latest, original)
|
91
91
|
latest.map.with_index { |v, i| (v && original[i]) ? v + original[i] : nil }
|
92
92
|
end
|
93
|
-
|
94
|
-
def simple_report(report)
|
95
|
-
report.each_with_object({}) do |(key, extended_data), simple|
|
96
|
-
simple[key] = extended_data['data']
|
97
|
-
end
|
98
|
-
end
|
99
93
|
end
|
100
94
|
end
|
101
95
|
end
|
@@ -24,6 +24,7 @@ module Coverband
|
|
24
24
|
@logger = Coverband.configuration.logger
|
25
25
|
@current_thread = Thread.current
|
26
26
|
@test_env = Coverband.configuration.test_env
|
27
|
+
@track_gems = Coverband.configuration.track_gems
|
27
28
|
@@previous_results = nil
|
28
29
|
Thread.current[:coverband_instance] = nil
|
29
30
|
self
|
@@ -48,10 +49,18 @@ module Coverband
|
|
48
49
|
|
49
50
|
protected
|
50
51
|
|
52
|
+
###
|
53
|
+
# Normally I would break this out into additional methods
|
54
|
+
# and improve the readability but this is in a tight loop
|
55
|
+
# on the critical performance path, and any refactoring I come up with
|
56
|
+
# would slow down the performance.
|
57
|
+
###
|
51
58
|
def track_file?(file)
|
52
59
|
@ignore_patterns.none? do |pattern|
|
53
60
|
file.include?(pattern)
|
54
|
-
end && file.start_with?(@project_directory)
|
61
|
+
end && (file.start_with?(@project_directory) ||
|
62
|
+
(@track_gems &&
|
63
|
+
Coverband.configuration.gem_paths.any? { |path| file.start_with?(path) }))
|
55
64
|
end
|
56
65
|
|
57
66
|
private
|
@@ -8,9 +8,10 @@ module Coverband
|
|
8
8
|
:redis_namespace, :redis_ttl,
|
9
9
|
:safe_reload_files, :background_reporting_enabled,
|
10
10
|
:background_reporting_sleep_seconds, :test_env,
|
11
|
-
:web_enable_clear
|
11
|
+
:web_enable_clear, :gem_details, :web_debug
|
12
12
|
|
13
13
|
attr_writer :logger, :s3_region, :s3_bucket, :s3_access_key_id, :s3_secret_access_key
|
14
|
+
attr_reader :track_gems
|
14
15
|
|
15
16
|
def initialize
|
16
17
|
reset
|
@@ -19,7 +20,7 @@ module Coverband
|
|
19
20
|
def reset
|
20
21
|
@root = Dir.pwd
|
21
22
|
@root_paths = []
|
22
|
-
@ignore = %w
|
23
|
+
@ignore = %w[vendor .erb$ .slim$]
|
23
24
|
@additional_files = []
|
24
25
|
@reporting_frequency = 0.0
|
25
26
|
@verbose = false
|
@@ -30,6 +31,10 @@ module Coverband
|
|
30
31
|
@background_reporting_sleep_seconds = 30
|
31
32
|
@test_env = nil
|
32
33
|
@web_enable_clear = false
|
34
|
+
@track_gems = false
|
35
|
+
@gem_details = false
|
36
|
+
@groups = {}
|
37
|
+
@web_debug = false
|
33
38
|
|
34
39
|
# TODO: should we push these to adapter configs
|
35
40
|
@s3_region = nil
|
@@ -76,6 +81,54 @@ module Coverband
|
|
76
81
|
end
|
77
82
|
end
|
78
83
|
|
84
|
+
def track_gems=(value)
|
85
|
+
@track_gems = value
|
86
|
+
return unless @track_gems
|
87
|
+
# by default we ignore vendor where many deployments put gems
|
88
|
+
# we will remove this default if track_gems is set
|
89
|
+
@ignore.delete('vendor')
|
90
|
+
# while we want to allow vendored gems we don't want to track vendored ruby STDLIB
|
91
|
+
@ignore << 'vendor/ruby-*'
|
92
|
+
add_group('App', root)
|
93
|
+
# TODO: rework support for multiple gem paths
|
94
|
+
# currently this supports GEM_HOME (which should be first path)
|
95
|
+
# but various gem managers setup multiple gem paths
|
96
|
+
# gem_paths.each_with_index do |path, index|
|
97
|
+
# add_group("gems_#{index}", path)
|
98
|
+
# end
|
99
|
+
add_group('Gems', gem_paths.first)
|
100
|
+
end
|
101
|
+
|
102
|
+
#
|
103
|
+
# Returns the configured groups. Add groups using SimpleCov.add_group
|
104
|
+
#
|
105
|
+
def groups
|
106
|
+
@groups ||= {}
|
107
|
+
end
|
108
|
+
|
109
|
+
#
|
110
|
+
# Define a group for files. Works similar to add_filter, only that the first
|
111
|
+
# argument is the desired group name and files PASSING the filter end up in the group
|
112
|
+
# (while filters exclude when the filter is applicable).
|
113
|
+
#
|
114
|
+
def add_group(group_name, filter_argument = nil)
|
115
|
+
groups[group_name] = filter_argument
|
116
|
+
end
|
117
|
+
|
118
|
+
def gem_paths
|
119
|
+
# notes ignore any paths that aren't on this system, resolves
|
120
|
+
# bug related to multiple ruby version managers / bad dot files
|
121
|
+
Gem::PathSupport.new(ENV).path.select { |path| File.exist?(path) }
|
122
|
+
end
|
123
|
+
|
124
|
+
SKIPPED_SETTINGS = %w[@s3_secret_access_key @store]
|
125
|
+
def to_h
|
126
|
+
instance_variables
|
127
|
+
.each_with_object('gem_paths': gem_paths) do |var, hash|
|
128
|
+
hash[var.to_s.delete('@')] = instance_variable_get(var) unless SKIPPED_SETTINGS.include?(var.to_s)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
79
132
|
private
|
80
133
|
|
81
134
|
def redis_url
|
@@ -22,6 +22,7 @@ module Coverband
|
|
22
22
|
|
23
23
|
def root_paths
|
24
24
|
roots = Coverband.configuration.root_paths
|
25
|
+
roots += Coverband.configuration.gem_paths if Coverband.configuration.track_gems
|
25
26
|
roots << "#{current_root}/"
|
26
27
|
roots
|
27
28
|
end
|
@@ -38,8 +39,10 @@ module Coverband
|
|
38
39
|
# normalize names across servers
|
39
40
|
report_hash.each_with_object({}) do |(key, vals), fixed_report|
|
40
41
|
filename = filename_from_key(key, roots)
|
41
|
-
fixed_report[filename] = if fixed_report.key?(filename)
|
42
|
-
merge_arrays(fixed_report[filename], vals)
|
42
|
+
fixed_report[filename] = if fixed_report.key?(filename) && fixed_report[filename]['data'] && vals['data']
|
43
|
+
merged_data = merge_arrays(fixed_report[filename]['data'], vals['data'])
|
44
|
+
vals['data'] = merged_data
|
45
|
+
vals
|
43
46
|
else
|
44
47
|
vals
|
45
48
|
end
|
@@ -61,23 +64,44 @@ module Coverband
|
|
61
64
|
merged
|
62
65
|
end
|
63
66
|
|
67
|
+
###
|
68
|
+
# filename_from_key code takes:
|
69
|
+
# key: which is a full path the same as reported by Coverage
|
70
|
+
# roots: if a collection of all possible full app paths
|
71
|
+
# EX: [Coverband.configuration.root_paths, "#{current_root}/"]
|
72
|
+
# The LAST item should be the current file system root
|
73
|
+
# it expands that expands and adds a '/' as that isn't there from Dir.pwd
|
74
|
+
#
|
75
|
+
# NOTEs on configuration.root_paths usage
|
76
|
+
# strings: matching is pretty simple for full string paths
|
77
|
+
# regex: to get regex to work for changing deploy directories
|
78
|
+
# the regex must be double escaped in double quotes
|
79
|
+
# (if using \d for example)
|
80
|
+
# or use single qoutes
|
81
|
+
# example: '/box/apps/app_name/releases/\d+/'
|
82
|
+
# example: '/var/local/company/company.d/[0-9]*/'
|
83
|
+
###
|
64
84
|
def filename_from_key(key, roots)
|
65
|
-
|
85
|
+
relative_filename = key
|
86
|
+
local_filename = relative_filename
|
66
87
|
roots.each do |root|
|
67
|
-
|
88
|
+
relative_filename = relative_filename.gsub(/^#{root}/, './')
|
68
89
|
end
|
69
|
-
# the filename for
|
90
|
+
# the filename for our reports is expected to be a full path.
|
70
91
|
# roots.last should be roots << current_root}/
|
71
92
|
# a fully expanded path of config.root
|
72
|
-
filename = filename.gsub('./', roots.last)
|
73
|
-
|
93
|
+
# filename = filename.gsub('./', roots.last)
|
94
|
+
# above only works for app files
|
95
|
+
# we need to rethink some of this logic
|
96
|
+
# gems aren't at project root and can have multiple locations
|
97
|
+
local_root = roots.find { |root| File.exist?(relative_filename.gsub('./', root)) }
|
98
|
+
local_root ? relative_filename.gsub('./', local_root) : local_filename
|
74
99
|
end
|
75
100
|
|
76
101
|
###
|
77
102
|
# why do we need to merge covered files data?
|
78
103
|
# basically because paths on machines or deployed hosts could be different, so
|
79
104
|
# two different keys could point to the same filename or `line_key`
|
80
|
-
# this logic should be pushed to base report
|
81
105
|
# TODO: think we are filtering based on ignore while sending to the store
|
82
106
|
# and as we also pull it out here
|
83
107
|
###
|
@@ -35,6 +35,10 @@ module Coverband
|
|
35
35
|
case request.path_info
|
36
36
|
when /.*\.(css|js|gif|png)/
|
37
37
|
@static.call(env)
|
38
|
+
when %r{\/settings}
|
39
|
+
[200, { 'Content-Type' => 'text/html' }, [settings]]
|
40
|
+
when %r{\/debug_data}
|
41
|
+
[200, { 'Content-Type' => 'text/json' }, [debug_data]]
|
38
42
|
when %r{\/$}
|
39
43
|
[200, { 'Content-Type' => 'text/html' }, [index]]
|
40
44
|
else
|
@@ -53,6 +57,14 @@ module Coverband
|
|
53
57
|
open_report: false)
|
54
58
|
end
|
55
59
|
|
60
|
+
def settings
|
61
|
+
Coverband::Utils::HTMLFormatter.new(nil, base_path: base_path).format_settings!
|
62
|
+
end
|
63
|
+
|
64
|
+
def debug_data
|
65
|
+
Coverband.configuration.store.coverage.to_json
|
66
|
+
end
|
67
|
+
|
56
68
|
def collect_coverage
|
57
69
|
Coverband::Collectors::Coverage.instance.report_coverage(true)
|
58
70
|
notice = 'coverband coverage collected'
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Applies the configured groups to the given array of Coverband::SourceFile items
|
5
|
+
#
|
6
|
+
module Coverband
|
7
|
+
module Utils
|
8
|
+
class FileGroups
|
9
|
+
def initialize(files)
|
10
|
+
@grouped = {}
|
11
|
+
@files = files
|
12
|
+
filter_to_groups
|
13
|
+
end
|
14
|
+
|
15
|
+
def grouped_results
|
16
|
+
@grouped
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def filter_to_groups
|
22
|
+
grouped_files = []
|
23
|
+
Coverband.configuration.groups.each do |name, filter|
|
24
|
+
if name == 'Gems'
|
25
|
+
gem_lists = gem_files(name, filter)
|
26
|
+
grouped_files.concat(gem_lists.flatten) if gem_lists.flatten.any?
|
27
|
+
else
|
28
|
+
app_files(name, filter)
|
29
|
+
grouped_files += @grouped[name]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
if !Coverband.configuration.groups.empty? && !(other_files = @files.reject do |source_file|
|
33
|
+
grouped_files.include?(source_file)
|
34
|
+
end).empty?
|
35
|
+
@grouped['Ungrouped'] = Coverband::Utils::FileList.new(other_files)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def gem_files(name, filter)
|
40
|
+
grouped_gems = @files.select { |source_file| source_file.filename =~ /#{filter}/ }.group_by(&:gem_name)
|
41
|
+
gem_lists = grouped_gems.values.map { |gem_files| Coverband::Utils::FileList.new(gem_files) }
|
42
|
+
@grouped[name] = Coverband::Utils::GemList.new(gem_lists) if gem_lists.flatten.any?
|
43
|
+
gem_lists
|
44
|
+
end
|
45
|
+
|
46
|
+
def app_files(name, filter)
|
47
|
+
@grouped[name] = Coverband::Utils::FileList.new(@files.select do |source_file|
|
48
|
+
source_file.filename =~ /#{filter}/ && source_file.filename !~ /#{Coverband.configuration.gem_paths.first}/
|
49
|
+
end)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
####
|
4
|
+
# An array of FileLists instances with helpers to roll up the stats
|
5
|
+
# methods for calculating coverage across them etc.
|
6
|
+
####
|
7
|
+
module Coverband
|
8
|
+
module Utils
|
9
|
+
class GemList < FileList
|
10
|
+
# Returns the count of lines that have coverage
|
11
|
+
def covered_lines
|
12
|
+
to_a.map(&:covered_lines).inject(:+)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Returns the count of lines that have been missed
|
16
|
+
def missed_lines
|
17
|
+
to_a.map(&:missed_lines).inject(:+)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns the count of lines that are not relevant for coverage
|
21
|
+
def never_lines
|
22
|
+
to_a.map(&:never_lines).inject(:+)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Returns the count of skipped lines
|
26
|
+
def skipped_lines
|
27
|
+
to_a.map(&:skipped_lines).inject(:+)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
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)
|
@@ -81,17 +89,30 @@ module Coverband
|
|
81
89
|
def formatted_source_file(source_file)
|
82
90
|
template('source_file').result(binding)
|
83
91
|
rescue Encoding::CompatibilityError => e
|
84
|
-
puts "Encoding
|
92
|
+
puts "Encoding error file:#{source_file.filename} Coverband/ERB error #{e.message}."
|
85
93
|
end
|
86
94
|
|
87
95
|
# Returns a table containing the given source files
|
88
|
-
def formatted_file_list(title, source_files)
|
96
|
+
def formatted_file_list(title, source_files, options = {})
|
89
97
|
title_id = title.gsub(/^[^a-zA-Z]+/, '').gsub(/[^a-zA-Z0-9\-\_]/, '')
|
90
98
|
# Silence a warning by using the following variable to assign to itself:
|
91
99
|
# "warning: possibly useless use of a variable in void context"
|
92
100
|
# The variable is used by ERB via binding.
|
93
101
|
title_id = title_id
|
94
|
-
|
102
|
+
options = options
|
103
|
+
if title == 'Gems'
|
104
|
+
template('gem_list').result(binding)
|
105
|
+
else
|
106
|
+
template('file_list').result(binding)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def view_gems?
|
111
|
+
Coverband.configuration.track_gems
|
112
|
+
end
|
113
|
+
|
114
|
+
def gem_details?
|
115
|
+
Coverband.configuration.gem_details
|
95
116
|
end
|
96
117
|
|
97
118
|
def coverage_css_class(covered_percent)
|
@@ -123,10 +144,13 @@ module Coverband
|
|
123
144
|
"<abbr class=\"timeago\" title=\"#{time.iso8601}\">#{time.iso8601}</abbr>"
|
124
145
|
end
|
125
146
|
|
126
|
-
# a bug that existed in simplecov was not checking that root was at the start of the file name
|
127
|
-
# I had previously patched this in my local Rails app
|
128
147
|
def shortened_filename(source_file)
|
129
|
-
source_file.
|
148
|
+
source_file.short_name
|
149
|
+
end
|
150
|
+
|
151
|
+
def link_to_gem_list(gem_name)
|
152
|
+
gem_id = gem_name.gsub(/^[^a-zA-Z]+/, '').gsub(/[^a-zA-Z0-9\-\_]/, '')
|
153
|
+
%(<a href="##{gem_id}" class="gem-link" title="#{gem_name}">#{gem_name}</a>)
|
130
154
|
end
|
131
155
|
|
132
156
|
def link_to_source_file(source_file)
|
@@ -14,26 +14,28 @@ module Coverband
|
|
14
14
|
module Utils
|
15
15
|
class Result
|
16
16
|
extend Forwardable
|
17
|
-
# Returns the original Coverage.result used for this instance of
|
17
|
+
# Returns the original Coverage.result used for this instance of Coverband::Result
|
18
18
|
attr_reader :original_result
|
19
|
-
# Returns all files that are applicable to this result (sans filters!)
|
19
|
+
# Returns all files that are applicable to this result (sans filters!)
|
20
|
+
# as instances of Coverband::SourceFile. Aliased as :source_files
|
20
21
|
attr_reader :files
|
21
22
|
alias source_files files
|
22
23
|
# Explicitly set the Time this result has been created
|
23
24
|
attr_writer :created_at
|
24
|
-
# Explicitly set the command name that was used for this coverage result.
|
25
|
+
# Explicitly set the command name that was used for this coverage result.
|
26
|
+
# Defaults to Coverband.command_name
|
25
27
|
attr_writer :command_name
|
26
28
|
|
27
29
|
def_delegators :files, :covered_percent, :covered_percentages, :least_covered_file, :covered_strength, :covered_lines, :missed_lines
|
28
30
|
def_delegator :files, :lines_of_code, :total_lines
|
29
31
|
|
30
|
-
# Initialize a new
|
32
|
+
# Initialize a new Coverband::Result from given Coverage.result (a Hash of filenames each containing an array of
|
31
33
|
# coverage data)
|
32
34
|
def initialize(original_result)
|
33
35
|
@original_result = original_result.freeze
|
34
36
|
@files = Coverband::Utils::FileList.new(original_result.map do |filename, coverage|
|
35
37
|
Coverband::Utils::SourceFile.new(filename, coverage) if File.file?(filename)
|
36
|
-
end.compact.sort_by(&:
|
38
|
+
end.compact.sort_by(&:short_name))
|
37
39
|
filter!
|
38
40
|
end
|
39
41
|
|
@@ -42,15 +44,9 @@ module Coverband
|
|
42
44
|
files.map(&:filename)
|
43
45
|
end
|
44
46
|
|
45
|
-
# Returns a Hash of groups for this result. Define groups using
|
46
|
-
# Coverband doesn't currently support groups
|
47
|
+
# Returns a Hash of groups for this result. Define groups using Coverband.add_group 'Models', 'app/models'
|
47
48
|
def groups
|
48
|
-
@groups ||=
|
49
|
-
end
|
50
|
-
|
51
|
-
# Applies the configured SimpleCov.formatter on this result
|
52
|
-
def format!
|
53
|
-
# SimpleCov.formatter.new.format(self)
|
49
|
+
@groups ||= FileGroups.new(files).grouped_results
|
54
50
|
end
|
55
51
|
|
56
52
|
# Defines when this result has been created. Defaults to Time.now
|
@@ -59,9 +55,9 @@ module Coverband
|
|
59
55
|
end
|
60
56
|
|
61
57
|
# The command name that launched this result.
|
62
|
-
# Delegated to
|
58
|
+
# Delegated to Coverband.command_name if not set manually
|
63
59
|
def command_name
|
64
|
-
@command_name ||= '
|
60
|
+
@command_name ||= 'Coverband'
|
65
61
|
end
|
66
62
|
|
67
63
|
# Returns a hash representation of this Result that can be used for marshalling it into JSON
|
@@ -69,7 +65,7 @@ module Coverband
|
|
69
65
|
{ command_name => { 'coverage' => coverage, 'timestamp' => created_at.to_i } }
|
70
66
|
end
|
71
67
|
|
72
|
-
# Loads a
|
68
|
+
# Loads a Coverband::Result#to_hash dump
|
73
69
|
def self.from_hash(hash)
|
74
70
|
command_name, data = hash.first
|
75
71
|
result = new(data['coverage'])
|
@@ -100,7 +96,7 @@ module Coverband
|
|
100
96
|
Hash[keys.zip(original_result.values_at(*keys))]
|
101
97
|
end
|
102
98
|
|
103
|
-
# Applies all configured
|
99
|
+
# Applies all configured Coverband filters on this result's source files
|
104
100
|
def filter!
|
105
101
|
@files = files
|
106
102
|
end
|
@@ -133,7 +133,7 @@ module Coverband
|
|
133
133
|
|
134
134
|
# Warning to identify condition from Issue #56
|
135
135
|
def coverage_exceeding_source_warn
|
136
|
-
warn "Warning: coverage data
|
136
|
+
warn "Warning: coverage data from Coverage [#{coverage.size}] exceeds line count in #{filename} [#{src.size}]"
|
137
137
|
end
|
138
138
|
|
139
139
|
# Access SimpleCov::SourceFile::Line source lines by line number
|
@@ -210,6 +210,23 @@ module Coverband
|
|
210
210
|
end
|
211
211
|
end
|
212
212
|
|
213
|
+
# a bug that existed in simplecov was not checking that root
|
214
|
+
# was at the start of the file name
|
215
|
+
# I had previously patched this in my local Rails app
|
216
|
+
def short_name
|
217
|
+
filename.sub(/^#{Coverband.configuration.root}/, '.')
|
218
|
+
.sub(%r{^.*\/gems}, '.')
|
219
|
+
.gsub(%r{^\.\/}, '')
|
220
|
+
end
|
221
|
+
|
222
|
+
def gem?
|
223
|
+
filename =~ %r{^.*\/gems\/}
|
224
|
+
end
|
225
|
+
|
226
|
+
def gem_name
|
227
|
+
gem? ? short_name.split('/').first : nil
|
228
|
+
end
|
229
|
+
|
213
230
|
private
|
214
231
|
|
215
232
|
# ruby 1.9 could use Float#round(places) instead
|
data/lib/coverband/version.rb
CHANGED
data/public/application.js
CHANGED
@@ -1684,24 +1684,37 @@ $(document).ready(function() {
|
|
1684
1684
|
if (!$(this).parent().hasClass('active')) {
|
1685
1685
|
$('.group_tabs a').parent().removeClass('active');
|
1686
1686
|
$(this).parent().addClass('active');
|
1687
|
-
$('.file_list_container').hide();
|
1688
|
-
$(".file_list_container" + $(this).attr('href')).show();
|
1689
|
-
window.location.href = window.location.href.split('#')[0] + $(this).attr('href').replace('#', '#_');
|
1690
|
-
|
1691
|
-
// Force favicon reload - otherwise the location change containing anchor would drop the favicon...
|
1692
|
-
// Works only on firefox, but still... - Anyone know a better solution to force favicon on local file?
|
1693
|
-
$('link[rel="shortcut icon"]').remove();
|
1694
|
-
$('head').append('<link rel="shortcut icon" type="image/png" href="'+ favicon_path +'" />');
|
1695
1687
|
};
|
1688
|
+
$('.file_list_container').hide();
|
1689
|
+
$(".file_list_container" + $(this).attr('href')).show();
|
1690
|
+
window.location.href = window.location.href.split('#')[0] + $(this).attr('href').replace('#', '#_');
|
1691
|
+
|
1692
|
+
// Force favicon reload - otherwise the location change containing anchor would drop the favicon...
|
1693
|
+
// Works only on firefox, but still... - Anyone know a better solution to force favicon on local file?
|
1694
|
+
$('link[rel="shortcut icon"]').remove();
|
1695
|
+
$('head').append('<link rel="shortcut icon" type="image/png" href="'+ favicon_path +'" />');
|
1696
|
+
return false;
|
1697
|
+
});
|
1698
|
+
|
1699
|
+
$('a.gem-link').live('click', function(){
|
1700
|
+
$('.file_list_container').hide();
|
1701
|
+
$(".file_list_container" + $(this).attr('href')).show();
|
1702
|
+
window.location.href = window.location.href.split('#')[0] + $(this).attr('href').replace('#', '#_');
|
1696
1703
|
return false;
|
1697
1704
|
});
|
1698
1705
|
|
1699
1706
|
if (jQuery.url.attr('anchor')) {
|
1700
1707
|
var anchor = jQuery.url.attr('anchor')
|
1708
|
+
// source file hash
|
1701
1709
|
if (anchor.length == 40) {
|
1702
1710
|
$('a.src_link[href=#' + anchor + ']').click();
|
1703
1711
|
} else {
|
1704
|
-
$('.group_tabs a.'+anchor.replace('_', '')).
|
1712
|
+
if ($('.group_tabs a.'+anchor.replace('_', '')).length > 0) {
|
1713
|
+
$('.group_tabs a.'+anchor.replace('_', '')).click();
|
1714
|
+
} else {
|
1715
|
+
$('a.gem-link[href=#' + anchor.replace('_', '') + ']').click();
|
1716
|
+
}
|
1717
|
+
|
1705
1718
|
}
|
1706
1719
|
} else {
|
1707
1720
|
$('.group_tabs a:first').click();
|
data/test/test_helper.rb
CHANGED
@@ -95,6 +95,10 @@ def source_fixture(filename)
|
|
95
95
|
File.expand_path(File.join(File.dirname(__FILE__), 'fixtures', filename))
|
96
96
|
end
|
97
97
|
|
98
|
+
def test_root
|
99
|
+
File.expand_path(File.join(File.dirname(__FILE__)))
|
100
|
+
end
|
101
|
+
|
98
102
|
# Taken from http://stackoverflow.com/questions/4459330/how-do-i-temporarily-redirect-stderr-in-ruby
|
99
103
|
def capture_stderr
|
100
104
|
# The output stream must be an IO-like object. In this case we capture it in
|
@@ -21,6 +21,17 @@ class BaseTest < Minitest::Test
|
|
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
|
25
|
+
Coverband::Collectors::Coverage.instance.reset_instance
|
26
|
+
assert Coverband.configuration.gem_paths.first != nil
|
27
|
+
end
|
28
|
+
|
29
|
+
test 'groups ' do
|
30
|
+
Coverband::Collectors::Coverage.instance.reset_instance
|
31
|
+
Coverband.configuration.track_gems = true
|
32
|
+
assert_equal %w(App Gems), Coverband.configuration.groups.keys
|
33
|
+
end
|
34
|
+
|
24
35
|
test 's3 options' do
|
25
36
|
Coverband::Collectors::Coverage.instance.reset_instance
|
26
37
|
Coverband.configure do |config|
|
@@ -38,6 +38,19 @@ class FullStackTest < Minitest::Test
|
|
38
38
|
assert_equal expected, Coverband.configuration.store.coverage[@rack_file]['data']
|
39
39
|
end
|
40
40
|
|
41
|
+
test 'call app with gem tracking' do
|
42
|
+
Coverband.configuration.track_gems = true
|
43
|
+
Coverband::Collectors::Coverage.instance.reset_instance
|
44
|
+
require 'rainbow'
|
45
|
+
Rainbow('this text is red').red
|
46
|
+
request = Rack::MockRequest.env_for('/anything.json')
|
47
|
+
middleware = Coverband::Middleware.new(fake_app_with_lines)
|
48
|
+
results = middleware.call(request)
|
49
|
+
assert_equal 'Hello Rack!', results.last
|
50
|
+
sleep(0.1)
|
51
|
+
assert Coverband.configuration.store.coverage.keys.any? { |key| key.end_with?('rainbow/null_presenter.rb') }
|
52
|
+
end
|
53
|
+
|
41
54
|
private
|
42
55
|
|
43
56
|
def fake_app_with_lines
|
@@ -8,7 +8,7 @@ class RailsFullStackTest < Minitest::Test
|
|
8
8
|
|
9
9
|
def setup
|
10
10
|
super
|
11
|
-
#The normal relative directory lookup of coverband won't work for our dummy rails project
|
11
|
+
# The normal relative directory lookup of coverband won't work for our dummy rails project
|
12
12
|
Coverband.configure("./test/rails#{Rails::VERSION::MAJOR}_dummy/config/coverband.rb")
|
13
13
|
Coverband.start
|
14
14
|
end
|
@@ -24,7 +24,7 @@ class RailsFullStackTest < Minitest::Test
|
|
24
24
|
assert_content('I am no dummy')
|
25
25
|
sleep 0.2
|
26
26
|
visit '/coverage'
|
27
|
-
within page.find('a',
|
27
|
+
within page.find('a', text: /dummy_controller.rb/).find(:xpath, '../..') do
|
28
28
|
assert_selector('td', text: '100.0 %')
|
29
29
|
end
|
30
30
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require File.expand_path('../rails_test_helper', File.dirname(__FILE__))
|
4
|
+
|
5
|
+
class RailsGemsFullStackTest < Minitest::Test
|
6
|
+
include Capybara::DSL
|
7
|
+
include Capybara::Minitest::Assertions
|
8
|
+
|
9
|
+
def setup
|
10
|
+
super
|
11
|
+
# The normal relative directory lookup of coverband won't work for our dummy rails project
|
12
|
+
Coverband.configure("./test/rails#{Rails::VERSION::MAJOR}_dummy/config/coverband.rb")
|
13
|
+
Coverband.configuration.track_gems = true
|
14
|
+
Coverband.configuration.gem_details = true
|
15
|
+
Coverband.start
|
16
|
+
require 'rainbow'
|
17
|
+
Rainbow('this text is red').red
|
18
|
+
end
|
19
|
+
|
20
|
+
def teardown
|
21
|
+
super
|
22
|
+
Capybara.reset_sessions!
|
23
|
+
Capybara.use_default_driver
|
24
|
+
end
|
25
|
+
|
26
|
+
test 'this is how gem it' do
|
27
|
+
visit '/dummy/show'
|
28
|
+
assert_content('I am no dummy')
|
29
|
+
sleep 0.2
|
30
|
+
visit '/coverage'
|
31
|
+
assert_content('Coverband Admin')
|
32
|
+
assert_content('Gems')
|
33
|
+
assert page.html.match('rainbow/wrapper.rb')
|
34
|
+
end
|
35
|
+
end
|
@@ -14,36 +14,46 @@ class ReportsBaseTest < Minitest::Test
|
|
14
14
|
roots = ['/app/', '/full/remote_app/path/']
|
15
15
|
|
16
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)
|
17
19
|
assert_equal expected_path, Coverband::Reporters::Base.send(:filename_from_key, key, roots)
|
18
20
|
end
|
19
21
|
|
20
|
-
test 'filename_from_key fix filename a changing deploy path with
|
22
|
+
test 'filename_from_key fix filename a changing deploy path with quotes' do
|
21
23
|
Coverband.configure do |config|
|
22
24
|
config.reporter = 'std_out'
|
23
25
|
config.root = '/full/remote_app/path'
|
24
26
|
end
|
25
27
|
|
26
|
-
key = '/box/apps/app_name/releases/20140725203539/app/models/user.rb'
|
27
|
-
# the code takes config.root expands and adds a '/' for the final path in roots
|
28
|
-
# note to get regex to work for changing deploy directories it must be double escaped in double quotes or use single qoutes
|
29
|
-
roots = ['/box/apps/app_name/releases/\\d+/', '/full/remote_app/path/']
|
30
|
-
|
31
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(:filename_from_key, 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/']
|
32
37
|
assert_equal expected_path, Coverband::Reporters::Base.send(:filename_from_key, key, roots)
|
33
38
|
end
|
34
39
|
|
35
|
-
test 'filename_from_key fix filename a changing deploy path
|
40
|
+
test 'filename_from_key fix filename a changing deploy path real world examples' do
|
41
|
+
current_app_root = '/var/local/company/company.d/79'
|
36
42
|
Coverband.configure do |config|
|
37
43
|
config.reporter = 'std_out'
|
38
|
-
config.root =
|
44
|
+
config.root = current_app_root
|
39
45
|
end
|
40
46
|
|
41
|
-
|
42
|
-
|
43
|
-
# note to get regex to work for changing deploy directories it must be double escaped in double quotes or use single qoutes
|
44
|
-
roots = ['/box/apps/app_name/releases/\d+/', '/full/remote_app/path/']
|
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'
|
45
49
|
|
46
|
-
|
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(:filename_from_key, 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}/"]
|
47
57
|
assert_equal expected_path, Coverband::Reporters::Base.send(:filename_from_key, key, roots)
|
48
58
|
end
|
49
59
|
|
@@ -92,7 +102,6 @@ class ReportsBaseTest < Minitest::Test
|
|
92
102
|
|
93
103
|
Coverband.configure do |config|
|
94
104
|
config.reporter = 'std_out'
|
95
|
-
config.ignore = %w(vendor .erb$ .slim$)
|
96
105
|
config.root = '/full/remote_app/path'
|
97
106
|
config.store = store
|
98
107
|
end
|
@@ -106,4 +115,54 @@ class ReportsBaseTest < Minitest::Test
|
|
106
115
|
|
107
116
|
assert_equal expected, Coverband::Reporters::Base.send(:get_current_scov_data_imp, store, roots)
|
108
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
|
109
168
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require File.expand_path('../../test_helper', File.dirname(__FILE__))
|
4
|
+
|
5
|
+
describe Coverband::Utils::FileGroups do
|
6
|
+
FAKE_GEM_PATH = 'fake/gem/path'
|
7
|
+
subject do
|
8
|
+
controller_lines = [nil, 2, 2, 0, nil, nil, 0, nil, nil, nil]
|
9
|
+
files = [
|
10
|
+
Coverband::Utils::SourceFile.new(source_fixture('sample.rb'), [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil]),
|
11
|
+
Coverband::Utils::SourceFile.new(source_fixture('app/models/user.rb'), [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil]),
|
12
|
+
Coverband::Utils::SourceFile.new(source_fixture('app/controllers/sample_controller.rb'), controller_lines),
|
13
|
+
Coverband::Utils::SourceFile.new("#{FAKE_GEM_PATH}/gem_name.rb", controller_lines)
|
14
|
+
]
|
15
|
+
Coverband.configuration.expects(:gem_paths).at_least_once.returns([FAKE_GEM_PATH])
|
16
|
+
Coverband.configuration.track_gems = true
|
17
|
+
Coverband::Utils::FileGroups.new(files)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'has app files' do
|
21
|
+
assert_equal 'test/fixtures/sample.rb', subject.grouped_results['App'].first.short_name
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'has gem files' do
|
25
|
+
assert_equal "#{FAKE_GEM_PATH}/gem_name.rb", subject.grouped_results['Gems'].first.first.short_name
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe Coverband::Utils::FileGroups, :vendored_gems do
|
30
|
+
FAKE_VENDOR_GEM_PATH = "#{test_root}/app/vendor/bundle/ruby/2.5.0/gems"
|
31
|
+
subject do
|
32
|
+
controller_lines = [nil, 2, 2, 0, nil, nil, 0, nil, nil, nil]
|
33
|
+
files = [
|
34
|
+
Coverband::Utils::SourceFile.new(source_fixture('sample.rb'), [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil]),
|
35
|
+
Coverband::Utils::SourceFile.new(source_fixture('app/models/user.rb'), [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil]),
|
36
|
+
Coverband::Utils::SourceFile.new(source_fixture('app/controllers/sample_controller.rb'), controller_lines),
|
37
|
+
Coverband::Utils::SourceFile.new("#{FAKE_VENDOR_GEM_PATH}/gem_name.rb", controller_lines)
|
38
|
+
]
|
39
|
+
Coverband.configuration.expects(:gem_paths).at_least_once.returns([FAKE_VENDOR_GEM_PATH])
|
40
|
+
Coverband.configuration.track_gems = true
|
41
|
+
Coverband::Utils::FileGroups.new(files)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'has app files' do
|
45
|
+
assert_equal 'test/fixtures/sample.rb', subject.grouped_results['App'].first.short_name
|
46
|
+
end
|
47
|
+
|
48
|
+
it "doesn't include vendor gems in app files app files" do
|
49
|
+
assert_nil subject.grouped_results['App'].select { |files| files.short_name.match(/gem_name/) }.first
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'does has gem files' do
|
53
|
+
assert_equal 'gem_name.rb', subject.grouped_results['Gems'].first.first.short_name
|
54
|
+
end
|
55
|
+
end
|
@@ -6,7 +6,7 @@ require File.expand_path('../../test_helper', File.dirname(__FILE__))
|
|
6
6
|
# Thanks for all the help SimpleCov https://github.com/colszowka/simplecov-html
|
7
7
|
# initial version of test pulled into Coverband from Simplecov 12/19/2018
|
8
8
|
####
|
9
|
-
describe Coverband::Utils::
|
9
|
+
describe Coverband::Utils::FileList do
|
10
10
|
subject do
|
11
11
|
original_result = {
|
12
12
|
source_fixture('sample.rb') => [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil],
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require File.expand_path('../../test_helper', File.dirname(__FILE__))
|
4
|
+
|
5
|
+
####
|
6
|
+
# Thanks for all the help SimpleCov https://github.com/colszowka/simplecov-html
|
7
|
+
# initial version of test pulled into Coverband from Simplecov 12/19/2018
|
8
|
+
####
|
9
|
+
describe Coverband::Utils::GemList do
|
10
|
+
subject do
|
11
|
+
controller_lines = [nil, 2, 2, 0, nil, nil, 0, nil, nil, nil]
|
12
|
+
gem_files = [
|
13
|
+
Coverband::Utils::SourceFile.new(source_fixture('sample.rb'), [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil]),
|
14
|
+
Coverband::Utils::SourceFile.new(source_fixture('app/models/user.rb'), [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil]),
|
15
|
+
Coverband::Utils::SourceFile.new(source_fixture('app/controllers/sample_controller.rb'), controller_lines)
|
16
|
+
]
|
17
|
+
gem_lists = [Coverband::Utils::FileList.new(gem_files), Coverband::Utils::FileList.new(gem_files)]
|
18
|
+
Coverband::Utils::GemList.new(gem_lists)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'has 22 covered lines' do
|
22
|
+
assert_equal 22, subject.covered_lines
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'has 6 missed lines' do
|
26
|
+
assert_equal 6, subject.missed_lines
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'has 34 never lines' do
|
30
|
+
assert_equal 34, subject.never_lines
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'has 28 lines of code' do
|
34
|
+
assert_equal 28, subject.lines_of_code
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'has 10 skipped lines' do
|
38
|
+
assert_equal 10, subject.skipped_lines
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'has the correct covered percent' do
|
42
|
+
assert_equal 78.57142857142857, subject.covered_percent
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'has the correct covered strength' do
|
46
|
+
assert_equal 0.9285714285714286, subject.covered_strength
|
47
|
+
end
|
48
|
+
end
|
data/views/file_list.erb
CHANGED
@@ -1,18 +1,20 @@
|
|
1
1
|
<div class="file_list_container" id="<%= title_id %>">
|
2
|
-
|
3
|
-
<
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
<span class="
|
8
|
-
<%= source_files.covered_strength
|
9
|
-
|
10
|
-
|
11
|
-
|
2
|
+
<% unless options[:skip_nav] %>
|
3
|
+
<h2>
|
4
|
+
<span class="group_name"><%= title %></span>
|
5
|
+
(<span class="covered_percent"><span class="<%= coverage_css_class(source_files.covered_percent) %>"><%= source_files.covered_percent.round(2) %>%</span></span>
|
6
|
+
covered at
|
7
|
+
<span class="covered_strength">
|
8
|
+
<span class="<%= strength_css_class(source_files.covered_strength) %>">
|
9
|
+
<%= source_files.covered_strength.round(2) %>
|
10
|
+
</span>
|
11
|
+
</span> hits/line)
|
12
|
+
</h2>
|
13
|
+
<% end %>
|
12
14
|
<a name="<%= title_id %>"></a>
|
13
15
|
<div>
|
14
16
|
<b><%= source_files.length %></b> files in total.
|
15
|
-
<b><%= source_files.lines_of_code %></b> relevant lines.
|
17
|
+
<b><%= source_files.lines_of_code %></b> relevant lines.
|
16
18
|
<span class="green"><b><%= source_files.covered_lines %></b> lines covered</span> and
|
17
19
|
<span class="red"><b><%= source_files.missed_lines %></b> lines missed </span>
|
18
20
|
</div>
|
@@ -30,15 +32,17 @@
|
|
30
32
|
</thead>
|
31
33
|
<tbody>
|
32
34
|
<% source_files.each do |source_file| %>
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
35
|
+
<tr>
|
36
|
+
<td class="strong">
|
37
|
+
<%= link_to_source_file(source_file) %>
|
38
|
+
</td>
|
39
|
+
<td class="<%= coverage_css_class(source_file.covered_percent) %> strong"><%= source_file.covered_percent.round(2).to_s %> %</td>
|
40
|
+
<td><%= source_file.lines.count %></td>
|
41
|
+
<td><%= source_file.covered_lines.count + source_file.missed_lines.count %></td>
|
42
|
+
<td><%= source_file.covered_lines.count %></td>
|
43
|
+
<td><%= source_file.missed_lines.count %></td>
|
44
|
+
<td><%= source_file.covered_strength %></td>
|
45
|
+
</tr>
|
42
46
|
<% end %>
|
43
47
|
</tbody>
|
44
48
|
</table>
|
data/views/gem_list.erb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
<div class="file_list_container" id="<%= title_id %>">
|
2
|
+
<h2>
|
3
|
+
<span class="group_name"><%= title %></span>
|
4
|
+
(<span class="covered_percent"><span class="<%= coverage_css_class(source_files.covered_percent) %>"><%= source_files.covered_percent.round(2) %>%</span></span>
|
5
|
+
covered at
|
6
|
+
<span class="covered_strength">
|
7
|
+
<span class="<%= strength_css_class(source_files.covered_strength) %>">
|
8
|
+
<%= source_files.covered_strength.round(2) %>
|
9
|
+
</span>
|
10
|
+
</span> hits/line)
|
11
|
+
</h2>
|
12
|
+
<div>
|
13
|
+
<b><%= source_files.length %></b> files in total.
|
14
|
+
<b><%= source_files.lines_of_code %></b> relevant lines.
|
15
|
+
<span class="green"><b><%= source_files.covered_lines %></b> lines covered</span> and
|
16
|
+
<span class="red"><b><%= source_files.missed_lines %></b> lines missed </span>
|
17
|
+
</div>
|
18
|
+
<table class="gem_list">
|
19
|
+
<thead>
|
20
|
+
<tr>
|
21
|
+
<th>Gem</th>
|
22
|
+
<th>% covered</th>
|
23
|
+
<th>Relevant Lines</th>
|
24
|
+
<th>Lines covered</th>
|
25
|
+
<th>Lines missed</th>
|
26
|
+
<th>Avg. Hits / Line</th>
|
27
|
+
</tr>
|
28
|
+
</thead>
|
29
|
+
<tbody>
|
30
|
+
<% source_files.each do |source_file| %>
|
31
|
+
<tr>
|
32
|
+
<td class="strong">
|
33
|
+
<% if gem_details? %>
|
34
|
+
<%= link_to_gem_list(source_file.first.gem_name) %>
|
35
|
+
<% else %>
|
36
|
+
<%= source_file.first.gem_name %>
|
37
|
+
<% end %>
|
38
|
+
</td>
|
39
|
+
<td class="<%= coverage_css_class(source_file.covered_percent) %> strong"><%= source_file.covered_percent.round(2).to_s %> %</td>
|
40
|
+
<td><%= source_file.covered_lines + source_file.missed_lines %></td>
|
41
|
+
<td><%= source_file.covered_lines %></td>
|
42
|
+
<td><%= source_file.missed_lines %></td>
|
43
|
+
<td><%= source_file.covered_strength %></td>
|
44
|
+
</tr>
|
45
|
+
<% end %>
|
46
|
+
</tbody>
|
47
|
+
</table>
|
48
|
+
</div>
|
49
|
+
|
50
|
+
<% if gem_details? %>
|
51
|
+
<% source_files.each do |gem_files| %>
|
52
|
+
<%= formatted_file_list(gem_files.first.gem_name, gem_files, skip_nav: true) %>
|
53
|
+
<% end %>
|
54
|
+
<% end %>
|
data/views/layout.erb
CHANGED
@@ -16,11 +16,15 @@
|
|
16
16
|
<div id="wrapper" style="display:none;">
|
17
17
|
<div id="header">
|
18
18
|
<a href='<%= base_path %>'>Coverband Admin</a>
|
19
|
+
<a href='<%= base_path %>settings'>Settings</a>
|
19
20
|
<%= button("#{base_path}collect_coverage", 'force coverage collection') %>
|
20
21
|
<%= button("#{base_path}reload_files", 'reload Coverband files') %>
|
21
22
|
<% if Coverband.configuration.web_enable_clear %>
|
22
23
|
<%= button("#{base_path}clear", 'clear coverage report', delete: true) %>
|
23
24
|
<% end %>
|
25
|
+
<% if Coverband.configuration.web_debug %>
|
26
|
+
<a href='<%= base_path %>debug_data'>Debug Data</a>
|
27
|
+
<% end %>
|
24
28
|
</div>
|
25
29
|
<% if notice.to_s.length > 0 %>
|
26
30
|
<div class="notice"><%= notice %></div>
|
@@ -29,7 +33,7 @@
|
|
29
33
|
<ul class="group_tabs"></ul>
|
30
34
|
|
31
35
|
<div id="content">
|
32
|
-
<%= formatted_file_list("All Files", result.source_files) %>
|
36
|
+
<%= formatted_file_list("All Files", result.source_files) unless view_gems? %>
|
33
37
|
|
34
38
|
<% result.groups.each do |name, files| %>
|
35
39
|
<%= formatted_file_list(name, files) %>
|
@@ -42,7 +46,9 @@
|
|
42
46
|
|
43
47
|
<div class="source_files">
|
44
48
|
<% result.source_files.each do |source_file| %>
|
45
|
-
|
49
|
+
<% if (!source_file.gem? || (view_gems? && gem_details? && source_file.gem? )) %>
|
50
|
+
<%= formatted_source_file(source_file) %>
|
51
|
+
<% end %>
|
46
52
|
<% end %>
|
47
53
|
</div>
|
48
54
|
</div>
|
data/views/settings.erb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html xmlns='http://www.w3.org/1999/xhtml'>
|
3
|
+
<head>
|
4
|
+
<title>Coverband Settings: <%= Coverband::VERSION %></title>
|
5
|
+
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
6
|
+
<script src='<%= assets_path('application.js') %>' type='text/javascript'></script>
|
7
|
+
<link href='<%= assets_path('application.css') %>' media='screen, projection, print' rel='stylesheet' type='text/css'>
|
8
|
+
<link rel="icon" type="image/png" href="<%= assets_path('favicon.png') %>" />
|
9
|
+
</head>
|
10
|
+
|
11
|
+
<body>
|
12
|
+
<div id="wrapper" style="">
|
13
|
+
<div id="header">
|
14
|
+
<a href='<%= base_path %>'>Coverband Admin</a>
|
15
|
+
<a href='<%= base_path %>settings'>Settings</a>
|
16
|
+
</div>
|
17
|
+
<div id="content">
|
18
|
+
<dl>
|
19
|
+
<% Coverband.configuration.to_h.each_pair do |key,value| %>
|
20
|
+
<dt><%= key %></dt>
|
21
|
+
<dd><%= value %></dd>
|
22
|
+
<% end %>
|
23
|
+
</dl>
|
24
|
+
</div>
|
25
|
+
<div id="footer">
|
26
|
+
Generated by <a href="http://github.com/danmayer/coverband">Coverband</a> v<%= Coverband::VERSION %>
|
27
|
+
</div>
|
28
|
+
</div>
|
29
|
+
</body>
|
30
|
+
</html>
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: coverband
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.1.0.
|
4
|
+
version: 4.1.0.beta
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dan Mayer
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2019-02-
|
12
|
+
date: 2019-02-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: aws-sdk-s3
|
@@ -255,7 +255,9 @@ files:
|
|
255
255
|
- lib/coverband/reporters/console_report.rb
|
256
256
|
- lib/coverband/reporters/html_report.rb
|
257
257
|
- lib/coverband/reporters/web.rb
|
258
|
+
- lib/coverband/utils/file_groups.rb
|
258
259
|
- lib/coverband/utils/file_list.rb
|
260
|
+
- lib/coverband/utils/gem_list.rb
|
259
261
|
- lib/coverband/utils/html_formatter.rb
|
260
262
|
- lib/coverband/utils/lines_classifier.rb
|
261
263
|
- lib/coverband/utils/railtie.rb
|
@@ -329,20 +331,25 @@ files:
|
|
329
331
|
- test/unit/middleware_test.rb
|
330
332
|
- test/unit/rack_server_checkout_test.rb
|
331
333
|
- test/unit/rails_full_stack_test.rb
|
334
|
+
- test/unit/rails_gems_full_stack_test.rb
|
332
335
|
- test/unit/reports_base_test.rb
|
333
336
|
- test/unit/reports_console_test.rb
|
334
337
|
- test/unit/reports_html_test.rb
|
335
338
|
- test/unit/reports_web_test.rb
|
336
339
|
- test/unit/resque_worker_test.rb
|
337
340
|
- test/unit/test_resque_job.rb
|
341
|
+
- test/unit/utils/file_groups_test.rb
|
338
342
|
- test/unit/utils/file_list_test.rb
|
343
|
+
- test/unit/utils/gem_list_test.rb
|
339
344
|
- test/unit/utils/lines_classifier_test.rb
|
340
345
|
- test/unit/utils/result_test.rb
|
341
346
|
- test/unit/utils/s3_report_test.rb
|
342
347
|
- test/unit/utils/source_file_line_test.rb
|
343
348
|
- test/unit/utils/source_file_test.rb
|
344
349
|
- views/file_list.erb
|
350
|
+
- views/gem_list.erb
|
345
351
|
- views/layout.erb
|
352
|
+
- views/settings.erb
|
346
353
|
- views/source_file.erb
|
347
354
|
homepage: https://github.com/danmayer/coverband
|
348
355
|
licenses:
|
@@ -364,7 +371,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
364
371
|
version: 1.3.1
|
365
372
|
requirements: []
|
366
373
|
rubyforge_project:
|
367
|
-
rubygems_version: 2.5.
|
374
|
+
rubygems_version: 2.5.1
|
368
375
|
signing_key:
|
369
376
|
specification_version: 4
|
370
377
|
summary: Rack middleware to help measure production code usage (LOC runtime usage)
|
@@ -410,13 +417,16 @@ test_files:
|
|
410
417
|
- test/unit/middleware_test.rb
|
411
418
|
- test/unit/rack_server_checkout_test.rb
|
412
419
|
- test/unit/rails_full_stack_test.rb
|
420
|
+
- test/unit/rails_gems_full_stack_test.rb
|
413
421
|
- test/unit/reports_base_test.rb
|
414
422
|
- test/unit/reports_console_test.rb
|
415
423
|
- test/unit/reports_html_test.rb
|
416
424
|
- test/unit/reports_web_test.rb
|
417
425
|
- test/unit/resque_worker_test.rb
|
418
426
|
- test/unit/test_resque_job.rb
|
427
|
+
- test/unit/utils/file_groups_test.rb
|
419
428
|
- test/unit/utils/file_list_test.rb
|
429
|
+
- test/unit/utils/gem_list_test.rb
|
420
430
|
- test/unit/utils/lines_classifier_test.rb
|
421
431
|
- test/unit/utils/result_test.rb
|
422
432
|
- test/unit/utils/s3_report_test.rb
|