1
0
Fork 0
mirror of https://github.com/thoughtbot/factory_bot.git synced 2022-11-09 11:43:51 -05:00
thoughtbot--factory_bot/lib/factory_bot.rb

92 lines
3 KiB
Ruby
Raw Normal View History

require "set"
require "active_support/core_ext/module/delegation"
require "active_support/core_ext/module/attribute_accessors"
require "active_support/deprecation"
require "active_support/notifications"
require "factory_bot/internal"
require "factory_bot/definition_hierarchy"
require "factory_bot/configuration"
require "factory_bot/errors"
require "factory_bot/factory_runner"
require "factory_bot/strategy_syntax_method_registrar"
require "factory_bot/strategy_calculator"
require "factory_bot/strategy/build"
require "factory_bot/strategy/create"
require "factory_bot/strategy/attributes_for"
require "factory_bot/strategy/stub"
require "factory_bot/strategy/null"
require "factory_bot/registry"
require "factory_bot/null_factory"
require "factory_bot/null_object"
require "factory_bot/evaluation"
require "factory_bot/factory"
require "factory_bot/attribute_assigner"
require "factory_bot/evaluator"
require "factory_bot/evaluator_class_definer"
require "factory_bot/attribute"
require "factory_bot/callback"
require "factory_bot/callbacks_observer"
require "factory_bot/declaration_list"
require "factory_bot/declaration"
require "factory_bot/sequence"
require "factory_bot/attribute_list"
require "factory_bot/trait"
Add functionality for enum traits (#1380) ## Enum traits Given a Rails model with an enum attribute: ```rb class Task < ActiveRecord::Base enum status: {queued: 0, started: 1, finished: 2} end ``` It is common for people to define traits for each possible value of the enum: ```rb FactoryBot.define do factory :task do trait :queued do status { :queued } end trait :started do status { :started } end trait :finished do status { :finished } end end end ``` With this commit, those trait definitions are no longer necessary—they are defined automatically by factory_bot. If automatically defining traits for enum attributes on every factory is not desired, it is possible to disable the feature by setting `FactoryBot.automatically_define_enum_traits = false` (see commit: [Allow opting out of automatically defining traits](https://github.com/thoughtbot/factory_bot/pull/1380/commits/5a20017351b08ce2ec9918d799e187e9eaa3ec32)). In that case, it is still possible to explicitly define traits for an enum attribute in a particular factory: ```rb FactoryBot.automatically_define_enum_traits = false FactoryBot.define do factory :task do traits_for_enum(:status) end end ``` It is also possible to use this feature for other enumerable values, not specifically tied to ActiveRecord enum attributes: ```rb class Task attr_accessor :status end FactoryBot.define do factory :task do traits_for_enum(:status, ["queued", "started", "finished"]) end end ``` The second argument here can be an enumerable object, including a Hash or Array. Closes #1049 Co-authored-by: Lance Johnson <lancejjohnson@gmail.com> Co-authored-by: PoTa <pota@mosfet.hu> Co-authored-by: Frida Casas <fridacasas.fc@gmail.com> Co-authored-by: Daniel Colson <danieljamescolson@gmail.com>
2020-05-01 17:50:51 -04:00
require "factory_bot/enum"
require "factory_bot/aliases"
require "factory_bot/definition"
require "factory_bot/definition_proxy"
require "factory_bot/syntax"
require "factory_bot/syntax_runner"
require "factory_bot/find_definitions"
require "factory_bot/reload"
require "factory_bot/decorator"
require "factory_bot/decorator/attribute_hash"
require "factory_bot/decorator/disallows_duplicates_registry"
require "factory_bot/decorator/invocation_tracker"
require "factory_bot/decorator/new_constructor"
require "factory_bot/linter"
require "factory_bot/version"
module FactoryBot
Deprecation = ActiveSupport::Deprecation.new("7.0", "factory_bot")
mattr_accessor :use_parent_strategy, instance_accessor: false
self.use_parent_strategy = true
Add functionality for enum traits (#1380) ## Enum traits Given a Rails model with an enum attribute: ```rb class Task < ActiveRecord::Base enum status: {queued: 0, started: 1, finished: 2} end ``` It is common for people to define traits for each possible value of the enum: ```rb FactoryBot.define do factory :task do trait :queued do status { :queued } end trait :started do status { :started } end trait :finished do status { :finished } end end end ``` With this commit, those trait definitions are no longer necessary—they are defined automatically by factory_bot. If automatically defining traits for enum attributes on every factory is not desired, it is possible to disable the feature by setting `FactoryBot.automatically_define_enum_traits = false` (see commit: [Allow opting out of automatically defining traits](https://github.com/thoughtbot/factory_bot/pull/1380/commits/5a20017351b08ce2ec9918d799e187e9eaa3ec32)). In that case, it is still possible to explicitly define traits for an enum attribute in a particular factory: ```rb FactoryBot.automatically_define_enum_traits = false FactoryBot.define do factory :task do traits_for_enum(:status) end end ``` It is also possible to use this feature for other enumerable values, not specifically tied to ActiveRecord enum attributes: ```rb class Task attr_accessor :status end FactoryBot.define do factory :task do traits_for_enum(:status, ["queued", "started", "finished"]) end end ``` The second argument here can be an enumerable object, including a Hash or Array. Closes #1049 Co-authored-by: Lance Johnson <lancejjohnson@gmail.com> Co-authored-by: PoTa <pota@mosfet.hu> Co-authored-by: Frida Casas <fridacasas.fc@gmail.com> Co-authored-by: Daniel Colson <danieljamescolson@gmail.com>
2020-05-01 17:50:51 -04:00
mattr_accessor :automatically_define_enum_traits, instance_accessor: false
self.automatically_define_enum_traits = true
# Look for errors in factories and (optionally) their traits.
# Parameters:
# factories - which factories to lint; omit for all factories
# options:
# traits: true - to lint traits as well as factories
# strategy: :create - to specify the strategy for linting
Add option for verbose linting This has come up a few times, and I can see why it might be helpful to have access to full backtraces when debugging a factory error uncovered by `FactoryBot.lint`. But since most of the time I don't want the extra noise from the backtrace, I added this as a verbose option. The default message is still: ``` The following factories are invalid: * user - undefined method `save!' for #<User:0x00007ff0cbc89100> * admin - undefined method `save!' for #<User:0x00007ff0cbc73e40> ``` And with the verbose option (usually with more lines of backtrace): ``` The following factories are invalid: * user - undefined method `save!' for #<User:0x00007ff0cbc89100> /Users/.../thoughtbot/factory_bot/lib/factory_bot/evaluation.rb:18:in `create' /Users/.../factory_bot/lib/factory_bot/strategy/create.rb:12:in `block in result' * admin - undefined method `save!' for #<User:0x00007ff0cbc73e40> /Users/.../thoughtbot/factory_bot/lib/factory_bot/evaluation.rb:18:in `create' /Users/.../factory_bot/lib/factory_bot/strategy/create.rb:12:in `block in result' ``` I moved the linting option defaults out of the FactoryBot.lint method and into keyword argument defaults in Linter#initialize. This seems a bit cleaner, and now we will get an error if we pass an option we don't understand (before 6e511597 we had a test that passed in a bogus option) Closes #710 Closes #1124 I am opening a new PR since the original PR is years old and it seemed unkind to request changes after so long. Instead I will list the authors as co-authors. Co-authored-by: Jack Kinsella <jack.kinsella@gmail.com> Co-authored-by: Jasper Woudenberg <mail@jasperwoudenberg.com>
2018-11-21 15:28:28 -05:00
# verbose: true - to include full backtraces for each linting error
def self.lint(*args)
options = args.extract_options!
factories_to_lint = args[0] || FactoryBot.factories
Linter.new(factories_to_lint, **options).lint!
end
# Set the starting value for ids when using the build_stubbed strategy
#
# Arguments:
# * starting_id +Integer+
# The new starting id value.
def self.build_stubbed_starting_id=(starting_id)
Strategy::Stub.next_id = starting_id - 1
end
class << self
delegate :factories,
:register_strategy,
:rewind_sequences,
:strategy_by_name,
to: Internal
end
end
FactoryBot::Internal.register_default_strategies