data-provider 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/data_provider.rb CHANGED
@@ -1,2 +1,3 @@
1
1
  require 'data_provider/provider'
2
+ require 'data_provider/container'
2
3
  require 'data_provider/base'
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