factory_girl_extensions 0.4.0 → 2.0.0
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.
- data/.gemtest +0 -0
- data/.gitignore +2 -0
- data/Gemfile +3 -0
- data/README.markdown +115 -0
- data/Rakefile +10 -0
- data/factory_girl_extensions.gemspec +27 -0
- data/lib/factory_girl_extensions/core.rb +151 -0
- data/lib/factory_girl_extensions/version.rb +8 -0
- data/lib/factory_girl_extensions.rb +2 -4
- data/spec/factory_girl_extensions_spec.rb +232 -0
- metadata +62 -55
- data/lib/factory_girl_extensions/module.rb +0 -91
data/.gemtest
ADDED
File without changes
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.markdown
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
# FactoryGirl extensions
|
2
|
+
|
3
|
+
factory_girl_extensions is a simple set of syntax extensions that I typically like to use on projects when using factory_girl.
|
4
|
+
|
5
|
+
## Install
|
6
|
+
|
7
|
+
gem install factory_girl_extensions
|
8
|
+
|
9
|
+
## FactoryGirl extensions 2.0
|
10
|
+
|
11
|
+
As of version 2.0, factory_girl_extensions now targets the new FactoryGirl 2.0 API.
|
12
|
+
|
13
|
+
- Only FactoryGirl 2.0+ is supported now. If you are using an older version of FactoryGirl, please use factory_girl_extensions < 2.0
|
14
|
+
- You can no longer use `:email.next` to generate the next :email sequence. factory_girl_extensions no longer includes custom sequence code (because this feature wasn't heavily used and the new FactoryGirl inline sequences are pretty awesome)
|
15
|
+
- The code has been updated to be Ruby 1.8/1.9 compatible and now follows the same patterns as other official FactoryGirl alternative syntaxes
|
16
|
+
|
17
|
+
## Usage
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
require 'factory_girl_extensions'
|
21
|
+
|
22
|
+
FactoryGirl.define do
|
23
|
+
factory :user do
|
24
|
+
name 'Bob Smith'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Creates a saved instance without raising (same as saving the result of FactoryGirl.build)
|
29
|
+
User.generate(:name => 'Johnny')
|
30
|
+
|
31
|
+
# Creates a saved instance and raises when invalid (same as FactoryGirl.create)
|
32
|
+
User.generate!
|
33
|
+
|
34
|
+
# Creates an unsaved instance (same as FactoryGirl.build)
|
35
|
+
User.build
|
36
|
+
|
37
|
+
# Creates an instance and yields it to the passed block
|
38
|
+
User.generate do |user|
|
39
|
+
# ...do something with user...
|
40
|
+
end
|
41
|
+
|
42
|
+
# Creates and returns a Hash of attributes from this factory (same as FactoryGirl.attributes_for).
|
43
|
+
User.attributes
|
44
|
+
|
45
|
+
# A few short aliases are included for convenience.
|
46
|
+
User.gen
|
47
|
+
User.gen!
|
48
|
+
User.attrs
|
49
|
+
|
50
|
+
# Factories with custom prefix/suffixes are also supported.
|
51
|
+
FactoryGirl.define do
|
52
|
+
factory :admin_user, :parent => :user do
|
53
|
+
is_admin true
|
54
|
+
end
|
55
|
+
|
56
|
+
factory :user_with_profile, :parent => :user do
|
57
|
+
profile_complete true
|
58
|
+
end
|
59
|
+
|
60
|
+
factory :admin_user_with_profile, :parent => :admin_user do
|
61
|
+
profile_complete true
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Generates the :admin_user factory
|
66
|
+
User.generate(:admin)
|
67
|
+
User.generate(:admin, :name => 'Cool Admin')
|
68
|
+
|
69
|
+
# Generates the :user_with_profile factory
|
70
|
+
User.generate(:with_profile)
|
71
|
+
|
72
|
+
# Generates the :admin_user_with_profile factory
|
73
|
+
User.generate(:admin, :with_profile)
|
74
|
+
User.generate(:admin, :with_profile, :name => 'Custom name')
|
75
|
+
|
76
|
+
# User.build and User.attributes also support these custom prefix/suffixes.
|
77
|
+
```
|
78
|
+
|
79
|
+
## Why User.gen instead of FactoryGirl(:user)?
|
80
|
+
|
81
|
+
Personally, I really dislike the `FactoryGirl(:user)` syntax. When you have a lot of
|
82
|
+
factories, it's hard to see the names of the actual model classes. I don't like this:
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
FactoryGirl(:user).should be_valid
|
86
|
+
FactoryGirl(:name, :string => 'something').should be_awesome
|
87
|
+
FactoryGirl(:comment, :user => Factory(:user)).should be_cool
|
88
|
+
FactoryGirl(:user).should do_some_stuff_with(:things)
|
89
|
+
```
|
90
|
+
|
91
|
+
To me, the thing that draws my attention in that code snippet is `FactoryGirl`.
|
92
|
+
I don't care about `Factory`, I care about the actual models! I prefer:
|
93
|
+
|
94
|
+
```ruby
|
95
|
+
User.gen.should be_valid
|
96
|
+
Name.gen(:string => 'something').should be_awesome
|
97
|
+
Comment.gen(:user => User.gen).should be_cool
|
98
|
+
User.gen.should do_some_stuff_with(:things)
|
99
|
+
```
|
100
|
+
|
101
|
+
When you syntax highlight the above code, the constants (model names) are usually
|
102
|
+
the things that really jump out at you. Even in plain text, it's easier to
|
103
|
+
understand that code than the above `FactoryGirl(:code)` in my opinion.
|
104
|
+
|
105
|
+
## Dude, why isn't this stuff included in the official FactoryGirl gem as an alternative syntax?
|
106
|
+
|
107
|
+
Originally, when I made this, not many people were using this syntax.
|
108
|
+
|
109
|
+
Now that I know many people using this syntax, I may send a pull request to FactoryGirl to see if they would consider accepting this.
|
110
|
+
|
111
|
+
As of factory_girl_extensions 2.0, the code is actually written in the same style as official syntaxes, so it should be very easy to include this into the official FactoryGirl gem.
|
112
|
+
|
113
|
+
## License
|
114
|
+
|
115
|
+
factory_girl_extensions is released under the MIT license.
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path("../lib/factory_girl_extensions/version", __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.name = "factory_girl_extensions"
|
6
|
+
gem.author = "remi"
|
7
|
+
gem.email = "remi@remitaylor.com"
|
8
|
+
gem.homepage = "http://github.com/remi/factory_girl_extensions"
|
9
|
+
gem.summary = "Alternative FactoryGirl API"
|
10
|
+
|
11
|
+
gem.description = <<-desc.gsub(/^\s+/, '')
|
12
|
+
Alternative FactoryGirl API allowing you to build/generate factories
|
13
|
+
using your class constants, eg. User.gen instead of Factory(:user).
|
14
|
+
desc
|
15
|
+
|
16
|
+
files = `git ls-files`.split("\n")
|
17
|
+
gem.files = files
|
18
|
+
gem.executables = files.grep(%r{^bin/.*}).map {|f| File.basename(f) }
|
19
|
+
gem.test_files = files.grep(%r{^spec/.*})
|
20
|
+
gem.require_paths = ["lib"]
|
21
|
+
gem.version = FactoryGirlExtensions::VERSION
|
22
|
+
|
23
|
+
gem.add_dependency "factory_girl", ">= 2.0"
|
24
|
+
|
25
|
+
gem.add_development_dependency "rake"
|
26
|
+
gem.add_development_dependency "rspec"
|
27
|
+
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
require "factory_girl_extensions/version"
|
2
|
+
|
3
|
+
module FactoryGirl
|
4
|
+
module Syntax
|
5
|
+
|
6
|
+
# Extends any object to provide generation methods for factories.
|
7
|
+
#
|
8
|
+
# Usage:
|
9
|
+
#
|
10
|
+
# require 'factory_girl_extensions'
|
11
|
+
#
|
12
|
+
# FactoryGirl.define do
|
13
|
+
# factory :user do
|
14
|
+
# name 'Bob Smith'
|
15
|
+
# end
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# # Creates a saved instance without raising (same as saving the result of FactoryGirl.build)
|
19
|
+
# User.generate(:name => 'Johnny')
|
20
|
+
#
|
21
|
+
# # Creates a saved instance and raises when invalid (same as FactoryGirl.create)
|
22
|
+
# User.generate!
|
23
|
+
#
|
24
|
+
# # Creates an unsaved instance (same as FactoryGirl.build)
|
25
|
+
# User.build
|
26
|
+
#
|
27
|
+
# # Creates an instance and yields it to the passed block
|
28
|
+
# User.generate do |user|
|
29
|
+
# # ...do something with user...
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# # Creates and returns a Hash of attributes from this factory (same as FactoryGirl.attributes_for).
|
33
|
+
# User.attributes
|
34
|
+
#
|
35
|
+
# # A few short aliases are included for convenience.
|
36
|
+
# User.gen
|
37
|
+
# User.gen!
|
38
|
+
# User.attrs
|
39
|
+
#
|
40
|
+
# # Factories with custom prefix/suffixes are also supported.
|
41
|
+
# FactoryGirl.define do
|
42
|
+
# factory :admin_user, :parent => :user do
|
43
|
+
# is_admin true
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# factory :user_with_profile, :parent => :user do
|
47
|
+
# profile_complete true
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
# factory :admin_user_with_profile, :parent => :admin_user do
|
51
|
+
# profile_complete true
|
52
|
+
# end
|
53
|
+
# end
|
54
|
+
#
|
55
|
+
# # Generates the :admin_user factory
|
56
|
+
# User.generate(:admin)
|
57
|
+
# User.generate(:admin, :name => 'Cool Admin')
|
58
|
+
#
|
59
|
+
# # Generates the :user_with_profile factory
|
60
|
+
# User.generate(:with_profile)
|
61
|
+
#
|
62
|
+
# # Generates the :admin_user_with_profile factory
|
63
|
+
# User.generate(:admin, :with_profile)
|
64
|
+
# User.generate(:admin, :with_profile, :name => 'Custom name')
|
65
|
+
#
|
66
|
+
# # User.build and User.attributes also support these custom prefix/suffixes.
|
67
|
+
#
|
68
|
+
# This syntax was derived from remi Taylor's factory_girl_extensions.
|
69
|
+
module ObjectMethods
|
70
|
+
|
71
|
+
# Creates an unsaved instance (same as FactoryGirl.build)
|
72
|
+
def build(*args, &block)
|
73
|
+
factory, overrides = ObjectMethods.factory_and_overrides(name.underscore, args)
|
74
|
+
instance = factory.run(Strategy::Build, overrides, &block)
|
75
|
+
instance
|
76
|
+
end
|
77
|
+
|
78
|
+
# Creates a saved instance without raising (same as saving the result of FactoryGirl.build)
|
79
|
+
def generate(*args, &block)
|
80
|
+
instance = build(*args)
|
81
|
+
instance.save
|
82
|
+
yield instance if block_given?
|
83
|
+
instance
|
84
|
+
end
|
85
|
+
|
86
|
+
# Creates a saved instance and raises when invalid (same as FactoryGirl.create)
|
87
|
+
def generate!(*args, &block)
|
88
|
+
factory, overrides = ObjectMethods.factory_and_overrides(name.underscore, args)
|
89
|
+
instance = factory.run(Strategy::Create, overrides, &block)
|
90
|
+
instance
|
91
|
+
end
|
92
|
+
|
93
|
+
# Creates and returns a Hash of attributes from this factory (same as FactoryGirl.attributes_for)
|
94
|
+
def attributes(*args, &block)
|
95
|
+
factory, overrides = ObjectMethods.factory_and_overrides(name.underscore, args)
|
96
|
+
attrs = factory.run(Strategy::AttributesFor, overrides, &block)
|
97
|
+
attrs
|
98
|
+
end
|
99
|
+
|
100
|
+
alias attrs attributes
|
101
|
+
alias gen generate
|
102
|
+
alias gen! generate!
|
103
|
+
|
104
|
+
# @private
|
105
|
+
#
|
106
|
+
# Helper to get the Factory object and overrides hash from the arguments passed to any ObjectMethods.
|
107
|
+
def self.factory_and_overrides(base_name, args)
|
108
|
+
overrides = args.last.is_a?(Hash) ? args.pop : {}
|
109
|
+
factory = find_factory(base_name, args)
|
110
|
+
raise ArgumentError.new("Could not find factory for #{base_name.inspect} with #{args.inspect}") unless factory
|
111
|
+
[factory, overrides]
|
112
|
+
end
|
113
|
+
|
114
|
+
# @private
|
115
|
+
#
|
116
|
+
# Given the base_name for a class's factory and 0-2 parts (prefix/suffixes),
|
117
|
+
# this finds the first matching factory that FactoryGirl has in its registry.
|
118
|
+
def self.find_factory(base_name, parts)
|
119
|
+
case parts.length
|
120
|
+
when 0
|
121
|
+
detect_factory base_name
|
122
|
+
when 1
|
123
|
+
detect_factory "#{parts.first}_#{base_name}", "#{base_name}_#{parts.first}"
|
124
|
+
when 2
|
125
|
+
detect_factory "#{parts.first}_#{base_name}_#{parts.last}", "#{parts.last}_#{base_name}_#{parts.first}"
|
126
|
+
else
|
127
|
+
raise ArgumentError.new("Don't know how to find factory for #{base_name.inspect} with #{parts.inspect}")
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# @private
|
132
|
+
#
|
133
|
+
# Given any number of arguments representing the possible names for a factory that you
|
134
|
+
# want to find, this iterates over the given names and returns the first FactoryGirl
|
135
|
+
# factory object that FactoryGirl returns (skipping unregistered factory names).
|
136
|
+
def self.detect_factory(*possible_factory_names)
|
137
|
+
factory = nil
|
138
|
+
possible_factory_names.each do |factory_name|
|
139
|
+
begin
|
140
|
+
factory = FactoryGirl.factory_by_name(factory_name)
|
141
|
+
break
|
142
|
+
rescue ArgumentError => e
|
143
|
+
raise e unless e.message =~ /Factory not registered/
|
144
|
+
next
|
145
|
+
end
|
146
|
+
end
|
147
|
+
factory
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,232 @@
|
|
1
|
+
# If you require "factory_girl_extensions", it automatically extends Object with these extensions.
|
2
|
+
#
|
3
|
+
# If you require "factory_girl_extensions/core", it doesn't automatically include extensions anywhere
|
4
|
+
# so you can choose which classes/objects you want to extend to get the gen/build/etc methods.
|
5
|
+
require "factory_girl_extensions/core"
|
6
|
+
|
7
|
+
# Required after factory_girl_extensions to ensure that factory_girl_extensions doesn't
|
8
|
+
# blow up if factory_girl hasn't been required yet.
|
9
|
+
require "factory_girl"
|
10
|
+
|
11
|
+
require "rspec"
|
12
|
+
|
13
|
+
# Example class
|
14
|
+
class Dog
|
15
|
+
extend FactoryGirl::Syntax::ObjectMethods
|
16
|
+
|
17
|
+
attr_accessor :name, :saved
|
18
|
+
|
19
|
+
def save
|
20
|
+
self.saved = true
|
21
|
+
end
|
22
|
+
|
23
|
+
def saved?
|
24
|
+
saved == true
|
25
|
+
end
|
26
|
+
|
27
|
+
def save!
|
28
|
+
raise "Called save!" unless name == "Valid Name"
|
29
|
+
self.saved = true
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Example factories
|
34
|
+
FactoryGirl.define do
|
35
|
+
factory :dog do
|
36
|
+
name "Rover"
|
37
|
+
end
|
38
|
+
|
39
|
+
factory :awesome_dog, :class => Dog do
|
40
|
+
name "Awesome Dog"
|
41
|
+
end
|
42
|
+
|
43
|
+
factory :dog_with_toys, :class => Dog do
|
44
|
+
name "Dog with toys"
|
45
|
+
end
|
46
|
+
|
47
|
+
factory :awesome_dog_with_toys, :class => Dog do
|
48
|
+
name "Awesome Dog with toys"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe Dog do
|
53
|
+
it "should act as expected" do
|
54
|
+
dog = Dog.new
|
55
|
+
dog.name.should be_nil
|
56
|
+
|
57
|
+
dog.name = "Rover"
|
58
|
+
dog.name.should == "Rover"
|
59
|
+
|
60
|
+
dog.saved?.should == false
|
61
|
+
dog.save
|
62
|
+
dog.saved?.should == true
|
63
|
+
|
64
|
+
dog.saved = false
|
65
|
+
expect { dog.save! }.to raise_error(RuntimeError, /Called save!/)
|
66
|
+
dog.saved?.should == false
|
67
|
+
|
68
|
+
dog.name = "Valid Name" # this let's you call save!
|
69
|
+
dog.save!
|
70
|
+
dog.saved?.should == true
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe FactoryGirl::Syntax::ObjectMethods do
|
75
|
+
|
76
|
+
it "raises useful Exception when no matching factory can be found" do
|
77
|
+
expect { Dog.build(:foo, :bar) }.to raise_error(ArgumentError, %{Could not find factory for "dog" with [:foo, :bar]})
|
78
|
+
expect { Dog.generate(:foo, :bar) }.to raise_error(ArgumentError, %{Could not find factory for "dog" with [:foo, :bar]})
|
79
|
+
expect { Dog.attributes(:foo, :bar) }.to raise_error(ArgumentError, %{Could not find factory for "dog" with [:foo, :bar]})
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "#build" do
|
83
|
+
after do
|
84
|
+
@dog.should_not be_saved if @dog
|
85
|
+
end
|
86
|
+
|
87
|
+
it "without arguments" do
|
88
|
+
@dog = Dog.build
|
89
|
+
@dog.name.should == "Rover"
|
90
|
+
end
|
91
|
+
|
92
|
+
it "with overrides" do
|
93
|
+
@dog = Dog.build(:name => "Spot")
|
94
|
+
@dog.name.should == "Spot"
|
95
|
+
end
|
96
|
+
|
97
|
+
it "yields the built instance to block" do
|
98
|
+
@dog = Dog.build(:name => "Spot"){|d| d.name += " Remover" }
|
99
|
+
@dog.name.should == "Spot Remover"
|
100
|
+
end
|
101
|
+
|
102
|
+
it "with prefix" do
|
103
|
+
@dog = Dog.build(:awesome)
|
104
|
+
@dog.name.should == "Awesome Dog"
|
105
|
+
end
|
106
|
+
|
107
|
+
it "with suffix" do
|
108
|
+
@dog = Dog.build(:with_toys)
|
109
|
+
@dog.name.should == "Dog with toys"
|
110
|
+
end
|
111
|
+
|
112
|
+
it "with prefix and suffix" do
|
113
|
+
@dog = Dog.build(:awesome, :with_toys)
|
114
|
+
@dog.name.should == "Awesome Dog with toys"
|
115
|
+
end
|
116
|
+
|
117
|
+
it "with prefix and suffix (reversed works too)" do
|
118
|
+
@dog = Dog.build(:with_toys, :awesome)
|
119
|
+
@dog.name.should == "Awesome Dog with toys"
|
120
|
+
end
|
121
|
+
|
122
|
+
it "cannot pass more than 2 prefix/suffix" do
|
123
|
+
expect { Dog.build(:one, :two, :three) }.to raise_error(ArgumentError, %{Don't know how to find factory for "dog" with [:one, :two, :three]})
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe "#generate" do
|
128
|
+
after do
|
129
|
+
@dog.should be_saved if @dog
|
130
|
+
end
|
131
|
+
|
132
|
+
it "can call #gen as a shortcut" do
|
133
|
+
@dog = Dog.gen
|
134
|
+
@dog.name.should == "Rover"
|
135
|
+
@dog.should be_saved
|
136
|
+
end
|
137
|
+
|
138
|
+
it "can call with a bang to save! (to raise an Exception on failure)" do
|
139
|
+
expect { Dog.generate! }.to raise_error(RuntimeError, /Called save!/)
|
140
|
+
expect { Dog.gen! }.to raise_error(RuntimeError, /Called save!/)
|
141
|
+
|
142
|
+
Dog.gen!(:name => "Valid Name").name.should == "Valid Name"
|
143
|
+
Dog.gen!(:name => "Valid Name"){|d| d.name += " FOO" }.name.should == "Valid Name FOO"
|
144
|
+
end
|
145
|
+
|
146
|
+
it "without arguments" do
|
147
|
+
@dog = Dog.generate
|
148
|
+
@dog.name.should == "Rover"
|
149
|
+
end
|
150
|
+
|
151
|
+
it "with overrides" do
|
152
|
+
@dog = Dog.generate(:name => "Spot")
|
153
|
+
@dog.name.should == "Spot"
|
154
|
+
end
|
155
|
+
|
156
|
+
it "yields the built instance to block (after calling #save on it)" do
|
157
|
+
@dog = Dog.generate(:name => "Spot") do |dog|
|
158
|
+
dog.should be_saved
|
159
|
+
dog.name += " Remover"
|
160
|
+
end
|
161
|
+
@dog.name.should == "Spot Remover"
|
162
|
+
end
|
163
|
+
|
164
|
+
it "generate! yields the resulting instance (after calling save! on it)" do
|
165
|
+
Dog.gen!(:name => "Valid Name") do |dog|
|
166
|
+
dog.should be_saved
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
it "with prefix" do
|
171
|
+
@dog = Dog.generate(:awesome)
|
172
|
+
@dog.name.should == "Awesome Dog"
|
173
|
+
end
|
174
|
+
|
175
|
+
it "with suffix" do
|
176
|
+
@dog = Dog.generate(:with_toys)
|
177
|
+
@dog.name.should == "Dog with toys"
|
178
|
+
end
|
179
|
+
|
180
|
+
it "with prefix and suffix" do
|
181
|
+
@dog = Dog.generate(:awesome, :with_toys)
|
182
|
+
@dog.name.should == "Awesome Dog with toys"
|
183
|
+
end
|
184
|
+
|
185
|
+
it "with prefix and suffix (reversed works too)" do
|
186
|
+
@dog = Dog.generate(:with_toys, :awesome)
|
187
|
+
@dog.name.should == "Awesome Dog with toys"
|
188
|
+
end
|
189
|
+
|
190
|
+
it "cannot pass more than 2 prefix/suffix" do
|
191
|
+
expect { Dog.generate(:one, :two, :three) }.to raise_error(ArgumentError, %{Don't know how to find factory for "dog" with [:one, :two, :three]})
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
describe "#attributes" do
|
196
|
+
it "without arguments" do
|
197
|
+
Dog.attributes.should == { :name => "Rover" }
|
198
|
+
end
|
199
|
+
|
200
|
+
it "can call #attrs as a shortcut" do
|
201
|
+
Dog.attrs.should == { :name => "Rover" }
|
202
|
+
end
|
203
|
+
|
204
|
+
it "with overrides" do
|
205
|
+
Dog.attributes(:name => "Spot").should == { :name => "Spot" }
|
206
|
+
end
|
207
|
+
|
208
|
+
it "yields the built instance to block" do
|
209
|
+
Dog.attributes(:name => "Spot"){|hash| hash[:name] += " Remover" }.should == { :name => "Spot Remover" }
|
210
|
+
end
|
211
|
+
|
212
|
+
it "with prefix" do
|
213
|
+
Dog.attributes(:awesome).should == { :name => "Awesome Dog" }
|
214
|
+
end
|
215
|
+
|
216
|
+
it "with suffix" do
|
217
|
+
Dog.attributes(:with_toys).should == { :name => "Dog with toys" }
|
218
|
+
end
|
219
|
+
|
220
|
+
it "with prefix and suffix" do
|
221
|
+
Dog.attributes(:awesome, :with_toys).should == { :name => "Awesome Dog with toys" }
|
222
|
+
end
|
223
|
+
|
224
|
+
it "with prefix and suffix (reversed works too)" do
|
225
|
+
Dog.attributes(:with_toys, :awesome).should == { :name => "Awesome Dog with toys" }
|
226
|
+
end
|
227
|
+
|
228
|
+
it "cannot pass more than 2 prefix/suffix" do
|
229
|
+
expect { Dog.attributes(:one, :two, :three) }.to raise_error(ArgumentError, %{Don't know how to find factory for "dog" with [:one, :two, :three]})
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
metadata
CHANGED
@@ -1,82 +1,89 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: factory_girl_extensions
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2.0.0
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 4
|
9
|
-
- 0
|
10
|
-
version: 0.4.0
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- remi
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2012-02-24 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
21
15
|
name: factory_girl
|
22
|
-
|
23
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: &19502360 !ruby/object:Gem::Requirement
|
24
17
|
none: false
|
25
|
-
requirements:
|
26
|
-
- -
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
|
29
|
-
segments:
|
30
|
-
- 0
|
31
|
-
- 0
|
32
|
-
- 0
|
33
|
-
version: 0.0.0
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '2.0'
|
34
22
|
type: :runtime
|
35
|
-
|
36
|
-
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *19502360
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rake
|
27
|
+
requirement: &19501200 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *19501200
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rspec
|
38
|
+
requirement: &19499300 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *19499300
|
47
|
+
description: ! "Alternative FactoryGirl API allowing you to build/generate factories
|
48
|
+
\nusing your class constants, eg. User.gen instead of Factory(:user).\n"
|
37
49
|
email: remi@remitaylor.com
|
38
50
|
executables: []
|
39
|
-
|
40
51
|
extensions: []
|
41
|
-
|
42
52
|
extra_rdoc_files: []
|
43
|
-
|
44
|
-
|
45
|
-
-
|
53
|
+
files:
|
54
|
+
- .gemtest
|
55
|
+
- .gitignore
|
56
|
+
- Gemfile
|
57
|
+
- README.markdown
|
58
|
+
- Rakefile
|
59
|
+
- factory_girl_extensions.gemspec
|
46
60
|
- lib/factory_girl_extensions.rb
|
61
|
+
- lib/factory_girl_extensions/core.rb
|
62
|
+
- lib/factory_girl_extensions/version.rb
|
63
|
+
- spec/factory_girl_extensions_spec.rb
|
47
64
|
homepage: http://github.com/remi/factory_girl_extensions
|
48
65
|
licenses: []
|
49
|
-
|
50
66
|
post_install_message:
|
51
67
|
rdoc_options: []
|
52
|
-
|
53
|
-
require_paths:
|
68
|
+
require_paths:
|
54
69
|
- lib
|
55
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
70
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
56
71
|
none: false
|
57
|
-
requirements:
|
58
|
-
- -
|
59
|
-
- !ruby/object:Gem::Version
|
60
|
-
|
61
|
-
|
62
|
-
- 0
|
63
|
-
version: "0"
|
64
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ! '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
65
77
|
none: false
|
66
|
-
requirements:
|
67
|
-
- -
|
68
|
-
- !ruby/object:Gem::Version
|
69
|
-
|
70
|
-
segments:
|
71
|
-
- 0
|
72
|
-
version: "0"
|
78
|
+
requirements:
|
79
|
+
- - ! '>='
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
73
82
|
requirements: []
|
74
|
-
|
75
83
|
rubyforge_project:
|
76
84
|
rubygems_version: 1.8.17
|
77
85
|
signing_key:
|
78
86
|
specification_version: 3
|
79
|
-
summary:
|
80
|
-
test_files:
|
81
|
-
|
82
|
-
has_rdoc:
|
87
|
+
summary: Alternative FactoryGirl API
|
88
|
+
test_files:
|
89
|
+
- spec/factory_girl_extensions_spec.rb
|
@@ -1,91 +0,0 @@
|
|
1
|
-
# Just the module. You should require this if you don't want FactoryGirlExtensions
|
2
|
-
# automatically included into Object.
|
3
|
-
|
4
|
-
# Adds helpful factory_girl methods to objects.
|
5
|
-
#
|
6
|
-
# This uses method_missing just incase the given Object
|
7
|
-
# already responds to one of these methods.
|
8
|
-
#
|
9
|
-
# == Usage
|
10
|
-
#
|
11
|
-
# User.generate! # this is equivalent to Factory(:user) or Factory.create(:user)
|
12
|
-
# User.gen! # this is a shortcut alias for #generate
|
13
|
-
# User.generate # this is equivalent to Factory.build(:user) and then #save
|
14
|
-
# User.gen # this is equivalent to Factory.build(:user) and then #save
|
15
|
-
# User.build # this is equivalent to Factory.build(:user)
|
16
|
-
# User.gen! :name => 'Bob' # this is equivalent to Factory(:user, :name => 'Bob')
|
17
|
-
# :email.next # this is equivalent to Factory.next(:email)
|
18
|
-
# 'email'.next # this will NOT work because String#next already exists
|
19
|
-
# :admin_user.gen! # this is equivalent to Factory.gen(:admin_user)
|
20
|
-
# 'admin_user'.gen! # this is equivalent to Factory.gen(:admin_user)
|
21
|
-
# User.attrs # this is equivalent to Factory.attributes_for(:user)
|
22
|
-
# 'user'.attrs # this is equivalent to Factory.attributes_for(:user)
|
23
|
-
# :user.attrs # this is equivalent to Factory.attributes_for(:user)
|
24
|
-
#
|
25
|
-
# == TODO
|
26
|
-
#
|
27
|
-
# * properly implement <tt>respond_to?</tt>
|
28
|
-
# * add syntax like User.gen_admin or User.gen(:admin) for generating an :admin_user
|
29
|
-
#
|
30
|
-
module FactoryGirlExtensions
|
31
|
-
|
32
|
-
# I was relying on String#underscore being available and it's not always.
|
33
|
-
# Copies this from ActiveSupport.
|
34
|
-
def underscore_string string
|
35
|
-
string.to_s.gsub(/::/, '/').
|
36
|
-
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
37
|
-
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
38
|
-
tr("-", "_").
|
39
|
-
downcase
|
40
|
-
end
|
41
|
-
|
42
|
-
# This is the actual (private) implementation
|
43
|
-
def self.__method_missing object, name, *args, &block
|
44
|
-
raise 'Factory is not defined. Have you required factory_girl?' unless defined? Factory
|
45
|
-
|
46
|
-
messages = case name.to_s
|
47
|
-
when /^gen(erate)?\!$/
|
48
|
-
[:build, :save!]
|
49
|
-
when /^gen(erate)?$/
|
50
|
-
[:build, :save]
|
51
|
-
when 'build'
|
52
|
-
[:build]
|
53
|
-
when 'next'
|
54
|
-
[:next]
|
55
|
-
when /^attr(ibute)?s(_for)?$/
|
56
|
-
[:attributes_for]
|
57
|
-
end
|
58
|
-
|
59
|
-
if messages
|
60
|
-
# if this is an instance of String/Symbol use this instance as the factory name, else use the class name
|
61
|
-
factory_name = ( object.kind_of?(Symbol) || object.kind_of?(String) ) ? object.to_s.to_sym : underscore_string(object.name).to_sym
|
62
|
-
|
63
|
-
factory_method, instance_method = messages
|
64
|
-
instance = Factory.send factory_method, factory_name, *args
|
65
|
-
|
66
|
-
if instance_method
|
67
|
-
instance.send instance_method if instance.respond_to? instance_method
|
68
|
-
end
|
69
|
-
|
70
|
-
instance
|
71
|
-
|
72
|
-
else
|
73
|
-
:no_extension_found
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
# This is the public implementation. When you include
|
78
|
-
# FactoryGirlExtensions into a class, this is what gives
|
79
|
-
# you the #gen and other methods.
|
80
|
-
def method_missing name, *args, &block
|
81
|
-
object = FactoryGirlExtensions.__method_missing(self, name, *args, &block)
|
82
|
-
|
83
|
-
# If no extensions were found, call super
|
84
|
-
if object == :no_extension_found
|
85
|
-
super
|
86
|
-
else
|
87
|
-
object
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
end
|