once-ler 0.0.6 → 0.0.7
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 +6 -0
- data/lib/onceler/basic_helpers.rb +3 -17
- data/lib/onceler/configuration.rb +0 -8
- data/lib/onceler/{blank_tape.rb → recordable.rb} +12 -14
- data/lib/onceler/recorder.rb +8 -36
- metadata +3 -3
data/README.md
CHANGED
@@ -60,6 +60,12 @@ RSpec.configure do |c|
|
|
60
60
|
end
|
61
61
|
```
|
62
62
|
|
63
|
+
## How much of a speedup will I get?
|
64
|
+
|
65
|
+
YMMV, it depends on how bad your `let`s/`before`s are. For example,
|
66
|
+
adding once-ler to a subset of [canvas-lms](https://github.com/instructure/canvas-lms)'s
|
67
|
+
model specs (spec/models/a*) **reduces their runtime by 40%**.
|
68
|
+
|
63
69
|
## How does it work?
|
64
70
|
|
65
71
|
Any `before(:once)`/`let_once` blocks will run just once for the current
|
@@ -76,30 +76,16 @@ module Onceler
|
|
76
76
|
|
77
77
|
def create_onceler!
|
78
78
|
add_onceler_hooks!
|
79
|
-
Recorder.new(
|
79
|
+
Recorder.new(self)
|
80
80
|
end
|
81
81
|
|
82
|
-
# make sure we have access to subsequently added methods when
|
83
|
-
# recording (not just `lets'). note that this really only works
|
84
|
-
# for truly functional methods with no external dependencies. e.g.
|
85
|
-
# methods that add stubs or set instance variables will not work
|
86
|
-
# while recording
|
87
|
-
def method_added(method_name)
|
88
|
-
return if method_name == @current_let_once
|
89
|
-
return if !@onceler
|
90
|
-
proxy = onceler.helper_proxy ||= new
|
91
|
-
onceler.helper_methods[method_name] ||= Proc.new do |*args|
|
92
|
-
proxy.send method_name, *args
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
private
|
97
|
-
|
98
82
|
def parent_onceler
|
99
83
|
return unless superclass.respond_to?(:onceler)
|
100
84
|
superclass.onceler
|
101
85
|
end
|
102
86
|
|
87
|
+
private
|
88
|
+
|
103
89
|
def add_onceler_hooks!
|
104
90
|
before(:all) do |group|
|
105
91
|
Onceler.configuration.run_callbacks(:record, :before)
|
@@ -1,9 +1,11 @@
|
|
1
1
|
module Onceler
|
2
|
-
|
3
|
-
def
|
4
|
-
|
5
|
-
|
6
|
-
|
2
|
+
module Recordable
|
3
|
+
def self.extended(instance)
|
4
|
+
instance.instance_eval do
|
5
|
+
@__retvals = {}
|
6
|
+
@__retvals_recorded = {} # we might override an inherited one, so we need to differentiate
|
7
|
+
@__ignore_ivars = instance_variables
|
8
|
+
end
|
7
9
|
end
|
8
10
|
|
9
11
|
def __prepare_recording(recording)
|
@@ -23,10 +25,12 @@ module Onceler
|
|
23
25
|
end
|
24
26
|
|
25
27
|
def __ivars
|
26
|
-
ivars = instance_variables -
|
28
|
+
ivars = instance_variables - @__ignore_ivars
|
27
29
|
ivars.inject({}) do |hash, key|
|
28
|
-
|
29
|
-
|
30
|
+
if key.to_s !~ /\A@__/
|
31
|
+
val = instance_variable_get(key)
|
32
|
+
hash[key] = val
|
33
|
+
end
|
30
34
|
hash
|
31
35
|
end
|
32
36
|
end
|
@@ -35,12 +39,6 @@ module Onceler
|
|
35
39
|
@__data ||= Marshal.dump([__ivars, @__retvals])
|
36
40
|
end
|
37
41
|
|
38
|
-
def copy(mixins)
|
39
|
-
copy = self.class.new(mixins)
|
40
|
-
copy.copy_from(self)
|
41
|
-
copy
|
42
|
-
end
|
43
|
-
|
44
42
|
def copy_from(other)
|
45
43
|
ivars, @__retvals = Marshal.load(other.__data)
|
46
44
|
ivars.each do |key, value|
|
data/lib/onceler/recorder.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require "onceler/
|
1
|
+
require "onceler/recordable"
|
2
2
|
require "onceler/transactions"
|
3
3
|
|
4
4
|
module Onceler
|
@@ -7,8 +7,8 @@ module Onceler
|
|
7
7
|
|
8
8
|
attr_accessor :tape, :helper_proxy
|
9
9
|
|
10
|
-
def initialize(
|
11
|
-
@
|
10
|
+
def initialize(group_class)
|
11
|
+
@group_class = group_class
|
12
12
|
@recordings = []
|
13
13
|
@named_recordings = []
|
14
14
|
end
|
@@ -28,8 +28,11 @@ module Onceler
|
|
28
28
|
|
29
29
|
def record!
|
30
30
|
begin_transactions!
|
31
|
-
@tape = @
|
32
|
-
|
31
|
+
@tape = @group_class.new
|
32
|
+
@tape.send :extend, Recordable
|
33
|
+
if parent = @group_class.parent_onceler
|
34
|
+
@tape.copy_from(parent.tape)
|
35
|
+
end
|
33
36
|
|
34
37
|
# we don't know the order named recordings will be called (or if
|
35
38
|
# they'll call each other), so prep everything first
|
@@ -46,37 +49,6 @@ module Onceler
|
|
46
49
|
rollback_transactions!
|
47
50
|
end
|
48
51
|
|
49
|
-
def proxy_recordable_methods!
|
50
|
-
# the proxy is used to run non-recordable methods that may be called
|
51
|
-
# by ones are recording. since the former could in turn call more of
|
52
|
-
# the latter, we need to proxy the other way too
|
53
|
-
return unless helper_proxy
|
54
|
-
methods = @named_recordings
|
55
|
-
reverse_proxy = @tape
|
56
|
-
helper_proxy.instance_eval do
|
57
|
-
methods.each do |method|
|
58
|
-
define_singleton_method(method) { reverse_proxy.send(method) }
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def helper_methods
|
64
|
-
@helper_methods ||= {}
|
65
|
-
end
|
66
|
-
|
67
|
-
def mixins
|
68
|
-
mixins = (@parent ? @parent.mixins : Onceler.configuration.modules).dup
|
69
|
-
if methods = @helper_methods
|
70
|
-
mixin = Module.new do
|
71
|
-
methods.each do |key, method|
|
72
|
-
define_method(key, &method)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
mixins.push mixin
|
76
|
-
end
|
77
|
-
mixins
|
78
|
-
end
|
79
|
-
|
80
52
|
def reconsitute_data!
|
81
53
|
@ivars, @retvals = Marshal.load(@data)
|
82
54
|
identity_map = {}
|
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.7
|
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-06-
|
12
|
+
date: 2014-06-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
@@ -54,13 +54,13 @@ files:
|
|
54
54
|
- lib/once-ler.rb
|
55
55
|
- lib/onceler/ambitious_helpers.rb
|
56
56
|
- lib/onceler/basic_helpers.rb
|
57
|
-
- lib/onceler/blank_tape.rb
|
58
57
|
- lib/onceler/configuration.rb
|
59
58
|
- lib/onceler/extensions/active_record.rb
|
60
59
|
- lib/onceler/extensions/active_record_3_0.rb
|
61
60
|
- lib/onceler/extensions/active_record_3_2.rb
|
62
61
|
- lib/onceler/extensions/active_record_4_0.rb
|
63
62
|
- lib/onceler/extensions/active_record_4_1.rb
|
63
|
+
- lib/onceler/recordable.rb
|
64
64
|
- lib/onceler/recorder.rb
|
65
65
|
- lib/onceler/transactions/active_record_3.rb
|
66
66
|
- lib/onceler/transactions/active_record_4.rb
|