data-provider 0.1.0 → 0.2.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 +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +2 -2
- data/data-provider.gemspec +2 -5
- data/lib/data_provider/base.rb +149 -146
- data/lib/data_provider/container.rb +277 -0
- data/lib/data_provider.rb +1 -0
- data/spec/base_spec.rb +818 -0
- data/spec/container_spec.rb +792 -0
- data/spec/data_provider_spec.rb +85 -349
- metadata +4 -1
data/lib/data_provider.rb
CHANGED
data/spec/base_spec.rb
ADDED
@@ -0,0 +1,818 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe DataProvider::Base do
|
4
|
+
# Example implementation of DataProvider::Base
|
5
|
+
class ProviderClass
|
6
|
+
include DataProvider::Base
|
7
|
+
|
8
|
+
provider :sum, :requires => [:array] do
|
9
|
+
sum = 0
|
10
|
+
|
11
|
+
given(:array).each do |number|
|
12
|
+
sum += number.to_i
|
13
|
+
end
|
14
|
+
|
15
|
+
sum
|
16
|
+
end
|
17
|
+
|
18
|
+
provider :static do
|
19
|
+
'StaticValue'
|
20
|
+
end
|
21
|
+
|
22
|
+
provider :billy do
|
23
|
+
take([:identification, :fullname])
|
24
|
+
end
|
25
|
+
|
26
|
+
provider [:identification, :firstname] do
|
27
|
+
'Billy'
|
28
|
+
end
|
29
|
+
|
30
|
+
provider [:identification, :lastname] do
|
31
|
+
'Bragg'
|
32
|
+
end
|
33
|
+
|
34
|
+
provider [:identification, :fullname] do
|
35
|
+
"#{scoped_take(:firstname)} #{scoped_take(:lastname)}"
|
36
|
+
end
|
37
|
+
|
38
|
+
provider [:identification, :identifier] do
|
39
|
+
take(:firstname)
|
40
|
+
end
|
41
|
+
|
42
|
+
provider :fullname do
|
43
|
+
'Stephen William Bragg'
|
44
|
+
end
|
45
|
+
|
46
|
+
provider [:identification, :id] do
|
47
|
+
take(:fullname)
|
48
|
+
end
|
49
|
+
|
50
|
+
provider [:identification, :ID] do
|
51
|
+
take(:id)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
let(:provider){
|
56
|
+
ProviderClass.new(:data => {:array => [1,2,4]})
|
57
|
+
}
|
58
|
+
|
59
|
+
describe "Class level" do
|
60
|
+
describe "#has_provider?" do
|
61
|
+
it 'tells if the specified provider exists' do
|
62
|
+
expect(ProviderClass.respond_to?(:has_provider?)).to eq true
|
63
|
+
expect(ProviderClass.has_provider?(:sum)).to eq true
|
64
|
+
expect(ProviderClass.has_provider?(:divid)).to eq false
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "#has_providers_with_scope?" do
|
69
|
+
let(:klass){
|
70
|
+
Class.new Object do
|
71
|
+
include DataProvider::Base
|
72
|
+
provider [:a, :b ,:c]
|
73
|
+
provider :unscoped
|
74
|
+
end
|
75
|
+
}
|
76
|
+
|
77
|
+
it "return true if there are providers defined with an array identifier that start with the given prefix" do
|
78
|
+
expect(klass.has_providers_with_scope?(:unscoped)).to eq false
|
79
|
+
expect(klass.has_providers_with_scope?(:a)).to eq true
|
80
|
+
expect(klass.has_providers_with_scope?([:a, :b])).to eq true
|
81
|
+
# scope means prefix, identfier may not be exactly the given array
|
82
|
+
expect(klass.has_providers_with_scope?([:a, :b, :c])).to eq false
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe "#provides" do
|
87
|
+
class SimpleProviders
|
88
|
+
include DataProvider::Base
|
89
|
+
provides({
|
90
|
+
:name => 'Paddy',
|
91
|
+
'instrument' => :bass,
|
92
|
+
})
|
93
|
+
end
|
94
|
+
|
95
|
+
it "lets you request all currently available simple providers when called without a parameter" do
|
96
|
+
expect(SimpleProviders.provides).to eq({
|
97
|
+
:name => 'Paddy',
|
98
|
+
'instrument' => :bass
|
99
|
+
})
|
100
|
+
end
|
101
|
+
|
102
|
+
it "lets you define simple providers" do
|
103
|
+
expect(SimpleProviders.new.take(:name)).to eq 'Paddy'
|
104
|
+
expect(SimpleProviders.new.take('instrument')).to eq :bass
|
105
|
+
end
|
106
|
+
|
107
|
+
it "works with has_provider?" do
|
108
|
+
expect(SimpleProviders.has_provider?(:name)).to eq true
|
109
|
+
expect(SimpleProviders.new.has_provider?('name')).to eq false
|
110
|
+
expect(SimpleProviders.has_provider?('instrument')).to eq true
|
111
|
+
expect(SimpleProviders.new.has_provider?(:instrument)).to eq false
|
112
|
+
end
|
113
|
+
|
114
|
+
it "lets you overwrite existing simple providers" do
|
115
|
+
SimpleProviders.provides({:name => 'Erik'})
|
116
|
+
expect(SimpleProviders.new.take(:name)).to eq 'Erik'
|
117
|
+
end
|
118
|
+
|
119
|
+
it "lets you write linked notation" do
|
120
|
+
expect(SimpleProviders.provides({:name => 'Lane'}).new.take(:name)).to eq 'Lane'
|
121
|
+
end
|
122
|
+
|
123
|
+
it "works with lambdas" do
|
124
|
+
expect(SimpleProviders.provides(:name => lambda{ 'Patrick' }).new.take(:name)).to eq 'Patrick'
|
125
|
+
end
|
126
|
+
|
127
|
+
it "works with Procs" do
|
128
|
+
expect(SimpleProviders.provides(:name => Proc.new{ 'St. Patrick' }).new.take(:name)).to eq 'St. Patrick'
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
describe "#add" do
|
133
|
+
module OddProviders
|
134
|
+
include DataProvider::Base
|
135
|
+
provides({1 => 'one'})
|
136
|
+
provider :three do 3 end
|
137
|
+
end
|
138
|
+
|
139
|
+
module OddOverwriteProviders
|
140
|
+
include DataProvider::Base
|
141
|
+
provides({1 => 'Uno', :five => 555})
|
142
|
+
provider :three do :tres end
|
143
|
+
end
|
144
|
+
|
145
|
+
class BasicProviders
|
146
|
+
include DataProvider::Base
|
147
|
+
provides({2 => '1'})
|
148
|
+
provider :four do '4' end
|
149
|
+
add OddProviders
|
150
|
+
end
|
151
|
+
|
152
|
+
it "lets you add providers from another module" do
|
153
|
+
expect(BasicProviders.has_provider?(1)).to eq true
|
154
|
+
expect(BasicProviders.has_provider?(2)).to eq true
|
155
|
+
expect(BasicProviders.has_provider?(:three)).to eq true
|
156
|
+
expect(BasicProviders.has_provider?(:four)).to eq true
|
157
|
+
# expect(BasicProviders.new.take(1)).to eq 'one'
|
158
|
+
expect(BasicProviders.new.take(:three)).to eq 3
|
159
|
+
end
|
160
|
+
|
161
|
+
it "lets you add providers from another module at runtime" do
|
162
|
+
expect(BasicProviders.has_provider?(:five)).to eq false
|
163
|
+
BasicProviders.add(OddOverwriteProviders)
|
164
|
+
expect(BasicProviders.has_provider?(:five)).to eq true
|
165
|
+
end
|
166
|
+
|
167
|
+
# for the following test the providers of OddOverwriteProviders
|
168
|
+
# have already been added (by the previous test)
|
169
|
+
it "lets overwrite providers" do
|
170
|
+
expect(BasicProviders.new.take(1)).to eq 'Uno'
|
171
|
+
expect(BasicProviders.new.take(:three)).to eq :tres
|
172
|
+
end
|
173
|
+
|
174
|
+
it "includes providers which can be overwritten" do
|
175
|
+
klass = Class.new(Object) do
|
176
|
+
include DataProvider::Base
|
177
|
+
add OddProviders
|
178
|
+
provider :three do '33' end
|
179
|
+
end
|
180
|
+
|
181
|
+
expect(klass.new.take(:three)).to eq '33'
|
182
|
+
end
|
183
|
+
|
184
|
+
it "can be used in modules, latest provider always overwrites the previous" do
|
185
|
+
m1 = Module.new do
|
186
|
+
include DataProvider::Base
|
187
|
+
|
188
|
+
# this provider should get overwritten by the m2 version
|
189
|
+
provider :aa do 'aa1' end
|
190
|
+
end
|
191
|
+
|
192
|
+
m2 = Module.new do
|
193
|
+
include DataProvider::Base
|
194
|
+
add m1
|
195
|
+
|
196
|
+
# this provider should overwrite the m1 version
|
197
|
+
provider :aa do 'aa2' end
|
198
|
+
end
|
199
|
+
|
200
|
+
c = Class.new(Object) do
|
201
|
+
include DataProvider::Base
|
202
|
+
|
203
|
+
# this provider gets overwritten when we do the add call below
|
204
|
+
provider :aa do 'aa3' end
|
205
|
+
|
206
|
+
add m2
|
207
|
+
end
|
208
|
+
|
209
|
+
expect(c.new.take(:aa)).to eq 'aa2'
|
210
|
+
end
|
211
|
+
|
212
|
+
it "includes a module as well, so normal methods are added as well" do
|
213
|
+
m = Module.new do
|
214
|
+
include DataProvider::Base
|
215
|
+
provider :mprovider do mfunc end
|
216
|
+
def mfunc
|
217
|
+
'Methodized!'
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
c = Class.new(Object) do
|
222
|
+
include DataProvider::Base
|
223
|
+
add m
|
224
|
+
|
225
|
+
def cfunc1
|
226
|
+
take(:cprovider)
|
227
|
+
end
|
228
|
+
|
229
|
+
provider :cprovider do cfunc2 end
|
230
|
+
|
231
|
+
def cfunc2
|
232
|
+
take :mprovider
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
expect(c.new.cfunc1).to eq 'Methodized!'
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
describe "#add_scoped" do
|
241
|
+
module ChildProviders
|
242
|
+
include DataProvider::Base
|
243
|
+
provider :name do "child" end
|
244
|
+
end
|
245
|
+
|
246
|
+
module GrandchildProviders
|
247
|
+
include DataProvider::Base
|
248
|
+
provider :name do "grandchild" end
|
249
|
+
provider [:age] do 1 end
|
250
|
+
provides({
|
251
|
+
:mommy => 'Wilma',
|
252
|
+
:daddy => 'Fret'
|
253
|
+
})
|
254
|
+
|
255
|
+
provider :mobility do
|
256
|
+
'crawling'
|
257
|
+
end
|
258
|
+
|
259
|
+
provider :movement do
|
260
|
+
take(:mobility)
|
261
|
+
end
|
262
|
+
|
263
|
+
provider :symbol do
|
264
|
+
'Symbol provider'
|
265
|
+
end
|
266
|
+
|
267
|
+
provider :sym do
|
268
|
+
take(:symbol)
|
269
|
+
end
|
270
|
+
|
271
|
+
provider ['string'] do
|
272
|
+
'String provider: ' + take(:symbol)
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
class ProviderKlass
|
277
|
+
include DataProvider::Base
|
278
|
+
provider :parent do 'parent' end
|
279
|
+
add_scoped ChildProviders, :scope => :child
|
280
|
+
add_scoped GrandchildProviders, :scope => [:child, :child]
|
281
|
+
end
|
282
|
+
|
283
|
+
it 'let you array-prefix the providers of an included module' do
|
284
|
+
expect(ProviderKlass.has_provider?(:parent)).to eq true
|
285
|
+
expect(ProviderKlass.has_provider?(:name)).to eq false
|
286
|
+
expect(ProviderKlass.has_provider?([:child, :name])).to eq true
|
287
|
+
expect(ProviderKlass.has_provider?([:child, :age])).to eq false
|
288
|
+
expect(ProviderKlass.has_provider?([:child, :child, :name])).to eq true
|
289
|
+
expect(ProviderKlass.has_provider?([:child, :child, :age])).to eq true
|
290
|
+
expect(ProviderKlass.has_provider?([:child, :child, :mommy])).to eq true
|
291
|
+
expect(ProviderKlass.has_provider?([:child, :child, :daddy])).to eq true
|
292
|
+
expect(ProviderKlass.new.take([:child, :name])).to eq 'child'
|
293
|
+
expect(ProviderKlass.new.take([:child, :child, :name])).to eq 'grandchild'
|
294
|
+
expect(ProviderKlass.new.take([:child, :child, :age])).to eq 1
|
295
|
+
expect(ProviderKlass.new.take([:child, :child, :mommy])).to eq 'Wilma'
|
296
|
+
expect(ProviderKlass.new.take([:child, :child, :daddy])).to eq 'Fret'
|
297
|
+
end
|
298
|
+
|
299
|
+
it "#take acts like #scoped_take inside providers works for add_scoped modules as well" do
|
300
|
+
expect( ProviderKlass.new.take([:child, :child, :mobility]) ).to eq 'crawling'
|
301
|
+
expect( ProviderKlass.new.take([:child, :child, :movement]) ).to eq 'crawling'
|
302
|
+
end
|
303
|
+
|
304
|
+
it "doesn't act up when mixing symbols and strings in array identifiers" do
|
305
|
+
expect( ProviderKlass.new.take([:child, :child, 'string']) ).to eq 'String provider: Symbol provider'
|
306
|
+
end
|
307
|
+
|
308
|
+
it "lets #take act like #scoped_take recursively" do
|
309
|
+
expect( ProviderKlass.new.take([:child, :child, :sym]) ).to eq 'Symbol provider'
|
310
|
+
end
|
311
|
+
|
312
|
+
it 'respect provider order/priority' do
|
313
|
+
m1 = Module.new do
|
314
|
+
include DataProvider::Base
|
315
|
+
provider 'version' do 1 end
|
316
|
+
end
|
317
|
+
|
318
|
+
m2 = Module.new do
|
319
|
+
include DataProvider::Base
|
320
|
+
add m1
|
321
|
+
provider 'version' do 2 end
|
322
|
+
end
|
323
|
+
|
324
|
+
c = Class.new(Object) do
|
325
|
+
include DataProvider::Base
|
326
|
+
provider 'version' do 0 end
|
327
|
+
provider ['module', 'version'] do -1 end
|
328
|
+
add_scoped m2, :scope => 'module'
|
329
|
+
end
|
330
|
+
|
331
|
+
expect(c.new.try_take('version')).to eq 0
|
332
|
+
expect(c.new.try_take(['module', 'version'])).to eq 2
|
333
|
+
end
|
334
|
+
|
335
|
+
it 'works recursively' do
|
336
|
+
m1 = Module.new do
|
337
|
+
include DataProvider::Base
|
338
|
+
provider ['name'] do 'Johnny Blaze' end
|
339
|
+
end
|
340
|
+
|
341
|
+
expect(m1.provider_identifiers).to eq [['name']]
|
342
|
+
|
343
|
+
m2 = Module.new do
|
344
|
+
include DataProvider::Base
|
345
|
+
# this next line adds the provider ['name'] to m2
|
346
|
+
add m1
|
347
|
+
end
|
348
|
+
|
349
|
+
expect(m2.provider_identifiers).to eq [['name']]
|
350
|
+
|
351
|
+
m3 = Module.new do
|
352
|
+
include DataProvider::Base
|
353
|
+
# this provider will end up like ['creatures', 'name'] in c1
|
354
|
+
provider ['name'] do 'Mr. Nobody' end
|
355
|
+
# the next line adds the provider ['person', 'name'] to m3
|
356
|
+
add_scoped m2, :scope => 'person'
|
357
|
+
end
|
358
|
+
|
359
|
+
# providers are internally added in reverse order
|
360
|
+
expect(m3.provider_identifiers).to eq [['person', 'name'], ['name']]
|
361
|
+
|
362
|
+
c1 = Class.new(Object) do
|
363
|
+
include DataProvider::Base
|
364
|
+
# the next line will add the provides ['creatures', 'name'] and ['creatures', 'person', 'name']
|
365
|
+
add_scoped m3, :scope => 'creatures'
|
366
|
+
end
|
367
|
+
|
368
|
+
expect(c1.has_provider?('name')).to eq false
|
369
|
+
expect(c1.has_provider?(['name'])).to eq false
|
370
|
+
expect(c1.has_provider?(['person', 'name'])).to eq false
|
371
|
+
expect(c1.has_provider?(['creatures', 'person', 'name'])).to eq true
|
372
|
+
expect(c1.new.take(['creatures', 'person', 'name'])).to eq 'Johnny Blaze'
|
373
|
+
end
|
374
|
+
|
375
|
+
it "doesn't affect the added module" do
|
376
|
+
m1 = Module.new do
|
377
|
+
include DataProvider::Base
|
378
|
+
provider ['name'] do 'Johnny Blaze' end
|
379
|
+
end
|
380
|
+
|
381
|
+
expect(m1.provider_identifiers).to eq [['name']]
|
382
|
+
|
383
|
+
c1 = Class.new(Object) do
|
384
|
+
include DataProvider::Base
|
385
|
+
add_scoped m1, :scope => 'prefix'
|
386
|
+
end
|
387
|
+
|
388
|
+
expect(m1.provider_identifiers).to eq [['name']]
|
389
|
+
end
|
390
|
+
end
|
391
|
+
|
392
|
+
describe "provider_missing" do
|
393
|
+
it "lets you define a default fallback provider" do
|
394
|
+
klass = Class.new Object do
|
395
|
+
include DataProvider::Base
|
396
|
+
provider_missing do
|
397
|
+
"This provider don't exist!"
|
398
|
+
end
|
399
|
+
end
|
400
|
+
|
401
|
+
expect(klass.has_provider?(:message)).to eq false
|
402
|
+
expect(klass.new.take(:message)).to eq "This provider don't exist!"
|
403
|
+
end
|
404
|
+
|
405
|
+
it "provides the missing provider id through the private missing_provider method" do
|
406
|
+
klass = Class.new Object do
|
407
|
+
include DataProvider::Base
|
408
|
+
provider_missing do
|
409
|
+
"Missing #{missing_provider}"
|
410
|
+
end
|
411
|
+
end
|
412
|
+
|
413
|
+
expect(klass.new.take(:something)).to eq 'Missing something'
|
414
|
+
expect{klass.new.missing_provider}.to raise_error(NoMethodError)
|
415
|
+
end
|
416
|
+
|
417
|
+
it 'calls the fallback provider when using try_take with an unknown provider' do
|
418
|
+
klass = Class.new Object do
|
419
|
+
include DataProvider::Base
|
420
|
+
provider_missing do
|
421
|
+
"fallback_#{missing_provider}"
|
422
|
+
end
|
423
|
+
end
|
424
|
+
|
425
|
+
expect(klass.new.try_take(:cool)).to eq 'fallback_cool'
|
426
|
+
end
|
427
|
+
end
|
428
|
+
|
429
|
+
describe "fallback_provider?" do
|
430
|
+
it "lets you know if a fallback provider has been registered" do
|
431
|
+
klass = Class.new Object do
|
432
|
+
include DataProvider::Base
|
433
|
+
end
|
434
|
+
|
435
|
+
expect(klass.fallback_provider?).to eq false
|
436
|
+
|
437
|
+
klass.provider_missing do
|
438
|
+
"New fallback!"
|
439
|
+
end
|
440
|
+
|
441
|
+
expect(klass.fallback_provider?).to eq true
|
442
|
+
end
|
443
|
+
end
|
444
|
+
end
|
445
|
+
|
446
|
+
describe "Instance level" do
|
447
|
+
describe "#has_provider?" do
|
448
|
+
it 'tells if the instance knows the specified provider' do
|
449
|
+
expect(provider.has_provider?(:sum)).to be true
|
450
|
+
expect(provider.has_provider?(:static)).to be true
|
451
|
+
expect(provider.has_provider?(:modulus)).to be false
|
452
|
+
end
|
453
|
+
end
|
454
|
+
|
455
|
+
describe "#has_providers_with_scope?" do
|
456
|
+
let(:klass){
|
457
|
+
Class.new Object do
|
458
|
+
include DataProvider::Base
|
459
|
+
provider [:a, :b ,:c]
|
460
|
+
provider :unscoped
|
461
|
+
end
|
462
|
+
}
|
463
|
+
|
464
|
+
it "return true if there are providers defined with an array identifier that start with the given prefix" do
|
465
|
+
expect(klass.new.has_providers_with_scope?(:unscoped)).to eq false
|
466
|
+
expect(klass.new.has_providers_with_scope?(:a)).to eq true
|
467
|
+
expect(klass.new.has_providers_with_scope?([:a, :b])).to eq true
|
468
|
+
# scope means prefix, identfier may not be exactly the given array
|
469
|
+
expect(klass.new.has_providers_with_scope?([:a, :b, :c])).to eq false
|
470
|
+
end
|
471
|
+
end
|
472
|
+
|
473
|
+
describe "#take" do
|
474
|
+
it 'lets you take data from a data provider instance' do
|
475
|
+
expect(provider.take(:sum)).to eq 7
|
476
|
+
expect(provider.take(:static)).to eq 'StaticValue'
|
477
|
+
end
|
478
|
+
|
479
|
+
it 'raise a ProviderMissingException when attempting to take from unknown provider' do
|
480
|
+
expect{provider.take(:unknown)}.to raise_error(DataProvider::ProviderMissingException)
|
481
|
+
expect{provider.take([:identification, :foo])}.to raise_error(DataProvider::ProviderMissingException)
|
482
|
+
end
|
483
|
+
|
484
|
+
it 'works from within a provider block' do
|
485
|
+
expect(provider.take(:billy)).to eq 'Billy Bragg'
|
486
|
+
end
|
487
|
+
|
488
|
+
it "acts like #scoped_take when used inside a provider and the specified provider isn't available" do
|
489
|
+
expect(provider.take([:identification, :id])).to eq 'Stephen William Bragg'
|
490
|
+
expect(provider.take([:identification, :identifier])).to eq 'Billy'
|
491
|
+
end
|
492
|
+
|
493
|
+
it "can act like #scoped_take recursively" do
|
494
|
+
expect(provider.take([:identification, :ID])).to eq 'Stephen William Bragg'
|
495
|
+
end
|
496
|
+
|
497
|
+
it "executes providers with the Base-class instance as scope" do
|
498
|
+
klass = Class.new(Object) do
|
499
|
+
include DataProvider::Base
|
500
|
+
provider :klasss do self.class end
|
501
|
+
end
|
502
|
+
|
503
|
+
instance = klass.new
|
504
|
+
expect(instance.take(:klasss)).to eq klass
|
505
|
+
end
|
506
|
+
end
|
507
|
+
|
508
|
+
describe "#try_take" do
|
509
|
+
it "acts like #take when the specified provider is present" do
|
510
|
+
expect(provider.try_take(:sum)).to eq 7
|
511
|
+
end
|
512
|
+
|
513
|
+
it "returns nil when the specified provider is not found" do
|
514
|
+
expect(provider.try_take(:square_root)).to eq nil
|
515
|
+
end
|
516
|
+
|
517
|
+
it "executes providers with the Base-class instance as scope" do
|
518
|
+
klass = Class.new(Object) do
|
519
|
+
include DataProvider::Base
|
520
|
+
provider :klasss do self.class end
|
521
|
+
end
|
522
|
+
|
523
|
+
instance = klass.new
|
524
|
+
expect(instance.try_take(:klasss)).to eq klass
|
525
|
+
end
|
526
|
+
end
|
527
|
+
|
528
|
+
describe "#scope" do
|
529
|
+
let(:klass){
|
530
|
+
Class.new Object do
|
531
|
+
include DataProvider::Base
|
532
|
+
provider [:a, :b] do
|
533
|
+
'woeha!'
|
534
|
+
end
|
535
|
+
provider [:a, :b ,:c] do
|
536
|
+
scope
|
537
|
+
end
|
538
|
+
|
539
|
+
provider [:a, :b ,:eq] do
|
540
|
+
take scope
|
541
|
+
end
|
542
|
+
end
|
543
|
+
}
|
544
|
+
|
545
|
+
it 'gives providers the current scope' do
|
546
|
+
expect(klass.new.take([:a,:b,:c])).to eq [:a,:b]
|
547
|
+
end
|
548
|
+
|
549
|
+
it "can be used by providers to call the 'parent provider'" do
|
550
|
+
expect(klass.new.take([:a,:b,:eq])).to eq klass.new.take([:a,:b])
|
551
|
+
end
|
552
|
+
end
|
553
|
+
|
554
|
+
describe "#scoped_take" do
|
555
|
+
it 'lets a provider call providers within its own scope' do
|
556
|
+
expect(provider.take([:identification, :fullname])).to eq 'Billy Bragg'
|
557
|
+
end
|
558
|
+
# it 'lets attribute providers'
|
559
|
+
end
|
560
|
+
|
561
|
+
describe "#give" do
|
562
|
+
it "lets you give data, creating a new data provider instance" do
|
563
|
+
updated_provider = provider.give :array => [1,80]
|
564
|
+
expect(provider.take(:sum)).to eq 7
|
565
|
+
expect(updated_provider.take(:sum)).to eq 81
|
566
|
+
end
|
567
|
+
|
568
|
+
it "returns an instance of its own class" do
|
569
|
+
expect(provider.give(:what => :ever).class).to eq provider.class
|
570
|
+
end
|
571
|
+
|
572
|
+
it "allows for linked notation" do
|
573
|
+
expect(provider.give(:array => [7, -3]).take(:sum)).to eq 4
|
574
|
+
end
|
575
|
+
|
576
|
+
it "has an add_scope alias" do
|
577
|
+
expect(provider.add_scope(:array => [400, 20]).take(:sum)).to eq 420
|
578
|
+
end
|
579
|
+
|
580
|
+
it "has an add_data alias" do
|
581
|
+
expect(provider.add_data(:array => [400, 20]).take(:sum)).to eq 420
|
582
|
+
end
|
583
|
+
end
|
584
|
+
|
585
|
+
describe "#give!" do
|
586
|
+
it "lets you update the current provider with additional data" do
|
587
|
+
prov = ProviderClass.new(:data => {:array => [1,1,90]})
|
588
|
+
expect(prov.take(:sum)).to eq 92
|
589
|
+
prov.give!(:array => [3,90])
|
590
|
+
expect(prov.take(:sum)).to eq 93
|
591
|
+
end
|
592
|
+
|
593
|
+
it "returns self" do
|
594
|
+
expect(provider.give!(:some => 'thing')).to be provider
|
595
|
+
end
|
596
|
+
|
597
|
+
it "allows for linked notation" do
|
598
|
+
expect(provider.give.give!(:array => [-1, -4]).take(:sum)).to eq -5
|
599
|
+
end
|
600
|
+
|
601
|
+
it "has an add_scope! alias" do
|
602
|
+
newprovider = provider.add_scope
|
603
|
+
newprovider.add_scope!(:array => [-1, -4])
|
604
|
+
expect(newprovider.given(:array)).to eq [-1,-4]
|
605
|
+
expect(newprovider.take(:sum)).to eq -5
|
606
|
+
end
|
607
|
+
|
608
|
+
it "has an add_data! alias" do
|
609
|
+
scoped_provider = provider.add_data(:array => []).add_data!(:array => [5, 5])
|
610
|
+
expect(scoped_provider.get_data(:array)).to eq [5,5]
|
611
|
+
expect(scoped_provider.take(:sum)).to eq 10
|
612
|
+
end
|
613
|
+
end
|
614
|
+
|
615
|
+
describe '#got?' do
|
616
|
+
it "returns if the specified piece of data is given" do
|
617
|
+
obj = ProviderClass.new(:data => {:name => 'John'})
|
618
|
+
expect( obj.got?(:lastname) ).to be false
|
619
|
+
expect( obj.got?(:name) ).to be true
|
620
|
+
expect( obj.give(:lastname => 'Doe').got?(:lastname) ).to be true
|
621
|
+
end
|
622
|
+
|
623
|
+
it "has an 'has_data?' alias" do
|
624
|
+
obj = ProviderClass.new(:data => {:name => 'John'})
|
625
|
+
expect( obj.has_data?(:lastname) ).to be false
|
626
|
+
expect( obj.has_data?(:name) ).to be true
|
627
|
+
expect( obj.add_data(:lastname => 'Doe').has_data?(:lastname) ).to be true
|
628
|
+
end
|
629
|
+
end
|
630
|
+
|
631
|
+
describe "#given" do
|
632
|
+
it "has a given method to get given data" do
|
633
|
+
expect(provider.given(:array)).to eq [1,2,4]
|
634
|
+
expect(provider.give(:array => 'array').given(:array)).to eq 'array'
|
635
|
+
end
|
636
|
+
|
637
|
+
it "has a get_data alias" do
|
638
|
+
expect(provider.get_data(:array)).to eq provider.given(:array)
|
639
|
+
end
|
640
|
+
end
|
641
|
+
|
642
|
+
describe "fallback_provider?" do
|
643
|
+
it "lets you know if a fallback provider has been registered" do
|
644
|
+
klass = Class.new Object do
|
645
|
+
include DataProvider::Base
|
646
|
+
end
|
647
|
+
|
648
|
+
expect(klass.new.fallback_provider?).to eq false
|
649
|
+
|
650
|
+
klass.provider_missing do
|
651
|
+
"New fallback!"
|
652
|
+
end
|
653
|
+
|
654
|
+
expect(klass.new.fallback_provider?).to eq true
|
655
|
+
end
|
656
|
+
end
|
657
|
+
|
658
|
+
describe "#add!" do
|
659
|
+
let(:m){
|
660
|
+
Module.new do
|
661
|
+
include DataProvider::Base
|
662
|
+
provider :new_provider do
|
663
|
+
"I'm new!"
|
664
|
+
end
|
665
|
+
end
|
666
|
+
}
|
667
|
+
|
668
|
+
let(:klass){
|
669
|
+
Class.new(Object) do include DataProvider::Base end
|
670
|
+
}
|
671
|
+
|
672
|
+
let(:instance){
|
673
|
+
klass.new
|
674
|
+
}
|
675
|
+
|
676
|
+
it "adds data providers from a module to itself" do
|
677
|
+
# before
|
678
|
+
expect(instance.has_provider?(:new_provider)).to eq false
|
679
|
+
expect(instance.try_take(:new_provider)).to eq nil
|
680
|
+
|
681
|
+
# add!
|
682
|
+
instance.add!(m)
|
683
|
+
|
684
|
+
# after
|
685
|
+
expect(instance.has_provider?(:new_provider)).to eq true
|
686
|
+
expect(instance.try_take(:new_provider)).to eq "I'm new!"
|
687
|
+
end
|
688
|
+
|
689
|
+
it "returns self" do
|
690
|
+
expect(instance.add!(m)).to be instance
|
691
|
+
end
|
692
|
+
|
693
|
+
it "includes a module into the object's class, so normal methods become available as well" do
|
694
|
+
m = Module.new do
|
695
|
+
include DataProvider::Base
|
696
|
+
|
697
|
+
def mfunc
|
698
|
+
take(:cprovider)
|
699
|
+
end
|
700
|
+
end
|
701
|
+
|
702
|
+
c = Class.new(Object) do
|
703
|
+
include DataProvider::Base
|
704
|
+
provider :cprovider do 'Good to be back' end
|
705
|
+
end
|
706
|
+
|
707
|
+
instance = c.new
|
708
|
+
expect{instance.mfunc}.to raise_error(NoMethodError)
|
709
|
+
instance.add!(m)
|
710
|
+
expect(instance.mfunc).to eq 'Good to be back'
|
711
|
+
end
|
712
|
+
end
|
713
|
+
|
714
|
+
describe "#add" do
|
715
|
+
it "adds modules to a clone and returns that clone" do
|
716
|
+
m = Module.new do
|
717
|
+
include DataProvider::Base
|
718
|
+
provider :new_provider do
|
719
|
+
"I'm new!"
|
720
|
+
end
|
721
|
+
end
|
722
|
+
|
723
|
+
klass = Class.new(Object) do include DataProvider::Base end
|
724
|
+
instance = klass.new
|
725
|
+
|
726
|
+
# before
|
727
|
+
expect(instance.has_provider?(:new_provider)).to eq false
|
728
|
+
expect(instance.try_take(:new_provider)).to eq nil
|
729
|
+
|
730
|
+
# add
|
731
|
+
clone = instance.add(m)
|
732
|
+
|
733
|
+
# after
|
734
|
+
expect(instance.has_provider?(:new_provider)).to eq false
|
735
|
+
expect(instance.try_take(:new_provider)).to eq nil
|
736
|
+
|
737
|
+
expect(clone.has_provider?(:new_provider)).to eq true
|
738
|
+
expect(clone.try_take(:new_provider)).to eq "I'm new!"
|
739
|
+
end
|
740
|
+
|
741
|
+
it "includes a module into the object's class, so normal methods become available as well" do
|
742
|
+
m = Module.new do
|
743
|
+
include DataProvider::Base
|
744
|
+
|
745
|
+
def mfunc
|
746
|
+
take(:cprovider)
|
747
|
+
end
|
748
|
+
end
|
749
|
+
|
750
|
+
c = Class.new(Object) do
|
751
|
+
include DataProvider::Base
|
752
|
+
|
753
|
+
provider :cprovider do 'Good to be back' end
|
754
|
+
end
|
755
|
+
|
756
|
+
instance = c.new
|
757
|
+
expect{instance.mfunc}.to raise_error(NoMethodError)
|
758
|
+
instance.add(m)
|
759
|
+
expect(instance.mfunc).to eq 'Good to be back'
|
760
|
+
end
|
761
|
+
end
|
762
|
+
|
763
|
+
describe "#add_scoped" do
|
764
|
+
it "adds providers to this object instance" do
|
765
|
+
m = Module.new do
|
766
|
+
include DataProvider::Base
|
767
|
+
provider :imnew do
|
768
|
+
"I'm new!"
|
769
|
+
end
|
770
|
+
end
|
771
|
+
|
772
|
+
klass = Class.new(Object) do include DataProvider::Base end
|
773
|
+
instance = klass.new
|
774
|
+
instance2 = instance.add_scoped(m, :scope => [:what, :ever])
|
775
|
+
# didn't get added to existing instance
|
776
|
+
expect(instance.has_provider?([:what, :ever, :imnew])).to eq false
|
777
|
+
# created new instance with the new scoped provider
|
778
|
+
expect(instance2.has_provider?([:what, :ever, :imnew])).to eq true
|
779
|
+
# unscoped provider was not added to new instance
|
780
|
+
expect(instance2.has_provider?([:imnew])).to eq false
|
781
|
+
end
|
782
|
+
end
|
783
|
+
|
784
|
+
describe "#provider_stack" do
|
785
|
+
let(:instance){
|
786
|
+
Class.new(Object) do
|
787
|
+
include DataProvider::Base
|
788
|
+
|
789
|
+
provider :one do
|
790
|
+
take :two
|
791
|
+
end
|
792
|
+
provider :two do
|
793
|
+
provider_stack
|
794
|
+
end
|
795
|
+
end
|
796
|
+
}
|
797
|
+
|
798
|
+
it "gives the provider's callstack" do
|
799
|
+
expect(instance.take(:one)).to eq [:one, :two]
|
800
|
+
end
|
801
|
+
end
|
802
|
+
|
803
|
+
describe "#provider_id" do
|
804
|
+
let(:instance){
|
805
|
+
Class.new(Object) do
|
806
|
+
include DataProvider::Base
|
807
|
+
provider :narcissist do
|
808
|
+
provider_id
|
809
|
+
end
|
810
|
+
end
|
811
|
+
}
|
812
|
+
|
813
|
+
it "give the provider's own id" do
|
814
|
+
expect(instance.take(:narcissist)).to eq :narcissist
|
815
|
+
end
|
816
|
+
end
|
817
|
+
end
|
818
|
+
end
|