factory_girl_kibiz0r 2.0.0.beta2

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.
Files changed (83) hide show
  1. data/Appraisals +12 -0
  2. data/CONTRIBUTION_GUIDELINES.md +9 -0
  3. data/Changelog +29 -0
  4. data/GETTING_STARTED.md +246 -0
  5. data/Gemfile +12 -0
  6. data/Gemfile.lock +62 -0
  7. data/LICENSE +19 -0
  8. data/README.md +64 -0
  9. data/Rakefile +54 -0
  10. data/features/factory_girl_steps.feature +151 -0
  11. data/features/step_definitions/database_steps.rb +20 -0
  12. data/features/support/env.rb +6 -0
  13. data/features/support/factories.rb +84 -0
  14. data/lib/factory_girl/aliases.rb +21 -0
  15. data/lib/factory_girl/attribute/association.rb +24 -0
  16. data/lib/factory_girl/attribute/callback.rb +16 -0
  17. data/lib/factory_girl/attribute/dynamic.rb +21 -0
  18. data/lib/factory_girl/attribute/implicit.rb +36 -0
  19. data/lib/factory_girl/attribute/list.rb +19 -0
  20. data/lib/factory_girl/attribute/sequence.rb +16 -0
  21. data/lib/factory_girl/attribute/static.rb +18 -0
  22. data/lib/factory_girl/attribute.rb +42 -0
  23. data/lib/factory_girl/definition_proxy.rb +147 -0
  24. data/lib/factory_girl/deprecated.rb +18 -0
  25. data/lib/factory_girl/factory.rb +196 -0
  26. data/lib/factory_girl/find_definitions.rb +23 -0
  27. data/lib/factory_girl/proxy/attributes_for.rb +21 -0
  28. data/lib/factory_girl/proxy/build.rb +36 -0
  29. data/lib/factory_girl/proxy/create.rb +16 -0
  30. data/lib/factory_girl/proxy/stub.rb +64 -0
  31. data/lib/factory_girl/proxy.rb +87 -0
  32. data/lib/factory_girl/rails2.rb +1 -0
  33. data/lib/factory_girl/registry.rb +45 -0
  34. data/lib/factory_girl/sequence.rb +31 -0
  35. data/lib/factory_girl/step_definitions.rb +60 -0
  36. data/lib/factory_girl/syntax/blueprint.rb +42 -0
  37. data/lib/factory_girl/syntax/default.rb +33 -0
  38. data/lib/factory_girl/syntax/generate.rb +73 -0
  39. data/lib/factory_girl/syntax/make.rb +41 -0
  40. data/lib/factory_girl/syntax/methods.rb +86 -0
  41. data/lib/factory_girl/syntax/sham.rb +45 -0
  42. data/lib/factory_girl/syntax/vintage.rb +152 -0
  43. data/lib/factory_girl/syntax.rb +12 -0
  44. data/lib/factory_girl/version.rb +4 -0
  45. data/lib/factory_girl.rb +54 -0
  46. data/spec/acceptance/acceptance_helper.rb +11 -0
  47. data/spec/acceptance/attribute_aliases_spec.rb +26 -0
  48. data/spec/acceptance/attributes_for_spec.rb +48 -0
  49. data/spec/acceptance/build_spec.rb +35 -0
  50. data/spec/acceptance/build_stubbed_spec.rb +79 -0
  51. data/spec/acceptance/callbacks_spec.rb +53 -0
  52. data/spec/acceptance/create_spec.rb +67 -0
  53. data/spec/acceptance/default_strategy_spec.rb +27 -0
  54. data/spec/acceptance/definition_spec.rb +28 -0
  55. data/spec/acceptance/parent_spec.rb +39 -0
  56. data/spec/acceptance/sequence_spec.rb +34 -0
  57. data/spec/acceptance/syntax/blueprint_spec.rb +32 -0
  58. data/spec/acceptance/syntax/generate_spec.rb +60 -0
  59. data/spec/acceptance/syntax/make_spec.rb +35 -0
  60. data/spec/acceptance/syntax/sham_spec.rb +44 -0
  61. data/spec/acceptance/syntax/vintage_spec.rb +224 -0
  62. data/spec/factory_girl/aliases_spec.rb +33 -0
  63. data/spec/factory_girl/attribute/association_spec.rb +33 -0
  64. data/spec/factory_girl/attribute/callback_spec.rb +23 -0
  65. data/spec/factory_girl/attribute/dynamic_spec.rb +60 -0
  66. data/spec/factory_girl/attribute/implicit_spec.rb +50 -0
  67. data/spec/factory_girl/attribute/sequence_spec.rb +21 -0
  68. data/spec/factory_girl/attribute/static_spec.rb +29 -0
  69. data/spec/factory_girl/attribute_spec.rb +39 -0
  70. data/spec/factory_girl/definition_proxy_spec.rb +129 -0
  71. data/spec/factory_girl/deprecated_spec.rb +66 -0
  72. data/spec/factory_girl/factory_spec.rb +374 -0
  73. data/spec/factory_girl/find_definitions_spec.rb +100 -0
  74. data/spec/factory_girl/proxy/attributes_for_spec.rb +52 -0
  75. data/spec/factory_girl/proxy/build_spec.rb +86 -0
  76. data/spec/factory_girl/proxy/create_spec.rb +107 -0
  77. data/spec/factory_girl/proxy/stub_spec.rb +80 -0
  78. data/spec/factory_girl/proxy_spec.rb +102 -0
  79. data/spec/factory_girl/registry_spec.rb +83 -0
  80. data/spec/factory_girl/sequence_spec.rb +96 -0
  81. data/spec/factory_girl_spec.rb +17 -0
  82. data/spec/spec_helper.rb +93 -0
  83. metadata +294 -0
@@ -0,0 +1,129 @@
1
+ require 'spec_helper'
2
+
3
+ describe FactoryGirl::DefinitionProxy do
4
+ let(:factory) { FactoryGirl::Factory.new(:object) }
5
+ subject { FactoryGirl::DefinitionProxy.new(factory) }
6
+
7
+ it "should add a static attribute for type" do
8
+ subject.type 'value'
9
+ factory.attributes.last.should be_kind_of(FactoryGirl::Attribute::Static)
10
+ end
11
+
12
+ it "should add a static attribute for id" do
13
+ subject.id 'value'
14
+ factory.attributes.last.should be_kind_of(FactoryGirl::Attribute::Static)
15
+ end
16
+
17
+ it "should add a static attribute when an attribute is defined with a value" do
18
+ attribute = 'attribute'
19
+ stub(attribute).name { :name }
20
+ mock(FactoryGirl::Attribute::Static).new(:name, 'value') { attribute }
21
+ mock(factory).define_attribute(attribute)
22
+ subject.add_attribute(:name, 'value')
23
+ end
24
+
25
+ it "should add a dynamic attribute when an attribute is defined with a block" do
26
+ attribute = 'attribute'
27
+ stub(attribute).name { :name }
28
+ block = lambda {}
29
+ mock(FactoryGirl::Attribute::Dynamic).new(:name, block) { attribute }
30
+ mock(factory).define_attribute(attribute)
31
+ subject.add_attribute(:name, &block)
32
+ end
33
+
34
+ it "should raise for an attribute with a value and a block" do
35
+ lambda {
36
+ subject.add_attribute(:name, 'value') {}
37
+ }.should raise_error(FactoryGirl::AttributeDefinitionError)
38
+ end
39
+
40
+ describe "adding an attribute using a in-line sequence" do
41
+ it "should create the sequence" do
42
+ mock(FactoryGirl::Sequence).new(:name, 1)
43
+ subject.sequence(:name) {}
44
+ end
45
+
46
+ it "should create the sequence with a custom default value" do
47
+ mock(FactoryGirl::Sequence).new(:name, "A")
48
+ subject.sequence(:name, "A") {}
49
+ end
50
+
51
+ it "should add a dynamic attribute" do
52
+ attribute = 'attribute'
53
+ stub(attribute).name { :name }
54
+ mock(FactoryGirl::Attribute::Dynamic).new(:name, is_a(Proc)) { attribute }
55
+ subject.sequence(:name) {}
56
+ factory.attributes.should include(attribute)
57
+ end
58
+ end
59
+
60
+ it "should add a callback attribute when the after_build attribute is defined" do
61
+ mock(FactoryGirl::Attribute::Callback).new(:after_build, is_a(Proc)) { 'after_build callback' }
62
+ subject.after_build {}
63
+ factory.attributes.should include('after_build callback')
64
+ end
65
+
66
+ it "should add a callback attribute when the after_create attribute is defined" do
67
+ mock(FactoryGirl::Attribute::Callback).new(:after_create, is_a(Proc)) { 'after_create callback' }
68
+ subject.after_create {}
69
+ factory.attributes.should include('after_create callback')
70
+ end
71
+
72
+ it "should add a callback attribute when the after_stub attribute is defined" do
73
+ mock(FactoryGirl::Attribute::Callback).new(:after_stub, is_a(Proc)) { 'after_stub callback' }
74
+ subject.after_stub {}
75
+ factory.attributes.should include('after_stub callback')
76
+ end
77
+
78
+ it "should add an association without a factory name or overrides" do
79
+ name = :user
80
+ attr = 'attribute'
81
+ stub(attr).name { name }
82
+ mock(FactoryGirl::Attribute::Association).new(name, name, {}) { attr }
83
+ subject.association(name)
84
+ factory.attributes.should include(attr)
85
+ end
86
+
87
+ it "should add an association with overrides" do
88
+ name = :user
89
+ attr = 'attribute'
90
+ overrides = { :first_name => 'Ben' }
91
+ stub(attr).name { name }
92
+ mock(FactoryGirl::Attribute::Association).new(name, name, overrides) { attr }
93
+ subject.association(name, overrides)
94
+ factory.attributes.should include(attr)
95
+ end
96
+
97
+ it "should add an attribute using the method name when passed an undefined method" do
98
+ attribute = 'attribute'
99
+ stub(attribute).name { :name }
100
+ mock(FactoryGirl::Attribute::Static).new(:name, 'value') { attribute }
101
+ subject.send(:name, 'value')
102
+ factory.attributes.should include(attribute)
103
+ end
104
+
105
+ it "adds an attribute using when passed an undefined method and block" do
106
+ attribute = 'attribute'
107
+ stub(attribute).name { :name }
108
+ block = lambda {}
109
+ mock(FactoryGirl::Attribute::Dynamic).new(:name, block) { attribute }
110
+ subject.send(:name, &block)
111
+ factory.attributes.should include(attribute)
112
+ end
113
+
114
+ it "adds an implicit attribute when passed an undefined method without arguments or a block" do
115
+ name = :user
116
+ attr = 'attribute'
117
+ stub(attr).name { name }
118
+ mock(FactoryGirl::Attribute::Implicit).new(name) { attr }
119
+ subject.send(name)
120
+ factory.attributes.should include(attr)
121
+ end
122
+
123
+ it "delegates to_create" do
124
+ result = 'expected'
125
+ mock(factory).to_create { result }
126
+
127
+ subject.to_create.should == result
128
+ end
129
+ end
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+
3
+ describe "accessing an undefined method on Factory that is defined on FactoryGirl" do
4
+ let(:method_name) { :aliases }
5
+ let(:return_value) { 'value' }
6
+ let(:args) { [1, 2, 3] }
7
+
8
+ before do
9
+ stub($stderr).puts
10
+ stub(FactoryGirl, method_name).returns { return_value }
11
+
12
+ @result = Factory.send(method_name, *args)
13
+ end
14
+
15
+ it "prints a deprecation warning" do
16
+ $stderr.should have_received.puts(anything)
17
+ end
18
+
19
+ it "invokes that method on FactoryGirl" do
20
+ FactoryGirl.should have_received.method_missing(method_name, *args)
21
+ end
22
+
23
+ it "returns the value from the method on FactoryGirl" do
24
+ @result.should == return_value
25
+ end
26
+ end
27
+
28
+ describe "accessing an undefined method on Factory that is not defined on FactoryGirl" do
29
+ let(:method_name) { :magic_beans }
30
+
31
+ before do
32
+ stub($stderr).puts { raise "Don't print a deprecation warning" }
33
+
34
+ begin
35
+ Factory.send(method_name)
36
+ rescue Exception => @raised
37
+ end
38
+ end
39
+
40
+ it "raises a NoMethodError" do
41
+ @raised.should be_a(NoMethodError)
42
+ end
43
+ end
44
+
45
+ describe "accessing an undefined constant on Factory that is defined on FactoryGirl" do
46
+ before do
47
+ @result = Factory::VERSION
48
+ end
49
+
50
+ it "returns that constant on FactoryGirl" do
51
+ @result.should == FactoryGirl::VERSION
52
+ end
53
+ end
54
+
55
+ describe "accessing an undefined constant on Factory that is undefined on FactoryGirl" do
56
+ it "raises a NameError for Factory" do
57
+ begin
58
+ Factory::BOGUS
59
+ rescue Exception => exception
60
+ end
61
+
62
+ exception.should be_a(NameError)
63
+ exception.message.should include("Factory::BOGUS")
64
+ end
65
+ end
66
+
@@ -0,0 +1,374 @@
1
+ require 'spec_helper'
2
+
3
+ describe FactoryGirl::Factory do
4
+ include DefinesConstants
5
+
6
+ before do
7
+ @name = :user
8
+ @class = define_class('User')
9
+ @factory = FactoryGirl::Factory.new(@name)
10
+ end
11
+
12
+ it "should have a factory name" do
13
+ @factory.name.should == @name
14
+ end
15
+
16
+ it "responds to factory_name" do
17
+ @factory.factory_name.should == @name
18
+ end
19
+
20
+ it "should have a build class" do
21
+ @factory.build_class.should == @class
22
+ end
23
+
24
+ it "should have a default strategy" do
25
+ @factory.default_strategy.should == :create
26
+ end
27
+
28
+ it "should not allow the same attribute to be added twice" do
29
+ lambda {
30
+ 2.times { @factory.define_attribute FactoryGirl::Attribute::Static.new(:name, 'value') }
31
+ }.should raise_error(FactoryGirl::AttributeDefinitionError)
32
+ end
33
+
34
+ it "should add a callback attribute when defining a callback" do
35
+ mock(FactoryGirl::Attribute::Callback).new(:after_create, is_a(Proc)) { 'after_create callback' }
36
+ @factory.add_callback(:after_create) {}
37
+ @factory.attributes.should include('after_create callback')
38
+ end
39
+
40
+ it "should raise an InvalidCallbackNameError when defining a callback with an invalid name" do
41
+ lambda{
42
+ @factory.add_callback(:invalid_callback_name) {}
43
+ }.should raise_error(FactoryGirl::InvalidCallbackNameError)
44
+ end
45
+
46
+ describe "after adding an attribute" do
47
+ before do
48
+ @attribute = "attribute"
49
+ @proxy = "proxy"
50
+
51
+ stub(@attribute).name { :name }
52
+ stub(@attribute).ignored? { false }
53
+ stub(@attribute).add_to
54
+ stub(@proxy).set
55
+ stub(@proxy).result { 'result' }
56
+ stub(FactoryGirl::Attribute::Static).new { @attribute }
57
+ stub(FactoryGirl::Proxy::Build).new { @proxy }
58
+
59
+ @factory.define_attribute(@attribute)
60
+ end
61
+
62
+ it "should create the right proxy using the build class when running" do
63
+ mock(FactoryGirl::Proxy::Build).new(@factory.build_class) { @proxy }
64
+ @factory.run(FactoryGirl::Proxy::Build, {})
65
+ end
66
+
67
+ it "should add the attribute to the proxy when running" do
68
+ mock(@attribute).add_to(@proxy)
69
+ @factory.run(FactoryGirl::Proxy::Build, {})
70
+ end
71
+
72
+ it "should return the result from the proxy when running" do
73
+ mock(@proxy).result(nil) { 'result' }
74
+ @factory.run(FactoryGirl::Proxy::Build, {}).should == 'result'
75
+ end
76
+ end
77
+
78
+ it "passes a custom creation block" do
79
+ proxy = 'proxy'
80
+ stub(FactoryGirl::Proxy::Build).new { proxy }
81
+ stub(proxy).result {}
82
+ block = lambda {}
83
+ factory = FactoryGirl::Factory.new(:object)
84
+ factory.to_create(&block)
85
+
86
+ factory.run(FactoryGirl::Proxy::Build, {})
87
+
88
+ proxy.should have_received.result(block)
89
+ end
90
+
91
+ it "should return associations" do
92
+ factory = FactoryGirl::Factory.new(:post)
93
+ FactoryGirl.register_factory(FactoryGirl::Factory.new(:admin))
94
+ factory.define_attribute(FactoryGirl::Attribute::Association.new(:author, :author, {}))
95
+ factory.define_attribute(FactoryGirl::Attribute::Association.new(:editor, :editor, {}))
96
+ factory.define_attribute(FactoryGirl::Attribute::Implicit.new(:admin))
97
+ factory.associations.each do |association|
98
+ association.should be_association
99
+ end
100
+ factory.associations.size.should == 3
101
+ end
102
+
103
+ it "should raise for a self referencing association" do
104
+ factory = FactoryGirl::Factory.new(:post)
105
+ lambda {
106
+ factory.define_attribute(FactoryGirl::Attribute::Association.new(:parent, :post, {}))
107
+ }.should raise_error(FactoryGirl::AssociationDefinitionError)
108
+ end
109
+
110
+ describe "when overriding generated attributes with a hash" do
111
+ before do
112
+ @name = :name
113
+ @value = 'The price is right!'
114
+ @hash = { @name => @value }
115
+ end
116
+
117
+ it "should return the overridden value in the generated attributes" do
118
+ attr = FactoryGirl::Attribute::Static.new(@name, 'The price is wrong, Bob!')
119
+ @factory.define_attribute(attr)
120
+ result = @factory.run(FactoryGirl::Proxy::AttributesFor, @hash)
121
+ result[@name].should == @value
122
+ end
123
+
124
+ it "should not call a lazy attribute block for an overridden attribute" do
125
+ attr = FactoryGirl::Attribute::Dynamic.new(@name, lambda { flunk })
126
+ @factory.define_attribute(attr)
127
+ result = @factory.run(FactoryGirl::Proxy::AttributesFor, @hash)
128
+ end
129
+
130
+ it "should override a symbol parameter with a string parameter" do
131
+ attr = FactoryGirl::Attribute::Static.new(@name, 'The price is wrong, Bob!')
132
+ @factory.define_attribute(attr)
133
+ @hash = { @name.to_s => @value }
134
+ result = @factory.run(FactoryGirl::Proxy::AttributesFor, @hash)
135
+ result[@name].should == @value
136
+ end
137
+ end
138
+
139
+ describe "overriding an attribute with an alias" do
140
+ before do
141
+ @factory.define_attribute(FactoryGirl::Attribute::Static.new(:test, 'original'))
142
+ Factory.alias(/(.*)_alias/, '\1')
143
+ @result = @factory.run(FactoryGirl::Proxy::AttributesFor,
144
+ :test_alias => 'new')
145
+ end
146
+
147
+ it "should use the passed in value for the alias" do
148
+ @result[:test_alias].should == 'new'
149
+ end
150
+
151
+ it "should discard the predefined value for the attribute" do
152
+ @result[:test].should be_nil
153
+ end
154
+ end
155
+
156
+ it "should guess the build class from the factory name" do
157
+ @factory.build_class.should == User
158
+ end
159
+
160
+ it "should create a new factory using the class of the parent" do
161
+ child = FactoryGirl::Factory.new(:child)
162
+ child.inherit_from(@factory)
163
+ child.build_class.should == @factory.build_class
164
+ end
165
+
166
+ it "should create a new factory while overriding the parent class" do
167
+ child = FactoryGirl::Factory.new(:child, :class => String)
168
+ child.inherit_from(@factory)
169
+ child.build_class.should == String
170
+ end
171
+
172
+ describe "given a parent with attributes" do
173
+ before do
174
+ @parent_attr = :name
175
+ @factory.define_attribute(FactoryGirl::Attribute::Static.new(@parent_attr, 'value'))
176
+ end
177
+
178
+ it "should create a new factory with attributes of the parent" do
179
+ child = FactoryGirl::Factory.new(:child)
180
+ child.inherit_from(@factory)
181
+ child.attributes.size.should == 1
182
+ child.attributes.first.name.should == @parent_attr
183
+ end
184
+
185
+ it "should allow a child to define additional attributes" do
186
+ child = FactoryGirl::Factory.new(:child)
187
+ child.define_attribute(FactoryGirl::Attribute::Static.new(:email, 'value'))
188
+ child.inherit_from(@factory)
189
+ child.attributes.size.should == 2
190
+ end
191
+
192
+ it "should allow to override parent attributes" do
193
+ child = FactoryGirl::Factory.new(:child)
194
+ @child_attr = FactoryGirl::Attribute::Static.new(@parent_attr, 'value')
195
+ child.define_attribute(@child_attr)
196
+ child.inherit_from(@factory)
197
+ child.attributes.size.should == 1
198
+ child.attributes.first.should == @child_attr
199
+ end
200
+
201
+ it "should allow to use parent attributes in defining additional attributes" do
202
+ User.class_eval { attr_accessor :name, :email }
203
+
204
+ child = FactoryGirl::Factory.new(:child)
205
+ @child_attr = FactoryGirl::Attribute::Dynamic.new(:email, lambda {|u| "#{u.name}@example.com"})
206
+ child.define_attribute(@child_attr)
207
+ child.inherit_from(@factory)
208
+ child.attributes.size.should == 2
209
+
210
+ result = child.run(FactoryGirl::Proxy::Build, {})
211
+ result.email.should == 'value@example.com'
212
+ end
213
+ end
214
+
215
+ it "inherit all callbacks" do
216
+ @factory.add_callback(:after_stub) { |object| object.name = 'Stubby' }
217
+ child = FactoryGirl::Factory.new(:child)
218
+ child.inherit_from(@factory)
219
+ child.attributes.last.should be_kind_of(FactoryGirl::Attribute::Callback)
220
+ end
221
+ end
222
+
223
+ describe FactoryGirl::Factory, "when defined with a custom class" do
224
+ before do
225
+ @class = Float
226
+ @factory = FactoryGirl::Factory.new(:author, :class => @class)
227
+ end
228
+
229
+ it "should use the specified class as the build class" do
230
+ @factory.build_class.should == @class
231
+ end
232
+ end
233
+
234
+ describe FactoryGirl::Factory, "when defined with a class instead of a name" do
235
+ before do
236
+ @class = ArgumentError
237
+ @name = :argument_error
238
+ @factory = FactoryGirl::Factory.new(@class)
239
+ end
240
+
241
+ it "should guess the name from the class" do
242
+ @factory.name.should == @name
243
+ end
244
+
245
+ it "should use the class as the build class" do
246
+ @factory.build_class.should == @class
247
+ end
248
+ end
249
+
250
+ describe FactoryGirl::Factory, "when defined with a custom class name" do
251
+ before do
252
+ @class = ArgumentError
253
+ @factory = FactoryGirl::Factory.new(:author, :class => :argument_error)
254
+ end
255
+
256
+ it "should use the specified class as the build class" do
257
+ @factory.build_class.should == @class
258
+ end
259
+ end
260
+
261
+ describe FactoryGirl::Factory, "with a name ending in s" do
262
+ include DefinesConstants
263
+
264
+ before do
265
+ define_class('Business')
266
+ @name = :business
267
+ @class = Business
268
+ @factory = FactoryGirl::Factory.new(@name)
269
+ end
270
+
271
+ it "should have a factory name" do
272
+ @factory.name.should == @name
273
+ end
274
+
275
+ it "should have a build class" do
276
+ @factory.build_class.should == @class
277
+ end
278
+ end
279
+
280
+ describe FactoryGirl::Factory, "with a string for a name" do
281
+ before do
282
+ @name = :string
283
+ @factory = FactoryGirl::Factory.new(@name.to_s) {}
284
+ end
285
+
286
+ it "should convert the string to a symbol" do
287
+ @factory.name.should == @name
288
+ end
289
+ end
290
+
291
+ describe FactoryGirl::Factory, "for namespaced class" do
292
+ include DefinesConstants
293
+
294
+ before do
295
+ define_class('Admin')
296
+ define_class('Admin::Settings')
297
+
298
+ @name = :settings
299
+ @class = Admin::Settings
300
+ end
301
+
302
+ it "should build namespaced class passed by string" do
303
+ factory = FactoryGirl::Factory.new(@name.to_s, :class => @class.name)
304
+ factory.build_class.should == @class
305
+ end
306
+
307
+ it "should build Admin::Settings class from Admin::Settings string" do
308
+ factory = FactoryGirl::Factory.new(@name.to_s, :class => 'admin/settings')
309
+ factory.build_class.should == @class
310
+ end
311
+ end
312
+
313
+ describe FactoryGirl::Factory do
314
+ include DefinesConstants
315
+
316
+ before do
317
+ define_class('User')
318
+ define_class('Admin', User)
319
+ end
320
+
321
+ it "should raise an ArgumentError when trying to use a non-existent strategy" do
322
+ lambda {
323
+ FactoryGirl::Factory.new(:object, :default_strategy => :nonexistent) {}
324
+ }.should raise_error(ArgumentError)
325
+ end
326
+
327
+ it "should create a new factory with a specified default strategy" do
328
+ factory = FactoryGirl::Factory.new(:object, :default_strategy => :stub)
329
+ factory.default_strategy.should == :stub
330
+ end
331
+
332
+ describe 'defining a child factory without setting default strategy' do
333
+ before do
334
+ @parent = FactoryGirl::Factory.new(:object, :default_strategy => :stub)
335
+ @child = FactoryGirl::Factory.new(:child_object)
336
+ @child.inherit_from(@parent)
337
+ end
338
+
339
+ it "should inherit default strategy from its parent" do
340
+ @child.default_strategy.should == :stub
341
+ end
342
+ end
343
+
344
+ describe 'defining a child factory with a default strategy' do
345
+ before do
346
+ @parent = FactoryGirl::Factory.new(:object, :default_strategy => :stub)
347
+ @child = FactoryGirl::Factory.new(:child_object2, :default_strategy => :build)
348
+ @child.inherit_from(@parent)
349
+ end
350
+
351
+ it "should override the default strategy from parent" do
352
+ @child.default_strategy.should == :build
353
+ end
354
+ end
355
+
356
+ end
357
+
358
+ describe FactoryGirl::Factory, "with an underscore in the name" do
359
+ subject { FactoryGirl::Factory.new("happy_users") }
360
+
361
+ it "has a human name" do
362
+ subject.human_name.should == 'happy users'
363
+ end
364
+ end
365
+
366
+
367
+ describe FactoryGirl::Factory, "with aliases" do
368
+ it "registers the aliases" do
369
+ name = :user
370
+ aliased_name = :guest
371
+ factory = FactoryGirl::Factory.new(:user, :aliases => [aliased_name])
372
+ factory.names.should =~ [name, aliased_name]
373
+ end
374
+ end
@@ -0,0 +1,100 @@
1
+ require 'spec_helper'
2
+
3
+ share_examples_for "finds definitions" do
4
+ before do
5
+ stub(FactoryGirl).require
6
+ FactoryGirl.find_definitions
7
+ end
8
+ subject { FactoryGirl }
9
+ end
10
+
11
+ RSpec::Matchers.define :require_definitions_from do |file|
12
+ match do |given|
13
+ @has_received = have_received.method_missing(:require, file)
14
+ @has_received.matches?(given)
15
+ end
16
+
17
+ description do
18
+ "require definitions from #{file}"
19
+ end
20
+
21
+ failure_message_for_should do
22
+ @has_received.failure_message
23
+ end
24
+ end
25
+
26
+
27
+ describe "definition loading" do
28
+ def self.in_directory_with_files(*files)
29
+ before do
30
+ @pwd = Dir.pwd
31
+ @tmp_dir = File.join(File.dirname(__FILE__), 'tmp')
32
+ FileUtils.mkdir_p @tmp_dir
33
+ Dir.chdir(@tmp_dir)
34
+
35
+ files.each do |file|
36
+ FileUtils.mkdir_p File.dirname(file)
37
+ FileUtils.touch file
38
+ end
39
+ end
40
+
41
+ after do
42
+ Dir.chdir(@pwd)
43
+ FileUtils.rm_rf(@tmp_dir)
44
+ end
45
+ end
46
+
47
+ describe "with factories.rb" do
48
+ in_directory_with_files 'factories.rb'
49
+ it_should_behave_like "finds definitions" do
50
+ it { should require_definitions_from('factories.rb') }
51
+ end
52
+ end
53
+
54
+ %w(spec test).each do |dir|
55
+ describe "with a factories file under #{dir}" do
56
+ in_directory_with_files File.join(dir, 'factories.rb')
57
+ it_should_behave_like "finds definitions" do
58
+ it { should require_definitions_from("#{dir}/factories.rb") }
59
+ end
60
+ end
61
+
62
+ describe "with a factories file under #{dir}/factories" do
63
+ in_directory_with_files File.join(dir, 'factories', 'post_factory.rb')
64
+ it_should_behave_like "finds definitions" do
65
+ it { should require_definitions_from("#{dir}/factories/post_factory.rb") }
66
+ end
67
+ end
68
+
69
+ describe "with several factories files under #{dir}/factories" do
70
+ in_directory_with_files File.join(dir, 'factories', 'post_factory.rb'),
71
+ File.join(dir, 'factories', 'person_factory.rb')
72
+ it_should_behave_like "finds definitions" do
73
+ it { should require_definitions_from("#{dir}/factories/post_factory.rb") }
74
+ it { should require_definitions_from("#{dir}/factories/person_factory.rb") }
75
+ end
76
+ end
77
+
78
+ describe "with several factories files under #{dir}/factories in non-alphabetical order" do
79
+ in_directory_with_files File.join(dir, 'factories', 'b.rb'),
80
+ File.join(dir, 'factories', 'a.rb')
81
+ it "should load the files in the right order" do
82
+ @loaded = []
83
+ stub(FactoryGirl).require { |a| @loaded << File.split(a)[-1] }
84
+ FactoryGirl.find_definitions
85
+ @loaded.should == ["a.rb", "b.rb"]
86
+ end
87
+ end
88
+
89
+ describe "with nested and unnested factories files under #{dir}" do
90
+ in_directory_with_files File.join(dir, 'factories.rb'),
91
+ File.join(dir, 'factories', 'post_factory.rb'),
92
+ File.join(dir, 'factories', 'person_factory.rb')
93
+ it_should_behave_like "finds definitions" do
94
+ it { should require_definitions_from("#{dir}/factories.rb") }
95
+ it { should require_definitions_from("#{dir}/factories/post_factory.rb") }
96
+ it { should require_definitions_from("#{dir}/factories/person_factory.rb") }
97
+ end
98
+ end
99
+ end
100
+ end