olfactory 0.2.0 → 0.2.1

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