test-prof 0.4.9 → 0.5.0.pre1
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 +63 -20
- data/README.md +10 -57
- data/assets/tagprof.demo.html +447 -0
- data/assets/tagprof.template.html +447 -0
- data/lib/minitest/event_prof_formatter.rb +18 -16
- data/lib/test_prof.rb +2 -1
- data/lib/test_prof/any_fixture.rb +80 -4
- data/lib/test_prof/any_fixture/dsl.rb +18 -0
- data/lib/test_prof/event_prof.rb +10 -108
- data/lib/test_prof/event_prof/custom_events.rb +30 -0
- data/lib/test_prof/event_prof/custom_events/factory_create.rb +1 -1
- data/lib/test_prof/event_prof/custom_events/sidekiq_inline.rb +1 -1
- data/lib/test_prof/event_prof/custom_events/sidekiq_jobs.rb +1 -1
- data/lib/test_prof/event_prof/minitest.rb +6 -0
- data/lib/test_prof/event_prof/profiler.rb +129 -0
- data/lib/test_prof/event_prof/rspec.rb +20 -11
- data/lib/test_prof/factory_all_stub.rb +32 -0
- data/lib/test_prof/factory_all_stub/factory_bot_patch.rb +13 -0
- data/lib/test_prof/factory_doctor/rspec.rb +3 -2
- data/lib/test_prof/factory_prof/printers/flamegraph.rb +9 -13
- data/lib/test_prof/recipes/active_record_shared_connection.rb +55 -0
- data/lib/test_prof/recipes/logging.rb +37 -0
- data/lib/test_prof/recipes/rspec/any_fixture.rb +4 -1
- data/lib/test_prof/recipes/rspec/factory_all_stub.rb +10 -0
- data/lib/test_prof/rspec_dissect/rspec.rb +4 -2
- data/lib/test_prof/rspec_stamp/rspec.rb +3 -2
- data/lib/test_prof/tag_prof.rb +4 -0
- data/lib/test_prof/tag_prof/printers/html.rb +24 -0
- data/lib/test_prof/tag_prof/printers/simple.rb +82 -0
- data/lib/test_prof/tag_prof/result.rb +38 -0
- data/lib/test_prof/tag_prof/rspec.rb +43 -40
- data/lib/test_prof/utils/html_builder.rb +21 -0
- data/lib/test_prof/version.rb +1 -1
- metadata +20 -24
- data/assets/logo.svg +0 -1
- data/assets/testprof.png +0 -0
- data/guides/.rubocop.yml +0 -1
- data/guides/any_fixture.md +0 -114
- data/guides/before_all.md +0 -98
- data/guides/event_prof.md +0 -177
- data/guides/factory_default.md +0 -111
- data/guides/factory_doctor.md +0 -119
- data/guides/factory_prof.md +0 -86
- data/guides/let_it_be.md +0 -97
- data/guides/rspec_dissect.md +0 -60
- data/guides/rspec_stamp.md +0 -52
- data/guides/rubocop.md +0 -48
- data/guides/ruby_prof.md +0 -63
- data/guides/stack_prof.md +0 -47
- data/guides/tag_prof.md +0 -51
- data/guides/tests_sampling.md +0 -24
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TestProf
|
4
|
+
module TagProf # :nodoc:
|
5
|
+
# Object holding all the stats for tags
|
6
|
+
class Result
|
7
|
+
attr_reader :tag, :data, :events
|
8
|
+
|
9
|
+
def initialize(tag, events = [])
|
10
|
+
@tag = tag
|
11
|
+
@events = events
|
12
|
+
|
13
|
+
@data = Hash.new do |h, k|
|
14
|
+
h[k] = { value: k, count: 0, time: 0.0 }
|
15
|
+
h[k].merge!(Hash[events.map { |event| [event, 0.0] }]) unless
|
16
|
+
events.empty?
|
17
|
+
h[k]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def track(tag, time:, events: {})
|
22
|
+
data[tag][:count] += 1
|
23
|
+
data[tag][:time] += time
|
24
|
+
events.each do |k, v|
|
25
|
+
data[tag][k] += v
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_json
|
30
|
+
{
|
31
|
+
tag: tag,
|
32
|
+
data: data.values,
|
33
|
+
events: events
|
34
|
+
}.to_json
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -1,14 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "test_prof/ext/float_duration"
|
4
|
-
require "test_prof/ext/string_strip_heredoc"
|
5
|
-
|
6
3
|
module TestProf
|
7
4
|
module TagProf
|
8
5
|
class RSpecListener # :nodoc:
|
9
6
|
include Logging
|
10
|
-
using FloatDuration
|
11
|
-
using StringStripHeredoc
|
12
7
|
|
13
8
|
NOTIFICATIONS = %i[
|
14
9
|
example_started
|
@@ -16,58 +11,58 @@ module TestProf
|
|
16
11
|
example_passed
|
17
12
|
].freeze
|
18
13
|
|
14
|
+
attr_reader :result, :printer
|
15
|
+
|
19
16
|
def initialize
|
20
|
-
@
|
21
|
-
|
17
|
+
@printer = ENV['TAG_PROF_FORMAT'] == 'html' ? Printers::HTML : Printers::Simple
|
18
|
+
|
19
|
+
@result =
|
20
|
+
if ENV['TAG_PROF_EVENT'].nil?
|
21
|
+
Result.new ENV['TAG_PROF'].to_sym
|
22
|
+
else
|
23
|
+
require "test_prof/event_prof"
|
24
|
+
|
25
|
+
@events_profiler = EventProf.build(ENV['TAG_PROF_EVENT'])
|
22
26
|
|
23
|
-
|
27
|
+
Result.new ENV['TAG_PROF'].to_sym, @events_profiler.events
|
28
|
+
end
|
29
|
+
|
30
|
+
log :info, "TagProf enabled (#{result.tag})"
|
24
31
|
end
|
25
32
|
|
26
33
|
def example_started(_notification)
|
27
34
|
@ts = TestProf.now
|
35
|
+
# enable event profiling
|
36
|
+
@events_profiler.group_started(true) if @events_profiler
|
28
37
|
end
|
29
38
|
|
30
39
|
def example_finished(notification)
|
31
|
-
tag = notification.example.metadata.fetch(
|
40
|
+
tag = notification.example.metadata.fetch(result.tag, :__unknown__)
|
41
|
+
|
42
|
+
result.track(tag, time: TestProf.now - @ts, events: fetch_events_data)
|
32
43
|
|
33
|
-
|
34
|
-
@
|
44
|
+
# reset and disable event profilers
|
45
|
+
@events_profiler.group_started(nil) if @events_profiler
|
35
46
|
end
|
36
47
|
|
37
48
|
# NOTE: RSpec < 3.4.0 doesn't have example_finished event
|
38
49
|
alias example_passed example_finished
|
39
50
|
alias example_failed example_finished
|
40
51
|
|
41
|
-
def
|
42
|
-
|
43
|
-
|
44
|
-
msgs <<
|
45
|
-
<<-MSG.strip_heredoc
|
46
|
-
TagProf report for #{@tag}
|
47
|
-
MSG
|
48
|
-
|
49
|
-
msgs << format(
|
50
|
-
"%15s %12s %6s %6s %6s %12s",
|
51
|
-
@tag,
|
52
|
-
'time', 'total', '%total', '%time', 'avg'
|
53
|
-
)
|
54
|
-
|
55
|
-
msgs << ""
|
52
|
+
def report
|
53
|
+
printer.dump(result)
|
54
|
+
end
|
56
55
|
|
57
|
-
|
58
|
-
total_time = @tags.values.inject(0) { |acc, v| acc + v[:time] }
|
56
|
+
private
|
59
57
|
|
60
|
-
|
61
|
-
|
62
|
-
"%15s %12s %6d %6.2f %6.2f %12s",
|
63
|
-
tag[:val], tag[:time].duration, tag[:count],
|
64
|
-
100 * tag[:count].to_f / total,
|
65
|
-
100 * tag[:time] / total_time,
|
66
|
-
(tag[:time] / tag[:count]).duration
|
67
|
-
)
|
68
|
-
end
|
58
|
+
def fetch_events_data
|
59
|
+
return {} unless @events_profiler
|
69
60
|
|
70
|
-
|
61
|
+
Hash[
|
62
|
+
@events_profiler.profilers.map do |profiler|
|
63
|
+
[profiler.event, profiler.time]
|
64
|
+
end
|
65
|
+
]
|
71
66
|
end
|
72
67
|
end
|
73
68
|
end
|
@@ -76,14 +71,22 @@ end
|
|
76
71
|
# Register TagProf listener
|
77
72
|
TestProf.activate('TAG_PROF') do
|
78
73
|
RSpec.configure do |config|
|
79
|
-
listener =
|
74
|
+
listener = nil
|
80
75
|
|
81
76
|
config.before(:suite) do
|
77
|
+
listener = TestProf::TagProf::RSpecListener.new
|
82
78
|
config.reporter.register_listener(
|
83
79
|
listener, *TestProf::TagProf::RSpecListener::NOTIFICATIONS
|
84
80
|
)
|
85
81
|
end
|
86
82
|
|
87
|
-
config.after(:suite) { listener.
|
83
|
+
config.after(:suite) { listener.report unless listener.nil? }
|
88
84
|
end
|
89
85
|
end
|
86
|
+
|
87
|
+
# Activate custom events
|
88
|
+
TestProf.activate('TAG_PROF_EVENT') do
|
89
|
+
require "test_prof/event_prof"
|
90
|
+
|
91
|
+
TestProf::EventProf::CustomEvents.activate_all(ENV['TAG_PROF_EVENT'])
|
92
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "json"
|
4
|
+
|
5
|
+
module TestProf
|
6
|
+
module Utils
|
7
|
+
# Generates static HTML reports with injected data
|
8
|
+
module HTMLBuilder
|
9
|
+
class << self
|
10
|
+
def generate(data:, template:, output:)
|
11
|
+
template = File.read(TestProf.asset_path(template))
|
12
|
+
template.sub! '/**REPORT-DATA**/', data.to_json
|
13
|
+
|
14
|
+
outpath = TestProf.artifact_path(output)
|
15
|
+
File.write(outpath, template)
|
16
|
+
outpath
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
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
|
+
version: 0.5.0.pre1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vladimir Dementyev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-05-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -72,14 +72,14 @@ dependencies:
|
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
75
|
+
version: 0.56.0
|
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
|
-
version:
|
82
|
+
version: 0.56.0
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: rubocop-md
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -109,7 +109,6 @@ files:
|
|
109
109
|
- README.md
|
110
110
|
- assets/flamegraph.demo.html
|
111
111
|
- assets/flamegraph.template.html
|
112
|
-
- assets/logo.svg
|
113
112
|
- assets/src/d3-tip.js
|
114
113
|
- assets/src/d3-tip.min.js
|
115
114
|
- assets/src/d3.flameGraph.css
|
@@ -117,28 +116,15 @@ files:
|
|
117
116
|
- assets/src/d3.flameGraph.min.css
|
118
117
|
- assets/src/d3.flameGraph.min.js
|
119
118
|
- assets/src/d3.v4.min.js
|
120
|
-
- assets/
|
121
|
-
-
|
122
|
-
- guides/any_fixture.md
|
123
|
-
- guides/before_all.md
|
124
|
-
- guides/event_prof.md
|
125
|
-
- guides/factory_default.md
|
126
|
-
- guides/factory_doctor.md
|
127
|
-
- guides/factory_prof.md
|
128
|
-
- guides/let_it_be.md
|
129
|
-
- guides/rspec_dissect.md
|
130
|
-
- guides/rspec_stamp.md
|
131
|
-
- guides/rubocop.md
|
132
|
-
- guides/ruby_prof.md
|
133
|
-
- guides/stack_prof.md
|
134
|
-
- guides/tag_prof.md
|
135
|
-
- guides/tests_sampling.md
|
119
|
+
- assets/tagprof.demo.html
|
120
|
+
- assets/tagprof.template.html
|
136
121
|
- lib/minitest/base_reporter.rb
|
137
122
|
- lib/minitest/event_prof_formatter.rb
|
138
123
|
- lib/minitest/test_prof_plugin.rb
|
139
124
|
- lib/test-prof.rb
|
140
125
|
- lib/test_prof.rb
|
141
126
|
- lib/test_prof/any_fixture.rb
|
127
|
+
- lib/test_prof/any_fixture/dsl.rb
|
142
128
|
- lib/test_prof/cops/rspec/aggregate_failures.rb
|
143
129
|
- lib/test_prof/event_prof.rb
|
144
130
|
- lib/test_prof/event_prof/custom_events.rb
|
@@ -147,12 +133,15 @@ files:
|
|
147
133
|
- lib/test_prof/event_prof/custom_events/sidekiq_jobs.rb
|
148
134
|
- lib/test_prof/event_prof/instrumentations/active_support.rb
|
149
135
|
- lib/test_prof/event_prof/minitest.rb
|
136
|
+
- lib/test_prof/event_prof/profiler.rb
|
150
137
|
- lib/test_prof/event_prof/rspec.rb
|
151
138
|
- lib/test_prof/ext/active_record_3.rb
|
152
139
|
- lib/test_prof/ext/array_bsearch_index.rb
|
153
140
|
- lib/test_prof/ext/float_duration.rb
|
154
141
|
- lib/test_prof/ext/string_strip_heredoc.rb
|
155
142
|
- lib/test_prof/ext/string_truncate.rb
|
143
|
+
- lib/test_prof/factory_all_stub.rb
|
144
|
+
- lib/test_prof/factory_all_stub/factory_bot_patch.rb
|
156
145
|
- lib/test_prof/factory_bot.rb
|
157
146
|
- lib/test_prof/factory_default.rb
|
158
147
|
- lib/test_prof/factory_default/factory_bot_patch.rb
|
@@ -168,9 +157,12 @@ files:
|
|
168
157
|
- lib/test_prof/factory_prof/printers/flamegraph.rb
|
169
158
|
- lib/test_prof/factory_prof/printers/simple.rb
|
170
159
|
- lib/test_prof/logging.rb
|
160
|
+
- lib/test_prof/recipes/active_record_shared_connection.rb
|
161
|
+
- lib/test_prof/recipes/logging.rb
|
171
162
|
- lib/test_prof/recipes/minitest/sample.rb
|
172
163
|
- lib/test_prof/recipes/rspec/any_fixture.rb
|
173
164
|
- lib/test_prof/recipes/rspec/before_all.rb
|
165
|
+
- lib/test_prof/recipes/rspec/factory_all_stub.rb
|
174
166
|
- lib/test_prof/recipes/rspec/factory_default.rb
|
175
167
|
- lib/test_prof/recipes/rspec/let_it_be.rb
|
176
168
|
- lib/test_prof/recipes/rspec/sample.rb
|
@@ -185,8 +177,12 @@ files:
|
|
185
177
|
- lib/test_prof/stack_prof.rb
|
186
178
|
- lib/test_prof/stack_prof/rspec.rb
|
187
179
|
- lib/test_prof/tag_prof.rb
|
180
|
+
- lib/test_prof/tag_prof/printers/html.rb
|
181
|
+
- lib/test_prof/tag_prof/printers/simple.rb
|
182
|
+
- lib/test_prof/tag_prof/result.rb
|
188
183
|
- lib/test_prof/tag_prof/rspec.rb
|
189
184
|
- lib/test_prof/utils.rb
|
185
|
+
- lib/test_prof/utils/html_builder.rb
|
190
186
|
- lib/test_prof/utils/sized_ordered_set.rb
|
191
187
|
- lib/test_prof/version.rb
|
192
188
|
homepage: http://github.com/palkan/test-prof
|
@@ -204,12 +200,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
204
200
|
version: 2.2.0
|
205
201
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
206
202
|
requirements:
|
207
|
-
- - "
|
203
|
+
- - ">"
|
208
204
|
- !ruby/object:Gem::Version
|
209
|
-
version:
|
205
|
+
version: 1.3.1
|
210
206
|
requirements: []
|
211
207
|
rubyforge_project:
|
212
|
-
rubygems_version: 2.7.
|
208
|
+
rubygems_version: 2.7.6
|
213
209
|
signing_key:
|
214
210
|
specification_version: 4
|
215
211
|
summary: Ruby applications tests profiling tools
|
data/assets/logo.svg
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 86 100"><defs><linearGradient id="a" x1="43" y1="100" x2="43" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#b5afbf"/><stop offset="1" stop-color="#dbd1d6"/></linearGradient><linearGradient id="b" x1="16" y1="87" x2="16" y2="73" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#a99ea7"/><stop offset=".6" stop-color="#c8b8c1"/></linearGradient><linearGradient id="c" x1="14" y1="75" x2="14" y2="79" xlink:href="#linear-gradient-2"/><linearGradient id="d" x1="34" x2="34" xlink:href="#linear-gradient-2"/><linearGradient id="e" x1="36" y1="79" x2="36" y2="83" xlink:href="#linear-gradient-2"/></defs><rect fill="url(#a)" width="86" height="100" rx="13" ry="13"/><rect fill="#fef7f9" x="1" y="1" width="84" height="94" rx="12" ry="12"/><path fill="#fff" d="M73 1H13A12 12 0 0 0 1 13v1A12 12 0 0 1 13 2h60a12 12 0 0 1 12 12v-1A12 12 0 0 0 73 1z"/><rect fill="#7e628f" x="9" y="9" width="68" height="58" rx="4" ry="4"/><path fill="#675077" d="M73 9H13a4 4 0 0 0-4 4v1a4 4 0 0 1 4-4h60a4 4 0 0 1 4 4v-1a4 4 0 0 0-4-4z"/><rect fill="#d84b9d" x="51" y="73" width="26" height="14" rx="4" ry="4"/><rect fill="#f159b0" x="51" y="73" width="26" height="12" rx="4" ry="4"/><path fill="#fc7acb" d="M73 84H55a4 4 0 0 1-4-4v1a4 4 0 0 0 4 4h18a4 4 0 0 0 4-4v-1a4 4 0 0 1-4 4z"/><circle fill="url(#b)" cx="16" cy="80" r="7"/><circle fill="#dec7d4" cx="16" cy="79" r="6"/><path fill="#f9edf4" d="M16 74a6 6 0 0 1 6 5.5V79a6 6 0 0 0-12 0v.5a6 6 0 0 1 6-5.5z"/><circle fill="url(#c)" cx="14" cy="77" r="2"/><circle fill="url(#d)" cx="34" cy="80" r="7"/><circle fill="#dec7d4" cx="34" cy="79" r="6"/><path fill="#f9edf4" d="M34 74a6 6 0 0 1 6 5.5V79a6 6 0 0 0-12 0v.5a6 6 0 0 1 6-5.5z"/><circle fill="url(#e)" cx="36" cy="81" r="2"/><path fill="#9072a0" d="M27 60.8A11.8 11.8 0 1 1 38.8 49 11.8 11.8 0 0 1 27 60.8zm0-20a8.2 8.2 0 1 0 8.2 8.2 8.2 8.2 0 0 0-8.2-8.2z"/><path fill="#fe5bb7" d="M37 51a2 2 0 0 1-2-2 8 8 0 0 0-8-8 2 2 0 0 1 0-4 12 12 0 0 1 12 12 2 2 0 0 1-2 2z"/><path fill="#9072a0" d="M59 60.8A11.8 11.8 0 1 1 70.8 49 11.8 11.8 0 0 1 59 60.8zm0-20a8.2 8.2 0 1 0 8.2 8.2 8.2 8.2 0 0 0-8.2-8.2z"/><path fill="#5bd3e8" d="M59 61a12 12 0 0 1-12-12 2 2 0 0 1 4 0 8 8 0 1 0 8-8 2 2 0 0 1 0-4 12 12 0 0 1 0 24z"/><path fill="#ffae43" d="M70 17.5l-11 11-4-5-7.8 8.8-11-21.2L26 25.7l-4-4-8 10.7-5-8V28l5 7.8 8-11.3 4 4L36 15l10.8 20.8 8.2-9.2 4 5 11-11 7 8.5v-3l-7-8.4z"/></svg>
|
data/assets/testprof.png
DELETED
Binary file
|
data/guides/.rubocop.yml
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
# Leave it blank to use default Rubocop config in guides
|
data/guides/any_fixture.md
DELETED
@@ -1,114 +0,0 @@
|
|
1
|
-
# Any Fixture
|
2
|
-
|
3
|
-
Fixtures are the great way to increase your test suite performance, but for the large project, they are very hard to maintain.
|
4
|
-
|
5
|
-
We propose a more general approach to lazy-generate the _global_ state for your test suite – AnyFixture.
|
6
|
-
|
7
|
-
With AnyFixture you can use any block of code for data generation, and it will take care of cleaning it out at the end of the run.
|
8
|
-
|
9
|
-
Consider an example:
|
10
|
-
|
11
|
-
```ruby
|
12
|
-
# The best way to use AnyFixture is through RSpec shared contexts
|
13
|
-
RSpec.shared_context 'account', account: true do
|
14
|
-
# You should call AnyFixture outside of transaction to re-use the same
|
15
|
-
# data between examples
|
16
|
-
before(:all) do
|
17
|
-
# The provided name ("account") should be unique.
|
18
|
-
@account = TestProf::AnyFixture.register(:account) do
|
19
|
-
# Do anything here, AnyFixture keeps track of affected DB tables
|
20
|
-
# For example, you can use factories here
|
21
|
-
FactoryGirl.create(:account)
|
22
|
-
|
23
|
-
# or with Fabrication
|
24
|
-
Fabricate(:account)
|
25
|
-
|
26
|
-
# or with plain old AR
|
27
|
-
Account.create!(name: 'test')
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
let(:account) { @account }
|
32
|
-
|
33
|
-
# Or hard-reload object if there is chance of in-place modification
|
34
|
-
let(:account) { Account.find(@account.id) }
|
35
|
-
end
|
36
|
-
|
37
|
-
# Then in your tests
|
38
|
-
|
39
|
-
# Active this fixture using a tag
|
40
|
-
describe UsersController, :account do
|
41
|
-
# ...
|
42
|
-
end
|
43
|
-
|
44
|
-
# This test also uses the same account record,
|
45
|
-
# no double-creation
|
46
|
-
describe PostsController, :account do
|
47
|
-
# ...
|
48
|
-
end
|
49
|
-
```
|
50
|
-
|
51
|
-
## Instructions
|
52
|
-
|
53
|
-
In your `spec_helper.rb`:
|
54
|
-
|
55
|
-
```ruby
|
56
|
-
require 'test_prof/recipes/rspec/any_fixture'
|
57
|
-
```
|
58
|
-
|
59
|
-
Now you can use `TestProf::AnyFixture` in your tests.
|
60
|
-
|
61
|
-
## Caveats
|
62
|
-
|
63
|
-
`AnyFixture` cleans tables in the reverse order as compared to the order they were populated. That
|
64
|
-
means when you register a fixture which references a not-yet-registered table, a
|
65
|
-
foreign-key violation error *might* occur (if any). An example is worth more than 1000
|
66
|
-
words:
|
67
|
-
|
68
|
-
```ruby
|
69
|
-
class Author < ApplicationRecord
|
70
|
-
has_many :articles
|
71
|
-
end
|
72
|
-
|
73
|
-
class Article < ApplicationRecord
|
74
|
-
belongs_to :author
|
75
|
-
end
|
76
|
-
```
|
77
|
-
|
78
|
-
And the shared contexts:
|
79
|
-
|
80
|
-
```ruby
|
81
|
-
RSpec.shared_context 'author' do
|
82
|
-
before(:all) do
|
83
|
-
@author = TestProf::AnyFixture.register(:author) do
|
84
|
-
FactoryGirl.create(:account)
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
let(:author) { @author }
|
89
|
-
end
|
90
|
-
|
91
|
-
RSpec.shared_context 'article' do
|
92
|
-
before(:all) do
|
93
|
-
# outside of AnyFixture, we don't know about its dependent tables
|
94
|
-
author = FactoryGirl.create(:author)
|
95
|
-
|
96
|
-
@article = TestProf::AnyFixture.register(:article) do
|
97
|
-
FactoryGirl.create(:article, author: author)
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
let(:article) { @article }
|
102
|
-
end
|
103
|
-
```
|
104
|
-
|
105
|
-
Then in some example:
|
106
|
-
|
107
|
-
```ruby
|
108
|
-
# This one adds only the 'articles' table to the list of affected tables
|
109
|
-
include_context 'article'
|
110
|
-
# And this one adds the 'authors' table
|
111
|
-
include_context 'author'
|
112
|
-
```
|
113
|
-
|
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.
|