serializable_proc 0.1.0

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.
@@ -0,0 +1,159 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ describe 'One arity serializable proc' do
4
+
5
+ extend SerializableProc::Spec::Helpers
6
+
7
+ expected_file = File.expand_path(__FILE__)
8
+ expected_code = "lambda { |lvar_arg| [\"a\", \"b\"].map { |lvar_x| puts(lvar_x) } }"
9
+
10
+ should_handle_proc_variable expected_file, expected_code, {
11
+ # ////////////////////////////////////////////////////////////////////////
12
+ # >> Always newlinling
13
+ # ////////////////////////////////////////////////////////////////////////
14
+ __LINE__ =>
15
+ lambda do |arg|
16
+ %w{a b}.map do |x|
17
+ puts x
18
+ end
19
+ end,
20
+ __LINE__ =>
21
+ lambda { |arg|
22
+ %w{a b}.map{|x|
23
+ puts x
24
+ }
25
+ },
26
+ __LINE__ =>
27
+ proc do |arg|
28
+ %w{a b}.map do |x|
29
+ puts x
30
+ end
31
+ end,
32
+ __LINE__ =>
33
+ lambda { |arg|
34
+ %w{a b}.map{|x|
35
+ puts x
36
+ }
37
+ },
38
+ __LINE__ =>
39
+ Proc.new do |arg|
40
+ %w{a b}.map do |x|
41
+ puts x
42
+ end
43
+ end,
44
+ __LINE__ =>
45
+ Proc.new { |arg|
46
+ %w{a b}.map{|x|
47
+ puts x
48
+ }
49
+ },
50
+ # ////////////////////////////////////////////////////////////////////////
51
+ # >> Partial newlining
52
+ # ////////////////////////////////////////////////////////////////////////
53
+ __LINE__ =>
54
+ lambda do |arg|
55
+ %w{a b}.map do |x| puts x end
56
+ end,
57
+ __LINE__ =>
58
+ lambda { |arg|
59
+ %w{a b}.map{|x| puts x }
60
+ },
61
+ __LINE__ =>
62
+ proc do |arg|
63
+ %w{a b}.map do |x| puts x end
64
+ end,
65
+ __LINE__ =>
66
+ lambda { |arg|
67
+ %w{a b}.map{|x| puts x }
68
+ },
69
+ __LINE__ =>
70
+ Proc.new do |arg|
71
+ %w{a b}.map do |x| puts x end
72
+ end,
73
+ __LINE__ =>
74
+ Proc.new { |arg|
75
+ %w{a b}.map{|x| puts x }
76
+ },
77
+ # ////////////////////////////////////////////////////////////////////////
78
+ # >> No newlining
79
+ # ////////////////////////////////////////////////////////////////////////
80
+ __LINE__ =>
81
+ lambda do |arg| %w{a b}.map do |x| puts x end end,
82
+ __LINE__ =>
83
+ lambda { |arg| %w{a b}.map{|x| puts x } },
84
+ __LINE__ =>
85
+ proc do |arg| %w{a b}.map do |x| puts x end end,
86
+ __LINE__ =>
87
+ lambda { |arg| %w{a b}.map{|x| puts x } },
88
+ __LINE__ =>
89
+ Proc.new do |arg| %w{a b}.map do |x| puts x end end,
90
+ __LINE__ =>
91
+ Proc.new { |arg| %w{a b}.map{|x| puts x } },
92
+ }
93
+
94
+ should "handle block using do ... end [##{__LINE__}]" do
95
+ (
96
+ SerializableProc.new do |arg|
97
+ %w{a b}.map{|x| puts x }
98
+ end
99
+ ).should.be having_expected_proc_attrs(expected_file, __LINE__ - 3, expected_code)
100
+ end
101
+
102
+ should "handle block using do ... end [##{__LINE__}]" do
103
+ (SerializableProc.new do |arg| %w{a b}.map{|x| puts x } end).
104
+ should.be having_expected_proc_attrs(expected_file, __LINE__.pred, expected_code)
105
+ end
106
+
107
+ should "handle block using { ... } [##{__LINE__}]" do
108
+ (
109
+ SerializableProc.new { |arg|
110
+ %w{a b}.map{|x| puts x }
111
+ }
112
+ ).should.be having_expected_proc_attrs(expected_file, __LINE__ - 3, expected_code)
113
+ end
114
+
115
+ should "handle block using { ... } [##{__LINE__}]" do
116
+ (SerializableProc.new { |arg| %w{a b}.map{|x| puts x } }).
117
+ should.be having_expected_proc_attrs(expected_file, __LINE__.pred, expected_code)
118
+ end
119
+
120
+ should "handle fanciful initializing with lambda { ... } [##{__LINE__}]" do
121
+ (SerializableProc.new(&(lambda { |arg| %w{a b}.map{|x| puts x } }))).
122
+ should.be having_expected_proc_attrs(expected_file, __LINE__.pred, expected_code)
123
+ end
124
+
125
+ should "handle fanciful initializing with lambda do ... end [##{__LINE__}]" do
126
+ (
127
+ SerializableProc.new(&(lambda do |arg|
128
+ %w{a b}.map{|x| puts x }
129
+ end))
130
+ ).should.be having_expected_proc_attrs(expected_file, __LINE__ - 3, expected_code)
131
+ end
132
+
133
+ should "handle fanciful initializing with proc { ... } [##{__LINE__}]" do
134
+ (SerializableProc.new(&(proc { |arg| %w{a b}.map{|x| puts x } }))).
135
+ should.be having_expected_proc_attrs(expected_file, __LINE__.pred, expected_code)
136
+ end
137
+
138
+ should "handle fanciful initializing with proc do ... end [##{__LINE__}]" do
139
+ (
140
+ SerializableProc.new(&(proc do |arg|
141
+ %w{a b}.map{|x| puts x }
142
+ end))
143
+ ).should.be having_expected_proc_attrs(expected_file, __LINE__ - 3, expected_code)
144
+ end
145
+
146
+ should "handle fanciful initializing with Proc.new { ... } [##{__LINE__}]" do
147
+ (SerializableProc.new(&(Proc.new { |arg| %w{a b}.map{|x| puts x } }))).
148
+ should.be having_expected_proc_attrs(expected_file, __LINE__.pred, expected_code)
149
+ end
150
+
151
+ should "handle fanciful initializing with Proc.new do ... end [##{__LINE__}]" do
152
+ (
153
+ SerializableProc.new(&(Proc.new do |arg|
154
+ %w{a b}.map{|x| puts x }
155
+ end))
156
+ ).should.be having_expected_proc_attrs(expected_file, __LINE__ - 3, expected_code)
157
+ end
158
+
159
+ end
@@ -0,0 +1,160 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ describe 'Optional arity serializable proc' do
4
+
5
+ extend SerializableProc::Spec::Helpers
6
+
7
+ expected_file = File.expand_path(__FILE__)
8
+ expected_code = "lambda { |*lvar_args| [\"a\", \"b\"].map { |lvar_x| puts(lvar_x) } }"
9
+
10
+ should_handle_proc_variable expected_file, expected_code, {
11
+ # ////////////////////////////////////////////////////////////////////////
12
+ # >> Always newlinling
13
+ # ////////////////////////////////////////////////////////////////////////
14
+ __LINE__ =>
15
+ lambda do |*args|
16
+ %w{a b}.map do |x|
17
+ puts x
18
+ end
19
+ end,
20
+ __LINE__ =>
21
+ lambda { |*args|
22
+ %w{a b}.map{|x|
23
+ puts x
24
+ }
25
+ },
26
+ __LINE__ =>
27
+ proc do |*args|
28
+ %w{a b}.map do |x|
29
+ puts x
30
+ end
31
+ end,
32
+ __LINE__ =>
33
+ lambda { |*args|
34
+ %w{a b}.map{|x|
35
+ puts x
36
+ }
37
+ },
38
+ __LINE__ =>
39
+ Proc.new do |*args|
40
+ %w{a b}.map do |x|
41
+ puts x
42
+ end
43
+ end,
44
+ __LINE__ =>
45
+ Proc.new { |*args|
46
+ %w{a b}.map{|x|
47
+ puts x
48
+ }
49
+ },
50
+ # ////////////////////////////////////////////////////////////////////////
51
+ # >> Partial newlining
52
+ # ////////////////////////////////////////////////////////////////////////
53
+ __LINE__ =>
54
+ lambda do |*args|
55
+ %w{a b}.map do |x| puts x end
56
+ end,
57
+ __LINE__ =>
58
+ lambda { |*args|
59
+ %w{a b}.map{|x| puts x }
60
+ },
61
+ __LINE__ =>
62
+ proc do |*args|
63
+ %w{a b}.map do |x| puts x end
64
+ end,
65
+ __LINE__ =>
66
+ lambda { |*args|
67
+ %w{a b}.map{|x| puts x }
68
+ },
69
+ __LINE__ =>
70
+ Proc.new do |*args|
71
+ %w{a b}.map do |x| puts x end
72
+ end,
73
+ __LINE__ =>
74
+ Proc.new { |*args|
75
+ %w{a b}.map{|x| puts x }
76
+ },
77
+ # ////////////////////////////////////////////////////////////////////////
78
+ # >> No newlining
79
+ # ////////////////////////////////////////////////////////////////////////
80
+ __LINE__ =>
81
+ lambda do |*args| %w{a b}.map do |x| puts x end end,
82
+ __LINE__ =>
83
+ lambda { |*args| %w{a b}.map{|x| puts x } },
84
+ __LINE__ =>
85
+ proc do |*args| %w{a b}.map do |x| puts x end end,
86
+ __LINE__ =>
87
+ lambda { |*args| %w{a b}.map{|x| puts x } },
88
+ __LINE__ =>
89
+ Proc.new do |*args| %w{a b}.map do |x| puts x end end,
90
+ __LINE__ =>
91
+ Proc.new { |*args| %w{a b}.map{|x| puts x } },
92
+ }
93
+
94
+ should "handle block using do ... end [##{__LINE__}]" do
95
+ (
96
+ SerializableProc.new do |*args|
97
+ %w{a b}.map{|x| puts x }
98
+ end
99
+ ).should.be having_expected_proc_attrs(expected_file, __LINE__ - 3, expected_code)
100
+ end
101
+
102
+ should "handle block using do ... end [##{__LINE__}]" do
103
+ (SerializableProc.new do |*args| %w{a b}.map{|x| puts x } end).
104
+ should.be having_expected_proc_attrs(expected_file, __LINE__.pred, expected_code)
105
+ end
106
+
107
+ should "handle block using { ... } [##{__LINE__}]" do
108
+ (
109
+ SerializableProc.new { |*args|
110
+ %w{a b}.map{|x| puts x }
111
+ }
112
+ ).should.be having_expected_proc_attrs(expected_file, __LINE__ - 3, expected_code)
113
+ end
114
+
115
+ should "handle block using { ... } [##{__LINE__}]" do
116
+ (SerializableProc.new { |*args| %w{a b}.map{|x| puts x } }).
117
+ should.be having_expected_proc_attrs(expected_file, __LINE__.pred, expected_code)
118
+ end
119
+
120
+ should "handle fanciful initializing with lambda { ... } [##{__LINE__}]" do
121
+ (SerializableProc.new(&(lambda { |*args| %w{a b}.map{|x| puts x } }))).
122
+ should.be having_expected_proc_attrs(expected_file, __LINE__.pred, expected_code)
123
+ end
124
+
125
+ should "handle fanciful initializing with lambda do ... end [##{__LINE__}]" do
126
+ (
127
+ SerializableProc.new(&(lambda do |*args|
128
+ %w{a b}.map{|x| puts x }
129
+ end))
130
+ ).should.be having_expected_proc_attrs(expected_file, __LINE__ - 3, expected_code)
131
+ end
132
+
133
+ should "handle fanciful initializing with proc { ... } [##{__LINE__}]" do
134
+ (SerializableProc.new(&(proc { |*args| %w{a b}.map{|x| puts x } }))).
135
+ should.be having_expected_proc_attrs(expected_file, __LINE__.pred, expected_code)
136
+ end
137
+
138
+ should "handle fanciful initializing with proc do ... end [##{__LINE__}]" do
139
+ (
140
+ SerializableProc.new(&(proc do |*args|
141
+ %w{a b}.map{|x| puts x }
142
+ end))
143
+ ).should.be having_expected_proc_attrs(expected_file, __LINE__ - 3, expected_code)
144
+ end
145
+
146
+ should "handle fanciful initializing with Proc.new { ... } [##{__LINE__}]" do
147
+ (SerializableProc.new(&(Proc.new { |*args| %w{a b}.map{|x| puts x } }))).
148
+ should.be having_expected_proc_attrs(expected_file, __LINE__.pred, expected_code)
149
+ end
150
+
151
+ should "handle fanciful initializing with Proc.new do ... end [##{__LINE__}]" do
152
+ (
153
+ SerializableProc.new(&(Proc.new do |*args|
154
+ %w{a b}.map{|x| puts x }
155
+ end))
156
+ ).should.be having_expected_proc_attrs(expected_file, __LINE__ - 3, expected_code)
157
+ end
158
+
159
+
160
+ end
@@ -0,0 +1,191 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ describe 'Being proc like' do
4
+
5
+ describe '>> ==' do
6
+
7
+ before do
8
+ @proc = SerializableProc.new{ %w{a b}.map{|x| x } }
9
+ end
10
+
11
+ should 'return true if comparing to itself' do
12
+ @proc.should.equal(@proc)
13
+ end
14
+
15
+ should 'return true if another SerializableProc has the same code' do
16
+ SerializableProc.new{ %w{a b}.map{|x| x } }.should.equal(@proc)
17
+ end
18
+
19
+ should 'return false if another SerializableProc does not have the same code' do
20
+ SerializableProc.new{ %w{b c}.map{|x| x } }.should.not.equal(@proc)
21
+ end
22
+
23
+ end
24
+
25
+ describe '>> call (alias [])' do
26
+
27
+ should 'return yield result given no arg' do
28
+ s_proc = SerializableProc.new { %w{b c}.map{|x| x } }
29
+ expected = %w{b c}
30
+ s_proc.call.should.equal(expected)
31
+ s_proc[].should.equal(expected)
32
+ end
33
+
34
+ should 'reflect bound instance variable value (unaffected by outside-scope change)' do
35
+ x, y = 'awe', 'some'
36
+ expected = 'hand' + y
37
+ s_proc = SerializableProc.new { x.sub!('awe','hand'); x + y }
38
+ x, y = 'wonder', 'ful'
39
+ s_proc.call.should.equal(expected)
40
+ s_proc[].should.equal(expected)
41
+ end
42
+
43
+ should 'not affect any outside-scope change to instance variable' do
44
+ x, y = 'awe', 'some'
45
+ s_proc = SerializableProc.new { x.sub!('awe','hand'); x + y }
46
+ x, y = 'wonder', 'ful'
47
+ s_proc.call ; s_proc[]
48
+ x.should.equal('wonder')
49
+ y.should.equal('ful')
50
+ end
51
+
52
+ should 'reflect bound instance variable value (unaffected by outside-scope change)' do
53
+ @x, @y = 'awe', 'some'
54
+ expected = 'hand' + @y
55
+ s_proc = SerializableProc.new { @x.sub!('awe','hand'); @x + @y }
56
+ @x, @y = 'wonder', 'ful'
57
+ s_proc.call.should.equal(expected)
58
+ s_proc[].should.equal(expected)
59
+ end
60
+
61
+ should 'not affect any outside-scope change to instance variable' do
62
+ @x, @y = 'awe', 'some'
63
+ s_proc = SerializableProc.new { @x.sub!('awe','hand'); @x + @y }
64
+ @x, @y = 'wonder', 'ful'
65
+ s_proc.call ; s_proc[]
66
+ @x.should.equal('wonder')
67
+ @y.should.equal('ful')
68
+ end
69
+
70
+ should 'reflect bound class variable value (unaffected by outside-scope change)' do
71
+ @@x, @@y = 'awe', 'some'
72
+ expected = 'hand' + @@y
73
+ s_proc = SerializableProc.new { @@x.sub!('awe','hand'); @@x + @@y }
74
+ @@x, @@y = 'wonder', 'ful'
75
+ s_proc.call.should.equal(expected)
76
+ s_proc[].should.equal(expected)
77
+ end
78
+
79
+ should 'not affect any outside-scope change to class variable' do
80
+ @@x, @@y = 'awe', 'some'
81
+ s_proc = SerializableProc.new { @@x.sub!('awe','hand'); @@x + @@y }
82
+ @@x, @@y = 'wonder', 'ful'
83
+ s_proc.call ; s_proc[]
84
+ @@x.should.equal('wonder')
85
+ @@y.should.equal('ful')
86
+ end
87
+
88
+ should 'reflect bound global variable value (unaffected by outside-scope change)' do
89
+ $x, $y = 'awe', 'some'
90
+ expected = 'hand' + $y
91
+ s_proc = SerializableProc.new { $x.sub!('awe','hand'); $x + $y }
92
+ $x, $y = 'wonder', 'ful'
93
+ s_proc.call.should.equal(expected)
94
+ s_proc[].should.equal(expected)
95
+ end
96
+
97
+ should 'not affect any outside-scope change to global variable' do
98
+ $x, $y = 'awe', 'some'
99
+ s_proc = SerializableProc.new { $x.sub!('awe','hand'); $x + $y }
100
+ $x, $y = 'wonder', 'ful'
101
+ s_proc.call ; s_proc[]
102
+ $x.should.equal('wonder')
103
+ $y.should.equal('ful')
104
+ end
105
+
106
+ end
107
+
108
+ describe '>> clone' do
109
+ should 'return a serializable proc that yields +ve ==' do
110
+ s_proc = SerializableProc.new { %w{b c}.map{|x| x } }
111
+ clone = s_proc.clone
112
+ clone.should.equal(s_proc)
113
+ clone.object_id.should.not.equal(s_proc.object_id)
114
+ end
115
+ end
116
+
117
+ describe '>> binding' do
118
+ should 'raise NotImplementedError' do
119
+ lambda { SerializableProc.new { x }.binding }.should.raise(NotImplementedError)
120
+ end
121
+ # should 'return binding that contains duplicated contextual reference values' do
122
+ # x, @x, @@x, $x = 'lx', 'ix', 'cx', 'gx'
123
+ # expected = {'x' => x.dup, '@x' => @x.dup, '@@x' => @@x.dup, '$x' => $x.dup}
124
+ # s_proc = SerializableProc.new { [x, @x, @@x, $x] }
125
+ # x, @x, @@x, $x = 'ly', 'iy', 'cy', 'gy'
126
+ # expected.each{|k,v| s_proc.binding.eval(k).should.equal(v) }
127
+ # end
128
+ end
129
+
130
+ describe '>> to_proc' do
131
+
132
+ class << self
133
+ def work(&block) ; yield ; end
134
+ end
135
+
136
+ should 'return a non-serializable proc' do
137
+ o_proc = lambda { %w{b c}.map{|x| x } }
138
+ s_proc = SerializableProc.new(&o_proc)
139
+ n_proc = s_proc.to_proc
140
+ s_proc.should.not == n_proc
141
+ n_proc.class.should == Proc
142
+ n_proc.call.should.equal(o_proc.call)
143
+ end
144
+
145
+ should "support passing to a method using '&' char" do
146
+ s_proc = SerializableProc.new { %w{b c}.map{|x| x } }
147
+ work(&s_proc).should.equal(%w{b c})
148
+ end
149
+
150
+ end
151
+
152
+ describe '>> to_s' do
153
+
154
+ extend SerializableProc::Spec::Helpers
155
+
156
+ should 'return extracted code when debug is not specified' do
157
+ x, @x, @@x, $x = 'lx', 'ix', 'cx', 'gx'
158
+ SerializableProc.new{ [x,@x,@@x,$x] }.to_s.should.be \
159
+ having_same_semantics_as('lambda { [x, @x, @@x, $x] }')
160
+ end
161
+
162
+ should 'return extracted code when debug is turned off' do
163
+ x, @x, @@x, $x = 'lx', 'ix', 'cx', 'gx'
164
+ SerializableProc.new{ [x,@x,@@x,$x] }.to_s(false).should.be \
165
+ having_same_semantics_as('lambda { [x, @x, @@x, $x] }')
166
+ end
167
+
168
+ should 'return runnable code when debug is turned on' do
169
+ x, @x, @@x, $x = 'lx', 'ix', 'cx', 'gx'
170
+ SerializableProc.new{ [x,@x,@@x,$x] }.to_s(true).should.be \
171
+ having_same_semantics_as('lambda { [lvar_x, ivar_x, cvar_x, gvar_x] }')
172
+ end
173
+
174
+ end
175
+
176
+ describe '>> arity' do
177
+ {
178
+ __LINE__ => lambda { },
179
+ __LINE__ => lambda {|x| },
180
+ __LINE__ => lambda {|x,y| },
181
+ __LINE__ => lambda {|*x| },
182
+ __LINE__ => lambda {|x, *y| },
183
+ __LINE__ => lambda {|(x,y)| },
184
+ }.each do |debug, block|
185
+ should "return arity of initializing block [##{debug}]" do
186
+ SerializableProc.new(&block).arity.should.equal(block.arity)
187
+ end
188
+ end
189
+ end
190
+
191
+ end
@@ -0,0 +1,100 @@
1
+ require 'rubygems'
2
+ require 'bacon'
3
+ require 'tempfile'
4
+ require 'ruby2ruby'
5
+
6
+ $parse_tree_installed =
7
+ begin
8
+ require 'parse_tree'
9
+ true
10
+ rescue LoadError
11
+ require 'ruby_parser'
12
+ nil
13
+ end
14
+
15
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
16
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
17
+ require 'serializable_proc'
18
+
19
+ Bacon.summary_on_exit
20
+
21
+ class SerializableProc
22
+
23
+ attr_reader :code, :file, :line
24
+
25
+ def binding_dump
26
+ @binding.instance_variable_get(:@vars)
27
+ end
28
+
29
+ module Spec
30
+
31
+ module Matchers
32
+
33
+ def having_same_semantics_as(code2)
34
+ to_code = lambda{|sexp| ::Ruby2Ruby.new.process(sexp) }
35
+ to_sexp = $parse_tree_installed ?
36
+ lambda{|code| Unifier.new.process(::ParseTree.translate(code)) } :
37
+ lambda{|code| ::RubyParser.new.parse(code) }
38
+ normalize = lambda{|code| to_code[to_sexp[code]].sub('lambda','proc') }
39
+ lambda {|code1| normalize[code1].should.equal(normalize[code2]) }
40
+ end
41
+
42
+ def same_object_as(o2)
43
+ lambda {|o1| o1.object_id == o2.object_id }
44
+ end
45
+
46
+ def having_expected_proc_attrs(file, line, code)
47
+ lambda do |s_proc|
48
+ s_proc.code[:runnable].should.be having_same_semantics_as(code)
49
+ s_proc.file.should.equal(file)
50
+ s_proc.line.should.equal(line)
51
+ end
52
+ end
53
+
54
+ def raising_cannot_serialize_variable_error(var)
55
+ lambda do |block|
56
+ block.should.raise(SerializableProc::CannotSerializeVariableError).
57
+ message.should.equal('Variable %s cannot be serialized !!' % var)
58
+ true
59
+ end
60
+ end
61
+
62
+ def raising_cannot_analyse_error(descrp)
63
+ lambda do |block|
64
+ block.should.raise(SerializableProc::CannotAnalyseCodeError).message.should.
65
+ equal("Static code analysis can only handle single occurrence of #{descrp} per line !!")
66
+ true
67
+ end
68
+ end
69
+
70
+ end
71
+
72
+ module Macros
73
+
74
+ def should_have_expected_binding(s_proc, expected)
75
+ s_proc.binding_dump.should.equal(expected)
76
+ expected.each do |key, val|
77
+ (s_proc.binding_dump[key].should.not.be same_object_as(val)) if val
78
+ end
79
+ end
80
+
81
+ def should_handle_proc_variable(file, code, test_args)
82
+ test_args.each do |line, block|
83
+ should "handle proc variable [##{line}]" do
84
+ s_proc = SerializableProc.new(&block)
85
+ s_proc.code[:runnable].should.be having_same_semantics_as(code)
86
+ s_proc.file.should.equal(file)
87
+ s_proc.line.should.equal(line.succ)
88
+ end
89
+ end
90
+ end
91
+
92
+ end
93
+
94
+ module Helpers
95
+ include Macros
96
+ include Matchers
97
+ end
98
+
99
+ end
100
+ end