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.
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