factory_bot 5.1.1 → 6.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +52 -13
  3. data/GETTING_STARTED.md +426 -68
  4. data/NEWS.md +18 -1
  5. data/README.md +4 -4
  6. data/lib/factory_bot/aliases.rb +3 -3
  7. data/lib/factory_bot/attribute/association.rb +2 -2
  8. data/lib/factory_bot/attribute/dynamic.rb +2 -1
  9. data/lib/factory_bot/attribute_assigner.rb +9 -10
  10. data/lib/factory_bot/attribute_list.rb +1 -1
  11. data/lib/factory_bot/callback.rb +2 -10
  12. data/lib/factory_bot/configuration.rb +6 -6
  13. data/lib/factory_bot/declaration.rb +1 -1
  14. data/lib/factory_bot/declaration_list.rb +2 -2
  15. data/lib/factory_bot/decorator/invocation_tracker.rb +1 -1
  16. data/lib/factory_bot/decorator.rb +1 -1
  17. data/lib/factory_bot/definition.rb +42 -16
  18. data/lib/factory_bot/definition_hierarchy.rb +1 -11
  19. data/lib/factory_bot/definition_proxy.rb +64 -6
  20. data/lib/factory_bot/enum.rb +27 -0
  21. data/lib/factory_bot/evaluator.rb +5 -7
  22. data/lib/factory_bot/evaluator_class_definer.rb +1 -1
  23. data/lib/factory_bot/factory.rb +12 -12
  24. data/lib/factory_bot/factory_runner.rb +3 -3
  25. data/lib/factory_bot/find_definitions.rb +1 -1
  26. data/lib/factory_bot/internal.rb +18 -29
  27. data/lib/factory_bot/linter.rb +9 -13
  28. data/lib/factory_bot/null_factory.rb +10 -4
  29. data/lib/factory_bot/null_object.rb +2 -6
  30. data/lib/factory_bot/registry.rb +4 -4
  31. data/lib/factory_bot/reload.rb +0 -1
  32. data/lib/factory_bot/sequence.rb +5 -5
  33. data/lib/factory_bot/strategy/null.rb +4 -2
  34. data/lib/factory_bot/strategy/stub.rb +6 -2
  35. data/lib/factory_bot/strategy_syntax_method_registrar.rb +12 -1
  36. data/lib/factory_bot/syntax/default.rb +7 -19
  37. data/lib/factory_bot/trait.rb +1 -1
  38. data/lib/factory_bot/version.rb +1 -1
  39. data/lib/factory_bot.rb +21 -55
  40. metadata +12 -11
@@ -1,26 +1,20 @@
1
1
  module FactoryBot
2
2
  # @api private
3
3
  module Internal
4
- DEFAULT_STRATEGIES = {
5
- build: FactoryBot::Strategy::Build,
6
- create: FactoryBot::Strategy::Create,
7
- attributes_for: FactoryBot::Strategy::AttributesFor,
8
- build_stubbed: FactoryBot::Strategy::Stub,
9
- null: FactoryBot::Strategy::Null,
10
- }.freeze
11
-
12
- DEFAULT_CALLBACKS = [
13
- :after_create, :after_build, :after_stub, :after_create
14
- ].freeze
15
-
16
4
  class << self
17
- delegate :callback_names,
18
- :factories,
19
- :inline_sequences,
20
- :sequences,
21
- :strategies,
22
- :traits,
23
- to: :configuration
5
+ delegate :after,
6
+ :before,
7
+ :callbacks,
8
+ :constructor,
9
+ :factories,
10
+ :initialize_with,
11
+ :inline_sequences,
12
+ :sequences,
13
+ :skip_create,
14
+ :strategies,
15
+ :to_create,
16
+ :traits,
17
+ to: :configuration
24
18
 
25
19
  def configuration
26
20
  @configuration ||= Configuration.new
@@ -86,16 +80,11 @@ module FactoryBot
86
80
  end
87
81
 
88
82
  def register_default_strategies
89
- DEFAULT_STRATEGIES.each { |name, klass| register_strategy(name, klass) }
90
- end
91
-
92
- def register_default_callbacks
93
- DEFAULT_CALLBACKS.each(&method(:register_callback))
94
- end
95
-
96
- def register_callback(name)
97
- name = name.to_sym
98
- callback_names << name
83
+ register_strategy(:build, FactoryBot::Strategy::Build)
84
+ register_strategy(:create, FactoryBot::Strategy::Create)
85
+ register_strategy(:attributes_for, FactoryBot::Strategy::AttributesFor)
86
+ register_strategy(:build_stubbed, FactoryBot::Strategy::Stub)
87
+ register_strategy(:null, FactoryBot::Strategy::Null)
99
88
  end
100
89
  end
101
90
  end
@@ -19,17 +19,16 @@ module FactoryBot
19
19
  attr_reader :factories_to_lint, :invalid_factories, :factory_strategy
20
20
 
21
21
  def calculate_invalid_factories
22
- factories_to_lint.reduce(Hash.new([])) do |result, factory|
22
+ factories_to_lint.each_with_object(Hash.new([])) do |factory, result|
23
23
  errors = lint(factory)
24
24
  result[factory] |= errors unless errors.empty?
25
- result
26
25
  end
27
26
  end
28
27
 
29
28
  class FactoryError
30
29
  def initialize(wrapped_error, factory)
31
30
  @wrapped_error = wrapped_error
32
- @factory = factory
31
+ @factory = factory
33
32
  end
34
33
 
35
34
  def message
@@ -72,8 +71,8 @@ module FactoryBot
72
71
  result = []
73
72
  begin
74
73
  FactoryBot.public_send(factory_strategy, factory.name)
75
- rescue StandardError => error
76
- result |= [FactoryError.new(error, factory)]
74
+ rescue => e
75
+ result |= [FactoryError.new(e, factory)]
77
76
  end
78
77
  result
79
78
  end
@@ -81,20 +80,17 @@ module FactoryBot
81
80
  def lint_traits(factory)
82
81
  result = []
83
82
  factory.definition.defined_traits.map(&:name).each do |trait_name|
84
- begin
85
- FactoryBot.public_send(factory_strategy, factory.name, trait_name)
86
- rescue StandardError => error
87
- result |=
88
- [FactoryTraitError.new(error, factory, trait_name)]
89
- end
83
+ FactoryBot.public_send(factory_strategy, factory.name, trait_name)
84
+ rescue => e
85
+ result |= [FactoryTraitError.new(e, factory, trait_name)]
90
86
  end
91
87
  result
92
88
  end
93
89
 
94
90
  def error_message
95
- lines = invalid_factories.map do |_factory, exceptions|
91
+ lines = invalid_factories.map { |_factory, exceptions|
96
92
  exceptions.map(&error_message_type)
97
- end.flatten
93
+ }.flatten
98
94
 
99
95
  <<~ERROR_MESSAGE.strip
100
96
  The following factories are invalid:
@@ -10,12 +10,18 @@ module FactoryBot
10
10
  delegate :defined_traits, :callbacks, :attributes, :constructor,
11
11
  :to_create, to: :definition
12
12
 
13
- def compile; end
13
+ def compile
14
+ end
14
15
 
15
- def class_name; end
16
+ def class_name
17
+ end
16
18
 
17
- def evaluator_class; FactoryBot::Evaluator; end
19
+ def evaluator_class
20
+ FactoryBot::Evaluator
21
+ end
18
22
 
19
- def hierarchy_class; FactoryBot::DefinitionHierarchy; end
23
+ def hierarchy_class
24
+ FactoryBot::DefinitionHierarchy
25
+ end
20
26
  end
21
27
  end
@@ -5,7 +5,7 @@ module FactoryBot
5
5
  @methods_to_respond_to = methods_to_respond_to.map(&:to_s)
6
6
  end
7
7
 
8
- def method_missing(name, *args, &block)
8
+ def method_missing(name, *args, &block) # rubocop:disable Style/MissingRespondToMissing
9
9
  if respond_to?(name)
10
10
  nil
11
11
  else
@@ -13,12 +13,8 @@ module FactoryBot
13
13
  end
14
14
  end
15
15
 
16
- def respond_to?(method, _include_private = false)
16
+ def respond_to?(method)
17
17
  @methods_to_respond_to.include? method.to_s
18
18
  end
19
-
20
- def respond_to_missing?(*)
21
- false
22
- end
23
19
  end
24
20
  end
@@ -7,7 +7,7 @@ module FactoryBot
7
7
  attr_reader :name
8
8
 
9
9
  def initialize(name)
10
- @name = name
10
+ @name = name
11
11
  @items = ActiveSupport::HashWithIndifferentAccess.new
12
12
  end
13
13
 
@@ -21,11 +21,11 @@ module FactoryBot
21
21
 
22
22
  def find(name)
23
23
  @items.fetch(name)
24
- rescue KeyError => key_error
25
- raise key_error_with_custom_message(key_error)
24
+ rescue KeyError => e
25
+ raise key_error_with_custom_message(e)
26
26
  end
27
27
 
28
- alias :[] :find
28
+ alias [] find
29
29
 
30
30
  def register(name, item)
31
31
  @items[name] = item
@@ -2,7 +2,6 @@ module FactoryBot
2
2
  def self.reload
3
3
  Internal.reset_configuration
4
4
  Internal.register_default_strategies
5
- Internal.register_default_callbacks
6
5
  find_definitions
7
6
  end
8
7
  end
@@ -6,14 +6,14 @@ module FactoryBot
6
6
  attr_reader :name
7
7
 
8
8
  def initialize(name, *args, &proc)
9
- @name = name
10
- @proc = proc
9
+ @name = name
10
+ @proc = proc
11
11
 
12
- options = args.extract_options!
13
- @value = args.first || 1
12
+ options = args.extract_options!
13
+ @value = args.first || 1
14
14
  @aliases = options.fetch(:aliases) { [] }
15
15
 
16
- if !@value.respond_to?(:peek)
16
+ unless @value.respond_to?(:peek)
17
17
  @value = EnumeratorAdapter.new(@value)
18
18
  end
19
19
  end
@@ -1,9 +1,11 @@
1
1
  module FactoryBot
2
2
  module Strategy
3
3
  class Null
4
- def association(runner); end
4
+ def association(runner)
5
+ end
5
6
 
6
- def result(evaluation); end
7
+ def result(evaluation)
8
+ end
7
9
  end
8
10
  end
9
11
  end
@@ -21,9 +21,13 @@ module FactoryBot
21
21
  :update_attributes!,
22
22
  :update_attributes,
23
23
  :update_column,
24
- :update_columns,
24
+ :update_columns
25
25
  ].freeze
26
26
 
27
+ def self.next_id=(id)
28
+ @@next_id = id
29
+ end
30
+
27
31
  def association(runner)
28
32
  runner.run(:build_stubbed)
29
33
  end
@@ -64,7 +68,7 @@ module FactoryBot
64
68
  DISABLED_PERSISTENCE_METHODS.each do |write_method|
65
69
  define_singleton_method(write_method) do |*args|
66
70
  raise "stubbed models are not allowed to access the database - "\
67
- "#{self.class}##{write_method}(#{args.join(',')})"
71
+ "#{self.class}##{write_method}(#{args.join(",")})"
68
72
  end
69
73
  end
70
74
  end
@@ -11,6 +11,14 @@ module FactoryBot
11
11
  define_pair_strategy_method
12
12
  end
13
13
 
14
+ def self.with_index(block, index)
15
+ if block&.arity == 2
16
+ ->(instance) { block.call(instance, index) }
17
+ else
18
+ block
19
+ end
20
+ end
21
+
14
22
  private
15
23
 
16
24
  def define_singular_strategy_method
@@ -29,7 +37,10 @@ module FactoryBot
29
37
  raise ArgumentError, "count missing for #{strategy_name}_list"
30
38
  end
31
39
 
32
- Array.new(amount) { send(strategy_name, name, *traits_and_overrides, &block) }
40
+ Array.new(amount) do |i|
41
+ block_with_index = StrategySyntaxMethodRegistrar.with_index(block, i)
42
+ send(strategy_name, name, *traits_and_overrides, &block_with_index)
43
+ end
33
44
  end
34
45
  end
35
46
 
@@ -33,29 +33,17 @@ module FactoryBot
33
33
  Internal.register_trait(Trait.new(name, &block))
34
34
  end
35
35
 
36
- def to_create(&block)
37
- FactoryBot.to_create(&block)
38
- end
39
-
40
- def skip_create
41
- FactoryBot.skip_create
42
- end
43
-
44
- def initialize_with(&block)
45
- FactoryBot.initialize_with(&block)
46
- end
47
-
48
36
  def self.run(block)
49
37
  new.instance_eval(&block)
50
38
  end
51
39
 
52
- delegate :before, :after, :callback, to: :configuration
53
-
54
- private
55
-
56
- def configuration
57
- Internal.configuration
58
- end
40
+ delegate :after,
41
+ :before,
42
+ :callback,
43
+ :initialize_with,
44
+ :skip_create,
45
+ :to_create,
46
+ to: FactoryBot::Internal
59
47
  end
60
48
 
61
49
  class ModifyDSL
@@ -15,7 +15,7 @@ module FactoryBot
15
15
  end
16
16
 
17
17
  delegate :add_callback, :declare_attribute, :to_create, :define_trait, :constructor,
18
- :callbacks, :attributes, to: :@definition
18
+ :callbacks, :attributes, to: :@definition
19
19
 
20
20
  def names
21
21
  [@name]
@@ -1,3 +1,3 @@
1
1
  module FactoryBot
2
- VERSION = "5.1.1".freeze
2
+ VERSION = "6.0.1".freeze
3
3
  end
data/lib/factory_bot.rb CHANGED
@@ -4,6 +4,7 @@ require "active_support/core_ext/module/attribute_accessors"
4
4
  require "active_support/deprecation"
5
5
  require "active_support/notifications"
6
6
 
7
+ require "factory_bot/internal"
7
8
  require "factory_bot/definition_hierarchy"
8
9
  require "factory_bot/configuration"
9
10
  require "factory_bot/errors"
@@ -31,6 +32,7 @@ require "factory_bot/declaration"
31
32
  require "factory_bot/sequence"
32
33
  require "factory_bot/attribute_list"
33
34
  require "factory_bot/trait"
35
+ require "factory_bot/enum"
34
36
  require "factory_bot/aliases"
35
37
  require "factory_bot/definition"
36
38
  require "factory_bot/definition_proxy"
@@ -45,22 +47,16 @@ require "factory_bot/decorator/invocation_tracker"
45
47
  require "factory_bot/decorator/new_constructor"
46
48
  require "factory_bot/linter"
47
49
  require "factory_bot/version"
48
- require "factory_bot/internal"
49
50
 
50
51
  module FactoryBot
51
- Deprecation = ActiveSupport::Deprecation.new("6.0", "factory_bot")
52
-
53
- def self.configuration
54
- Internal.configuration
55
- end
56
-
57
- def self.reset_configuration
58
- Internal.reset_configuration
59
- end
52
+ Deprecation = ActiveSupport::Deprecation.new("7.0", "factory_bot")
60
53
 
61
54
  mattr_accessor :use_parent_strategy, instance_accessor: false
62
55
  self.use_parent_strategy = true
63
56
 
57
+ mattr_accessor :automatically_define_enum_traits, instance_accessor: false
58
+ self.automatically_define_enum_traits = true
59
+
64
60
  # Look for errors in factories and (optionally) their traits.
65
61
  # Parameters:
66
62
  # factories - which factories to lint; omit for all factories
@@ -71,55 +67,25 @@ module FactoryBot
71
67
  def self.lint(*args)
72
68
  options = args.extract_options!
73
69
  factories_to_lint = args[0] || FactoryBot.factories
74
- Linter.new(factories_to_lint, options).lint!
70
+ Linter.new(factories_to_lint, **options).lint!
75
71
  end
76
72
 
77
- class << self
78
- delegate :callbacks,
79
- :callback_names,
80
- :constructor,
81
- :factories,
82
- :initialize_with,
83
- :sequences,
84
- :skip_create,
85
- :strategies,
86
- :to_create,
87
- :traits,
88
- to: :configuration
89
-
90
- delegate :factory_by_name,
91
- :register_callback,
92
- :register_default_callbacks,
93
- :register_default_strategies,
94
- :register_factory,
95
- :register_sequence,
96
- :register_strategy,
97
- :register_trait,
98
- :rewind_sequences,
99
- :sequence_by_name,
100
- :strategy_by_name,
101
- :trait_by_name,
102
- to: Internal
103
-
104
- attr_accessor :allow_class_lookup
73
+ # Set the starting value for ids when using the build_stubbed strategy
74
+ #
75
+ # Arguments:
76
+ # * starting_id +Integer+
77
+ # The new starting id value.
78
+ def self.build_stubbed_starting_id=(starting_id)
79
+ Strategy::Stub.next_id = starting_id - 1
80
+ end
105
81
 
106
- deprecate :allow_class_lookup,
107
- :allow_class_lookup=,
108
- :callback_names,
109
- :factory_by_name,
110
- :register_callback,
111
- :register_default_callbacks,
112
- :register_default_strategies,
113
- :register_factory,
114
- :register_trait,
115
- :sequence_by_name,
116
- :sequences,
117
- :strategies,
118
- :trait_by_name,
119
- :traits,
120
- deprecator: Deprecation
82
+ class << self
83
+ delegate :factories,
84
+ :register_strategy,
85
+ :rewind_sequences,
86
+ :strategy_by_name,
87
+ to: Internal
121
88
  end
122
89
  end
123
90
 
124
91
  FactoryBot::Internal.register_default_strategies
125
- FactoryBot::Internal.register_default_callbacks
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: factory_bot
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.1.1
4
+ version: 6.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Josh Clayton
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2019-10-02 00:00:00.000000000 Z
12
+ date: 2020-06-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -17,14 +17,14 @@ dependencies:
17
17
  requirements:
18
18
  - - ">="
19
19
  - !ruby/object:Gem::Version
20
- version: 4.2.0
20
+ version: 5.0.0
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - ">="
26
26
  - !ruby/object:Gem::Version
27
- version: 4.2.0
27
+ version: 5.0.0
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: activerecord
30
30
  requirement: !ruby/object:Gem::Requirement
@@ -124,19 +124,19 @@ dependencies:
124
124
  - !ruby/object:Gem::Version
125
125
  version: '0'
126
126
  - !ruby/object:Gem::Dependency
127
- name: rubocop
127
+ name: standard
128
128
  requirement: !ruby/object:Gem::Requirement
129
129
  requirements:
130
- - - '='
130
+ - - ">="
131
131
  - !ruby/object:Gem::Version
132
- version: '0.54'
132
+ version: '0'
133
133
  type: :development
134
134
  prerelease: false
135
135
  version_requirements: !ruby/object:Gem::Requirement
136
136
  requirements:
137
- - - '='
137
+ - - ">="
138
138
  - !ruby/object:Gem::Version
139
- version: '0.54'
139
+ version: '0'
140
140
  - !ruby/object:Gem::Dependency
141
141
  name: simplecov
142
142
  requirement: !ruby/object:Gem::Requirement
@@ -205,6 +205,7 @@ files:
205
205
  - lib/factory_bot/definition.rb
206
206
  - lib/factory_bot/definition_hierarchy.rb
207
207
  - lib/factory_bot/definition_proxy.rb
208
+ - lib/factory_bot/enum.rb
208
209
  - lib/factory_bot/errors.rb
209
210
  - lib/factory_bot/evaluation.rb
210
211
  - lib/factory_bot/evaluator.rb
@@ -244,14 +245,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
244
245
  requirements:
245
246
  - - ">="
246
247
  - !ruby/object:Gem::Version
247
- version: 2.3.0
248
+ version: 2.5.0
248
249
  required_rubygems_version: !ruby/object:Gem::Requirement
249
250
  requirements:
250
251
  - - ">="
251
252
  - !ruby/object:Gem::Version
252
253
  version: '0'
253
254
  requirements: []
254
- rubygems_version: 3.0.3
255
+ rubygems_version: 3.1.2
255
256
  signing_key:
256
257
  specification_version: 4
257
258
  summary: factory_bot provides a framework and DSL for defining and using model instance