factory_girl 2.0.0.beta3 → 2.0.0.beta4

Sign up to get free protection for your applications and to get access to all the features.
data/GETTING_STARTED.md CHANGED
@@ -52,10 +52,10 @@ factory_girl supports several different build strategies: build, create, attribu
52
52
  # Returns a saved User instance
53
53
  user = FactoryGirl.create(:user)
54
54
 
55
- # Returns a hash of attributes that can be used to build a User instance:
55
+ # Returns a hash of attributes that can be used to build a User instance
56
56
  attrs = FactoryGirl.attributes_for(:user)
57
57
 
58
- # Returns an object with all defined attributes stubbed out:
58
+ # Returns an object with all defined attributes stubbed out
59
59
  stub = FactoryGirl.stub(:user)
60
60
 
61
61
  No matter which strategy is used, it's possible to override the defined attributes by passing a hash:
@@ -104,8 +104,7 @@ Attributes can be based on the values of other attributes using the proxy that i
104
104
  Associations
105
105
  ------------
106
106
 
107
- Associated instances can be generated by using the association method when
108
- defining a lazy attribute:
107
+ It's possbile to set up associations within factories. If the factory name is the same as the association name, the factory name can be left out.
109
108
 
110
109
  factory :post do
111
110
  # ...
@@ -131,25 +130,39 @@ The behavior of the association method varies depending on the build strategy us
131
130
  post.new_record? # => true
132
131
  post.author.new_record # => false
133
132
 
134
- If the factory name is the same as the association name, the factory name can
135
- be left out.
136
-
137
133
  Inheritance
138
134
  -----------
139
135
 
140
- You can easily create multiple factories for the same class without repeating common attributes by using inheritance:
136
+ You can easily create multiple factories for the same class without repeating common attributes by nesting factories:
137
+
138
+ factory :post do
139
+ title 'A title'
140
+
141
+ factory :approved_post do
142
+ approved true
143
+ end
144
+ end
145
+
146
+ approved_post = FactoryGirl.create(:approved_post)
147
+ approved_post.title # => 'A title'
148
+ approved_post.approved # => true
149
+
150
+ You can also assign the parent explicitly:
141
151
 
142
152
  factory :post do
143
- # the 'title' attribute is required for all posts
144
153
  title 'A title'
145
154
  end
146
155
 
147
156
  factory :approved_post, :parent => :post do
148
157
  approved true
149
- # the 'approver' association is required for an approved post
150
- association :approver, :factory => :user
151
158
  end
152
159
 
160
+ approved_post = FactoryGirl.create(:approved_post)
161
+ approved_post.title # => 'A title'
162
+ approved_post.approved # => true
163
+
164
+ As mentioned above, it's good practice to define a basic factory for each class with only the attributes required to create it. Then, create more specific factories that inherit from this basic parent. Factory definitions are still code, so keep them DRY.
165
+
153
166
  Sequences
154
167
  ---------
155
168
 
@@ -223,7 +236,7 @@ Note that you'll have an instance of the user in the block. This can be useful.
223
236
  You can also define multiple types of callbacks on the same factory:
224
237
 
225
238
  factory :user do
226
- after_build { |user| do_something_to(user) }
239
+ after_build { |user| do_something_to(user) }
227
240
  after_create { |user| do_something_else_to(user) }
228
241
  end
229
242
 
@@ -231,7 +244,7 @@ Factories can also define any number of the same kind of callback. These callba
231
244
 
232
245
  factory :user do
233
246
  after_create { this_runs_first }
234
- after_create { then_this }
247
+ after_create { then_this }
235
248
  end
236
249
 
237
250
  Calling FactoryGirl.create will invoke both after_build and after_create callbacks.
@@ -264,7 +277,7 @@ Users' tastes for syntax vary dramatically, but most users are looking for a com
264
277
 
265
278
  User.blueprint do
266
279
  name { 'Billy Bob' }
267
- email { Sham.email }
280
+ email { Sham.email }
268
281
  end
269
282
 
270
283
  User.make(:name => 'Johnny')
Binary file
@@ -4,8 +4,11 @@ module FactoryGirl
4
4
  undef_method(method) unless method =~ /(^__|^nil\?$|^send$|^object_id$|^extend$|^instance_eval$)/
5
5
  end
6
6
 
7
+ attr_reader :child_factories
8
+
7
9
  def initialize(factory)
8
10
  @factory = factory
11
+ @child_factories = []
9
12
  end
10
13
 
11
14
  # Adds an attribute that should be assigned on generated instances for this
@@ -143,5 +146,9 @@ module FactoryGirl
143
146
  def to_create(&block)
144
147
  @factory.to_create(&block)
145
148
  end
149
+
150
+ def factory(name, options = {}, &block)
151
+ @child_factories << [name, options, block]
152
+ end
146
153
  end
147
154
  end
@@ -15,11 +15,15 @@ module FactoryGirl
15
15
  def factory(name, options = {}, &block)
16
16
  factory = Factory.new(name, options)
17
17
  proxy = FactoryGirl::DefinitionProxy.new(factory)
18
- proxy.instance_eval(&block)
18
+ proxy.instance_eval(&block) if block_given?
19
19
  if parent = options.delete(:parent)
20
20
  factory.inherit_from(FactoryGirl.factory_by_name(parent))
21
21
  end
22
22
  FactoryGirl.register_factory(factory)
23
+
24
+ proxy.child_factories.each do |(child_name, child_options, child_block)|
25
+ factory(child_name, child_options.merge(:parent => name), &child_block)
26
+ end
23
27
  end
24
28
 
25
29
  def sequence(name, start_value = 1, &block)
@@ -1,4 +1,4 @@
1
1
  module FactoryGirl
2
- VERSION = "2.0.0.beta3"
2
+ VERSION = "2.0.0.beta4"
3
3
  end
4
4
 
@@ -10,8 +10,7 @@ describe "attribute aliases" do
10
10
  end
11
11
 
12
12
  FactoryGirl.define do
13
- factory :user do
14
- end
13
+ factory :user
15
14
 
16
15
  factory :post do
17
16
  user
@@ -15,8 +15,7 @@ describe "a generated attributes hash" do
15
15
  end
16
16
 
17
17
  FactoryGirl.define do
18
- factory :user do
19
- end
18
+ factory :user
20
19
 
21
20
  factory :post do
22
21
  title { "default title" }
@@ -12,8 +12,7 @@ describe "a built instance" do
12
12
  end
13
13
 
14
14
  FactoryGirl.define do
15
- factory :user do
16
- end
15
+ factory :user
17
16
 
18
17
  factory :post do
19
18
  user
@@ -14,8 +14,7 @@ describe "a generated stub instance" do
14
14
  end
15
15
 
16
16
  FactoryGirl.define do
17
- factory :user do
18
- end
17
+ factory :user
19
18
 
20
19
  factory :post do
21
20
  title { "default title" }
@@ -12,8 +12,7 @@ describe "a created instance" do
12
12
  end
13
13
 
14
14
  FactoryGirl.define do
15
- factory :user do
16
- end
15
+ factory :user
17
16
 
18
17
  factory :post do
19
18
  user
@@ -6,8 +6,7 @@ describe "default strategy" do
6
6
  define_model('User')
7
7
 
8
8
  FactoryGirl.define do
9
- factory :user do
10
- end
9
+ factory :user
11
10
  end
12
11
 
13
12
  Factory(:user).should_not be_new_record
@@ -17,8 +16,7 @@ describe "default strategy" do
17
16
  define_model('User')
18
17
 
19
18
  FactoryGirl.define do
20
- factory :user, :default_strategy => :build do
21
- end
19
+ factory :user, :default_strategy => :build
22
20
  end
23
21
 
24
22
  Factory(:user).should be_new_record
@@ -6,8 +6,7 @@ describe "an instance generated by a factory with a custom class name" do
6
6
  define_model("User", :admin => :boolean)
7
7
 
8
8
  FactoryGirl.define do
9
- factory :user do
10
- end
9
+ factory :user
11
10
 
12
11
  factory :admin, :class => User do
13
12
  admin { true }
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+ require 'acceptance/acceptance_helper'
3
+
4
+ describe "an instance generated by a factory" do
5
+ before do
6
+ define_model("User")
7
+
8
+ FactoryGirl.define do
9
+ factory :user
10
+ end
11
+ end
12
+
13
+ it "registers the user factory" do
14
+ FactoryGirl.factory_by_name(:user).should be_a(FactoryGirl::Factory)
15
+ end
16
+ end
@@ -7,33 +7,29 @@ describe "an instance generated by a factory that inherits from another factory"
7
7
 
8
8
  FactoryGirl.define do
9
9
  factory :user do
10
- name { "John" }
11
- email { "john@example.com" }
12
- end
10
+ name "John"
11
+ email "john@example.com"
13
12
 
14
- factory :admin, :parent => :user do
15
- admin { true }
16
- email { "admin@example.com" }
13
+ factory :admin do
14
+ admin true
15
+ email "admin@example.com"
16
+ end
17
17
  end
18
18
  end
19
19
  end
20
20
 
21
- subject { FactoryGirl.create(:admin) }
22
-
23
- it "uses the parent build class" do
24
- subject.should be_kind_of(User)
25
- end
26
-
27
- it "inherits attributes" do
28
- subject.name.should == 'John'
29
- end
30
-
31
- it "has its own attributes" do
32
- subject.should be_admin
21
+ describe "the parent class" do
22
+ subject { FactoryGirl.create(:user) }
23
+ it { should_not be_admin }
24
+ its(:email) { should == "john@example.com" }
33
25
  end
34
26
 
35
- it "overrides attributes" do
36
- subject.email.should == 'admin@example.com'
27
+ describe "the child class" do
28
+ subject { FactoryGirl.create(:admin) }
29
+ it { should be_kind_of(User) }
30
+ it { should be_admin }
31
+ its(:name) { should == "John" }
32
+ its(:email) { should == "admin@example.com" }
37
33
  end
38
34
  end
39
35
 
@@ -37,6 +37,16 @@ describe FactoryGirl::DefinitionProxy do
37
37
  }.should raise_error(FactoryGirl::AttributeDefinitionError)
38
38
  end
39
39
 
40
+ describe "child factories" do
41
+ its(:child_factories) { should == [] }
42
+
43
+ it "should be able to add child factories" do
44
+ block = lambda {}
45
+ subject.factory(:admin, { :aliases => [:great] }, &block)
46
+ subject.child_factories.should == [[:admin, { :aliases => [:great] }, block]]
47
+ end
48
+ end
49
+
40
50
  describe "adding an attribute using a in-line sequence" do
41
51
  it "should create the sequence" do
42
52
  mock(FactoryGirl::Sequence).new(:name, 1)
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: factory_girl
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease: 6
5
- version: 2.0.0.beta3
5
+ version: 2.0.0.beta4
6
6
  platform: ruby
7
7
  authors:
8
8
  - Joe Ferris
@@ -153,6 +153,7 @@ files:
153
153
  - spec/acceptance/create_spec.rb
154
154
  - spec/acceptance/default_strategy_spec.rb
155
155
  - spec/acceptance/definition_spec.rb
156
+ - spec/acceptance/definition_without_block_spec.rb
156
157
  - spec/acceptance/parent_spec.rb
157
158
  - spec/acceptance/sequence_spec.rb
158
159
  - spec/acceptance/syntax/blueprint_spec.rb
@@ -225,6 +226,7 @@ test_files:
225
226
  - spec/acceptance/create_spec.rb
226
227
  - spec/acceptance/default_strategy_spec.rb
227
228
  - spec/acceptance/definition_spec.rb
229
+ - spec/acceptance/definition_without_block_spec.rb
228
230
  - spec/acceptance/parent_spec.rb
229
231
  - spec/acceptance/sequence_spec.rb
230
232
  - spec/acceptance/syntax/blueprint_spec.rb