once-ler 0.0.11 → 0.0.12
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.
- data/README.md +46 -4
- data/lib/onceler/ambitious_helpers.rb +2 -2
- data/lib/onceler/basic_helpers.rb +18 -5
- data/lib/onceler/configuration.rb +14 -9
- data/lib/onceler/recorder.rb +33 -0
- metadata +2 -2
data/README.md
CHANGED
@@ -52,6 +52,47 @@ describe "something" do
|
|
52
52
|
end
|
53
53
|
```
|
54
54
|
|
55
|
+
## Configuration
|
56
|
+
|
57
|
+
once-ler adds two new `before`/`after` scopes, `:record` and `:reset`, in
|
58
|
+
case you need to implement additional logic. `:record` runs in
|
59
|
+
conjunction with once-ler's recording phase (the implicit `before :all`).
|
60
|
+
`:reset` runs in conjunction with its cleanup phase (database rollback,
|
61
|
+
implicit `after :all`). As oppose to `:all`/`:context` hooks, these ones
|
62
|
+
are inherited down, and will run before/after any nested once-ler setup/
|
63
|
+
teardown.`
|
64
|
+
|
65
|
+
They can be used globally, or in a particular group. For example:
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
Onceler.configure do |config|
|
69
|
+
config.before :record do
|
70
|
+
# reset some caching to ensure all recordings get a blank slate
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe Foo do
|
75
|
+
before(:record) { Foo.stubs(:enabled?).returns(true) }
|
76
|
+
after(:record) { Foo.unstub(:enabled?) } # can't serialize stubs
|
77
|
+
before(:each) { Foo.stubs(:enabled?).returns(true) }
|
78
|
+
|
79
|
+
context "lol" do
|
80
|
+
before :once do
|
81
|
+
# something that needs the stub to work
|
82
|
+
end
|
83
|
+
# ...
|
84
|
+
end
|
85
|
+
|
86
|
+
context "wut" do
|
87
|
+
it do
|
88
|
+
# something that needs the stub to work
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# ...
|
93
|
+
end
|
94
|
+
```
|
95
|
+
|
55
96
|
## How much of a speedup will I get?
|
56
97
|
|
57
98
|
YMMV, it depends on how bad your `let`s/`before`s are. For example,
|
@@ -63,7 +104,7 @@ model specs (spec/models/a*) **reduces their runtime by 40%**.
|
|
63
104
|
Any `before(:once)`/`let_once` blocks will run just once for the current
|
64
105
|
context/describe block, before any of its examples run. Any side effects
|
65
106
|
(ivars) and return values will be recorded, and will then be reapplied
|
66
|
-
before each spec in the block runs.
|
107
|
+
before each spec in the block runs. once-ler uses nested transactions
|
67
108
|
(savepoints) to ensure that specs don't mess with each other's database
|
68
109
|
rows.
|
69
110
|
|
@@ -79,9 +120,10 @@ of activerecord callbacks/inserts/updates.
|
|
79
120
|
statements, return values, and instance variables.
|
80
121
|
* Your return values and instance variables:
|
81
122
|
1. need to be able to handle a `Marshal.dump`/`load` round trip.
|
82
|
-
|
83
|
-
|
84
|
-
need to
|
123
|
+
RSpec mocks/doubles can't.
|
124
|
+
1. should implement `#==`. For built-ins types (e.g. String) or models,
|
125
|
+
this isn't a problem, but if it's a custom class you might need to
|
126
|
+
go override `Object#==`
|
85
127
|
* Your once'd blocks' behavior should not depend on side effects of other
|
86
128
|
non-once'd blocks. For example:
|
87
129
|
* a `before(:once)` block should not reference instance variables set by a
|
@@ -31,8 +31,8 @@ module Onceler
|
|
31
31
|
onceler(:create) << block
|
32
32
|
end
|
33
33
|
|
34
|
-
def
|
35
|
-
|
34
|
+
def once_scopes
|
35
|
+
[:once]
|
36
36
|
end
|
37
37
|
|
38
38
|
# add second scope argument to explicitly differentiate between
|
@@ -40,7 +40,7 @@ module Onceler
|
|
40
40
|
[:let, :let!, :subject, :subject!].each do |method|
|
41
41
|
once_method = (method.to_s.sub(/!\z/, '') + "_once").to_sym
|
42
42
|
define_method(method) do |name = nil, scope = nil, &block|
|
43
|
-
if
|
43
|
+
if once_scopes.include?(scope)
|
44
44
|
send once_method, name, &block
|
45
45
|
else
|
46
46
|
super name, &block
|
@@ -59,13 +59,27 @@ module Onceler
|
|
59
59
|
end
|
60
60
|
|
61
61
|
def before(*args, &block)
|
62
|
-
|
62
|
+
scope = args.first
|
63
|
+
case scope
|
64
|
+
when :record, :reset
|
65
|
+
onceler(:create).hooks[:before][scope] << block
|
66
|
+
when *once_scopes
|
63
67
|
before_once(&block)
|
64
68
|
else
|
65
69
|
super(*args, &block)
|
66
70
|
end
|
67
71
|
end
|
68
72
|
|
73
|
+
def after(*args, &block)
|
74
|
+
scope = args.first
|
75
|
+
case scope
|
76
|
+
when :record, :reset
|
77
|
+
onceler(:create).hooks[:after][scope] << block
|
78
|
+
else
|
79
|
+
super
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
69
83
|
def onceler(create_own = false)
|
70
84
|
if create_own
|
71
85
|
@onceler ||= create_onceler!
|
@@ -88,7 +102,6 @@ module Onceler
|
|
88
102
|
|
89
103
|
def add_onceler_hooks!
|
90
104
|
before(:all) do |group|
|
91
|
-
Onceler.configuration.run_callbacks(:record, :before)
|
92
105
|
group.onceler.record!
|
93
106
|
end
|
94
107
|
|
@@ -9,19 +9,24 @@ module Onceler
|
|
9
9
|
|
10
10
|
class Configuration
|
11
11
|
def before(scope, &block)
|
12
|
-
|
12
|
+
hooks[:before][scope] << block
|
13
13
|
end
|
14
14
|
|
15
|
-
def
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
15
|
+
def after(scope, &block)
|
16
|
+
hooks[:before][scope] << block
|
17
|
+
end
|
18
|
+
|
19
|
+
def hooks
|
20
|
+
@hooks ||= {
|
21
|
+
before: {record: [], reset: []},
|
22
|
+
after: {record: [], reset: []}
|
23
|
+
}
|
21
24
|
end
|
22
25
|
|
23
|
-
def
|
24
|
-
|
26
|
+
def run_hooks(timing, scope, context)
|
27
|
+
hooks[timing][scope].each do |hook|
|
28
|
+
context ? context.instance_eval(&hook) : hook.call
|
29
|
+
end
|
25
30
|
end
|
26
31
|
end
|
27
32
|
end
|
data/lib/onceler/recorder.rb
CHANGED
@@ -55,6 +55,7 @@ module Onceler
|
|
55
55
|
@tape.copy_from(parent.tape)
|
56
56
|
end
|
57
57
|
|
58
|
+
run_before_hooks(:record, @tape)
|
58
59
|
# we don't know the order named recordings will be called (or if
|
59
60
|
# they'll call each other), so prep everything first
|
60
61
|
@recordings.each do |recording|
|
@@ -63,19 +64,51 @@ module Onceler
|
|
63
64
|
@recordings.each do |recording|
|
64
65
|
recording.record_onto!(@tape)
|
65
66
|
end
|
67
|
+
run_after_hooks(:record, @tape)
|
66
68
|
@data = @tape.__data
|
67
69
|
ensure
|
68
70
|
Onceler.recording = false
|
69
71
|
end
|
70
72
|
|
71
73
|
def reset!
|
74
|
+
run_before_hooks(:reset)
|
72
75
|
rollback_transactions!
|
76
|
+
run_after_hooks(:reset)
|
73
77
|
end
|
74
78
|
|
75
79
|
def parent
|
76
80
|
@group_class.parent_onceler
|
77
81
|
end
|
78
82
|
|
83
|
+
def hooks
|
84
|
+
@hooks ||= {
|
85
|
+
before: {record: [], reset: []},
|
86
|
+
after: {record: [], reset: []}
|
87
|
+
}
|
88
|
+
end
|
89
|
+
|
90
|
+
def run_before_hooks(scope, context = nil)
|
91
|
+
if parent
|
92
|
+
parent.run_before_hooks(scope, context)
|
93
|
+
else
|
94
|
+
Onceler.configuration.run_hooks(:before, scope, context)
|
95
|
+
end
|
96
|
+
hooks[:before][scope].each do |hook|
|
97
|
+
context ? context.instance_eval(&hook) : hook.call
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def run_after_hooks(scope, context = nil)
|
102
|
+
hooks[:after][scope].each do |hook|
|
103
|
+
context ? context.instance_eval(&hook) : hook.call
|
104
|
+
end
|
105
|
+
if parent
|
106
|
+
parent.run_before_hooks(scope, context)
|
107
|
+
else
|
108
|
+
Onceler.configuration.run_hooks(:after, scope, context)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
79
112
|
def replay_into!(instance)
|
80
113
|
@ivars, @retvals = Marshal.load(@data)
|
81
114
|
@ivars.each do |key, value|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: once-ler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.12
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-07-
|
12
|
+
date: 2014-07-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|