test-prof 0.11.3 → 1.0.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +122 -447
- data/LICENSE.txt +1 -1
- data/README.md +9 -13
- data/config/default.yml +0 -15
- data/config/rubocop-rspec.yml +6 -0
- data/lib/minitest/test_prof_plugin.rb +3 -0
- data/lib/test_prof/any_fixture.rb +116 -7
- data/lib/test_prof/any_fixture/dump.rb +207 -0
- data/lib/test_prof/any_fixture/dump/base_adapter.rb +43 -0
- data/lib/test_prof/any_fixture/dump/digest.rb +29 -0
- data/lib/test_prof/any_fixture/dump/postgresql.rb +91 -0
- data/lib/test_prof/any_fixture/dump/sqlite.rb +42 -0
- data/lib/test_prof/before_all.rb +9 -4
- data/lib/test_prof/before_all/adapters/active_record.rb +14 -5
- data/lib/test_prof/cops/rspec/aggregate_examples.rb +2 -2
- data/lib/test_prof/cops/rspec/aggregate_examples/its.rb +1 -1
- data/lib/test_prof/cops/rspec/aggregate_examples/line_range_helpers.rb +1 -1
- data/lib/test_prof/cops/rspec/aggregate_examples/matchers_with_side_effects.rb +1 -1
- data/lib/test_prof/cops/rspec/aggregate_examples/metadata_helpers.rb +1 -1
- data/lib/test_prof/cops/rspec/aggregate_examples/node_matchers.rb +1 -1
- data/lib/test_prof/event_prof/instrumentations/active_support.rb +22 -4
- data/lib/test_prof/recipes/minitest/before_all.rb +48 -23
- data/lib/test_prof/recipes/minitest/sample.rb +6 -10
- data/lib/test_prof/recipes/rspec/before_all.rb +10 -10
- data/lib/test_prof/recipes/rspec/let_it_be.rb +111 -13
- data/lib/test_prof/recipes/rspec/sample.rb +4 -2
- data/lib/test_prof/rubocop.rb +0 -1
- data/lib/test_prof/stack_prof.rb +3 -0
- data/lib/test_prof/version.rb +1 -1
- metadata +23 -21
- data/lib/test_prof/cops/rspec/aggregate_failures.rb +0 -26
- data/lib/test_prof/ext/active_record_3.rb +0 -27
- data/lib/test_prof/recipes/active_record_one_love.rb +0 -6
- data/lib/test_prof/recipes/active_record_shared_connection.rb +0 -77
@@ -35,18 +35,14 @@ module TestProf
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
38
|
-
end
|
39
38
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
39
|
+
def call
|
40
|
+
if ENV["SAMPLE"]
|
41
|
+
::TestProf::MinitestSample.sample_examples(ENV["SAMPLE"].to_i)
|
42
|
+
elsif ENV["SAMPLE_GROUPS"]
|
43
|
+
::TestProf::MinitestSample.sample_groups(ENV["SAMPLE_GROUPS"].to_i)
|
44
|
+
end
|
46
45
|
end
|
47
|
-
super
|
48
46
|
end
|
49
47
|
end
|
50
48
|
end
|
51
|
-
|
52
|
-
Minitest.singleton_class.prepend(TestProf::MinitestSample)
|
@@ -6,14 +6,22 @@ module TestProf
|
|
6
6
|
module BeforeAll
|
7
7
|
# Helper to wrap the whole example group into a transaction
|
8
8
|
module RSpec
|
9
|
-
def before_all(&block)
|
9
|
+
def before_all(setup_fixtures: BeforeAll.config.setup_fixtures, &block)
|
10
10
|
raise ArgumentError, "Block is required!" unless block_given?
|
11
11
|
|
12
|
-
|
12
|
+
if within_before_all?
|
13
|
+
before(:all) do
|
14
|
+
@__inspect_output = "before_all hook"
|
15
|
+
instance_eval(&block)
|
16
|
+
end
|
17
|
+
return
|
18
|
+
end
|
13
19
|
|
14
20
|
@__before_all_activated__ = true
|
15
21
|
|
16
22
|
before(:all) do
|
23
|
+
@__inspect_output = "before_all hook"
|
24
|
+
BeforeAll.setup_fixtures(self) if setup_fixtures
|
17
25
|
BeforeAll.begin_transaction do
|
18
26
|
instance_eval(&block)
|
19
27
|
end
|
@@ -24,14 +32,6 @@ module TestProf
|
|
24
32
|
end
|
25
33
|
end
|
26
34
|
|
27
|
-
def within_before_all(&block)
|
28
|
-
before(:all) do
|
29
|
-
BeforeAll.within_transaction do
|
30
|
-
instance_eval(&block)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
35
|
def within_before_all?
|
36
36
|
instance_variable_defined?(:@__before_all_activated__)
|
37
37
|
end
|
@@ -22,6 +22,10 @@ module TestProf
|
|
22
22
|
|
23
23
|
LetItBe.modifiers[key] = block
|
24
24
|
end
|
25
|
+
|
26
|
+
def default_modifiers
|
27
|
+
@default_modifiers ||= {}
|
28
|
+
end
|
25
29
|
end
|
26
30
|
|
27
31
|
class << self
|
@@ -75,6 +79,8 @@ module TestProf
|
|
75
79
|
# And we love cats!)
|
76
80
|
PREFIX = RUBY_ENGINE == "jruby" ? "@__jruby_is_not_cat_friendly__" : "@😸"
|
77
81
|
|
82
|
+
FROZEN_ERROR_HINT = "\nIf you are using `let_it_be`, you may want to pass `reload: true` or `refind: true` modifier to it."
|
83
|
+
|
78
84
|
def self.define_let_it_be_alias(name, **default_args)
|
79
85
|
define_method(name) do |identifier, **options, &blk|
|
80
86
|
let_it_be(identifier, **default_args.merge(options), &blk)
|
@@ -83,27 +89,28 @@ module TestProf
|
|
83
89
|
|
84
90
|
def let_it_be(identifier, **options, &block)
|
85
91
|
initializer = proc do
|
86
|
-
instance_variable_set(:"#{PREFIX}#{identifier}", instance_exec(&block))
|
92
|
+
instance_variable_set(:"#{TestProf::LetItBe::PREFIX}#{identifier}", instance_exec(&block))
|
93
|
+
rescue FrozenError => e
|
94
|
+
e.message << TestProf::LetItBe::FROZEN_ERROR_HINT
|
95
|
+
raise
|
87
96
|
end
|
88
97
|
|
89
|
-
|
90
|
-
|
91
|
-
else
|
92
|
-
before_all(&initializer)
|
93
|
-
end
|
98
|
+
default_options = LetItBe.config.default_modifiers.dup
|
99
|
+
default_options.merge!(metadata[:let_it_be_modifiers]) if metadata[:let_it_be_modifiers]
|
94
100
|
|
95
|
-
|
96
|
-
|
101
|
+
options = default_options.merge(options)
|
102
|
+
|
103
|
+
before_all(&initializer)
|
97
104
|
|
98
|
-
|
99
|
-
let_accessor = LetItBe.wrap_with_modifiers(modifiers) do
|
105
|
+
let_accessor = LetItBe.wrap_with_modifiers(options) do
|
100
106
|
instance_variable_get(:"#{PREFIX}#{identifier}")
|
101
107
|
end
|
102
108
|
|
103
109
|
LetItBe.module_for(self).module_eval do
|
104
110
|
define_method(identifier) do
|
105
|
-
# Trying to detect the context
|
106
|
-
|
111
|
+
# Trying to detect the context
|
112
|
+
# Based on https://github.com/rspec/rspec-rails/commit/7cb796db064f58da7790a92e73ab906ef50b1f34
|
113
|
+
if @__inspect_output.include?("before(:context)") || @__inspect_output.include?("before_all")
|
107
114
|
instance_variable_get(:"#{PREFIX}#{identifier}")
|
108
115
|
else
|
109
116
|
# Fallback to let definition
|
@@ -114,16 +121,78 @@ module TestProf
|
|
114
121
|
|
115
122
|
let(identifier, &let_accessor)
|
116
123
|
end
|
124
|
+
|
125
|
+
module Freezer
|
126
|
+
# Stoplist to prevent freezing objects and theirs associations that are defined
|
127
|
+
# with `let_it_be`'s `freeze: false` options during deep freezing.
|
128
|
+
#
|
129
|
+
# To only keep track of objects that are available in current example group,
|
130
|
+
# `begin` adds a new layer, and `rollback` removes a layer of unrelated objects
|
131
|
+
# along with rolling back the transaction where they were created.
|
132
|
+
#
|
133
|
+
# Stoplist holds records declared with `freeze: false` (so we do not freeze them even if they're used as
|
134
|
+
# associated records for frozen objects)
|
135
|
+
module Stoplist
|
136
|
+
class << self
|
137
|
+
def stop?(record)
|
138
|
+
@stoplist.any? { |layer| layer.include?(record) }
|
139
|
+
end
|
140
|
+
|
141
|
+
def stop!(record)
|
142
|
+
@stoplist.last.push(record)
|
143
|
+
end
|
144
|
+
|
145
|
+
def begin
|
146
|
+
@stoplist.push([])
|
147
|
+
end
|
148
|
+
|
149
|
+
def rollback
|
150
|
+
@stoplist.pop
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
# Stack of example group-related variable definitions
|
155
|
+
@stoplist = []
|
156
|
+
end
|
157
|
+
|
158
|
+
class << self
|
159
|
+
# Rerucsively freezes the object to detect modifications
|
160
|
+
def deep_freeze(record)
|
161
|
+
return if record.frozen?
|
162
|
+
return if Stoplist.stop?(record)
|
163
|
+
|
164
|
+
record.freeze
|
165
|
+
|
166
|
+
# Support `let_it_be` with `create_list`
|
167
|
+
return record.each { |rec| deep_freeze(rec) } if record.respond_to?(:each)
|
168
|
+
|
169
|
+
# Freeze associations as well.
|
170
|
+
return unless defined?(::ActiveRecord::Base)
|
171
|
+
return unless record.is_a?(::ActiveRecord::Base)
|
172
|
+
|
173
|
+
record.class.reflections.keys.each do |reflection|
|
174
|
+
# But only if they are already loaded. If not yet loaded, they weren't
|
175
|
+
# created by factories, and it's ok to mutate them.
|
176
|
+
|
177
|
+
next unless record.association(reflection.to_sym).loaded?
|
178
|
+
|
179
|
+
target = record.association(reflection.to_sym).target
|
180
|
+
deep_freeze(target) if target.is_a?(::ActiveRecord::Base) || target.respond_to?(:each)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
117
185
|
end
|
118
186
|
end
|
119
187
|
|
120
|
-
if defined?(::ActiveRecord)
|
188
|
+
if defined?(::ActiveRecord::Base)
|
121
189
|
require "test_prof/ext/active_record_refind"
|
122
190
|
using TestProf::Ext::ActiveRecordRefind
|
123
191
|
|
124
192
|
TestProf::LetItBe.configure do |config|
|
125
193
|
config.register_modifier :reload do |record, val|
|
126
194
|
next record unless val
|
195
|
+
|
127
196
|
next record.reload if record.is_a?(::ActiveRecord::Base)
|
128
197
|
|
129
198
|
if record.respond_to?(:map)
|
@@ -136,6 +205,7 @@ if defined?(::ActiveRecord)
|
|
136
205
|
|
137
206
|
config.register_modifier :refind do |record, val|
|
138
207
|
next record unless val
|
208
|
+
|
139
209
|
next record.refind if record.is_a?(::ActiveRecord::Base)
|
140
210
|
|
141
211
|
if record.respond_to?(:map)
|
@@ -145,7 +215,35 @@ if defined?(::ActiveRecord)
|
|
145
215
|
end
|
146
216
|
record
|
147
217
|
end
|
218
|
+
|
219
|
+
config.register_modifier :freeze do |record, val|
|
220
|
+
if val == false
|
221
|
+
TestProf::LetItBe::Freezer::Stoplist.stop!(record)
|
222
|
+
next record
|
223
|
+
end
|
224
|
+
|
225
|
+
TestProf::LetItBe::Freezer.deep_freeze(record)
|
226
|
+
record
|
227
|
+
end
|
148
228
|
end
|
149
229
|
end
|
150
230
|
|
151
231
|
RSpec::Core::ExampleGroup.extend TestProf::LetItBe
|
232
|
+
|
233
|
+
TestProf::BeforeAll.configure do |config|
|
234
|
+
config.before(:begin) do
|
235
|
+
TestProf::LetItBe::Freezer::Stoplist.begin
|
236
|
+
end
|
237
|
+
|
238
|
+
config.after(:rollback) do
|
239
|
+
TestProf::LetItBe::Freezer::Stoplist.rollback
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
RSpec.configure do |config|
|
244
|
+
config.after(:example) do |example|
|
245
|
+
if example.exception&.is_a?(FrozenError)
|
246
|
+
example.exception.message << TestProf::LetItBe::FROZEN_ERROR_HINT
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
@@ -15,7 +15,8 @@ if ENV["SAMPLE"]
|
|
15
15
|
RSpec.configure do |config|
|
16
16
|
config.before(:suite) do
|
17
17
|
filtered_examples = RSpec.world.filtered_examples.values.flatten
|
18
|
-
|
18
|
+
random = Random.new(RSpec.configuration.seed)
|
19
|
+
sample = filtered_examples.sample(ENV["SAMPLE"].to_i, random: random)
|
19
20
|
RSpec.world.filtered_examples = Hash.new do |hash, group|
|
20
21
|
hash[group] = group.examples & sample
|
21
22
|
end
|
@@ -31,7 +32,8 @@ if ENV["SAMPLE_GROUPS"]
|
|
31
32
|
filtered_groups = RSpec.world.filtered_examples.reject do |_group, examples|
|
32
33
|
examples.empty?
|
33
34
|
end.keys
|
34
|
-
|
35
|
+
random = Random.new(RSpec.configuration.seed)
|
36
|
+
sample = filtered_groups.sample(ENV["SAMPLE_GROUPS"].to_i, random: random)
|
35
37
|
RSpec.world.filtered_examples = Hash.new do |hash, group|
|
36
38
|
hash[group] = sample.include?(group) ? group.examples : []
|
37
39
|
end
|
data/lib/test_prof/rubocop.rb
CHANGED
data/lib/test_prof/stack_prof.rb
CHANGED
data/lib/test_prof/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: test-prof
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0.rc2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vladimir Dementyev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-01-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '13.0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '13.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -56,42 +56,42 @@ dependencies:
|
|
56
56
|
name: isolator
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0.6'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - "
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0.6'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: minitest
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - "
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '5.9'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - "
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '5.9'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: rubocop
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - "
|
87
|
+
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: 0.77.0
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- - "
|
94
|
+
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: 0.77.0
|
97
97
|
description: "\n Ruby applications tests profiling tools.\n\n Contains tools
|
@@ -119,6 +119,7 @@ files:
|
|
119
119
|
- assets/tagprof.demo.html
|
120
120
|
- assets/tagprof.template.html
|
121
121
|
- config/default.yml
|
122
|
+
- config/rubocop-rspec.yml
|
122
123
|
- lib/minitest/base_reporter.rb
|
123
124
|
- lib/minitest/event_prof_formatter.rb
|
124
125
|
- lib/minitest/test_prof_plugin.rb
|
@@ -126,6 +127,11 @@ files:
|
|
126
127
|
- lib/test_prof.rb
|
127
128
|
- lib/test_prof/any_fixture.rb
|
128
129
|
- lib/test_prof/any_fixture/dsl.rb
|
130
|
+
- lib/test_prof/any_fixture/dump.rb
|
131
|
+
- lib/test_prof/any_fixture/dump/base_adapter.rb
|
132
|
+
- lib/test_prof/any_fixture/dump/digest.rb
|
133
|
+
- lib/test_prof/any_fixture/dump/postgresql.rb
|
134
|
+
- lib/test_prof/any_fixture/dump/sqlite.rb
|
129
135
|
- lib/test_prof/before_all.rb
|
130
136
|
- lib/test_prof/before_all/adapters/active_record.rb
|
131
137
|
- lib/test_prof/before_all/isolator.rb
|
@@ -136,7 +142,6 @@ files:
|
|
136
142
|
- lib/test_prof/cops/rspec/aggregate_examples/matchers_with_side_effects.rb
|
137
143
|
- lib/test_prof/cops/rspec/aggregate_examples/metadata_helpers.rb
|
138
144
|
- lib/test_prof/cops/rspec/aggregate_examples/node_matchers.rb
|
139
|
-
- lib/test_prof/cops/rspec/aggregate_failures.rb
|
140
145
|
- lib/test_prof/cops/rspec/language.rb
|
141
146
|
- lib/test_prof/event_prof.rb
|
142
147
|
- lib/test_prof/event_prof/custom_events.rb
|
@@ -148,7 +153,6 @@ files:
|
|
148
153
|
- lib/test_prof/event_prof/monitor.rb
|
149
154
|
- lib/test_prof/event_prof/profiler.rb
|
150
155
|
- lib/test_prof/event_prof/rspec.rb
|
151
|
-
- lib/test_prof/ext/active_record_3.rb
|
152
156
|
- lib/test_prof/ext/active_record_refind.rb
|
153
157
|
- lib/test_prof/ext/array_bsearch_index.rb
|
154
158
|
- lib/test_prof/ext/factory_bot_strategy.rb
|
@@ -173,8 +177,6 @@ files:
|
|
173
177
|
- lib/test_prof/factory_prof/printers/flamegraph.rb
|
174
178
|
- lib/test_prof/factory_prof/printers/simple.rb
|
175
179
|
- lib/test_prof/logging.rb
|
176
|
-
- lib/test_prof/recipes/active_record_one_love.rb
|
177
|
-
- lib/test_prof/recipes/active_record_shared_connection.rb
|
178
180
|
- lib/test_prof/recipes/logging.rb
|
179
181
|
- lib/test_prof/recipes/minitest/before_all.rb
|
180
182
|
- lib/test_prof/recipes/minitest/sample.rb
|
@@ -208,15 +210,15 @@ files:
|
|
208
210
|
- lib/test_prof/utils/rspec.rb
|
209
211
|
- lib/test_prof/utils/sized_ordered_set.rb
|
210
212
|
- lib/test_prof/version.rb
|
211
|
-
homepage: http://github.com/
|
213
|
+
homepage: http://github.com/test-prof/test-prof
|
212
214
|
licenses:
|
213
215
|
- MIT
|
214
216
|
metadata:
|
215
|
-
bug_tracker_uri: http://github.com/
|
216
|
-
changelog_uri: https://github.com/
|
217
|
+
bug_tracker_uri: http://github.com/test-prof/test-prof/issues
|
218
|
+
changelog_uri: https://github.com/test-prof/test-prof/blob/master/CHANGELOG.md
|
217
219
|
documentation_uri: https://test-prof.evilmartians.io/
|
218
220
|
homepage_uri: https://test-prof.evilmartians.io/
|
219
|
-
source_code_uri: http://github.com/
|
221
|
+
source_code_uri: http://github.com/test-prof/test-prof
|
220
222
|
post_install_message:
|
221
223
|
rdoc_options: []
|
222
224
|
require_paths:
|
@@ -225,12 +227,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
225
227
|
requirements:
|
226
228
|
- - ">="
|
227
229
|
- !ruby/object:Gem::Version
|
228
|
-
version: 2.
|
230
|
+
version: 2.5.0
|
229
231
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
230
232
|
requirements:
|
231
|
-
- - "
|
233
|
+
- - ">"
|
232
234
|
- !ruby/object:Gem::Version
|
233
|
-
version:
|
235
|
+
version: 1.3.1
|
234
236
|
requirements: []
|
235
237
|
rubygems_version: 3.0.6
|
236
238
|
signing_key:
|