dsel 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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +0 -0
- data/Gemfile +15 -0
- data/LICENSE.md +23 -0
- data/README.md +113 -0
- data/Rakefile +6 -0
- data/dsel.gemspec +22 -0
- data/lib/dsel/api/generator.rb +285 -0
- data/lib/dsel/api/node.rb +241 -0
- data/lib/dsel/api.rb +8 -0
- data/lib/dsel/dsl/mixins/environment/ivar_explorer.rb +34 -0
- data/lib/dsel/dsl/nodes/api/environment.rb +49 -0
- data/lib/dsel/dsl/nodes/api.rb +18 -0
- data/lib/dsel/dsl/nodes/api_builder/environment.rb +56 -0
- data/lib/dsel/dsl/nodes/api_builder.rb +71 -0
- data/lib/dsel/dsl/nodes/base/environment.rb +50 -0
- data/lib/dsel/dsl/nodes/base.rb +110 -0
- data/lib/dsel/dsl/nodes/direct/environment.rb +14 -0
- data/lib/dsel/dsl/nodes/direct.rb +75 -0
- data/lib/dsel/dsl/nodes/proxy/environment.rb +41 -0
- data/lib/dsel/dsl/nodes/proxy.rb +20 -0
- data/lib/dsel/dsl.rb +10 -0
- data/lib/dsel/node.rb +42 -0
- data/lib/dsel/ruby/object.rb +53 -0
- data/lib/dsel/version.rb +3 -0
- data/lib/dsel.rb +10 -0
- data/spec/dsel/api/generator_spec.rb +402 -0
- data/spec/dsel/api/node_spec.rb +328 -0
- data/spec/dsel/dsel_spec.rb +63 -0
- data/spec/dsel/dsl/nodes/api/environment.rb +208 -0
- data/spec/dsel/dsl/nodes/api_builder/environment_spec.rb +91 -0
- data/spec/dsel/dsl/nodes/api_builder_spec.rb +148 -0
- data/spec/dsel/dsl/nodes/api_spec.rb +15 -0
- data/spec/dsel/dsl/nodes/direct/environment_spec.rb +14 -0
- data/spec/dsel/dsl/nodes/direct_spec.rb +43 -0
- data/spec/dsel/dsl/nodes/proxy/environment_spec.rb +56 -0
- data/spec/dsel/dsl/nodes/proxy_spec.rb +11 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/support/factories/clean_api_spec.rb +6 -0
- data/spec/support/fixtures/mock_api.rb +4 -0
- data/spec/support/helpers/paths.rb +19 -0
- data/spec/support/lib/factory.rb +107 -0
- data/spec/support/shared/dsl/nodes/base/environment.rb +104 -0
- data/spec/support/shared/dsl/nodes/base.rb +171 -0
- data/spec/support/shared/node.rb +70 -0
- metadata +108 -0
@@ -0,0 +1,75 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
require_relative '../mixins/environment/ivar_explorer'
|
3
|
+
|
4
|
+
module DSeL
|
5
|
+
module DSL
|
6
|
+
module Nodes
|
7
|
+
|
8
|
+
class Direct < Base
|
9
|
+
require_relative 'direct/environment'
|
10
|
+
|
11
|
+
def extend_env
|
12
|
+
[
|
13
|
+
Environment,
|
14
|
+
Mixins::Environment::IvarExplorer
|
15
|
+
]
|
16
|
+
end
|
17
|
+
|
18
|
+
def reset_methods
|
19
|
+
[
|
20
|
+
:instance_variables,
|
21
|
+
:method_missing
|
22
|
+
]
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def prepare_environment
|
28
|
+
capture_subject
|
29
|
+
decorate_subject
|
30
|
+
|
31
|
+
@environment = @subject
|
32
|
+
end
|
33
|
+
|
34
|
+
def cleanup_environment
|
35
|
+
restore_subject
|
36
|
+
end
|
37
|
+
|
38
|
+
def capture_subject
|
39
|
+
@original_methods = reset_methods.map do |m|
|
40
|
+
@subject.instance_eval do
|
41
|
+
method( m ) if respond_to? m
|
42
|
+
end
|
43
|
+
end.compact
|
44
|
+
end
|
45
|
+
|
46
|
+
def decorate_subject
|
47
|
+
# We could use @subject.extend but that only works the first time.
|
48
|
+
extend_env.each do |mod|
|
49
|
+
mod.instance_methods( true ).each do |m|
|
50
|
+
@subject.instance_eval do
|
51
|
+
define_singleton_method m, mod.instance_method( m )
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def restore_subject
|
58
|
+
cmethods = @subject.methods
|
59
|
+
extend_env.each do |mod|
|
60
|
+
mod.instance_methods( true ).each do |m|
|
61
|
+
next if !cmethods.include?( m )
|
62
|
+
@subject.instance_eval( "undef :'#{m}'" )
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
@original_methods.each do |m|
|
67
|
+
@subject.define_singleton_method m.name, &m
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require_relative '../../mixins/environment/ivar_explorer'
|
2
|
+
|
3
|
+
module DSeL
|
4
|
+
module DSL
|
5
|
+
module Nodes
|
6
|
+
class Proxy
|
7
|
+
|
8
|
+
class Environment
|
9
|
+
include Base::Environment
|
10
|
+
include Mixins::Environment::IvarExplorer
|
11
|
+
|
12
|
+
define_method "#{DSEL_NODE_ACCESSOR}=" do |node|
|
13
|
+
super( node )
|
14
|
+
|
15
|
+
if node
|
16
|
+
_dsel_node.subject.public_methods( false ).each do |m|
|
17
|
+
instance_eval( "undef :'#{m}'" ) rescue nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
node
|
22
|
+
end
|
23
|
+
|
24
|
+
def method_missing( name, *args, &block )
|
25
|
+
if _dsel_node && _dsel_self.respond_to?( name )
|
26
|
+
return _dsel_self.send( name, *args, &block )
|
27
|
+
end
|
28
|
+
|
29
|
+
super( name, *args, &block )
|
30
|
+
end
|
31
|
+
|
32
|
+
def respond_to?( *args )
|
33
|
+
super( *args ) || (_dsel_node && _dsel_self.respond_to?( *args ))
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
|
3
|
+
module DSeL
|
4
|
+
module DSL
|
5
|
+
module Nodes
|
6
|
+
|
7
|
+
class Proxy < Base
|
8
|
+
require_relative 'proxy/environment'
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def prepare_environment
|
13
|
+
@environment ||= Environment.new
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/dsel/dsl.rb
ADDED
data/lib/dsel/node.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
module DSeL
|
2
|
+
class Node
|
3
|
+
|
4
|
+
# @return [Object]
|
5
|
+
attr_reader :subject
|
6
|
+
|
7
|
+
# @return [Base, nil]
|
8
|
+
attr_reader :parent
|
9
|
+
|
10
|
+
# @return [Base]
|
11
|
+
# `self` if {#root?}.
|
12
|
+
attr_reader :root
|
13
|
+
|
14
|
+
# @param [Object] subject
|
15
|
+
# @param [Hash] options
|
16
|
+
# @option options [Base, nil] :parent (nil)
|
17
|
+
def initialize( subject = nil, options = {} )
|
18
|
+
@subject = subject
|
19
|
+
@parent = options[:parent]
|
20
|
+
@root = (@parent ? @parent._dsel_node.root : self)
|
21
|
+
end
|
22
|
+
|
23
|
+
def root?
|
24
|
+
@root == self
|
25
|
+
end
|
26
|
+
|
27
|
+
# @private
|
28
|
+
def _dsel_node
|
29
|
+
self
|
30
|
+
end
|
31
|
+
|
32
|
+
def calc_node_hash( subject )
|
33
|
+
"#{self.class}:#{subject.object_id}".hash
|
34
|
+
end
|
35
|
+
|
36
|
+
def hash
|
37
|
+
calc_node_hash( @subject )
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
class Object
|
2
|
+
|
3
|
+
def as_dsel( parent = nil, &block )
|
4
|
+
_dsel_determine_node( DSeL::DSL::Nodes::Proxy, parent ).run( &block )
|
5
|
+
end
|
6
|
+
|
7
|
+
def dsel_script( script, parent = nil )
|
8
|
+
_dsel_determine_node( DSeL::DSL::Nodes::Proxy, parent ).run( script )
|
9
|
+
end
|
10
|
+
|
11
|
+
def as_direct_dsel( parent = nil, &block )
|
12
|
+
_dsel_determine_node( DSeL::DSL::Nodes::Direct, parent ).run( &block )
|
13
|
+
end
|
14
|
+
|
15
|
+
def direct_dsel_script( script, parent = nil )
|
16
|
+
_dsel_determine_node( DSeL::DSL::Nodes::Direct, parent ).run( script )
|
17
|
+
end
|
18
|
+
|
19
|
+
def DSeL( object = self, &block )
|
20
|
+
object.as_dsel( _dsel_self_if_node, &block )
|
21
|
+
end
|
22
|
+
|
23
|
+
def DSeLScript( script, object = self )
|
24
|
+
object.dsel_script( script, _dsel_self_if_node )
|
25
|
+
end
|
26
|
+
|
27
|
+
def DirectDSeL( object = self, &block )
|
28
|
+
object.as_direct_dsel( _dsel_self_if_node, &block )
|
29
|
+
end
|
30
|
+
|
31
|
+
def DirectDSeLScript( script, object = self )
|
32
|
+
object.direct_dsel_script( script, _dsel_self_if_node )
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def _dsel_self_if_node
|
38
|
+
respond_to?( DSeL::DSL::Nodes::Base::Environment::DSEL_NODE_ACCESSOR ) ? self : nil
|
39
|
+
end
|
40
|
+
|
41
|
+
def _dsel_determine_node( klass, parent = nil )
|
42
|
+
return klass.new( self ) if !parent
|
43
|
+
|
44
|
+
if parent._dsel_node.is_a?( klass )
|
45
|
+
parent._dsel_node.node_for( self )
|
46
|
+
else
|
47
|
+
node = klass.new( self, parent: parent )
|
48
|
+
parent._dsel_node.cache_node node
|
49
|
+
node
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
data/lib/dsel/version.rb
ADDED
data/lib/dsel.rb
ADDED
@@ -0,0 +1,402 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe DSeL::API::Generator do
|
4
|
+
let(:api_spec) { MockAPI }
|
5
|
+
let(:api) { api_spec.new }
|
6
|
+
let(:clean_api_spec) { Factory[:clean_api_spec] }
|
7
|
+
let(:clean_api) { clean_api_spec.new }
|
8
|
+
subject { described_class }
|
9
|
+
|
10
|
+
describe '#last_call' do
|
11
|
+
let(:last_call) { subject.last_call }
|
12
|
+
|
13
|
+
before do
|
14
|
+
api.on
|
15
|
+
api.on 2
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'returns the last call' do
|
19
|
+
expect(last_call[:node]).to be api_spec
|
20
|
+
expect(last_call[:type]).to be :on
|
21
|
+
expect(last_call[:args]).to eq [2]
|
22
|
+
end
|
23
|
+
|
24
|
+
context '#last_call_with_caller?' do
|
25
|
+
context 'true' do
|
26
|
+
before do
|
27
|
+
subject.last_call_with_caller!
|
28
|
+
api.on 3
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'includes caller information' do
|
32
|
+
expect(last_call[:caller]).to be_kind_of Array
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'false' do
|
37
|
+
before do
|
38
|
+
subject.last_call_without_caller!
|
39
|
+
api.on 3
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'does not include caller information' do
|
43
|
+
expect(last_call).to_not include :caller
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'default' do
|
48
|
+
before do
|
49
|
+
api.on 3
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'does not include caller information' do
|
53
|
+
expect(last_call).to_not include :caller
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe '#last_call_with_caller?' do
|
60
|
+
it 'returns false' do
|
61
|
+
expect(subject).to_not be_last_call_with_caller
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'when #last_call_with_caller! has been called' do
|
65
|
+
before do
|
66
|
+
subject.last_call_with_caller!
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'returns true' do
|
70
|
+
expect(subject).to be_last_call_with_caller
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe '#last_call_without_caller!' do
|
76
|
+
it 'disables tracking of last call callers' do
|
77
|
+
subject.last_call_with_caller!
|
78
|
+
expect(subject).to be_last_call_with_caller
|
79
|
+
|
80
|
+
subject.last_call_without_caller!
|
81
|
+
expect(subject).to_not be_last_call_with_caller
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe '#last_call_witt_caller!' do
|
86
|
+
it 'enables tracking of last call callers' do
|
87
|
+
subject.last_call_with_caller!
|
88
|
+
expect(subject).to be_last_call_with_caller
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe '#on_call' do
|
93
|
+
it 'sets callbacks for each call' do
|
94
|
+
calls = Hash.new
|
95
|
+
|
96
|
+
subject.on_call do |call|
|
97
|
+
(calls[:first] ||= []) << call
|
98
|
+
end
|
99
|
+
|
100
|
+
subject.on_call do |call|
|
101
|
+
(calls[:second] ||= []) << call
|
102
|
+
end
|
103
|
+
|
104
|
+
api.on 4
|
105
|
+
|
106
|
+
expect(calls[:first]).to eq calls[:second]
|
107
|
+
{
|
108
|
+
node: api_spec,
|
109
|
+
type: :on,
|
110
|
+
args: [4]
|
111
|
+
}.each do |k, v|
|
112
|
+
calls[:first].each do |call|
|
113
|
+
expect(call[k]).to eq v
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'returns self' do
|
119
|
+
expect(subject.on_call{}).to be subject.instance
|
120
|
+
end
|
121
|
+
|
122
|
+
context 'when no block is given' do
|
123
|
+
it 'raises ArgumentError' do
|
124
|
+
expect do
|
125
|
+
subject.on_call
|
126
|
+
end.to raise_error ArgumentError
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe '#call_object_hasher=' do
|
132
|
+
before do
|
133
|
+
subject.define_definers( clean_api_spec, :on )
|
134
|
+
end
|
135
|
+
|
136
|
+
context 'nil' do
|
137
|
+
before do
|
138
|
+
subject.call_object_hasher = nil
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'uses #hash' do
|
142
|
+
o = Object.new
|
143
|
+
expect(o).to receive(:hash).and_return(1)
|
144
|
+
|
145
|
+
called = false
|
146
|
+
subject.define_call_handler clean_api_spec, :on, o do |*a, &block|
|
147
|
+
called = true
|
148
|
+
end
|
149
|
+
|
150
|
+
o2 = Object.new
|
151
|
+
expect(o2).to receive(:hash).and_return(1)
|
152
|
+
|
153
|
+
clean_api.on o2
|
154
|
+
expect(called).to be_truthy
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'treats strings as case-insensitive' do
|
158
|
+
o = 'StFuFf'
|
159
|
+
|
160
|
+
called = false
|
161
|
+
subject.define_call_handler clean_api_spec, :on, o do |*a, &block|
|
162
|
+
called = true
|
163
|
+
end
|
164
|
+
|
165
|
+
clean_api.on o.downcase
|
166
|
+
expect(called).to be_truthy
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
context 'Symbol' do
|
171
|
+
before do
|
172
|
+
subject.call_object_hasher = :object_id
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'uses it as a method on the object' do
|
176
|
+
o = Object.new
|
177
|
+
|
178
|
+
called = false
|
179
|
+
subject.define_call_handler clean_api_spec, :on, o do |*a, &block|
|
180
|
+
called = true
|
181
|
+
end
|
182
|
+
|
183
|
+
expect do
|
184
|
+
clean_api.on Object.new
|
185
|
+
end.to raise_error NoMethodError
|
186
|
+
|
187
|
+
clean_api.on o
|
188
|
+
expect(called).to be_truthy
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
context '#call' do
|
193
|
+
before do
|
194
|
+
subject.call_object_hasher = proc do |o|
|
195
|
+
o.hash
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
it 'passes the object to it' do
|
200
|
+
o = Object.new
|
201
|
+
expect(o).to receive(:hash).and_return(1)
|
202
|
+
|
203
|
+
called = false
|
204
|
+
subject.define_call_handler clean_api_spec, :on, o do |*a, &block|
|
205
|
+
called = true
|
206
|
+
end
|
207
|
+
|
208
|
+
o2 = Object.new
|
209
|
+
expect(o2).to receive(:hash).and_return(1)
|
210
|
+
|
211
|
+
clean_api.on o2
|
212
|
+
expect(called).to be_truthy
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
context 'other' do
|
217
|
+
it 'raises ArgumentError' do
|
218
|
+
expect do
|
219
|
+
subject.call_object_hasher = 'stuff'
|
220
|
+
end.to raise_error ArgumentError
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
context 'when the return value is not an Integer' do
|
225
|
+
before do
|
226
|
+
subject.call_object_hasher = :to_s
|
227
|
+
end
|
228
|
+
|
229
|
+
it 'raises ArgumentError' do
|
230
|
+
o = Object.new
|
231
|
+
|
232
|
+
expect do
|
233
|
+
subject.define_call_handler( clean_api_spec, :on, o ){}
|
234
|
+
end.to raise_error ArgumentError
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
describe '#define_definers' do
|
240
|
+
it 'defines the given definers on the given node' do
|
241
|
+
subject.define_definers( clean_api_spec, :on, :after )
|
242
|
+
|
243
|
+
expect(clean_api_spec.definers).to eq [
|
244
|
+
{ type: :on, method: :def_on },
|
245
|
+
{ type: :after, method: :def_after }
|
246
|
+
]
|
247
|
+
|
248
|
+
expect(clean_api_spec).to respond_to :def_on
|
249
|
+
expect(clean_api_spec).to respond_to :def_after
|
250
|
+
end
|
251
|
+
|
252
|
+
context 'when a definer already exists' do
|
253
|
+
it 'raises NameError' do
|
254
|
+
subject.define_definers( clean_api_spec, :on )
|
255
|
+
|
256
|
+
expect do
|
257
|
+
subject.define_definers( clean_api_spec, :on )
|
258
|
+
end.to raise_error NameError
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
context 'when a definer is given more than 2 objects' do
|
263
|
+
it 'raises ArgumentError' do
|
264
|
+
subject.define_definers( clean_api_spec, :on )
|
265
|
+
|
266
|
+
expect do
|
267
|
+
clean_api_spec.def_on :stuff, :stuff2 do
|
268
|
+
|
269
|
+
end
|
270
|
+
end.to raise_error ArgumentError
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
describe '#define_call_handler' do
|
276
|
+
before do
|
277
|
+
subject.define_definers( clean_api_spec, :on, :after )
|
278
|
+
end
|
279
|
+
|
280
|
+
it 'defines a handler for the given type and object' do
|
281
|
+
on_args = []
|
282
|
+
subject.define_call_handler clean_api_spec, :on, :stuff do |*a, &block|
|
283
|
+
on_args << [a, block]
|
284
|
+
end
|
285
|
+
|
286
|
+
after_args = []
|
287
|
+
subject.define_call_handler clean_api_spec, :after, :stuff do |*a, &block|
|
288
|
+
after_args << [a, block]
|
289
|
+
end
|
290
|
+
|
291
|
+
b1 = proc{}
|
292
|
+
clean_api.on :stuff, 1, &b1
|
293
|
+
|
294
|
+
b2 = proc{}
|
295
|
+
clean_api.after :stuff, 2, &b2
|
296
|
+
|
297
|
+
expect(on_args).to eq [[[1], b1]]
|
298
|
+
expect(after_args).to eq [[[2], b2]]
|
299
|
+
end
|
300
|
+
|
301
|
+
it 'enforces argument arity' do
|
302
|
+
subject.define_call_handler clean_api_spec, :on, :none do
|
303
|
+
end
|
304
|
+
|
305
|
+
expect do
|
306
|
+
clean_api.on :none
|
307
|
+
end.to_not raise_error
|
308
|
+
|
309
|
+
expect do
|
310
|
+
clean_api.on :none, 1
|
311
|
+
end.to raise_error ArgumentError
|
312
|
+
|
313
|
+
|
314
|
+
subject.define_call_handler clean_api_spec, :on, :one do |x|
|
315
|
+
end
|
316
|
+
|
317
|
+
expect do
|
318
|
+
clean_api.on :one, 1
|
319
|
+
end.to_not raise_error
|
320
|
+
|
321
|
+
expect do
|
322
|
+
clean_api.on :one
|
323
|
+
end.to raise_error ArgumentError
|
324
|
+
|
325
|
+
expect do
|
326
|
+
clean_api.on :one, 1, 2
|
327
|
+
end.to raise_error ArgumentError
|
328
|
+
|
329
|
+
|
330
|
+
subject.define_call_handler clean_api_spec, :on, :two do |x, y|
|
331
|
+
end
|
332
|
+
|
333
|
+
expect do
|
334
|
+
clean_api.on :two, 1, 2
|
335
|
+
end.to_not raise_error
|
336
|
+
|
337
|
+
expect do
|
338
|
+
clean_api.on :two
|
339
|
+
end.to raise_error ArgumentError
|
340
|
+
|
341
|
+
expect do
|
342
|
+
clean_api.on :two, 1
|
343
|
+
end.to raise_error ArgumentError
|
344
|
+
|
345
|
+
expect do
|
346
|
+
clean_api.on :two, 1, 2, 3
|
347
|
+
end.to raise_error ArgumentError
|
348
|
+
|
349
|
+
|
350
|
+
subject.define_call_handler clean_api_spec, :on, :var do |*args|
|
351
|
+
end
|
352
|
+
|
353
|
+
expect do
|
354
|
+
clean_api.on :var
|
355
|
+
end.to_not raise_error
|
356
|
+
|
357
|
+
expect do
|
358
|
+
clean_api.on :var, 1
|
359
|
+
end.to_not raise_error
|
360
|
+
end
|
361
|
+
|
362
|
+
context 'when object is' do
|
363
|
+
context 'nil' do
|
364
|
+
it 'is treated as an object' do
|
365
|
+
args = []
|
366
|
+
subject.define_call_handler clean_api_spec, :on, nil do |*a|
|
367
|
+
args << a
|
368
|
+
end
|
369
|
+
|
370
|
+
expect do
|
371
|
+
clean_api.on
|
372
|
+
end.to raise_error NoMethodError
|
373
|
+
|
374
|
+
clean_api.on nil, :stuff
|
375
|
+
|
376
|
+
expect(args).to eq [[:stuff]]
|
377
|
+
end
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
381
|
+
context 'when no object is given' do
|
382
|
+
it 'is treated as a catch-call' do
|
383
|
+
args = []
|
384
|
+
subject.define_call_handler clean_api_spec, :on do |*a|
|
385
|
+
args << a
|
386
|
+
end
|
387
|
+
|
388
|
+
subject.define_call_handler clean_api_spec, :on, :something do |*a|
|
389
|
+
end
|
390
|
+
|
391
|
+
clean_api.on
|
392
|
+
clean_api.on nil
|
393
|
+
clean_api.on [:stuff]
|
394
|
+
clean_api.on :stuff2, { mode: :stuff }
|
395
|
+
|
396
|
+
clean_api.on :something
|
397
|
+
|
398
|
+
expect(args).to eq [[], [nil], [[:stuff]], [:stuff2, { mode: :stuff }]]
|
399
|
+
end
|
400
|
+
end
|
401
|
+
end
|
402
|
+
end
|