factory_girl_kibiz0r 2.0.0.beta2
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/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
|