masa-iwasaki-factory_girl 1.2.3.1 → 1.2.3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Changelog +6 -28
- data/README.rdoc +40 -254
- data/Rakefile +1 -1
- data/lib/factory_girl/factory.rb +25 -21
- data/lib/factory_girl/proxy.rb +1 -1
- data/lib/factory_girl/proxy/create.rb +1 -1
- metadata +1 -1
data/Changelog
CHANGED
@@ -1,29 +1,7 @@
|
|
1
|
-
1.
|
2
|
-
|
3
|
-
Factory definitions are now detected in subdirectories, such as
|
4
|
-
factories/person_factory.rb (thanks to Josh Nichols)
|
5
|
-
Factory definitions are now loaded after the environment in a Rails project
|
6
|
-
(fixes some issues with dependencies being loaded too early) (thanks to
|
7
|
-
Josh Nichols)
|
8
|
-
Factory names ending in 's' no longer cause problems (thanks to Alex Sharp
|
9
|
-
and Josh Owens)
|
10
|
-
|
11
|
-
1.1.3 (September 12, 2008)
|
12
|
-
Automatically pull in definitions from factories.rb, test/factories.rb, or
|
13
|
-
spec/factories.rb
|
14
|
-
1.1.2 (July 30, 2008)
|
15
|
-
Improved error handling for invalid and undefined factories/attributes
|
16
|
-
Improved handling of strings vs symbols vs classes
|
17
|
-
Added a prettier syntax for handling associations
|
18
|
-
Updated documentation and fixed compatibility with Rails 2.1
|
1
|
+
1.2.3.2 (January 6, 2010)
|
2
|
+
Bug fix for Factory.assert_valid_options.
|
19
3
|
|
20
|
-
1.
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
Added support for dependent attributes
|
25
|
-
Fixed the attributes_for build strategy to not build associations
|
26
|
-
Added support for sequences
|
27
|
-
|
28
|
-
1.0.0 (May 31, 208)
|
29
|
-
First version
|
4
|
+
1.2.3.1 (January 6, 2010)
|
5
|
+
Rebase to 1.2.3 of an original repositry.
|
6
|
+
Remove disable_caches.
|
7
|
+
Cache definitions only :singleton option has set.
|
data/README.rdoc
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
=
|
2
|
-
== Caching
|
1
|
+
= Singleton support
|
3
2
|
By default, the association created by factory_girl is based on Factory#create. This means there would be twice creation for project_1 in the code shown below.
|
4
3
|
|
5
4
|
# Factory definitions
|
@@ -26,283 +25,70 @@ By default, the association created by factory_girl is based on Factory#create.
|
|
26
25
|
end
|
27
26
|
end
|
28
27
|
|
29
|
-
This fork added @@instances to Factory::Proxy::Create. @@instances keeps instances
|
28
|
+
This fork added @@instances to Factory::Proxy::Create. @@instances keeps singleton instances. In this example, you can use singleton options like below.
|
30
29
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
- Factory::Proxy::Create.disable_cache
|
35
|
-
- Factory::Proxy::Create.enable_cache
|
36
|
-
|
37
|
-
== Other changes
|
38
|
-
These modification affects the definitions written in some syntax.
|
39
|
-
|
40
|
-
- If you are using bluprint or sham syntax, you might need to use "Factory.create(factory_name)" explicityly instead of "Facotry(factory_name)"
|
41
|
-
- With generate syntas, Factory.generate will raise an exception as same as Factory.generate!
|
42
|
-
|
43
|
-
= factory_girl
|
44
|
-
|
45
|
-
factory_girl is a fixtures replacement with a straightforward definition syntax, support for multiple build strategies (saved instances, unsaved instances, attribute hashes, and stubbed objects), and support for multiple factories for the same class (user, admin_user, and so on), including factory inheritance.
|
46
|
-
|
47
|
-
== Download
|
48
|
-
|
49
|
-
Github: http://github.com/thoughtbot/factory_girl/tree/master
|
50
|
-
|
51
|
-
Gem:
|
52
|
-
gem install factory_girl --source http://gemcutter.org
|
53
|
-
|
54
|
-
Note: if you install factory_girl using the gem from Gemcutter, you'll need this
|
55
|
-
in your environment.rb if you want to use Rails 2.1+'s dependency manager:
|
56
|
-
|
57
|
-
config.gem "factory_girl",
|
58
|
-
:source => "http://gemcutter.org"
|
59
|
-
|
60
|
-
== Defining factories
|
61
|
-
|
62
|
-
Each factory has a name and a set of attributes. The name is used to guess the class of the object by default, but it's possible to explicitly specify it:
|
63
|
-
|
64
|
-
# This will guess the User class
|
65
|
-
Factory.define :user do |u|
|
66
|
-
u.first_name 'John'
|
67
|
-
u.last_name 'Doe'
|
68
|
-
u.admin false
|
69
|
-
end
|
70
|
-
|
71
|
-
# This will use the User class (Admin would have been guessed)
|
72
|
-
Factory.define :admin, :class => User do |u|
|
73
|
-
u.first_name 'Admin'
|
74
|
-
u.last_name 'User'
|
75
|
-
u.admin true
|
76
|
-
end
|
77
|
-
|
78
|
-
# The same, but using a string instead of class constant
|
79
|
-
Factory.define :admin, :class => 'user' do |u|
|
80
|
-
u.first_name 'Admin'
|
81
|
-
u.last_name 'User'
|
82
|
-
u.admin true
|
83
|
-
end
|
84
|
-
|
85
|
-
It is highly recommended that you have one factory for each class that provides the simplest set of attributes necessary to create an instance of that class. If you're creating ActiveRecord objects, that means that you should only provide attributes that are required through validations and that do not have defaults. Other factories can be created through inheritance to cover common scenarios for each class.
|
86
|
-
|
87
|
-
Attempting to define multiple factories with the same name will raise an error.
|
88
|
-
|
89
|
-
Factories can either be defined anywhere, but will automatically be loaded if they are defined in files at the following locations:
|
90
|
-
|
91
|
-
test/factories.rb
|
92
|
-
spec/factories.rb
|
93
|
-
test/factories/*.rb
|
94
|
-
spec/factories/*.rb
|
95
|
-
|
96
|
-
== Using factories
|
97
|
-
|
98
|
-
factory_girl supports several different build strategies: build, create, attributes_for and stub:
|
99
|
-
|
100
|
-
# Returns a User instance that's not saved
|
101
|
-
user = Factory.build(:user)
|
102
|
-
|
103
|
-
# Returns a saved User instance
|
104
|
-
user = Factory.create(:user)
|
105
|
-
|
106
|
-
# Returns a hash of attributes that can be used to build a User instance:
|
107
|
-
attrs = Factory.attributes_for(:user)
|
108
|
-
|
109
|
-
# Returns an object with all defined attributes stubbed out:
|
110
|
-
stub = Factory.stub(:user)
|
111
|
-
|
112
|
-
You can use the Factory method as a shortcut for the default build strategy:
|
113
|
-
|
114
|
-
# Same as Factory.create :user:
|
115
|
-
user = Factory(:user)
|
116
|
-
|
117
|
-
The default strategy can be overriden:
|
118
|
-
|
119
|
-
# Now same as Factory.build(:user)
|
120
|
-
Factory.define :user, :default_strategy => :build do |u|
|
30
|
+
# Factory definitions
|
31
|
+
Factory.define :user_john, :class => User, :singleton => true do |r|
|
121
32
|
...
|
122
33
|
end
|
123
34
|
|
124
|
-
|
125
|
-
|
126
|
-
No matter which strategy is used, it's possible to override the defined attributes by passing a hash:
|
127
|
-
|
128
|
-
# Build a User instance and override the first_name property
|
129
|
-
user = Factory.build(:user, :first_name => 'Joe')
|
130
|
-
user.first_name
|
131
|
-
# => "Joe"
|
132
|
-
|
133
|
-
== Lazy Attributes
|
134
|
-
|
135
|
-
Most factory attributes can be added using static values that are evaluated when the factory is defined, but some attributes (such as associations and other attributes that must be dynamically generated) will need values assigned each time an instance is generated. These "lazy" attributes can be added by passing a block instead of a parameter:
|
136
|
-
|
137
|
-
Factory.define :user do |u|
|
138
|
-
# ...
|
139
|
-
u.activation_code { User.generate_activation_code }
|
140
|
-
end
|
141
|
-
|
142
|
-
== Dependent Attributes
|
143
|
-
|
144
|
-
Attributes can be based on the values of other attributes using the proxy that is yieled to lazy attribute blocks:
|
145
|
-
|
146
|
-
Factory.define :user do |u|
|
147
|
-
u.first_name 'Joe'
|
148
|
-
u.last_name 'Blow'
|
149
|
-
u.email {|a| "#{a.first_name}.#{a.last_name}@example.com".downcase }
|
150
|
-
end
|
151
|
-
|
152
|
-
Factory(:user, :last_name => 'Doe').email
|
153
|
-
# => "joe.doe@example.com"
|
154
|
-
|
155
|
-
== Associations
|
156
|
-
|
157
|
-
Associated instances can be generated by using the association method when
|
158
|
-
defining a lazy attribute:
|
159
|
-
|
160
|
-
Factory.define :post do |p|
|
161
|
-
# ...
|
162
|
-
p.author {|author| author.association(:user, :last_name => 'Writely') }
|
163
|
-
end
|
164
|
-
|
165
|
-
The behavior of the association method varies depending on the build strategy used for the parent object.
|
166
|
-
|
167
|
-
# Builds and saves a User and a Post
|
168
|
-
post = Factory(:post)
|
169
|
-
post.new_record? # => false
|
170
|
-
post.author.new_record # => false
|
171
|
-
|
172
|
-
# Builds and saves a User, and then builds but does not save a Post
|
173
|
-
Factory.build(:post)
|
174
|
-
post.new_record? # => true
|
175
|
-
post.author.new_record # => false
|
176
|
-
|
177
|
-
Because this pattern is so common, a prettier syntax is available for defining
|
178
|
-
associations:
|
179
|
-
|
180
|
-
# The following definitions are equivilent:
|
181
|
-
Factory.define :post do |p|
|
182
|
-
p.author {|a| a.association(:user) }
|
183
|
-
end
|
184
|
-
|
185
|
-
Factory.define :post do |p|
|
186
|
-
p.association :author, :factory => :user
|
187
|
-
end
|
188
|
-
|
189
|
-
If the factory name is the same as the association name, the factory name can
|
190
|
-
be left out.
|
191
|
-
|
192
|
-
|
193
|
-
== Inheritance
|
194
|
-
|
195
|
-
You can easily create multiple factories for the same class without repeating common attributes by using inheritance:
|
196
|
-
|
197
|
-
Factory.define :post do |p|
|
198
|
-
# the 'title' attribute is required for all posts
|
199
|
-
p.title 'A title'
|
200
|
-
end
|
201
|
-
|
202
|
-
Factory.define :approved_post, :parent => :post do |p|
|
203
|
-
p.approved true
|
204
|
-
# the 'approver' association is required for an approved post
|
205
|
-
p.association :approver, :factory => :user
|
35
|
+
Factory.define :user_bob, :class => User, :singleton => true do |r|
|
36
|
+
...
|
206
37
|
end
|
207
38
|
|
208
|
-
|
39
|
+
This means you would not have the creation of a same factory and the code shown above turns green.
|
209
40
|
|
210
|
-
|
211
|
-
generated using sequences. Sequences are defined by calling Factory.sequence,
|
212
|
-
and values in a sequence are generated by calling Factory.next:
|
41
|
+
== Install
|
213
42
|
|
214
|
-
|
215
|
-
Factory.sequence :email do |n|
|
216
|
-
"person#{n}@example.com"
|
217
|
-
end
|
218
|
-
|
219
|
-
Factory.next :email
|
220
|
-
# => "person1@example.com"
|
221
|
-
|
222
|
-
Factory.next :email
|
223
|
-
# => "person2@example.com"
|
43
|
+
Use a gem package at gemucutter.org
|
224
44
|
|
225
|
-
|
45
|
+
config.gem "masa-iwasaki-factory_girl",
|
46
|
+
:lib => 'factory_girl', :source => "http://gemcutter.org"
|
226
47
|
|
227
|
-
|
228
|
-
f.email { Factory.next(:email) }
|
229
|
-
end
|
48
|
+
== Clearing caches
|
230
49
|
|
231
|
-
|
232
|
-
a particular factory:
|
50
|
+
You can clear cached instances anytime.
|
233
51
|
|
234
|
-
Factory
|
235
|
-
f.sequence(:email) {|n| "person#{n}@example.com" }
|
236
|
-
end
|
52
|
+
Factory::clear_caches
|
237
53
|
|
238
|
-
== Callbacks
|
239
54
|
|
240
|
-
|
55
|
+
== Clear caches on every test with RSpec.
|
241
56
|
|
242
|
-
|
243
|
-
|
244
|
-
|
57
|
+
You may want to clear caches on every iteration of test. With RSpec, you can set global before
|
58
|
+
filter in spec/spec_helper.rb
|
59
|
+
Spec::Runner.configure do |config|
|
60
|
+
...
|
245
61
|
|
246
|
-
|
62
|
+
config.before(:each) {
|
63
|
+
::Factory.clear_caches
|
64
|
+
}
|
247
65
|
|
248
|
-
|
249
|
-
Factory.define :user do |u|
|
250
|
-
u.after_build { |user| do_something_to(user) }
|
66
|
+
...
|
251
67
|
end
|
252
68
|
|
253
|
-
|
254
|
-
|
255
|
-
You can also define multiple types of callbacks on the same factory:
|
69
|
+
== Clear caches on every scenario with Cucumber
|
256
70
|
|
257
|
-
|
258
|
-
|
259
|
-
|
71
|
+
You can define step definition to clear caches like this.
|
72
|
+
|
73
|
+
Given /^I have no factory instances$/ do
|
74
|
+
::Factory.clear_caches
|
260
75
|
end
|
261
76
|
|
262
|
-
|
77
|
+
= Other modifications
|
78
|
+
== Show model name on validation error
|
79
|
+
For easy debugging, this fork overwrites validation error messages of an instance in factory_girl/proxy/create.rb.
|
263
80
|
|
264
|
-
|
265
|
-
|
266
|
-
|
81
|
+
begin
|
82
|
+
@instance.save!
|
83
|
+
run_callbacks(:after_create)
|
84
|
+
rescue => e
|
85
|
+
n = Exception.new("#{@instance.class.to_s} #{e.message}")
|
86
|
+
n.set_backtrace(e.backtrace)
|
87
|
+
raise n
|
267
88
|
end
|
268
89
|
|
269
|
-
|
270
|
-
|
271
|
-
Also, like standard attributes, child factories will inherit (and can define additional) callbacks from their parent factory.
|
272
|
-
|
273
|
-
== Alternate Syntaxes
|
274
|
-
|
275
|
-
Users' tastes for syntax vary dramatically, but most users are looking for a common feature set. Because of this, factory_girl supports "syntax layers" which provide alternate interfaces. See Factory::Syntax for information about the various layers available.
|
276
|
-
|
277
|
-
== More Information
|
278
|
-
|
279
|
-
Our blog: http://giantrobots.thoughtbot.com
|
280
|
-
|
281
|
-
factory_girl rdoc: http://rdoc.info/projects/thoughtbot/factory_girl
|
282
|
-
|
283
|
-
Mailing list: http://groups.google.com/group/factory_girl
|
284
|
-
|
285
|
-
factory_girl issues: http://github.com/thoughtbot/factory_girl/issues
|
286
|
-
|
287
|
-
== Contributing
|
288
|
-
|
289
|
-
Please read the contribution guidelines before submitting patches or pull requests.
|
290
|
-
|
291
|
-
== Author
|
292
|
-
|
293
|
-
factory_girl was written by Joe Ferris with contributions from several authors, including:
|
294
|
-
* Alex Sharp
|
295
|
-
* Eugene Bolshakov
|
296
|
-
* Jon Yurek
|
297
|
-
* Josh Nichols
|
298
|
-
* Josh Owens
|
299
|
-
* Nate Sutton
|
300
|
-
|
301
|
-
The syntax layers are derived from software written by the following authors:
|
302
|
-
* Pete Yandell
|
303
|
-
* Rick Bradley
|
304
|
-
* Yossef Mendelssohn
|
90
|
+
= Original repositry
|
305
91
|
|
306
|
-
|
92
|
+
http://github.com/thoughtbot/factory_girl[http://github.com/thoughtbot/factory_girl]
|
307
93
|
|
308
94
|
Copyright 2008-2009 Joe Ferris and thoughtbot[http://www.thoughtbot.com], inc.
|
data/Rakefile
CHANGED
@@ -38,7 +38,7 @@ end
|
|
38
38
|
|
39
39
|
spec = Gem::Specification.new do |s|
|
40
40
|
s.name = %q{masa-iwasaki-factory_girl}
|
41
|
-
s.version = "1.2.3.
|
41
|
+
s.version = "1.2.3.2"
|
42
42
|
s.summary = %q{factory_girl with singleton support}
|
43
43
|
s.description = %q{This forked factory_girl has been added a singleton
|
44
44
|
support. You can specify ':singleton => true' option
|
data/lib/factory_girl/factory.rb
CHANGED
@@ -3,7 +3,7 @@ class Factory
|
|
3
3
|
# Raised when a factory is defined that attempts to instantiate itself.
|
4
4
|
class AssociationDefinitionError < RuntimeError
|
5
5
|
end
|
6
|
-
|
6
|
+
|
7
7
|
# Raised when a callback is defined that has an invalid name
|
8
8
|
class InvalidCallbackNameError < RuntimeError
|
9
9
|
end
|
@@ -26,7 +26,7 @@ class Factory
|
|
26
26
|
self.definition_file_paths = %w(factories test/factories spec/factories)
|
27
27
|
|
28
28
|
attr_reader :factory_name #:nodoc:
|
29
|
-
attr_reader :
|
29
|
+
attr_reader :is_singleton #:nodoc:
|
30
30
|
attr_reader :attributes #:nodoc:
|
31
31
|
|
32
32
|
# Defines a new factory that can be used by the build strategies (create and
|
@@ -56,13 +56,13 @@ class Factory
|
|
56
56
|
if parent = options.delete(:parent)
|
57
57
|
instance.inherit_from(Factory.factory_by_name(parent))
|
58
58
|
end
|
59
|
-
if
|
60
|
-
instance.singleton
|
59
|
+
if options.delete(:singleton)
|
60
|
+
instance.singleton(true)
|
61
61
|
end
|
62
62
|
if self.factories[instance.factory_name]
|
63
63
|
raise DuplicateDefinitionError, "Factory already defined: #{name}"
|
64
64
|
end
|
65
|
-
|
65
|
+
|
66
66
|
self.factories[instance.factory_name] = instance
|
67
67
|
end
|
68
68
|
|
@@ -70,7 +70,11 @@ class Factory
|
|
70
70
|
def self.clear_caches
|
71
71
|
::Factory::Proxy::Create.clear_caches
|
72
72
|
end
|
73
|
-
|
73
|
+
|
74
|
+
def singleton(bool) #:nodoc:
|
75
|
+
@is_singleton = bool
|
76
|
+
end
|
77
|
+
|
74
78
|
def class_name #:nodoc:
|
75
79
|
@options[:class] || factory_name
|
76
80
|
end
|
@@ -78,7 +82,7 @@ class Factory
|
|
78
82
|
def build_class #:nodoc:
|
79
83
|
@build_class ||= class_for(class_name)
|
80
84
|
end
|
81
|
-
|
85
|
+
|
82
86
|
def default_strategy #:nodoc:
|
83
87
|
@options[:default_strategy] || :create
|
84
88
|
end
|
@@ -87,10 +91,10 @@ class Factory
|
|
87
91
|
assert_valid_options(options)
|
88
92
|
@factory_name = factory_name_for(name)
|
89
93
|
@options = options
|
90
|
-
@
|
94
|
+
@is_singleton = false
|
91
95
|
@attributes = []
|
92
96
|
end
|
93
|
-
|
97
|
+
|
94
98
|
def inherit_from(parent) #:nodoc:
|
95
99
|
@options[:class] ||= parent.class_name
|
96
100
|
parent.attributes.each do |attribute|
|
@@ -205,26 +209,26 @@ class Factory
|
|
205
209
|
s = Sequence.new(&block)
|
206
210
|
add_attribute(name) { s.next }
|
207
211
|
end
|
208
|
-
|
212
|
+
|
209
213
|
def after_build(&block)
|
210
214
|
callback(:after_build, &block)
|
211
215
|
end
|
212
|
-
|
216
|
+
|
213
217
|
def after_create(&block)
|
214
218
|
callback(:after_create, &block)
|
215
219
|
end
|
216
|
-
|
220
|
+
|
217
221
|
def after_stub(&block)
|
218
222
|
callback(:after_stub, &block)
|
219
223
|
end
|
220
|
-
|
224
|
+
|
221
225
|
def callback(name, &block)
|
222
226
|
unless [:after_build, :after_create, :after_stub].include?(name.to_sym)
|
223
227
|
raise InvalidCallbackNameError, "#{name} is not a valid callback name. Valid callback names are :after_build, :after_create, and :after_stub"
|
224
228
|
end
|
225
229
|
@attributes << Attribute::Callback.new(name.to_sym, block)
|
226
230
|
end
|
227
|
-
|
231
|
+
|
228
232
|
# Generates and returns a Hash of attributes from this factory. Attributes
|
229
233
|
# can be individually overridden by passing in a Hash of attribute => value
|
230
234
|
# pairs.
|
@@ -277,7 +281,7 @@ class Factory
|
|
277
281
|
def self.create (name, overrides = {})
|
278
282
|
factory_by_name(name).run(Proxy::Create, overrides)
|
279
283
|
end
|
280
|
-
|
284
|
+
|
281
285
|
# Generates and returns an object with all attributes from this factory
|
282
286
|
# stubbed out. Attributes can be individually overridden by passing in a Hash
|
283
287
|
# of attribute => value pairs.
|
@@ -293,7 +297,7 @@ class Factory
|
|
293
297
|
def self.stub (name, overrides = {})
|
294
298
|
factory_by_name(name).run(Proxy::Stub, overrides)
|
295
299
|
end
|
296
|
-
|
300
|
+
|
297
301
|
# Executes the default strategy for the given factory. This is usually create,
|
298
302
|
# but it can be overridden for each factory.
|
299
303
|
#
|
@@ -332,7 +336,7 @@ class Factory
|
|
332
336
|
end
|
333
337
|
end
|
334
338
|
proxy.factory_name = factory_name
|
335
|
-
proxy.
|
339
|
+
proxy.is_singleton = is_singleton
|
336
340
|
proxy.result
|
337
341
|
end
|
338
342
|
|
@@ -375,13 +379,13 @@ class Factory
|
|
375
379
|
end
|
376
380
|
|
377
381
|
def assert_valid_options(options)
|
378
|
-
invalid_keys = options.keys - [:class, :parent, :default_strategy]
|
382
|
+
invalid_keys = options.keys - [:class, :parent, :default_strategy, :singleton]
|
379
383
|
unless invalid_keys == []
|
380
384
|
raise ArgumentError, "Unknown arguments: #{invalid_keys.inspect}"
|
381
385
|
end
|
382
386
|
assert_valid_strategy(options[:default_strategy]) if options[:default_strategy]
|
383
387
|
end
|
384
|
-
|
388
|
+
|
385
389
|
def assert_valid_strategy(strategy)
|
386
390
|
unless Factory::Proxy.const_defined? variable_name_to_class_name(strategy)
|
387
391
|
raise ArgumentError, "Unknown strategy: #{strategy}"
|
@@ -401,14 +405,14 @@ class Factory
|
|
401
405
|
def variable_name_to_class_name(name)
|
402
406
|
name.to_s.
|
403
407
|
gsub(/\/(.?)/) { "::#{$1.upcase}" }.
|
404
|
-
|
408
|
+
gsub(/(?:^|_)(.)/) { $1.upcase }
|
405
409
|
end
|
406
410
|
|
407
411
|
# From ActiveSupport
|
408
412
|
def symbolize_keys(hash)
|
409
413
|
hash.inject({}) do |options, (key, value)|
|
410
414
|
options[(key.to_sym rescue key) || key] = value
|
411
|
-
|
415
|
+
options
|
412
416
|
end
|
413
417
|
end
|
414
418
|
|
data/lib/factory_girl/proxy.rb
CHANGED