factory_bot 6.5.4 → 6.5.6
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 +4 -4
- data/GETTING_STARTED.md +106 -85
- data/NEWS.md +430 -334
- data/README.md +11 -19
- data/lib/factory_bot/attribute_assigner.rb +74 -18
- data/lib/factory_bot/callbacks_observer.rb +19 -1
- data/lib/factory_bot/evaluator.rb +9 -3
- data/lib/factory_bot/factory.rb +8 -4
- data/lib/factory_bot/registry.rb +1 -1
- data/lib/factory_bot/sequence.rb +24 -10
- data/lib/factory_bot/strategy/build.rb +2 -0
- data/lib/factory_bot/strategy/create.rb +2 -0
- data/lib/factory_bot/strategy.rb +15 -0
- data/lib/factory_bot/syntax/methods.rb +7 -9
- data/lib/factory_bot/version.rb +1 -1
- data/lib/factory_bot.rb +1 -6
- metadata +5 -5
- data/lib/factory_bot/strategy_calculator.rb +0 -26
    
        data/README.md
    CHANGED
    
    | @@ -1,20 +1,17 @@ | |
| 1 | 
            -
            # factory_bot  | 
| 1 | 
            +
            # factory_bot 
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            [![Build Status][ci-image]][ci] [![Code Climate][grade-image]][grade] [![Gem Version][version-image]][version]
         | 
| 2 4 |  | 
| 3 5 | 
             
            factory_bot is a fixtures replacement with a straightforward definition syntax, support for multiple build strategies (saved instances, unsaved instances, attribute hashes, and stubbed objects), and support for multiple factories for the same class (user, admin_user, and so on), including factory inheritance.
         | 
| 4 6 |  | 
| 5 7 | 
             
            If you want to use factory_bot with Rails, see
         | 
| 6 8 | 
             
            [factory_bot_rails](https://github.com/thoughtbot/factory_bot_rails).
         | 
| 7 9 |  | 
| 8 | 
            -
             | 
| 9 | 
            -
             | 
| 10 | 
            -
             | 
| 11 | 
            -
            ### Transitioning from factory\_girl?
         | 
| 10 | 
            +
            Interested in the history of the project name? You can find the history [here](https://github.com/thoughtbot/factory_bot/blob/main/NAME.md)
         | 
| 12 11 |  | 
| 13 | 
            -
            Check out the [guide](https://github.com/thoughtbot/factory_bot/blob/v4.9.0/UPGRADE_FROM_FACTORY_GIRL.md).
         | 
| 12 | 
            +
            Transitioning from factory\_girl? Check out the [upgrade guide](https://github.com/thoughtbot/factory_bot/blob/v4.9.0/UPGRADE_FROM_FACTORY_GIRL.md).
         | 
| 14 13 |  | 
| 15 | 
            -
             | 
| 16 | 
            -
            Documentation
         | 
| 17 | 
            -
            -------------
         | 
| 14 | 
            +
            ## Documentation
         | 
| 18 15 |  | 
| 19 16 | 
             
            See our extensive reference, guides, and cookbook in [the factory_bot book][].
         | 
| 20 17 |  | 
| @@ -27,8 +24,7 @@ Rails, see [the factory_bot wiki][]. | |
| 27 24 | 
             
            [the factory_bot book]: https://thoughtbot.github.io/factory_bot
         | 
| 28 25 | 
             
            [the factory_bot wiki]: https://github.com/thoughtbot/factory_bot/wiki
         | 
| 29 26 |  | 
| 30 | 
            -
            Install
         | 
| 31 | 
            -
            --------
         | 
| 27 | 
            +
            ## Install
         | 
| 32 28 |  | 
| 33 29 | 
             
            Run:
         | 
| 34 30 |  | 
| @@ -42,13 +38,11 @@ To install the gem manually from your shell, run: | |
| 42 38 | 
             
            gem install factory_bot
         | 
| 43 39 | 
             
            ```
         | 
| 44 40 |  | 
| 45 | 
            -
            Supported Ruby versions
         | 
| 46 | 
            -
            -----------------------
         | 
| 41 | 
            +
            ## Supported Ruby versions
         | 
| 47 42 |  | 
| 48 | 
            -
            Supported Ruby versions are listed in  | 
| 43 | 
            +
            Supported Ruby versions are listed in `.github/workflows/build.yml` ([source](https://github.com/thoughtbot/factory_bot/blob/main/.github/workflows/build.yml))
         | 
| 49 44 |  | 
| 50 | 
            -
            More Information
         | 
| 51 | 
            -
            ----------------
         | 
| 45 | 
            +
            ## More Information
         | 
| 52 46 |  | 
| 53 47 | 
             
            * [Rubygems](https://rubygems.org/gems/factory_bot)
         | 
| 54 48 | 
             
            * [Stack Overflow](https://stackoverflow.com/questions/tagged/factory-bot)
         | 
| @@ -56,10 +50,8 @@ More Information | |
| 56 50 | 
             
            * [GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS](https://robots.thoughtbot.com/)
         | 
| 57 51 |  | 
| 58 52 | 
             
            [GETTING_STARTED]: https://github.com/thoughtbot/factory_bot/blob/main/GETTING_STARTED.md
         | 
| 59 | 
            -
            [NAME]: https://github.com/thoughtbot/factory_bot/blob/main/NAME.md
         | 
| 60 53 |  | 
| 61 | 
            -
            Useful Tools
         | 
| 62 | 
            -
            ------------
         | 
| 54 | 
            +
            ## Useful Tools
         | 
| 63 55 |  | 
| 64 56 | 
             
            * [FactoryTrace](https://github.com/djezzzl/factory_trace) - helps to find unused factories and traits.
         | 
| 65 57 | 
             
            * [ruby-lsp-factory_bot](https://github.com/donny741/ruby-lsp-factory_bot) / [ruby-lsp-rails-factory-bot](https://github.com/johansenja/ruby-lsp-rails-factory-bot) - integration with [ruby-lsp](https://github.com/Shopify/ruby-lsp) to provide intellisense
         | 
| @@ -9,6 +9,7 @@ module FactoryBot | |
| 9 9 | 
             
                  @attribute_names_assigned = []
         | 
| 10 10 | 
             
                end
         | 
| 11 11 |  | 
| 12 | 
            +
                # constructs an object-based factory product
         | 
| 12 13 | 
             
                def object
         | 
| 13 14 | 
             
                  @evaluator.instance = build_class_instance
         | 
| 14 15 | 
             
                  build_class_instance.tap do |instance|
         | 
| @@ -19,6 +20,7 @@ module FactoryBot | |
| 19 20 | 
             
                  end
         | 
| 20 21 | 
             
                end
         | 
| 21 22 |  | 
| 23 | 
            +
                # constructs a Hash-based factory product
         | 
| 22 24 | 
             
                def hash
         | 
| 23 25 | 
             
                  @evaluator.instance = build_hash
         | 
| 24 26 |  | 
| @@ -29,6 +31,8 @@ module FactoryBot | |
| 29 31 |  | 
| 30 32 | 
             
                private
         | 
| 31 33 |  | 
| 34 | 
            +
                # Track evaluation of methods on the evaluator to prevent the duplicate
         | 
| 35 | 
            +
                # assignment of attributes accessed and via `initialize_with` syntax
         | 
| 32 36 | 
             
                def method_tracking_evaluator
         | 
| 33 37 | 
             
                  @method_tracking_evaluator ||= Decorator::AttributeHash.new(
         | 
| 34 38 | 
             
                    decorated_evaluator,
         | 
| @@ -67,12 +71,15 @@ module FactoryBot | |
| 67 71 | 
             
                  attribute_names_to_assign - association_names
         | 
| 68 72 | 
             
                end
         | 
| 69 73 |  | 
| 74 | 
            +
                # Builds a list of attributes names that should be assigned to the factory product
         | 
| 70 75 | 
             
                def attribute_names_to_assign
         | 
| 71 | 
            -
                  @attribute_names_to_assign ||=
         | 
| 72 | 
            -
                     | 
| 73 | 
            -
                    override_names | 
| 74 | 
            -
                     | 
| 75 | 
            -
                     | 
| 76 | 
            +
                  @attribute_names_to_assign ||= begin
         | 
| 77 | 
            +
                    # start a list of candidates containing non-transient attributes and overrides
         | 
| 78 | 
            +
                    assignment_candidates = non_ignored_attribute_names + override_names
         | 
| 79 | 
            +
                    # then remove any transient attributes (potentially reintroduced by the overrides),
         | 
| 80 | 
            +
                    # and remove ignorable aliased attributes from the candidate list
         | 
| 81 | 
            +
                    assignment_candidates - ignored_attribute_names - attribute_names_overriden_by_alias
         | 
| 82 | 
            +
                  end
         | 
| 76 83 | 
             
                end
         | 
| 77 84 |  | 
| 78 85 | 
             
                def non_ignored_attribute_names
         | 
| @@ -91,22 +98,71 @@ module FactoryBot | |
| 91 98 | 
             
                  @evaluator.__override_names__
         | 
| 92 99 | 
             
                end
         | 
| 93 100 |  | 
| 94 | 
            -
                def  | 
| 95 | 
            -
                  @attribute_list.names | 
| 96 | 
            -
                end
         | 
| 97 | 
            -
             | 
| 98 | 
            -
                def alias_names_to_ignore
         | 
| 99 | 
            -
                  @attribute_list.non_ignored.flat_map { |attribute|
         | 
| 100 | 
            -
                    override_names.map do |override|
         | 
| 101 | 
            -
                      attribute.name if ignorable_alias?(attribute, override)
         | 
| 102 | 
            -
                    end
         | 
| 103 | 
            -
                  }.compact
         | 
| 101 | 
            +
                def attribute_names
         | 
| 102 | 
            +
                  @attribute_list.names
         | 
| 104 103 | 
             
                end
         | 
| 105 104 |  | 
| 105 | 
            +
                def hash_instance_methods_to_respond_to
         | 
| 106 | 
            +
                  attribute_names + override_names + @build_class.instance_methods
         | 
| 107 | 
            +
                end
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                # Builds a list of attribute names which are slated to be interrupted by an override.
         | 
| 110 | 
            +
                def attribute_names_overriden_by_alias
         | 
| 111 | 
            +
                  @attribute_list
         | 
| 112 | 
            +
                    .non_ignored
         | 
| 113 | 
            +
                    .flat_map { |attribute|
         | 
| 114 | 
            +
                      override_names.map do |override|
         | 
| 115 | 
            +
                        attribute.name if ignorable_alias?(attribute, override)
         | 
| 116 | 
            +
                      end
         | 
| 117 | 
            +
                    }
         | 
| 118 | 
            +
                    .compact
         | 
| 119 | 
            +
                end
         | 
| 120 | 
            +
             | 
| 121 | 
            +
                # Is the attribute an ignorable alias of the override?
         | 
| 122 | 
            +
                # An attribute is ignorable when it is an alias of the override AND it is
         | 
| 123 | 
            +
                # either interrupting an assocciation OR is not the name of another attribute
         | 
| 124 | 
            +
                #
         | 
| 125 | 
            +
                # @note An "alias" is currently an overloaded term for two distinct cases:
         | 
| 126 | 
            +
                #   (1) attributes which are aliases and reference the same value
         | 
| 127 | 
            +
                #   (2) a logical grouping of a foreign key and an associated object
         | 
| 106 128 | 
             
                def ignorable_alias?(attribute, override)
         | 
| 107 | 
            -
                  attribute.alias_for?(override) | 
| 108 | 
            -
             | 
| 109 | 
            -
             | 
| 129 | 
            +
                  return false unless attribute.alias_for?(override)
         | 
| 130 | 
            +
             | 
| 131 | 
            +
                  # The attribute alias should be ignored when the override interrupts an association
         | 
| 132 | 
            +
                  return true if override_interrupts_association?(attribute, override)
         | 
| 133 | 
            +
             | 
| 134 | 
            +
                  # Remaining aliases should be ignored when the override does not match a declared attribute.
         | 
| 135 | 
            +
                  # An override which is an alias to a declared attribute should not interrupt the aliased
         | 
| 136 | 
            +
                  # attribute and interrupt only the attribute with a matching name. This workaround allows a
         | 
| 137 | 
            +
                  # factory to declare both <attribute> and <attribute>_id as separate and distinct attributes.
         | 
| 138 | 
            +
                  !override_matches_declared_attribute?(override)
         | 
| 139 | 
            +
                end
         | 
| 140 | 
            +
             | 
| 141 | 
            +
                # Does this override interrupt an association?
         | 
| 142 | 
            +
                # When true, this indicates the aliased attribute is related to a declared association and the
         | 
| 143 | 
            +
                # override does not match the attribute name.
         | 
| 144 | 
            +
                #
         | 
| 145 | 
            +
                # @note Association overrides should take precedence over a declared foreign key attribute.
         | 
| 146 | 
            +
                #
         | 
| 147 | 
            +
                # @note An override may interrupt an association by providing the associated object or
         | 
| 148 | 
            +
                #   by providing the foreign key.
         | 
| 149 | 
            +
                #
         | 
| 150 | 
            +
                # @param [FactoryBot::Attribute] aliased_attribute
         | 
| 151 | 
            +
                # @param [Symbol] override name of an override which is an alias to the attribute name
         | 
| 152 | 
            +
                def override_interrupts_association?(aliased_attribute, override)
         | 
| 153 | 
            +
                  (aliased_attribute.association? || association_names.include?(override)) &&
         | 
| 154 | 
            +
                    aliased_attribute.name != override
         | 
| 155 | 
            +
                end
         | 
| 156 | 
            +
             | 
| 157 | 
            +
                # Does this override match the name of any declared attribute?
         | 
| 158 | 
            +
                #
         | 
| 159 | 
            +
                # @note Checking against the names of all attributes, resolves any issues with having both
         | 
| 160 | 
            +
                #   <attribute> and <attribute>_id in the same factory. This also takes into account ignored
         | 
| 161 | 
            +
                #   attributes that should not be assigned (aka transient attributes)
         | 
| 162 | 
            +
                #
         | 
| 163 | 
            +
                # @param [Symbol] override the name of an override
         | 
| 164 | 
            +
                def override_matches_declared_attribute?(override)
         | 
| 165 | 
            +
                  attribute_names.include?(override)
         | 
| 110 166 | 
             
                end
         | 
| 111 167 | 
             
              end
         | 
| 112 168 | 
             
            end
         | 
| @@ -4,11 +4,15 @@ module FactoryBot | |
| 4 4 | 
             
                def initialize(callbacks, evaluator)
         | 
| 5 5 | 
             
                  @callbacks = callbacks
         | 
| 6 6 | 
             
                  @evaluator = evaluator
         | 
| 7 | 
            +
                  @completed = []
         | 
| 7 8 | 
             
                end
         | 
| 8 9 |  | 
| 9 10 | 
             
                def update(name, result_instance)
         | 
| 10 11 | 
             
                  callbacks_by_name(name).each do |callback|
         | 
| 11 | 
            -
                     | 
| 12 | 
            +
                    if !completed?(result_instance, callback)
         | 
| 13 | 
            +
                      callback.run(result_instance, @evaluator)
         | 
| 14 | 
            +
                      record_completion!(result_instance, callback)
         | 
| 15 | 
            +
                    end
         | 
| 12 16 | 
             
                  end
         | 
| 13 17 | 
             
                end
         | 
| 14 18 |  | 
| @@ -17,5 +21,19 @@ module FactoryBot | |
| 17 21 | 
             
                def callbacks_by_name(name)
         | 
| 18 22 | 
             
                  @callbacks.select { |callback| callback.name == name }
         | 
| 19 23 | 
             
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def completed?(instance, callback)
         | 
| 26 | 
            +
                  key = completion_key_for(instance, callback)
         | 
| 27 | 
            +
                  @completed.include?(key)
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                def record_completion!(instance, callback)
         | 
| 31 | 
            +
                  key = completion_key_for(instance, callback)
         | 
| 32 | 
            +
                  @completed << key
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                def completion_key_for(instance, callback)
         | 
| 36 | 
            +
                  "#{instance.object_id}-#{callback.object_id}"
         | 
| 37 | 
            +
                end
         | 
| 20 38 | 
             
              end
         | 
| 21 39 | 
             
            end
         | 
| @@ -1,4 +1,3 @@ | |
| 1 | 
            -
            require "active_support/core_ext/hash/except"
         | 
| 2 1 | 
             
            require "active_support/core_ext/class/attribute"
         | 
| 3 2 |  | 
| 4 3 | 
             
            module FactoryBot
         | 
| @@ -51,8 +50,15 @@ module FactoryBot | |
| 51 50 | 
             
                  @overrides.keys
         | 
| 52 51 | 
             
                end
         | 
| 53 52 |  | 
| 54 | 
            -
                def increment_sequence(sequence)
         | 
| 55 | 
            -
                  sequence.next( | 
| 53 | 
            +
                def increment_sequence(sequence, scope: self)
         | 
| 54 | 
            +
                  value = sequence.next(scope)
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                  raise if value.respond_to?(:start_with?) && value.start_with?("#<FactoryBot::Declaration")
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                  value
         | 
| 59 | 
            +
                rescue
         | 
| 60 | 
            +
                  raise ArgumentError, "Sequence '#{sequence.uri_manager.first}' failed to " \
         | 
| 61 | 
            +
                                      "return a value. Perhaps it needs a scope to operate? (scope: <object>)"
         | 
| 56 62 | 
             
                end
         | 
| 57 63 |  | 
| 58 64 | 
             
                def self.attribute_list
         | 
    
        data/lib/factory_bot/factory.rb
    CHANGED
    
    | @@ -33,18 +33,22 @@ module FactoryBot | |
| 33 33 |  | 
| 34 34 | 
             
                def run(build_strategy, overrides, &block)
         | 
| 35 35 | 
             
                  block ||= ->(result) { result }
         | 
| 36 | 
            +
             | 
| 36 37 | 
             
                  compile
         | 
| 37 38 |  | 
| 38 | 
            -
                  strategy =  | 
| 39 | 
            +
                  strategy = Strategy.lookup_strategy(build_strategy).new
         | 
| 39 40 |  | 
| 40 41 | 
             
                  evaluator = evaluator_class.new(strategy, overrides.symbolize_keys)
         | 
| 41 42 | 
             
                  attribute_assigner = AttributeAssigner.new(evaluator, build_class, &compiled_constructor)
         | 
| 42 43 |  | 
| 43 44 | 
             
                  observer = CallbacksObserver.new(callbacks, evaluator)
         | 
| 44 | 
            -
                  evaluation =
         | 
| 45 | 
            -
             | 
| 45 | 
            +
                  evaluation = Evaluation.new(evaluator, attribute_assigner, compiled_to_create, observer)
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                  evaluation.notify(:before_all, nil)
         | 
| 48 | 
            +
                  instance = strategy.result(evaluation).tap(&block)
         | 
| 49 | 
            +
                  evaluation.notify(:after_all, instance)
         | 
| 46 50 |  | 
| 47 | 
            -
                   | 
| 51 | 
            +
                  instance
         | 
| 48 52 | 
             
                end
         | 
| 49 53 |  | 
| 50 54 | 
             
                def human_names
         | 
    
        data/lib/factory_bot/registry.rb
    CHANGED
    
    
    
        data/lib/factory_bot/sequence.rb
    CHANGED
    
    | @@ -17,8 +17,8 @@ module FactoryBot | |
| 17 17 |  | 
| 18 18 | 
             
                def self.find_by_uri(uri)
         | 
| 19 19 | 
             
                  uri = uri.to_sym
         | 
| 20 | 
            -
                   | 
| 21 | 
            -
                     | 
| 20 | 
            +
                  FactoryBot::Internal.sequences.to_a.find { |seq| seq.has_uri?(uri) } ||
         | 
| 21 | 
            +
                    FactoryBot::Internal.inline_sequences.find { |seq| seq.has_uri?(uri) }
         | 
| 22 22 | 
             
                end
         | 
| 23 23 |  | 
| 24 24 | 
             
                def initialize(name, *args, &proc)
         | 
| @@ -150,25 +150,24 @@ module FactoryBot | |
| 150 150 | 
             
                end
         | 
| 151 151 |  | 
| 152 152 | 
             
                class EnumeratorAdapter
         | 
| 153 | 
            -
                  def initialize( | 
| 154 | 
            -
                    @ | 
| 155 | 
            -
                    @value = value
         | 
| 153 | 
            +
                  def initialize(initial_value)
         | 
| 154 | 
            +
                    @initial_value = initial_value
         | 
| 156 155 | 
             
                  end
         | 
| 157 156 |  | 
| 158 157 | 
             
                  def peek
         | 
| 159 | 
            -
                     | 
| 158 | 
            +
                    value
         | 
| 160 159 | 
             
                  end
         | 
| 161 160 |  | 
| 162 161 | 
             
                  def next
         | 
| 163 | 
            -
                    @value =  | 
| 162 | 
            +
                    @value = value.next
         | 
| 164 163 | 
             
                  end
         | 
| 165 164 |  | 
| 166 165 | 
             
                  def rewind
         | 
| 167 | 
            -
                    @value =  | 
| 166 | 
            +
                    @value = first_value
         | 
| 168 167 | 
             
                  end
         | 
| 169 168 |  | 
| 170 169 | 
             
                  def set_value(new_value)
         | 
| 171 | 
            -
                    if new_value >=  | 
| 170 | 
            +
                    if new_value >= first_value
         | 
| 172 171 | 
             
                      @value = new_value
         | 
| 173 172 | 
             
                    else
         | 
| 174 173 | 
             
                      fail ArgumentError, "Value cannot be less than: #{@first_value}"
         | 
| @@ -176,7 +175,22 @@ module FactoryBot | |
| 176 175 | 
             
                  end
         | 
| 177 176 |  | 
| 178 177 | 
             
                  def integer_value?
         | 
| 179 | 
            -
                     | 
| 178 | 
            +
                    first_value.is_a?(Integer)
         | 
| 179 | 
            +
                  end
         | 
| 180 | 
            +
             | 
| 181 | 
            +
                  private
         | 
| 182 | 
            +
             | 
| 183 | 
            +
                  def first_value
         | 
| 184 | 
            +
                    @first_value ||= initial_value
         | 
| 185 | 
            +
                  end
         | 
| 186 | 
            +
             | 
| 187 | 
            +
                  def value
         | 
| 188 | 
            +
                    @value ||= initial_value
         | 
| 189 | 
            +
                  end
         | 
| 190 | 
            +
             | 
| 191 | 
            +
                  def initial_value
         | 
| 192 | 
            +
                    @value = @initial_value.respond_to?(:call) ? @initial_value.call : @initial_value
         | 
| 193 | 
            +
                    @first_value = @value
         | 
| 180 194 | 
             
                  end
         | 
| 181 195 | 
             
                end
         | 
| 182 196 | 
             
              end
         | 
| @@ -0,0 +1,15 @@ | |
| 1 | 
            +
            require "factory_bot/strategy/build"
         | 
| 2 | 
            +
            require "factory_bot/strategy/create"
         | 
| 3 | 
            +
            require "factory_bot/strategy/attributes_for"
         | 
| 4 | 
            +
            require "factory_bot/strategy/stub"
         | 
| 5 | 
            +
            require "factory_bot/strategy/null"
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            module FactoryBot
         | 
| 8 | 
            +
              module Strategy
         | 
| 9 | 
            +
                def self.lookup_strategy(name_or_object)
         | 
| 10 | 
            +
                  return name_or_object if name_or_object.is_a?(Class)
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  FactoryBot::Internal.strategy_by_name(name_or_object)
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
            end
         | 
| @@ -83,20 +83,20 @@ module FactoryBot | |
| 83 83 | 
             
                  # (see #strategy_method_pair)
         | 
| 84 84 | 
             
                  # @return [Array<Hash>] pair of attribute hashes for the factory
         | 
| 85 85 |  | 
| 86 | 
            -
                  # @!method strategy_method
         | 
| 86 | 
            +
                  # @!method strategy_method(name, traits_and_overrides, &block)
         | 
| 87 87 | 
             
                  # @!visibility private
         | 
| 88 88 | 
             
                  # @param [Symbol] name the name of the factory to build
         | 
| 89 89 | 
             
                  # @param [Array<Symbol, Symbol, Hash>] traits_and_overrides splat args traits and a hash of overrides
         | 
| 90 90 | 
             
                  # @param [Proc] block block to be executed
         | 
| 91 91 |  | 
| 92 | 
            -
                  # @!method strategy_method_list
         | 
| 92 | 
            +
                  # @!method strategy_method_list(name, amount, traits_and_overrides, &block)
         | 
| 93 93 | 
             
                  # @!visibility private
         | 
| 94 94 | 
             
                  # @param [Symbol] name the name of the factory to execute
         | 
| 95 95 | 
             
                  # @param [Integer] amount the number of instances to execute
         | 
| 96 96 | 
             
                  # @param [Array<Symbol, Symbol, Hash>] traits_and_overrides splat args traits and a hash of overrides
         | 
| 97 97 | 
             
                  # @param [Proc] block block to be executed
         | 
| 98 98 |  | 
| 99 | 
            -
                  # @!method strategy_method_pair
         | 
| 99 | 
            +
                  # @!method strategy_method_pair(name, traits_and_overrides, &block)
         | 
| 100 100 | 
             
                  # @!visibility private
         | 
| 101 101 | 
             
                  # @param [Symbol] name the name of the factory to execute
         | 
| 102 102 | 
             
                  # @param [Array<Symbol, Symbol, Hash>] traits_and_overrides splat args traits and a hash of overrides
         | 
| @@ -123,7 +123,7 @@ module FactoryBot | |
| 123 123 | 
             
                      raise(KeyError,
         | 
| 124 124 | 
             
                        "Sequence not registered: #{FactoryBot::UriManager.build_uri(uri_parts)}")
         | 
| 125 125 |  | 
| 126 | 
            -
                    increment_sequence( | 
| 126 | 
            +
                    increment_sequence(sequence, scope: scope)
         | 
| 127 127 | 
             
                  end
         | 
| 128 128 |  | 
| 129 129 | 
             
                  # Generates and returns the list of values in a global or factory sequence.
         | 
| @@ -147,7 +147,7 @@ module FactoryBot | |
| 147 147 | 
             
                      raise(KeyError, "Sequence not registered: '#{uri}'")
         | 
| 148 148 |  | 
| 149 149 | 
             
                    (1..count).map do
         | 
| 150 | 
            -
                      increment_sequence( | 
| 150 | 
            +
                      increment_sequence(sequence, scope: scope)
         | 
| 151 151 | 
             
                    end
         | 
| 152 152 | 
             
                  end
         | 
| 153 153 |  | 
| @@ -161,21 +161,19 @@ module FactoryBot | |
| 161 161 | 
             
                  # Increments the given sequence and returns the value.
         | 
| 162 162 | 
             
                  #
         | 
| 163 163 | 
             
                  # Arguments:
         | 
| 164 | 
            -
                  #   uri: (Symbol)
         | 
| 165 | 
            -
                  #     The URI for the sequence
         | 
| 166 164 | 
             
                  #   sequence:
         | 
| 167 165 | 
             
                  #     The sequence instance
         | 
| 168 166 | 
             
                  #   scope: (object)(optional)
         | 
| 169 167 | 
             
                  #     The object the sequence should be evaluated within
         | 
| 170 168 | 
             
                  #
         | 
| 171 | 
            -
                  def increment_sequence( | 
| 169 | 
            +
                  def increment_sequence(sequence, scope: nil)
         | 
| 172 170 | 
             
                    value = sequence.next(scope)
         | 
| 173 171 |  | 
| 174 172 | 
             
                    raise if value.respond_to?(:start_with?) && value.start_with?("#<FactoryBot::Declaration")
         | 
| 175 173 |  | 
| 176 174 | 
             
                    value
         | 
| 177 175 | 
             
                  rescue
         | 
| 178 | 
            -
                    raise ArgumentError, "Sequence '#{ | 
| 176 | 
            +
                    raise ArgumentError, "Sequence '#{sequence.uri_manager.first}' failed to " \
         | 
| 179 177 | 
             
                                        "return a value. Perhaps it needs a scope to operate? (scope: <object>)"
         | 
| 180 178 | 
             
                  end
         | 
| 181 179 | 
             
                end
         | 
    
        data/lib/factory_bot/version.rb
    CHANGED
    
    
    
        data/lib/factory_bot.rb
    CHANGED
    
    | @@ -11,12 +11,7 @@ require "factory_bot/configuration" | |
| 11 11 | 
             
            require "factory_bot/errors"
         | 
| 12 12 | 
             
            require "factory_bot/factory_runner"
         | 
| 13 13 | 
             
            require "factory_bot/strategy_syntax_method_registrar"
         | 
| 14 | 
            -
            require "factory_bot/ | 
| 15 | 
            -
            require "factory_bot/strategy/build"
         | 
| 16 | 
            -
            require "factory_bot/strategy/create"
         | 
| 17 | 
            -
            require "factory_bot/strategy/attributes_for"
         | 
| 18 | 
            -
            require "factory_bot/strategy/stub"
         | 
| 19 | 
            -
            require "factory_bot/strategy/null"
         | 
| 14 | 
            +
            require "factory_bot/strategy"
         | 
| 20 15 | 
             
            require "factory_bot/registry"
         | 
| 21 16 | 
             
            require "factory_bot/null_factory"
         | 
| 22 17 | 
             
            require "factory_bot/null_object"
         | 
    
        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: 6.5. | 
| 4 | 
            +
              version: 6.5.6
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Josh Clayton
         | 
| @@ -67,7 +67,7 @@ dependencies: | |
| 67 67 | 
             
                  - !ruby/object:Gem::Version
         | 
| 68 68 | 
             
                    version: '0'
         | 
| 69 69 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 70 | 
            -
              name:  | 
| 70 | 
            +
              name: mutex_m
         | 
| 71 71 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 72 72 | 
             
                requirements:
         | 
| 73 73 | 
             
                - - ">="
         | 
| @@ -81,7 +81,7 @@ dependencies: | |
| 81 81 | 
             
                  - !ruby/object:Gem::Version
         | 
| 82 82 | 
             
                    version: '0'
         | 
| 83 83 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 84 | 
            -
              name:  | 
| 84 | 
            +
              name: ostruct
         | 
| 85 85 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 86 86 | 
             
                requirements:
         | 
| 87 87 | 
             
                - - ">="
         | 
| @@ -233,12 +233,12 @@ files: | |
| 233 233 | 
             
            - lib/factory_bot/registry.rb
         | 
| 234 234 | 
             
            - lib/factory_bot/reload.rb
         | 
| 235 235 | 
             
            - lib/factory_bot/sequence.rb
         | 
| 236 | 
            +
            - lib/factory_bot/strategy.rb
         | 
| 236 237 | 
             
            - lib/factory_bot/strategy/attributes_for.rb
         | 
| 237 238 | 
             
            - lib/factory_bot/strategy/build.rb
         | 
| 238 239 | 
             
            - lib/factory_bot/strategy/create.rb
         | 
| 239 240 | 
             
            - lib/factory_bot/strategy/null.rb
         | 
| 240 241 | 
             
            - lib/factory_bot/strategy/stub.rb
         | 
| 241 | 
            -
            - lib/factory_bot/strategy_calculator.rb
         | 
| 242 242 | 
             
            - lib/factory_bot/strategy_syntax_method_registrar.rb
         | 
| 243 243 | 
             
            - lib/factory_bot/syntax.rb
         | 
| 244 244 | 
             
            - lib/factory_bot/syntax/default.rb
         | 
| @@ -266,7 +266,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 266 266 | 
             
                - !ruby/object:Gem::Version
         | 
| 267 267 | 
             
                  version: '0'
         | 
| 268 268 | 
             
            requirements: []
         | 
| 269 | 
            -
            rubygems_version: 3. | 
| 269 | 
            +
            rubygems_version: 3.7.1
         | 
| 270 270 | 
             
            specification_version: 4
         | 
| 271 271 | 
             
            summary: factory_bot provides a framework and DSL for defining and using model instance
         | 
| 272 272 | 
             
              factories.
         | 
| @@ -1,26 +0,0 @@ | |
| 1 | 
            -
            module FactoryBot
         | 
| 2 | 
            -
              # @api private
         | 
| 3 | 
            -
              class StrategyCalculator
         | 
| 4 | 
            -
                def initialize(name_or_object)
         | 
| 5 | 
            -
                  @name_or_object = name_or_object
         | 
| 6 | 
            -
                end
         | 
| 7 | 
            -
             | 
| 8 | 
            -
                def strategy
         | 
| 9 | 
            -
                  if strategy_is_object?
         | 
| 10 | 
            -
                    @name_or_object
         | 
| 11 | 
            -
                  else
         | 
| 12 | 
            -
                    strategy_name_to_object
         | 
| 13 | 
            -
                  end
         | 
| 14 | 
            -
                end
         | 
| 15 | 
            -
             | 
| 16 | 
            -
                private
         | 
| 17 | 
            -
             | 
| 18 | 
            -
                def strategy_is_object?
         | 
| 19 | 
            -
                  @name_or_object.is_a?(Class)
         | 
| 20 | 
            -
                end
         | 
| 21 | 
            -
             | 
| 22 | 
            -
                def strategy_name_to_object
         | 
| 23 | 
            -
                  FactoryBot::Internal.strategy_by_name(@name_or_object)
         | 
| 24 | 
            -
                end
         | 
| 25 | 
            -
              end
         | 
| 26 | 
            -
            end
         |