coverband 4.2.1 → 4.2.2.rc.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -9
- data/CODE_OF_CONDUCT.md +76 -0
- data/README.md +7 -22
- data/changes.md +13 -11
- data/coverband.gemspec +0 -5
- data/lib/coverband/adapters/base.rb +8 -13
- data/lib/coverband/adapters/file_store.rb +10 -4
- data/lib/coverband/adapters/hash_redis_store.rb +174 -0
- data/lib/coverband/adapters/redis_store.rb +15 -1
- data/lib/coverband/collectors/coverage.rb +5 -7
- data/lib/coverband/collectors/view_tracker.rb +124 -0
- data/lib/coverband/configuration.rb +21 -1
- data/lib/coverband/integrations/background.rb +2 -1
- data/lib/coverband/reporters/base.rb +4 -5
- data/lib/coverband/reporters/console_report.rb +1 -0
- data/lib/coverband/reporters/web.rb +6 -0
- data/lib/coverband/utils/absolute_file_converter.rb +47 -0
- data/lib/coverband/utils/file_hasher.rb +16 -0
- data/lib/coverband/utils/html_formatter.rb +12 -0
- data/lib/coverband/utils/railtie.rb +15 -3
- data/lib/coverband/utils/relative_file_converter.rb +41 -0
- data/lib/coverband/utils/s3_report.rb +2 -2
- data/lib/coverband/utils/source_file.rb +1 -3
- data/lib/coverband/utils/tasks.rb +1 -0
- data/lib/coverband/version.rb +5 -1
- data/lib/coverband.rb +7 -1
- data/public/application.css +6 -6
- data/test/benchmarks/benchmark.rake +25 -49
- data/test/benchmarks/init_rails.rake +10 -0
- data/test/coverband/adapters/hash_redis_store_test.rb +190 -0
- data/test/coverband/adapters/redis_store_test.rb +90 -88
- data/test/coverband/collectors/coverage_test.rb +6 -2
- data/test/coverband/collectors/view_tracker_test.rb +77 -0
- data/test/coverband/integrations/resque_worker_test.rb +2 -3
- data/test/coverband/reporters/base_test.rb +1 -78
- data/test/coverband/reporters/console_test.rb +1 -4
- data/test/coverband/reporters/html_test.rb +9 -9
- data/test/coverband/utils/absolute_file_converter_test.rb +56 -0
- data/test/coverband/utils/file_hasher_test.rb +29 -0
- data/test/coverband/utils/relative_file_converter_test.rb +39 -0
- data/test/forked/rails_rake_full_stack_test.rb +9 -1
- data/test/integration/full_stack_test.rb +1 -2
- data/test/test_helper.rb +6 -7
- data/test/unique_files.rb +1 -1
- data/views/layout.erb +1 -20
- data/views/nav.erb +35 -0
- data/views/view_tracker.erb +37 -0
- metadata +24 -33
- data/lib/coverband/utils/file_path_helper.rb +0 -68
@@ -8,7 +8,7 @@ module Coverband
|
|
8
8
|
:background_reporting_enabled,
|
9
9
|
:background_reporting_sleep_seconds, :test_env,
|
10
10
|
:web_enable_clear, :gem_details, :web_debug, :report_on_exit,
|
11
|
-
:simulate_oneshot_lines_coverage
|
11
|
+
:simulate_oneshot_lines_coverage, :track_views, :view_tracker
|
12
12
|
|
13
13
|
attr_writer :logger, :s3_region, :s3_bucket, :s3_access_key_id, :s3_secret_access_key, :password
|
14
14
|
attr_reader :track_gems, :ignore, :use_oneshot_lines_coverage
|
@@ -30,6 +30,10 @@ module Coverband
|
|
30
30
|
# heroku asset compilation
|
31
31
|
IGNORE_DEFAULTS = %w[vendor .erb$ .slim$ /tmp internal:prelude schema.rb]
|
32
32
|
|
33
|
+
# Add in missing files which were never loaded
|
34
|
+
# we need to know what all paths to check for unloaded files
|
35
|
+
TRACKED_DEFAULT_PATHS = %w[app lib config]
|
36
|
+
|
33
37
|
def initialize
|
34
38
|
reset
|
35
39
|
end
|
@@ -38,6 +42,7 @@ module Coverband
|
|
38
42
|
@root = Dir.pwd
|
39
43
|
@root_paths = []
|
40
44
|
@ignore = IGNORE_DEFAULTS.dup
|
45
|
+
@seach_paths = TRACKED_DEFAULT_PATHS.dup
|
41
46
|
@additional_files = []
|
42
47
|
@verbose = false
|
43
48
|
@reporter = 'scov'
|
@@ -49,6 +54,7 @@ module Coverband
|
|
49
54
|
@web_enable_clear = false
|
50
55
|
@track_gems = false
|
51
56
|
@gem_details = false
|
57
|
+
@track_views = false
|
52
58
|
@groups = {}
|
53
59
|
@web_debug = false
|
54
60
|
@report_on_exit = true
|
@@ -106,6 +112,20 @@ module Coverband
|
|
106
112
|
@store = store
|
107
113
|
end
|
108
114
|
|
115
|
+
###
|
116
|
+
# Search Paths
|
117
|
+
###
|
118
|
+
def tracked_search_paths
|
119
|
+
"#{Coverband.configuration.current_root}/{#{@seach_paths.join(',')}}/**/*.{rb}"
|
120
|
+
end
|
121
|
+
|
122
|
+
###
|
123
|
+
# Don't allow the to override defaults
|
124
|
+
###
|
125
|
+
def search_paths=(path_array)
|
126
|
+
@seach_paths = (@seach_paths + path_array).uniq
|
127
|
+
end
|
128
|
+
|
109
129
|
###
|
110
130
|
# Don't allow the ignore to override things like gem tracking
|
111
131
|
###
|
@@ -27,11 +27,12 @@ module Coverband
|
|
27
27
|
@semaphore.synchronize do
|
28
28
|
return if running?
|
29
29
|
|
30
|
-
logger.debug('Coverband: Starting background reporting')
|
30
|
+
logger.debug('Coverband: Starting background reporting') if Coverband.configuration.verbose
|
31
31
|
sleep_seconds = Coverband.configuration.background_reporting_sleep_seconds
|
32
32
|
@thread = Thread.new do
|
33
33
|
loop do
|
34
34
|
Coverband.report_coverage
|
35
|
+
Coverband.configuration.view_tracker&.report_views_tracked
|
35
36
|
if Coverband.configuration.verbose
|
36
37
|
logger.debug("Coverband: background reporting coverage (#{Coverband.configuration.store.type}). Sleeping #{sleep_seconds}s")
|
37
38
|
end
|
@@ -8,8 +8,6 @@ module Coverband
|
|
8
8
|
###
|
9
9
|
class Base
|
10
10
|
class << self
|
11
|
-
include Coverband::Utils::FilePathHelper
|
12
|
-
|
13
11
|
DATA_KEY = 'data'
|
14
12
|
|
15
13
|
def report(store, _options = {})
|
@@ -17,6 +15,7 @@ module Coverband
|
|
17
15
|
scov_style_report = get_current_scov_data_imp(store, all_roots)
|
18
16
|
|
19
17
|
# These are extremelhy verbose but useful during coverband development, not generally for users
|
18
|
+
# Only avaiable by uncommenting this mode is never released
|
20
19
|
# if Coverband.configuration.verbose
|
21
20
|
# # msg = "report:\n #{scov_style_report.inspect}"
|
22
21
|
# # Coverband.configuration.logger.debug msg
|
@@ -30,7 +29,7 @@ module Coverband
|
|
30
29
|
###
|
31
30
|
def fix_reports(reports)
|
32
31
|
# list all files, even if not tracked by Coverband (0% coverage)
|
33
|
-
tracked_glob =
|
32
|
+
tracked_glob = Coverband.configuration.tracked_search_paths
|
34
33
|
filtered_report_files = {}
|
35
34
|
|
36
35
|
reports.each_pair do |report_name, report_data|
|
@@ -50,13 +49,13 @@ module Coverband
|
|
50
49
|
protected
|
51
50
|
|
52
51
|
def fix_file_names(report_hash, roots)
|
53
|
-
Coverband.configuration.logger.
|
52
|
+
Coverband.configuration.logger.debug "fixing root: #{roots.join(', ')}" if Coverband.configuration.verbose
|
54
53
|
|
55
54
|
# normalize names across servers
|
56
55
|
report_hash.each_with_object({}) do |(name, report), fixed_report|
|
57
56
|
fixed_report[name] = {}
|
58
57
|
report.each_pair do |key, vals|
|
59
|
-
filename =
|
58
|
+
filename = Coverband::Utils::AbsoluteFileConverter.convert(key)
|
60
59
|
fixed_report[name][filename] = if fixed_report[name].key?(filename) && fixed_report[name][filename][DATA_KEY] && vals[DATA_KEY]
|
61
60
|
merged_data = merge_arrays(fixed_report[name][filename][DATA_KEY], vals[DATA_KEY])
|
62
61
|
vals[DATA_KEY] = merged_data
|
@@ -10,6 +10,7 @@ module Coverband
|
|
10
10
|
scov_style_report = super(store, options)
|
11
11
|
|
12
12
|
scov_style_report.each_pair do |file, usage|
|
13
|
+
# TODO: In Coverband 5 deprecate none hash format
|
13
14
|
if usage.is_a?(Hash)
|
14
15
|
Coverband.configuration.logger.info "#{file}: #{usage['data']}"
|
15
16
|
else
|
@@ -47,6 +47,8 @@ module Coverband
|
|
47
47
|
@static.call(env)
|
48
48
|
when %r{\/settings}
|
49
49
|
[200, { 'Content-Type' => 'text/html' }, [settings]]
|
50
|
+
when %r{\/view_tracker}
|
51
|
+
[200, { 'Content-Type' => 'text/html' }, [view_tracker]]
|
50
52
|
when %r{\/debug_data}
|
51
53
|
[200, { 'Content-Type' => 'text/json' }, [debug_data]]
|
52
54
|
when %r{\/load_file_details}
|
@@ -73,6 +75,10 @@ module Coverband
|
|
73
75
|
Coverband::Utils::HTMLFormatter.new(nil, base_path: base_path).format_settings!
|
74
76
|
end
|
75
77
|
|
78
|
+
def view_tracker
|
79
|
+
Coverband::Utils::HTMLFormatter.new(nil, base_path: base_path).format_view_tracker!
|
80
|
+
end
|
81
|
+
|
76
82
|
def debug_data
|
77
83
|
Coverband.configuration.store.get_coverage_report.to_json
|
78
84
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Coverband
|
4
|
+
module Utils
|
5
|
+
class AbsoluteFileConverter
|
6
|
+
def initialize(roots)
|
7
|
+
@cache = {}
|
8
|
+
@roots = roots.map { |root| "#{File.expand_path(root)}/" }
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.instance
|
12
|
+
@instance ||= new(Coverband.configuration.all_root_paths)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.reset
|
16
|
+
@instance = nil
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.convert(relative_path)
|
20
|
+
instance.convert(relative_path)
|
21
|
+
end
|
22
|
+
|
23
|
+
def convert(relative_path)
|
24
|
+
@cache[relative_path] ||= begin
|
25
|
+
relative_filename = relative_path
|
26
|
+
local_filename = relative_filename
|
27
|
+
@roots.each do |root|
|
28
|
+
relative_filename = relative_filename.sub(/^#{root}/, './')
|
29
|
+
# once we have a relative path break out of the loop
|
30
|
+
break if relative_filename.start_with? './'
|
31
|
+
end
|
32
|
+
# the filename for our reports is expected to be a full path.
|
33
|
+
# roots.last should be roots << current_root}/
|
34
|
+
# a fully expanded path of config.root
|
35
|
+
# filename = filename.gsub('./', roots.last)
|
36
|
+
# above only works for app files
|
37
|
+
# we need to rethink some of this logic
|
38
|
+
# gems aren't at project root and can have multiple locations
|
39
|
+
local_root = @roots.find do |root|
|
40
|
+
File.exist?(relative_filename.gsub('./', root))
|
41
|
+
end
|
42
|
+
local_root ? relative_filename.gsub('./', local_root) : local_filename
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Coverband
|
4
|
+
module Utils
|
5
|
+
class FileHasher
|
6
|
+
@cache = {}
|
7
|
+
|
8
|
+
def self.hash(file, path_converter: AbsoluteFileConverter.instance)
|
9
|
+
@cache[file] ||= begin
|
10
|
+
file = path_converter.convert(file)
|
11
|
+
Digest::MD5.file(file).hexdigest if File.exist?(file)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -33,6 +33,10 @@ module Coverband
|
|
33
33
|
format_settings
|
34
34
|
end
|
35
35
|
|
36
|
+
def format_view_tracker!
|
37
|
+
format_view_tracker
|
38
|
+
end
|
39
|
+
|
36
40
|
def format_source_file!(filename)
|
37
41
|
source_file = @coverage_result.file_from_path_with_type(filename)
|
38
42
|
|
@@ -49,6 +53,10 @@ module Coverband
|
|
49
53
|
template('settings').result(binding)
|
50
54
|
end
|
51
55
|
|
56
|
+
def format_view_tracker
|
57
|
+
template('view_tracker').result(binding)
|
58
|
+
end
|
59
|
+
|
52
60
|
def format(result)
|
53
61
|
Dir[File.join(File.dirname(__FILE__), '../../../public/*')].each do |path|
|
54
62
|
FileUtils.cp_r(path, asset_output_path)
|
@@ -104,6 +112,10 @@ module Coverband
|
|
104
112
|
button + '</form>'
|
105
113
|
end
|
106
114
|
|
115
|
+
def display_nav(nav_options = {})
|
116
|
+
template('nav').result(binding)
|
117
|
+
end
|
118
|
+
|
107
119
|
# Returns the html for the given source_file
|
108
120
|
def formatted_source_file(result, source_file)
|
109
121
|
template('source_file').result(binding)
|
@@ -5,9 +5,6 @@ module Coverband
|
|
5
5
|
def eager_load!
|
6
6
|
Coverband.eager_loading_coverage!
|
7
7
|
super
|
8
|
-
ensure
|
9
|
-
Coverband.report_coverage
|
10
|
-
Coverband.runtime_coverage!
|
11
8
|
end
|
12
9
|
end
|
13
10
|
Rails::Engine.prepend(RailsEagerLoad)
|
@@ -15,6 +12,21 @@ module Coverband
|
|
15
12
|
class Railtie < Rails::Railtie
|
16
13
|
initializer 'coverband.configure' do |app|
|
17
14
|
app.middleware.use Coverband::BackgroundMiddleware
|
15
|
+
|
16
|
+
if Coverband.configuration.track_views
|
17
|
+
CoverbandViewTracker = Coverband::Collectors::ViewTracker.new
|
18
|
+
Coverband.configuration.view_tracker = CoverbandViewTracker
|
19
|
+
|
20
|
+
ActiveSupport::Notifications.subscribe(/render_partial.action_view|render_template.action_view/) do |name, start, finish, id, payload|
|
21
|
+
CoverbandViewTracker.track_views(name, start, finish, id, payload) unless name.include?('!')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
config.after_initialize do
|
27
|
+
Coverband.eager_loading_coverage!
|
28
|
+
Coverband.report_coverage
|
29
|
+
Coverband.runtime_coverage!
|
18
30
|
end
|
19
31
|
|
20
32
|
rake_tasks do
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Coverband
|
4
|
+
module Utils
|
5
|
+
class RelativeFileConverter
|
6
|
+
def self.instance
|
7
|
+
@instance ||= new(Coverband.configuration.all_root_paths)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.reset
|
11
|
+
@instance = nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.convert(file)
|
15
|
+
instance.convert(file)
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(roots)
|
19
|
+
@cache = {}
|
20
|
+
@roots = normalize(roots)
|
21
|
+
end
|
22
|
+
|
23
|
+
def convert(file)
|
24
|
+
@cache[file] ||= begin
|
25
|
+
relative_file = file
|
26
|
+
@roots.each do |root|
|
27
|
+
relative_file = file.gsub(/^#{root}/, '.')
|
28
|
+
break relative_file if relative_file.start_with?('.')
|
29
|
+
end
|
30
|
+
relative_file
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def normalize(paths)
|
37
|
+
paths.map { |root| File.expand_path(root) }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -26,8 +26,8 @@ module Coverband
|
|
26
26
|
begin
|
27
27
|
require 'aws-sdk-s3'
|
28
28
|
rescue StandardError
|
29
|
-
err_msg = '
|
30
|
-
Coverband.configuration.logger
|
29
|
+
err_msg = 'Coverband requires aws-sdk in order use S3Report.'
|
30
|
+
Coverband.configuration.logger&.error err_msg
|
31
31
|
return
|
32
32
|
end
|
33
33
|
end
|
@@ -10,8 +10,6 @@
|
|
10
10
|
module Coverband
|
11
11
|
module Utils
|
12
12
|
class SourceFile
|
13
|
-
include Coverband::Utils::FilePathHelper
|
14
|
-
|
15
13
|
# TODO: Refactor Line into its own file
|
16
14
|
# Representation of a single line in a source file including
|
17
15
|
# this specific line's source code, line_number and code coverage,
|
@@ -246,7 +244,7 @@ module Coverband
|
|
246
244
|
end
|
247
245
|
|
248
246
|
def relative_path
|
249
|
-
|
247
|
+
RelativeFileConverter.convert(filename)
|
250
248
|
end
|
251
249
|
|
252
250
|
def gem?
|
@@ -15,6 +15,7 @@ namespace :coverband do
|
|
15
15
|
|
16
16
|
desc 'report runtime Coverband code coverage'
|
17
17
|
task :coverage_server do
|
18
|
+
Rake.application['environment'].invoke if Rake::Task.task_defined?('environment')
|
18
19
|
Rack::Server.start app: Coverband::Reporters::Web.new, Port: ENV.fetch('COVERBAND_COVERAGE_PORT', 1022).to_i
|
19
20
|
end
|
20
21
|
|
data/lib/coverband/version.rb
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
###
|
4
|
+
# ensure we properly do release candidate versioning; https://github.com/danmayer/coverband/issues/288
|
5
|
+
# use format '4.2.1.rc.1' ~> 4.2.1.rc to prerelease versions like v4.2.1.rc.2 and v4.2.1.rc.3
|
6
|
+
###
|
3
7
|
module Coverband
|
4
|
-
VERSION = '4.2.1'
|
8
|
+
VERSION = '4.2.2.rc.1'
|
5
9
|
end
|
data/lib/coverband.rb
CHANGED
@@ -6,10 +6,13 @@ require 'redis'
|
|
6
6
|
require 'coverband/version'
|
7
7
|
require 'coverband/at_exit'
|
8
8
|
require 'coverband/configuration'
|
9
|
-
require 'coverband/utils/
|
9
|
+
require 'coverband/utils/relative_file_converter'
|
10
|
+
require 'coverband/utils/absolute_file_converter'
|
10
11
|
require 'coverband/adapters/base'
|
11
12
|
require 'coverband/adapters/redis_store'
|
13
|
+
require 'coverband/adapters/hash_redis_store'
|
12
14
|
require 'coverband/adapters/file_store'
|
15
|
+
require 'coverband/utils/file_hasher'
|
13
16
|
require 'coverband/utils/s3_report'
|
14
17
|
require 'coverband/utils/html_formatter'
|
15
18
|
require 'coverband/utils/result'
|
@@ -20,6 +23,7 @@ require 'coverband/utils/file_groups'
|
|
20
23
|
require 'coverband/utils/lines_classifier'
|
21
24
|
require 'coverband/utils/results'
|
22
25
|
require 'coverband/collectors/coverage'
|
26
|
+
require 'coverband/collectors/view_tracker'
|
23
27
|
require 'coverband/reporters/base'
|
24
28
|
require 'coverband/reporters/html_report'
|
25
29
|
require 'coverband/reporters/console_report'
|
@@ -28,6 +32,8 @@ require 'coverband/integrations/background'
|
|
28
32
|
require 'coverband/integrations/background_middleware'
|
29
33
|
require 'coverband/integrations/rack_server_check'
|
30
34
|
|
35
|
+
Coverband::Adapters::RedisStore = Coverband::Adapters::HashRedisStore if ENV['COVERBAND_HASH_REDIS_STORE']
|
36
|
+
|
31
37
|
module Coverband
|
32
38
|
@@configured = false
|
33
39
|
CONFIG_FILE = './config/coverband.rb'
|
data/public/application.css
CHANGED
@@ -634,15 +634,15 @@ abbr.timeago {
|
|
634
634
|
float: right;
|
635
635
|
color: #dddddd; }
|
636
636
|
|
637
|
-
.group_tabs {
|
637
|
+
.group_tabs, .extra_tabs {
|
638
638
|
list-style: none;
|
639
639
|
float: left;
|
640
640
|
margin: 0;
|
641
641
|
padding: 0; }
|
642
|
-
.group_tabs li {
|
642
|
+
.group_tabs li, .extra_tabs li {
|
643
643
|
display: inline;
|
644
644
|
float: left; }
|
645
|
-
.group_tabs li a {
|
645
|
+
.group_tabs li a, .extra_tabs li a {
|
646
646
|
font-family: Helvetica, Arial, sans-serif;
|
647
647
|
display: block;
|
648
648
|
float: left;
|
@@ -664,15 +664,15 @@ abbr.timeago {
|
|
664
664
|
-moz-border-radius-topright: 2px;
|
665
665
|
border-top-left-radius: 2px;
|
666
666
|
border-top-right-radius: 2px; }
|
667
|
-
.group_tabs li a:hover {
|
667
|
+
.group_tabs li a:hover, .extra_tabs li a:hover {
|
668
668
|
background-color: #cccccc;
|
669
669
|
background: -webkit-gradient(linear, 0 0, 0 bottom, from(#eeeeee), to(#aaaaaa));
|
670
670
|
background: -moz-linear-gradient(#eeeeee, #aaaaaa);
|
671
671
|
background: linear-gradient(#eeeeee, #aaaaaa); }
|
672
|
-
.group_tabs li a:active {
|
672
|
+
.group_tabs li a:active, .extra_tabs li a:active {
|
673
673
|
padding-top: 5px;
|
674
674
|
padding-bottom: 3px; }
|
675
|
-
.group_tabs li.active a {
|
675
|
+
.group_tabs li.active a, .extra_tabs li.active a {
|
676
676
|
color: black;
|
677
677
|
text-shadow: white 1px 1px 0px;
|
678
678
|
background-color: #dddddd;
|
@@ -27,30 +27,11 @@ namespace :benchmarks do
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
def classifier_dir
|
31
|
-
File.join(File.dirname(__FILE__), 'classifier-reborn')
|
32
|
-
end
|
33
|
-
|
34
|
-
def clone_classifier
|
35
|
-
system "git clone https://github.com/jekyll/classifier-reborn.git #{classifier_dir}" unless Dir.exist? classifier_dir
|
36
|
-
end
|
37
|
-
|
38
30
|
# desc 'setup standard benchmark'
|
39
31
|
task :setup do
|
40
|
-
clone_classifier
|
41
|
-
$LOAD_PATH.unshift(File.join(classifier_dir, 'lib'))
|
42
32
|
require 'benchmark'
|
43
33
|
require 'benchmark/ips'
|
44
34
|
|
45
|
-
# TODO: ok this is interesting and weird
|
46
|
-
# basically the earlier I require coverage and
|
47
|
-
# then require files the larger perf impact
|
48
|
-
# this is somewhat expected but can lead to significant perf diffs
|
49
|
-
# for example moving `require 'classifier-reborn'` below the coverage.start
|
50
|
-
# results in 1.5x slower vs "difference falls within error"
|
51
|
-
# moving from 5 second of time to 12 still shows slower based on when classifier is required
|
52
|
-
# make sure to be plugged in while benchmarking ;) Otherwise you get very unreliable results
|
53
|
-
require 'classifier-reborn'
|
54
35
|
if ENV['COVERAGE'] || ENV['ONESHOT']
|
55
36
|
require 'coverage'
|
56
37
|
::Coverage.start(oneshot_lines: !!ENV['ONESHOT'])
|
@@ -91,32 +72,7 @@ namespace :benchmarks do
|
|
91
72
|
end
|
92
73
|
end
|
93
74
|
|
94
|
-
def bayes_classification
|
95
|
-
b = ClassifierReborn::Bayes.new 'Interesting', 'Uninteresting'
|
96
|
-
b.train_interesting 'here are some good words. I hope you love them'
|
97
|
-
b.train_uninteresting 'here are some bad words, I hate you'
|
98
|
-
b.classify 'I hate bad words and you' # returns 'Uninteresting'
|
99
|
-
end
|
100
|
-
|
101
|
-
def lsi_classification
|
102
|
-
lsi = ClassifierReborn::LSI.new
|
103
|
-
strings = [['This text deals with dogs. Dogs.', :dog],
|
104
|
-
['This text involves dogs too. Dogs! ', :dog],
|
105
|
-
['This text revolves around cats. Cats.', :cat],
|
106
|
-
['This text also involves cats. Cats!', :cat],
|
107
|
-
['This text involves birds. Birds.', :bird]]
|
108
|
-
strings.each { |x| lsi.add_item x.first, x.last }
|
109
|
-
lsi.search('dog', 3)
|
110
|
-
lsi.find_related(strings[2], 2)
|
111
|
-
lsi.classify 'This text is also about dogs!'
|
112
|
-
end
|
113
|
-
|
114
75
|
def work
|
115
|
-
5.times do
|
116
|
-
bayes_classification
|
117
|
-
lsi_classification
|
118
|
-
end
|
119
|
-
|
120
76
|
# simulate many calls to the same line
|
121
77
|
10_000.times { Dog.new.bark }
|
122
78
|
end
|
@@ -140,9 +96,11 @@ namespace :benchmarks do
|
|
140
96
|
Coverband::Collectors::Coverage.instance.reset_instance
|
141
97
|
end
|
142
98
|
|
99
|
+
LINES = 45
|
100
|
+
NON_NIL_LINES = 18
|
143
101
|
def fake_line_numbers
|
144
|
-
|
145
|
-
|
102
|
+
LINES.times.map do |line|
|
103
|
+
coverage = (line < NON_NIL_LINES) ? rand(5) : nil
|
146
104
|
end
|
147
105
|
end
|
148
106
|
|
@@ -165,8 +123,8 @@ namespace :benchmarks do
|
|
165
123
|
###
|
166
124
|
# this is a hack because in the benchmark we don't have real files
|
167
125
|
###
|
168
|
-
def store.file_hash(
|
169
|
-
@
|
126
|
+
def store.file_hash(_file)
|
127
|
+
@file_hash ||= Digest::MD5.file(__FILE__).hexdigest
|
170
128
|
end
|
171
129
|
|
172
130
|
def store.full_path_to_relative(file)
|
@@ -183,7 +141,13 @@ namespace :benchmarks do
|
|
183
141
|
5.times { store.save_report(report) }
|
184
142
|
Benchmark.ips do |x|
|
185
143
|
x.config(time: 15, warmup: 5)
|
186
|
-
x.report('
|
144
|
+
x.report('store_reports_all') { store.save_report(report) }
|
145
|
+
end
|
146
|
+
keys_subset = report.keys.first(100)
|
147
|
+
report_subset = report.select { |key, _value| keys_subset.include?(key) }
|
148
|
+
Benchmark.ips do |x|
|
149
|
+
x.config(time: 20, warmup: 5)
|
150
|
+
x.report('store_reports_subset') { store.save_report(report_subset) }
|
187
151
|
end
|
188
152
|
end
|
189
153
|
|
@@ -415,6 +379,18 @@ namespace :benchmarks do
|
|
415
379
|
`open tmp/timeseries.jpg`
|
416
380
|
end
|
417
381
|
|
382
|
+
desc 'benchmark initialization of rails'
|
383
|
+
task :init_rails do
|
384
|
+
require 'benchmark'
|
385
|
+
require 'benchmark/ips'
|
386
|
+
Benchmark.ips do |x|
|
387
|
+
x.config(time: 60, warmup: 0)
|
388
|
+
x.report('init_rails') do
|
389
|
+
system('bundle exec rake init_rails -f ./test/benchmarks/init_rails.rake')
|
390
|
+
end
|
391
|
+
end
|
392
|
+
end
|
393
|
+
|
418
394
|
desc 'compare Coverband Ruby Coverage with Filestore with normal Ruby'
|
419
395
|
task :compare_file do
|
420
396
|
puts 'comparing Coverage loaded/not, this takes some time for output...'
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails'
|
4
|
+
require 'coverband'
|
5
|
+
|
6
|
+
desc 'Initialize rails'
|
7
|
+
task 'init_rails' do
|
8
|
+
Coverband.configure("./test/rails#{Rails::VERSION::MAJOR}_dummy/config/coverband.rb")
|
9
|
+
require "./test/rails#{Rails::VERSION::MAJOR}_dummy/config/environment"
|
10
|
+
end
|