test-prof 1.0.5 → 1.0.8
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 +31 -7
- data/lib/test_prof/any_fixture/dump/postgresql.rb +1 -1
- data/lib/test_prof/any_fixture/dump/sqlite.rb +1 -1
- data/lib/test_prof/any_fixture.rb +1 -0
- data/lib/test_prof/before_all/adapters/active_record.rb +9 -0
- data/lib/test_prof/before_all.rb +2 -0
- data/lib/test_prof/cops/rspec/aggregate_examples/matchers_with_side_effects.rb +1 -1
- data/lib/test_prof/cops/rspec/aggregate_examples/node_matchers.rb +1 -1
- data/lib/test_prof/cops/rspec/aggregate_examples.rb +5 -5
- data/lib/test_prof/factory_all_stub.rb +1 -0
- data/lib/test_prof/factory_default.rb +5 -3
- data/lib/test_prof/factory_prof.rb +9 -3
- data/lib/test_prof/recipes/logging.rb +0 -2
- data/lib/test_prof/recipes/minitest/before_all.rb +88 -11
- data/lib/test_prof/recipes/rspec/let_it_be.rb +3 -3
- data/lib/test_prof/rspec_dissect/collectors/before.rb +1 -1
- data/lib/test_prof/rspec_dissect/collectors/let.rb +1 -1
- data/lib/test_prof/rspec_stamp/parser.rb +0 -2
- data/lib/test_prof/rspec_stamp.rb +0 -2
- data/lib/test_prof/rubocop.rb +1 -1
- data/lib/test_prof/stack_prof.rb +2 -2
- data/lib/test_prof/version.rb +1 -1
- data/lib/test_prof.rb +8 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9e1623dde5386ea71184b81cf99eb67ac377613d46b2ebac3ce874164103fcbd
|
4
|
+
data.tar.gz: 1b9fa94cb2616226019cbc57ee8dbefa5c03db8f42f0be277352884ab6dfdb48
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7eeec86920c82c3afb8b89478b3992bf1750fdacd949913c0a6c18a684bcefb5998880e4da2cecec1c8d5866dcc89b8a16de31e7e881713f8a4707aa08b25fd6
|
7
|
+
data.tar.gz: 793ec788e3cb95c29b8b3b1a9026db05e64d1ae828ca2ce8a180ffc460cf3d653710b2c4356e47d0dbc3aa8a3fd5ea633502fa5c0f0114a467a5dd01ae99b5b5
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,28 @@
|
|
1
1
|
# Change log
|
2
2
|
|
3
|
-
## master (
|
3
|
+
## master (unreleased)
|
4
|
+
|
5
|
+
## 1.0.8 (2022-03-11)
|
6
|
+
|
7
|
+
- Restore the lock_thread value after rollback. ([@cou929][])
|
8
|
+
|
9
|
+
- Fixes the configuration of a printer for factory_prof runs
|
10
|
+
|
11
|
+
- Ensure that defaults are stored in a threadsafe manner
|
12
|
+
|
13
|
+
## 1.0.7 (2021-08-30)
|
14
|
+
|
15
|
+
- Fix access to `let_it_be` variables in `after(:all)` hook. ([@cbarton][])
|
16
|
+
|
17
|
+
- Add support for using the before_all hook with Rails' parallelize feature (using processes). ([@peret][])
|
18
|
+
|
19
|
+
Make sure to include `TestProf::BeforeAll::Minitest` before you call `parallelize`.
|
20
|
+
|
21
|
+
## 1.0.6 (2021-06-23)
|
22
|
+
|
23
|
+
- Fix Spring detection when `DISABLE_SPRING=1` is used. ([@palkan][])
|
24
|
+
|
25
|
+
- Make `before_all` in Minitest inheritable. ([@palkan][])
|
4
26
|
|
5
27
|
## 1.0.5 (2021-05-13)
|
6
28
|
|
@@ -178,7 +200,7 @@ end
|
|
178
200
|
```
|
179
201
|
|
180
202
|
- Print warning when `ActiveRecordSharedConnection` is used in the version of Rails
|
181
|
-
supporting `lock_threads` (5.1+). ([@palkan][])
|
203
|
+
supporting `lock_threads` (5.1+). ([@palkan][])
|
182
204
|
|
183
205
|
## 0.9.0 (2019-05-14)
|
184
206
|
|
@@ -236,20 +258,22 @@ See [changelog](https://github.com/test-prof/test-prof/blob/v0.8.0/CHANGELOG.md)
|
|
236
258
|
[@palkan]: https://github.com/palkan
|
237
259
|
[@marshall-lee]: https://github.com/marshall-lee
|
238
260
|
[@danielwestendorf]: https://github.com/danielwestendorf
|
239
|
-
[@
|
240
|
-
[@
|
261
|
+
[@shkrt]: https://github.com/Shkrt
|
262
|
+
[@idolgirev]: https://github.com/IDolgirev
|
241
263
|
[@desoleary]: https://github.com/desoleary
|
242
264
|
[@rabotyaga]: https://github.com/rabotyaga
|
243
|
-
[@
|
265
|
+
[@vasfed]: https://github.com/Vasfed
|
244
266
|
[@szemek]: https://github.com/szemek
|
245
267
|
[@mkldon]: https://github.com/mkldon
|
246
268
|
[@dmagro]: https://github.com/dmagro
|
247
269
|
[@danielwaterworth]: https://github.com/danielwaterworth
|
248
|
-
[@
|
270
|
+
[@envek]: https://github.com/Envek
|
249
271
|
[@tyleriguchi]: https://github.com/tyleriguchi
|
250
272
|
[@lostie]: https://github.com/lostie
|
251
273
|
[@pirj]: https://github.com/pirj
|
252
|
-
[@
|
274
|
+
[@lynxeyes]: https://github.com/LynxEyes
|
253
275
|
[@stefkin]: https://github.com/stefkin
|
254
276
|
[@jaimerson]: https://github.com/jaimerson
|
255
277
|
[@alexvko]: https://github.com/alexvko
|
278
|
+
[@grillermo]: https://github.com/grillermo
|
279
|
+
[@cou929]: https://github.com/cou929
|
@@ -37,6 +37,9 @@ module TestProf
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
+
# avoid instance variable collisions with cats
|
41
|
+
PREFIX_RESTORE_LOCK_THREAD = "@😺"
|
42
|
+
|
40
43
|
configure do |config|
|
41
44
|
# Make sure ActiveRecord uses locked thread.
|
42
45
|
# It only gets locked in `before` / `setup` hook,
|
@@ -44,8 +47,14 @@ module TestProf
|
|
44
47
|
# might lead to leaking connections
|
45
48
|
config.before(:begin) do
|
46
49
|
next unless ::ActiveRecord::Base.connection.pool.respond_to?(:lock_thread=)
|
50
|
+
instance_variable_set("#{PREFIX_RESTORE_LOCK_THREAD}_orig_lock_thread", ::ActiveRecord::Base.connection.pool.instance_variable_get(:@lock_thread))
|
47
51
|
::ActiveRecord::Base.connection.pool.lock_thread = true
|
48
52
|
end
|
53
|
+
|
54
|
+
config.after(:rollback) do
|
55
|
+
next unless ::ActiveRecord::Base.connection.pool.respond_to?(:lock_thread=)
|
56
|
+
::ActiveRecord::Base.connection.pool.lock_thread = instance_variable_get("#{PREFIX_RESTORE_LOCK_THREAD}_orig_lock_thread")
|
57
|
+
end
|
49
58
|
end
|
50
59
|
end
|
51
60
|
end
|
data/lib/test_prof/before_all.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
require "test_prof/cops/rspec/aggregate_examples/line_range_helpers"
|
4
|
+
require "test_prof/cops/rspec/aggregate_examples/metadata_helpers"
|
5
|
+
require "test_prof/cops/rspec/aggregate_examples/node_matchers"
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
require "test_prof/cops/rspec/aggregate_examples/its"
|
8
|
+
require "test_prof/cops/rspec/aggregate_examples/matchers_with_side_effects"
|
9
9
|
|
10
10
|
module RuboCop
|
11
11
|
module Cop
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "test_prof"
|
3
4
|
require "test_prof/factory_bot"
|
4
5
|
require "test_prof/factory_default/factory_bot_patch"
|
5
6
|
|
@@ -31,7 +32,6 @@ module TestProf
|
|
31
32
|
TestProf::FactoryBot::Strategy::Build.prepend StrategyExt
|
32
33
|
TestProf::FactoryBot::Strategy::Stub.prepend StrategyExt
|
33
34
|
|
34
|
-
@store = {}
|
35
35
|
# default is false to retain backward compatibility
|
36
36
|
@preserve_traits = false
|
37
37
|
end
|
@@ -57,12 +57,14 @@ module TestProf
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def reset
|
60
|
-
|
60
|
+
store.clear
|
61
61
|
end
|
62
62
|
|
63
63
|
private
|
64
64
|
|
65
|
-
|
65
|
+
def store
|
66
|
+
Thread.current[:testprof_factory_store] ||= {}
|
67
|
+
end
|
66
68
|
end
|
67
69
|
end
|
68
70
|
end
|
@@ -100,15 +100,21 @@ module TestProf
|
|
100
100
|
def run
|
101
101
|
init
|
102
102
|
|
103
|
-
printer = config.printer
|
104
|
-
|
105
103
|
started_at = TestProf.now
|
106
104
|
|
107
|
-
at_exit
|
105
|
+
at_exit do
|
106
|
+
print(started_at)
|
107
|
+
end
|
108
108
|
|
109
109
|
start
|
110
110
|
end
|
111
111
|
|
112
|
+
def print(started_at)
|
113
|
+
printer = config.printer
|
114
|
+
|
115
|
+
printer.dump(result, start_time: started_at)
|
116
|
+
end
|
117
|
+
|
112
118
|
def start
|
113
119
|
reset!
|
114
120
|
@running = true
|
@@ -2,6 +2,22 @@
|
|
2
2
|
|
3
3
|
require "test_prof/before_all"
|
4
4
|
|
5
|
+
Minitest.singleton_class.prepend(Module.new do
|
6
|
+
attr_reader :previous_klass
|
7
|
+
@previous_klass = nil
|
8
|
+
|
9
|
+
def run_one_method(klass, method_name)
|
10
|
+
return super unless klass.respond_to?(:parallelized) && klass.parallelized
|
11
|
+
|
12
|
+
if @previous_klass && @previous_klass != klass
|
13
|
+
@previous_klass.before_all_executor&.deactivate!
|
14
|
+
end
|
15
|
+
@previous_klass = klass
|
16
|
+
|
17
|
+
super
|
18
|
+
end
|
19
|
+
end)
|
20
|
+
|
5
21
|
module TestProf
|
6
22
|
module BeforeAll
|
7
23
|
# Add before_all hook to Minitest: wrap all examples into a transaction and
|
@@ -9,13 +25,15 @@ module TestProf
|
|
9
25
|
module Minitest # :nodoc: all
|
10
26
|
class Executor
|
11
27
|
attr_reader :active, :block, :captured_ivars, :teardown_block, :current_test_object,
|
12
|
-
:setup_fixtures
|
28
|
+
:setup_fixtures, :parent
|
13
29
|
|
14
30
|
alias_method :active?, :active
|
15
31
|
alias_method :setup_fixtures?, :setup_fixtures
|
16
32
|
|
17
|
-
def initialize(setup_fixtures: false, &block)
|
18
|
-
@
|
33
|
+
def initialize(setup_fixtures: false, parent: nil, &block)
|
34
|
+
@parent = parent
|
35
|
+
# Fixtures must be instantiated if any of the executors needs them
|
36
|
+
@setup_fixtures = setup_fixtures || parent&.setup_fixtures
|
19
37
|
@block = block
|
20
38
|
@captured_ivars = []
|
21
39
|
end
|
@@ -28,7 +46,9 @@ module TestProf
|
|
28
46
|
@current_test_object = test_object
|
29
47
|
|
30
48
|
return restore_ivars(test_object) if active?
|
49
|
+
|
31
50
|
@active = true
|
51
|
+
|
32
52
|
BeforeAll.setup_fixtures(test_object) if setup_fixtures?
|
33
53
|
BeforeAll.begin_transaction do
|
34
54
|
capture!(test_object)
|
@@ -36,20 +56,20 @@ module TestProf
|
|
36
56
|
end
|
37
57
|
|
38
58
|
def deactivate!
|
59
|
+
return unless active
|
60
|
+
|
39
61
|
@active = false
|
40
62
|
|
41
|
-
current_test_object
|
63
|
+
perform_teardown(current_test_object)
|
42
64
|
|
43
65
|
@current_test_object = nil
|
44
66
|
BeforeAll.rollback_transaction
|
45
67
|
end
|
46
68
|
|
47
69
|
def capture!(test_object)
|
48
|
-
return unless block
|
49
|
-
|
50
70
|
before_ivars = test_object.instance_variables
|
51
71
|
|
52
|
-
test_object
|
72
|
+
perform_setup(test_object)
|
53
73
|
|
54
74
|
(test_object.instance_variables - before_ivars).each do |ivar|
|
55
75
|
captured_ivars << [ivar, test_object.instance_variable_get(ivar)]
|
@@ -64,19 +84,76 @@ module TestProf
|
|
64
84
|
)
|
65
85
|
end
|
66
86
|
end
|
87
|
+
|
88
|
+
def perform_setup(test_object)
|
89
|
+
parent&.perform_setup(test_object)
|
90
|
+
test_object.instance_eval(&block) if block
|
91
|
+
end
|
92
|
+
|
93
|
+
def perform_teardown(test_object)
|
94
|
+
current_test_object&.instance_eval(&teardown_block) if teardown_block
|
95
|
+
parent&.perform_teardown(test_object)
|
96
|
+
end
|
67
97
|
end
|
68
98
|
|
69
99
|
class << self
|
70
100
|
def included(base)
|
71
101
|
base.extend ClassMethods
|
102
|
+
|
103
|
+
base.cattr_accessor :parallelized
|
104
|
+
if base.respond_to?(:parallelize_teardown)
|
105
|
+
base.parallelize_teardown do
|
106
|
+
last_klass = ::Minitest.previous_klass
|
107
|
+
if last_klass&.respond_to?(:parallelized) && last_klass&.parallelized
|
108
|
+
last_klass.before_all_executor&.deactivate!
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
if base.respond_to?(:parallelize)
|
114
|
+
base.singleton_class.prepend(Module.new do
|
115
|
+
def parallelize(workers: :number_of_processors, with: :processes)
|
116
|
+
# super.parallelize returns nil when no parallelization is set up
|
117
|
+
if super(workers: workers, with: with).nil?
|
118
|
+
return
|
119
|
+
end
|
120
|
+
|
121
|
+
case with
|
122
|
+
when :processes
|
123
|
+
self.parallelized = true
|
124
|
+
when :threads
|
125
|
+
warn "!!! before_all is not implemented for parallalization with threads and " \
|
126
|
+
"could work incorrectly"
|
127
|
+
else
|
128
|
+
warn "!!! tests are using an unknown parallelization strategy and before_all " \
|
129
|
+
"could work incorrectly"
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end)
|
133
|
+
end
|
72
134
|
end
|
73
135
|
end
|
74
136
|
|
75
137
|
module ClassMethods
|
76
|
-
|
138
|
+
attr_writer :before_all_executor
|
139
|
+
|
140
|
+
def before_all_executor
|
141
|
+
return @before_all_executor if instance_variable_defined?(:@before_all_executor)
|
142
|
+
|
143
|
+
@before_all_executor = if superclass.respond_to?(:before_all_executor)
|
144
|
+
superclass.before_all_executor
|
145
|
+
end
|
146
|
+
end
|
77
147
|
|
78
148
|
def before_all(setup_fixtures: BeforeAll.config.setup_fixtures, &block)
|
79
|
-
self.before_all_executor = Executor.new(
|
149
|
+
self.before_all_executor = Executor.new(
|
150
|
+
setup_fixtures: setup_fixtures,
|
151
|
+
parent: before_all_executor,
|
152
|
+
&block
|
153
|
+
)
|
154
|
+
|
155
|
+
# Do not add patches multiple times
|
156
|
+
return if before_all_executor.parent
|
80
157
|
|
81
158
|
prepend(Module.new do
|
82
159
|
def before_setup
|
@@ -89,13 +166,13 @@ module TestProf
|
|
89
166
|
def run(*)
|
90
167
|
super
|
91
168
|
ensure
|
92
|
-
before_all_executor&.deactivate!
|
169
|
+
before_all_executor&.deactivate! unless parallelized
|
93
170
|
end
|
94
171
|
end)
|
95
172
|
end
|
96
173
|
|
97
174
|
def after_all(&block)
|
98
|
-
self.before_all_executor
|
175
|
+
self.before_all_executor = Executor.new(parent: before_all_executor)
|
99
176
|
before_all_executor.teardown(&block)
|
100
177
|
end
|
101
178
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "test_prof"
|
4
|
-
|
4
|
+
require "test_prof/recipes/rspec/before_all"
|
5
5
|
|
6
6
|
module TestProf
|
7
7
|
# Just like `let`, but persist the result for the whole group.
|
@@ -75,7 +75,7 @@ module TestProf
|
|
75
75
|
# Use uniq prefix for instance variables to avoid collisions
|
76
76
|
# We want to use the power of Ruby's unicode support)
|
77
77
|
# And we love cats!)
|
78
|
-
PREFIX =
|
78
|
+
PREFIX = "@😸"
|
79
79
|
|
80
80
|
FROZEN_ERROR_HINT = "\nIf you are using `let_it_be`, you may want to pass `reload: true` or `refind: true` modifier to it."
|
81
81
|
|
@@ -107,7 +107,7 @@ module TestProf
|
|
107
107
|
define_method(identifier) do
|
108
108
|
# Trying to detect the context
|
109
109
|
# Based on https://github.com/rspec/rspec-rails/commit/7cb796db064f58da7790a92e73ab906ef50b1f34
|
110
|
-
if
|
110
|
+
if /(before|after)\(:context\)/.match?(@__inspect_output) || @__inspect_output.include?("before_all")
|
111
111
|
instance_variable_get(:"#{PREFIX}#{identifier}")
|
112
112
|
else
|
113
113
|
# Fallback to let definition
|
data/lib/test_prof/rubocop.rb
CHANGED
data/lib/test_prof/stack_prof.rb
CHANGED
@@ -162,13 +162,13 @@ module TestProf
|
|
162
162
|
log :info, <<~MSG
|
163
163
|
Run the following command to generate a flame graph report:
|
164
164
|
|
165
|
-
stackprof --flamegraph #{path} > #{html_path} && stackprof --flamegraph-viewer=#{html_path}
|
165
|
+
stackprof --d3-flamegraph #{path} > #{html_path} && stackprof --flamegraph-viewer=#{html_path}
|
166
166
|
MSG
|
167
167
|
end
|
168
168
|
|
169
169
|
def dump_json_report(path)
|
170
170
|
report = ::StackProf::Report.new(
|
171
|
-
Marshal.load(IO.binread(path))
|
171
|
+
Marshal.load(IO.binread(path))
|
172
172
|
)
|
173
173
|
json_path = path.gsub(/\.dump$/, ".json")
|
174
174
|
File.write(json_path, JSON.generate(report.data))
|
data/lib/test_prof/version.rb
CHANGED
data/lib/test_prof.rb
CHANGED
@@ -46,6 +46,13 @@ module TestProf
|
|
46
46
|
defined?(Minitest)
|
47
47
|
end
|
48
48
|
|
49
|
+
# Returns true if Spring is used and not disabled
|
50
|
+
def spring?
|
51
|
+
# See https://github.com/rails/spring/blob/577cf01f232bb6dbd0ade7df2df2ac209697e741/lib/spring/binstub.rb
|
52
|
+
disabled = ENV["DISABLE_SPRING"]
|
53
|
+
defined?(::Spring::Application) && (disabled.nil? || disabled.empty? || disabled == "0")
|
54
|
+
end
|
55
|
+
|
49
56
|
# Returns the current process time
|
50
57
|
def now
|
51
58
|
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
@@ -65,7 +72,7 @@ module TestProf
|
|
65
72
|
# equal to the provided value (if any).
|
66
73
|
# Contains workaround for applications using Spring.
|
67
74
|
def activate(env_var, val = nil)
|
68
|
-
if
|
75
|
+
if spring?
|
69
76
|
notify_spring_detected
|
70
77
|
::Spring.after_fork do
|
71
78
|
activate!(env_var, val) do
|
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: 1.0.
|
4
|
+
version: 1.0.8
|
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: 2022-04-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -237,7 +237,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
237
237
|
- !ruby/object:Gem::Version
|
238
238
|
version: '0'
|
239
239
|
requirements: []
|
240
|
-
rubygems_version: 3.
|
240
|
+
rubygems_version: 3.3.7
|
241
241
|
signing_key:
|
242
242
|
specification_version: 4
|
243
243
|
summary: Ruby applications tests profiling tools
|