test-prof 0.4.5 → 0.4.6
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 +10 -2
- data/guides/.rubocop.yml +1 -0
- data/guides/any_fixture.md +9 -10
- data/guides/before_all.md +7 -7
- data/guides/factory_default.md +9 -9
- data/guides/factory_doctor.md +4 -4
- data/guides/factory_prof.md +1 -1
- data/guides/let_it_be.md +4 -4
- data/guides/rspec_stamp.md +1 -1
- data/guides/rubocop.md +1 -1
- data/guides/ruby_prof.md +2 -2
- data/guides/stack_prof.md +2 -2
- data/guides/tag_prof.md +1 -2
- data/guides/tests_sampling.md +2 -2
- data/lib/test_prof/cops/rspec/aggregate_failures.rb +18 -2
- data/lib/test_prof/recipes/rspec/let_it_be.rb +1 -1
- data/lib/test_prof/rspec_dissect/rspec.rb +1 -0
- data/lib/test_prof/ruby_prof.rb +2 -3
- data/lib/test_prof/utils.rb +9 -3
- data/lib/test_prof/version.rb +1 -1
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 24cff6c482c079404a3305f62252be2030f673fc
|
4
|
+
data.tar.gz: ed0f1cb0674d57d171cb7214ecb0c890750e3841
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 812bd0c997bac0956f02f63056100bddce61ba1ec4b0bcbce6d279b36f28f6d963ed83ce976664b1181840a7a4daf24af5dbdc2646401db212e4ae377fb091a6
|
7
|
+
data.tar.gz: 45bdcee69c2ff43ec1c4117b5e2d1df21046708956df1818cc900c056f914a500df28397487a4989a5695c0f46f1ebb7db66bc3a24690812e7e7cdd67a71be56
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
# Change log
|
2
2
|
|
3
|
+
## master
|
4
|
+
|
5
|
+
- Upgrade RSpec/AggregateFailures to RuboCop 0.52.0. ([@palkan][])
|
6
|
+
|
7
|
+
RuboCop < 0.51.0 is not supported anymore.
|
8
|
+
|
9
|
+
- [Fixes [#49](https://github.com/palkan/test-prof/issues/49)] Correcly detect RSpec version in `let_it_be`. ([@desoleary][])
|
10
|
+
|
3
11
|
## 0.4.5
|
4
12
|
|
5
13
|
- Fix circular require in `lib/factory_doctor/minitest`. ([@palkan][])
|
@@ -10,7 +18,7 @@
|
|
10
18
|
|
11
19
|
## 0.4.3
|
12
20
|
|
13
|
-
- [#46](https://github.com/palkan/test-prof/pull/46) Support FactoryBot, which is [former FactoryGirl](https://github.com/thoughtbot/factory_bot/pull/1051),
|
21
|
+
- [#46](https://github.com/palkan/test-prof/pull/46) Support FactoryBot, which is [former FactoryGirl](https://github.com/thoughtbot/factory_bot/pull/1051),
|
14
22
|
while maintaining compatibility with latter. ([@Shkrt][])
|
15
23
|
|
16
24
|
## 0.4.2
|
@@ -134,4 +142,4 @@ Ensure output dir exists in `#artifact_path` method.
|
|
134
142
|
[@danielwestendorf]: https://github.com/danielwestendorf
|
135
143
|
[@Shkrt]: https://github.com/Shkrt
|
136
144
|
[@IDolgirev]: https://github.com/IDolgirev
|
137
|
-
|
145
|
+
[@desoleary]: https://github.com/desoleary
|
data/guides/.rubocop.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# Leave it blank to use default Rubocop config in guides
|
data/guides/any_fixture.md
CHANGED
@@ -10,7 +10,7 @@ Consider an example:
|
|
10
10
|
|
11
11
|
```ruby
|
12
12
|
# The best way to use AnyFixture is through RSpec shared contexts
|
13
|
-
RSpec.shared_context
|
13
|
+
RSpec.shared_context 'account', account: true do
|
14
14
|
# You should call AnyFixture outside of transaction to re-use the same
|
15
15
|
# data between examples
|
16
16
|
before(:all) do
|
@@ -30,22 +30,21 @@ RSpec.shared_context "account", account: true do
|
|
30
30
|
|
31
31
|
let(:account) { @account }
|
32
32
|
|
33
|
-
# Or hard-reload object if there is chance of in-place modification
|
33
|
+
# Or hard-reload object if there is chance of in-place modification
|
34
34
|
let(:account) { Account.find(@account.id) }
|
35
35
|
end
|
36
36
|
|
37
|
-
|
38
37
|
# Then in your tests
|
39
38
|
|
40
39
|
# Active this fixture using a tag
|
41
40
|
describe UsersController, :account do
|
42
|
-
...
|
41
|
+
# ...
|
43
42
|
end
|
44
43
|
|
45
44
|
# This test also uses the same account record,
|
46
45
|
# no double-creation
|
47
46
|
describe PostsController, :account do
|
48
|
-
...
|
47
|
+
# ...
|
49
48
|
end
|
50
49
|
```
|
51
50
|
|
@@ -54,7 +53,7 @@ end
|
|
54
53
|
In your `spec_helper.rb`:
|
55
54
|
|
56
55
|
```ruby
|
57
|
-
require
|
56
|
+
require 'test_prof/recipes/rspec/any_fixture'
|
58
57
|
```
|
59
58
|
|
60
59
|
Now you can use `TestProf::AnyFixture` in your tests.
|
@@ -79,7 +78,7 @@ end
|
|
79
78
|
And the shared contexts:
|
80
79
|
|
81
80
|
```ruby
|
82
|
-
RSpec.shared_context
|
81
|
+
RSpec.shared_context 'author' do
|
83
82
|
before(:all) do
|
84
83
|
@author = TestProf::AnyFixture.register(:author) do
|
85
84
|
FactoryGirl.create(:account)
|
@@ -89,7 +88,7 @@ RSpec.shared_context "author" do
|
|
89
88
|
let(:author) { @author }
|
90
89
|
end
|
91
90
|
|
92
|
-
RSpec.shared_context
|
91
|
+
RSpec.shared_context 'article' do
|
93
92
|
before(:all) do
|
94
93
|
# outside of AnyFixture, we don't know about its dependent tables
|
95
94
|
author = FactoryGirl.create(:author)
|
@@ -107,9 +106,9 @@ Then in some example:
|
|
107
106
|
|
108
107
|
```ruby
|
109
108
|
# This one adds only the 'articles' table to the list of affected tables
|
110
|
-
include_context
|
109
|
+
include_context 'article'
|
111
110
|
# And this one adds the 'authors' table
|
112
|
-
include_context
|
111
|
+
include_context 'author'
|
113
112
|
```
|
114
113
|
|
115
114
|
Now we have the following affected tables list: `['articles', 'authors']`. At the end of the suite, the 'authors' table is cleaned first which leads to a foreign-key violation error.
|
data/guides/before_all.md
CHANGED
@@ -27,10 +27,10 @@ Or you can try `before(:all)`:
|
|
27
27
|
describe BeatleWeightedSearchQuery do
|
28
28
|
before(:all) do
|
29
29
|
@paul = create(:beatle, name: 'Paul')
|
30
|
-
...
|
30
|
+
# ...
|
31
31
|
end
|
32
32
|
|
33
|
-
...
|
33
|
+
# ...
|
34
34
|
end
|
35
35
|
```
|
36
36
|
|
@@ -43,10 +43,10 @@ And that's how `before_all` works:
|
|
43
43
|
describe BeatleWeightedSearchQuery do
|
44
44
|
before_all do
|
45
45
|
@paul = create(:beatle, name: 'Paul')
|
46
|
-
...
|
46
|
+
# ...
|
47
47
|
end
|
48
48
|
|
49
|
-
...
|
49
|
+
# ...
|
50
50
|
end
|
51
51
|
```
|
52
52
|
|
@@ -57,7 +57,7 @@ That's all!
|
|
57
57
|
In your `spec_helper.rb`:
|
58
58
|
|
59
59
|
```ruby
|
60
|
-
require
|
60
|
+
require 'test_prof/recipes/rspec/before_all'
|
61
61
|
```
|
62
62
|
|
63
63
|
## Caveats
|
@@ -72,13 +72,13 @@ end
|
|
72
72
|
|
73
73
|
let(:user) { @user }
|
74
74
|
|
75
|
-
it
|
75
|
+
it 'when user is admin' do
|
76
76
|
# we modified our object in-place!
|
77
77
|
user.update!(role: 1)
|
78
78
|
expect(user).to be_admin
|
79
79
|
end
|
80
80
|
|
81
|
-
it
|
81
|
+
it 'when user is regular' do
|
82
82
|
# now @user's state depends on the order of specs!
|
83
83
|
expect(user).not_to be_admin
|
84
84
|
end
|
data/guides/factory_default.md
CHANGED
@@ -31,15 +31,15 @@ end
|
|
31
31
|
And we want to test the `Task` model:
|
32
32
|
|
33
33
|
```ruby
|
34
|
-
describe
|
34
|
+
describe 'PATCH #update' do
|
35
35
|
let(:task) { create(:task) }
|
36
36
|
|
37
|
-
it
|
37
|
+
it 'works' do
|
38
38
|
patch :update, id: task.id, task: { completed: 't' }
|
39
39
|
expect(response).to be_success
|
40
40
|
end
|
41
41
|
|
42
|
-
...
|
42
|
+
# ...
|
43
43
|
end
|
44
44
|
```
|
45
45
|
|
@@ -50,12 +50,12 @@ And it breaks our logic (every object should belong to the same account).
|
|
50
50
|
Typical workaround:
|
51
51
|
|
52
52
|
```ruby
|
53
|
-
describe
|
53
|
+
describe 'PATCH #update' do
|
54
54
|
let(:account) { create(:account) }
|
55
55
|
let(:project) { create(:project, account: account) }
|
56
56
|
let(:task) { create(:task, project: project, account: account) }
|
57
57
|
|
58
|
-
it
|
58
|
+
it 'works' do
|
59
59
|
patch :update, id: task.id, task: { completed: 't' }
|
60
60
|
expect(response).to be_success
|
61
61
|
end
|
@@ -67,7 +67,7 @@ That works. And there are some cons: it's a little bit verbose and error-prone (
|
|
67
67
|
Here is how we can deal with it using FactoryDefault:
|
68
68
|
|
69
69
|
```ruby
|
70
|
-
describe
|
70
|
+
describe 'PATCH #update' do
|
71
71
|
let(:account) { create_default(:account) }
|
72
72
|
let(:project) { create_default(:project) }
|
73
73
|
let(:task) { create(:task) }
|
@@ -75,9 +75,9 @@ describe "PATCH #update" do
|
|
75
75
|
# and if we need more projects, users, tasks with the same parent record,
|
76
76
|
# we just write
|
77
77
|
let(:another_project) { create(:project) } # uses the same account
|
78
|
-
let(:another_task) { create(:task) } # uses the same account
|
78
|
+
let(:another_task) { create(:task) } # uses the same account
|
79
79
|
|
80
|
-
it
|
80
|
+
it 'works' do
|
81
81
|
patch :update, id: task.id, task: { completed: 't' }
|
82
82
|
expect(response).to be_success
|
83
83
|
end
|
@@ -91,7 +91,7 @@ end
|
|
91
91
|
In your `spec_helper.rb`:
|
92
92
|
|
93
93
|
```ruby
|
94
|
-
require
|
94
|
+
require 'test_prof/recipes/rspec/factory_default'
|
95
95
|
```
|
96
96
|
|
97
97
|
This adds two new methods to FactoryBot:
|
data/guides/factory_doctor.md
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
One common bad pattern that slows our tests down is unnecessary database manipulation. Consider a _bad_ example:
|
4
4
|
|
5
5
|
```ruby
|
6
|
-
it
|
6
|
+
it 'validates name presence' do
|
7
7
|
user = create(:user)
|
8
8
|
user.name = ''
|
9
9
|
expect(user).not_to be_valid
|
@@ -13,7 +13,7 @@ end
|
|
13
13
|
Here we create a new user record, run all callbacks and validations and save it to the database. We don't need all these! Here is a _good_ example:
|
14
14
|
|
15
15
|
```ruby
|
16
|
-
it
|
16
|
+
it 'validates name presence' do
|
17
17
|
user = build_stubbed(:user)
|
18
18
|
user.name = ''
|
19
19
|
expect(user).not_to be_valid
|
@@ -46,7 +46,7 @@ You can also tell FactoryDoctor to ignore specific examples/groups. Just add the
|
|
46
46
|
|
47
47
|
```ruby
|
48
48
|
# won't be reported as offense
|
49
|
-
it
|
49
|
+
it 'is ignored', :fd_ignore do
|
50
50
|
user = create(:user)
|
51
51
|
user.name = ''
|
52
52
|
expect(user).not_to be_valid
|
@@ -94,7 +94,7 @@ Just use `fd_ignore` inside your example:
|
|
94
94
|
|
95
95
|
```ruby
|
96
96
|
# won't be reported as offense
|
97
|
-
it
|
97
|
+
it 'is ignored' do
|
98
98
|
fd_ignore
|
99
99
|
|
100
100
|
@user.name = ''
|
data/guides/factory_prof.md
CHANGED
@@ -72,7 +72,7 @@ end
|
|
72
72
|
create(:comment) #=> creates 5 records
|
73
73
|
|
74
74
|
# And the corresponding stack is:
|
75
|
-
[:comment, :answer, :question, :author, :author, :author]
|
75
|
+
# [:comment, :answer, :question, :author, :author, :author]
|
76
76
|
```
|
77
77
|
|
78
78
|
The wider column the more often this stack appears.
|
data/guides/let_it_be.md
CHANGED
@@ -25,12 +25,12 @@ We already have [`before_all`](https://github.com/palkan/test-prof/tree/master/g
|
|
25
25
|
describe BeatleWeightedSearchQuery do
|
26
26
|
before_all do
|
27
27
|
@paul = create(:beatle, name: 'Paul')
|
28
|
-
...
|
28
|
+
# ...
|
29
29
|
end
|
30
30
|
|
31
31
|
specify { expect(subject.call('joh')).to contain_exactly(@john) }
|
32
32
|
|
33
|
-
...
|
33
|
+
# ...
|
34
34
|
end
|
35
35
|
```
|
36
36
|
|
@@ -60,7 +60,7 @@ That's it! Just replace `let!` with `let_it_be`. That's equal to the `before_all
|
|
60
60
|
In your `spec_helper.rb`:
|
61
61
|
|
62
62
|
```ruby
|
63
|
-
require
|
63
|
+
require 'test_prof/recipes/rspec/let_it_be'
|
64
64
|
```
|
65
65
|
|
66
66
|
In your tests:
|
@@ -69,7 +69,7 @@ In your tests:
|
|
69
69
|
describe MySuperDryService do
|
70
70
|
let_it_be(:user) { create(:user) }
|
71
71
|
|
72
|
-
...
|
72
|
+
# ...
|
73
73
|
end
|
74
74
|
```
|
75
75
|
|
data/guides/rspec_stamp.md
CHANGED
@@ -17,7 +17,7 @@ Step 0. Make sure that all your tests pass.
|
|
17
17
|
Step 1. Create a shared context to conditionally turn on `inline!` mode:
|
18
18
|
|
19
19
|
```ruby
|
20
|
-
shared_context
|
20
|
+
shared_context 'sidekiq:inline', sidekiq: :inline do
|
21
21
|
around(:each) { |ex| Sidekiq::Testing.inline!(&ex) }
|
22
22
|
end
|
23
23
|
```
|
data/guides/rubocop.md
CHANGED
@@ -36,7 +36,7 @@ it { is_expected.to have_header('X-TOTAL-PAGES', 10) }
|
|
36
36
|
it { is_expected.to have_header('X-NEXT-PAGE', 2) }
|
37
37
|
|
38
38
|
# good
|
39
|
-
it
|
39
|
+
it 'returns the second page', :aggregate_failures do
|
40
40
|
is_expected.to be_success
|
41
41
|
is_expected.to have_header('X-TOTAL-PAGES', 10)
|
42
42
|
is_expected.to have_header('X-NEXT-PAGE', 2)
|
data/guides/ruby_prof.md
CHANGED
data/guides/stack_prof.md
CHANGED
data/guides/tag_prof.md
CHANGED
data/guides/tests_sampling.md
CHANGED
@@ -9,10 +9,10 @@ Require the corresponding patch:
|
|
9
9
|
|
10
10
|
```ruby
|
11
11
|
# For RSpec in your spec_helper.rb
|
12
|
-
require
|
12
|
+
require 'test_prof/recipes/rspec/sample'
|
13
13
|
|
14
14
|
# For Minitest in your test_helper.rb
|
15
|
-
require
|
15
|
+
require 'test_prof/recipes/minitest/sample'
|
16
16
|
```
|
17
17
|
|
18
18
|
And then just add `SAMPLE` env variable with the number of example groups (or suites) you want to run:
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'rubocop'
|
4
|
+
require 'test_prof/utils'
|
4
5
|
|
5
6
|
module RuboCop
|
6
7
|
module Cop
|
@@ -37,7 +38,22 @@ module RuboCop
|
|
37
38
|
pending
|
38
39
|
].freeze
|
39
40
|
|
41
|
+
class << self
|
42
|
+
def supported?
|
43
|
+
return @supported if instance_variable_defined?(:@supported)
|
44
|
+
@supported = TestProf::Utils.verify_gem_version('rubocop', at_least: '0.51.0')
|
45
|
+
|
46
|
+
unless @supported
|
47
|
+
warn "RSpec/AggregateFailures cop requires RuboCop >= 0.51.0. Skipping"
|
48
|
+
end
|
49
|
+
|
50
|
+
@supported
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
40
54
|
def on_block(node)
|
55
|
+
return unless self.class.supported?
|
56
|
+
|
41
57
|
method, _args, body = *node
|
42
58
|
return unless body && body.begin_type?
|
43
59
|
|
@@ -48,8 +64,8 @@ module RuboCop
|
|
48
64
|
|
49
65
|
add_offense(
|
50
66
|
node,
|
51
|
-
:expression,
|
52
|
-
'Use :aggregate_failures instead of several one-liners.'
|
67
|
+
location: :expression,
|
68
|
+
message: 'Use :aggregate_failures instead of several one-liners.'
|
53
69
|
)
|
54
70
|
end
|
55
71
|
|
data/lib/test_prof/ruby_prof.rb
CHANGED
@@ -103,9 +103,8 @@ module TestProf
|
|
103
103
|
def dump(name)
|
104
104
|
result = @profiler.stop
|
105
105
|
|
106
|
-
|
107
|
-
|
108
|
-
end
|
106
|
+
result.eliminate_methods!(config.eliminate_methods) if
|
107
|
+
config.eliminate_methods?
|
109
108
|
|
110
109
|
printer_type, printer_class = config.resolve_printer
|
111
110
|
path = build_path name, printer_type
|
data/lib/test_prof/utils.rb
CHANGED
@@ -8,10 +8,16 @@ module TestProf
|
|
8
8
|
raise ArgumentError, "Please, provide `at_least` or `at_most` argument" if
|
9
9
|
at_least.nil? && at_most.nil?
|
10
10
|
|
11
|
-
|
11
|
+
spec = Gem.loaded_specs[gem_name]
|
12
|
+
version = spec.version if spec
|
13
|
+
return false if version.nil?
|
12
14
|
|
13
|
-
(
|
14
|
-
|
15
|
+
supported_version?(version, at_least, at_most)
|
16
|
+
end
|
17
|
+
|
18
|
+
def supported_version?(gem_version, at_least, at_most)
|
19
|
+
(at_least.nil? || Gem::Version.new(at_least) <= gem_version) &&
|
20
|
+
(at_most.nil? || Gem::Version.new(at_most) >= gem_version)
|
15
21
|
end
|
16
22
|
end
|
17
23
|
end
|
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.
|
4
|
+
version: 0.4.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vladimir Dementyev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-12-
|
11
|
+
date: 2017-12-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0.50'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop-md
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.1.1
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.1.1
|
83
97
|
description: "\n Ruby applications tests profiling tools.\n\n Contains tools
|
84
98
|
to analyze factories usage, integrate with Ruby profilers,\n profile your examples
|
85
99
|
using ActiveSupport notifications (if any) and\n statically analyze your code
|
@@ -104,6 +118,7 @@ files:
|
|
104
118
|
- assets/src/d3.flameGraph.min.js
|
105
119
|
- assets/src/d3.v4.min.js
|
106
120
|
- assets/testprof.png
|
121
|
+
- guides/.rubocop.yml
|
107
122
|
- guides/any_fixture.md
|
108
123
|
- guides/before_all.md
|
109
124
|
- guides/event_prof.md
|