factory_bot 4.11.1 → 6.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +58 -13
  3. data/GETTING_STARTED.md +785 -153
  4. data/LICENSE +1 -1
  5. data/NEWS.md +379 -0
  6. data/README.md +20 -30
  7. data/lib/factory_bot/aliases.rb +2 -2
  8. data/lib/factory_bot/attribute/association.rb +2 -2
  9. data/lib/factory_bot/attribute/dynamic.rb +3 -2
  10. data/lib/factory_bot/attribute.rb +4 -39
  11. data/lib/factory_bot/attribute_assigner.rb +24 -10
  12. data/lib/factory_bot/attribute_list.rb +3 -2
  13. data/lib/factory_bot/callback.rb +4 -11
  14. data/lib/factory_bot/configuration.rb +15 -19
  15. data/lib/factory_bot/declaration/association.rb +33 -3
  16. data/lib/factory_bot/declaration/dynamic.rb +3 -1
  17. data/lib/factory_bot/declaration/implicit.rb +7 -2
  18. data/lib/factory_bot/declaration.rb +5 -5
  19. data/lib/factory_bot/declaration_list.rb +3 -3
  20. data/lib/factory_bot/decorator/attribute_hash.rb +1 -1
  21. data/lib/factory_bot/decorator/invocation_tracker.rb +2 -1
  22. data/lib/factory_bot/decorator.rb +20 -4
  23. data/lib/factory_bot/definition.rb +69 -21
  24. data/lib/factory_bot/definition_hierarchy.rb +1 -11
  25. data/lib/factory_bot/definition_proxy.rb +119 -64
  26. data/lib/factory_bot/enum.rb +27 -0
  27. data/lib/factory_bot/errors.rb +7 -4
  28. data/lib/factory_bot/evaluation.rb +1 -1
  29. data/lib/factory_bot/evaluator.rb +10 -11
  30. data/lib/factory_bot/evaluator_class_definer.rb +1 -1
  31. data/lib/factory_bot/factory.rb +12 -12
  32. data/lib/factory_bot/factory_runner.rb +4 -4
  33. data/lib/factory_bot/find_definitions.rb +2 -2
  34. data/lib/factory_bot/internal.rb +91 -0
  35. data/lib/factory_bot/linter.rb +41 -28
  36. data/lib/factory_bot/null_factory.rb +13 -4
  37. data/lib/factory_bot/null_object.rb +2 -6
  38. data/lib/factory_bot/registry.rb +17 -8
  39. data/lib/factory_bot/reload.rb +2 -3
  40. data/lib/factory_bot/sequence.rb +5 -6
  41. data/lib/factory_bot/strategy/stub.rb +37 -32
  42. data/lib/factory_bot/strategy_calculator.rb +1 -1
  43. data/lib/factory_bot/strategy_syntax_method_registrar.rb +13 -2
  44. data/lib/factory_bot/syntax/default.rb +13 -25
  45. data/lib/factory_bot/syntax/methods.rb +32 -9
  46. data/lib/factory_bot/syntax.rb +2 -2
  47. data/lib/factory_bot/trait.rb +7 -4
  48. data/lib/factory_bot/version.rb +1 -1
  49. data/lib/factory_bot.rb +71 -140
  50. metadata +46 -34
  51. data/NEWS +0 -306
  52. data/lib/factory_bot/attribute/static.rb +0 -16
  53. data/lib/factory_bot/declaration/static.rb +0 -26
  54. data/lib/factory_bot/decorator/class_key_hash.rb +0 -28
@@ -1,10 +1,10 @@
1
1
  module FactoryBot
2
2
  class Linter
3
-
4
- def initialize(factories, linting_strategy, factory_strategy = :create)
3
+ def initialize(factories, strategy: :create, traits: false, verbose: false)
5
4
  @factories_to_lint = factories
6
- @linting_method = "lint_#{linting_strategy}"
7
- @factory_strategy = factory_strategy
5
+ @factory_strategy = strategy
6
+ @traits = traits
7
+ @verbose = verbose
8
8
  @invalid_factories = calculate_invalid_factories
9
9
  end
10
10
 
@@ -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|
23
- errors = send(@linting_method, factory)
22
+ factories_to_lint.each_with_object(Hash.new([])) do |factory, result|
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
@@ -37,6 +36,13 @@ module FactoryBot
37
36
  "* #{location} - #{message} (#{@wrapped_error.class.name})"
38
37
  end
39
38
 
39
+ def verbose_message
40
+ <<~MESSAGE
41
+ #{message}
42
+ #{@wrapped_error.backtrace.join("\n ")}
43
+ MESSAGE
44
+ end
45
+
40
46
  def location
41
47
  @factory.name
42
48
  end
@@ -53,12 +59,20 @@ module FactoryBot
53
59
  end
54
60
  end
55
61
 
62
+ def lint(factory)
63
+ if @traits
64
+ lint_factory(factory) + lint_traits(factory)
65
+ else
66
+ lint_factory(factory)
67
+ end
68
+ end
69
+
56
70
  def lint_factory(factory)
57
71
  result = []
58
72
  begin
59
73
  FactoryBot.public_send(factory_strategy, factory.name)
60
- rescue => error
61
- result |= [FactoryError.new(error, factory)]
74
+ rescue => e
75
+ result |= [FactoryError.new(e, factory)]
62
76
  end
63
77
  result
64
78
  end
@@ -66,32 +80,31 @@ module FactoryBot
66
80
  def lint_traits(factory)
67
81
  result = []
68
82
  factory.definition.defined_traits.map(&:name).each do |trait_name|
69
- begin
70
- FactoryBot.public_send(factory_strategy, factory.name, trait_name)
71
- rescue => error
72
- result |=
73
- [FactoryTraitError.new(error, factory, trait_name)]
74
- end
83
+ FactoryBot.public_send(factory_strategy, factory.name, trait_name)
84
+ rescue => e
85
+ result |= [FactoryTraitError.new(e, factory, trait_name)]
75
86
  end
76
87
  result
77
88
  end
78
89
 
79
- def lint_factory_and_traits(factory)
80
- errors = lint_factory(factory)
81
- errors |= lint_traits(factory)
82
- errors
83
- end
84
-
85
90
  def error_message
86
- lines = invalid_factories.map do |_factory, exceptions|
87
- exceptions.map(&:message)
88
- end.flatten
91
+ lines = invalid_factories.map { |_factory, exceptions|
92
+ exceptions.map(&error_message_type)
93
+ }.flatten
89
94
 
90
- <<-ERROR_MESSAGE.strip
91
- The following factories are invalid:
95
+ <<~ERROR_MESSAGE.strip
96
+ The following factories are invalid:
92
97
 
93
- #{lines.join("\n")}
98
+ #{lines.join("\n")}
94
99
  ERROR_MESSAGE
95
100
  end
101
+
102
+ def error_message_type
103
+ if @verbose
104
+ :verbose_message
105
+ else
106
+ :message
107
+ end
108
+ end
96
109
  end
97
110
  end
@@ -10,9 +10,18 @@ module FactoryBot
10
10
  delegate :defined_traits, :callbacks, :attributes, :constructor,
11
11
  :to_create, to: :definition
12
12
 
13
- def compile; end
14
- def class_name; end
15
- def evaluator_class; FactoryBot::Evaluator; end
16
- def hierarchy_class; FactoryBot::DefinitionHierarchy; end
13
+ def compile
14
+ end
15
+
16
+ def class_name
17
+ end
18
+
19
+ def evaluator_class
20
+ FactoryBot::Evaluator
21
+ end
22
+
23
+ def hierarchy_class
24
+ FactoryBot::DefinitionHierarchy
25
+ end
17
26
  end
18
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?(*args)
21
- false
22
- end
23
19
  end
24
20
  end
@@ -1,3 +1,5 @@
1
+ require "active_support/core_ext/hash/indifferent_access"
2
+
1
3
  module FactoryBot
2
4
  class Registry
3
5
  include Enumerable
@@ -5,8 +7,8 @@ module FactoryBot
5
7
  attr_reader :name
6
8
 
7
9
  def initialize(name)
8
- @name = name
9
- @items = Decorator::ClassKeyHash.new({})
10
+ @name = name
11
+ @items = ActiveSupport::HashWithIndifferentAccess.new
10
12
  end
11
13
 
12
14
  def clear
@@ -18,14 +20,12 @@ module FactoryBot
18
20
  end
19
21
 
20
22
  def find(name)
21
- if registered?(name)
22
- @items[name]
23
- else
24
- raise ArgumentError, "#{@name} not registered: #{name}"
25
- end
23
+ @items.fetch(name)
24
+ rescue KeyError => e
25
+ raise key_error_with_custom_message(e)
26
26
  end
27
27
 
28
- alias :[] :find
28
+ alias_method :[], :find
29
29
 
30
30
  def register(name, item)
31
31
  @items[name] = item
@@ -34,5 +34,14 @@ module FactoryBot
34
34
  def registered?(name)
35
35
  @items.key?(name)
36
36
  end
37
+
38
+ private
39
+
40
+ def key_error_with_custom_message(key_error)
41
+ message = key_error.message.sub("key not found", "#{@name} not registered")
42
+ error = KeyError.new(message)
43
+ error.set_backtrace(key_error.backtrace)
44
+ error
45
+ end
37
46
  end
38
47
  end
@@ -1,8 +1,7 @@
1
1
  module FactoryBot
2
2
  def self.reload
3
- reset_configuration
4
- register_default_strategies
5
- register_default_callbacks
3
+ Internal.reset_configuration
4
+ Internal.register_default_strategies
6
5
  find_definitions
7
6
  end
8
7
  end
@@ -1,5 +1,4 @@
1
1
  module FactoryBot
2
-
3
2
  # Sequences are defined using sequence within a FactoryBot.define block.
4
3
  # Sequence values are generated using next.
5
4
  # @api private
@@ -7,14 +6,14 @@ module FactoryBot
7
6
  attr_reader :name
8
7
 
9
8
  def initialize(name, *args, &proc)
10
- @name = name
11
- @proc = proc
9
+ @name = name
10
+ @proc = proc
12
11
 
13
- options = args.extract_options!
14
- @value = args.first || 1
12
+ options = args.extract_options!
13
+ @value = args.first || 1
15
14
  @aliases = options.fetch(:aliases) { [] }
16
15
 
17
- if !@value.respond_to?(:peek)
16
+ unless @value.respond_to?(:peek)
18
17
  @value = EnumeratorAdapter.new(@value)
19
18
  end
20
19
  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
@@ -31,7 +35,8 @@ module FactoryBot
31
35
  def result(evaluation)
32
36
  evaluation.object.tap do |instance|
33
37
  stub_database_interaction_on_result(instance)
34
- clear_changed_attributes_on_result(instance)
38
+ set_timestamps(instance)
39
+ clear_changes_information(instance)
35
40
  evaluation.notify(:after_stub, instance)
36
41
  end
37
42
  end
@@ -43,15 +48,17 @@ module FactoryBot
43
48
  end
44
49
 
45
50
  def stub_database_interaction_on_result(result_instance)
46
- result_instance.id ||= next_id
51
+ if has_settable_id?(result_instance)
52
+ result_instance.id ||= next_id
53
+ end
47
54
 
48
55
  result_instance.instance_eval do
49
56
  def persisted?
50
- !new_record?
57
+ true
51
58
  end
52
59
 
53
60
  def new_record?
54
- id.nil?
61
+ false
55
62
  end
56
63
 
57
64
  def destroyed?
@@ -60,46 +67,44 @@ module FactoryBot
60
67
 
61
68
  DISABLED_PERSISTENCE_METHODS.each do |write_method|
62
69
  define_singleton_method(write_method) do |*args|
63
- raise "stubbed models are not allowed to access the database - #{self.class}##{write_method}(#{args.join(",")})"
70
+ raise "stubbed models are not allowed to access the database - "\
71
+ "#{self.class}##{write_method}(#{args.join(",")})"
64
72
  end
65
73
  end
66
74
  end
75
+ end
67
76
 
68
- created_at_missing_default = result_instance.respond_to?(:created_at) && !result_instance.created_at
77
+ def has_settable_id?(result_instance)
78
+ !result_instance.class.respond_to?(:primary_key) ||
79
+ result_instance.class.primary_key
80
+ end
69
81
 
70
- if created_at_missing_default
71
- result_instance.instance_eval do
72
- def created_at
73
- @created_at ||= Time.now.in_time_zone
74
- end
75
- end
82
+ def clear_changes_information(result_instance)
83
+ if result_instance.respond_to?(:clear_changes_information)
84
+ result_instance.clear_changes_information
76
85
  end
86
+ end
77
87
 
78
- has_updated_at = result_instance.respond_to?(:updated_at)
79
- updated_at_no_default = has_updated_at && !result_instance.updated_at
80
-
81
- if updated_at_no_default
82
- result_instance.instance_eval do
83
- def updated_at
84
- @updated_at ||= Time.current
85
- end
86
- end
88
+ def set_timestamps(result_instance)
89
+ if missing_created_at?(result_instance)
90
+ result_instance.created_at = Time.current
87
91
  end
88
- end
89
92
 
90
- def clear_changed_attributes_on_result(result_instance)
91
- unless result_instance.respond_to?(:clear_changes_information)
92
- result_instance.extend ActiveModelDirtyBackport
93
+ if missing_updated_at?(result_instance)
94
+ result_instance.updated_at = Time.current
93
95
  end
96
+ end
94
97
 
95
- result_instance.clear_changes_information
98
+ def missing_created_at?(result_instance)
99
+ result_instance.respond_to?(:created_at) &&
100
+ result_instance.respond_to?(:created_at=) &&
101
+ result_instance.created_at.blank?
96
102
  end
97
- end
98
103
 
99
- module ActiveModelDirtyBackport
100
- def clear_changes_information
101
- @previously_changed = ActiveSupport::HashWithIndifferentAccess.new
102
- @changed_attributes = ActiveSupport::HashWithIndifferentAccess.new
104
+ def missing_updated_at?(result_instance)
105
+ result_instance.respond_to?(:updated_at) &&
106
+ result_instance.respond_to?(:updated_at=) &&
107
+ result_instance.updated_at.blank?
103
108
  end
104
109
  end
105
110
  end
@@ -20,7 +20,7 @@ module FactoryBot
20
20
  end
21
21
 
22
22
  def strategy_name_to_object
23
- FactoryBot.strategy_by_name(@name_or_object)
23
+ FactoryBot::Internal.strategy_by_name(@name_or_object)
24
24
  end
25
25
  end
26
26
  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
- amount.times.map { 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
 
@@ -37,7 +48,7 @@ module FactoryBot
37
48
  strategy_name = @strategy_name
38
49
 
39
50
  define_syntax_method("#{strategy_name}_pair") do |name, *traits_and_overrides, &block|
40
- 2.times.map { send(strategy_name, name, *traits_and_overrides, &block) }
51
+ Array.new(2) { send(strategy_name, name, *traits_and_overrides, &block) }
41
52
  end
42
53
  end
43
54
 
@@ -15,9 +15,9 @@ module FactoryBot
15
15
  def factory(name, options = {}, &block)
16
16
  factory = Factory.new(name, options)
17
17
  proxy = FactoryBot::DefinitionProxy.new(factory.definition)
18
- proxy.instance_eval(&block) if block_given?
18
+ proxy.instance_eval(&block) if block
19
19
 
20
- FactoryBot.register_factory(factory)
20
+ Internal.register_factory(factory)
21
21
 
22
22
  proxy.child_factories.each do |(child_name, child_options, child_block)|
23
23
  parent_factory = child_options.delete(:parent) || name
@@ -26,41 +26,29 @@ module FactoryBot
26
26
  end
27
27
 
28
28
  def sequence(name, *args, &block)
29
- FactoryBot.register_sequence(Sequence.new(name, *args, &block))
29
+ Internal.register_sequence(Sequence.new(name, *args, &block))
30
30
  end
31
31
 
32
32
  def trait(name, &block)
33
- FactoryBot.register_trait(Trait.new(name, &block))
34
- end
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)
33
+ Internal.register_trait(Trait.new(name, &block))
46
34
  end
47
35
 
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
- FactoryBot.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
62
- def factory(name, options = {}, &block)
63
- factory = FactoryBot.factory_by_name(name)
50
+ def factory(name, _options = {}, &block)
51
+ factory = Internal.factory_by_name(name)
64
52
  proxy = FactoryBot::DefinitionProxy.new(factory.definition.overridable)
65
53
  proxy.instance_eval(&block)
66
54
  end
@@ -2,8 +2,8 @@ module FactoryBot
2
2
  module Syntax
3
3
  ## This module is a container for all strategy methods provided by
4
4
  ## FactoryBot. This includes all the default strategies provided ({Methods#build},
5
- ## {Methods#create}, {Methods#build_stubbed}, and {Methods#attributes_for}), as well as
6
- ## the complementary *_list methods.
5
+ ## {Methods#create}, {Methods#build_stubbed}, and {Methods#attributes_for}), as
6
+ ## well as the complementary *_list and *_pair methods.
7
7
  ## @example singular factory execution
8
8
  ## # basic use case
9
9
  ## build(:completed_order)
@@ -30,7 +30,7 @@ module FactoryBot
30
30
  ## # factory with traits and attribute override
31
31
  ## build_stubbed_list(:user, 15, :admin, :male, name: "John Doe")
32
32
  module Methods
33
- # @!parse FactoryBot.register_default_strategies
33
+ # @!parse FactoryBot::Internal.register_default_strategies
34
34
  # @!method build(name, *traits_and_overrides, &block)
35
35
  # (see #strategy_method)
36
36
  # Builds a registered factory by name.
@@ -51,22 +51,38 @@ module FactoryBot
51
51
  # Generates a hash of attributes for a registered factory by name.
52
52
  # @return [Hash] hash of attributes for the factory
53
53
 
54
- # @!method build_list(name, amount, *traits_and_overrides)
54
+ # @!method build_list(name, amount, *traits_and_overrides, &block)
55
55
  # (see #strategy_method_list)
56
56
  # @return [Array] array of built objects defined by the factory
57
57
 
58
- # @!method create_list(name, amount, *traits_and_overrides)
58
+ # @!method create_list(name, amount, *traits_and_overrides, &block)
59
59
  # (see #strategy_method_list)
60
60
  # @return [Array] array of created objects defined by the factory
61
61
 
62
- # @!method build_stubbed_list(name, amount, *traits_and_overrides)
62
+ # @!method build_stubbed_list(name, amount, *traits_and_overrides, &block)
63
63
  # (see #strategy_method_list)
64
64
  # @return [Array] array of stubbed objects defined by the factory
65
65
 
66
- # @!method attributes_for_list(name, amount, *traits_and_overrides)
66
+ # @!method attributes_for_list(name, amount, *traits_and_overrides, &block)
67
67
  # (see #strategy_method_list)
68
68
  # @return [Array<Hash>] array of attribute hashes for the factory
69
69
 
70
+ # @!method build_pair(name, *traits_and_overrides, &block)
71
+ # (see #strategy_method_pair)
72
+ # @return [Array] pair of built objects defined by the factory
73
+
74
+ # @!method create_pair(name, *traits_and_overrides, &block)
75
+ # (see #strategy_method_pair)
76
+ # @return [Array] pair of created objects defined by the factory
77
+
78
+ # @!method build_stubbed_pair(name, *traits_and_overrides, &block)
79
+ # (see #strategy_method_pair)
80
+ # @return [Array] pair of stubbed objects defined by the factory
81
+
82
+ # @!method attributes_for_pair(name, *traits_and_overrides, &block)
83
+ # (see #strategy_method_pair)
84
+ # @return [Array<Hash>] pair of attribute hashes for the factory
85
+
70
86
  # @!method strategy_method
71
87
  # @!visibility private
72
88
  # @param [Symbol] name the name of the factory to build
@@ -78,6 +94,13 @@ module FactoryBot
78
94
  # @param [Symbol] name the name of the factory to execute
79
95
  # @param [Integer] amount the number of instances to execute
80
96
  # @param [Array<Symbol, Symbol, Hash>] traits_and_overrides splat args traits and a hash of overrides
97
+ # @param [Proc] block block to be executed
98
+
99
+ # @!method strategy_method_pair
100
+ # @!visibility private
101
+ # @param [Symbol] name the name of the factory to execute
102
+ # @param [Array<Symbol, Symbol, Hash>] traits_and_overrides splat args traits and a hash of overrides
103
+ # @param [Proc] block block to be executed
81
104
 
82
105
  # Generates and returns the next value in a sequence.
83
106
  #
@@ -88,7 +111,7 @@ module FactoryBot
88
111
  # Returns:
89
112
  # The next value in the sequence. (Object)
90
113
  def generate(name)
91
- FactoryBot.sequence_by_name(name).next
114
+ Internal.sequence_by_name(name).next
92
115
  end
93
116
 
94
117
  # Generates and returns the list of values in a sequence.
@@ -103,7 +126,7 @@ module FactoryBot
103
126
  # The next value in the sequence. (Object)
104
127
  def generate_list(name, count)
105
128
  (1..count).map do
106
- FactoryBot.sequence_by_name(name).next
129
+ Internal.sequence_by_name(name).next
107
130
  end
108
131
  end
109
132
  end
@@ -1,5 +1,5 @@
1
- require 'factory_bot/syntax/methods'
2
- require 'factory_bot/syntax/default'
1
+ require "factory_bot/syntax/methods"
2
+ require "factory_bot/syntax/default"
3
3
 
4
4
  module FactoryBot
5
5
  module Syntax
@@ -4,16 +4,18 @@ module FactoryBot
4
4
  attr_reader :name, :definition
5
5
 
6
6
  def initialize(name, &block)
7
- @name = name
7
+ @name = name.to_s
8
8
  @block = block
9
9
  @definition = Definition.new(@name)
10
-
11
10
  proxy = FactoryBot::DefinitionProxy.new(@definition)
12
- proxy.instance_eval(&@block) if block_given?
11
+
12
+ if block
13
+ proxy.instance_eval(&@block)
14
+ end
13
15
  end
14
16
 
15
17
  delegate :add_callback, :declare_attribute, :to_create, :define_trait, :constructor,
16
- :callbacks, :attributes, to: :@definition
18
+ :callbacks, :attributes, to: :@definition
17
19
 
18
20
  def names
19
21
  [@name]
@@ -25,6 +27,7 @@ module FactoryBot
25
27
  end
26
28
 
27
29
  protected
30
+
28
31
  attr_reader :block
29
32
  end
30
33
  end
@@ -1,3 +1,3 @@
1
1
  module FactoryBot
2
- VERSION = "4.11.1".freeze
2
+ VERSION = "6.2.0".freeze
3
3
  end