test-prof 0.4.5 → 0.4.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|