test-prof 0.11.0 → 0.12.0
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 +54 -1
- data/LICENSE.txt +1 -1
- data/README.md +2 -6
- data/config/default.yml +35 -0
- data/lib/minitest/test_prof_plugin.rb +3 -0
- data/lib/test_prof/before_all.rb +0 -4
- data/lib/test_prof/cops/inject.rb +16 -14
- data/lib/test_prof/cops/rspec/aggregate_examples.rb +1 -1
- data/lib/test_prof/cops/rspec/aggregate_failures.rb +2 -4
- data/lib/test_prof/event_prof/instrumentations/active_support.rb +22 -4
- data/lib/test_prof/recipes/minitest/sample.rb +6 -10
- data/lib/test_prof/recipes/rspec/before_all.rb +1 -9
- data/lib/test_prof/recipes/rspec/let_it_be.rb +108 -11
- data/lib/test_prof/recipes/rspec/sample.rb +4 -2
- data/lib/test_prof/stack_prof.rb +3 -0
- data/lib/test_prof/version.rb +1 -1
- metadata +12 -11
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 64b1be0cdb0b04518ed2fb900756fd07d212f79709d76e784798384fb92a2a5f
|
|
4
|
+
data.tar.gz: fa59a7d025eda4e53ce0381cc9c973cbcad50e0c4584b1ca30aa5cfb1e9d0ebc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d08d874b6948df045adbdba66960abbb47e2fe8fd55700b8f9f4ab6a411f94ffd632d15937c30df36728709440be7209f21951a47b66f54c1ea39669aed35b72
|
|
7
|
+
data.tar.gz: 955199e5fce56fea5237bc07151526e83156ebd7f3f74f00a05eac5b7da20ad9b7ffe21807c8c7644327bc13020315d8262436e65f323057fd75be4378a89342
|
data/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,55 @@
|
|
|
1
1
|
# Change log
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## 0.12.0 (2020-07-17)
|
|
4
|
+
|
|
5
|
+
- Add state leakage detection for `let_it_be`. ([@pirj][], [@jaimerson][], [@alexvko][])
|
|
6
|
+
|
|
7
|
+
- Add default let_it_be modifiers configuration. ([@palkan][])
|
|
8
|
+
|
|
9
|
+
You can configure global modifiers:
|
|
10
|
+
|
|
11
|
+
```ruby
|
|
12
|
+
TestProf::LetItBe.configure do |config|
|
|
13
|
+
# Make refind activated by default
|
|
14
|
+
config.default_modifiers[:refind] = true
|
|
15
|
+
end
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Or for specific contexts via tags:
|
|
19
|
+
|
|
20
|
+
```ruby
|
|
21
|
+
context "with let_it_be reload", let_it_be_modifiers: {reload: true} do
|
|
22
|
+
# examples
|
|
23
|
+
end
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
- **Drop Ruby 2.4 support.** ([@palkan][])
|
|
27
|
+
|
|
28
|
+
- SAMPLE and SAMPLE_GROUP work consistently with seed in RSpec and Minitest. ([@stefkin][])
|
|
29
|
+
|
|
30
|
+
- Make sure EventProf is not affected by time freezing. ([@palkan][])
|
|
31
|
+
|
|
32
|
+
EventProf results now is not affected by `Timecop.freeze` or similar.
|
|
33
|
+
|
|
34
|
+
See more in [#181](https://github.com/palkan/test-prof/issues/181).
|
|
35
|
+
|
|
36
|
+
- Adds the ability to define stackprof's interval sampling by using `TEST_STACK_PROF_INTERVAL` env variable ([@LynxEyes][])
|
|
37
|
+
|
|
38
|
+
Now you can use `$ TEST_STACK_PROF=1 TEST_STACK_PROF_INTERVAL=10000 rspec` to define a custom interval (in microseconds).
|
|
39
|
+
|
|
40
|
+
## 0.11.3 (2020-02-11)
|
|
41
|
+
|
|
42
|
+
- Disable `RSpec/AggregateFailures` by default. ([@pirj][])
|
|
43
|
+
|
|
44
|
+
## 0.11.2 (2020-02-11)
|
|
45
|
+
|
|
46
|
+
- Fix RuboCop integration regressions. ([@palkan][])
|
|
47
|
+
|
|
48
|
+
## 0.11.1 (2020-02-10)
|
|
49
|
+
|
|
50
|
+
- Add `config/` to the gem contents. ([@palkan][])
|
|
51
|
+
|
|
52
|
+
Fixes RuboCop integration regression from 0.11.0.
|
|
4
53
|
|
|
5
54
|
## 0.11.0 (2020-02-09)
|
|
6
55
|
|
|
@@ -522,3 +571,7 @@ Fixes [#10](https://github.com/palkan/test-prof/issues/10).
|
|
|
522
571
|
[@tyleriguchi]: https://github.com/tyleriguchi
|
|
523
572
|
[@lostie]: https://github.com/lostie
|
|
524
573
|
[@pirj]: https://github.com/pirj
|
|
574
|
+
[@LynxEyes]: https://github.com/LynxEyes
|
|
575
|
+
[@stefkin]: https://github.com/stefkin
|
|
576
|
+
[@jaimerson]: https://github.com/jaimerson
|
|
577
|
+
[@alexvko]: https://github.com/alexvko
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
[](
|
|
1
|
+
[](https://cultofmartians.com)
|
|
2
2
|
[](https://rubygems.org/gems/test-prof) [](https://github.com/palkan/test-prof/actions)
|
|
3
3
|
[](https://github.com/palkan/test-prof/actions)
|
|
4
4
|
[](https://www.codetriage.com/palkan/test-prof)
|
|
@@ -47,7 +47,7 @@ TestProf toolbox aims to help you identify bottlenecks in your test suite. It co
|
|
|
47
47
|
## Who uses TestProf
|
|
48
48
|
|
|
49
49
|
- [Discourse](https://github.com/discourse/discourse) reduced [~27% of their test suite time](https://twitter.com/samsaffron/status/1125602558024699904)
|
|
50
|
-
- [Gitlab](https://gitlab.com/gitlab-org/gitlab-ce) reduced [39% of their API tests time](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/14370)
|
|
50
|
+
- [Gitlab](https://gitlab.com/gitlab-org/gitlab-ce) reduced [39% of their API tests time](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/14370) and [improved factories usage](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/26810)
|
|
51
51
|
- [CodeTriage](https://github.com/codetriage/codetriage)
|
|
52
52
|
- [Dev.to](https://github.com/thepracticaldev/dev.to)
|
|
53
53
|
- [Open Project](https://github.com/opf/openproject)
|
|
@@ -104,7 +104,3 @@ Already using TestProf? [Share your story!](https://github.com/palkan/test-prof/
|
|
|
104
104
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
|
105
105
|
|
|
106
106
|
[docs]: https://test-prof.evilmartians.io
|
|
107
|
-
|
|
108
|
-
## Security Contact
|
|
109
|
-
|
|
110
|
-
To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure.
|
data/config/default.yml
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
AllCops:
|
|
3
|
+
RSpec:
|
|
4
|
+
Patterns:
|
|
5
|
+
- _spec.rb
|
|
6
|
+
- "(?:^|/)spec/"
|
|
7
|
+
|
|
8
|
+
RSpec/AggregateExamples:
|
|
9
|
+
Description: Checks if example group contains two or more aggregatable examples.
|
|
10
|
+
Enabled: true
|
|
11
|
+
StyleGuide: https://rspec.rubystyle.guide/#expectation-per-example
|
|
12
|
+
AddAggregateFailuresMetadata: true
|
|
13
|
+
MatchersWithSideEffects:
|
|
14
|
+
- allow_value
|
|
15
|
+
- allow_values
|
|
16
|
+
- validate_presence_of
|
|
17
|
+
- validate_absence_of
|
|
18
|
+
- validate_length_of
|
|
19
|
+
- validate_inclusion_of
|
|
20
|
+
- validates_exclusion_of
|
|
21
|
+
|
|
22
|
+
# TODO: remove this one we hit 1.0
|
|
23
|
+
RSpec/AggregateFailures:
|
|
24
|
+
Description: Checks if example group contains two or more aggregatable examples.
|
|
25
|
+
Enabled: false
|
|
26
|
+
StyleGuide: https://rspec.rubystyle.guide/#expectation-per-example
|
|
27
|
+
AddAggregateFailuresMetadata: true
|
|
28
|
+
MatchersWithSideEffects:
|
|
29
|
+
- allow_value
|
|
30
|
+
- allow_values
|
|
31
|
+
- validate_presence_of
|
|
32
|
+
- validate_absence_of
|
|
33
|
+
- validate_length_of
|
|
34
|
+
- validate_inclusion_of
|
|
35
|
+
- validates_exclusion_of
|
|
@@ -12,6 +12,7 @@ module Minitest # :nodoc:
|
|
|
12
12
|
opts[:top_count] = ENV["EVENT_PROF_TOP"].to_i if ENV["EVENT_PROF_TOP"]
|
|
13
13
|
opts[:per_example] = true if ENV["EVENT_PROF_EXAMPLES"]
|
|
14
14
|
opts[:fdoc] = true if ENV["FDOC"]
|
|
15
|
+
opts[:sample] = true if ENV["SAMPLE"] || ENV["SAMPLE_GROUPS"]
|
|
15
16
|
end
|
|
16
17
|
end
|
|
17
18
|
end
|
|
@@ -39,5 +40,7 @@ module Minitest # :nodoc:
|
|
|
39
40
|
|
|
40
41
|
reporter << TestProf::EventProfReporter.new(options[:io], options) if options[:event]
|
|
41
42
|
reporter << TestProf::FactoryDoctorReporter.new(options[:io], options) if options[:fdoc]
|
|
43
|
+
|
|
44
|
+
::TestProf::MinitestSample.call if options[:sample]
|
|
42
45
|
end
|
|
43
46
|
end
|
data/lib/test_prof/before_all.rb
CHANGED
|
@@ -2,22 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
# This is shamelessly borrowed from RuboCop RSpec
|
|
4
4
|
# https://github.com/rubocop-hq/rubocop-rspec/blob/master/lib/rubocop/rspec/inject.rb
|
|
5
|
-
module
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
module TestProf
|
|
6
|
+
module Cops
|
|
7
|
+
# Because RuboCop doesn't yet support plugins, we have to monkey patch in a
|
|
8
|
+
# bit of our configuration.
|
|
9
|
+
module Inject
|
|
10
|
+
PROJECT_ROOT = Pathname.new(__dir__).parent.parent.parent.expand_path.freeze
|
|
11
|
+
CONFIG_DEFAULT = PROJECT_ROOT.join("config", "default.yml").freeze
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
def self.defaults!
|
|
14
|
+
path = CONFIG_DEFAULT.to_s
|
|
15
|
+
hash = RuboCop::ConfigLoader.send(:load_yaml_configuration, path)
|
|
16
|
+
config = RuboCop::Config.new(hash, path)
|
|
17
|
+
puts "configuration from #{path}" if RuboCop::ConfigLoader.debug?
|
|
18
|
+
config = RuboCop::ConfigLoader.merge_with_default(config, path)
|
|
19
|
+
RuboCop::ConfigLoader.instance_variable_set(:@default_configuration, config)
|
|
20
|
+
end
|
|
19
21
|
end
|
|
20
22
|
end
|
|
21
23
|
end
|
|
22
24
|
|
|
23
|
-
|
|
25
|
+
TestProf::Cops::Inject.defaults!
|
|
@@ -12,7 +12,7 @@ module RuboCop
|
|
|
12
12
|
module RSpec
|
|
13
13
|
# Checks if example groups contain two or more aggregatable examples.
|
|
14
14
|
#
|
|
15
|
-
# @see https://github.com/rubocop-hq/rspec-style-guide#
|
|
15
|
+
# @see https://github.com/rubocop-hq/rspec-style-guide#expectation-per-example
|
|
16
16
|
#
|
|
17
17
|
# This cop is primarily for reducing the cost of repeated expensive
|
|
18
18
|
# context initialization.
|
|
@@ -4,14 +4,12 @@ module RuboCop
|
|
|
4
4
|
module Cop
|
|
5
5
|
module RSpec
|
|
6
6
|
class AggregateExamples
|
|
7
|
-
def self.
|
|
8
|
-
|
|
7
|
+
def self.registry
|
|
8
|
+
RuboCop::Cop::Cop.registry
|
|
9
9
|
end
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
class AggregateFailures < AggregateExamples
|
|
13
|
-
raise "Remove me" if TestProf::VERSION >= "1.0"
|
|
14
|
-
|
|
15
13
|
def initialize(*)
|
|
16
14
|
super
|
|
17
15
|
self.class.just_once { warn "`AggregateFailures` cop has been renamed to `AggregateExamples`." }
|
|
@@ -4,13 +4,31 @@ module TestProf::EventProf
|
|
|
4
4
|
module Instrumentations
|
|
5
5
|
# Wrapper over ActiveSupport::Notifications
|
|
6
6
|
module ActiveSupport
|
|
7
|
+
class Subscriber
|
|
8
|
+
attr_reader :block, :started_at
|
|
9
|
+
|
|
10
|
+
def initialize(block)
|
|
11
|
+
@block = block
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def start(*)
|
|
15
|
+
@started_at = TestProf.now
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def publish(_name, started_at, finished_at, *)
|
|
19
|
+
block.call(finished_at - started_at)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def finish(*)
|
|
23
|
+
block.call(TestProf.now - started_at)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
7
27
|
class << self
|
|
8
|
-
def subscribe(event)
|
|
28
|
+
def subscribe(event, &block)
|
|
9
29
|
raise ArgumentError, "Block is required!" unless block_given?
|
|
10
30
|
|
|
11
|
-
::ActiveSupport::Notifications.subscribe(event
|
|
12
|
-
yield (finish - start)
|
|
13
|
-
end
|
|
31
|
+
::ActiveSupport::Notifications.subscribe(event, Subscriber.new(block))
|
|
14
32
|
end
|
|
15
33
|
|
|
16
34
|
def instrument(event)
|
|
@@ -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)
|
|
@@ -9,7 +9,7 @@ module TestProf
|
|
|
9
9
|
def before_all(&block)
|
|
10
10
|
raise ArgumentError, "Block is required!" unless block_given?
|
|
11
11
|
|
|
12
|
-
return
|
|
12
|
+
return before(:all, &block) if within_before_all?
|
|
13
13
|
|
|
14
14
|
@__before_all_activated__ = true
|
|
15
15
|
|
|
@@ -24,14 +24,6 @@ module TestProf
|
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
26
|
|
|
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
27
|
def within_before_all?
|
|
36
28
|
instance_variable_defined?(:@__before_all_activated__)
|
|
37
29
|
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,20 +89,20 @@ 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
|
|
|
@@ -114,16 +120,78 @@ module TestProf
|
|
|
114
120
|
|
|
115
121
|
let(identifier, &let_accessor)
|
|
116
122
|
end
|
|
123
|
+
|
|
124
|
+
module Freezer
|
|
125
|
+
# Stoplist to prevent freezing objects and theirs associations that are defined
|
|
126
|
+
# with `let_it_be`'s `freeze: false` options during deep freezing.
|
|
127
|
+
#
|
|
128
|
+
# To only keep track of objects that are available in current example group,
|
|
129
|
+
# `begin` adds a new layer, and `rollback` removes a layer of unrelated objects
|
|
130
|
+
# along with rolling back the transaction where they were created.
|
|
131
|
+
#
|
|
132
|
+
# Stoplist holds records declared with `freeze: false` (so we do not freeze them even if they're used as
|
|
133
|
+
# associated records for frozen objects)
|
|
134
|
+
module Stoplist
|
|
135
|
+
class << self
|
|
136
|
+
def stop?(record)
|
|
137
|
+
@stoplist.any? { |layer| layer.include?(record) }
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def stop!(record)
|
|
141
|
+
@stoplist.last.push(record)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def begin
|
|
145
|
+
@stoplist.push([])
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def rollback
|
|
149
|
+
@stoplist.pop
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# Stack of example group-related variable definitions
|
|
154
|
+
@stoplist = []
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
class << self
|
|
158
|
+
# Rerucsively freezes the object to detect modifications
|
|
159
|
+
def deep_freeze(record)
|
|
160
|
+
return if record.frozen?
|
|
161
|
+
return if Stoplist.stop?(record)
|
|
162
|
+
|
|
163
|
+
record.freeze
|
|
164
|
+
|
|
165
|
+
# Support `let_it_be` with `create_list`
|
|
166
|
+
return record.each { |rec| deep_freeze(rec) } if record.respond_to?(:each)
|
|
167
|
+
|
|
168
|
+
# Freeze associations as well.
|
|
169
|
+
return unless defined?(::ActiveRecord::Base)
|
|
170
|
+
return unless record.is_a?(::ActiveRecord::Base)
|
|
171
|
+
|
|
172
|
+
record.class.reflections.keys.each do |reflection|
|
|
173
|
+
# But only if they are already loaded. If not yet loaded, they weren't
|
|
174
|
+
# created by factories, and it's ok to mutate them.
|
|
175
|
+
|
|
176
|
+
next unless record.association(reflection.to_sym).loaded?
|
|
177
|
+
|
|
178
|
+
target = record.association(reflection.to_sym).target
|
|
179
|
+
deep_freeze(target) if target.is_a?(::ActiveRecord::Base) || target.respond_to?(:each)
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
end
|
|
117
184
|
end
|
|
118
185
|
end
|
|
119
186
|
|
|
120
|
-
if defined?(::ActiveRecord)
|
|
187
|
+
if defined?(::ActiveRecord::Base)
|
|
121
188
|
require "test_prof/ext/active_record_refind"
|
|
122
189
|
using TestProf::Ext::ActiveRecordRefind
|
|
123
190
|
|
|
124
191
|
TestProf::LetItBe.configure do |config|
|
|
125
192
|
config.register_modifier :reload do |record, val|
|
|
126
193
|
next record unless val
|
|
194
|
+
|
|
127
195
|
next record.reload if record.is_a?(::ActiveRecord::Base)
|
|
128
196
|
|
|
129
197
|
if record.respond_to?(:map)
|
|
@@ -136,6 +204,7 @@ if defined?(::ActiveRecord)
|
|
|
136
204
|
|
|
137
205
|
config.register_modifier :refind do |record, val|
|
|
138
206
|
next record unless val
|
|
207
|
+
|
|
139
208
|
next record.refind if record.is_a?(::ActiveRecord::Base)
|
|
140
209
|
|
|
141
210
|
if record.respond_to?(:map)
|
|
@@ -145,7 +214,35 @@ if defined?(::ActiveRecord)
|
|
|
145
214
|
end
|
|
146
215
|
record
|
|
147
216
|
end
|
|
217
|
+
|
|
218
|
+
config.register_modifier :freeze do |record, val|
|
|
219
|
+
if val == false
|
|
220
|
+
TestProf::LetItBe::Freezer::Stoplist.stop!(record)
|
|
221
|
+
next record
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
TestProf::LetItBe::Freezer.deep_freeze(record)
|
|
225
|
+
record
|
|
226
|
+
end
|
|
148
227
|
end
|
|
149
228
|
end
|
|
150
229
|
|
|
151
230
|
RSpec::Core::ExampleGroup.extend TestProf::LetItBe
|
|
231
|
+
|
|
232
|
+
TestProf::BeforeAll.configure do |config|
|
|
233
|
+
config.before(:begin) do
|
|
234
|
+
TestProf::LetItBe::Freezer::Stoplist.begin
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
config.after(:rollback) do
|
|
238
|
+
TestProf::LetItBe::Freezer::Stoplist.rollback
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
RSpec.configure do |config|
|
|
243
|
+
config.after(:example) do |example|
|
|
244
|
+
if example.exception&.is_a?(FrozenError)
|
|
245
|
+
example.exception.message << TestProf::LetItBe::FROZEN_ERROR_HINT
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
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/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: 0.12.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Vladimir Dementyev
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2020-
|
|
11
|
+
date: 2020-07-17 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
|
|
@@ -118,6 +118,7 @@ files:
|
|
|
118
118
|
- assets/src/d3.v4.min.js
|
|
119
119
|
- assets/tagprof.demo.html
|
|
120
120
|
- assets/tagprof.template.html
|
|
121
|
+
- config/default.yml
|
|
121
122
|
- lib/minitest/base_reporter.rb
|
|
122
123
|
- lib/minitest/event_prof_formatter.rb
|
|
123
124
|
- lib/minitest/test_prof_plugin.rb
|
|
@@ -224,7 +225,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
224
225
|
requirements:
|
|
225
226
|
- - ">="
|
|
226
227
|
- !ruby/object:Gem::Version
|
|
227
|
-
version: 2.
|
|
228
|
+
version: 2.5.0
|
|
228
229
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
229
230
|
requirements:
|
|
230
231
|
- - ">="
|