olfactory 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2aa21e7c9e5db497a09aae366070f380c53fd06d
4
+ data.tar.gz: 8cc46a8a5c7651ee48a2ab9aa63c85670409f2e7
5
+ SHA512:
6
+ metadata.gz: 86b174607b353e2daf29dfbee9f19d7594b95433c629f925e4feecb58b50e205f2f58a43014d2dc107c987530518154c8612930e9b8cba3859a81a6dd57a66ef
7
+ data.tar.gz: ae15150ca718660d8de6b7a8252ef61e8e7e633337eb28b44fcd57df76864915e8f882d7831f12ef3d582d568ac5a2fa5c09dc4b3eef9c624c447677f4cd9a55
data/README.md CHANGED
@@ -8,7 +8,7 @@ Olfactory
8
8
 
9
9
  Olfactory is a factory extension for creating complex object sets, as a supplement to `factory_girl`, `fabrication`, or other factories.
10
10
 
11
- It introduces the concept of **templates**: an abstract group of objects. You define what objects (or other templates) your template can contain (not unlike a factory), then you can create instances of it by invoking the build or create functions. These templates can be used to make test setup much quicker and easier. Templates are not intended to replace factories, but bridge the gap where `factory_girl` and `fabrication` factories fall short.
11
+ It introduces the concept of **templates**: a group of named values/objects (as a `Hash`.) You define what objects (or other templates) your template can contain (similar to a factory), then you can create instances of that template using the `#build` or `#create` functions. These templates can be used to make test setup much quicker and easier. Templates are not intended to replace factories, but bridge the gap where `factory_girl` and `fabrication` factories fall short.
12
12
 
13
13
  They are most useful when:
14
14
  - Your models are weakly related or non-relational (e.g. not joined by ActiveRecord associations)
@@ -54,8 +54,14 @@ context "networkable people" do
54
54
  end
55
55
  ```
56
56
 
57
+ In this sample, the `let(:user_group)` block returns a `Hash` object, that contains structured, pre-fabricated data of our choosing that we can use for our `it` example.
58
+
57
59
  ### Usage
58
60
 
61
+ ##### What is a template?
62
+
63
+ Templates are effectively `Hash` schemas. By defining a template, you are specifying which named-values can appear in a `Hash` instance of that template. When defining a template, you can also define custom presets, sequences, and other named options. You can leverage these features to simplify how you create complex objects & test data.
64
+
59
65
  ##### Defining templates
60
66
 
61
67
  Templates are defined in `spec/templates/**/*.rb` files. Define a template using the `Olfactory#template` method.
@@ -67,7 +73,17 @@ Templates are defined in `spec/templates/**/*.rb` files. Define a template using
67
73
  Once defined, these templates can be instantiated using `build` and `create`, which are analogous to the same `factory_girl`/`fabrication` methods
68
74
 
69
75
  Olfactory.build :computer # Creates objects, but does not implictly save them
70
- Olfactory.create :computer # Creates objects, and attempts to save all items that respond to #save!
76
+ Olfactory.create :computer # Creates objects, and attempts to save all items in the Hash that respond to #save!
77
+
78
+ Invoking these two methods will return a `Hash` matching the template schema, populated with either custom or preset values.
79
+
80
+ ##### Defining template relationships using `has` & `embeds`
81
+
82
+ Every template is composed of two kinds of named values: *fields* or other *templates*.
83
+
84
+ Fields hold actual values: integers, strings, objects, etc. The `has` relation is used define a field. `#has_one` holds one object, and '#has_many' holds a collection of objects (`Array` or `Hash`.)
85
+
86
+ You can also embed a template within another template. This is useful if you have a template composed of other smaller sub-templates (e.g. a Computer template composed of Processor and Memory templates.) Use the `embeds` relation to nest a template. `#embeds_one` will embed a single instance of a template. `#embeds_many` will embed a collection of template instances (in the form of an `Array` or `Hash`.)
71
87
 
72
88
  ##### #has_one
73
89
 
@@ -513,12 +529,14 @@ Sample:
513
529
 
514
530
  ##### #transient
515
531
 
516
- Similar to `factory_girl`'s transients, `transient` defines a temporary variable. You can store values in here to compose conditional logic or more sophisticated templates. When a template contains an embedded template, it will pass down all of its transients to the embedded template. Invoking `transients` on an instance of a template will return a hash of its transient variables.
532
+ Similar to `factory_girl`'s transients, `transient` defines a temporary variable. You can store values in here to compose conditional logic or more sophisticated templates. When a template contains an embedded template, it will pass down all of its transients to the embedded template. Invoking `transients` on an instance of a template will return a `Hash` of its transient variables.
517
533
 
518
534
  Usage:
519
- > **transient** name, Object
535
+ > **transient** name, Object # Sets value
536
+ >
537
+ > **transient** name { Object } # Sets value (lazily)
520
538
  >
521
- > **transients**[name]
539
+ > **transients**[name] # Gets value
522
540
 
523
541
  Sample:
524
542
 
@@ -557,10 +575,15 @@ Sample:
557
575
  Defines default values, which are used to fill in any empty `has`, `embeds` or `transient` fields, before and after respectively. They will *not* overwrite any non-nil value.
558
576
 
559
577
  Definition:
560
- > **before** { |instance| &block }
578
+ > **before**(*:context, :run => Symbol*) { |instance| &block }
561
579
  >
562
580
  > **after** { |instance| &block }
563
581
 
582
+ - `:context` defines when this before should run. Specifying `:embedded` means it runs just before embedded objects are added to the instance. Default (by providing no value) is to run immediately as instance is created.
583
+ - `:run` defines how many times this before can be invoked for an instance. Specifying `:once` means it can only be invoked once (singleton-style.) Default is to always execute. Can only be specified if `:context` is also specified.
584
+
585
+ The latter two options can be useful if you are embedding a template that reads the parent's fields or transients.
586
+
564
587
  Sample:
565
588
 
566
589
  # Template defintion
@@ -597,6 +620,85 @@ Sample:
597
620
  end
598
621
  # Result
599
622
  {
600
- :cpu => "ARM",
601
- :memory_size => "1GB"
623
+ :memory_size => "1GB",
624
+ :cpu => "ARM"
625
+ }
626
+
627
+ Another `before` sample using `:context` and `:run` options:
628
+
629
+ # Template defintions
630
+ Olfactory.template :widget do |t|
631
+ t.embeds_many :doodads, :singular => :doodad
632
+ t.has_one :thingamabob
633
+ t.macro :quality do |m, type|
634
+ m.transient :attribute, type.to_s
635
+ end
636
+ t.before(:embedded) do |d|
637
+ d.quality :dull
638
+ d.thingamabob "thingamabob" if d[:doodads] && d[:doodads].count > 0
639
+ end
640
+ end
641
+ Olfactory.template :doodad do |t|
642
+ t.has_one :gizmo
643
+ t.after do |d|
644
+ d.gizmo "#{d.transients[:attribute]} doodad"
645
+ end
646
+ end
647
+ # Build instance of template
648
+ Olfactory.build :widget do |w|
649
+ w.doodad
650
+ w.quality :shiny
651
+ w.doodad
652
+ end
653
+ # Result
654
+ {
655
+ :doodads => [{ :gizmo => "dull doodad" },
656
+ { :gizmo => "shiny doodad" }]
657
+ # NOTE: A 'thingamabob' wasn't added. This is because the #before only ran once.
602
658
  }
659
+
660
+ ##### #instantiate
661
+
662
+ Defines an 'instantiator': a function you can call to build custom objects from an instance of a template. The block can accept arguments or use the template instance as input, and should return an object or collection. Invoke the block using the `#build` or `#create` method to get the return value from the instantiator. When `#create` is used, any object that responds to `#save!` will be saved.
663
+
664
+ Definition:
665
+ > **instantiate** :name { |instance, *args..| &block }
666
+
667
+ When using:
668
+ > **build**(name*[, arg1, arg2...]*)
669
+ >
670
+ > **create**(name*[, arg1, arg2...]*)
671
+
672
+ Sample:
673
+
674
+ # Template defintion
675
+ Olfactory.template :widget do |t|
676
+ t.has_one :doodad
677
+ t.instantiate :doodad do |i, j|
678
+ String.new("#{i[:doodad]}-instance-#{j}")
679
+ end
680
+ end
681
+ # Build instance of template
682
+ instance = Olfactory.build :widget do |w| w.doodad "doodad" end
683
+ instance.build(:doodad, 1)
684
+ # Result
685
+ "doodad-instance-1"
686
+
687
+ ### Changelog
688
+
689
+ #### Version 0.2.1
690
+
691
+ - Added: `context` and `run` options to `before` blocks.
692
+ - Added: `dimension` option to sequences, to allow scoping.
693
+ - Fixed: Default values not being overridden in special cases.
694
+ - Fixed: Defaults adding to item and subtemplate collections.
695
+
696
+ #### Version 0.2.0
697
+
698
+ - Added: Sequences (like factory_girl's)
699
+ - Added: Dictionaries (generic hash storage)
700
+ - Changed: `#build_template` and `#create_template` have been renamed to `#build` and `#create` respectively.
701
+
702
+ #### Version 0.1.0
703
+
704
+ - Initial version of Olfactory (templates, transients, macros, presets, has/embeds relations)
data/lib/olfactory.rb CHANGED
@@ -35,16 +35,16 @@ module Olfactory
35
35
 
36
36
  # Invocations
37
37
  def self.build(name, options = {}, &block)
38
- self.templates[name].build(block, options)
38
+ self.templates[name].construct(block, options)
39
39
  end
40
40
  def self.create(name, options = {}, &block)
41
- template = self.templates[name].build(block, options)
41
+ template = self.templates[name].construct(block, options)
42
42
  template.save!
43
43
  template
44
44
  end
45
45
  def self.generate(name, options = {}, &block)
46
46
  if sequence = self.sequences[name]
47
- sequence.generate(name, options, block)
47
+ sequence.generate(options, block)
48
48
  else
49
49
  raise "Unknown sequence '#{name}'!"
50
50
  end
@@ -67,8 +67,9 @@ module Olfactory
67
67
  self.sequences[name].reset
68
68
  end
69
69
  end
70
- def self.reset_template_sequences(template, *names)
71
- if template = self.templates[template]
70
+ def self.reset_template_sequences(template = nil, *names)
71
+ templates = template.nil? ? self.templates.values : [self.templates[template]].compact
72
+ templates.each do |template|
72
73
  template.reset_sequences(*names)
73
74
  end
74
75
  end
@@ -78,8 +79,9 @@ module Olfactory
78
79
  self.dictionaries[name].reset
79
80
  end
80
81
  end
81
- def self.reset_template_dictionaries(template, *names)
82
- if template = self.templates[template]
82
+ def self.reset_template_dictionaries(template = nil, *names)
83
+ templates = template.nil? ? self.templates.values : [self.templates[template]].compact
84
+ templates.each do |template|
83
85
  template.reset_dictionaries(*names)
84
86
  end
85
87
  end
@@ -6,19 +6,20 @@ module Olfactory
6
6
  self[:evaluator] = block
7
7
  self[:scope] = (options[:scope] || :global)
8
8
  self[:seed] = (options[:seed] || 0)
9
- self[:current_seed] = (options[:seed] || 0)
9
+ self[:dimensions] = { nil => { :current_seed => (options[:seed] || 0) } }
10
10
  end
11
11
 
12
- def generate(name, options, block)
13
- seed = options[:seed] || self[:current_seed]
12
+ def generate(options = {}, block)
13
+ seed = options[:seed] || (self[:dimensions][options[:dimension]] ||= { :current_seed => self[:seed] })[:current_seed]
14
14
  target = block || self[:evaluator]
15
- value = target.call(seed, options.reject { |k,v| k == :seed })
16
- self[:current_seed] += 1 if !options.has_key?(:seed)
15
+ value = target.call(seed, options.reject { |k,v| [:seed, :dimension].include?(k) })
16
+ self[:dimensions][options[:dimension]][:current_seed] += 1 if !options.has_key?(:seed)
17
17
 
18
18
  value
19
19
  end
20
20
  def reset
21
- self[:current_seed] = self[:seed]
21
+ self[:dimensions].values.each { |v| v[:current_seed] = self[:seed] }
22
+ self
22
23
  end
23
24
  end
24
25
  end
@@ -1,16 +1,26 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  module Olfactory
3
3
  class Template < Hash
4
- attr_accessor :definition, :transients, :sequences, :dictionaries, :default_mode
4
+ attr_accessor :definition,
5
+ :transients,
6
+ :sequences,
7
+ :dictionaries,
8
+ :default_mode,
9
+ :default_populated,
10
+ :default_populated_transients,
11
+ :block_invocations
5
12
 
6
13
  def initialize(definition, options = {})
7
14
  self.definition = definition
8
15
  self.transients = options[:transients] ? options[:transients].clone : {}
9
16
  self.sequences = options[:sequences] ? options[:sequences].clone : {}
10
17
  self.dictionaries = options[:dictionaries] ? options[:dictionaries].clone : {}
18
+ self.default_populated = {}
19
+ self.default_populated_transients = {}
20
+ self.block_invocations = []
11
21
  end
12
22
 
13
- def build(block, options = {})
23
+ def construct(block, options = {})
14
24
  self.add_defaults(:before) if options[:defaults].nil? || options[:defaults]
15
25
  if block # Block can be nil (when we want only defaults)
16
26
  if options[:value]
@@ -20,10 +30,8 @@ module Olfactory
20
30
  end
21
31
  end
22
32
  self.add_defaults(:after) if options[:defaults].nil? || options[:defaults]
23
-
24
33
  self
25
34
  end
26
-
27
35
  def save!
28
36
  # Items, then subtemplates
29
37
  [self.definition.t_items, self.definition.t_subtemplates].each do |field_group_definitions|
@@ -49,8 +57,8 @@ module Olfactory
49
57
  super # Unknown method
50
58
  end
51
59
  end
52
- def can_set_field?(meth)
53
- !(self.default_mode && self.has_key?(meth))
60
+ def can_set_field?(name)
61
+ !(self.default_mode && self.has_key?(name)) || (self.default_mode && (self.default_populated[name] == true))
54
62
  end
55
63
  def extract_variable_name(args)
56
64
  variable_name = args.first
@@ -59,13 +67,20 @@ module Olfactory
59
67
  end
60
68
  def populate_field(field_definition, meth, args, block)
61
69
  if field_definition[:type] == :macro
62
- field_value = build_macro(field_definition, args, block)
70
+ field_value = construct_macro(field_definition, args, block)
63
71
  do_not_set_value = true
64
- elsif field_definition[:type] == :subtemplate && can_set_field?(meth)
72
+ elsif field_definition[:type] == :subtemplate && can_set_field?(field_definition[:name])
65
73
  subtemplate_name = field_definition.has_key?(:template) ? field_definition[:template] : field_definition[:name]
66
74
  subtemplate_definition = Olfactory.templates[subtemplate_name]
67
75
  subtemplate_definition ||= Olfactory.templates[field_definition[:singular]]
68
76
  if subtemplate_definition
77
+ # Invoke before clauses
78
+ self.add_defaults(:before_embedded)
79
+ # self.default_mode = true
80
+ # before_block = field_definition[:evaluator]
81
+ # before_block.call(self) if before_block
82
+ # self.default_mode = false
83
+
69
84
  if field_definition[:collection] && field_definition[:collection] <= Array
70
85
  # Embeds many
71
86
  if meth == field_definition[:singular]
@@ -73,14 +88,14 @@ module Olfactory
73
88
  grammar = :singular
74
89
  preset_name = args.first
75
90
 
76
- field_value = build_one_subtemplate(subtemplate_definition, preset_name, block)
91
+ field_value = construct_one_subtemplate(subtemplate_definition, preset_name, block)
77
92
  else
78
93
  # Plural
79
94
  grammar = :plural
80
95
  quantity = args.detect { |value| value.class <= Integer }
81
96
  preset_name = args.detect { |value| value != quantity }
82
97
 
83
- field_value = build_many_subtemplates(subtemplate_definition, quantity, preset_name, block)
98
+ field_value = construct_many_subtemplates(subtemplate_definition, quantity, preset_name, block)
84
99
  do_not_set_value if field_value.nil?
85
100
  end
86
101
  elsif field_definition[:collection] && field_definition[:collection] <= Hash
@@ -92,7 +107,7 @@ module Olfactory
92
107
  args = args[1..(args.size-1)]
93
108
  preset_name = args.first
94
109
 
95
- field_value = build_one_subtemplate(subtemplate_definition, preset_name, block)
110
+ field_value = construct_one_subtemplate(subtemplate_definition, preset_name, block)
96
111
  do_not_set_value if field_value.nil? # || field_value.empty?
97
112
  else
98
113
  # Plural
@@ -104,13 +119,16 @@ module Olfactory
104
119
  # Embeds one
105
120
  preset_name = args.first
106
121
 
107
- field_value = build_one_subtemplate(subtemplate_definition, preset_name, block)
122
+ field_value = construct_one_subtemplate(subtemplate_definition, preset_name, block)
108
123
  do_not_set_value if field_value.nil?
109
124
  end
125
+
126
+ # Invoke after clauses
127
+ self.add_defaults(:after_embedded)
110
128
  else
111
129
  raise "Could not find a template matching '#{subtemplate_name}'!"
112
130
  end
113
- elsif field_definition[:type] == :item && can_set_field?(meth)
131
+ elsif field_definition[:type] == :item && can_set_field?(field_definition[:name])
114
132
  if field_definition[:collection] && field_definition[:collection] <= Array
115
133
  # Has many
116
134
  if meth == field_definition[:singular]
@@ -118,7 +136,7 @@ module Olfactory
118
136
  grammar = :singular
119
137
  obj = args.count == 1 ? args.first : args
120
138
 
121
- field_value = build_one_item(field_definition, obj, block)
139
+ field_value = construct_one_item(field_definition, obj, block)
122
140
  do_not_set_value = true if field_value.nil?
123
141
  else
124
142
  # Plural
@@ -126,7 +144,7 @@ module Olfactory
126
144
  quantity = args.first if block && args.first.class <= Integer
127
145
  arr = args.first if args.count == 1 && args.first.class <= Array
128
146
 
129
- field_value = build_many_items(field_definition, quantity, arr, args, block)
147
+ field_value = construct_many_items(field_definition, quantity, arr, args, block)
130
148
  do_not_set_value = true if field_value.empty?
131
149
  end
132
150
  elsif field_definition[:collection] && field_definition[:collection] <= Hash
@@ -138,7 +156,7 @@ module Olfactory
138
156
  args = args[1..(args.size-1)]
139
157
  obj = args.first
140
158
 
141
- field_value = build_one_item(field_definition, obj, block)
159
+ field_value = construct_one_item(field_definition, obj, block)
142
160
  do_not_set_value = true if field_value.nil?
143
161
  else
144
162
  # Plural
@@ -155,7 +173,7 @@ module Olfactory
155
173
  # Has one
156
174
  obj = args.first
157
175
 
158
- field_value = build_one_item(field_definition, obj, block)
176
+ field_value = construct_one_item(field_definition, obj, block)
159
177
  end
160
178
  elsif field_definition.class == Olfactory::Dictionary
161
179
  if field_definition.scope == :template
@@ -188,79 +206,116 @@ module Olfactory
188
206
  else
189
207
  return_value = self[field_definition[:name]] = field_value
190
208
  end
209
+ if self.default_mode && (self.default_populated[field_definition[:name]] != false)
210
+ self.default_populated[field_definition[:name]] = true
211
+ else
212
+ self.default_populated[field_definition[:name]] = false
213
+ end
191
214
  end
192
215
  return_value
193
216
  end
194
- def transient(name, value)
195
- self.transients[name] = value if !(self.default_mode && self.transients.has_key?(name))
217
+ def transient(name, value = nil, &block)
218
+ if !(self.default_mode && self.transients.has_key?(name)) || (self.default_mode && (self.default_populated_transients[name] == true))
219
+ self.transients[name] = (block ? block.call : value)
220
+ if self.default_mode && (self.default_populated_transients[name] != false)
221
+ self.default_populated_transients[name] = true
222
+ else
223
+ self.default_populated_transients[name] = false
224
+ end
225
+ end
196
226
  end
197
227
  def generate(name, options = {}, &block)
198
228
  sequence = self.definition.t_sequences[name]
199
229
  # Template scope
200
230
  if sequence && sequence[:scope] == :template
201
- value = sequence.generate(name, options, block)
231
+ value = sequence.generate(options, block)
202
232
  # Instance scope
203
233
  elsif sequence && sequence[:scope] == :instance
204
- self.sequences[name] ||= { :current_seed => (options[:seed] || sequence[:seed]) }
205
- value = sequence.generate(name, options.merge(:seed => self.sequences[name][:current_seed]), block)
206
- self.sequences[name][:current_seed] += 1 if !options.has_key?(:seed)
234
+ self.sequences[name] ||= sequence.dup.reset
235
+ value = self.sequences[name].generate(options, block)
236
+ # self.sequences[name][:current_seed] += 1 if !options.has_key?(:seed)
207
237
  else
208
238
  raise "Unknown sequence '#{name}'!"
209
239
  end
210
240
  value
211
241
  end
242
+ def build(name, *args)
243
+ if instantiator_definition = self.definition.t_instantiators[name]
244
+ instantiator_definition[:evaluator].call(self, *args)
245
+ end
246
+ end
247
+ def create(name, *args)
248
+ obj = self.build(name, *args)
249
+ if obj.class <= Array
250
+ obj.each { |o| o.save! if o.respond_to?(:save!) }
251
+ elsif obj.class <= Hash
252
+ obj.values.each { |o| o.save! if o.respond_to?(:save!) }
253
+ elsif obj.respond_to?(:save!)
254
+ obj.save!
255
+ end
256
+ obj
257
+ end
212
258
  def add_defaults(mode)
213
259
  # Prevents overwrites of custom values by defaults
214
260
  self.default_mode = true # Hackish for sure, but its efficient...
215
261
 
216
262
  case mode
217
263
  when :before
218
- default_definition = definition.t_before
264
+ default_definitions = definition.t_befores[:all]
219
265
  when :after
220
- default_definition = definition.t_after
266
+ default_definitions = definition.t_afters[:all]
267
+ when :before_embedded
268
+ default_definitions = definition.t_befores[:embedded]
269
+ when :after_embedded
270
+ default_definitions = definition.t_afters[:embedded]
221
271
  end
222
-
223
- if default_definition[:evaluator]
224
- default_definition[:evaluator].call(self)
225
- elsif default_definition[:preset]
226
- preset_definition = definition.find_preset_definition(default_definition[:preset])
227
- preset_definition[:evaluator].call(self)
272
+ default_definitions ||= []
273
+ default_definitions.reject! { |dfn| dfn[:run] == :once && self.block_invocations.include?(dfn.object_id) }
274
+
275
+ default_definitions.each do |default_definition|
276
+ if default_definition[:evaluator]
277
+ default_definition[:evaluator].call(self)
278
+ elsif default_definition[:preset]
279
+ preset_definition = definition.find_preset_definition(default_definition[:preset])
280
+ preset_definition[:evaluator].call(self)
281
+ end
282
+ self.block_invocations << default_definition.object_id if default_definition[:run] # Mark block as invoked
228
283
  end
229
284
 
230
285
  self.default_mode = false
231
286
  end
232
- def build_macro(macro_definition, args, block)
287
+ def construct_macro(macro_definition, args, block)
233
288
  if macro_definition[:evaluator]
234
289
  macro_definition[:evaluator].call(self, *args)
235
290
  end
236
291
  end
237
- def build_one_subtemplate(subtemplate_definition, preset_name, block)
292
+ def construct_one_subtemplate(subtemplate_definition, preset_name, block)
238
293
  # Block
239
294
  if block
240
- subtemplate_definition.build(block, :transients => self.transients)
295
+ subtemplate_definition.construct(block, :transients => self.transients)
241
296
  # Preset Name
242
297
  elsif preset_name
243
- subtemplate_definition.build_preset(preset_name, 1, :transients => self.transients)
298
+ subtemplate_definition.construct_preset(preset_name, 1, :transients => self.transients)
244
299
  # Default (nothing)
245
300
  else
246
- subtemplate_definition.build(nil, :transients => self.transients)
301
+ subtemplate_definition.construct(nil, :transients => self.transients)
247
302
  end
248
303
  end
249
- def build_many_subtemplates(subtemplate_definition, quantity, preset_name, block)
304
+ def construct_many_subtemplates(subtemplate_definition, quantity, preset_name, block)
250
305
  # Integer, Block
251
306
  if quantity && block
252
- Array.new(quantity) { subtemplate_definition.build(block, :transients => self.transients) }
307
+ Array.new(quantity) { subtemplate_definition.construct(block, :transients => self.transients) }
253
308
  # Integer, Preset Name
254
309
  elsif quantity && preset_name
255
- subtemplate_definition.build_preset(preset_name, quantity, :transients => self.transients)
310
+ subtemplate_definition.construct_preset(preset_name, quantity, :transients => self.transients)
256
311
  # Integer
257
312
  elsif quantity
258
- Array.new(quantity) { subtemplate_definition.build(nil, :transients => self.transients) }
313
+ Array.new(quantity) { subtemplate_definition.construct(nil, :transients => self.transients) }
259
314
  else
260
315
  nil
261
316
  end
262
317
  end
263
- def build_one_item(item_definition, obj, block)
318
+ def construct_one_item(item_definition, obj, block)
264
319
  if block
265
320
  block.call
266
321
  elsif obj
@@ -269,7 +324,7 @@ module Olfactory
269
324
  nil
270
325
  end
271
326
  end
272
- def build_many_items(item_definition, quantity, arr, args, block)
327
+ def construct_many_items(item_definition, quantity, arr, args, block)
273
328
  # Integer, Block
274
329
  if quantity && block
275
330
  Array.new(quantity) { block.call }