test-prof 0.11.3 → 1.0.0.rc2
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/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:
|