thoughtbot-factory_girl 1.1.5 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/README.rdoc +228 -0
  2. data/Rakefile +7 -5
  3. data/lib/factory_girl.rb +11 -4
  4. data/lib/factory_girl/aliases.rb +18 -7
  5. data/lib/factory_girl/attribute.rb +10 -20
  6. data/lib/factory_girl/attribute/association.rb +18 -0
  7. data/lib/factory_girl/attribute/dynamic.rb +17 -0
  8. data/lib/factory_girl/attribute/static.rb +17 -0
  9. data/lib/factory_girl/factory.rb +199 -119
  10. data/lib/factory_girl/proxy.rb +62 -0
  11. data/lib/factory_girl/proxy/attributes_for.rb +21 -0
  12. data/lib/factory_girl/proxy/build.rb +29 -0
  13. data/lib/factory_girl/proxy/create.rb +10 -0
  14. data/lib/factory_girl/proxy/stub.rb +28 -0
  15. data/lib/factory_girl/sequence.rb +2 -0
  16. data/lib/factory_girl/syntax.rb +12 -0
  17. data/lib/factory_girl/syntax/blueprint.rb +42 -0
  18. data/lib/factory_girl/syntax/generate.rb +68 -0
  19. data/lib/factory_girl/syntax/make.rb +39 -0
  20. data/lib/factory_girl/syntax/sham.rb +42 -0
  21. data/test/aliases_test.rb +1 -1
  22. data/test/association_attribute_test.rb +31 -0
  23. data/test/attribute_test.rb +8 -46
  24. data/test/attributes_for_strategy_test.rb +55 -0
  25. data/test/build_strategy_test.rb +79 -0
  26. data/test/create_strategy_test.rb +90 -0
  27. data/test/dynamic_attribute_test.rb +41 -0
  28. data/test/factory_test.rb +255 -243
  29. data/test/integration_test.rb +91 -3
  30. data/test/models.rb +1 -0
  31. data/test/sequence_test.rb +1 -1
  32. data/test/static_attribute_test.rb +33 -0
  33. data/test/strategy_test.rb +33 -0
  34. data/test/stub_strategy_test.rb +52 -0
  35. data/test/syntax/blueprint_test.rb +39 -0
  36. data/test/syntax/generate_test.rb +63 -0
  37. data/test/syntax/make_test.rb +39 -0
  38. data/test/syntax/sham_test.rb +40 -0
  39. data/test/test_helper.rb +1 -0
  40. metadata +42 -8
  41. data/README.textile +0 -151
  42. data/lib/factory_girl/attribute_proxy.rb +0 -92
  43. data/test/attribute_proxy_test.rb +0 -121
@@ -0,0 +1,55 @@
1
+ require 'test_helper'
2
+
3
+ class AttributesForProxyTest < Test::Unit::TestCase
4
+
5
+ context "the attributes_for proxy" do
6
+ setup do
7
+ @proxy = Factory::Proxy::AttributesFor.new(@class)
8
+ end
9
+
10
+ context "when asked to associate with another factory" do
11
+ setup do
12
+ Factory.stubs(:create)
13
+ @proxy.associate(:owner, :user, {})
14
+ end
15
+
16
+ should "not set a value for the association" do
17
+ assert !@proxy.result.key?(:owner)
18
+ end
19
+ end
20
+
21
+ should "return nil when building an association" do
22
+ assert_nil @proxy.association(:user)
23
+ end
24
+
25
+ should "not call Factory.create when building an association" do
26
+ Factory.expects(:create).never
27
+ assert_nil @proxy.association(:user)
28
+ end
29
+
30
+ should "always return nil when building an association" do
31
+ @proxy.set(:association, 'x')
32
+ assert_nil @proxy.association(:user)
33
+ end
34
+
35
+ should "return a hash when asked for the result" do
36
+ assert_kind_of Hash, @proxy.result
37
+ end
38
+
39
+ context "after setting an attribute" do
40
+ setup do
41
+ @proxy.set(:attribute, 'value')
42
+ end
43
+
44
+ should "set that value in the resulting hash" do
45
+ assert_equal 'value', @proxy.result[:attribute]
46
+ end
47
+
48
+ should "return that value when asked for that attribute" do
49
+ assert_equal 'value', @proxy.get(:attribute)
50
+ end
51
+ end
52
+ end
53
+
54
+ end
55
+
@@ -0,0 +1,79 @@
1
+ require 'test_helper'
2
+
3
+ class BuildProxyTest < Test::Unit::TestCase
4
+
5
+ context "with a class to build" do
6
+ setup do
7
+ @class = Class.new
8
+ @instance = mock('built-instance')
9
+ @association = mock('associated-instance')
10
+
11
+ @class. stubs(:new). returns(@instance)
12
+ @instance.stubs(:attribute).returns('value')
13
+ Factory. stubs(:create). returns(@association)
14
+ @instance.stubs(:attribute=)
15
+ @instance.stubs(:owner=)
16
+ end
17
+
18
+ context "the build proxy" do
19
+ setup do
20
+ @proxy = Factory::Proxy::Build.new(@class)
21
+ end
22
+
23
+ before_should "instantiate the class" do
24
+ @class.expects(:new).with().returns(@instance)
25
+ end
26
+
27
+ context "when asked to associate with another factory" do
28
+ setup do
29
+ @proxy.associate(:owner, :user, {})
30
+ end
31
+
32
+ before_should "create the associated instance" do
33
+ Factory.expects(:create).with(:user, {}).returns(@association)
34
+ end
35
+
36
+ before_should "set the associated instance" do
37
+ @instance.expects(:owner=).with(@association)
38
+ end
39
+ end
40
+
41
+ should "call Factory.create when building an association" do
42
+ association = 'association'
43
+ attribs = { :first_name => 'Billy' }
44
+ Factory.expects(:create).with(:user, attribs).returns(association)
45
+ assert_equal association, @proxy.association(:user, attribs)
46
+ end
47
+
48
+ should "return the built instance when asked for the result" do
49
+ assert_equal @instance, @proxy.result
50
+ end
51
+
52
+ context "when setting an attribute" do
53
+ setup do
54
+ @proxy.set(:attribute, 'value')
55
+ end
56
+
57
+ before_should "set that value" do
58
+ @instance.expects(:attribute=).with('value')
59
+ end
60
+ end
61
+
62
+ context "when getting an attribute" do
63
+ setup do
64
+ @result = @proxy.get(:attribute)
65
+ end
66
+
67
+ before_should "ask the built class for the value" do
68
+ @instance.expects(:attribute).with().returns('value')
69
+ end
70
+
71
+ should "return the value for that attribute" do
72
+ assert_equal 'value', @result
73
+ end
74
+ end
75
+ end
76
+ end
77
+
78
+ end
79
+
@@ -0,0 +1,90 @@
1
+ require 'test_helper'
2
+
3
+ class CreateProxyTest < Test::Unit::TestCase
4
+
5
+ context "with a class to build" do
6
+ setup do
7
+ @class = Class.new
8
+ @instance = mock('built-instance')
9
+ @association = mock('associated-instance')
10
+
11
+ @class. stubs(:new). returns(@instance)
12
+ Factory. stubs(:create). returns(@association)
13
+ @instance.stubs(:attribute).returns('value')
14
+ @instance.stubs(:attribute=)
15
+ @instance.stubs(:owner=)
16
+ @instance.stubs(:save!)
17
+ end
18
+
19
+ context "the create proxy" do
20
+ setup do
21
+ @proxy = Factory::Proxy::Create.new(@class)
22
+ end
23
+
24
+ before_should "instantiate the class" do
25
+ @class.expects(:new).with().returns(@instance)
26
+ end
27
+
28
+ context "when asked to associate with another factory" do
29
+ setup do
30
+ @proxy.associate(:owner, :user, {})
31
+ end
32
+
33
+ before_should "create the associated instance" do
34
+ Factory.expects(:create).with(:user, {}).returns(@association)
35
+ end
36
+
37
+ before_should "set the associated instance" do
38
+ @instance.expects(:owner=).with(@association)
39
+ end
40
+ end
41
+
42
+ should "call Factory.create when building an association" do
43
+ association = 'association'
44
+ attribs = { :first_name => 'Billy' }
45
+ Factory.expects(:create).with(:user, attribs).returns(association)
46
+ assert_equal association, @proxy.association(:user, attribs)
47
+ end
48
+
49
+ context "when asked for the result" do
50
+ setup do
51
+ @result = @proxy.result
52
+ end
53
+
54
+ before_should "save the instance" do
55
+ @instance.expects(:save!).with()
56
+ end
57
+
58
+ should "return the built instance" do
59
+ assert_equal @instance, @result
60
+ end
61
+ end
62
+
63
+ context "when setting an attribute" do
64
+ setup do
65
+ @proxy.set(:attribute, 'value')
66
+ end
67
+
68
+ before_should "set that value" do
69
+ @instance.expects(:attribute=).with('value')
70
+ end
71
+ end
72
+
73
+ context "when getting an attribute" do
74
+ setup do
75
+ @result = @proxy.get(:attribute)
76
+ end
77
+
78
+ before_should "ask the built class for the value" do
79
+ @instance.expects(:attribute).with().returns('value')
80
+ end
81
+
82
+ should "return the value for that attribute" do
83
+ assert_equal 'value', @result
84
+ end
85
+ end
86
+ end
87
+ end
88
+
89
+ end
90
+
@@ -0,0 +1,41 @@
1
+ require 'test_helper'
2
+
3
+ class DynamicAttributeTest < Test::Unit::TestCase
4
+
5
+ context "a static attribute" do
6
+ setup do
7
+ @name = :first_name
8
+ @block = lambda { 'value' }
9
+ @attr = Factory::Attribute::Dynamic.new(@name, @block)
10
+ end
11
+
12
+ should "have a name" do
13
+ assert_equal @name, @attr.name
14
+ end
15
+
16
+ should "call the block to set a value" do
17
+ @proxy = mock('proxy')
18
+ @proxy.expects(:set).with(@name, 'value')
19
+ @attr.add_to(@proxy)
20
+ end
21
+
22
+ should "yield the proxy to the block when adding its value to a proxy" do
23
+ @block = lambda {|a| a }
24
+ @attr = Factory::Attribute::Dynamic.new(:user, @block)
25
+ @proxy = mock('proxy')
26
+ @proxy.expects(:set).with(:user, @proxy)
27
+ @attr.add_to(@proxy)
28
+ end
29
+ end
30
+
31
+ should "raise an error when defining an attribute writer" do
32
+ assert_raise Factory::AttributeDefinitionError do
33
+ Factory::Attribute::Dynamic.new('test=', nil)
34
+ end
35
+ end
36
+
37
+ should "convert names to symbols" do
38
+ assert_equal :name, Factory::Attribute::Dynamic.new('name', nil).name
39
+ end
40
+
41
+ end
data/test/factory_test.rb CHANGED
@@ -1,28 +1,8 @@
1
- require(File.join(File.dirname(__FILE__), 'test_helper'))
1
+ require 'test_helper'
2
2
 
3
3
  class FactoryTest < Test::Unit::TestCase
4
-
5
- def self.should_instantiate_class
6
-
7
- should "instantiate the build class" do
8
- assert_kind_of @class, @instance
9
- end
10
-
11
- should "assign attributes on the instance" do
12
- assert_equal @first_name, @instance.first_name
13
- assert_equal @last_name, @instance.last_name
14
- end
15
-
16
- should "override attributes using the passed hash" do
17
- @value = 'Davis'
18
- @instance = @factory.build(:first_name => @value)
19
- assert_equal @value, @instance.first_name
20
- end
21
-
22
- end
23
-
4
+ factory = Factory.new(:post)
24
5
  context "defining a factory" do
25
-
26
6
  setup do
27
7
  @name = :user
28
8
  @factory = mock('factory')
@@ -50,11 +30,9 @@ class FactoryTest < Test::Unit::TestCase
50
30
  @factory,
51
31
  "Factories: #{Factory.factories.inspect}"
52
32
  end
53
-
54
33
  end
55
34
 
56
35
  context "a factory" do
57
-
58
36
  setup do
59
37
  @name = :user
60
38
  @class = User
@@ -68,146 +46,161 @@ class FactoryTest < Test::Unit::TestCase
68
46
  should "have a build class" do
69
47
  assert_equal @class, @factory.build_class
70
48
  end
49
+
50
+ should "have a default strategy" do
51
+ assert_equal :create, @factory.default_strategy
52
+ end
71
53
 
72
54
  should "not allow the same attribute to be added twice" do
73
55
  assert_raise(Factory::AttributeDefinitionError) do
74
- 2.times { @factory.add_attribute @name }
56
+ 2.times { @factory.add_attribute :first_name }
75
57
  end
76
58
  end
77
-
78
- context "when adding an attribute with a value parameter" do
79
-
80
- setup do
81
- @attr = :name
82
- @value = 'Elvis lives!'
83
- @factory.add_attribute(@attr, @value)
84
- end
85
-
86
- should "include that value in the generated attributes hash" do
87
- assert_equal @value, @factory.attributes_for[@attr]
59
+
60
+ should "add a static attribute when an attribute is defined with a value" do
61
+ attribute = mock('attribute', :name => :name)
62
+ Factory::Attribute::Static.
63
+ expects(:new).
64
+ with(:name, 'value').
65
+ returns(attribute)
66
+ @factory.add_attribute(:name, 'value')
67
+ end
68
+
69
+ should "add a dynamic attribute when an attribute is defined with a block" do
70
+ attribute = mock('attribute', :name => :name)
71
+ block = lambda {}
72
+ Factory::Attribute::Dynamic.
73
+ expects(:new).
74
+ with(:name, block).
75
+ returns(attribute)
76
+ @factory.add_attribute(:name, &block)
77
+ end
78
+
79
+ should "raise for an attribute with a value and a block" do
80
+ assert_raise(Factory::AttributeDefinitionError) do
81
+ @factory.add_attribute(:name, 'value') {}
88
82
  end
89
-
90
83
  end
91
-
92
- context "when adding an attribute with a block" do
93
-
94
- setup do
95
- @attr = :name
96
- @attrs = {}
97
- @proxy = mock('attr-proxy')
98
- Factory::AttributeProxy.stubs(:new).returns(@proxy)
99
- end
100
-
101
- should "not evaluate the block when the attribute is added" do
102
- @factory.add_attribute(@attr) { flunk }
103
- end
104
-
105
- should "evaluate the block when attributes are generated" do
106
- called = false
107
- @factory.add_attribute(@attr) do
108
- called = true
109
- end
110
- @factory.attributes_for
111
- assert called
112
- end
113
-
114
- should "use the result of the block as the value of the attribute" do
115
- value = "Watch out for snakes!"
116
- @factory.add_attribute(@attr) { value }
117
- assert_equal value, @factory.attributes_for[@attr]
118
- end
119
-
120
- should "build an attribute proxy" do
121
- Factory::AttributeProxy.expects(:new).with(@factory, @attr, :attributes_for, @attrs)
122
- @factory.add_attribute(@attr) {}
123
- @factory.attributes_for
124
- end
125
-
126
- should "yield an attribute proxy to the block" do
127
- yielded = nil
128
- @factory.add_attribute(@attr) {|y| yielded = y }
129
- @factory.attributes_for
130
- assert_equal @proxy, yielded
131
- end
132
-
133
- context "when other attributes have previously been defined" do
134
-
135
- setup do
136
- @attr = :unimportant
137
- @attrs = {
138
- :one => 'whatever',
139
- :another => 'soup'
140
- }
141
- @factory.add_attribute(:one, 'whatever')
142
- @factory.add_attribute(:another) { 'soup' }
143
- @factory.add_attribute(@attr) {}
144
- end
145
-
146
- should "provide previously set attributes" do
147
- Factory::AttributeProxy.expects(:new).with(@factory, @attr, :attributes_for, @attrs)
148
- @factory.attributes_for
149
- end
150
-
84
+
85
+ context "adding an attribute using a in-line sequence" do
86
+ should 'create the sequence' do
87
+ Factory::Sequence.
88
+ expects(:new)
89
+ @factory.sequence(:name) {}
90
+ end
91
+
92
+ should 'add a dynamic attribute' do
93
+ attr = mock('attribute', :name => :name)
94
+ Factory::Attribute::Dynamic.
95
+ expects(:new).
96
+ with(:name, instance_of(Proc)).
97
+ returns(attr)
98
+ @factory.sequence(:name) {}
99
+ assert @factory.attributes.include?(attr)
151
100
  end
101
+ end
152
102
 
153
- end
154
-
155
- context "when adding an association without a factory name" do
156
-
103
+ context "after adding an attribute" do
157
104
  setup do
158
- @factory = Factory.new(:post)
159
- @name = :user
160
- @factory.association(@name)
161
- Post.any_instance.stubs(:user=)
162
- Factory.stubs(:create)
163
- end
164
-
165
- should "add an attribute with the name of the association" do
166
- assert @factory.attributes_for.key?(@name)
167
- end
168
-
169
- should "create a block that builds the association" do
170
- Factory.expects(:create).with(@name, {})
171
- @factory.build
172
- end
173
-
105
+ @attribute = mock('attribute')
106
+ @proxy = mock('proxy')
107
+
108
+ @attribute. stubs(:name). returns(:name)
109
+ @attribute. stubs(:add_to)
110
+ @proxy. stubs(:set)
111
+ @proxy. stubs(:result).returns('result')
112
+ Factory::Attribute::Static.stubs(:new). returns(@attribute)
113
+ Factory::Proxy::Build. stubs(:new). returns(@proxy)
114
+
115
+ @factory.add_attribute(:name, 'value')
116
+ end
117
+
118
+ should "create the right proxy using the build class when running" do
119
+ Factory::Proxy::Build.
120
+ expects(:new).
121
+ with(@factory.build_class).
122
+ returns(@proxy)
123
+ @factory.run(Factory::Proxy::Build, {})
124
+ end
125
+
126
+ should "add the attribute to the proxy when running" do
127
+ @attribute.expects(:add_to).with(@proxy)
128
+ @factory.run(Factory::Proxy::Build, {})
129
+ end
130
+
131
+ should "return the result from the proxy when running" do
132
+ @proxy.expects(:result).with().returns('result')
133
+ assert_equal 'result',
134
+ @factory.run(Factory::Proxy::Build, {})
135
+ end
136
+ end
137
+
138
+ should "add an association without a factory name or overrides" do
139
+ factory = Factory.new(:post)
140
+ name = :user
141
+ attr = 'attribute'
142
+ Factory::Attribute::Association.
143
+ expects(:new).
144
+ with(name, name, {}).
145
+ returns(attr)
146
+ factory.association(name)
147
+ assert factory.attributes.include?(attr)
148
+ end
149
+
150
+ should "add an association with overrides" do
151
+ factory = Factory.new(:post)
152
+ name = :user
153
+ attr = 'attribute'
154
+ overrides = { :first_name => 'Ben' }
155
+ Factory::Attribute::Association.
156
+ expects(:new).
157
+ with(name, name, overrides).
158
+ returns(attr)
159
+ factory.association(name, overrides)
160
+ assert factory.attributes.include?(attr)
161
+ end
162
+
163
+ should "add an association with a factory name" do
164
+ factory = Factory.new(:post)
165
+ attr = 'attribute'
166
+ Factory::Attribute::Association.
167
+ expects(:new).
168
+ with(:author, :user, {}).
169
+ returns(attr)
170
+ factory.association(:author, :factory => :user)
171
+ assert factory.attributes.include?(attr)
172
+ end
173
+
174
+ should "add an association with a factory name and overrides" do
175
+ factory = Factory.new(:post)
176
+ attr = 'attribute'
177
+ Factory::Attribute::Association.
178
+ expects(:new).
179
+ with(:author, :user, :first_name => 'Ben').
180
+ returns(attr)
181
+ factory.association(:author, :factory => :user, :first_name => 'Ben')
182
+ assert factory.attributes.include?(attr)
174
183
  end
175
-
176
- context "when adding an association with a factory name" do
177
-
178
- setup do
179
- @factory = Factory.new(:post)
180
- @name = :author
181
- @factory_name = :user
182
- @factory.association(@name, :factory => @factory_name)
183
- Factory.stubs(:create)
184
- end
185
-
186
- should "add an attribute with the name of the association" do
187
- assert @factory.attributes_for.key?(@name)
188
- end
189
-
190
- should "create a block that builds the association" do
191
- Factory.expects(:create).with(@factory_name, {})
192
- @factory.build
184
+
185
+ should "raise for a self referencing association" do
186
+ factory = Factory.new(:post)
187
+ assert_raise(Factory::AssociationDefinitionError) do
188
+ factory.association(:parent, :factory => :post)
193
189
  end
194
-
195
- end
190
+ end
196
191
 
197
192
  should "add an attribute using the method name when passed an undefined method" do
198
- @attr = :first_name
199
- @value = 'Sugar'
200
- @factory.send(@attr, @value)
201
- assert_equal @value, @factory.attributes_for[@attr]
193
+ attr = mock('attribute', :name => :name)
194
+ block = lambda {}
195
+ Factory::Attribute::Static.
196
+ expects(:new).
197
+ with(:name, 'value').
198
+ returns(attr)
199
+ @factory.send(:name, 'value')
200
+ assert @factory.attributes.include?(attr)
202
201
  end
203
-
204
- should "allow attributes to be added with strings as names" do
205
- @factory.add_attribute('name', 'value')
206
- assert_equal 'value', @factory.attributes_for[:name]
207
- end
208
-
202
+
209
203
  context "when overriding generated attributes with a hash" do
210
-
211
204
  setup do
212
205
  @attr = :name
213
206
  @value = 'The price is right!'
@@ -216,28 +209,29 @@ class FactoryTest < Test::Unit::TestCase
216
209
 
217
210
  should "return the overridden value in the generated attributes" do
218
211
  @factory.add_attribute(@attr, 'The price is wrong, Bob!')
219
- assert_equal @value, @factory.attributes_for(@hash)[@attr]
212
+ result = @factory.run(Factory::Proxy::AttributesFor, @hash)
213
+ assert_equal @value, result[@attr]
220
214
  end
221
215
 
222
216
  should "not call a lazy attribute block for an overridden attribute" do
223
217
  @factory.add_attribute(@attr) { flunk }
224
- @factory.attributes_for(@hash)
218
+ result = @factory.run(Factory::Proxy::AttributesFor, @hash)
225
219
  end
226
220
 
227
221
  should "override a symbol parameter with a string parameter" do
228
222
  @factory.add_attribute(@attr, 'The price is wrong, Bob!')
229
223
  @hash = { @attr.to_s => @value }
230
- assert_equal @value, @factory.attributes_for(@hash)[@attr]
224
+ result = @factory.run(Factory::Proxy::AttributesFor, @hash)
225
+ assert_equal @value, result[@attr]
231
226
  end
232
-
233
227
  end
234
228
 
235
229
  context "overriding an attribute with an alias" do
236
-
237
230
  setup do
238
231
  @factory.add_attribute(:test, 'original')
239
232
  Factory.alias(/(.*)_alias/, '\1')
240
- @result = @factory.attributes_for(:test_alias => 'new')
233
+ @result = @factory.run(Factory::Proxy::AttributesFor,
234
+ :test_alias => 'new')
241
235
  end
242
236
 
243
237
  should "use the passed in value for the alias" do
@@ -247,15 +241,13 @@ class FactoryTest < Test::Unit::TestCase
247
241
  should "discard the predefined value for the attribute" do
248
242
  assert_nil @result[:test]
249
243
  end
250
-
251
244
  end
252
-
245
+
253
246
  should "guess the build class from the factory name" do
254
247
  assert_equal User, @factory.build_class
255
248
  end
256
249
 
257
250
  context "when defined with a custom class" do
258
-
259
251
  setup do
260
252
  @class = User
261
253
  @factory = Factory.new(:author, :class => @class)
@@ -264,11 +256,9 @@ class FactoryTest < Test::Unit::TestCase
264
256
  should "use the specified class as the build class" do
265
257
  assert_equal @class, @factory.build_class
266
258
  end
267
-
268
259
  end
269
260
 
270
261
  context "when defined with a class instead of a name" do
271
-
272
262
  setup do
273
263
  @class = ArgumentError
274
264
  @name = :argument_error
@@ -282,10 +272,9 @@ class FactoryTest < Test::Unit::TestCase
282
272
  should "use the class as the build class" do
283
273
  assert_equal @class, @factory.build_class
284
274
  end
285
-
286
275
  end
287
- context "when defined with a custom class name" do
288
276
 
277
+ context "when defined with a custom class name" do
289
278
  setup do
290
279
  @class = ArgumentError
291
280
  @factory = Factory.new(:author, :class => :argument_error)
@@ -294,61 +283,10 @@ class FactoryTest < Test::Unit::TestCase
294
283
  should "use the specified class as the build class" do
295
284
  assert_equal @class, @factory.build_class
296
285
  end
297
-
298
- end
299
-
300
- context "with some attributes added" do
301
-
302
- setup do
303
- @first_name = 'Billy'
304
- @last_name = 'Idol'
305
- @email = 'test@something.com'
306
-
307
- @factory.add_attribute(:first_name, @first_name)
308
- @factory.add_attribute(:last_name, @last_name)
309
- @factory.add_attribute(:email, @email)
310
- end
311
-
312
- context "when building an instance" do
313
-
314
- setup do
315
- @instance = @factory.build
316
- end
317
-
318
- should_instantiate_class
319
-
320
- should "not save the instance" do
321
- assert @instance.new_record?
322
- end
323
-
324
- end
325
-
326
- context "when creating an instance" do
327
-
328
- setup do
329
- @instance = @factory.create
330
- end
331
-
332
- should_instantiate_class
333
-
334
- should "save the instance" do
335
- assert !@instance.new_record?
336
- end
337
-
338
- end
339
-
340
- should "raise an error for invalid instances" do
341
- assert_raise(ActiveRecord::RecordInvalid) do
342
- @factory.create(:first_name => nil)
343
- end
344
- end
345
-
346
286
  end
347
-
348
287
  end
349
288
 
350
289
  context "a factory with a name ending in s" do
351
-
352
290
  setup do
353
291
  @name = :business
354
292
  @class = Business
@@ -362,11 +300,9 @@ class FactoryTest < Test::Unit::TestCase
362
300
  should "have a build class" do
363
301
  assert_equal @class, @factory.build_class
364
302
  end
365
-
366
303
  end
367
304
 
368
305
  context "a factory with a string for a name" do
369
-
370
306
  setup do
371
307
  @name = :user
372
308
  @factory = Factory.new(@name.to_s) {}
@@ -375,11 +311,9 @@ class FactoryTest < Test::Unit::TestCase
375
311
  should "convert the string to a symbol" do
376
312
  assert_equal @name, @factory.factory_name
377
313
  end
378
-
379
314
  end
380
315
 
381
316
  context "a factory defined with a string name" do
382
-
383
317
  setup do
384
318
  Factory.factories = {}
385
319
  @name = :user
@@ -389,52 +323,130 @@ class FactoryTest < Test::Unit::TestCase
389
323
  should "store the factory using a symbol" do
390
324
  assert_equal @factory, Factory.factories[@name]
391
325
  end
392
-
393
326
  end
394
327
 
395
- context "Factory class" do
396
-
328
+ context "after defining a factory" do
397
329
  setup do
398
- @name = :user
399
- @attrs = { :last_name => 'Override' }
400
- @first_name = 'Johnny'
401
- @last_name = 'Winter'
402
- @class = User
403
-
404
- Factory.define(@name) do |u|
405
- u.first_name @first_name
406
- u.last_name { @last_name }
407
- u.email 'jwinter@guitar.org'
408
- end
330
+ @name = :user
331
+ @factory = mock('factory')
409
332
 
410
- @factory = Factory.factories[@name]
333
+ Factory.factories[@name] = @factory
411
334
  end
412
335
 
413
- [:build, :create, :attributes_for].each do |method|
336
+ teardown { Factory.factories.clear }
414
337
 
415
- should "delegate the #{method} method to the factory instance" do
416
- @factory.expects(method).with(@attrs)
417
- Factory.send(method, @name, @attrs)
418
- end
338
+ should "use Proxy::AttributesFor for Factory.attributes_for" do
339
+ @factory.
340
+ expects(:run).
341
+ with(Factory::Proxy::AttributesFor, :attr => 'value').
342
+ returns('result')
343
+ assert_equal 'result', Factory.attributes_for(@name, :attr => 'value')
344
+ end
345
+
346
+ should "use Proxy::Build for Factory.build" do
347
+ @factory.
348
+ expects(:run).
349
+ with(Factory::Proxy::Build, :attr => 'value').
350
+ returns('result')
351
+ assert_equal 'result', Factory.build(@name, :attr => 'value')
352
+ end
353
+
354
+ should "use Proxy::Create for Factory.create" do
355
+ @factory.
356
+ expects(:run).
357
+ with(Factory::Proxy::Create, :attr => 'value').
358
+ returns('result')
359
+ assert_equal 'result', Factory.create(@name, :attr => 'value')
360
+ end
361
+
362
+ should "use Proxy::Stub for Factory.stub" do
363
+ @factory.
364
+ expects(:run).
365
+ with(Factory::Proxy::Stub, :attr => 'value').
366
+ returns('result')
367
+ assert_equal 'result', Factory.stub(@name, :attr => 'value')
368
+ end
369
+
370
+ should "use default strategy option as Factory.default_strategy" do
371
+ @factory.stubs(:default_strategy).returns(:create)
372
+ @factory.
373
+ expects(:run).
374
+ with(Factory::Proxy::Create, :attr => 'value').
375
+ returns('result')
376
+ assert_equal 'result', Factory.default_strategy(@name, :attr => 'value')
377
+ end
378
+
379
+ should "use the default strategy for the global Factory method" do
380
+ @factory.stubs(:default_strategy).returns(:create)
381
+ @factory.
382
+ expects(:run).
383
+ with(Factory::Proxy::Create, :attr => 'value').
384
+ returns('result')
385
+ assert_equal 'result', Factory(@name, :attr => 'value')
386
+ end
419
387
 
420
- should "raise an ArgumentError when #{method} is called with a nonexistant factory" do
388
+ [:build, :create, :attributes_for, :stub].each do |method|
389
+ should "raise an ArgumentError on #{method} with a nonexistant factory" do
421
390
  assert_raise(ArgumentError) { Factory.send(method, :bogus) }
422
391
  end
423
392
 
424
393
  should "recognize either 'name' or :name for Factory.#{method}" do
394
+ @factory.stubs(:run)
425
395
  assert_nothing_raised { Factory.send(method, @name.to_s) }
426
396
  assert_nothing_raised { Factory.send(method, @name.to_sym) }
427
397
  end
428
-
429
398
  end
430
-
431
- should "call the create method from the top-level Factory() method" do
432
- @factory.expects(:create).with(@attrs)
433
- Factory(@name, @attrs)
399
+ end
400
+
401
+ context 'defining a factory with a parent parameter' do
402
+ setup do
403
+ @parent = Factory.define :object do |f|
404
+ f.name 'Name'
405
+ end
406
+ end
407
+
408
+ should 'raise an ArgumentError when trying to use a non-existent factory as parent' do
409
+ assert_raise(ArgumentError) { Factory.define(:child, :parent => :nonexsitent) {} }
410
+ end
411
+
412
+ should 'create a new factory using the class of the parent' do
413
+ child = Factory.define(:child, :parent => :object) {}
414
+ assert_equal @parent.build_class, child.build_class
415
+ end
416
+
417
+ should 'create a new factory with attributes of the parent' do
418
+ child = Factory.define(:child, :parent => :object) {}
419
+ assert_equal 1, child.attributes.size
420
+ assert_equal :name, child.attributes.first.name
421
+ end
422
+
423
+ should 'allow to define additional attributes' do
424
+ child = Factory.define(:child, :parent => :object) do |f|
425
+ f.email 'person@somebody.com'
426
+ end
427
+ assert_equal 2, child.attributes.size
428
+ end
429
+
430
+ should 'allow to override parent attributes' do
431
+ child = Factory.define(:child, :parent => :object) do |f|
432
+ f.name { 'Child Name' }
433
+ end
434
+ assert_equal 1, child.attributes.size
435
+ assert_kind_of Factory::Attribute::Dynamic, child.attributes.first
434
436
  end
435
-
436
437
  end
437
438
 
439
+ context 'defining a factory with a default strategy parameter' do
440
+ should 'raise an ArgumentError when trying to use a non-existent factory' do
441
+ assert_raise(ArgumentError) { Factory.define(:object, :default_strategy => :nonexistent) {} }
442
+ end
443
+
444
+ should 'create a new factory with a specified default strategy' do
445
+ factory = Factory.define(:object, :default_strategy => :stub) {}
446
+ assert_equal :stub, factory.default_strategy
447
+ end
448
+ end
449
+
438
450
  def self.context_in_directory_with_files(*files)
439
451
  context "in a directory with #{files.to_sentence}" do
440
452
  setup do