test-prof 0.1.0.beta4 → 0.1.0.pre2
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/.gitignore +10 -0
- data/.rspec +2 -0
- data/.rubocop.yml +69 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/README.md +2 -16
- data/Rakefile +8 -0
- data/bin/setup +8 -0
- data/circle.yml +11 -0
- data/guides/any_fixture.md +1 -1
- data/guides/ruby_prof.md +0 -2
- data/guides/stack_prof.md +1 -5
- data/lib/test_prof.rb +6 -31
- data/lib/test_prof/event_prof.rb +4 -2
- data/lib/test_prof/event_prof/custom_events.rb +3 -3
- data/lib/test_prof/event_prof/custom_events/factory_create.rb +9 -11
- data/lib/test_prof/event_prof/custom_events/sidekiq_inline.rb +9 -11
- data/lib/test_prof/event_prof/custom_events/sidekiq_jobs.rb +11 -13
- data/lib/test_prof/event_prof/rspec.rb +1 -5
- data/lib/test_prof/factory_doctor.rb +9 -11
- data/lib/test_prof/factory_doctor/rspec.rb +3 -5
- data/lib/test_prof/ruby_prof.rb +12 -6
- data/lib/test_prof/stack_prof.rb +7 -14
- data/lib/test_prof/version.rb +1 -1
- data/spec/integrations/any_fixture_spec.rb +11 -0
- data/spec/integrations/before_all_spec.rb +11 -0
- data/spec/integrations/event_prof_spec.rb +100 -0
- data/spec/integrations/factory_doctor_spec.rb +20 -0
- data/spec/integrations/fixtures/rspec/any_fixture_fixture.rb +37 -0
- data/spec/integrations/fixtures/rspec/before_all_fixture.rb +32 -0
- data/spec/integrations/fixtures/rspec/event_prof_factory_create_fixture.rb +23 -0
- data/spec/integrations/fixtures/rspec/event_prof_fixture.rb +51 -0
- data/spec/integrations/fixtures/rspec/event_prof_sidekiq_fixture.rb +54 -0
- data/spec/integrations/fixtures/rspec/factory_doctor_fixture.rb +33 -0
- data/spec/spec_helper.rb +38 -0
- data/spec/support/ar_models.rb +43 -0
- data/spec/support/instrumenter_stub.rb +19 -0
- data/spec/support/integration_helpers.rb +13 -0
- data/spec/support/transactional_context.rb +11 -0
- data/spec/test_prof/any_fixture_spec.rb +66 -0
- data/spec/test_prof/event_prof_spec.rb +138 -0
- data/spec/test_prof/ext/float_duration_spec.rb +12 -0
- data/spec/test_prof/factory_doctor_spec.rb +84 -0
- data/spec/test_prof/ruby_prof_spec.rb +109 -0
- data/spec/test_prof/stack_prof_spec.rb +73 -0
- data/spec/test_prof_spec.rb +23 -0
- data/test-prof.gemspec +35 -0
- metadata +34 -49
- data/CHANGELOG.md +0 -7
- data/assets/flamegraph.demo.html +0 -173
- data/assets/flamegraph.template.html +0 -196
- data/assets/src/d3-tip.js +0 -352
- data/assets/src/d3-tip.min.js +0 -1
- data/assets/src/d3.flameGraph.css +0 -92
- data/assets/src/d3.flameGraph.js +0 -459
- data/assets/src/d3.flameGraph.min.css +0 -1
- data/assets/src/d3.flameGraph.min.js +0 -1
- data/assets/src/d3.v4.min.js +0 -8
- data/guides/factory_default.md +0 -109
- data/guides/factory_prof.md +0 -85
- data/guides/rspec_stamp.md +0 -53
- data/guides/rubocop.md +0 -48
- data/guides/tag_prof.md +0 -52
- data/guides/tests_sampling.md +0 -24
- data/lib/test_prof/cops/rspec/aggregate_failures.rb +0 -140
- data/lib/test_prof/factory_default.rb +0 -58
- data/lib/test_prof/factory_default/factory_girl_patch.rb +0 -22
- data/lib/test_prof/factory_prof.rb +0 -140
- data/lib/test_prof/factory_prof/factory_girl_patch.rb +0 -12
- data/lib/test_prof/factory_prof/printers/flamegraph.rb +0 -71
- data/lib/test_prof/factory_prof/printers/simple.rb +0 -28
- data/lib/test_prof/recipes/minitest/sample.rb +0 -29
- data/lib/test_prof/recipes/rspec/factory_default.rb +0 -9
- data/lib/test_prof/recipes/rspec/sample.rb +0 -13
- data/lib/test_prof/rspec_stamp.rb +0 -135
- data/lib/test_prof/rspec_stamp/parser.rb +0 -103
- data/lib/test_prof/rspec_stamp/rspec.rb +0 -95
- data/lib/test_prof/rubocop.rb +0 -3
- data/lib/test_prof/tag_prof.rb +0 -8
- data/lib/test_prof/tag_prof/rspec.rb +0 -84
@@ -1,103 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "ripper"
|
4
|
-
|
5
|
-
# rubocop: disable Metrics/CyclomaticComplexity
|
6
|
-
|
7
|
-
module TestProf
|
8
|
-
module RSpecStamp
|
9
|
-
# Parse examples headers
|
10
|
-
module Parser
|
11
|
-
# Contains the result of parsing
|
12
|
-
class Result
|
13
|
-
attr_accessor :fname, :desc
|
14
|
-
attr_reader :tags, :htags
|
15
|
-
|
16
|
-
def add_tag(v)
|
17
|
-
@tags ||= []
|
18
|
-
@tags << v
|
19
|
-
end
|
20
|
-
|
21
|
-
def add_htag(k, v)
|
22
|
-
@htags ||= []
|
23
|
-
@htags << [k, v]
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
class << self
|
28
|
-
def parse(code)
|
29
|
-
sexp = Ripper.sexp(code)
|
30
|
-
return unless sexp
|
31
|
-
|
32
|
-
# sexp has the following format:
|
33
|
-
# [:program,
|
34
|
-
# [
|
35
|
-
# [
|
36
|
-
# :command,
|
37
|
-
# [:@ident, "it", [1, 0]],
|
38
|
-
# [:args_add_block, [ ... ]]
|
39
|
-
# ]
|
40
|
-
# ]
|
41
|
-
# ]
|
42
|
-
#
|
43
|
-
# or
|
44
|
-
#
|
45
|
-
# [:program,
|
46
|
-
# [
|
47
|
-
# [
|
48
|
-
# :vcall,
|
49
|
-
# [:@ident, "it", [1, 0]]
|
50
|
-
# ]
|
51
|
-
# ]
|
52
|
-
# ]
|
53
|
-
res = Result.new
|
54
|
-
|
55
|
-
fcall = sexp[1][0][1]
|
56
|
-
fcall = fcall[1] if fcall.first == :fcall
|
57
|
-
res.fname = fcall[1]
|
58
|
-
|
59
|
-
args_block = sexp[1][0][2]
|
60
|
-
|
61
|
-
return res if args_block.nil?
|
62
|
-
|
63
|
-
args_block = args_block[1] if args_block.first == :arg_paren
|
64
|
-
|
65
|
-
args = args_block[1]
|
66
|
-
|
67
|
-
if args.first.first == :string_literal
|
68
|
-
res.desc = parse_literal(args.shift)
|
69
|
-
end
|
70
|
-
|
71
|
-
parse_arg(res, args.shift) until args.empty?
|
72
|
-
|
73
|
-
res
|
74
|
-
end
|
75
|
-
|
76
|
-
private
|
77
|
-
|
78
|
-
def parse_arg(res, arg)
|
79
|
-
if arg.first == :symbol_literal
|
80
|
-
res.add_tag parse_literal(arg)
|
81
|
-
elsif arg.first == :bare_assoc_hash
|
82
|
-
parse_hash(res, arg[1])
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
def parse_hash(res, hash_arg)
|
87
|
-
hash_arg.each do |(_, label, val)|
|
88
|
-
res.add_htag label[1][0..-2].to_sym, parse_literal(val)
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
# Expr of the form:
|
93
|
-
# [:string_literal, [:string_content, [:@tstring_content, "is", [1, 4]]]]
|
94
|
-
def parse_literal(expr)
|
95
|
-
val = expr[1][1][1]
|
96
|
-
val = val.to_sym if expr[0] == :symbol_literal ||
|
97
|
-
expr[0] == :assoc_new
|
98
|
-
val
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
@@ -1,95 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module TestProf
|
4
|
-
module RSpecStamp
|
5
|
-
class RSpecListener # :nodoc:
|
6
|
-
include Logging
|
7
|
-
|
8
|
-
NOTIFICATIONS = %i[
|
9
|
-
example_failed
|
10
|
-
].freeze
|
11
|
-
|
12
|
-
def initialize
|
13
|
-
@failed = 0
|
14
|
-
@ignored = 0
|
15
|
-
@total = 0
|
16
|
-
@examples = Hash.new { |h, k| h[k] = [] }
|
17
|
-
end
|
18
|
-
|
19
|
-
def example_failed(notification)
|
20
|
-
return if notification.example.pending?
|
21
|
-
|
22
|
-
location = notification.example.metadata[:location]
|
23
|
-
|
24
|
-
file, line = location.split(":")
|
25
|
-
|
26
|
-
@examples[file] << line.to_i
|
27
|
-
end
|
28
|
-
|
29
|
-
def stamp!
|
30
|
-
@examples.each do |file, lines|
|
31
|
-
stamp_file(file, lines.uniq)
|
32
|
-
end
|
33
|
-
|
34
|
-
msgs = []
|
35
|
-
|
36
|
-
msgs <<
|
37
|
-
<<~MSG
|
38
|
-
RSpec Stamp results
|
39
|
-
|
40
|
-
Total patches: #{@total}
|
41
|
-
Total files: #{@examples.keys.size}
|
42
|
-
|
43
|
-
Failed patches: #{@failed}
|
44
|
-
Ignored files: #{@ignored}
|
45
|
-
MSG
|
46
|
-
|
47
|
-
log :info, msgs.join
|
48
|
-
end
|
49
|
-
|
50
|
-
private
|
51
|
-
|
52
|
-
def stamp_file(file, lines)
|
53
|
-
@total += lines.size
|
54
|
-
return if ignored?(file)
|
55
|
-
|
56
|
-
log :info, "(dry-run) Patching #{file}" if dry_run?
|
57
|
-
|
58
|
-
code = File.readlines(file)
|
59
|
-
|
60
|
-
@failed += RSpecStamp.apply_tags(code, lines, RSpecStamp.config.tags)
|
61
|
-
|
62
|
-
File.write(file, code.join) unless dry_run?
|
63
|
-
end
|
64
|
-
|
65
|
-
def ignored?(file)
|
66
|
-
ignored = RSpecStamp.config.ignore_files.find do |pattern|
|
67
|
-
file =~ pattern
|
68
|
-
end
|
69
|
-
|
70
|
-
return unless ignored
|
71
|
-
log :warn, "Ignore stamping file: #{file}"
|
72
|
-
@ignored += 1
|
73
|
-
end
|
74
|
-
|
75
|
-
def dry_run?
|
76
|
-
RSpecStamp.config.dry_run?
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
# Register EventProf listener
|
83
|
-
TestProf.activate('RSTAMP') do
|
84
|
-
RSpec.configure do |config|
|
85
|
-
listener = TestProf::RSpecStamp::RSpecListener.new
|
86
|
-
|
87
|
-
config.before(:suite) do
|
88
|
-
config.reporter.register_listener(
|
89
|
-
listener, *TestProf::RSpecStamp::RSpecListener::NOTIFICATIONS
|
90
|
-
)
|
91
|
-
end
|
92
|
-
|
93
|
-
config.after(:suite) { listener.stamp! }
|
94
|
-
end
|
95
|
-
end
|
data/lib/test_prof/rubocop.rb
DELETED
data/lib/test_prof/tag_prof.rb
DELETED
@@ -1,84 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "test_prof/ext/float_duration"
|
4
|
-
|
5
|
-
module TestProf
|
6
|
-
module TagProf
|
7
|
-
class RSpecListener # :nodoc:
|
8
|
-
include Logging
|
9
|
-
using FloatDuration
|
10
|
-
|
11
|
-
NOTIFICATIONS = %i[
|
12
|
-
example_started
|
13
|
-
example_finished
|
14
|
-
].freeze
|
15
|
-
|
16
|
-
def initialize
|
17
|
-
@tag = ENV['TAG_PROF'].to_sym
|
18
|
-
@tags = Hash.new { |h, k| h[k] = { val: k, count: 0, time: 0.0 } }
|
19
|
-
|
20
|
-
log :info, "TagProf enabled (#{@tag})"
|
21
|
-
end
|
22
|
-
|
23
|
-
def example_started(_notification)
|
24
|
-
@ts = Time.now
|
25
|
-
end
|
26
|
-
|
27
|
-
def example_finished(notification)
|
28
|
-
return if notification.example.pending?
|
29
|
-
|
30
|
-
tag = notification.example.metadata.fetch(@tag, :__unknown__)
|
31
|
-
|
32
|
-
@tags[tag][:count] += 1
|
33
|
-
@tags[tag][:time] += (Time.now - @ts)
|
34
|
-
end
|
35
|
-
|
36
|
-
def print
|
37
|
-
msgs = []
|
38
|
-
|
39
|
-
msgs <<
|
40
|
-
<<~MSG
|
41
|
-
TagProf report for #{@tag}
|
42
|
-
MSG
|
43
|
-
|
44
|
-
msgs << format(
|
45
|
-
"%15s %12s %6s %6s %6s %12s",
|
46
|
-
@tag,
|
47
|
-
'time', 'total', '%total', '%time', 'avg'
|
48
|
-
)
|
49
|
-
|
50
|
-
msgs << ""
|
51
|
-
|
52
|
-
total = @tags.values.sum { |v| v[:count] }
|
53
|
-
total_time = @tags.values.sum { |v| v[:time] }
|
54
|
-
|
55
|
-
@tags.values.sort_by { |v| -v[:time] }.each do |tag|
|
56
|
-
msgs << format(
|
57
|
-
"%15s %12s %6d %6.2f %6.2f %12s",
|
58
|
-
tag[:val], tag[:time].duration, tag[:count],
|
59
|
-
100 * tag[:count].to_f / total,
|
60
|
-
100 * tag[:time] / total_time,
|
61
|
-
(tag[:time] / tag[:count]).duration
|
62
|
-
)
|
63
|
-
end
|
64
|
-
|
65
|
-
log :info, msgs.join("\n")
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
# Register TagProf listener
|
72
|
-
TestProf.activate('TAG_PROF') do
|
73
|
-
RSpec.configure do |config|
|
74
|
-
listener = TestProf::TagProf::RSpecListener.new
|
75
|
-
|
76
|
-
config.before(:suite) do
|
77
|
-
config.reporter.register_listener(
|
78
|
-
listener, *TestProf::TagProf::RSpecListener::NOTIFICATIONS
|
79
|
-
)
|
80
|
-
end
|
81
|
-
|
82
|
-
config.after(:suite) { listener.print }
|
83
|
-
end
|
84
|
-
end
|