factory_bot 1.0.0.alpha
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.
- checksums.yaml +7 -0
- data/.autotest +9 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.simplecov +4 -0
- data/.travis.yml +41 -0
- data/.yardopts +5 -0
- data/Appraisals +19 -0
- data/CONTRIBUTING.md +60 -0
- data/GETTING_STARTED.md +1387 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +123 -0
- data/LICENSE +19 -0
- data/NAME.md +11 -0
- data/NEWS +285 -0
- data/README.md +102 -0
- data/Rakefile +36 -0
- data/cucumber.yml +1 -0
- data/factory_bot.gemspec +38 -0
- data/factory_girl.gemspec +41 -0
- data/gemfiles/3.2.gemfile +10 -0
- data/gemfiles/3.2.gemfile.lock +112 -0
- data/gemfiles/4.0.gemfile +10 -0
- data/gemfiles/4.0.gemfile.lock +112 -0
- data/gemfiles/4.1.gemfile +10 -0
- data/gemfiles/4.1.gemfile.lock +111 -0
- data/gemfiles/4.2.gemfile +10 -0
- data/gemfiles/4.2.gemfile.lock +111 -0
- data/gemfiles/5.0.gemfile +10 -0
- data/gemfiles/5.0.gemfile.lock +110 -0
- data/lib/factory_bot.rb +154 -0
- data/lib/factory_bot/aliases.rb +18 -0
- data/lib/factory_bot/attribute.rb +62 -0
- data/lib/factory_bot/attribute/association.rb +27 -0
- data/lib/factory_bot/attribute/dynamic.rb +24 -0
- data/lib/factory_bot/attribute/sequence.rb +16 -0
- data/lib/factory_bot/attribute/static.rb +16 -0
- data/lib/factory_bot/attribute_assigner.rb +97 -0
- data/lib/factory_bot/attribute_list.rb +67 -0
- data/lib/factory_bot/callback.rb +40 -0
- data/lib/factory_bot/callbacks_observer.rb +21 -0
- data/lib/factory_bot/configuration.rb +37 -0
- data/lib/factory_bot/declaration.rb +23 -0
- data/lib/factory_bot/declaration/association.rb +28 -0
- data/lib/factory_bot/declaration/dynamic.rb +26 -0
- data/lib/factory_bot/declaration/implicit.rb +33 -0
- data/lib/factory_bot/declaration/static.rb +26 -0
- data/lib/factory_bot/declaration_list.rb +49 -0
- data/lib/factory_bot/decorator.rb +21 -0
- data/lib/factory_bot/decorator/attribute_hash.rb +16 -0
- data/lib/factory_bot/decorator/class_key_hash.rb +28 -0
- data/lib/factory_bot/decorator/disallows_duplicates_registry.rb +13 -0
- data/lib/factory_bot/decorator/invocation_tracker.rb +19 -0
- data/lib/factory_bot/decorator/new_constructor.rb +12 -0
- data/lib/factory_bot/definition.rb +136 -0
- data/lib/factory_bot/definition_hierarchy.rb +48 -0
- data/lib/factory_bot/definition_proxy.rb +174 -0
- data/lib/factory_bot/errors.rb +25 -0
- data/lib/factory_bot/evaluation.rb +23 -0
- data/lib/factory_bot/evaluator.rb +82 -0
- data/lib/factory_bot/evaluator_class_definer.rb +20 -0
- data/lib/factory_bot/factory.rb +162 -0
- data/lib/factory_bot/factory_runner.rb +33 -0
- data/lib/factory_bot/find_definitions.rb +25 -0
- data/lib/factory_bot/linter.rb +97 -0
- data/lib/factory_bot/null_factory.rb +18 -0
- data/lib/factory_bot/null_object.rb +24 -0
- data/lib/factory_bot/registry.rb +38 -0
- data/lib/factory_bot/reload.rb +8 -0
- data/lib/factory_bot/sequence.rb +62 -0
- data/lib/factory_bot/strategy/attributes_for.rb +13 -0
- data/lib/factory_bot/strategy/build.rb +15 -0
- data/lib/factory_bot/strategy/create.rb +18 -0
- data/lib/factory_bot/strategy/null.rb +11 -0
- data/lib/factory_bot/strategy/stub.rb +108 -0
- data/lib/factory_bot/strategy_calculator.rb +26 -0
- data/lib/factory_bot/strategy_syntax_method_registrar.rb +54 -0
- data/lib/factory_bot/syntax.rb +7 -0
- data/lib/factory_bot/syntax/default.rb +76 -0
- data/lib/factory_bot/syntax/methods.rb +111 -0
- data/lib/factory_bot/syntax_runner.rb +6 -0
- data/lib/factory_bot/trait.rb +30 -0
- data/lib/factory_bot/version.rb +3 -0
- data/lib/factory_girl.rb +5 -0
- data/lib/factory_girl/version.rb +1 -0
- metadata +302 -0
@@ -0,0 +1,28 @@
|
|
1
|
+
module FactoryBot
|
2
|
+
class Declaration
|
3
|
+
# @api private
|
4
|
+
class Association < Declaration
|
5
|
+
def initialize(name, *options)
|
6
|
+
super(name, false)
|
7
|
+
@options = options.dup
|
8
|
+
@overrides = options.extract_options!
|
9
|
+
@traits = options
|
10
|
+
end
|
11
|
+
|
12
|
+
def ==(other)
|
13
|
+
name == other.name &&
|
14
|
+
options == other.options
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
attr_reader :options
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def build
|
23
|
+
factory_name = @overrides[:factory] || name
|
24
|
+
[Attribute::Association.new(name, factory_name, [@traits, @overrides.except(:factory)].flatten)]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module FactoryBot
|
2
|
+
class Declaration
|
3
|
+
# @api private
|
4
|
+
class Dynamic < Declaration
|
5
|
+
def initialize(name, ignored = false, block = nil)
|
6
|
+
super(name, ignored)
|
7
|
+
@block = block
|
8
|
+
end
|
9
|
+
|
10
|
+
def ==(other)
|
11
|
+
name == other.name &&
|
12
|
+
ignored == other.ignored &&
|
13
|
+
block == other.block
|
14
|
+
end
|
15
|
+
|
16
|
+
protected
|
17
|
+
attr_reader :block
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def build
|
22
|
+
[Attribute::Dynamic.new(name, @ignored, @block)]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module FactoryBot
|
2
|
+
class Declaration
|
3
|
+
# @api private
|
4
|
+
class Implicit < Declaration
|
5
|
+
def initialize(name, factory = nil, ignored = false)
|
6
|
+
super(name, ignored)
|
7
|
+
@factory = factory
|
8
|
+
end
|
9
|
+
|
10
|
+
def ==(other)
|
11
|
+
name == other.name &&
|
12
|
+
factory == other.factory &&
|
13
|
+
ignored == other.ignored
|
14
|
+
end
|
15
|
+
|
16
|
+
protected
|
17
|
+
attr_reader :factory
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def build
|
22
|
+
if FactoryBot.factories.registered?(name)
|
23
|
+
[Attribute::Association.new(name, name, {})]
|
24
|
+
elsif FactoryBot.sequences.registered?(name)
|
25
|
+
[Attribute::Sequence.new(name, name, @ignored)]
|
26
|
+
else
|
27
|
+
@factory.inherit_traits([name])
|
28
|
+
[]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module FactoryBot
|
2
|
+
class Declaration
|
3
|
+
# @api private
|
4
|
+
class Static < Declaration
|
5
|
+
def initialize(name, value, ignored = false)
|
6
|
+
super(name, ignored)
|
7
|
+
@value = value
|
8
|
+
end
|
9
|
+
|
10
|
+
def ==(other)
|
11
|
+
name == other.name &&
|
12
|
+
value == other.value &&
|
13
|
+
ignored == other.ignored
|
14
|
+
end
|
15
|
+
|
16
|
+
protected
|
17
|
+
attr_reader :value
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def build
|
22
|
+
[Attribute::Static.new(name, @value, @ignored)]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module FactoryBot
|
2
|
+
# @api private
|
3
|
+
class DeclarationList
|
4
|
+
include Enumerable
|
5
|
+
|
6
|
+
def initialize(name = nil)
|
7
|
+
@declarations = []
|
8
|
+
@name = name
|
9
|
+
@overridable = false
|
10
|
+
end
|
11
|
+
|
12
|
+
def declare_attribute(declaration)
|
13
|
+
delete_declaration(declaration) if overridable?
|
14
|
+
|
15
|
+
@declarations << declaration
|
16
|
+
declaration
|
17
|
+
end
|
18
|
+
|
19
|
+
def overridable
|
20
|
+
@overridable = true
|
21
|
+
end
|
22
|
+
|
23
|
+
def attributes
|
24
|
+
@attributes ||= AttributeList.new(@name).tap do |list|
|
25
|
+
to_attributes.each do |attribute|
|
26
|
+
list.define_attribute(attribute)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def each(&block)
|
32
|
+
@declarations.each(&block)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def delete_declaration(declaration)
|
38
|
+
@declarations.delete_if { |decl| decl.name == declaration.name }
|
39
|
+
end
|
40
|
+
|
41
|
+
def to_attributes
|
42
|
+
@declarations.inject([]) { |result, declaration| result += declaration.to_attributes }
|
43
|
+
end
|
44
|
+
|
45
|
+
def overridable?
|
46
|
+
@overridable
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module FactoryBot
|
2
|
+
class Decorator < BasicObject
|
3
|
+
undef_method :==
|
4
|
+
|
5
|
+
def initialize(component)
|
6
|
+
@component = component
|
7
|
+
end
|
8
|
+
|
9
|
+
def method_missing(name, *args, &block)
|
10
|
+
@component.send(name, *args, &block)
|
11
|
+
end
|
12
|
+
|
13
|
+
def send(symbol, *args, &block)
|
14
|
+
__send__(symbol, *args, &block)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.const_missing(name)
|
18
|
+
::Object.const_get(name)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module FactoryBot
|
2
|
+
class Decorator
|
3
|
+
class AttributeHash < Decorator
|
4
|
+
def initialize(component, attributes = [])
|
5
|
+
super(component)
|
6
|
+
@attributes = attributes
|
7
|
+
end
|
8
|
+
|
9
|
+
def attributes
|
10
|
+
@attributes.each_with_object({}) do |attribute_name, result|
|
11
|
+
result[attribute_name] = send(attribute_name)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module FactoryBot
|
2
|
+
class Decorator
|
3
|
+
class ClassKeyHash < Decorator
|
4
|
+
def [](key)
|
5
|
+
@component[symbolized_key key]
|
6
|
+
end
|
7
|
+
|
8
|
+
def []=(key, value)
|
9
|
+
@component[symbolized_key key] = value
|
10
|
+
end
|
11
|
+
|
12
|
+
def key?(key)
|
13
|
+
@component.key? symbolized_key(key)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def symbolized_key(key)
|
19
|
+
if key.respond_to?(:to_sym)
|
20
|
+
key.to_sym
|
21
|
+
elsif FactoryBot.allow_class_lookup
|
22
|
+
ActiveSupport::Deprecation.warn "Looking up factories by class is deprecated and will be removed in 5.0. Use symbols instead and set FactoryBot.allow_class_lookup = false", caller
|
23
|
+
key.to_s.underscore.to_sym
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module FactoryBot
|
2
|
+
class Decorator
|
3
|
+
class DisallowsDuplicatesRegistry < Decorator
|
4
|
+
def register(name, item)
|
5
|
+
if registered?(name)
|
6
|
+
raise DuplicateDefinitionError, "#{@component.name} already registered: #{name}"
|
7
|
+
else
|
8
|
+
@component.register(name, item)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module FactoryBot
|
2
|
+
class Decorator
|
3
|
+
class InvocationTracker < Decorator
|
4
|
+
def initialize(component)
|
5
|
+
super
|
6
|
+
@invoked_methods = []
|
7
|
+
end
|
8
|
+
|
9
|
+
def method_missing(name, *args, &block)
|
10
|
+
@invoked_methods << name
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
14
|
+
def __invoked_methods__
|
15
|
+
@invoked_methods.uniq
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
module FactoryBot
|
2
|
+
# @api private
|
3
|
+
class Definition
|
4
|
+
attr_reader :defined_traits, :declarations
|
5
|
+
|
6
|
+
def initialize(name = nil, base_traits = [])
|
7
|
+
@declarations = DeclarationList.new(name)
|
8
|
+
@callbacks = []
|
9
|
+
@defined_traits = Set.new
|
10
|
+
@to_create = nil
|
11
|
+
@base_traits = base_traits
|
12
|
+
@additional_traits = []
|
13
|
+
@constructor = nil
|
14
|
+
@attributes = nil
|
15
|
+
@compiled = false
|
16
|
+
end
|
17
|
+
|
18
|
+
delegate :declare_attribute, to: :declarations
|
19
|
+
|
20
|
+
def attributes
|
21
|
+
@attributes ||= AttributeList.new.tap do |attribute_list|
|
22
|
+
attribute_lists = aggregate_from_traits_and_self(:attributes) { declarations.attributes }
|
23
|
+
attribute_lists.each do |attributes|
|
24
|
+
attribute_list.apply_attributes attributes
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_create(&block)
|
30
|
+
if block_given?
|
31
|
+
@to_create = block
|
32
|
+
else
|
33
|
+
aggregate_from_traits_and_self(:to_create) { @to_create }.last
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def constructor
|
38
|
+
aggregate_from_traits_and_self(:constructor) { @constructor }.last
|
39
|
+
end
|
40
|
+
|
41
|
+
def callbacks
|
42
|
+
aggregate_from_traits_and_self(:callbacks) { @callbacks }
|
43
|
+
end
|
44
|
+
|
45
|
+
def compile
|
46
|
+
unless @compiled
|
47
|
+
declarations.attributes
|
48
|
+
|
49
|
+
defined_traits.each do |defined_trait|
|
50
|
+
base_traits.each { |bt| bt.define_trait defined_trait }
|
51
|
+
additional_traits.each { |bt| bt.define_trait defined_trait }
|
52
|
+
end
|
53
|
+
|
54
|
+
@compiled = true
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def overridable
|
59
|
+
declarations.overridable
|
60
|
+
self
|
61
|
+
end
|
62
|
+
|
63
|
+
def inherit_traits(new_traits)
|
64
|
+
@base_traits += new_traits
|
65
|
+
end
|
66
|
+
|
67
|
+
def append_traits(new_traits)
|
68
|
+
@additional_traits += new_traits
|
69
|
+
end
|
70
|
+
|
71
|
+
def add_callback(callback)
|
72
|
+
@callbacks << callback
|
73
|
+
end
|
74
|
+
|
75
|
+
def skip_create
|
76
|
+
@to_create = ->(instance) { }
|
77
|
+
end
|
78
|
+
|
79
|
+
def define_trait(trait)
|
80
|
+
@defined_traits.add(trait)
|
81
|
+
end
|
82
|
+
|
83
|
+
def define_constructor(&block)
|
84
|
+
@constructor = block
|
85
|
+
end
|
86
|
+
|
87
|
+
def before(*names, &block)
|
88
|
+
callback(*names.map { |name| "before_#{name}" }, &block)
|
89
|
+
end
|
90
|
+
|
91
|
+
def after(*names, &block)
|
92
|
+
callback(*names.map { |name| "after_#{name}" }, &block)
|
93
|
+
end
|
94
|
+
|
95
|
+
def callback(*names, &block)
|
96
|
+
names.each do |name|
|
97
|
+
FactoryBot.register_callback(name)
|
98
|
+
add_callback(Callback.new(name, block))
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
private
|
103
|
+
|
104
|
+
def base_traits
|
105
|
+
@base_traits.map { |name| trait_by_name(name) }
|
106
|
+
end
|
107
|
+
|
108
|
+
def additional_traits
|
109
|
+
@additional_traits.map { |name| trait_by_name(name) }
|
110
|
+
end
|
111
|
+
|
112
|
+
def trait_by_name(name)
|
113
|
+
trait_for(name) || FactoryBot.trait_by_name(name)
|
114
|
+
end
|
115
|
+
|
116
|
+
def trait_for(name)
|
117
|
+
defined_traits.detect { |trait| trait.name == name }
|
118
|
+
end
|
119
|
+
|
120
|
+
def initialize_copy(source)
|
121
|
+
super
|
122
|
+
@attributes = nil
|
123
|
+
@compiled = false
|
124
|
+
end
|
125
|
+
|
126
|
+
def aggregate_from_traits_and_self(method_name, &block)
|
127
|
+
compile
|
128
|
+
|
129
|
+
[
|
130
|
+
base_traits.map(&method_name),
|
131
|
+
instance_exec(&block),
|
132
|
+
additional_traits.map(&method_name),
|
133
|
+
].flatten.compact
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module FactoryBot
|
2
|
+
class DefinitionHierarchy
|
3
|
+
def callbacks
|
4
|
+
FactoryBot.callbacks
|
5
|
+
end
|
6
|
+
|
7
|
+
def constructor
|
8
|
+
FactoryBot.constructor
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_create
|
12
|
+
FactoryBot.to_create
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.build_from_definition(definition)
|
16
|
+
build_to_create(&definition.to_create)
|
17
|
+
build_constructor(&definition.constructor)
|
18
|
+
add_callbacks definition.callbacks
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.add_callbacks(callbacks)
|
22
|
+
if callbacks.any?
|
23
|
+
define_method :callbacks do
|
24
|
+
super() + callbacks
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
private_class_method :add_callbacks
|
29
|
+
|
30
|
+
def self.build_constructor(&block)
|
31
|
+
if block
|
32
|
+
define_method(:constructor) do
|
33
|
+
block
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
private_class_method :build_constructor
|
38
|
+
|
39
|
+
def self.build_to_create(&block)
|
40
|
+
if block
|
41
|
+
define_method(:to_create) do
|
42
|
+
block
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
private_class_method :build_to_create
|
47
|
+
end
|
48
|
+
end
|