olfactory 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  module Olfactory
3
3
  class TemplateDefinition
4
- attr_accessor :t_items, :t_subtemplates, :t_sequences, :t_dictionaries, :t_macros, :t_presets, :t_before, :t_after
4
+ attr_accessor :t_items, :t_subtemplates, :t_sequences, :t_dictionaries, :t_macros, :t_presets, :t_befores, :t_afters, :t_instantiators
5
5
 
6
6
  def initialize
7
7
  self.t_items = {}
@@ -10,28 +10,29 @@ module Olfactory
10
10
  self.t_dictionaries = {}
11
11
  self.t_macros = {}
12
12
  self.t_presets = {}
13
- self.t_before = {}
14
- self.t_after = {}
13
+ self.t_befores = {}
14
+ self.t_afters = {}
15
+ self.t_instantiators = {}
15
16
  end
16
17
 
17
- def build(block, options = {})
18
+ def construct(block, options = {})
18
19
  if options[:preset] || options[:quantity]
19
- self.build_preset(options[:preset], (options[:quantity] || 1), options.reject { |k,v| [:preset, :quantity].include?(k) })
20
+ self.construct_preset(options[:preset], (options[:quantity] || 1), options.reject { |k,v| [:preset, :quantity].include?(k) })
20
21
  else
21
22
  new_template = Template.new(self, options)
22
- new_template.build(block, options)
23
+ new_template.construct(block, options)
23
24
  end
24
25
  new_template
25
26
  end
26
- def build_preset(preset_name, quantity, options = {})
27
+ def construct_preset(preset_name, quantity, options = {})
27
28
  raise "Quantity must be an integer!" if !(quantity.class <= Integer)
28
29
 
29
30
  if quantity > 1
30
31
  # Build multiple
31
32
  if preset_name
32
- Array.new(quantity) { self.build_preset(preset_name, 1, options) }
33
+ Array.new(quantity) { self.construct_preset(preset_name, 1, options) }
33
34
  else
34
- Array.new(quantity) { self.build(nil, options) }
35
+ Array.new(quantity) { self.construct(nil, options) }
35
36
  end
36
37
  elsif quantity == 1
37
38
  if preset_definition = self.find_preset_definition(preset_name)
@@ -39,12 +40,12 @@ module Olfactory
39
40
  new_template = Template.new(self, options)
40
41
  preset_block = preset_definition[:evaluator]
41
42
  if preset_definition[:regexp]
42
- new_template.build(preset_block, options.merge(:value => preset_name))
43
+ new_template.construct(preset_block, options.merge(:value => preset_name))
43
44
  else
44
- new_template.build(preset_block, options)
45
+ new_template.construct(preset_block, options)
45
46
  end
46
47
  elsif preset_name.nil?
47
- self.build(nil, options)
48
+ self.construct(nil, options)
48
49
  else
49
50
  raise "Missing preset matching '#{preset_name}' for template!"
50
51
  end
@@ -157,17 +158,42 @@ module Olfactory
157
158
  self.t_presets[name] = self.t_presets[name].merge(:regexp => name) if name.class <= Regexp
158
159
  end
159
160
 
161
+ # Defines an instantiator
162
+ def instantiate(name, options = {}, &block)
163
+ self.t_instantiators[name] = { :type => :instantiator,
164
+ :name => name,
165
+ :evaluator => block
166
+ }.merge(options)
167
+ end
168
+
160
169
  # Defines defaults
161
- def before(options = {}, &block)
162
- self.t_before = { :type => :default,
163
- :evaluator => block
164
- }.merge(options)
165
- self.t_before = self.t_before.merge(:preset => options[:preset]) if options[:preset]
166
- end
167
- def after(options = {}, &block)
168
- self.t_after = { :type => :default,
169
- :evaluator => block }.merge(options)
170
- self.t_after = self.t_after.merge(:preset => options[:preset]) if options[:preset]
170
+ def before(context = nil, options = {}, &block)
171
+ if context.class == Hash
172
+ # Arguments need to be remapped...
173
+ options = context
174
+ context = nil
175
+ end
176
+ before_definition = { :type => :default,
177
+ :evaluator => block
178
+ }.merge(options)
179
+ before_definition.merge!(:preset => options[:preset]) if options[:preset]
180
+ context ||= :all
181
+ self.t_befores[context] ||= []
182
+ self.t_befores[context] << before_definition
183
+ end
184
+ def after(context = nil, options = {}, &block)
185
+ if context.class == Hash
186
+ # Arguments need to be remapped...
187
+ options = context
188
+ context = nil
189
+ end
190
+ after_definition = { :type => :default,
191
+ :evaluator => block
192
+ }.merge(options)
193
+ after_definition.merge!(:preset => options[:preset]) if options[:preset]
194
+ context ||= :all
195
+ self.t_afters[context] ||= []
196
+ self.t_afters[context] << after_definition
171
197
  end
172
198
  end
173
199
  end
@@ -1,3 +1,3 @@
1
1
  module Olfactory
2
- VERSION = '0.2.0'
2
+ VERSION = '0.2.1'
3
3
  end
data/olfactory.gemspec CHANGED
@@ -16,7 +16,7 @@ Gem::Specification.new do |s|
16
16
  s.require_paths = ['lib']
17
17
  s.required_ruby_version = Gem::Requirement.new(">= 1.9.2")
18
18
 
19
- s.add_development_dependency("rspec", "~> 3.1")
19
+ s.add_development_dependency("rspec", "~> 3.2")
20
20
  s.add_development_dependency("pry", "~> 0.10")
21
21
  s.add_development_dependency("pry-nav", "~> 0.2")
22
22
  s.add_development_dependency("pry-stack_explorer", "~> 0.4.9")
@@ -4,7 +4,7 @@ describe Olfactory::Sequence do
4
4
  context "with no seed" do
5
5
  before(:example) do
6
6
  Olfactory.sequence :address do |n, options|
7
- "#{(n + (n % 2)) + 2} #{"#{options[:prefix]} " if options[:prefix]}BROADWAY"
7
+ "#{(2*n) + 2} #{"#{options[:prefix]} " if options[:prefix]}BROADWAY"
8
8
  end
9
9
  end
10
10
  context "given nothing" do
@@ -22,7 +22,7 @@ describe Olfactory::Sequence do
22
22
  context "given a block" do
23
23
  subject do
24
24
  Olfactory.generate(:address) do |n|
25
- "#{(n + (n % 2)) + 2} JOHN STREET"
25
+ "#{(2*n) + 2} JOHN STREET"
26
26
  end
27
27
  end
28
28
  it { expect(subject).to eq("2 JOHN STREET") }
@@ -30,7 +30,7 @@ describe Olfactory::Sequence do
30
30
  context "given options and a block" do
31
31
  subject do
32
32
  Olfactory.generate(:address, :suffix => "ROAD") do |n, options|
33
- "#{(n + (n % 2)) + 2} JOHN#{options[:suffix] ? " #{options[:suffix]}" : " STREET"}"
33
+ "#{(2*n) + 2} JOHN#{options[:suffix] ? " #{options[:suffix]}" : " STREET"}"
34
34
  end
35
35
  end
36
36
  it { expect(subject).to eq("2 JOHN ROAD") }
@@ -39,42 +39,54 @@ describe Olfactory::Sequence do
39
39
  context "with a seed" do
40
40
  before(:example) do
41
41
  Olfactory.sequence :address, :seed => 10 do |n, options|
42
- "#{(n + (n % 2))} #{"#{options[:prefix]} " if options[:prefix]}BROADWAY"
42
+ "#{(2*n)} #{"#{options[:prefix]} " if options[:prefix]}BROADWAY"
43
43
  end
44
44
  end
45
45
  context "given nothing" do
46
46
  subject do
47
47
  Olfactory.generate(:address)
48
48
  end
49
- it { expect(subject).to eq("10 BROADWAY") }
49
+ it { expect(subject).to eq("20 BROADWAY") }
50
50
  end
51
51
  context "given options" do
52
52
  subject do
53
53
  Olfactory.generate(:address, :prefix => "WEST")
54
54
  end
55
- it { expect(subject).to eq("10 WEST BROADWAY") }
55
+ it { expect(subject).to eq("20 WEST BROADWAY") }
56
56
  end
57
57
  context "given a block" do
58
58
  subject do
59
59
  Olfactory.generate(:address) do |n|
60
- "#{(n + (n % 2))} JOHN STREET"
60
+ "#{(2*n)} JOHN STREET"
61
61
  end
62
62
  end
63
- it { expect(subject).to eq("10 JOHN STREET") }
63
+ it { expect(subject).to eq("20 JOHN STREET") }
64
64
  end
65
65
  context "given options and a block" do
66
66
  subject do
67
67
  Olfactory.generate(:address, :suffix => "ROAD") do |n, options|
68
- "#{(n + (n % 2))} JOHN#{options[:suffix] ? " #{options[:suffix]}" : " STREET"}"
68
+ "#{(2*n)} JOHN#{options[:suffix] ? " #{options[:suffix]}" : " STREET"}"
69
69
  end
70
70
  end
71
- it { expect(subject).to eq("10 JOHN ROAD") }
71
+ it { expect(subject).to eq("20 JOHN ROAD") }
72
72
  end
73
73
  end
74
+ context "given a dimension" do
75
+ before(:context) do
76
+ Olfactory.sequence :address do |n|
77
+ "#{(2*n)+2} BROADWAY"
78
+ end
79
+ end
80
+ let(:address_one) { Olfactory.generate(:address) }
81
+ let(:address_two) { Olfactory.generate(:address, :dimension => "LAS VEGAS") }
82
+ it { expect(address_one).to eq("2 BROADWAY") }
83
+ it { expect(address_two).to eq("2 BROADWAY") }
84
+ it { expect(address_one).to eq("4 BROADWAY") }
85
+ end
74
86
  context "given sequential invocations" do
75
87
  before(:context) do
76
88
  Olfactory.sequence :address do |n, options|
77
- "#{(n + (n % 2)) + 2} #{"#{options[:prefix]} " if options[:prefix]}BROADWAY"
89
+ "#{(2*n) + 2} #{"#{options[:prefix]} " if options[:prefix]}BROADWAY"
78
90
  end
79
91
  end
80
92
  it { expect(Olfactory.generate(:address)).to eq("2 BROADWAY") }
@@ -395,6 +395,37 @@ describe Olfactory::Template do
395
395
  end
396
396
  end
397
397
  end
398
+ # context "with a before block" do
399
+ # before do
400
+ # Olfactory.template :widget do |t|
401
+ # t.embeds_one :doodad do |w|
402
+ # w.quality :dull
403
+ # end
404
+ # t.macro :quality do |m, type|
405
+ # m.transient :attribute, type.to_s
406
+ # end
407
+ # end
408
+ # Olfactory.template :doodad do |t|
409
+ # t.has_one :gizmo
410
+ # t.after do |d|
411
+ # d.gizmo "#{d.transients[:attribute]} #{value}"
412
+ # end
413
+ # end
414
+ # end
415
+ # let(:shiny) do
416
+ # Olfactory.build :widget do |w|
417
+ # w.quality :shiny
418
+ # w.doodad
419
+ # end
420
+ # end
421
+ # let(:dull) do
422
+ # Olfactory.build :widget do |w|
423
+ # w.doodad
424
+ # end
425
+ # end
426
+ # it { expect(shiny[:doodad][:gizmo]).to eq("shiny #{value}")}
427
+ # it { expect(dull[:doodad][:gizmo]).to eq("dull #{value}")}
428
+ # end
398
429
  end
399
430
  context "embeds_many" do
400
431
  before(:context) do
@@ -744,7 +775,7 @@ describe Olfactory::Template do
744
775
  Olfactory.template :building do |t|
745
776
  t.has_one :address
746
777
  t.sequence :address, :scope => :template do |n, options|
747
- "#{(n + (n % 2)) + 2} #{"#{options[:prefix]} " if options[:prefix]}BROADWAY"
778
+ "#{(2*n) + 2} #{"#{options[:prefix]} " if options[:prefix]}BROADWAY"
748
779
  end
749
780
  end
750
781
  end
@@ -769,7 +800,7 @@ describe Olfactory::Template do
769
800
  Olfactory.build :building do |building|
770
801
  building.address do
771
802
  building.generate(:address) do |n|
772
- "#{(n + (n % 2)) + 2} JOHN STREET"
803
+ "#{(2*n) + 2} JOHN STREET"
773
804
  end
774
805
  end
775
806
  end
@@ -781,20 +812,40 @@ describe Olfactory::Template do
781
812
  Olfactory.build :building do |building|
782
813
  building.address do
783
814
  building.generate(:address, :suffix => "ROAD") do |n, options|
784
- "#{(n + (n % 2)) + 2} JOHN#{options[:suffix] ? " #{options[:suffix]}" : " STREET"}"
815
+ "#{(2*n) + 2} JOHN#{options[:suffix] ? " #{options[:suffix]}" : " STREET"}"
785
816
  end
786
817
  end
787
818
  end
788
819
  end
789
820
  it { expect(subject[:address]).to eq("2 JOHN ROAD") }
790
821
  end
822
+ context "given a dimension" do
823
+ let!(:building_one) do
824
+ Olfactory.build :building do |building|
825
+ building.address building.generate(:address)
826
+ end
827
+ end
828
+ let!(:building_two) do
829
+ Olfactory.build :building do |building|
830
+ building.address building.generate(:address, :dimension => "LAS VEGAS")
831
+ end
832
+ end
833
+ let!(:building_three) do
834
+ Olfactory.build :building do |building|
835
+ building.address building.generate(:address)
836
+ end
837
+ end
838
+ it { expect(building_one[:address]).to eq("2 BROADWAY") }
839
+ it { expect(building_two[:address]).to eq("2 BROADWAY") }
840
+ it { expect(building_three[:address]).to eq("4 BROADWAY") }
841
+ end
791
842
  end
792
843
  context "given sequential invocations" do
793
844
  before(:context) do
794
845
  Olfactory.template :building do |t|
795
846
  t.has_one :address
796
847
  t.sequence :address, :scope => :template do |n, options|
797
- "#{(n + (n % 2)) + 2} #{"#{options[:prefix]} " if options[:prefix]}BROADWAY"
848
+ "#{(2*n) + 2} #{"#{options[:prefix]} " if options[:prefix]}BROADWAY"
798
849
  end
799
850
  end
800
851
  end
@@ -818,7 +869,7 @@ describe Olfactory::Template do
818
869
  Olfactory.template :building do |t|
819
870
  t.has_one :address
820
871
  t.sequence :address, :scope => :instance do |n, options|
821
- "#{(n + (n % 2)) + 2} #{"#{options[:prefix]} " if options[:prefix]}BROADWAY"
872
+ "#{(2*n) + 2} #{"#{options[:prefix]} " if options[:prefix]}BROADWAY"
822
873
  end
823
874
  end
824
875
  end
@@ -843,7 +894,7 @@ describe Olfactory::Template do
843
894
  Olfactory.build :building do |building|
844
895
  building.address do
845
896
  building.generate(:address) do |n|
846
- "#{(n + (n % 2)) + 2} JOHN STREET"
897
+ "#{(2*n) + 2} JOHN STREET"
847
898
  end
848
899
  end
849
900
  end
@@ -855,13 +906,45 @@ describe Olfactory::Template do
855
906
  Olfactory.build :building do |building|
856
907
  building.address do
857
908
  building.generate(:address, :suffix => "ROAD") do |n, options|
858
- "#{(n + (n % 2)) + 2} JOHN#{options[:suffix] ? " #{options[:suffix]}" : " STREET"}"
909
+ "#{(2*n) + 2} JOHN#{options[:suffix] ? " #{options[:suffix]}" : " STREET"}"
859
910
  end
860
911
  end
861
912
  end
862
913
  end
863
914
  it { expect(subject[:address]).to eq("2 JOHN ROAD") }
864
915
  end
916
+ context "given a dimension" do
917
+ before(:example) do
918
+ Olfactory.template :building do |t|
919
+ t.has_one :address
920
+ t.has_one :other_address
921
+ t.has_one :another_address
922
+ t.sequence :address, :scope => :instance do |n, options|
923
+ "#{(2*n) + 2} #{"#{options[:prefix]} " if options[:prefix]}BROADWAY"
924
+ end
925
+ end
926
+ end
927
+ let!(:building_one) do
928
+ Olfactory.build :building do |building|
929
+ building.address building.generate(:address)
930
+ building.other_address building.generate(:address, :dimension => "LAS VEGAS")
931
+ building.another_address building.generate(:address)
932
+ end
933
+ end
934
+ let!(:building_two) do
935
+ Olfactory.build :building do |building|
936
+ building.address building.generate(:address)
937
+ building.other_address building.generate(:address, :dimension => "LAS VEGAS")
938
+ building.another_address building.generate(:address)
939
+ end
940
+ end
941
+ it { expect(building_one[:address]).to eq("2 BROADWAY") }
942
+ it { expect(building_one[:other_address]).to eq("2 BROADWAY") }
943
+ it { expect(building_one[:another_address]).to eq("4 BROADWAY") }
944
+ it { expect(building_two[:address]).to eq("2 BROADWAY") }
945
+ it { expect(building_two[:other_address]).to eq("2 BROADWAY") }
946
+ it { expect(building_two[:another_address]).to eq("4 BROADWAY") }
947
+ end
865
948
  end
866
949
  context "given sequential invocations" do
867
950
  before(:context) do
@@ -869,7 +952,7 @@ describe Olfactory::Template do
869
952
  t.has_one :address
870
953
  t.has_one :other_address
871
954
  t.sequence :address, :scope => :instance do |n, options|
872
- "#{(n + (n % 2)) + 2} #{"#{options[:prefix]} " if options[:prefix]}BROADWAY"
955
+ "#{(2*n) + 2} #{"#{options[:prefix]} " if options[:prefix]}BROADWAY"
873
956
  end
874
957
  end
875
958
  end
@@ -898,10 +981,10 @@ describe Olfactory::Template do
898
981
  t.has_one :even_count
899
982
  t.has_one :odd_count
900
983
  t.sequence :even, :scope => :template do |n|
901
- (n + (n % 2)) + 2
984
+ (2*n) + 2
902
985
  end
903
986
  t.sequence :odd, :scope => :template do |n|
904
- (n + (n % 2)) + 1
987
+ (2*n) + 1
905
988
  end
906
989
  end
907
990
  end
@@ -1185,13 +1268,27 @@ describe Olfactory::Template do
1185
1268
  end
1186
1269
  let(:value) { "temporary value"}
1187
1270
  context "when set" do
1188
- subject do
1189
- Olfactory.build :widget do |t|
1190
- t.transient :foo, value
1271
+ context "given a basic value" do
1272
+ subject do
1273
+ Olfactory.build :widget do |t|
1274
+ t.transient :foo, value
1275
+ end
1276
+ end
1277
+ it do
1278
+ expect(subject.transients[:foo]).to eq(value)
1191
1279
  end
1192
1280
  end
1193
- it do
1194
- expect(subject.transients[:foo]).to eq(value)
1281
+ context "given a block" do
1282
+ subject do
1283
+ Olfactory.build :widget do |t|
1284
+ t.transient :foo do
1285
+ value
1286
+ end
1287
+ end
1288
+ end
1289
+ it do
1290
+ expect(subject.transients[:foo]).to eq(value)
1291
+ end
1195
1292
  end
1196
1293
  end
1197
1294
  context "when read" do
@@ -1228,50 +1325,322 @@ describe Olfactory::Template do
1228
1325
  context "defaults" do
1229
1326
  let(:value) { "doodad" }
1230
1327
  let(:default_value) { "default doodad" }
1328
+ let(:default_after_value) { "default after doodad" }
1231
1329
  context "before" do
1232
- before(:context) do
1233
- Olfactory.template :widget do |t|
1234
- t.has_one :doodad
1235
- t.has_one :other_doodad
1236
- t.before do |d|
1237
- d.doodad default_value
1238
- d.other_doodad default_value
1330
+ context "all" do
1331
+ before(:context) do
1332
+ Olfactory.template :widget do |t|
1333
+ t.has_one :doodad
1334
+ t.has_one :other_doodad
1335
+ t.before do |d|
1336
+ d.doodad default_value
1337
+ d.other_doodad default_value
1338
+ end
1239
1339
  end
1240
1340
  end
1341
+ subject do
1342
+ Olfactory.build :widget do |t|
1343
+ t.doodad value
1344
+ end
1345
+ end
1346
+ it "values can be overriden" do
1347
+ expect(subject[:doodad]).to eq(value)
1348
+ end
1349
+ it "values can be set"do
1350
+ expect(subject[:other_doodad]).to eq(default_value)
1351
+ end
1241
1352
  end
1242
- subject do
1243
- Olfactory.build :widget do |t|
1244
- t.doodad value
1353
+ context "embedded" do
1354
+ before(:context) do
1355
+ Olfactory.template :widget do |t|
1356
+ t.embeds_one :doodad
1357
+ t.macro :quality do |m, type|
1358
+ m.transient :attribute, type.to_s
1359
+ end
1360
+ t.before(:embedded) do |d|
1361
+ d.quality :dull
1362
+ end
1363
+ t.before do |d|
1364
+ d.quality :scratched
1365
+ end
1366
+ end
1367
+ Olfactory.template :doodad do |t|
1368
+ t.has_one :gizmo
1369
+ t.after do |d|
1370
+ d.gizmo "#{d.transients[:attribute]} #{value}"
1371
+ end
1372
+ end
1373
+ end
1374
+ let(:shiny) do
1375
+ Olfactory.build :widget do |w|
1376
+ w.quality :shiny
1377
+ w.doodad
1378
+ end
1379
+ end
1380
+ let(:dull) do
1381
+ Olfactory.build :widget do |w|
1382
+ w.doodad
1383
+ end
1384
+ end
1385
+ it { expect(shiny[:doodad][:gizmo]).to eq("shiny #{value}")}
1386
+ it { expect(dull[:doodad][:gizmo]).to eq("dull #{value}")}
1387
+ context "(run once)" do
1388
+ before(:context) do
1389
+ Olfactory.template :widget do |t|
1390
+ t.embeds_many :doodads, :singular => :doodad
1391
+ t.has_one :thingamabob
1392
+ t.macro :quality do |m, type|
1393
+ m.transient :attribute, type.to_s
1394
+ end
1395
+ t.before(:embedded, :run => :once) do |d|
1396
+ d.quality :dull
1397
+ d.thingamabob "thingamabob" if d[:doodads] && d[:doodads].count > 0
1398
+ end
1399
+ end
1400
+ Olfactory.template :doodad do |t|
1401
+ t.has_one :gizmo
1402
+ t.after do |d|
1403
+ d.gizmo "#{d.transients[:attribute]} #{value}"
1404
+ end
1405
+ end
1406
+ end
1407
+ subject do
1408
+ Olfactory.build :widget do |w|
1409
+ w.doodad
1410
+ w.quality :shiny
1411
+ w.doodad
1412
+ end
1413
+ end
1414
+ it do
1415
+ expect(subject[:doodads]).to eq([{ :gizmo => "dull #{value}" }, { :gizmo => "shiny #{value}" }])
1416
+ expect(subject[:thingamabob]).to be_nil
1417
+ end
1245
1418
  end
1246
1419
  end
1247
- it "values can be overriden" do
1248
- expect(subject[:doodad]).to eq(value)
1420
+ end
1421
+ context "after" do
1422
+ context "values" do
1423
+ context "given a has_one" do
1424
+ before(:context) do
1425
+ Olfactory.template :widget do |t|
1426
+ t.has_one :doodad
1427
+ t.has_one :other_doodad
1428
+ t.after do |d|
1429
+ d.doodad default_value
1430
+ d.other_doodad default_value
1431
+ end
1432
+ end
1433
+ end
1434
+ subject do
1435
+ Olfactory.build :widget do |t|
1436
+ t.doodad value
1437
+ end
1438
+ end
1439
+ it "will not override existing ones" do
1440
+ expect(subject[:doodad]).to eq(value)
1441
+ end
1442
+ it "will fill in missing ones"do
1443
+ expect(subject[:other_doodad]).to eq(default_value)
1444
+ end
1445
+ end
1446
+ context "given a has_many" do
1447
+ before(:context) do
1448
+ Olfactory.template :widget do |t|
1449
+ t.has_many :doodads, :singular => :doodad
1450
+ t.has_many :other_doodads, :singular => :other_doodad
1451
+ t.after do |d|
1452
+ d.doodad default_value
1453
+ d.doodads default_value
1454
+ d.other_doodad default_value
1455
+ d.other_doodads default_value, default_value
1456
+ end
1457
+ end
1458
+ end
1459
+ subject do
1460
+ Olfactory.build :widget do |t|
1461
+ t.doodad value
1462
+ end
1463
+ end
1464
+ it "will not override existing ones" do
1465
+ expect(subject[:doodads]).to eq([value])
1466
+ end
1467
+ it "will fill in missing ones"do
1468
+ expect(subject[:other_doodads]).to eq([default_value, default_value, default_value])
1469
+ end
1470
+ end
1471
+ context "given a embeds_one" do
1472
+ before(:context) do
1473
+ Olfactory.template :widget do |t|
1474
+ t.embeds_one :doodad
1475
+ t.embeds_one :other_doodad
1476
+ t.after do |d|
1477
+ d.doodad { |doodad| doodad.gizmo default_value }
1478
+ d.other_doodad { |doodad| doodad.gizmo default_value }
1479
+ end
1480
+ end
1481
+ Olfactory.template :doodad do |t|
1482
+ t.has_one :gizmo
1483
+ end
1484
+ Olfactory.template :other_doodad do |t|
1485
+ t.has_one :gizmo
1486
+ end
1487
+ end
1488
+ subject do
1489
+ Olfactory.build :widget do |t|
1490
+ t.doodad { |doodad| doodad.gizmo value }
1491
+ end
1492
+ end
1493
+ it "will not override existing ones" do
1494
+ expect(subject[:doodad]).to eq({ :gizmo => value })
1495
+ end
1496
+ it "will fill in missing ones" do
1497
+ expect(subject[:other_doodad]).to eq({ :gizmo => default_value })
1498
+ end
1499
+ end
1500
+ context "given a embeds_many" do
1501
+ before(:context) do
1502
+ Olfactory.template :widget do |t|
1503
+ t.embeds_many :doodads, :singular => :doodad
1504
+ t.embeds_many :other_doodads, :singular => :other_doodad
1505
+ t.after do |d|
1506
+ d.doodad { |doodad| doodad.gizmo default_value }
1507
+ d.doodads 2 do |doodad| doodad.gizmo default_value end
1508
+ d.other_doodad { |doodad| doodad.gizmo default_value }
1509
+ d.other_doodads 2 do |doodad| doodad.gizmo default_value end
1510
+ end
1511
+ end
1512
+ Olfactory.template :doodad do |t|
1513
+ t.has_one :gizmo
1514
+ end
1515
+ Olfactory.template :other_doodad do |t|
1516
+ t.has_one :gizmo
1517
+ end
1518
+ end
1519
+ subject do
1520
+ Olfactory.build :widget do |t|
1521
+ t.doodad { |doodad| doodad.gizmo value }
1522
+ end
1523
+ end
1524
+ it "will not override existing ones" do
1525
+ expect(subject[:doodads]).to eq([{ :gizmo => value }])
1526
+ end
1527
+ it "will fill in missing ones"do
1528
+ expect(subject[:other_doodads]).to eq([{ :gizmo => default_value }, { :gizmo => default_value }, { :gizmo => default_value }])
1529
+ end
1530
+ end
1531
+ end
1532
+ end
1533
+ context "both before and after" do
1534
+ context "given no value" do
1535
+ before(:context) do
1536
+ Olfactory.template :widget do |t|
1537
+ t.has_one :doodad
1538
+ t.before do |d|
1539
+ d.doodad default_value
1540
+ end
1541
+ t.after do |d|
1542
+ d.doodad default_after_value
1543
+ end
1544
+ end
1545
+ end
1546
+ subject do
1547
+ Olfactory.build :widget
1548
+ end
1549
+ it "will override with a default the second time" do
1550
+ expect(subject[:doodad]).to eq(default_after_value)
1551
+ end
1249
1552
  end
1250
- it "values can be set"do
1251
- expect(subject[:other_doodad]).to eq(default_value)
1553
+ context "given a value" do
1554
+ before(:context) do
1555
+ Olfactory.template :widget do |t|
1556
+ t.has_one :doodad
1557
+ t.before do |d|
1558
+ d.doodad default_value
1559
+ end
1560
+ t.after do |d|
1561
+ d.doodad default_value
1562
+ end
1563
+ end
1564
+ end
1565
+ subject do
1566
+ Olfactory.build :widget do |t|
1567
+ t.doodad value
1568
+ end
1569
+ end
1570
+ it "will not set override with a default the second time" do
1571
+ expect(subject[:doodad]).to eq(value)
1572
+ end
1252
1573
  end
1253
1574
  end
1254
- context "after" do
1575
+ end
1576
+ context "instantiators" do
1577
+ context "given a symbol and block" do
1255
1578
  before(:context) do
1256
1579
  Olfactory.template :widget do |t|
1257
1580
  t.has_one :doodad
1258
- t.has_one :other_doodad
1259
- t.after do |d|
1260
- d.doodad default_value
1261
- d.other_doodad default_value
1581
+ t.instantiate :doodad do |i|
1582
+ SaveableString.new("#{i[:doodad]}-instance")
1262
1583
  end
1263
1584
  end
1264
1585
  end
1265
- subject do
1266
- Olfactory.build :widget do |t|
1267
- t.doodad value
1586
+ let(:value) { "doodad" }
1587
+ let(:template) { Olfactory.build :widget do |w| w.doodad "doodad" end }
1588
+
1589
+ context "invoked with #build" do
1590
+ subject do
1591
+ template.build(:doodad)
1592
+ end
1593
+ it do
1594
+ expect(subject).to eq("#{value}-instance")
1595
+ expect(subject.saved?).to be false
1268
1596
  end
1269
1597
  end
1270
- it "values will not override existing ones" do
1271
- expect(subject[:doodad]).to eq(value)
1272
- end
1273
- it "values will fill in missing ones"do
1274
- expect(subject[:other_doodad]).to eq(default_value)
1598
+ context "invoked with #create" do
1599
+ subject do
1600
+ template.create(:doodad)
1601
+ end
1602
+ context "that returns a saveable object" do
1603
+ before(:context) do
1604
+ Olfactory.template :widget do |t|
1605
+ t.has_one :doodad
1606
+ t.instantiate :doodad do |i|
1607
+ SaveableString.new("#{i[:doodad]}-instance")
1608
+ end
1609
+ end
1610
+ end
1611
+ it do
1612
+ expect(subject).to eq("#{value}-instance")
1613
+ expect(subject.saved?).to be true
1614
+ end
1615
+ end
1616
+ context "that returns an array of saveable objects" do
1617
+ before(:context) do
1618
+ Olfactory.template :widget do |t|
1619
+ t.has_one :doodad
1620
+ t.instantiate :doodad do |i|
1621
+ [SaveableString.new("#{i[:doodad]}-instance-1"), SaveableString.new("#{i[:doodad]}-instance-2")]
1622
+ end
1623
+ end
1624
+ end
1625
+ it do
1626
+ expect(subject).to eq(["#{value}-instance-1", "#{value}-instance-2"])
1627
+ expect(subject.all? { |d| d.saved? }).to be true
1628
+ end
1629
+ end
1630
+ context "that returns a hash of saveable objects" do
1631
+ before(:context) do
1632
+ Olfactory.template :widget do |t|
1633
+ t.has_one :doodad
1634
+ t.instantiate :doodad do |i|
1635
+ { 1 => SaveableString.new("#{i[:doodad]}-instance"), 2 => SaveableString.new("#{i[:doodad]}-instance") }
1636
+ end
1637
+ end
1638
+ end
1639
+ it do
1640
+ expect(subject).to eq({ 1 => "#{value}-instance", 2 => "#{value}-instance" })
1641
+ expect(subject.values.all? { |d| d.saved? }).to be true
1642
+ end
1643
+ end
1275
1644
  end
1276
1645
  end
1277
1646
  end