factory_girl 2.1.0 → 2.1.2
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/.travis.yml +3 -0
- data/Changelog +9 -0
- data/GETTING_STARTED.md +47 -16
- data/Gemfile.lock +10 -9
- data/gemfiles/2.1.gemfile.lock +2 -1
- data/gemfiles/2.3.gemfile.lock +2 -1
- data/gemfiles/3.0.gemfile.lock +2 -1
- data/gemfiles/3.1.gemfile.lock +2 -1
- data/lib/factory_girl.rb +6 -3
- data/lib/factory_girl/attribute/static.rb +8 -0
- data/lib/factory_girl/attribute_list.rb +20 -12
- data/lib/factory_girl/callback.rb +30 -0
- data/lib/factory_girl/declaration.rb +19 -0
- data/lib/factory_girl/declaration/association.rb +17 -0
- data/lib/factory_girl/declaration/dynamic.rb +16 -0
- data/lib/factory_girl/declaration/implicit.rb +23 -0
- data/lib/factory_girl/declaration/static.rb +16 -0
- data/lib/factory_girl/definition_proxy.rb +6 -6
- data/lib/factory_girl/factory.rb +63 -79
- data/lib/factory_girl/proxy.rb +7 -11
- data/lib/factory_girl/proxy/attributes_for.rb +1 -0
- data/lib/factory_girl/proxy/build.rb +1 -0
- data/lib/factory_girl/proxy/stub.rb +1 -0
- data/lib/factory_girl/syntax/default.rb +4 -2
- data/lib/factory_girl/syntax/vintage.rb +1 -1
- data/lib/factory_girl/trait.rb +12 -4
- data/lib/factory_girl/version.rb +1 -1
- data/spec/acceptance/callbacks_spec.rb +7 -1
- data/spec/acceptance/modify_inherited_spec.rb +52 -0
- data/spec/acceptance/syntax/vintage_spec.rb +19 -7
- data/spec/factory_girl/attribute_list_spec.rb +18 -45
- data/spec/factory_girl/callback_spec.rb +41 -0
- data/spec/factory_girl/{attribute → declaration}/implicit_spec.rb +16 -11
- data/spec/factory_girl/definition_proxy_spec.rb +16 -12
- data/spec/factory_girl/factory_spec.rb +43 -34
- data/spec/factory_girl/proxy/create_spec.rb +7 -9
- data/spec/factory_girl/proxy_spec.rb +26 -39
- data/spec/support/shared_examples/proxy.rb +1 -1
- metadata +137 -114
- data/lib/factory_girl/attribute/callback.rb +0 -14
- data/lib/factory_girl/attribute/implicit.rb +0 -39
- data/lib/factory_girl/attribute/trait.rb +0 -22
- data/spec/factory_girl/attribute/callback_spec.rb +0 -22
@@ -0,0 +1,23 @@
|
|
1
|
+
module FactoryGirl
|
2
|
+
class Declaration
|
3
|
+
class Implicit < Declaration
|
4
|
+
def initialize(name, factory = nil)
|
5
|
+
super(name)
|
6
|
+
@factory = factory
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def build
|
12
|
+
if FactoryGirl.factories.registered?(name)
|
13
|
+
[Attribute::Association.new(name, name, {})]
|
14
|
+
elsif FactoryGirl.sequences.registered?(name)
|
15
|
+
[Attribute::Sequence.new(name, name)]
|
16
|
+
else
|
17
|
+
trait_root = @factory || FactoryGirl
|
18
|
+
trait_root.trait_by_name(name).attributes.to_a
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -36,13 +36,14 @@ module FactoryGirl
|
|
36
36
|
if value
|
37
37
|
raise AttributeDefinitionError, "Both value and block given"
|
38
38
|
else
|
39
|
-
|
39
|
+
declaration = Declaration::Dynamic.new(name, block)
|
40
40
|
end
|
41
41
|
else
|
42
|
-
|
42
|
+
declaration = FactoryGirl::Declaration::Static.new(name, value)
|
43
43
|
end
|
44
44
|
|
45
|
-
@factory.
|
45
|
+
@factory.declare_attribute(declaration)
|
46
|
+
declaration
|
46
47
|
end
|
47
48
|
|
48
49
|
# Calls add_attribute using the missing method name as the name of the
|
@@ -78,7 +79,7 @@ module FactoryGirl
|
|
78
79
|
# are equivalent.
|
79
80
|
def method_missing(name, *args, &block)
|
80
81
|
if args.empty? && block.nil?
|
81
|
-
@factory.
|
82
|
+
@factory.declare_attribute(Declaration::Implicit.new(name, @factory))
|
82
83
|
elsif args.first.is_a?(Hash) && args.first.has_key?(:factory)
|
83
84
|
association(name, *args)
|
84
85
|
else
|
@@ -131,8 +132,7 @@ module FactoryGirl
|
|
131
132
|
# name of the factory. For example, a "user" association will by
|
132
133
|
# default use the "user" factory.
|
133
134
|
def association(name, options = {})
|
134
|
-
|
135
|
-
@factory.define_attribute(Attribute::Association.new(name, factory_name, options))
|
135
|
+
@factory.declare_attribute(Declaration::Association.new(name, options))
|
136
136
|
end
|
137
137
|
|
138
138
|
def after_build(&block)
|
data/lib/factory_girl/factory.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
require "active_support/core_ext/hash/keys"
|
2
|
+
require "active_support/inflector"
|
3
|
+
|
1
4
|
module FactoryGirl
|
2
5
|
# Raised when a factory is defined that attempts to instantiate itself.
|
3
6
|
class AssociationDefinitionError < RuntimeError
|
@@ -13,7 +16,6 @@ module FactoryGirl
|
|
13
16
|
|
14
17
|
class Factory
|
15
18
|
attr_reader :name #:nodoc:
|
16
|
-
attr_reader :traits #:nodoc:
|
17
19
|
|
18
20
|
def factory_name
|
19
21
|
puts "WARNING: factory.factory_name is deprecated. Use factory.name instead."
|
@@ -25,7 +27,7 @@ module FactoryGirl
|
|
25
27
|
end
|
26
28
|
|
27
29
|
def build_class #:nodoc:
|
28
|
-
@build_class ||=
|
30
|
+
@build_class ||= class_name.to_s.camelize.constantize
|
29
31
|
end
|
30
32
|
|
31
33
|
def default_strategy #:nodoc:
|
@@ -34,18 +36,19 @@ module FactoryGirl
|
|
34
36
|
|
35
37
|
def initialize(name, options = {}) #:nodoc:
|
36
38
|
assert_valid_options(options)
|
37
|
-
@name
|
38
|
-
@parent
|
39
|
-
@
|
40
|
-
@
|
41
|
-
@
|
42
|
-
@
|
43
|
-
@
|
39
|
+
@name = name.to_s.underscore.to_sym
|
40
|
+
@parent = options[:parent]
|
41
|
+
@parent_factory = nil
|
42
|
+
@options = options
|
43
|
+
@defined_traits = []
|
44
|
+
@traits = []
|
45
|
+
@children = []
|
46
|
+
@attribute_list = AttributeList.new
|
47
|
+
@compiled = false
|
44
48
|
end
|
45
49
|
|
46
50
|
def allow_overrides
|
47
51
|
@attribute_list.overridable
|
48
|
-
@inherited_attribute_list.overridable
|
49
52
|
self
|
50
53
|
end
|
51
54
|
|
@@ -53,56 +56,48 @@ module FactoryGirl
|
|
53
56
|
@attribute_list.overridable?
|
54
57
|
end
|
55
58
|
|
56
|
-
def
|
59
|
+
def inherit_factory(parent) #:nodoc:
|
57
60
|
@options[:class] ||= parent.class_name
|
58
61
|
@options[:default_strategy] ||= parent.default_strategy
|
59
62
|
|
60
63
|
allow_overrides if parent.allow_overrides?
|
61
64
|
parent.add_child(self)
|
62
65
|
|
63
|
-
@
|
66
|
+
@parent_factory = parent
|
64
67
|
end
|
65
68
|
|
66
69
|
def add_child(factory)
|
67
70
|
@children << factory unless @children.include?(factory)
|
68
71
|
end
|
69
72
|
|
70
|
-
def
|
71
|
-
traits
|
72
|
-
apply_attributes(trait.attributes)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
def apply_attributes(attributes_to_apply)
|
77
|
-
@attribute_list.apply_attributes(attributes_to_apply)
|
78
|
-
end
|
79
|
-
|
80
|
-
def define_attribute(attribute)
|
81
|
-
if attribute.respond_to?(:factory) && attribute.factory == self.name
|
82
|
-
raise AssociationDefinitionError, "Self-referencing association '#{attribute.name}' in factory '#{self.name}'"
|
83
|
-
end
|
84
|
-
|
85
|
-
@attribute_list.define_attribute(attribute).tap { update_children }
|
73
|
+
def inherit_traits(traits)
|
74
|
+
@traits = traits
|
86
75
|
end
|
87
76
|
|
88
77
|
def define_trait(trait)
|
89
|
-
@
|
78
|
+
@defined_traits << trait
|
90
79
|
end
|
91
80
|
|
92
81
|
def add_callback(name, &block)
|
93
|
-
@attribute_list.add_callback(name,
|
82
|
+
@attribute_list.add_callback(Callback.new(name, block))
|
94
83
|
end
|
95
84
|
|
96
85
|
def attributes
|
86
|
+
ensure_compiled
|
97
87
|
AttributeList.new.tap do |list|
|
88
|
+
@traits.reverse.map { |name| trait_by_name(name) }.each do |trait|
|
89
|
+
list.apply_attributes(trait.attributes)
|
90
|
+
end
|
91
|
+
|
98
92
|
list.apply_attributes(@attribute_list)
|
99
|
-
list.apply_attributes(@
|
100
|
-
end
|
93
|
+
list.apply_attributes(@parent_factory.attributes) if @parent_factory
|
94
|
+
end
|
101
95
|
end
|
102
96
|
|
103
97
|
def run(proxy_class, overrides) #:nodoc:
|
104
98
|
proxy = proxy_class.new(build_class)
|
105
|
-
|
99
|
+
callbacks.each { |callback| proxy.add_callback(callback) }
|
100
|
+
overrides = overrides.symbolize_keys
|
106
101
|
|
107
102
|
attributes.each do |attribute|
|
108
103
|
factory_overrides = overrides.select { |attr, val| attribute.aliases_for?(attr) }
|
@@ -117,7 +112,7 @@ module FactoryGirl
|
|
117
112
|
end
|
118
113
|
|
119
114
|
def human_names
|
120
|
-
names.map {|name| name.to_s.
|
115
|
+
names.map {|name| name.to_s.humanize.downcase }
|
121
116
|
end
|
122
117
|
|
123
118
|
def associations
|
@@ -167,36 +162,45 @@ module FactoryGirl
|
|
167
162
|
@to_create_block = block
|
168
163
|
end
|
169
164
|
|
170
|
-
|
171
|
-
|
172
|
-
def update_children
|
173
|
-
@children.each { |child| child.inherit_from(self) }
|
165
|
+
def callbacks
|
166
|
+
attributes.callbacks
|
174
167
|
end
|
175
168
|
|
176
|
-
def
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
object.const_get(string)
|
169
|
+
def compile
|
170
|
+
declarations.each do |declaration|
|
171
|
+
declaration.to_attributes.each do |attribute|
|
172
|
+
define_attribute(attribute)
|
181
173
|
end
|
182
|
-
else
|
183
|
-
class_or_to_s
|
184
174
|
end
|
175
|
+
@compiled = true
|
185
176
|
end
|
186
177
|
|
187
|
-
def
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
178
|
+
def declare_attribute(declaration)
|
179
|
+
@attribute_list.declare_attribute(declaration)
|
180
|
+
end
|
181
|
+
|
182
|
+
private
|
183
|
+
|
184
|
+
def declarations
|
185
|
+
@attribute_list.declarations
|
186
|
+
end
|
187
|
+
|
188
|
+
def update_children
|
189
|
+
@children.each { |child| child.inherit_factory(self) }
|
190
|
+
end
|
191
|
+
|
192
|
+
def define_attribute(attribute)
|
193
|
+
if attribute.respond_to?(:factory) && attribute.factory == self.name
|
194
|
+
raise AssociationDefinitionError, "Self-referencing association '#{attribute.name}' in factory '#{self.name}'"
|
192
195
|
end
|
196
|
+
|
197
|
+
@attribute_list.define_attribute(attribute)
|
198
|
+
update_children if allow_overrides?
|
193
199
|
end
|
194
200
|
|
195
201
|
def assert_valid_options(options)
|
196
|
-
|
197
|
-
|
198
|
-
raise ArgumentError, "Unknown arguments: #{invalid_keys.inspect}"
|
199
|
-
end
|
202
|
+
options.assert_valid_keys(:class, :parent, :default_strategy, :aliases, :traits)
|
203
|
+
|
200
204
|
if options[:default_strategy]
|
201
205
|
assert_valid_strategy(options[:default_strategy])
|
202
206
|
puts "WARNING: default_strategy is deprecated."
|
@@ -205,37 +209,17 @@ module FactoryGirl
|
|
205
209
|
end
|
206
210
|
|
207
211
|
def assert_valid_strategy(strategy)
|
208
|
-
unless Proxy.const_defined?
|
212
|
+
unless Proxy.const_defined? strategy.to_s.camelize
|
209
213
|
raise ArgumentError, "Unknown strategy: #{strategy}"
|
210
214
|
end
|
211
215
|
end
|
212
216
|
|
213
|
-
|
214
|
-
|
215
|
-
name.to_s.gsub(/::/, '/').
|
216
|
-
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
217
|
-
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
218
|
-
tr("-", "_").
|
219
|
-
downcase
|
220
|
-
end
|
221
|
-
|
222
|
-
# Based on ActiveSupport's camelize inflector
|
223
|
-
def variable_name_to_class_name(name)
|
224
|
-
name.to_s.
|
225
|
-
gsub(/\/(.?)/) { "::#{$1.upcase}" }.
|
226
|
-
gsub(/(?:^|_)(.)/) { $1.upcase }
|
227
|
-
end
|
228
|
-
|
229
|
-
# From ActiveSupport
|
230
|
-
def symbolize_keys(hash)
|
231
|
-
hash.inject({}) do |options, (key, value)|
|
232
|
-
options[(key.to_sym rescue key) || key] = value
|
233
|
-
options
|
234
|
-
end
|
217
|
+
def trait_for(name)
|
218
|
+
@defined_traits.detect {|trait| trait.name == name }
|
235
219
|
end
|
236
220
|
|
237
|
-
def
|
238
|
-
|
221
|
+
def ensure_compiled
|
222
|
+
compile unless @compiled
|
239
223
|
end
|
240
224
|
end
|
241
225
|
end
|
data/lib/factory_girl/proxy.rb
CHANGED
@@ -4,6 +4,7 @@ module FactoryGirl
|
|
4
4
|
attr_reader :callbacks
|
5
5
|
|
6
6
|
def initialize(klass)
|
7
|
+
@callbacks = {}
|
7
8
|
end
|
8
9
|
|
9
10
|
def get(attribute)
|
@@ -15,20 +16,15 @@ module FactoryGirl
|
|
15
16
|
def associate(name, factory, attributes)
|
16
17
|
end
|
17
18
|
|
18
|
-
def add_callback(
|
19
|
-
@callbacks ||=
|
20
|
-
@callbacks[name]
|
21
|
-
@callbacks[name] << block
|
19
|
+
def add_callback(callback)
|
20
|
+
@callbacks[callback.name] ||= []
|
21
|
+
@callbacks[callback.name] << callback
|
22
22
|
end
|
23
23
|
|
24
24
|
def run_callbacks(name)
|
25
|
-
if @callbacks
|
26
|
-
@callbacks[name].each do |
|
27
|
-
|
28
|
-
when 0 then block.call
|
29
|
-
when 2 then block.call(@instance, self)
|
30
|
-
else block.call(@instance)
|
31
|
-
end
|
25
|
+
if @callbacks[name]
|
26
|
+
@callbacks[name].each do |callback|
|
27
|
+
callback.run(@instance, self)
|
32
28
|
end
|
33
29
|
end
|
34
30
|
end
|
@@ -22,12 +22,13 @@ module FactoryGirl
|
|
22
22
|
proxy.instance_eval(&block) if block_given?
|
23
23
|
|
24
24
|
if traits = options.delete(:traits)
|
25
|
-
factory.
|
25
|
+
factory.inherit_traits(traits)
|
26
26
|
end
|
27
27
|
|
28
28
|
if parent = options.delete(:parent)
|
29
|
-
factory.
|
29
|
+
factory.inherit_factory(FactoryGirl.factory_by_name(parent))
|
30
30
|
end
|
31
|
+
|
31
32
|
FactoryGirl.register_factory(factory)
|
32
33
|
|
33
34
|
proxy.child_factories.each do |(child_name, child_options, child_block)|
|
@@ -53,6 +54,7 @@ module FactoryGirl
|
|
53
54
|
factory = FactoryGirl.factory_by_name(name).allow_overrides
|
54
55
|
proxy = FactoryGirl::DefinitionProxy.new(factory)
|
55
56
|
proxy.instance_eval(&block)
|
57
|
+
factory.compile
|
56
58
|
end
|
57
59
|
end
|
58
60
|
end
|
@@ -29,7 +29,7 @@ module FactoryGirl
|
|
29
29
|
proxy = FactoryGirl::DefinitionProxy.new(factory)
|
30
30
|
yield(proxy)
|
31
31
|
if parent = options.delete(:parent)
|
32
|
-
factory.
|
32
|
+
factory.inherit_factory(FactoryGirl.factory_by_name(parent))
|
33
33
|
end
|
34
34
|
FactoryGirl.register_factory(factory)
|
35
35
|
end
|
data/lib/factory_girl/trait.rb
CHANGED
@@ -10,16 +10,24 @@ module FactoryGirl
|
|
10
10
|
proxy.instance_eval(&block) if block_given?
|
11
11
|
end
|
12
12
|
|
13
|
-
def
|
14
|
-
@attribute_list.
|
13
|
+
def declare_attribute(declaration)
|
14
|
+
@attribute_list.declare_attribute(declaration)
|
15
|
+
declaration
|
15
16
|
end
|
16
17
|
|
17
18
|
def add_callback(name, &block)
|
18
|
-
@attribute_list.add_callback(name,
|
19
|
+
@attribute_list.add_callback(Callback.new(name, block))
|
19
20
|
end
|
20
21
|
|
21
22
|
def attributes
|
22
|
-
|
23
|
+
AttributeList.new.tap do |list|
|
24
|
+
@attribute_list.declarations.each do |declaration|
|
25
|
+
declaration.to_attributes.each do |attribute|
|
26
|
+
list.define_attribute(attribute)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
list.apply_attributes @attribute_list
|
30
|
+
end
|
23
31
|
end
|
24
32
|
|
25
33
|
def names
|
data/lib/factory_girl/version.rb
CHANGED