vitalish-factory_girl 1.2.5 → 1.2.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/README.rdoc +67 -121
  2. data/Rakefile +103 -29
  3. data/VERSION +1 -0
  4. data/lib/factory_girl/aliases.rb +32 -3
  5. data/lib/factory_girl/attribute/association.rb +1 -1
  6. data/lib/factory_girl/attribute/callback.rb +1 -1
  7. data/lib/factory_girl/attribute/dynamic.rb +3 -3
  8. data/lib/factory_girl/attribute/static.rb +1 -1
  9. data/lib/factory_girl/attribute.rb +3 -3
  10. data/lib/factory_girl/factory.rb +354 -164
  11. data/lib/factory_girl/proxy/attributes_for.rb +1 -1
  12. data/lib/factory_girl/proxy/build.rb +5 -7
  13. data/lib/factory_girl/proxy/create.rb +3 -2
  14. data/lib/factory_girl/proxy/stub.rb +5 -19
  15. data/lib/factory_girl/proxy.rb +23 -7
  16. data/lib/factory_girl/sequence.rb +40 -5
  17. data/lib/factory_girl/step_definitions.rb +13 -19
  18. data/lib/factory_girl/syntax/blueprint.rb +5 -5
  19. data/lib/factory_girl/syntax/generate.rb +8 -13
  20. data/lib/factory_girl/syntax/make.rb +7 -9
  21. data/lib/factory_girl/syntax/sham.rb +8 -11
  22. data/lib/factory_girl/syntax.rb +7 -7
  23. data/lib/factory_girl.rb +19 -8
  24. data/spec/factory_girl/aliases_spec.rb +5 -9
  25. data/spec/factory_girl/attribute/association_spec.rb +4 -4
  26. data/spec/factory_girl/attribute/callback_spec.rb +4 -4
  27. data/spec/factory_girl/attribute/dynamic_spec.rb +10 -21
  28. data/spec/factory_girl/attribute/static_spec.rb +6 -6
  29. data/spec/factory_girl/attribute_spec.rb +6 -6
  30. data/spec/factory_girl/factory_spec.rb +465 -305
  31. data/spec/factory_girl/proxy/attributes_for_spec.rb +3 -3
  32. data/spec/factory_girl/proxy/build_spec.rb +13 -18
  33. data/spec/factory_girl/proxy/create_spec.rb +13 -18
  34. data/spec/factory_girl/proxy/stub_spec.rb +6 -7
  35. data/spec/factory_girl/proxy_spec.rb +3 -3
  36. data/spec/factory_girl/sequence_spec.rb +39 -16
  37. data/spec/factory_girl/syntax/blueprint_spec.rb +34 -0
  38. data/spec/factory_girl/syntax/generate_spec.rb +57 -0
  39. data/spec/factory_girl/syntax/make_spec.rb +35 -0
  40. data/spec/factory_girl/syntax/sham_spec.rb +35 -0
  41. data/spec/integration_spec.rb +304 -0
  42. data/spec/models.rb +43 -0
  43. data/spec/spec_helper.rb +10 -85
  44. metadata +15 -3
data/README.rdoc CHANGED
@@ -1,56 +1,49 @@
1
- = NOTE: this documentation is for the beta version of factory_girl 2
2
-
3
- Up-to-date documentation for the stable branch can be found here:
4
-
5
- http://github.com/thoughtbot/factory_girl/tree/1.3.x
6
-
7
1
  = factory_girl
8
2
 
9
3
  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.
10
4
 
11
- If you want to use factory_girl with Rails 3, see
12
- http://github.com/thoughtbot/factory_girl_rails
13
-
14
5
  == Download
15
6
 
16
7
  Github: http://github.com/thoughtbot/factory_girl/tree/master
17
8
 
18
9
  Gem:
19
- gem install factory_girl
10
+ gem install thoughtbot-factory_girl --source http://gems.github.com
11
+
12
+ Note: if you install factory_girl using the gem from Github, you'll need this
13
+ in your environment.rb if you want to use Rails 2.1+'s dependency manager:
14
+
15
+ config.gem "thoughtbot-factory_girl",
16
+ :lib => "factory_girl",
17
+ :source => "http://gems.github.com"
20
18
 
21
19
  == Defining factories
22
20
 
23
21
  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:
24
22
 
25
23
  # This will guess the User class
26
- FactoryGirl.define do
27
- factory :user do
28
- first_name 'John'
29
- last_name 'Doe'
30
- admin false
31
- end
32
-
33
- # This will use the User class (Admin would have been guessed)
34
- factory :admin, :class => User do
35
- first_name 'Admin'
36
- last_name 'User'
37
- admin true
38
- end
39
-
40
- # The same, but using a string instead of class constant
41
- factory :admin, :class => 'user' do
42
- first_name 'Admin'
43
- last_name 'User'
44
- admin true
45
- end
24
+ Factory.define :user do |u|
25
+ u.first_name 'John'
26
+ u.last_name 'Doe'
27
+ u.admin false
46
28
  end
47
29
 
48
- 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.
30
+ # This will use the User class (Admin would have been guessed)
31
+ Factory.define :admin, :class => User do |u|
32
+ u.first_name 'Admin'
33
+ u.last_name 'User'
34
+ u.admin true
35
+ end
49
36
 
50
- Attempting to define multiple factories with the same name will raise an error.
37
+ # The same, but using a string instead of class constant
38
+ Factory.define :admin, :class => 'user' do |u|
39
+ u.first_name 'Admin'
40
+ u.last_name 'User'
41
+ u.admin true
42
+ end
43
+
44
+ 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.
51
45
 
52
- Factories can be defined anywhere, but will be automatically loaded if they
53
- are defined in files at the following locations:
46
+ Factories can either be defined anywhere, but will automatically be loaded if they are defined in files at the following locations:
54
47
 
55
48
  test/factories.rb
56
49
  spec/factories.rb
@@ -81,13 +74,13 @@ You can use the Factory method as a shortcut for the default build strategy:
81
74
  The default strategy can be overriden:
82
75
 
83
76
  # Now same as Factory.build(:user)
84
- factory :user, :default_strategy => :build do
77
+ Factory.define :user, :default_strategy => :build do |u|
85
78
  ...
86
79
  end
87
80
 
88
81
  user = Factory(:user)
89
82
 
90
- No matter which strategy is used, it's possible to override the defined attributes by passing a hash:
83
+ No matter which startegy is used, it's possible to override the defined attributes by passing a hash:
91
84
 
92
85
  # Build a User instance and override the first_name property
93
86
  user = Factory.build(:user, :first_name => 'Joe')
@@ -98,19 +91,19 @@ No matter which strategy is used, it's possible to override the defined attribut
98
91
 
99
92
  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:
100
93
 
101
- factory :user do
94
+ Factory.define :user do |u|
102
95
  # ...
103
- activation_code { User.generate_activation_code }
96
+ u.activation_code { User.generate_activation_code }
104
97
  end
105
98
 
106
99
  == Dependent Attributes
107
100
 
108
101
  Attributes can be based on the values of other attributes using the proxy that is yieled to lazy attribute blocks:
109
102
 
110
- factory :user do
111
- first_name 'Joe'
112
- last_name 'Blow'
113
- email { "#{first_name}.#{last_name}@example.com".downcase }
103
+ Factory.define :user do |u|
104
+ u.first_name 'Joe'
105
+ u.last_name 'Blow'
106
+ u.email {|a| "#{a.first_name}.#{a.last_name}@example.com".downcase }
114
107
  end
115
108
 
116
109
  Factory(:user, :last_name => 'Doe').email
@@ -121,16 +114,9 @@ Attributes can be based on the values of other attributes using the proxy that i
121
114
  Associated instances can be generated by using the association method when
122
115
  defining a lazy attribute:
123
116
 
124
- factory :post do
117
+ Factory.define :post do |p|
125
118
  # ...
126
- author
127
- end
128
-
129
- You can also specify a different factory or override attributes:
130
-
131
- factory :post do
132
- # ...
133
- association :author, :factory => :user, :last_name => 'Writely'
119
+ p.author {|author| author.association(:user, :last_name => 'Writely') }
134
120
  end
135
121
 
136
122
  The behavior of the association method varies depending on the build strategy used for the parent object.
@@ -141,10 +127,22 @@ The behavior of the association method varies depending on the build strategy us
141
127
  post.author.new_record # => false
142
128
 
143
129
  # Builds and saves a User, and then builds but does not save a Post
144
- post = Factory.build(:post)
130
+ Factory.build(:post)
145
131
  post.new_record? # => true
146
132
  post.author.new_record # => false
147
133
 
134
+ Because this pattern is so common, a prettier syntax is available for defining
135
+ associations:
136
+
137
+ # The following definitions are equivilent:
138
+ Factory.define :post do |p|
139
+ p.author {|a| a.association(:user) }
140
+ end
141
+
142
+ Factory.define :post do |p|
143
+ p.association :author, :factory => :user
144
+ end
145
+
148
146
  If the factory name is the same as the association name, the factory name can
149
147
  be left out.
150
148
 
@@ -152,15 +150,15 @@ be left out.
152
150
 
153
151
  You can easily create multiple factories for the same class without repeating common attributes by using inheritance:
154
152
 
155
- factory :post do
153
+ Factory.define :post do |p|
156
154
  # the 'title' attribute is required for all posts
157
- title 'A title'
155
+ p.title 'A title'
158
156
  end
159
157
 
160
- factory :approved_post, :parent => :post do
161
- approved true
158
+ Factory.define :approved_post, :parent => :post do |p|
159
+ p.approved true
162
160
  # the 'approver' association is required for an approved post
163
- association :approver, :factory => :user
161
+ p.association :approver, :factory => :user
164
162
  end
165
163
 
166
164
  == Sequences
@@ -170,7 +168,7 @@ generated using sequences. Sequences are defined by calling Factory.sequence,
170
168
  and values in a sequence are generated by calling Factory.next:
171
169
 
172
170
  # Defines a new sequence
173
- FactoryGirl.sequence :email do |n|
171
+ Factory.sequence :email do |n|
174
172
  "person#{n}@example.com"
175
173
  end
176
174
 
@@ -180,83 +178,32 @@ and values in a sequence are generated by calling Factory.next:
180
178
  Factory.next :email
181
179
  # => "person2@example.com"
182
180
 
183
- Sequences can be used as attributes:
184
-
185
- factory :user do
186
- email
187
- end
188
-
189
- Or in lazy attributes:
181
+ Sequences can be used in lazy attributes:
190
182
 
191
- factory :invite do
192
- invitee { Factory.next(:email) }
183
+ Factory.define :user do |f|
184
+ f.email { Factory.next(:email) }
193
185
  end
194
186
 
195
187
  And it's also possible to define an in-line sequence that is only used in
196
188
  a particular factory:
197
189
 
198
- factory :user do
190
+ Factory.define :user do |f|
199
191
  f.sequence(:email) {|n| "person#{n}@example.com" }
200
192
  end
201
193
 
202
- == Callbacks
203
-
204
- Factory_girl makes available three callbacks for injecting some code:
205
-
206
- * after_build - called after a factory is built (via Factory.build)
207
- * after_create - called after a factory is saved (via Factory.create)
208
- * after_stub - called after a factory is stubbed (via Factory.stub)
209
-
210
- Examples:
211
-
212
- # Define a factory that calls the generate_hashed_password method after it is built
213
- factory :user do
214
- after_build { |user| do_something_to(user) }
215
- end
216
-
217
- Note that you'll have an instance of the user in the block. This can be useful.
218
-
219
- You can also define multiple types of callbacks on the same factory:
220
-
221
- factory :user do
222
- after_build { |user| do_something_to(user) }
223
- after_create { |user| do_something_else_to(user) }
224
- end
225
-
226
- Factories can also define any number of the same kind of callback. These callbacks will be executed in the order they are specified:
227
-
228
- factory :user do
229
- after_create { this_runs_first }
230
- after_create { then_this }
231
- end
232
-
233
- Calling Factory.create will invoke both after_build and after_create callbacks.
234
-
235
- Also, like standard attributes, child factories will inherit (and can define additional) callbacks from their parent factory.
236
-
237
194
  == Alternate Syntaxes
238
195
 
239
- 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. For example, the Machinist-style syntax is popular:
196
+ 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.
240
197
 
241
- require 'factory_girl/syntax/blueprint'
242
- require 'factory_girl/syntax/make'
243
- require 'factory_girl/syntax/sham'
198
+ == More Information
244
199
 
245
- Sham.email {|n| "#{n}@example.com" }
200
+ Our blog: http://giantrobots.thoughtbot.com
246
201
 
247
- User.blueprint do
248
- name { 'Billy Bob' }
249
- email { Sham.email }
250
- end
202
+ factory_girl rdoc: http://rdoc.info/projects/thoughtbot/factory_girl
251
203
 
252
- User.make(:name => 'Johnny')
253
-
254
- == More Information
204
+ Mailing list: http://groups.google.com/group/factory_girl
255
205
 
256
- * RDoc[http://rdoc.info/projects/thoughtbot/factory_girl]
257
- * Mailing list[http://groups.google.com/group/factory_girl]
258
- * Issues[http://github.com/thoughtbot/factory_girl/issues]
259
- * GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS[http://giantrobots.thoughtbot.com]
206
+ factory_girl issues: http://github.com/thoughtbot/factory_girl/issues
260
207
 
261
208
  == Contributing
262
209
 
@@ -270,7 +217,6 @@ factory_girl was written by Joe Ferris with contributions from several authors,
270
217
  * Jon Yurek
271
218
  * Josh Nichols
272
219
  * Josh Owens
273
- * Nate Sutton
274
220
 
275
221
  The syntax layers are derived from software written by the following authors:
276
222
  * Pete Yandell
@@ -279,4 +225,4 @@ The syntax layers are derived from software written by the following authors:
279
225
 
280
226
  Thanks to all members of thoughtbot for inspiration, ideas, and funding.
281
227
 
282
- Copyright 2008-2010 Joe Ferris and thoughtbot[http://www.thoughtbot.com], inc.
228
+ Copyright 2008-2009 Joe Ferris and thoughtbot[http://www.thoughtbot.com], inc.
data/Rakefile CHANGED
@@ -1,34 +1,20 @@
1
1
  require 'rubygems'
2
- require 'bundler/setup'
3
2
  require 'rake'
4
3
  require 'rake/rdoctask'
4
+ require 'rake/gempackagetask'
5
5
  require 'rcov/rcovtask'
6
6
  require 'date'
7
- require 'rake/gempackagetask'
8
- require 'rspec/core/rake_task'
7
+
8
+ require 'spec/rake/spectask'
9
9
  require 'cucumber/rake/task'
10
- require 'appraisal'
11
10
 
12
11
  desc 'Default: run the specs and features.'
13
- task :default => 'spec:unit' do
14
- system("rake -s appraisal spec:acceptance features;")
15
- end
12
+ task :default => [:spec, :features]
16
13
 
17
- namespace :spec do
18
- desc "Run unit specs"
19
- RSpec::Core::RakeTask.new('unit') do |t|
20
- t.pattern = 'spec/factory_girl/**/*_spec.rb'
21
- end
22
-
23
- desc "Run acceptance specs"
24
- RSpec::Core::RakeTask.new('acceptance') do |t|
25
- t.pattern = 'spec/acceptance/**/*_spec.rb'
26
- end
14
+ Spec::Rake::SpecTask.new do |t|
15
+ t.spec_opts = ['--options', "spec/spec.opts"]
27
16
  end
28
17
 
29
- desc "Run the unit and acceptance specs"
30
- task :spec => ['spec:unit', 'spec:acceptance']
31
-
32
18
  desc 'Performs code coverage on the factory_girl plugin.'
33
19
  Rcov::RcovTask.new do |t|
34
20
  t.test_files = FileList['spec/*_spec.rb']
@@ -50,17 +36,105 @@ task :sync_docs => 'rdoc' do
50
36
  `rsync -ave ssh rdoc/ dev@dev.thoughtbot.com:/home/dev/www/dev.thoughtbot.com/factory_girl`
51
37
  end
52
38
 
53
- desc "Clean files generated by rake tasks"
54
- task :clobber => [:clobber_rdoc, :clobber_rcov]
39
+ # spec = Gem::Specification.new do |s|
40
+ # s.name = %q{factory_girl}
41
+ # s.version = "1.2.3"
42
+ # s.summary = %q{factory_girl provides a framework and DSL for defining and
43
+ # using model instance factories.}
44
+ # s.description = %q{factory_girl provides a framework and DSL for defining and
45
+ # using factories - less error-prone, more explicit, and
46
+ # all-around easier to work with than fixtures.}
47
+ #
48
+ # s.files = FileList['[A-Z]*', 'lib/**/*.rb', 'spec/**/*.rb']
49
+ # s.require_path = 'lib'
50
+ # s.test_files = Dir[*['spec/**/*_spec.rb']]
51
+ #
52
+ # s.has_rdoc = true
53
+ # s.extra_rdoc_files = ["README.rdoc"]
54
+ # s.rdoc_options = ['--line-numbers', "--main", "README.rdoc"]
55
+ #
56
+ # s.authors = ["Joe Ferris"]
57
+ # s.email = %q{jferris@thoughtbot.com}
58
+ # s.homepage = "http://thoughtbot.com/projects/factory_girl"
59
+ #
60
+ # s.platform = Gem::Platform::RUBY
61
+ # end
55
62
 
56
- Cucumber::Rake::Task.new(:features) do |t|
57
- t.fork = true
58
- t.cucumber_opts = ['--format', (ENV['CUCUMBER_FORMAT'] || 'progress')]
63
+ require 'jeweler'
64
+
65
+ class Jeweler
66
+ module Commands
67
+ class ReleaseGemspec
68
+ def run
69
+ unless clean_staging_area?
70
+ system "git status"
71
+ raise "Unclean staging area! Be sure to commit or .gitignore everything first. See `git status` above."
72
+ end
73
+
74
+ repo.checkout('parametrize')
75
+
76
+ regenerate_gemspec!
77
+ commit_gemspec! if gemspec_changed?
78
+
79
+ output.puts "Pushing parametrize to origin"
80
+ repo.push
81
+ end
82
+ end
83
+ end
59
84
  end
60
85
 
61
- eval("$specification = begin; #{IO.read('factory_girl.gemspec')}; end")
62
- Rake::GemPackageTask.new($specification) do |package|
63
- package.need_zip = true
64
- package.need_tar = true
86
+ class Jeweler
87
+ module Commands
88
+ class ReleaseToGit
89
+ def run
90
+ unless clean_staging_area?
91
+ system "git status"
92
+ raise "Unclean staging area! Be sure to commit or .gitignore everything first. See `git status` above."
93
+ end
94
+ output.puts "Checkouting"
95
+ repo.checkout('parametrize')
96
+ repo.push
97
+
98
+ if release_not_tagged?
99
+ output.puts "Tagging #{release_tag}"
100
+ repo.add_tag(release_tag)
101
+
102
+ output.puts "Pushing #{release_tag} to origin"
103
+ repo.push('origin', release_tag)
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
109
+ jt = Jeweler::Tasks.new do |gem|
110
+ gem.name = "vitalish-factory_girl"
111
+ gem.summary = "factory_girl provides a framework and DSL for defining and using model instance factories."
112
+ gem.description = "factory_girl provides a framework and DSL for defining and using factories - less error-prone, more explicit, and all-around easier to work with than fixtures."
113
+ gem.email = "jferris@thoughtbot.com"
114
+ gem.homepage = "http://thoughtbot.com/projects/factory_girl"
115
+ gem.authors = ["Joe Ferris","Vitalish"]
116
+ gem.has_rdoc = true
117
+ gem.files = FileList['[A-Z]*', 'lib/**/*.rb', 'spec/**/*.rb']
118
+ gem.test_files = Dir[*['spec/**/*_spec.rb']]
65
119
  end
120
+ Jeweler::GemcutterTasks.new
66
121
 
122
+ # Rake::GemPackageTask.new spec do |pkg|
123
+ # pkg.need_tar = true
124
+ # pkg.need_zip = true
125
+ # end
126
+
127
+ # desc "Clean files generated by rake tasks"
128
+ # task :clobber => [:clobber_rdoc, :clobber_package]
129
+ #
130
+ # desc "Generate a gemspec file"
131
+ # task :gemspec do
132
+ # File.open("#{spec.name}.gemspec", 'w') do |f|
133
+ # f.write spec.to_ruby
134
+ # end
135
+ # end
136
+
137
+ Cucumber::Rake::Task.new(:features) do |t|
138
+ t.fork = true
139
+ t.cucumber_opts = ['--format', (ENV['CUCUMBER_FORMAT'] || 'progress')]
140
+ end