factory_girl_kibiz0r 2.0.0.beta2
Sign up to get free protection for your applications and to get access to all the features.
- data/Appraisals +12 -0
- data/CONTRIBUTION_GUIDELINES.md +9 -0
- data/Changelog +29 -0
- data/GETTING_STARTED.md +246 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +62 -0
- data/LICENSE +19 -0
- data/README.md +64 -0
- data/Rakefile +54 -0
- data/features/factory_girl_steps.feature +151 -0
- data/features/step_definitions/database_steps.rb +20 -0
- data/features/support/env.rb +6 -0
- data/features/support/factories.rb +84 -0
- data/lib/factory_girl/aliases.rb +21 -0
- data/lib/factory_girl/attribute/association.rb +24 -0
- data/lib/factory_girl/attribute/callback.rb +16 -0
- data/lib/factory_girl/attribute/dynamic.rb +21 -0
- data/lib/factory_girl/attribute/implicit.rb +36 -0
- data/lib/factory_girl/attribute/list.rb +19 -0
- data/lib/factory_girl/attribute/sequence.rb +16 -0
- data/lib/factory_girl/attribute/static.rb +18 -0
- data/lib/factory_girl/attribute.rb +42 -0
- data/lib/factory_girl/definition_proxy.rb +147 -0
- data/lib/factory_girl/deprecated.rb +18 -0
- data/lib/factory_girl/factory.rb +196 -0
- data/lib/factory_girl/find_definitions.rb +23 -0
- data/lib/factory_girl/proxy/attributes_for.rb +21 -0
- data/lib/factory_girl/proxy/build.rb +36 -0
- data/lib/factory_girl/proxy/create.rb +16 -0
- data/lib/factory_girl/proxy/stub.rb +64 -0
- data/lib/factory_girl/proxy.rb +87 -0
- data/lib/factory_girl/rails2.rb +1 -0
- data/lib/factory_girl/registry.rb +45 -0
- data/lib/factory_girl/sequence.rb +31 -0
- data/lib/factory_girl/step_definitions.rb +60 -0
- data/lib/factory_girl/syntax/blueprint.rb +42 -0
- data/lib/factory_girl/syntax/default.rb +33 -0
- data/lib/factory_girl/syntax/generate.rb +73 -0
- data/lib/factory_girl/syntax/make.rb +41 -0
- data/lib/factory_girl/syntax/methods.rb +86 -0
- data/lib/factory_girl/syntax/sham.rb +45 -0
- data/lib/factory_girl/syntax/vintage.rb +152 -0
- data/lib/factory_girl/syntax.rb +12 -0
- data/lib/factory_girl/version.rb +4 -0
- data/lib/factory_girl.rb +54 -0
- data/spec/acceptance/acceptance_helper.rb +11 -0
- data/spec/acceptance/attribute_aliases_spec.rb +26 -0
- data/spec/acceptance/attributes_for_spec.rb +48 -0
- data/spec/acceptance/build_spec.rb +35 -0
- data/spec/acceptance/build_stubbed_spec.rb +79 -0
- data/spec/acceptance/callbacks_spec.rb +53 -0
- data/spec/acceptance/create_spec.rb +67 -0
- data/spec/acceptance/default_strategy_spec.rb +27 -0
- data/spec/acceptance/definition_spec.rb +28 -0
- data/spec/acceptance/parent_spec.rb +39 -0
- data/spec/acceptance/sequence_spec.rb +34 -0
- data/spec/acceptance/syntax/blueprint_spec.rb +32 -0
- data/spec/acceptance/syntax/generate_spec.rb +60 -0
- data/spec/acceptance/syntax/make_spec.rb +35 -0
- data/spec/acceptance/syntax/sham_spec.rb +44 -0
- data/spec/acceptance/syntax/vintage_spec.rb +224 -0
- data/spec/factory_girl/aliases_spec.rb +33 -0
- data/spec/factory_girl/attribute/association_spec.rb +33 -0
- data/spec/factory_girl/attribute/callback_spec.rb +23 -0
- data/spec/factory_girl/attribute/dynamic_spec.rb +60 -0
- data/spec/factory_girl/attribute/implicit_spec.rb +50 -0
- data/spec/factory_girl/attribute/sequence_spec.rb +21 -0
- data/spec/factory_girl/attribute/static_spec.rb +29 -0
- data/spec/factory_girl/attribute_spec.rb +39 -0
- data/spec/factory_girl/definition_proxy_spec.rb +129 -0
- data/spec/factory_girl/deprecated_spec.rb +66 -0
- data/spec/factory_girl/factory_spec.rb +374 -0
- data/spec/factory_girl/find_definitions_spec.rb +100 -0
- data/spec/factory_girl/proxy/attributes_for_spec.rb +52 -0
- data/spec/factory_girl/proxy/build_spec.rb +86 -0
- data/spec/factory_girl/proxy/create_spec.rb +107 -0
- data/spec/factory_girl/proxy/stub_spec.rb +80 -0
- data/spec/factory_girl/proxy_spec.rb +102 -0
- data/spec/factory_girl/registry_spec.rb +83 -0
- data/spec/factory_girl/sequence_spec.rb +96 -0
- data/spec/factory_girl_spec.rb +17 -0
- data/spec/spec_helper.rb +93 -0
- 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
|