[
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: 'bug'\nassignees: ''\n\n---\n\n<!-- By contributing to this project, you agree to abide by the thoughtbot Code\nof Conduct: https://thoughtbot.com/open-source-code-of-conduct -->\n\n### Description\n\n<!-- A clear and concise description of what the bug is. -->\n\n### Reproduction Steps\n\n<!-- Steps for others to reproduce the bug. Be as specific as possible. A\nreproduction script or link to a sample application that demonstrates the\nproblem are especially helpful. -->\n\n<!-- You can create a reproduction script by copying this sample reproduction\nscript and adding whatever code is necessary to get a failing test case:\nhttps://github.com/thoughtbot/factory_bot/blob/main/.github/REPRODUCTION_SCRIPT.rb -->\n\n### Expected behavior\n\n<!-- What you expected to happen. -->\n\n### Actual behavior\n\n<!-- What happened instead. -->\n\n### System configuration\n**factory_bot version**:  \n**rails version**:  \n**ruby version**:\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "content": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: 'feature'\nassignees: ''\n\n---\n\n<!-- By contributing to this project, you agree to abide by the thoughtbot Code\nof Conduct: https://thoughtbot.com/open-source-code-of-conduct -->\n\n### Problem this feature will solve\n\n<!-- A clear and concise description of what the problem is. Ex. When doing\n[...] I find it difficult to [...] -->\n\n### Desired solution\n\n<!-- The feature or change that would solve the problem -->\n\n## Alternatives considered\n\n<!-- Any alternative solutions or features you've considered. -->\n\n## Additional context\n\n<!-- Add any other context about this feature request. -->\n"
  },
  {
    "path": ".github/REPRODUCTION_SCRIPT.rb",
    "content": "require \"bundler/inline\"\n\ngemfile(true) do\n  source \"https://rubygems.org\"\n  git_source(:github) { |repo| \"https://github.com/#{repo}.git\" }\n  gem \"factory_bot\", \"~> 6.0\"\n  gem \"activerecord\"\n  gem \"sqlite3\"\nend\n\nrequire \"active_record\"\nrequire \"factory_bot\"\nrequire \"minitest/autorun\"\nrequire \"logger\"\n\nActiveRecord::Base.establish_connection(adapter: \"sqlite3\", database: \":memory:\")\nActiveRecord::Base.logger = Logger.new(STDOUT)\n\nActiveRecord::Schema.define do\n  # TODO: Update the schema to include the specific tables or columns necessary\n  # to reproduct the bug\n  create_table :posts, force: true do |t|\n    t.string :body\n  end\nend\n\n# TODO: Add any application specific code necessary to reproduce the bug\nclass Post < ActiveRecord::Base\nend\n\nFactoryBot.define do\n  # TODO: Write the factory definitions necessary to reproduce the bug\n  factory :post do\n    body { \"Post body\" }\n  end\nend\n\nclass FactoryBotTest < Minitest::Test\n  def test_factory_bot_stuff\n    # TODO: Write a failing test case to demonstrate what isn't working as\n    # expected\n    body_override = \"Body override\"\n\n    post = FactoryBot.build(:post, body: body_override)\n\n    assert_equal post.body, body_override\n  end\nend\n\n# Run the tests with `ruby <filename>`\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "---\nversion: 2\n\nupdates:\n  - package-ecosystem: \"bundler\"\n    directory: \"/\"\n    schedule:\n      interval: weekly\n      time: \"02:00\"\n      timezone: \"Etc/UTC\"\n  - package-ecosystem: \"github-actions\"\n    directory: \"/\"\n    schedule:\n      interval: weekly\n      time: \"02:00\"\n      timezone: \"Etc/UTC\"\n"
  },
  {
    "path": ".github/workflows/build.yml",
    "content": "name: Build\non:\n  pull_request:\n  push:\n    branches: [ main ]\n\njobs:\n  build:\n    name: Ruby ${{ matrix.ruby }} / Rails ${{ matrix.rails }}\n    strategy:\n      fail-fast: false\n      matrix:\n        ruby:\n          - jruby-9.4\n          - truffleruby\n          - \"4.0\"\n          - \"3.4\"\n          - \"3.3\"\n          - \"3.2\"\n          - \"3.1\"\n        rails:\n          - \"7.0\"\n          - \"7.1\"\n          - \"7.2\"\n          - \"8.0\"\n          - main\n        exclude:\n          - { ruby: jruby-9.4, rails: \"7.1\" }\n          - { ruby: jruby-9.4, rails: \"7.2\" }\n          - { ruby: jruby-9.4, rails: \"8.0\" }\n          - { ruby: jruby-9.4, rails: main }\n          # Rails >= 8.0 requires Ruby 3.2\n          - { ruby: \"3.1\", rails: \"8.0\" }\n          - { ruby: \"3.1\", rails: \"main\" }\n          # Rails >= 8.1 requires Ruby 3.3\n          - { ruby: \"3.2\", rails: \"main\" }\n          # 2025-10-23 There's an incompatibility between truffleruby and rails edge Git ref\n          # results in a \"NoMethodError: undefined method `[]' for class Fiber\" error whilst running specs\n          - { ruby: truffleruby, rails: \"main\" }\n\n    runs-on: 'ubuntu-latest'\n\n    env:\n      BUNDLE_GEMFILE: gemfiles/${{ matrix.rails }}.gemfile\n\n    steps:\n      - uses: actions/checkout@v6\n      - uses: ruby/setup-ruby@v1\n        with:\n          ruby-version: ${{ matrix.ruby }}\n      - name: Setup project\n        run: bundle install\n      - name: Run test\n        run: bundle exec rake all_specs\n\n  standard:\n    name: Run standard\n    runs-on: 'ubuntu-latest'\n    steps:\n      - uses: actions/checkout@v6\n      - uses: ruby/setup-ruby@v1\n        with:\n          ruby-version: \"3.3\"\n      - name: Setup project\n        run: bundle install\n      - name: Run test\n        run: bundle exec rake standard\n"
  },
  {
    "path": ".github/workflows/docs.yml",
    "content": "name: Docs\non:\n  push:\n    branches:\n      - main\n\njobs:\n  deploy:\n    runs-on: ubuntu-latest\n    permissions:\n      contents: write  # To push a branch\n      pull-requests: write  # To create a PR from that branch\n    steps:\n    - uses: actions/checkout@v6\n      with:\n        fetch-depth: 0\n    - name: Install mdbook\n      run: |\n        mkdir mdbook\n        curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.27/mdbook-v0.4.27-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=./mdbook\n        echo `pwd`/mdbook >> $GITHUB_PATH\n    - name: Deploy GitHub Pages\n      run: |\n        cd docs\n        mdbook build\n        git worktree add gh-pages\n        git config user.name \"Deploy from CI\"\n        git config user.email \"\"\n        cd gh-pages\n        # Delete the ref to avoid keeping history.\n        git update-ref -d refs/heads/gh-pages\n        rm -rf *\n        mv ../book/* .\n        git add .\n        git commit -m \"Deploy $GITHUB_SHA to gh-pages\"\n        git push --force --set-upstream origin gh-pages\n"
  },
  {
    "path": ".github/workflows/dynamic-readme.yml",
    "content": "name: update-templates\n\non:\n  push:\n    branches:\n      - main\n    paths:\n      - README.md\n  workflow_dispatch:\n\njobs:\n  update-templates:\n    permissions:\n      contents: write\n      pull-requests: write\n      pages: write\n    uses: thoughtbot/templates/.github/workflows/dynamic-readme.yaml@main\n    secrets:\n      token: ${{ secrets.GITHUB_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/dynamic-security.yml",
    "content": "name: update-security\n\non:\n  push:\n    paths:\n      - SECURITY.md\n    branches:\n      - main\n  workflow_dispatch:\n\njobs:\n  update-security:\n    permissions:\n      contents: write\n      pull-requests: write\n      pages: write\n    uses: thoughtbot/templates/.github/workflows/dynamic-security.yaml@main\n    secrets:\n      token: ${{ secrets.GITHUB_TOKEN }}\n"
  },
  {
    "path": ".gitignore",
    "content": ".bundle\n.rubocop-https*\n.yardoc\n.zed\n*.swp\nbin\ncoverage\ntest.db\ntmp\n\n# yard\ndoc\n\n# gem builds\nfactory_bot-*.gem\nfactory_girl-*.gem\n\n# mdBook generated output\ndocs/book\n\n# lock files generated by appraisal\ngemfiles/*.lock\n"
  },
  {
    "path": ".irbrc",
    "content": "def reload!\n  # Undefine FactoryBot so we can reload constants and fresh code\n  Object.send(:remove_const, :FactoryBot) if Object.const_defined?(:FactoryBot)\n\n  # Remove all files from the 'loaded' register\n  $LOADED_FEATURES.delete_if { |path| path.match?(/factory_bot/) }\n\n  # re-load it again\n  require \"factory_bot\"\n  puts \"\\nfactory_bot reloaded!\\n\\n\"\n  true\nend\n"
  },
  {
    "path": ".rspec",
    "content": "--format progress\n--color\n--require spec_helper\n"
  },
  {
    "path": ".simplecov",
    "content": "SimpleCov.start do\n  add_filter \"/spec/\"\n  add_filter \"/tmp/\"\nend\n"
  },
  {
    "path": ".standard.yml",
    "content": "ruby_version: \"3.0\"\nparallel: true\nformat: progress\n"
  },
  {
    "path": ".standard_todo.yml",
    "content": "# Auto generated files with errors to ignore.\n# Remove from this list as you refactor files.\n---\nignore:\n- lib/factory_bot/linter.rb:\n  - Lint/SharedMutableDefault\n"
  },
  {
    "path": ".yardopts",
    "content": "lib/**/*.rb\n-\nGETTING_STARTED.md\nCONTRIBUTING.md\nNAME.md\nLICENSE\n"
  },
  {
    "path": "Appraisals",
    "content": "appraise \"6.1\" do\n  gem \"activerecord\", \"~> 6.1.0\"\n  gem \"activerecord-jdbcsqlite3-adapter\", \"~> 61.0\", platforms: [:jruby]\n  gem \"sqlite3\", \"~> 1.4\", platforms: [:ruby]\n  gem \"concurrent-ruby\", \"< 1.3.5\"\nend\n\nappraise \"7.0\" do\n  gem \"activerecord\", \"~> 7.0.0\"\n  gem \"activerecord-jdbcsqlite3-adapter\", \"~> 70.0\", platforms: [:jruby]\n  gem \"sqlite3\", \"~> 1.4\", platforms: [:ruby]\n  gem \"concurrent-ruby\", \"< 1.3.5\"\nend\n\nappraise \"7.1\" do\n  gem \"activerecord\", \"~> 7.1.0\"\n  # When version 71 is released, uncomment this and also allow it in the GitHub\n  # Action build workflow.\n  # gem \"activerecord-jdbcsqlite3-adapter\", \"~> 71.0\", platforms: [:jruby]\n  gem \"sqlite3\", \"~> 1.4\", platforms: [:ruby]\nend\n\nappraise \"7.2\" do\n  gem \"activerecord\", \"~> 7.2.0\"\n  # When version 71 is released, uncomment this and also allow it in the GitHub\n  # Action build workflow.\n  # gem \"activerecord-jdbcsqlite3-adapter\", \"~> 71.0\", platforms: [:jruby]\n  gem \"sqlite3\", platforms: [:ruby]\nend\n\nappraise \"main\" do\n  gem \"activerecord\", git: \"https://github.com/rails/rails.git\", branch: \"main\"\n  gem \"activerecord-jdbcsqlite3-adapter\", \"~> 70.0\", platforms: [:jruby]\n  gem \"sqlite3\", platforms: [:ruby]\nend\n"
  },
  {
    "path": "CODEOWNERS",
    "content": "# Lines starting with '#' are comments.\n# Each line is a file pattern followed by one or more owners.\n\n# More details are here: https://help.github.com/articles/about-codeowners/\n\n# The '*' pattern is global owners.\n\n# Order is important. The last matching pattern has the most precedence.\n# The folders are ordered as follows:\n\n# In each subsection folders are ordered first by depth, then alphabetically.\n# This should make it easy to add new rules without breaking existing ones.\n\n# Global rule:\n* @neilvcarvalho @vburzynski\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Code of conduct\n\nBy participating in this project, you agree to abide by the\n[thoughtbot code of conduct][1].\n\n[1]: https://thoughtbot.com/open-source-code-of-conduct\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing to Factory Bot\n\nWe love pull requests from everyone. By participating in this project, you\nagree to abide by the thoughtbot [code of conduct].\n\n[code of conduct]: https://thoughtbot.com/open-source-code-of-conduct\n\nHere are some ways *you* can contribute:\n\n* by using alpha, beta, and prerelease versions\n* by reporting bugs\n* by suggesting new features\n* by writing or editing documentation\n* by writing specifications\n* by writing code ( **no patch is too small** : fix typos, add comments, etc. )\n* by refactoring code\n* by closing [issues][]\n* by reviewing patches\n\n[issues]: https://github.com/thoughtbot/factory_bot/issues\n\n## Submitting an Issue\n\n* We use the [GitHub issue tracker][issues] to track bugs and features.\n* Before submitting a bug report or feature request, check to make sure it hasn't\n  already been submitted.\n* When submitting a bug report, please include a [reproduction script] and any\n  other details that may be necessary to reproduce the bug, including your gem\n  version, Ruby version, and operating system.\n\n## Cleaning up issues\n\n* Issues that have no response from the submitter will be closed after 30 days.\n* Issues will be closed once they're assumed to be fixed or answered. If the\n  maintainer is wrong, it can be opened again.\n* If your issue is closed by mistake, please understand and explain the issue.\n  We will happily reopen the issue.\n\n## Submitting a Pull Request\n\n1. [Fork][fork] the [official repository][repo].\n1. [Create a topic branch.][branch]\n1. Implement your feature or bug fix.\n1. Add, commit, and push your changes.\n1. [Submit a pull request.][pr]\n\n### Notes\n\n* Please add tests if you changed code. Contributions without tests won't be accepted.\n* If you don't know how to add tests, please put in a PR and leave a comment\n  asking for help. We love helping!\n* Please don't update the Gem version.\n\n## Setting up\n\n```sh\nbundle install\n```\n\n## Running the test suite\n\nThe default rake task will run the full test suite and [standard]:\n\n```sh\nbundle exec rake\n```\n\nYou can also run a single group of tests (unit, spec, or feature)\n\n```sh\nbundle exec rake spec:unit\nbundle exec rake spec:acceptance\nbundle exec rake features\n```\n\nTo run an individual rspec test, you can provide a path and line number:\n\n```sh\nbundle exec rspec spec/path/to/spec.rb:123\n```\n\nYou can run tests with a specific version of rails via [appraisal]. To run\nthe default rake task against Rails 6, for example:\n\n```sh\nbundle exec appraisal 6.0 rake\n```\n\n## Formatting\n\nUse [standard] to automatically format your code:\n\n```sh\nbundle exec rake standard:fix\n```\n\n[repo]: https://github.com/thoughtbot/factory_bot/tree/main\n[fork]: https://help.github.com/articles/fork-a-repo/\n[branch]: https://help.github.com/articles/creating-and-deleting-branches-within-your-repository/\n[pr]: https://help.github.com/articles/using-pull-requests/\n[standard]: https://github.com/testdouble/standard\n[appraisal]: https://github.com/thoughtbot/appraisal\n[reproduction script]: https://github.com/thoughtbot/factory_bot/blob/main/.github/REPRODUCTION_SCRIPT.rb\n\nInspired by https://github.com/middleman/middleman-heroku/blob/master/CONTRIBUTING.md\n"
  },
  {
    "path": "GETTING_STARTED.md",
    "content": "**Deprecated**\n\nSee our extensive reference, guides, and cookbook in [the factory_bot book][].\n\nFor information on integrations with third party libraries, such as RSpec or\nRails, see [the factory_bot wiki][].\n\n We also have [a detailed introductory video][], available for free on Upcase.\n\n[a detailed introductory video]: https://upcase.com/videos/factory-bot?utm_source=github&utm_medium=open-source&utm_campaign=factory-girl\n[the factory_bot book]: https://thoughtbot.github.io/factory_bot\n[the factory_bot wiki]: https://github.com/thoughtbot/factory_bot/wiki\n\nThis document is deprecated and preserved for historical use. It may disappear\nat any time.\n\nGetting Started\n===============\n\n- [Setup](#setup)\n  - [Update Your Gemfile](#update-your-gemfile)\n  - [Configure your test suite](#configure-your-test-suite)\n    - [RSpec](#rspec)\n    - [Test::Unit](#testunit)\n    - [Cucumber](#cucumber)\n    - [Spinach](#spinach)\n    - [Minitest](#minitest)\n    - [Minitest::Spec](#minitestspec)\n    - [minitest-rails](#minitest-rails)\n- [Defining factories](#defining-factories)\n  - [Factory name and attributes](#factory-name-and-attributes)\n  - [Specifying the class explicitly](#specifying-the-class-explicitly)\n  - [Hash attributes](#hash-attributes)\n  - [Best practices](#best-practices)\n  - [Definition file paths](#definition-file-paths)\n  - [Static Attributes](#static-attributes)\n- [Using factories](#using-factories)\n  - [Build strategies](#build-strategies)\n  - [Attribute overrides](#attribute-overrides)\n  - [build\\_stubbed and Marshal.dump](#build_stubbed-and-marshaldump)\n- [Aliases](#aliases)\n- [Dependent Attributes](#dependent-attributes)\n- [Transient Attributes](#transient-attributes)\n  - [With other attributes](#with-other-attributes)\n  - [With attributes\\_for](#with-attributes_for)\n  - [With callbacks](#with-callbacks)\n  - [With associations](#with-associations)\n- [Method Name / Reserved Word Attributes](#method-name--reserved-word-attributes)\n- [Inheritance](#inheritance)\n  - [Nested factories](#nested-factories)\n  - [Assigning parent explicitly](#assigning-parent-explicitly)\n  - [Best practices](#best-practices-1)\n- [Associations](#associations)\n  - [Implicit definition](#implicit-definition)\n  - [Explicit definition](#explicit-definition)\n  - [Inline definition](#inline-definition)\n  - [Specifying the factory](#specifying-the-factory)\n  - [Overriding attributes](#overriding-attributes)\n  - [Association overrides](#association-overrides)\n  - [Build strategies](#build-strategies-1)\n  - [has\\_many associations](#has_many-associations)\n  - [has\\_and\\_belongs\\_to\\_many associations](#has_and_belongs_to_many-associations)\n  - [Polymorphic associations](#polymorphic-associations)\n  - [Interconnected associations](#interconnected-associations)\n- [Sequences](#sequences)\n  - [Global sequences](#global-sequences)\n  - [With dynamic attributes](#with-dynamic-attributes)\n  - [As implicit attributes](#as-implicit-attributes)\n  - [Inline sequences](#inline-sequences)\n  - [Initial value](#initial-value)\n  - [Without a block](#without-a-block)\n  - [Aliases](#aliases-1)\n  - [Rewinding](#rewinding)\n  - [Uniqueness](#uniqueness)\n- [Traits](#traits)\n  - [Defining traits](#defining-traits)\n  - [As implicit attributes](#as-implicit-attributes-1)\n  - [Attribute precedence](#attribute-precedence)\n  - [In child factories](#in-child-factories)\n  - [As mixins](#as-mixins)\n  - [Using traits](#using-traits)\n  - [With associations](#with-associations-1)\n  - [Traits within traits](#traits-within-traits)\n  - [With transient attributes](#with-transient-attributes)\n  - [Enum traits](#enum-traits)\n- [Callbacks](#callbacks)\n  - [Default callbacks](#default-callbacks)\n  - [Multiple callbacks](#multiple-callbacks)\n  - [Global callbacks](#global-callbacks)\n  - [Symbol#to\\_proc](#symbolto_proc)\n- [Modifying factories](#modifying-factories)\n- [Building or Creating Multiple Records](#building-or-creating-multiple-records)\n- [Linting Factories](#linting-factories)\n- [Custom Construction](#custom-construction)\n- [Custom Strategies](#custom-strategies)\n- [Custom Callbacks](#custom-callbacks)\n- [Custom Methods to Persist Objects](#custom-methods-to-persist-objects)\n- [ActiveSupport Instrumentation](#activesupport-instrumentation)\n- [Rails Preloaders and RSpec](#rails-preloaders-and-rspec)\n- [Using Without Bundler](#using-without-bundler)\n\nSetup\n-----\n\n### Update Your Gemfile\n\nIf you're using Rails:\n\n```ruby\ngem \"factory_bot_rails\"\n```\n\nIf you're *not* using Rails:\n\n```ruby\ngem \"factory_bot\"\n```\n\n### Configure your test suite\n\n#### RSpec\n\nIf you're using Rails, add the following configuration to\n`spec/support/factory_bot.rb` and be sure to require that file in\n`rails_helper.rb`:\n\n```ruby\nRSpec.configure do |config|\n  config.include FactoryBot::Syntax::Methods\nend\n```\n\nIf you're *not* using Rails:\n\n```ruby\nRSpec.configure do |config|\n  config.include FactoryBot::Syntax::Methods\n\n  config.before(:suite) do\n    FactoryBot.find_definitions\n  end\nend\n```\n\n#### Test::Unit\n\n```ruby\nclass Test::Unit::TestCase\n  include FactoryBot::Syntax::Methods\nend\n```\n\n#### Cucumber\n\n```ruby\n# env.rb (Rails example location - RAILS_ROOT/features/support/env.rb)\nWorld(FactoryBot::Syntax::Methods)\n```\n\n#### Spinach\n\n```ruby\nclass Spinach::FeatureSteps\n  include FactoryBot::Syntax::Methods\nend\n```\n\n#### Minitest\n\n```ruby\nclass Minitest::Unit::TestCase\n  include FactoryBot::Syntax::Methods\nend\n```\n\n#### Minitest::Spec\n\n```ruby\nclass Minitest::Spec\n  include FactoryBot::Syntax::Methods\nend\n```\n\n#### minitest-rails\n\n```ruby\nclass ActiveSupport::TestCase\n  include FactoryBot::Syntax::Methods\nend\n```\n\nIf you do not include `FactoryBot::Syntax::Methods` in your test suite, then all\nfactory\\_bot methods will need to be prefaced with `FactoryBot`.\n\nDefining factories\n------------------\n\n### Factory name and attributes\n\nEach factory has a name and a set of attributes. The name is used to guess the\nclass of the object by default:\n\n```ruby\n# This will guess the User class\nFactoryBot.define do\n  factory :user do\n    first_name { \"John\" }\n    last_name  { \"Doe\" }\n    admin { false }\n  end\nend\n```\n\n### Specifying the class explicitly\n\nIt is also possible to explicitly specify the class:\n\n```ruby\n# This will use the User class (otherwise Admin would have been guessed)\nfactory :admin, class: \"User\"\n```\n\nExplicit specification of the class, _with the full namespace_, is necessary when defining factories for classes nested within other modules or classes:\n\n```ruby\n# foo/bar.rb\nmodule Foo\n  class Bar\n    ...\n  end\nend\n\n# factories.rb\nFactoryBot.define do\n  factory :bar, class: 'Foo::Bar' do\n    ...\n  end\nend\n```\n\nIf the full namespace is not provided in the `factory` statement, you will receive a `NameError: uninitialized constant Bar` error.\n\nYou can pass a constant as well, if the constant is available (note that this\ncan cause test performance problems in large Rails applications, since\nreferring to the constant will cause it to be eagerly loaded).\n\n```ruby\nfactory :access_token, class: User\n```\n\n### Hash attributes\n\nBecause of the block syntax in Ruby, defining attributes as `Hash`es (for\nserialized/JSON columns, for example) requires two sets of curly brackets:\n\n```ruby\nfactory :program do\n  configuration { { auto_resolve: false, auto_define: true } }\nend\n```\n\n### Best practices\n\nIt is recommended that you have one factory for each class that provides\nthe simplest set of attributes necessary to create an instance of that class. If\nyou're creating ActiveRecord objects, that means that you should only provide\nattributes that are required through validations and that do not have defaults.\nOther factories can be created through inheritance to cover common scenarios for\neach class.\n\nAttempting to define multiple factories with the same name will raise an error.\n\n### Definition file paths\n\nFactories can be defined anywhere, but will be automatically loaded after\ncalling `FactoryBot.find_definitions` if factories are defined in files at the\nfollowing locations:\n\n    factories.rb\n    factories/**/*.rb\n    test/factories.rb\n    test/factories/**/*.rb\n    spec/factories.rb\n    spec/factories/**/*.rb\n\n### Static Attributes\n\nStatic attributes (without a block) are no longer available in factory\\_bot 5.\nYou can read more about the decision to remove them in\n[this blog post](https://robots.thoughtbot.com/deprecating-static-attributes-in-factory_bot-4-11).\n\n\nUsing factories\n---------------\n\n### Build strategies\n\nfactory\\_bot supports several different build strategies: build, create,\nattributes\\_for and build\\_stubbed:\n\n```ruby\n# Returns a User instance that's not saved\nuser = build(:user)\n\n# Returns a saved User instance\nuser = create(:user)\n\n# Returns a hash of attributes that can be used to build a User instance\nattrs = attributes_for(:user)\n\n# Integrates with Ruby 3.0's support for pattern matching assignment\nattributes_for(:user) => {email:, name:, **attrs}\n\n# Returns an object with all defined attributes stubbed out\nstub = build_stubbed(:user)\n\n# Passing a block to any of the methods above will yield the return object\ncreate(:user) do |user|\n  user.posts.create(attributes_for(:post))\nend\n```\n\n### Attribute overrides\n\nNo matter which strategy is used, it's possible to override the defined\nattributes by passing a Hash:\n\n```ruby\n# Build a User instance and override the first_name property\nuser = build(:user, first_name: \"Joe\")\nuser.first_name\n# => \"Joe\"\n```\n\nOverriding associations is also supported:\n\n```ruby\naccount = build(:account, :deluxe)\nfriends = build_list(:user, 2)\n\nuser = build(:user, account: account, friends: friends)\n```\n\nRuby 3.1's support for [omitting values][] from `Hash` literals dovetails with\nattribute overrides and provides an opportunity to limit the repetition of\nvariable names:\n\n```ruby\naccount = build(:account, :deluxe)\nfriends = build_list(:user, 2)\n\n# The keyword arguments correspond to local variable names, so omit their values\nuser = build(:user, account:, friends:)\n```\n\n[omitting values]: https://docs.ruby-lang.org/en/3.1/syntax/literals_rdoc.html#label-Hash+Literals\n\n### build_stubbed and Marshal.dump\n\nNote that objects created with `build_stubbed` cannot be serialized with\n`Marshal.dump`, since factory\\_bot defines singleton methods on these objects.\n\nAliases\n-------\n\nfactory\\_bot allows you to define aliases to existing factories to make them\neasier to re-use. This could come in handy when, for example, your Post object\nhas an author attribute that actually refers to an instance of a User class.\nWhile normally factory\\_bot can infer the factory name from the association name,\nin this case it will look for an author factory in vain. So, alias your user\nfactory so it can be used under alias names.\n\n```ruby\nfactory :user, aliases: [:author, :commenter] do\n  first_name { \"John\" }\n  last_name { \"Doe\" }\n  date_of_birth { 18.years.ago }\nend\n\nfactory :post do\n  # The alias allows us to write author instead of\n  # association :author, factory: :user\n  author\n  title { \"How to read a book effectively\" }\n  body { \"There are five steps involved.\" }\nend\n\nfactory :comment do\n  # The alias allows us to write commenter instead of\n  # association :commenter, factory: :user\n  commenter\n  body { \"Great article!\" }\nend\n```\n\nDependent Attributes\n--------------------\n\nAttributes can be based on the values of other attributes using the evaluator\nthat is yielded to dynamic attribute blocks:\n\n```ruby\nfactory :user do\n  first_name { \"Joe\" }\n  last_name  { \"Blow\" }\n  email { \"#{first_name}.#{last_name}@example.com\".downcase }\nend\n\ncreate(:user, last_name: \"Doe\").email\n# => \"joe.doe@example.com\"\n```\n\nTransient Attributes\n--------------------\nTransient attributes are attributes only available within the factory definition, and not set on the object being built. This allows for more complex logic inside factories.\n\n### With other attributes\n\nThere may be times where your code can be DRYed up by passing in transient\nattributes to factories. You can access transient attributes within other\nattributes (see [Dependent Attributes](#dependent-attributes)):\n\n```ruby\nfactory :user do\n  transient do\n    rockstar { true }\n  end\n\n  name { \"John Doe#{\" - Rockstar\" if rockstar}\" }\nend\n\ncreate(:user).name\n#=> \"John Doe - ROCKSTAR\"\n\ncreate(:user, rockstar: false).name\n#=> \"John Doe\"\n```\n\n### With attributes_for\n\nTransient attributes will be ignored within attributes\\_for and won't be set on\nthe model, even if the attribute exists or you attempt to override it.\n\n### With callbacks\n\nIf you need to access the evaluator in a factory\\_bot callback,\nyou'll need to declare a second block argument (for the evaluator) and access\ntransient attributes from there.\n\n```ruby\nfactory :user do\n  transient do\n    upcased { false }\n  end\n\n  name { \"John Doe\" }\n\n  after(:create) do |user, evaluator|\n    user.name.upcase! if evaluator.upcased\n  end\nend\n\ncreate(:user).name\n#=> \"John Doe\"\n\ncreate(:user, upcased: true).name\n#=> \"JOHN DOE\"\n```\n\n### With associations\n\nTransient [associations](#associations) are not supported in factory\\_bot.\nAssociations within the transient block will be treated as regular,\nnon-transient associations.\n\nIf needed, you can generally work around this by building a factory within a\ntransient attribute:\n\n```ruby\nfactory :post\n\nfactory :user do\n  transient do\n    post { build(:post) }\n  end\nend\n```\n\nMethod Name / Reserved Word Attributes\n-------------------------------\n\nIf your attributes conflict with existing methods or reserved words (all methods in the [DefinitionProxy](https://github.com/thoughtbot/factory_bot/blob/main/lib/factory_bot/definition_proxy.rb) class) you can define them with `add_attribute`.\n\n```ruby\nfactory :dna do\n  add_attribute(:sequence) { 'GATTACA' }\nend\n\nfactory :payment do\n  add_attribute(:method) { 'paypal' }\nend\n\n```\n\nInheritance\n-----------\n\n### Nested factories\n\nYou can easily create multiple factories for the same class without repeating\ncommon attributes by nesting factories:\n\n```ruby\nfactory :post do\n  title { \"A title\" }\n\n  factory :approved_post do\n    approved { true }\n  end\nend\n\napproved_post = create(:approved_post)\napproved_post.title    # => \"A title\"\napproved_post.approved # => true\n```\n\n### Assigning parent explicitly\n\nYou can also assign the parent explicitly:\n\n```ruby\nfactory :post do\n  title { \"A title\" }\nend\n\nfactory :approved_post, parent: :post do\n  approved { true }\nend\n```\n\n### Best practices\n\nAs mentioned above, it's good practice to define a basic factory for each class\nwith only the attributes required to create it. Then, create more specific\nfactories that inherit from this basic parent. Factory definitions are still\ncode, so keep them DRY.\n\nAssociations\n------------\n\n### Implicit definition\n\nIt's possible to set up associations within factories. If the factory name is\nthe same as the association name, the factory name can be left out.\n\n```ruby\nfactory :post do\n  # ...\n  author\nend\n```\n\n### Explicit definition\n\nYou can define associations explicitly. This can be handy especially when\n[Overriding attributes](#overriding-attributes)\n\n```ruby\nfactory :post do\n  # ...\n  association :author\nend\n```\n\n### Inline definition\n\nYou can also define associations inline within regular attributes,\nbut note that the value will be `nil`\nwhen using the `attributes_for` strategy.\n\n```ruby\nfactory :post do\n  # ...\n  author { association :author }\nend\n```\n\n### Specifying the factory\n\nYou can specify a different factory (although [Aliases](#aliases) might also\nhelp you out here).\n\nImplicitly:\n\n```ruby\nfactory :post do\n  # ...\n  author factory: :user\nend\n```\n\nExplicitly:\n\n```ruby\nfactory :post do\n  # ...\n  association :author, factory: :user\nend\n```\n\nInline:\n\n```ruby\nfactory :post do\n  # ...\n  author { association :user }\nend\n```\n\n### Overriding attributes\n\nYou can also override attributes.\n\nImplicitly:\n\n```ruby\nfactory :post do\n  # ...\n  author factory: :author, last_name: \"Writely\"\nend\n```\n\nExplicitly:\n\n\n```ruby\nfactory :post do\n  # ...\n  association :author, last_name: \"Writely\"\nend\n```\n\nOr inline using attributes from the factory:\n\n```ruby\nfactory :post do\n  # ...\n  author_last_name { \"Writely\" }\n  author { association :author, last_name: author_last_name }\nend\n```\n\n### Association overrides\n\nAttribute overrides can be used to link associated objects:\n\n```ruby\nFactoryBot.define do\n  factory :author do\n    name { 'Taylor' }\n  end\n\n  factory :post do\n    author\n  end\nend\n\neunji = build(:author, name: 'Eunji')\npost = build(:post, author: eunji)\n```\n\n### Build strategies\n\nIn factory\\_bot 5, associations default to using the same build strategy as\ntheir parent object:\n\n```ruby\nFactoryBot.define do\n  factory :author\n\n  factory :post do\n    author\n  end\nend\n\npost = build(:post)\npost.new_record?        # => true\npost.author.new_record? # => true\n\npost = create(:post)\npost.new_record?        # => false\npost.author.new_record? # => false\n```\n\nThis is different than the default behavior for previous versions of\nfactory\\_bot, where the association strategy would not always match the strategy\nof the parent object. If you want to continue using the old behavior, you can\nset the `use_parent_strategy` configuration option to `false`.\n\n```ruby\nFactoryBot.use_parent_strategy = false\n\n# Builds and saves a User and a Post\npost = create(:post)\npost.new_record?        # => false\npost.author.new_record? # => false\n\n# Builds and saves a User, and then builds but does not save a Post\npost = build(:post)\npost.new_record?        # => true\npost.author.new_record? # => false\n```\n\nTo not save the associated object, specify `strategy: :build` in the factory:\n\n```ruby\nFactoryBot.use_parent_strategy = false\n\nfactory :post do\n  # ...\n  association :author, factory: :user, strategy: :build\nend\n\n# Builds a User, and then builds a Post, but does not save either\npost = build(:post)\npost.new_record?        # => true\npost.author.new_record? # => true\n```\n\nPlease note that the `strategy: :build` option must be passed to an explicit call to `association`,\nand cannot be used with implicit associations:\n\n```ruby\nfactory :post do\n  # ...\n  author strategy: :build    # <<< this does *not* work; causes author_id to be nil\n```\n\n### has_many associations\n\nThere are a few ways to generate data for a `has_many` relationship. The\nsimplest approach is to write a helper method in plain Ruby to tie together the\ndifferent records:\n\n```ruby\nFactoryBot.define do\n  factory :post do\n    title { \"Through the Looking Glass\" }\n    user\n  end\n\n  factory :user do\n    name { \"Rachel Sanchez\" }\n  end\nend\n\ndef user_with_posts(posts_count: 5)\n  FactoryBot.create(:user) do |user|\n    FactoryBot.create_list(:post, posts_count, user: user)\n  end\nend\n\ncreate(:user).posts.length # 0\nuser_with_posts.posts.length # 5\nuser_with_posts(posts_count: 15).posts.length # 15\n```\n\nIf you prefer to keep the object creation fully within factory\\_bot, you can\nbuild the posts in an `after(:create)` callback.\n\n\n```ruby\nFactoryBot.define do\n  factory :post do\n    title { \"Through the Looking Glass\" }\n    user\n  end\n\n  factory :user do\n    name { \"John Doe\" }\n\n    # user_with_posts will create post data after the user has been created\n    factory :user_with_posts do\n      # posts_count is declared as a transient attribute available in the\n      # callback via the evaluator\n      transient do\n        posts_count { 5 }\n      end\n\n      # the after(:create) yields two values; the user instance itself and the\n      # evaluator, which stores all values from the factory, including transient\n      # attributes; `create_list`'s second argument is the number of records\n      # to create and we make sure the user is associated properly to the post\n      after(:create) do |user, evaluator|\n        create_list(:post, evaluator.posts_count, user: user)\n\n        # You may need to reload the record here, depending on your application\n        user.reload\n      end\n    end\n  end\nend\n\ncreate(:user).posts.length # 0\ncreate(:user_with_posts).posts.length # 5\ncreate(:user_with_posts, posts_count: 15).posts.length # 15\n```\n\nOr, for a solution that works with `build`, `build_stubbed`, and `create`\n(although it doesn't work well with `attributes_for`), you can use inline\nassociations:\n\n```ruby\nFactoryBot.define do\n  factory :post do\n    title { \"Through the Looking Glass\" }\n    user\n  end\n\n  factory :user do\n    name { \"Taylor Kim\" }\n\n    factory :user_with_posts do\n      posts { [association(:post)] }\n    end\n  end\nend\n\ncreate(:user).posts.length # 0\ncreate(:user_with_posts).posts.length # 1\nbuild(:user_with_posts).posts.length # 1\nbuild_stubbed(:user_with_posts).posts.length # 1\n```\n\nFor more flexibility you can combine this with the `posts_count` transient\nattribute from the callback example:\n\n```ruby\nFactoryBot.define do\n  factory :post do\n    title { \"Through the Looking Glass\" }\n    user\n  end\n\n  factory :user do\n    name { \"Adiza Kumato\" }\n\n    factory :user_with_posts do\n      transient do\n        posts_count { 5 }\n      end\n\n      posts do\n        Array.new(posts_count) { association(:post) }\n      end\n    end\n  end\nend\n\ncreate(:user_with_posts).posts.length # 5\ncreate(:user_with_posts, posts_count: 15).posts.length # 15\nbuild(:user_with_posts, posts_count: 15).posts.length # 15\nbuild_stubbed(:user_with_posts, posts_count: 15).posts.length # 15\n```\n\n### has_and_belongs_to_many associations\n\nGenerating data for a `has_and_belongs_to_many` relationship is very similar\nto the above `has_many` relationship, with a small change: you need to pass an\narray of objects to the model's pluralized attribute name rather than a single\nobject to the singular version of the attribute name.\n\n\n```ruby\ndef profile_with_languages(languages_count: 2)\n  FactoryBot.create(:profile) do |profile|\n    FactoryBot.create_list(:language, languages_count, profiles: [profile])\n  end\nend\n```\n\nOr with the callback approach:\n\n```ruby\nfactory :profile_with_languages do\n  transient do\n    languages_count { 2 }\n  end\n\n  after(:create) do |profile, evaluator|\n    create_list(:language, evaluator.languages_count, profiles: [profile])\n    profile.reload\n  end\nend\n```\n\nOr the inline association approach (note the use of the `instance` method here\nto refer to the profile being built):\n\n```ruby\nfactory :profile_with_languages do\n  transient do\n    languages_count { 2 }\n  end\n\n  languages do\n    Array.new(languages_count) do\n      association(:language, profiles: [instance])\n    end\n  end\nend\n```\n\n### Polymorphic associations\n\nPolymorphic associations can be handled with traits:\n\n```ruby\nFactoryBot.define do\n  factory :video\n  factory :photo\n\n  factory :comment do\n    for_photo # default to the :for_photo trait if none is specified\n\n    trait :for_video do\n      association :commentable, factory: :video\n    end\n\n    trait :for_photo do\n      association :commentable, factory: :photo\n    end\n  end\nend\n```\n\nThis allows us to do:\n\n```ruby\ncreate(:comment)\ncreate(:comment, :for_video)\ncreate(:comment, :for_photo)\n```\n\n### Interconnected associations\n\nThere are limitless ways objects might be interconnected, and\nfactory\\_bot may not always be suited to handle those relationships. In some\ncases it makes sense to use factory\\_bot to build each individual object, and\nthen to write helper methods in plain Ruby to tie those objects together.\n\nThat said, some more complex, interconnected relationships can be built in factory\\_bot\nusing inline associations with reference to the `instance` being built.\n\nLet's say your models look like this, where an associated `Student` and\n`Profile` should both belong to the same `School`:\n\n```ruby\nclass Student < ApplicationRecord\n  belongs_to :school\n  has_one :profile\nend\n\nclass Profile < ApplicationRecord\n  belongs_to :school\n  belongs_to :student\nend\n\nclass School < ApplicationRecord\n  has_many :students\n  has_many :profiles\nend\n```\n\nWe can ensure the student and profile are connected to each other and to the\nsame school with a factory like this:\n\n```ruby\nFactoryBot.define do\n  factory :student do\n    school\n    profile { association :profile, student: instance, school: school }\n  end\n\n  factory :profile do\n    school\n    student { association :student, profile: instance, school: school }\n  end\n\n  factory :school\nend\n```\n\nNote that this approach works with `build`, `build_stubbed`, and `create`, but\nthe associations will return `nil` when using `attributes_for`.\n\nAlso, note that if you assign any attributes inside a custom `initialize_with`\n(e.g. `initialize_with { new(**attributes) }`), those attributes should not refer to `instance`,\nsince it will be `nil`.\n\nSequences\n---------\n\n### Global sequences\n\nUnique values in a specific format (for example, e-mail addresses) can be\ngenerated using sequences. Sequences are defined by calling `sequence` in a\ndefinition block, and values in a sequence are generated by calling\n`generate`:\n\n```ruby\n# Defines a new sequence\nFactoryBot.define do\n  sequence :email do |n|\n    \"person#{n}@example.com\"\n  end\nend\n\ngenerate :email\n# => \"person1@example.com\"\n\ngenerate :email\n# => \"person2@example.com\"\n```\n\n### With dynamic attributes\n\nSequences can be used in dynamic attributes:\n\n```ruby\nfactory :invite do\n  invitee { generate(:email) }\nend\n```\n\n### As implicit attributes\n\nOr as implicit attributes:\n\n```ruby\nfactory :user do\n  email # Same as `email { generate(:email) }`\nend\n```\n\nNote that defining sequences as implicit attributes will not work if you have a\nfactory with the same name as the sequence.\n\n### Inline sequences\n\nAnd it's also possible to define an in-line sequence that is only used in\na particular factory:\n\n```ruby\nfactory :user do\n  sequence(:email) { |n| \"person#{n}@example.com\" }\nend\n```\n\nWith Ruby 2.7's support for [numbered parameters][], inline definitions can be\neven more abbreviated:\n\n```ruby\nfactory :user do\n  sequence(:email) { \"person#{_1}@example.com\" }\nend\n```\n\n[numbered parameters]: https://ruby-doc.org/core-2.7.1/Proc.html#class-Proc-label-Numbered+parameters\n\n### Initial value\n\nYou can override the initial value. Any value that responds to the `#next`\nmethod will work (e.g. 1, 2, 3, 'a', 'b', 'c')\n\n```ruby\nfactory :user do\n  sequence(:email, 1000) { |n| \"person#{n}@example.com\" }\nend\n```\n\n### Without a block\n\nWithout a block, the value will increment itself, starting at its initial value:\n\n```ruby\nfactory :post do\n  sequence(:position)\nend\n```\n\nPlease note, that the value for the sequence could be any Enumerable instance,\nas long as it responds to `#next`:\n\n```ruby\nfactory :task do\n  sequence :priority, %i[low medium high urgent].cycle\nend\n```\n\n### Aliases\n\nSequences can also have aliases. The sequence aliases share the same counter:\n\n```ruby\nfactory :user do\n  sequence(:email, 1000, aliases: [:sender, :receiver]) { |n| \"person#{n}@example.com\" }\nend\n\n# will increase value counter for :email which is shared by :sender and :receiver\ngenerate(:sender)\n```\n\nDefine aliases and use default value (1) for the counter\n\n```ruby\nfactory :user do\n  sequence(:email, aliases: [:sender, :receiver]) { |n| \"person#{n}@example.com\" }\nend\n```\n\nSetting the value:\n\n```ruby\nfactory :user do\n  sequence(:email, 'a', aliases: [:sender, :receiver]) { |n| \"person#{n}@example.com\" }\nend\n```\n\nThe value just needs to support the `#next` method. Here the next value will be 'a', then 'b', etc.\n\n### Rewinding\n\nSequences can also be rewound with `FactoryBot.rewind_sequences`:\n\n```ruby\nsequence(:email) {|n| \"person#{n}@example.com\" }\n\ngenerate(:email) # \"person1@example.com\"\ngenerate(:email) # \"person2@example.com\"\ngenerate(:email) # \"person3@example.com\"\n\nFactoryBot.rewind_sequences\n\ngenerate(:email) # \"person1@example.com\"\n```\n\nThis rewinds all registered sequences.\n\n### Uniqueness\n\nWhen working with uniqueness constraints, be careful not to pass in override values that will conflict with the generated sequence values.\n\nIn this example the email will be the same for both users. If email must be unique, this code will error:\n\n```ruby\nfactory :user do\n  sequence(:email) { |n| \"person#{n}@example.com\" }\nend\n\nFactoryBot.create(:user, email: \"person1@example.com\")\nFactoryBot.create(:user)\n```\n\n\nTraits\n------\n\n### Defining traits\n\nTraits allow you to group attributes together and then apply them\nto any factory.\n\n```ruby\nfactory :user, aliases: [:author]\n\nfactory :story do\n  title { \"My awesome story\" }\n  author\n\n  trait :published do\n    published { true }\n  end\n\n  trait :unpublished do\n    published { false }\n  end\n\n  trait :week_long_publishing do\n    start_at { 1.week.ago }\n    end_at { Time.now }\n  end\n\n  trait :month_long_publishing do\n    start_at { 1.month.ago }\n    end_at { Time.now }\n  end\n\n  factory :week_long_published_story,    traits: [:published, :week_long_publishing]\n  factory :month_long_published_story,   traits: [:published, :month_long_publishing]\n  factory :week_long_unpublished_story,  traits: [:unpublished, :week_long_publishing]\n  factory :month_long_unpublished_story, traits: [:unpublished, :month_long_publishing]\nend\n```\n\n### As implicit attributes\n\nTraits can be used as implicit attributes:\n\n```ruby\nfactory :week_long_published_story_with_title, parent: :story do\n  published\n  week_long_publishing\n  title { \"Publishing that was started at #{start_at}\" }\nend\n```\n\nNote that defining traits as implicit attributes will not work if you have a\nfactory or sequence with the same name as the trait.\n\n### Attribute precedence\n\nTraits that define the same attributes won't raise AttributeDefinitionErrors;\nthe trait that defines the attribute latest gets precedence.\n\n```ruby\nfactory :user do\n  name { \"Friendly User\" }\n  login { name }\n\n  trait :active do\n    name { \"John Doe\" }\n    status { :active }\n    login { \"#{name} (active)\" }\n  end\n\n  trait :inactive do\n    name { \"Jane Doe\" }\n    status { :inactive }\n    login { \"#{name} (inactive)\" }\n  end\n\n  trait :admin do\n    admin { true }\n    login { \"admin-#{name}\" }\n  end\n\n  factory :active_admin,   traits: [:active, :admin]   # login will be \"admin-John Doe\"\n  factory :inactive_admin, traits: [:admin, :inactive] # login will be \"Jane Doe (inactive)\"\nend\n```\n\n### In child factories\n\nYou can override individual attributes granted by a trait in a child factory:\n\n```ruby\nfactory :user do\n  name { \"Friendly User\" }\n  login { name }\n\n  trait :active do\n    name { \"John Doe\" }\n    status { :active }\n    login { \"#{name} (M)\" }\n  end\n\n  factory :brandon do\n    active\n    name { \"Brandon\" }\n  end\nend\n```\n\n### As mixins\n\nTraits can be defined outside of factories and used as mixins to compose shared attributes\n\n```ruby\nFactoryBot.define do\n  trait :timestamps do\n    created_at { 8.days.ago }\n    updated_at { 4.days.ago }\n  end\n\n  factory :user, traits: [:timestamps] do\n    username { \"john_doe\" }\n  end\n\n  factory :post do\n    timestamps\n    title { \"Traits rock\" }\n  end\nend\n```\n\n### Using traits\n\nTraits can also be passed in as a list of symbols when you construct an instance\nfrom factory\\_bot.\n\n```ruby\nfactory :user do\n  name { \"Friendly User\" }\n\n  trait :active do\n    name { \"John Doe\" }\n    status { :active }\n  end\n\n  trait :admin do\n    admin { true }\n  end\nend\n\n# creates an admin user with :active status and name \"Jon Snow\"\ncreate(:user, :admin, :active, name: \"Jon Snow\")\n```\n\nThis ability works with `build`, `build_stubbed`, `attributes_for`, and `create`.\n\n`create_list` and `build_list` methods are supported as well. Just remember to pass\nthe number of instances to create/build as second parameter, as documented in the\n\"Building or Creating Multiple Records\" section of this file.\n\n```ruby\nfactory :user do\n  name { \"Friendly User\" }\n\n  trait :admin do\n    admin { true }\n  end\nend\n\n# creates 3 admin users with :active status and name \"Jon Snow\"\ncreate_list(:user, 3, :admin, :active, name: \"Jon Snow\")\n```\n\n### With associations\n\nTraits can be used with associations easily too:\n\n```ruby\nfactory :user do\n  name { \"Friendly User\" }\n\n  trait :admin do\n    admin { true }\n  end\nend\n\nfactory :post do\n  association :user, :admin, name: 'John Doe'\nend\n\n# creates an admin user with name \"John Doe\"\ncreate(:post).user\n```\n\nWhen you're using association names that're different than the factory:\n\n```ruby\nfactory :user do\n  name { \"Friendly User\" }\n\n  trait :admin do\n    admin { true }\n  end\nend\n\nfactory :post do\n  association :author, :admin, factory: :user, name: 'John Doe'\n  # or\n  association :author, factory: [:user, :admin], name: 'John Doe'\nend\n\n# creates an admin user with name \"John Doe\"\ncreate(:post).author\n```\n\n### Traits within traits\n\nTraits can be used within other traits to mix in their attributes.\n\n```ruby\nfactory :order do\n  trait :completed do\n    completed_at { 3.days.ago }\n  end\n\n  trait :refunded do\n    completed\n    refunded_at { 1.day.ago }\n  end\nend\n```\n\n### With transient attributes\n\nFinally, traits can accept transient attributes.\n\n```ruby\nfactory :invoice do\n  trait :with_amount do\n    transient do\n      amount { 1 }\n    end\n\n    after(:create) do |invoice, evaluator|\n      create :line_item, invoice: invoice, amount: evaluator.amount\n    end\n  end\nend\n\ncreate :invoice, :with_amount, amount: 2\n```\n\n### Enum traits\n\nGiven an Active Record model with an enum attribute:\n\n```ruby\nclass Task < ActiveRecord::Base\n  enum status: {queued: 0, started: 1, finished: 2}\nend\n\n```\n\nfactory\\_bot will automatically define traits for each possible value of the\nenum:\n\n```ruby\nFactoryBot.define do\n  factory :task\nend\n\nFactoryBot.build(:task, :queued)\nFactoryBot.build(:task, :started)\nFactoryBot.build(:task, :finished)\n```\n\nWriting the traits out manually would be cumbersome, and is not necessary:\n\n```ruby\nFactoryBot.define do\n  factory :task do\n    trait :queued do\n      status { :queued }\n    end\n\n    trait :started do\n      status { :started }\n    end\n\n    trait :finished do\n      status { :finished }\n    end\n  end\nend\n```\n\nIf automatically defining traits for enum attributes on every factory is not\ndesired, it is possible to disable the feature by setting\n`FactoryBot.automatically_define_enum_traits = false`\n\nIn that case, it is still possible to explicitly define traits for an enum\nattribute in a particular factory:\n\n```ruby\nFactoryBot.automatically_define_enum_traits = false\n\nFactoryBot.define do\n  factory :task do\n    traits_for_enum(:status)\n  end\nend\n```\n\nIt is also possible to use this feature for other enumerable values, not\nspecifically tied to Active Record enum attributes.\n\nWith an array:\n\n```ruby\nclass Task\n  attr_accessor :status\nend\n\nFactoryBot.define do\n  factory :task do\n    traits_for_enum(:status, [\"queued\", \"started\", \"finished\"])\n  end\nend\n```\n\nOr with a hash:\n\n```ruby\nclass Task\n  attr_accessor :status\nend\n\nFactoryBot.define do\n  factory :task do\n    traits_for_enum(:status, { queued: 0, started: 1, finished: 2 })\n  end\nend\n```\n\nCallbacks\n---------\n\n### Default callbacks\n\nfactory\\_bot makes available four callbacks for injecting some code:\n\n* after(:build)   - called after a factory is built   (via `FactoryBot.build`, `FactoryBot.create`)\n* before(:create) - called before a factory is saved  (via `FactoryBot.create`)\n* after(:create)  - called after a factory is saved   (via `FactoryBot.create`)\n* after(:stub)    - called after a factory is stubbed (via `FactoryBot.build_stubbed`)\n\nExamples:\n\n```ruby\n# Define a factory that calls the generate_hashed_password method after it is built\nfactory :user do\n  after(:build) { |user| generate_hashed_password(user) }\nend\n```\n\nNote that you'll have an instance of the user in the block. This can be useful.\n\n### Multiple callbacks\n\nYou can also define multiple types of callbacks on the same factory:\n\n```ruby\nfactory :user do\n  after(:build)  { |user| do_something_to(user) }\n  after(:create) { |user| do_something_else_to(user) }\nend\n```\n\nFactories can also define any number of the same kind of callback.  These\ncallbacks will be executed in the order they are specified:\n\n```ruby\nfactory :user do\n  after(:create) { this_runs_first }\n  after(:create) { then_this }\nend\n```\n\nCalling `create` will invoke both `after_build` and `after_create` callbacks.\n\nAlso, like standard attributes, child factories will inherit (and can also\ndefine) callbacks from their parent factory.\n\nMultiple callbacks can be assigned to run a block; this is useful when building\nvarious strategies that run the same code (since there are no callbacks that are\nshared across all strategies).\n\n```ruby\nfactory :user do\n  callback(:after_stub, :before_create) { do_something }\n  after(:stub, :create) { do_something_else }\n  before(:create, :custom) { do_a_third_thing }\nend\n```\n\n### Global callbacks\n\nTo override callbacks for all factories, define them within the\n`FactoryBot.define` block:\n\n```ruby\nFactoryBot.define do\n  after(:build) { |object| puts \"Built #{object}\" }\n  after(:create) { |object| AuditLog.create(attrs: object.attributes) }\n\n  factory :user do\n    name { \"John Doe\" }\n  end\nend\n```\n\n### Symbol#to_proc\n\nYou can call callbacks that rely on `Symbol#to_proc`:\n\n```ruby\n# app/models/user.rb\nclass User < ActiveRecord::Base\n  def confirm!\n    # confirm the user account\n  end\nend\n\n# spec/factories.rb\nFactoryBot.define do\n  factory :user do\n    after :create, &:confirm!\n  end\nend\n\ncreate(:user) # creates the user and confirms it\n```\n\nModifying factories\n-------------------\n\nIf you're given a set of factories (say, from a gem developer) but want to\nchange them to fit into your application better, you can modify that factory\ninstead of creating a child factory and adding attributes there.\n\nIf a gem were to give you a User factory:\n\n```ruby\nFactoryBot.define do\n  factory :user do\n    full_name { \"John Doe\" }\n    sequence(:username) { |n| \"user#{n}\" }\n    password { \"password\" }\n  end\nend\n```\n\nInstead of creating a child factory that added additional attributes:\n\n```ruby\nFactoryBot.define do\n  factory :application_user, parent: :user do\n    full_name { \"Jane Doe\" }\n    date_of_birth { 21.years.ago }\n    health { 90 }\n  end\nend\n```\n\nYou could modify that factory instead.\n\n```ruby\nFactoryBot.modify do\n  factory :user do\n    full_name { \"Jane Doe\" }\n    date_of_birth { 21.years.ago }\n    health { 90 }\n  end\nend\n```\n\nWhen modifying a factory, you can change any of the attributes you want (aside from callbacks).\n\n`FactoryBot.modify` must be called outside of a `FactoryBot.define` block as it operates on factories differently.\n\nA caveat: you can only modify factories (not sequences or traits) and callbacks *still compound as they normally would*. So, if\nthe factory you're modifying defines an `after(:create)` callback, you defining an `after(:create)` won't override it, it'll just get run after the first callback.\n\nBuilding or Creating Multiple Records\n-------------------------------------\n\nSometimes, you'll want to create or build multiple instances of a factory at once.\n\n```ruby\nbuilt_users   = build_list(:user, 25)\ncreated_users = create_list(:user, 25)\n```\n\nThese methods will build or create a specific amount of factories and return them as an array.\nTo set the attributes for each of the factories, you can pass in a hash as you normally would.\n\n```ruby\ntwenty_year_olds = build_list(:user, 25, date_of_birth: 20.years.ago)\n```\n\nIn order to set different attributes for each factory, these methods may be passed a block, with the factory and the index as parameters:\n\n```ruby\ntwenty_somethings = build_list(:user, 10) do |user, i|\n  user.date_of_birth = (20 + i).years.ago\nend\n```\n\n`create_list` passes saved instances into the block. If you modify the instance, you must save it again:\n\n```ruby\ntwenty_somethings = create_list(:user, 10) do |user, i|\n  user.date_of_birth = (20 + i).years.ago\n  user.save!\nend\n```\n\n`build_stubbed_list` will give you fully stubbed out instances:\n\n```ruby\nstubbed_users = build_stubbed_list(:user, 25) # array of stubbed users\n```\n\nThere's also a set of `*_pair` methods for creating two records at a time:\n\n```ruby\nbuilt_users   = build_pair(:user) # array of two built users\ncreated_users = create_pair(:user) # array of two created users\n```\n\nIf you need multiple attribute hashes, `attributes_for_list` will generate them:\n\n```ruby\nusers_attrs = attributes_for_list(:user, 25) # array of attribute hashes\n```\n\nLinting Factories\n-----------------\n\nfactory\\_bot allows for linting known factories:\n\n```ruby\nFactoryBot.lint\n```\n\n`FactoryBot.lint` creates each factory and catches any exceptions raised\nduring the creation process. `FactoryBot::InvalidFactoryError` is raised with\na list of factories (and corresponding exceptions) for factories which could\nnot be created.\n\nRecommended usage of `FactoryBot.lint`\nis to run this in a task\nbefore your test suite is executed.\nRunning it in a `before(:suite)`,\nwill negatively impact the performance\nof your tests\nwhen running single tests.\n\nExample Rake task:\n\n```ruby\n# lib/tasks/factory_bot.rake\nnamespace :factory_bot do\n  desc \"Verify that all FactoryBot factories are valid\"\n  task lint: :environment do\n    if Rails.env.test?\n      conn = ActiveRecord::Base.connection\n      conn.transaction do\n        FactoryBot.lint\n        raise ActiveRecord::Rollback\n      end\n    else\n      system(\"bundle exec rake factory_bot:lint RAILS_ENV='test'\")\n      fail if $?.exitstatus.nonzero?\n    end\n  end\nend\n```\n\nAfter calling `FactoryBot.lint`, you'll likely want to clear out the\ndatabase, as records will most likely be created. The provided example above\nuses an sql transaction and rollback to leave the database clean.\n\nYou can lint factories selectively by passing only factories you want linted:\n\n```ruby\nfactories_to_lint = FactoryBot.factories.reject do |factory|\n  factory.name =~ /^old_/\nend\n\nFactoryBot.lint factories_to_lint\n```\n\nThis would lint all factories that aren't prefixed with `old_`.\n\nTraits can also be linted. This option verifies that each\nand every trait of a factory generates a valid object on its own.\nThis is turned on by passing `traits: true` to the `lint` method:\n\n```ruby\nFactoryBot.lint traits: true\n```\n\nThis can also be combined with other arguments:\n\n```ruby\nFactoryBot.lint factories_to_lint, traits: true\n```\n\nYou can also specify the strategy used for linting:\n\n```ruby\nFactoryBot.lint strategy: :build\n```\n\nVerbose linting will include full backtraces for each error, which can be\nhelpful for debugging:\n\n```ruby\nFactoryBot.lint verbose: true\n```\n\nCustom Construction\n-------------------\n\nIf you want to use factory\\_bot to construct an object where some attributes\nare passed to `initialize` or if you want to do something other than simply\ncalling `new` on your build class, you can override the default behavior by\ndefining `initialize_with` on your factory. Example:\n\n```ruby\n# user.rb\nclass User\n  attr_accessor :name, :email\n\n  def initialize(name)\n    @name = name\n  end\nend\n\n# factories.rb\nsequence(:email) { |n| \"person#{n}@example.com\" }\n\nfactory :user do\n  name { \"Jane Doe\" }\n  email\n\n  initialize_with { new(name) }\nend\n\nbuild(:user).name # Jane Doe\n```\n\nAlthough factory\\_bot is written to work with ActiveRecord out of the box, it\ncan also work with any Ruby class. For maximum compatibility with ActiveRecord,\nthe default initializer builds all instances by calling `new` on your build class\nwithout any arguments. It then calls attribute writer methods to assign all the\nattribute values. While that works fine for ActiveRecord, it actually doesn't\nwork for almost any other Ruby class.\n\nYou can override the initializer in order to:\n\n* Build non-ActiveRecord objects that require arguments to `initialize`\n* Use a method other than `new` to instantiate the instance\n* Do wild things like decorate the instance after it's built\n\nWhen using `initialize_with`, you don't have to declare the class itself when\ncalling `new`; however, any other class methods you want to call will have to\nbe called on the class explicitly.\n\nFor example:\n\n```ruby\nfactory :user do\n  name { \"John Doe\" }\n\n  initialize_with { User.build_with_name(name) }\nend\n```\n\nYou can also access all public attributes within the `initialize_with` block\nby calling `attributes`:\n\n```ruby\nfactory :user do\n  transient do\n    comments_count { 5 }\n  end\n\n  name \"John Doe\"\n\n  initialize_with { new(**attributes) }\nend\n```\n\nThis will build a hash of all attributes to be passed to `new`. It won't\ninclude transient attributes, but everything else defined in the factory will be\npassed (associations, evaluated sequences, etc.)\n\nYou can define `initialize_with` for all factories by including it in the\n`FactoryBot.define` block:\n\n```ruby\nFactoryBot.define do\n  initialize_with { new(\"Awesome first argument\") }\nend\n```\n\nWhen using `initialize_with`, attributes accessed from within the `initialize_with`\nblock are assigned *only* in the constructor; this equates to roughly the\nfollowing code:\n\n```ruby\nFactoryBot.define do\n  factory :user do\n    initialize_with { new(name) }\n\n    name { 'value' }\n  end\nend\n\nbuild(:user)\n# runs\nUser.new('value')\n```\n\nThis prevents duplicate assignment; in versions of factory\\_bot before 4.0, it\nwould run this:\n\n```ruby\nFactoryBot.define do\n  factory :user do\n    initialize_with { new(name) }\n\n    name { 'value' }\n  end\nend\n\nbuild(:user)\n# runs\nuser = User.new('value')\nuser.name = 'value'\n```\n\nCustom Strategies\n-----------------\n\nThere are times where you may want to extend behavior of factory\\_bot by\nadding a custom build strategy.\n\nStrategies define two methods: `association` and `result`. `association`\nreceives a `FactoryBot::FactoryRunner` instance, upon which you can call\n`run`, overriding the strategy if you want. The second method, `result`,\nreceives a `FactoryBot::Evaluation` instance. It provides a way to trigger\ncallbacks (with `notify`), `object` or `hash` (to get the result instance or a\nhash based on the attributes defined in the factory), and `create`, which\nexecutes the `to_create` callback defined on the factory.\n\nTo understand how factory\\_bot uses strategies internally, it's probably\neasiest to just view the source for each of the four default strategies.\n\nHere's an example of composing a strategy using\n`FactoryBot::Strategy::Create` to build a JSON representation of your model.\n\n```ruby\nclass JsonStrategy\n  def initialize\n    @strategy = FactoryBot.strategy_by_name(:create).new\n  end\n\n  delegate :association, to: :@strategy\n\n  def result(evaluation)\n    @strategy.result(evaluation).to_json\n  end\n\n  def to_sym\n    :json\n  end\nend\n```\n\nFor factory\\_bot to recognize the new strategy, you can register it:\n\n```ruby\nFactoryBot.register_strategy(:json, JsonStrategy)\n```\n\nThis allows you to call\n\n```ruby\nFactoryBot.json(:user)\n```\n\nFinally, you can override factory\\_bot's own strategies if you'd like by\nregistering a new object in place of the strategies.\n\nCustom Callbacks\n----------------\n\nCustom callbacks can be defined if you're using custom strategies:\n\n```ruby\nclass JsonStrategy\n  def initialize\n    @strategy = FactoryBot.strategy_by_name(:create).new\n  end\n\n  delegate :association, to: :@strategy\n\n  def result(evaluation)\n    result = @strategy.result(evaluation)\n    evaluation.notify(:before_json, result)\n\n    result.to_json.tap do |json|\n      evaluation.notify(:after_json, json)\n      evaluation.notify(:make_json_awesome, json)\n    end\n  end\n\n  def to_sym\n    :json\n  end\nend\n\nFactoryBot.register_strategy(:json, JsonStrategy)\n\nFactoryBot.define do\n  factory :user do\n    before(:json)                { |user| do_something_to(user) }\n    after(:json)                 { |user_json| do_something_to(user_json) }\n    callback(:make_json_awesome) { |user_json| do_something_to(user_json) }\n  end\nend\n```\n\nCustom Methods to Persist Objects\n---------------------------------\n\nBy default, creating a record will call `save!` on the instance; since this\nmay not always be ideal, you can override that behavior by defining\n`to_create` on the factory:\n\n```ruby\nfactory :different_orm_model do\n  to_create { |instance| instance.persist! }\nend\n```\n\nTo disable the persistence method altogether on create, you can `skip_create`\nfor that factory:\n\n```ruby\nfactory :user_without_database do\n  skip_create\nend\n```\n\nTo override `to_create` for all factories, define it within the\n`FactoryBot.define` block:\n\n```ruby\nFactoryBot.define do\n  to_create { |instance| instance.persist! }\n\n\n  factory :user do\n    name { \"John Doe\" }\n  end\nend\n```\n\nActiveSupport Instrumentation\n-----------------------------\n\nIn order to track what factories are created (and with what build strategy),\n`ActiveSupport::Notifications` are included to provide a way to subscribe to\nfactories being compiled and run. One example would be to track factories based on a\nthreshold of execution time.\n\n```ruby\nActiveSupport::Notifications.subscribe(\"factory_bot.run_factory\") do |name, start, finish, id, payload|\n  execution_time_in_seconds = finish - start\n\n  if execution_time_in_seconds >= 0.5\n    $stderr.puts \"Slow factory: #{payload[:name]} using strategy #{payload[:strategy]}\"\n  end\nend\n```\n\nAnother example would be tracking all factories and how they're used\nthroughout your test suite. If you're using RSpec, it's as simple as adding a\n`before(:suite)` and `after(:suite)`:\n\n```ruby\nfactory_bot_results = {}\nconfig.before(:suite) do\n  ActiveSupport::Notifications.subscribe(\"factory_bot.run_factory\") do |name, start, finish, id, payload|\n    factory_name = payload[:name]\n    strategy_name = payload[:strategy]\n    factory_bot_results[factory_name] ||= {}\n    factory_bot_results[factory_name][strategy_name] ||= 0\n    factory_bot_results[factory_name][strategy_name] += 1\n  end\nend\n\nconfig.after(:suite) do\n  puts factory_bot_results\nend\n```\n\nAnother example could involve tracking the attributes and traits that factories are compiled with. If you're using RSpec, you could add `before(:suite)` and `after(:suite)` blocks that subscribe to `factory_bot.compile_factory` notifications:\n\n```ruby\nfactory_bot_results = {}\nconfig.before(:suite) do\n  ActiveSupport::Notifications.subscribe(\"factory_bot.compile_factory\") do |name, start, finish, id, payload|\n    factory_name = payload[:name]\n    factory_class = payload[:class]\n    attributes = payload[:attributes]\n    traits = payload[:traits]\n    factory_bot_results[factory_class] ||= {}\n    factory_bot_results[factory_class][factory_name] = {\n      attributes: attributes.map(&:name)\n      traits: traits.map(&:name)\n    }\n  end\nend\n\nconfig.after(:suite) do\n  puts factory_bot_results\nend\n```\n\nRails Preloaders and RSpec\n--------------------------\n\nWhen running RSpec with a Rails preloader such as `spring` or `zeus`, it's possible\nto encounter an `ActiveRecord::AssociationTypeMismatch` error when creating a factory\nwith associations, as below:\n\n```ruby\nFactoryBot.define do\n  factory :united_states, class: \"Location\" do\n    name { 'United States' }\n    association :location_group, factory: :north_america\n  end\n\n  factory :north_america, class: \"LocationGroup\" do\n    name { 'North America' }\n  end\nend\n```\n\nThe error occurs during the run of the test suite:\n\n```\nFailure/Error: united_states = create(:united_states)\nActiveRecord::AssociationTypeMismatch:\n  LocationGroup(#70251250797320) expected, got LocationGroup(#70251200725840)\n```\n\nThe two possible solutions are to either run the suite without the preloader, or\nto add `FactoryBot.reload` to the RSpec configuration, like so:\n\n```ruby\nRSpec.configure do |config|\n  config.before(:suite) { FactoryBot.reload }\nend\n```\n\nUsing Without Bundler\n---------------------\n\nIf you're not using Bundler, be sure to have the gem installed and call:\n\n```ruby\nrequire 'factory_bot'\n```\n\nOnce required, assuming you have a directory structure of `spec/factories` or\n`test/factories`, all you'll need to do is run:\n\n```ruby\nFactoryBot.find_definitions\n```\n\nIf you're using a separate directory structure for your factories, you can\nchange the definition file paths before trying to find definitions:\n\n```ruby\nFactoryBot.definition_file_paths = %w(custom_factories_directory)\nFactoryBot.find_definitions\n```\n\nIf you don't have a separate directory of factories and would like to define\nthem inline, that's possible as well:\n\n```ruby\nrequire 'factory_bot'\n\nFactoryBot.define do\n  factory :user do\n    name { 'John Doe' }\n    date_of_birth { 21.years.ago }\n  end\nend\n```\n"
  },
  {
    "path": "Gemfile",
    "content": "source \"https://rubygems.org\"\n\ngem \"activerecord-jdbcsqlite3-adapter\", platforms: [:jruby]\ngem \"sqlite3\", platforms: [:ruby]\n\ngemspec name: \"factory_bot\"\n"
  },
  {
    "path": "LICENSE",
    "content": "Copyright (c) 2008-2019 Joe Ferris and thoughtbot, inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "NAME.md",
    "content": "# Project Naming History\n\n## Factory Girl\n\nThis library was [initially released](https://robots.thoughtbot.com/waiting-for-a-factory-girl)\nin 2008 with the name \"Factory Girl\".\n\nWe chose the name as a nod in the direction of the [Factory method](https://en.wikipedia.org/wiki/Factory_method_pattern)\nand [Object Mother](http://martinfowler.com/bliki/ObjectMother.html) software\npatterns from the _Design Patterns_ book, and as a reference to the\n[Rolling Stones song](https://www.youtube.com/watch?v=4jKix2DFlnA) of the same\nname.\n\n## Factory Bot\n\nThe name \"Factory Girl\" was confusing to some developers who encountered this\nlibrary, and offensive or problematic to others. In October 2017 we [renamed the library](https://robots.thoughtbot.com/factory_bot)\nto \"Factory Bot\".\n"
  },
  {
    "path": "NEWS.md",
    "content": "# News\n\n## 6.5.6 (October 22, 2025)\n\n* Fix: Enforce association override precedence over trait foreign keys by @JinOketani in [#1768](https://github.com/thoughtbot/factory_bot/pull/1768)\n* Build: Add ostruct as a development dependency by @ydah in [#1778](https://github.com/thoughtbot/factory_bot/pull/1778)\n* Build: Bump standard from v1.44.0 to v1.51.1 by @ydah in [#1779](https://github.com/thoughtbot/factory_bot/pull/1779)\n* Build: Add Ruby 3.4 to CI matrix by @ydah in [#1780](https://github.com/thoughtbot/factory_bot/pull/1780)\n* Build: Remove unnecessary development dependencies by @ydah in [#1781](https://github.com/thoughtbot/factory_bot/pull/1781)\n* Build: update gem versions and dependencies by @ydah in [#1782](https://github.com/thoughtbot/factory_bot/pull/1782)\n* Build: revert removal of mutex_m by @vburzynski in [#1784](https://github.com/thoughtbot/factory_bot/pull/1784)\n* Refactor: factory calculator cleanup by @vburzynski in [#1770](https://github.com/thoughtbot/factory_bot/pull/1770)\n* Chore(ci): Bump actions/checkout from 4 to 5 by @dependabot[bot] in [#1765](https://github.com/thoughtbot/factory_bot/pull/1765)\n* Chore(specs): tag slow specs by @vburzynski in [#1776](https://github.com/thoughtbot/factory_bot/pull/1776)\n* Docs: Update RELEASING.md by @vburzynski in [#1763](https://github.com/thoughtbot/factory_bot/pull/1763)\n* Docs: Update link to FactoryGirl upgrade guide by @imRohan in [#1769](https://github.com/thoughtbot/factory_bot/pull/1769)\n* Docs: Fix some typos by @ydah in [#1783](https://github.com/thoughtbot/factory_bot/pull/1783)\n* Docs(yard): resolve yard doc warnings by @vburzynski in [#1764](https://github.com/thoughtbot/factory_bot/pull/1764)\n* Docs(yard): ruby syntax highlighting in yard docs by @djbender in [#1777](https://github.com/thoughtbot/factory_bot/pull/1777)\n\n## 6.5.5 (August 15, 2025)\n\n* Feat: Adds developer console features (CodeMeister)\n  * adds `bin/setup` to run bundle install\n  * adds `bin/console` to open an IRB console with factory_bot loaded\n  * adds a session method `reload!` will reload all gem files.\n* Feat: Before(:all) and after(:all) callbacks added (CodeMeister)\n* Feat: Adds support for before build callback (Mohammed Nasser and Neil Carvalho)\n* Feat: Adds support for lazy loaded initial value sequences (AJ Esler)\n* Fix: Refactors the removal of files from the loaded register in `.irbrc` (CodeMeister)\n* Fix: Improves the sequence handling with better context support (CodeMeister)\n  * Fixes issue #1754 where `#generate` was throwing an error\n  * Refactors the `#increment_sequence` method to remove the URI requirement\n* Fix: Cleans up ActiveSupport core extensions (Neil Carvalho)\n* Fix: Addresses issue #1709 with resolution of conflict between '<attribute>' and '<attribute_id>` (CodeMeister)\n* Fix: Addresses issue #1712 by ensuring callbacks only run once per instance (CodeMeister)\n* Docs: Downcase of the word \"constants\" in  `.irbrc` file (CodeMeister)\n* Docs: Update docs with note clarifying when the full namespace is required in a factory (John Pitchko)\n* Chore: Add new maintainers to CODEOWNERS (Ajina Slater)\n\n## 6.5.4 (June 13, 2025)\n\n* Fix bug where user-defined method named `definition` could not be set through `method_missing` in factories. (CodeMeister)\n\n## 6.5.3 (June 2, 2025)\n\n* Fix: Factory sequences without blocks (CodeMeister)\n* Added: New methods for setting, generating and rewinding sequences (CodeMeister)\n\n## 6.5.2 (May 30, 2025)\n\n* Changed: Updated \"verbose linting\" test to allow for backtrace changes in Ruby 3.4 (CodeMeister)\n* Fix: Set the same timestamps for `created_at` and `updated_at` on `build_stubbed` (Kim Emmanuel)\n* Fix: Refactored sequences to ensure cloned traits use parent sequences. (CodeMeister)\n* Docs: Fix definition_file_paths comment (Milo Winningham)\n* Docs: Add ruby-lsp extensions to Useful Tools in README.md (johansenja)\n* Docs: Fix docs about definition file paths (Ryo Nakamura)\n* Docs: Update has_many-associations.md to mention that traits can use inline associations (Matthew Zagaja)\n* Docs: Fix \"Transitioning from Factory Girl\" guide link (Neil Carvalho)\n\n## 6.5.1 (January 31, 2025)\n\n* Changed: execute linting tests within ActiveRecord transactions when available (Sean Doyle)\n* Fix: Random test failure when tracking compilation time (CodeMeister)\n* Fix: Bump the minimum required activesupport version to 6.1 (Earlopain)\n* Internal: Update development dependencies (Neil Carvalho)\n\n## 6.5.0 (September 6, 2024)\n\n* fix: issue 1621 broken links in ref/factory.md by @elasticspoon in https://github.com/thoughtbot/factory_bot/pull/1623\n* Add standard settings by @ydah in https://github.com/thoughtbot/factory_bot/pull/1625\n* Call dynamic-readme reusable workflow by @stefannibrasil in https://github.com/thoughtbot/factory_bot/pull/1628\n* Update README again by @stefannibrasil in https://github.com/thoughtbot/factory_bot/pull/1630\n* Only run this workflow if the README has been updated by @stefannibrasil in https://github.com/thoughtbot/factory_bot/pull/1635\n* Automatically Generated: Update Dynamic Section in README by @github-actions in https://github.com/thoughtbot/factory_bot/pull/1637\n* Added a case for build_class to handle class names with underscores passed as a string by @m-gizzi in https://github.com/thoughtbot/factory_bot/pull/1642\n* Add Ruby 3.3 to CI by @berkos in https://github.com/thoughtbot/factory_bot/pull/1615\n* Update Dependabot configuration by @smaboshe in https://github.com/thoughtbot/factory_bot/pull/1655\n* Add new maintainers to CODEOWNERS by @sarahraqueld in https://github.com/thoughtbot/factory_bot/pull/1651\n* Improve docs formatting and fix filename conflicts by @sarahraqueld in https://github.com/thoughtbot/factory_bot/pull/1666\n* Add a dynamic security workflow and a SECURITY.md file by @sarahraqueld in https://github.com/thoughtbot/factory_bot/pull/1677\n* Automatically Generated: Update Dynamic Section in SECURITY by @github-actions in https://github.com/thoughtbot/factory_bot/pull/1678\n* Ensure rails 7.2 compatibility by @Earlopain in https://github.com/thoughtbot/factory_bot/pull/1686\n* Fix the factory definition in traits documentation by @ddieulivol in https://github.com/thoughtbot/factory_bot/pull/1688\n\n## 6.4.6 (January 30, 2023)\n\n* Fix: Bump minimum required Ruby in gemspec (Earlopain).\n* Fix: Broken link in `FactoryBot.modify` docs (Matt Brictson).\n* Fix: Broken link in `FactoryBot.lint` docs (Anton Dieterle).\n\n## 6.4.5 (December 29, 2023)\n\n* Changed: Support Ruby 3.0+, Rails 6.1+ (Mike Burns).\n\n## 6.4.4 (December 27, 2023)\n\n* Internal: Remove observer dependency (Earlopain).\n\n## 6.4.3 (December 26, 2023)\n\n* Fix: Support models without ID setters in build_stubbed (Olivier Bellone).\n* Fix: Explicit observer dependency (Oleg Antonyan).\n* Internal: Add Rails 7.1 to CI (Olivier Bellone).\n* Internal: Bump github actions/checkout to v4 (Lorenzo Zabot)\n* Internal: Stop passing disable-error_highlight in CI (Mike Burns).\n* Internal: Relax the exception message check (Mike Burns).\n\n## 6.4.2 (November 22, 2023)\n\n* Fix: top-level traits pass their class to ActiveSupport::Notifications (makicamel).\n\n## 6.4.1 (November 20, 2023)\n\n* Fix: factories with traits pass their class to ActiveSupport::Notifications\n  (makicamel).\n\n## 6.4.0 (November 17, 2023)\n\n* Added: if `build_stubbed` detects a UUID primary key, generate the correct\n  type (Peter Boling, Alexandre Ruban).\n* Docs: show examples of Ruby 3 syntactic sugars (Sean Doyle).\n* Internal: resolve test warning messages (Mike Burns).\n\n## 6.3.0 (September 1, 2023)\n\n* Fix: link to changelog for RubyGems (Berkan Ünal).\n* Fix: integrate with Ruby 3.2's `did_you_mean` library (Daniel Colson).\n* Changed: explicitly define `#destroyed?` within the `Stub` strategy to return `false` to be consistent\n  with ActiveRecord (Benjamin Fleischer).\n* Added: announce `factory_bot.compile_factory` notification (Sean Doyle).\n* Docs: clarify that custom strategies need to define `#to_sym` (Edmund Korley, Jonas S).\n* Docs: fix CI link in README (Mark Huk).\n* Docs: fix GitHub links (Robert Fletcher).\n* Docs: install this library with `bundle add` (Glauco Custódio).\n* Docs: re-write into mdBook (Mike Burns, Sara Jackson, Stefanni Brasil)\n* Docs: clarify that automatic trait definitions could introduce new linting errors (Lawrence Chou).\n* Internal: skip TruffleRuby on Rails 5.0, 5.1, 5.2 (Andrii Konchyn).\n* Internal: fix typos throughout codebase (Yudai Takada).\n* Internal: run CI on `actions/checkout` v3 (Yudai Takada).\n* Internal: follow standardrb code style (Yudai Takada).\n* Internal: stop using Hound (Daniel Nolan).\n* Internal: only run simplecov on C Ruby (Daniel Colson).\n* Internal: quieter Cucumber (Daniel Colson).\n* Internal: Ruby 3.2 support (Daniel Colson).\n* Internal: Mike Burns is the CODEOWNER (Stefanni Brasil).\n\n## 6.2.1 (March 8, 2022)\n\n* Added: CI testing against truffleruby\n* Changed: Documentation improvements for sequences and traits\n* Fixed: ActiveSupport::Notifications reporting strategy through associations now report as symbols\n  * BREAKING CHANGE: Custom strategies now need to define a `to_sym` method to specify the strategy identifier\n* Fixed: `add_attribute` with reserved keywords assigns values correctly\n\n## 6.2.0 (May 7, 2021)\n\n* Added: support for Ruby 3.0\n* Changed: Include factory or trait name in error messages for missing traits. d05a9a3c\n* Changed: Switched from Travis CI to GitHub Actions\n* Fixed: More Ruby 2.7 kwarg deprecation warnings\n\n## 6.1.0 (July 8, 2020)\n\n* Added: public reader for the evaluation instance, helpful for building interrelated associations\n* Changed: raise a more helpful error when passing an invalid argument to an association\n* Fixed: Ruby 2.7 kwarg deprecation warnings\n\n## 6.0.2 (June 19, 2020)\n\n* Fixed: bug causing traits to consume more memory each time they were used\n\n## 6.0.1 (June 19, 2020)\n\n* Fixed: bug with constant resolution causing unexpected uninitialized constant errors\n\n## 6.0.0 (June 18, 2020)\n\n* Added: automatic definition of traits for Active Record enum attributes, enabled by default\n  (Note that this required changing where factory_bot constantizes the build\n  class, which may affect applications that were using abstract factories for\n  inheritance. See issue #1409.) (This may break `FactoryBot.lint` because\n  there may be previously non-existing factory+trait combinations being\n  defined and checked)\n* Added: `traits_for_enum` method to define traits for non-Active Record enums\n* Added: `build_stubbed_starting_id=` option to define the starting id for `build_stubbed`\n* Removed: deprecated methods on the top-level `FactoryBot` module meant only for internal use\n* Removed: support for EOL versions of Ruby (2.3, 2.4) and Rails (4.2)\n* Removed: support for \"abstract\" factories with no associated class; use traits instead.\n\n## 5.2.0 (April 24, 2020)\n\n* Added: Pass index to block for `*_list` methods\n* Deprecated: methods on the top-level `FactoryBot` module meant only for internal use: `callbacks`, `configuration`, `constructor`, `initialize_with`, `register_sequence`, `resent_configuration`, `skip_create`, `to_create`\n\n## 5.1.2 (March 25, 2020)\n\n* Fixed: Ruby 2.7 keyword deprecation warning in FactoryBot.lint\n\n## 5.1.1 (October 2, 2019)\n\n* Improved: performance of traits\n* Fixed: registering strategies on JRuby\n\n## 5.1.0 (September 21, 2019)\n\n* Added: \"Did you mean?\" style error message to help with typos in association declarations\n* Changed: `NoMethodError` for static attributes now offers a \"Did you mean?\" style message\n* Fixed: avoid undefining inherited evaluator methods\n* Fixed: avoid stubbing id for records without a primary key\n* Fixed: raise a helpful error for self-referencing traits to avoid a `SystemStackError`\n* Deprecated: methods on the top-level `FactoryBot` module meant only for internal use: `allow_class_lookup`, `allow_class_lookup`=, `register_trait`, `trait_by_name`, `traits`, `sequence_by_name`, `sequences`, `factory_by_name`, `register_factory`, `callback_names`, `register_callback`, `register_default_callbacks`, `register_default_strategies`, `strategies`\n\n## 5.0.2 (February 22, 2019)\n\n* Bugfix: raise \"Trait not registered\" error when passing invalid trait arguments\n\n## 5.0.1 (February 15, 2019)\n\n* Bugfix: Do not raise error when two sequences have the same name\n  in two traits that have the same name\n\n## 5.0.0 (February 1, 2019)\n\n* Added: Verbose option to include full backtraces in the linting output\n* Changed: use_parent_strategy now defaults to true, so by default the\n  build strategy will build, rather than create associations\n* Changed: Passing a block when defining associations now raises an error\n* Bugfix: use_parent_strategy is no longer reset by FactoryBot.reload\n* Bugfix: rewind_sequences will now rewind local sequences along with the global ones\n* Bugfix: the build_stubbed strategy now sets timestamps without changing the\n  the original behavior of the timestamp methods\n* Bugfix: avoid a stack error when referring to an \"attributes\" attribute in initialize_with\n* Removed: support for EOL versions of Ruby and Rails\n* Removed: static attributes (use dynamic attributes with a block instead)\n* Removed: looking up factories by class\n* Removed: ignore method (use transient instead)\n* Removed: duplicate_attribute_assignment_from_initialize_with configuration option\n* Deprecated: allow_class_lookup configuration option\n\n## 4.11.1 (September 7, 2018)\n\n* Documentation: Include .yardopts in the gem to fix broken RubyDoc links\n\n## 4.11.0 (August, 15, 2018)\n\n* Bugfix: Do not raise error for valid build_stubbed methods: decrement, increment, and toggle\n* Bugfix: Do not add timestamps with build_stubbed for objects that shouldn't have timestamps\n* Deprecate static attributes\n\n## 4.10.0 (May 25, 2018)\n\n* Allow sequences to be rewound\n\n## 4.9.0 (skipped - FactoryGirl only release)\n\n## 4.8.2 (October 20, 2017)\n\n* Rename factory_girl to factory_bot\n\n## 4.8.1 (September 28, 2017)\n\n* Explicitly define `#destroyed?` within the `Stub` strategy to return `nil` instead of raising\n* Update various dependencies\n* Update internal test suite to use RSpec's mocking/stubbing instead of mocha\n\n## 4.8.0 (December 16, 2016)\n\n* Improve documentation\n* Add `FactoryGirl.generate_list` to be consistent with `build_list`/`create_list` and friends\n* Add `FactoryGirl.use_parent_strategy` configuration to allow associations to leverage parent build strategy\n\n## 4.7.0 (April 1, 2016)\n\n* Improve documentation\n* Improve instrumentation payload to include traits, overrides, and the factory itself\n* Allow linting of traits\n* Deprecate factory lookup by class name in preparation for 5.0\n* Improve internal performance by using flat_map instead of map and compact\n* Improve handling of dirty attributes after building a stubbed object\n* Reduce warnings from redefining methods\n\n## 4.6.0 (skipped)\n\n## 4.5.0 (October 17, 2014)\n\n* Improve FactoryGirl.lint by including exception and message in output\n* Allow selective linting\n* Use more explicit #public_send when doing attribute assignment\n* Improve documentation around FactoryGirl.lint and initialize_with\n* Deprecate #ignore in favor of #transient\n\n## 4.4.0 (February 10, 2014)\n\n* Add FactoryGirl.lint\n* Fix memory leak in duplicate traits\n* Update documentation\n\n## 4.3.0 (November 3, 2013)\n\n* Start testing against Rails 4.0 and Ruby 2.0.0\n* Stop testing against Rails 3.0 and Ruby 1.9.2\n* Add `*_pair` methods to only build two objects\n* Raise if a method is defined with a FactoryGirl block (factory or trait)\n* Allow use of Symbol#to_proc in callbacks\n* Add global callbacks\n* Improve GETTING_STARTED and README\n\n## 4.2.0 (January 18, 2013)\n\n* Improve documentation\n* Allow `*_list` syntax methods to accept a block\n* Update gem dependencies\n* Allow setting id for objects created with `build_stubbed`\n* Fix Stub strategy to mimic ActiveRecord regarding `created_at`\n* Evaluate sequences within the context of an Evaluator\n* Fix Mocha deprecation warning\n* Fix some warnings when running RUBYOPT=-w rake\n* Convert test suite to RSpec's \"expect\" syntax\n\n## 4.1.0 (September 11, 2012)\n\n* Allow multiple callbacks to bind to the same block\n* Fix documentation surrounding the stub strategy\n\n## 4.0.0 (August 3, 2012)\n\n* Remove deprecated cucumber_steps\n* Remove deprecated alternate syntaxes\n* Deprecate duplicate_attribute_assignment_from_initialize_with, which is now unused\n  as attributes assigned within initialize_with are not subsequently assigned\n\n## 3.6.1 (August 2, 2012)\n\nUpdate README to include info about running with JRuby\n* Update dependencies on RSpec and tiny versions of Rails in Appraisal\n* Improve flexibility of using traits with associations and add documentation\n* Stub update_column to raise to mirror ActiveRecord's change from update_attribute\n\n## 3.6.0 (July 27, 2012)\n\n* Code/spec cleanup\n* Allow factories with traits to be used in associations\n* Refactor Factory to use DefinitionHierarchy to handle managing callbacks,\n  custom constructor, and custom to_create\n* Add memoization to speed up factories providing attribute overrides\n* Add initial support of JRuby when running in 1.9 mode\n* Improve docs on what happens when including FactoryGirl::Syntax::Methods\n\n## 3.5.0 (June 22, 2012)\n\n* Allow created_at to be set when using build_stubbed\n* Deprecate FactoryGirl step definitions\n\n## 3.4.2 (June 19, 2012)\n\n* Fix bug in traits with callbacks called implicitly in factories whose\n  callbacks trigger multiple times\n\n## 3.4.1 (June 18, 2012)\n\n* Fix traits so they can be nested and referred to from other traits\n\n## 3.4.0 (June 11, 2012)\n\n* Sequences support Enumerators\n* Optionally disable duplicate assignment of attributes in initialize_with\n* Make hash of public attributes available in initialize_with\n* Support referring to a factory based on class name\n\n## 3.3.0 (May 13, 2012)\n\n* Allow to_create, skip_create, and initialize_with to be defined globally\n* Allow to_create, skip_create, and initialize_with to be defined within traits\n* Fix deprecation messages for alternate syntaxes (make, generate, etc.)\n* Improve library documentation\n* Deprecate after_build, after_create, before_create, after_stub in favor of new callbacks\n* Introduce new callback syntax: after(:build) {}, after(:custom) {}, or callback(:different) {}\n  This allows for declaring any callback, usable with custom strategies\n* Add attributes_for_list and build_stubbed_list with the StrategySyntaxMethodRegistrar\n* Allow use of syntax methods (build, create, generate, etc) implicitly in callbacks\n* Internal refactoring of a handful of components\n\n## 3.2.0 (April 24, 2012)\n\n* Use AS::Notifications for pub/sub to track running factories\n* Call new within initialize_with implicitly on the build class\n* Skip to_create with skip_create\n* Allow registration of custom strategies\n* Deprecate alternate syntaxes\n* Implicitly call factory_bot's syntax methods from dynamic attributes\n\n## 3.1.0 (April 6, 2012)\n\n* Sequences support aliases, which reference the same block\n* Update documentation\n* Add before_create callback\n* Support use of #attribute_names method to determine available attributes for steps\n* Use ActiveSupport::Deprecation for all deprecations\n\n## 3.0.0 (March 23, 2012)\n\n* Deprecate the vintage syntax\n* Remove Rails 2.x support\n* Remove Ruby 1.8 support\n* Remove deprecated features, including default_strategy, factory_name,\n  :method for defining default strategy, ignore on individual attributes, and\n  interacting with Factory the way you would FactoryGirl\n\n## 2.6.4 (March 16, 2012)\n\n* Do not ignore names of transient attributes\n* Ensure attributes set on instance are calculated uniquely\n\n## 2.6.3 (March 9, 2012)\n\n* Fix issue with traits not being present the first time a factory is accessed\n* Update available Cucumber step definitions to not require a trailing colon\n  when building a table of attributes to instantiate records with\n\n## 2.6.2 (March 9, 2012)\n* Allow factories to use all their ancestors' traits\n* Ignore bin dir generated by bundler\n* Namespace ::Factory as top-level to fix vintage syntax issue with\n  Ruby 1.9.2-p3p18\n\n## 2.6.1 (March 2, 2012)\n\n* Use FactoryGirl.reload in specs\n* Clean up running named factories with a particular strategy with\n  FactoryGirl::FactoryRunner\n\n## 2.6.0 (February 17, 2012)\n\n* Improve documentation of has_many associations in the GETTING_STARTED\n  document\n* Deprecate :method in favor of :strategy when overriding an association's\n  build strategy\n\n## 2.5.2 (February 10, 2012)\n\n* Fix step definitions to use associations defined in parent factories\n* Add inline trait support to (build|create)_list\n* Update ActiveSupport dependency to >= 2.3.9, which introduced\n  class_attribute\n\n## 2.5.1 (February 3, 2012)\n\n* Fix attribute evaluation when the attribute isn't defined in the factory but\n  is a private method on Object\n* Update rubygems on Travis before running tests\n* Fix spec name\n* Update GETTING_STARTED with correct usage of build_stubbed\n* Update README with more info on initialize_with\n* Honor :parent on factory over block nesting\n\n## 2.5.0 (January 20, 2012)\n\n* Revert 'Deprecate build_stubbed and attributes_for'\n* Implement initialize_with to allow overriding object instantiation\n* Ensure FG runs against Rails 3.2.0\n\n## 2.4.2 (January 18, 2012)\n\n* Fix inline traits' interaction with defaults on the factory\n\n## 2.4.1 (January 17, 2012)\n\n* Deprecate build_stubbed and attributes_for\n* Fix inline traits\n\n## 2.4.0 (January 13, 2012)\n\n* Refactor internals of FactoryGirl to use anonymous class on which attributes\n  get defined\n* Explicitly require Ruby 1.8.7 or higher in gemspec\n* Fix documentation\n* Add Gemnasium status to documentation\n* Supplying a Class to a factory that overrides to_s no longer results in\n  getting the wrong Class constructed\n* Be more agnostic about ORMs when using columns in FactoryGirl step\n  definitions\n* Test against Active Record 3.2.0.rc2\n* Update GETTING_STARTED to use Ruby syntax highlighting\n\n## 2.3.2 (November 26, 2011)\n\n* Move logic of where instance.save! is set to Definition\n* Fix method name from aliases_for? to alias_for?\n* Refactor internal attribute handling to use an anonymous class instead of\n  faking Ruby's variable resolution. This allows for more sane usage of\n  attributes without having to manage sorting priority because attributes\n  can turn themselves into procs, which are used with define_method on a\n  class so attributes work correctly all the time.\n\n## 2.3.1 (November 23, 2011)\n\n* Remove internally-used associate method from all the FactoryGirl::Proxy subclasses\n* Move around requiring of files\n* Consolidate errors into factory_bot.rb\n* Refactor AttributeList to deal with priority only when iterating over\n  attributes\n* Refactor internals of some of the Proxy subclasses\n* Ensure callbacks on traits are executed in the correct order\n\n## 2.3.0 (November 18, 2011)\n\n* Registries are named, resulting in better messages when factories, traits,\n  or sequences cannot be found\n* Fix incorrect tests\n* Internals refactoring introducing FactoryGirl::NullFactory,\n  FactoryGirl::Definition, and FactoryGirl::DeclarationList\n* Use ActiveSupport for Hash#except and its delegation capabilities\n* Fix usage of callbacks when added via implicit traits\n* Use Bundler tasks and clean up dependencies\n* Fix failing spec for big letters in factory name passed as symbol\n* Add ability for traits to be added dynamically when creating an instance via\n  build, create, build_stubbed, or attributes_for\n\n## 2.2.0 (October 14, 2011)\n\n* Clean up RSpec suite to not use 'should'\n* Use create_list in step definitions\n* Syntax methods that deal with ORM interaction (attributes_for, build, build_stubbed,\n  and create) now accept a block that yields the result. This results in a\n  more convenient way to interact with the result than using Object.tap.\n* Standardize deprecation warnings\n* Update transient attribute syntax to use blocks instead of calling ignore on\n  each attribute declaration\n* Parents can be defined after children because factories are evaluated when\n  they're used; this means breaking up factories across multiple files will\n  behave as expected\n* Large internal refactoring, including changing access modifiers for a\n  handful of methods for a more clearly defined API\n\n## 2.1.2 (September 23, 2011)\n\n* Bugfix: Vintage syntax fixed after bug introduced in 2.1.1\n* Introduce dependency on activesupport to remove code from Factory class\n\n## 2.1.1 (September 23, 2011) (yanked)\n\n* Bugfix: Parent object callbacks are run before child object callbacks\n* Declarations: allow overriding/modification of individual traits in child factories\n* Callbacks refactored to not be attributes\n* Updating documentation for formatting and clarity (incl. new specificity for cucumber)\n\n## 2.1.0 (September 02, 2011)\n\n* Bugfix: created_at now defined for stubbed models\n* Gemspec updated for use with Rails 3.1\n* Factories can now be modified post-definition (useful for overriding defaults from gems/plugins)\n* All factories can now be reloaded with Factory.reload\n* Add :method => build to factory associations to prevent saving of associated objects\n* Factories defined in {Rails.root}/factories are now loaded by default\n* Various documentation updates\n\n## 1.1.4 (November 28, 2008)\n\n* Factory.build now uses Factory.create for associations of the built object\n* Factory definitions are now detected in subdirectories, such as\n  factories/person_factory.rb (thanks to Josh Nichols)\n* Factory definitions are now loaded after the environment in a Rails project\n  (fixes some issues with dependencies being loaded too early) (thanks to\n  Josh Nichols)\n* Factory names ending in 's' no longer cause problems (thanks to Alex Sharp\n  and Josh Owens)\n\n## 1.1.3 (September 12, 2008)\n\n* Automatically pull in definitions from factories.rb, test/factories.rb, or\n  spec/factories.rb\n\n## 1.1.2 (July 30, 2008)\n\n* Improved error handling for invalid and undefined factories/attributes\n* Improved handling of strings vs symbols vs classes\n* Added a prettier syntax for handling associations\n* Updated documentation and fixed compatibility with Rails 2.1\n\n## 1.1.1 (June 23, 2008)\n\n* The attribute \"name\" no longer requires using #add_attribute\n\n## 1.1.0 (June 03, 2008)\n\n* Added support for dependent attributes\n* Fixed the attributes_for build strategy to not build associations\n* Added support for sequences\n\n## 1.0.0 (May 31, 2008)\n\n* First version\n"
  },
  {
    "path": "README.md",
    "content": "# factory_bot \n\n[![Build Status][ci-image]][ci] [![Gem Version][version-image]][version]\n\nfactory_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.\n\nIf you want to use factory_bot with Rails, see\n[factory_bot_rails](https://github.com/thoughtbot/factory_bot_rails).\n\nInterested in the history of the project name? You can find the history [here](https://github.com/thoughtbot/factory_bot/blob/main/NAME.md)\n\nTransitioning from factory\\_girl? Check out the [upgrade guide](https://github.com/thoughtbot/factory_bot/blob/v4.9.0/UPGRADE_FROM_FACTORY_GIRL.md).\n\n## Documentation\n\nSee our extensive reference, guides, and cookbook in [the factory_bot book][].\n\nFor information on integrations with third party libraries, such as RSpec or\nRails, see [the factory_bot wiki][].\n\n We also have [a detailed introductory video][], available for free on Upcase.\n\n[a detailed introductory video]: https://upcase.com/videos/factory-bot?utm_source=github&utm_medium=open-source&utm_campaign=factory-girl\n[the factory_bot book]: https://thoughtbot.github.io/factory_bot\n[the factory_bot wiki]: https://github.com/thoughtbot/factory_bot/wiki\n\n## Install\n\nRun:\n\n```ruby\nbundle add factory_bot\n```\n\nTo install the gem manually from your shell, run:\n\n```shell\ngem install factory_bot\n```\n\n## Supported Ruby versions\n\nSupported Ruby versions are listed in `.github/workflows/build.yml` ([source](https://github.com/thoughtbot/factory_bot/blob/main/.github/workflows/build.yml))\n\n## More Information\n\n* [Rubygems](https://rubygems.org/gems/factory_bot)\n* [Stack Overflow](https://stackoverflow.com/questions/tagged/factory-bot)\n* [Issues](https://github.com/thoughtbot/factory_bot/issues)\n* [GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS](https://robots.thoughtbot.com/)\n\n[GETTING_STARTED]: https://github.com/thoughtbot/factory_bot/blob/main/GETTING_STARTED.md\n\n## Useful Tools\n\n* [FactoryTrace](https://github.com/djezzzl/factory_trace) - helps to find unused factories and traits.\n* [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\n\nContributing\n------------\n\nPlease see [CONTRIBUTING.md](https://github.com/thoughtbot/factory_bot/blob/main/CONTRIBUTING.md).\n\nfactory_bot was originally written by Joe Ferris and is maintained by thoughtbot.\nMany improvements and bugfixes were contributed by the [open source\ncommunity](https://github.com/thoughtbot/factory_bot/graphs/contributors).\n\nLicense\n-------\n\nfactory_bot is Copyright © 2008 Joe Ferris and thoughtbot. It is free\nsoftware, and may be redistributed under the terms specified in the\n[LICENSE] file.\n\n[LICENSE]: https://github.com/thoughtbot/factory_bot/blob/main/LICENSE\n\n<!-- START /templates/footer.md -->\n## About thoughtbot\n\n![thoughtbot](https://thoughtbot.com/thoughtbot-logo-for-readmes.svg)\n\nThis repo is maintained and funded by thoughtbot, inc.\nThe names and logos for thoughtbot are trademarks of thoughtbot, inc.\n\nWe love open source software!\nSee [our other projects][community].\nWe are [available for hire][hire].\n\n[community]: https://thoughtbot.com/community?utm_source=github\n[hire]: https://thoughtbot.com/hire-us?utm_source=github\n\n<!-- END /templates/footer.md -->\n\n[ci-image]: https://github.com/thoughtbot/factory_bot/actions/workflows/build.yml/badge.svg?branch=main\n[ci]: https://github.com/thoughtbot/factory_bot/actions?query=workflow%3ABuild+branch%3Amain\n[version-image]: https://badge.fury.io/rb/factory_bot.svg\n[version]: https://badge.fury.io/rb/factory_bot\n[hound-badge-image]: https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg\n[hound]: https://houndci.com\n"
  },
  {
    "path": "RELEASING.md",
    "content": "# Releasing\n\n1. Create a release branch using the naming scheme `release-x.x.x`\n\n   ```shell\n   git checkout main\n   git pull\n   git checkout -b release-x.x.x\n   ```\n\n2. Bump the `VERSION` inside `lib/factory_bot/version.rb`\n\n3. Run `bundle install` to ensure the `Gemfile.lock` file is up to date.\n\n4. Generate release notes using [GitHub's New Release](https://github.com/thoughtbot/factory_bot/releases/new) feature.\n\n   1. Click the tags drop down and select \"Create new tag\"\n   2. Fill in the create new tag modal and select \"Create\"\n      Note: This is a safe step as the tag will not be created unless the release is published\n   3. Click the \"Generate release notes\" button\n   4. Copy the generated text from the \"What's Changed\" section, for use when updating `NEWS.md` in the next step.\n\n5. Update `NEWS.md` to reflect the changes since last release.\n\n   1. Add a heading with the version number and date\n   2. Paste the release notes you copied from the previous step\n      Note: A useful GitHub URL to compare the changes is:\n      `https://github.com/thoughtbot/factory_bot/compare/vLAST_VERSION...main`\n\n6. Commit the changes.\n   Note: As there shouldn't be code changes, CI doesn't need to run.\n   You can add `[ci skip]` to the commit message to skip it.\n\n7. Create a Pull Request, get it reviewed, and merge it to the `main` branch once approved.\n\n8. Back on your machine, switch to the `main` branch and tag the latest commit with the release version: `git tag -s vVERSION`\n\n    - We recommend the [_quick guide on how to sign a release_] from git ready.\n\n9.  Push your changes: `git push && git push --tags`\n\n10. If you haven't already, add yourself as an owner of the `factory_bot` gem on [rubygems.org](https://rubygems.org/) using [the guide in the thoughtbot handbook](https://github.com/thoughtbot/handbook/blob/main/operations/services/rubygems.md#managing-rubygems)\n\n11. Build and publish the gem:\n\n    ```bash\n    gem build factory_bot.gemspec\n    gem push factory_bot-VERSION.gem\n    ```\n\n12. On GitHub, add a new release using the recent `NEWS.md` as the content. Sample\n    URL: `https://github.com/thoughtbot/factory_bot/releases/new?tag=vVERSION`\n\n13. Announce the new release, making sure to say \"thank you\" to the contributors who helped shape this version!\n    thoughtbotters can refer to the handbook for announcements guidelines.\n\n[_quick guide on how to sign a release_]: http://gitready.com/advanced/2014/11/02/gpg-sign-releases.html\n"
  },
  {
    "path": "Rakefile",
    "content": "require \"rubygems\"\nrequire \"bundler\"\nrequire \"rake\"\nrequire \"yard\"\nrequire \"rspec/core/rake_task\"\nrequire \"cucumber/rake/task\"\nrequire \"standard/rake\"\n\nBundler::GemHelper.install_tasks(name: \"factory_bot\")\n\ndesc \"Default: run all specs and standard\"\ntask default: %w[all_specs standard]\n\ndesc \"Run all specs and features\"\ntask all_specs: %w[spec:unit spec:acceptance features]\n\nnamespace :spec do\n  desc \"Run unit specs\"\n  RSpec::Core::RakeTask.new(\"unit\") do |t|\n    t.pattern = \"spec/{*_spec.rb,factory_bot/**/*_spec.rb}\"\n  end\n\n  desc \"Run acceptance specs\"\n  RSpec::Core::RakeTask.new(\"acceptance\") do |t|\n    t.pattern = \"spec/acceptance/**/*_spec.rb\"\n  end\nend\n\ndesc \"Run the unit and acceptance specs\"\ntask spec: [\"spec:unit\", \"spec:acceptance\"]\n\nCucumber::Rake::Task.new(:features) do |t|\n  t.fork = true\n  t.cucumber_opts = [\"--format\", ENV[\"CUCUMBER_FORMAT\"] || \"progress\"]\nend\n\nYARD::Rake::YardocTask.new do |t|\nend\n"
  },
  {
    "path": "SECURITY.md",
    "content": "<!-- START /templates/security.md -->\n# Security Policy\n\n## Supported Versions\n\nOnly the the latest version of this project is supported at a given time. If\nyou find a security issue with an older version, please try updating to the\nlatest version first.\n\nIf for some reason you can't update to the latest version, please let us know\nyour reasons so that we can have a better understanding of your situation.\n\n## Reporting a Vulnerability\n\nFor security inquiries or vulnerability reports, visit\n<https://thoughtbot.com/security>.\n\nIf you have any suggestions to improve this policy, visit <https://thoughtbot.com/security>.\n<!-- END /templates/security.md -->\n"
  },
  {
    "path": "cucumber.yml",
    "content": "default: --publish-quiet -r features features\n"
  },
  {
    "path": "docs/book.toml",
    "content": "[book]\nauthors = [\"Mike Burns\"]\nlanguage = \"en\"\nmultilingual = false\nsrc = \"src\"\ntitle = \"factory_bot\"\n\n[output.html.redirect]\n\"/setup/rspec.html\" = \"https://github.com/thoughtbot/factory_bot/wiki/Integration:-RSpec\"\n\"/setup/cucumber.html\" = \"https://github.com/thoughtbot/factory_bot/wiki/Integration:-Cucumber\"\n\"/setup/minitest-rails.html\" = \"https://github.com/thoughtbot/factory_bot/wiki/Integration:-minitest-rails\"\n\"/setup/minitest-spec.html\" = \"https://github.com/thoughtbot/factory_bot/wiki/Integration:-Minitest::Spec\"\n\"/setup/minitest.html\" = \"https://github.com/thoughtbot/factory_bot/wiki/Integration:-Minitest\"\n\"/setup/spinach.html\" = \"https://github.com/thoughtbot/factory_bot/wiki/Integration:-Spinach\"\n\"/setup/test-unit.html\" = \"https://github.com/thoughtbot/factory_bot/wiki/Integration:-Test::Unit\"\n\"/setup/update-gemfile.html\" = \"summary.html\"\n\"/setup/configure-test-suite.html\" = \"summary.html\"\n\"/using-factories/build_stubbed-and-marshaldump.html\" = \"build-strategies.html\"\n\"/associations/has_many-associations.html\" = \"../cookbook/has_many-associations.html\"\n\"/associations/has_and_belongs_to_many-associations.html\" = \"../cookbook/has_and_belongs_to_many-associations.html\"\n\"/associations/polymorphic-associations.html\" = \"../cookbook/polymorphic-associations.html\"\n\"/associations/interconnected-associations.html\" = \"../cookbook/interconnected-associations.html\"\n\"/traits/defining-traits.html\" = \"summary.html\"\n\"/callbacks/default-callbacks.html\" = \"summary.html\"\n"
  },
  {
    "path": "docs/src/SUMMARY.md",
    "content": "# Summary\n\n[Intro](intro.md)\n\n## Reference\n\n- [Build strategies](ref/build-strategies.md)\n- [FactoryBot.find_definitions](ref/find_definitions.md)\n- [FactoryBot.define](ref/define.md)\n- [factory](ref/factory.md)\n- [add_attribute](ref/add_attribute.md)\n- [association](ref/association.md)\n- [sequence](ref/sequence.md)\n- [trait](ref/trait.md)\n- [method_missing](ref/method_missing.md)\n- [traits_for_enum](ref/traits_for_enum.md)\n- [skip_create, to_create, and initialize_with](ref/build-and-create.md)\n- [transient](ref/transient.md)\n- [Hooks](ref/hooks.md)\n- [FactoryBot.modify](ref/modify.md)\n- [FactoryBot.lint](ref/lint.md)\n- [FactoryBot.register_strategy](ref/register_strategy.md)\n\n## Guide\n\n- [Setup](setup/summary.md)\n  - [Using Without Bundler](using-without-bundler/summary.md)\n  - [Rails Preloaders and RSpec](rails-preloaders-and-rspec/summary.md)\n- [Defining factories](defining/summary.md)\n  - [Factory name and attributes](defining/name-attributes.md)\n  - [Specifying the class explicitly](defining/explicit-class.md)\n  - [Definition file paths](defining/file-paths.md)\n  - [Hash attributes](defining/hash-attributes.md)\n  - [Best practices](defining/best-practices.md)\n  - [Static Attributes (deprecated)](defining/static-attributes.md)\n- [Using factories](using-factories/summary.md)\n  - [Build strategies](using-factories/build-strategies.md)\n  - [Building or Creating Multiple Records](building-or-creating-multiple-records/summary.md)\n  - [Attribute overrides](using-factories/attribute-overrides.md)\n- [Aliases](aliases/summary.md)\n- [Dependent Attributes](dependent-attributes/summary.md)\n- [Transient Attributes](transient-attributes/summary.md)\n  - [With other attributes](transient-attributes/with-other-attributes.md)\n  - [With `attributes_for`](transient-attributes/with-attributes_for.md)\n  - [With callbacks](transient-attributes/with-callbacks.md)\n  - [With associations](transient-attributes/with-associations.md)\n- [Method Name / Reserved Word Attributes](method-name-reserved-word-attributes/summary.md)\n- [Inheritance](inheritance/summary.md)\n  - [Nested factories](inheritance/nested-factories.md)\n  - [Assigning parent explicitly](inheritance/assigning-parent-explicitly.md)\n  - [Best practices](inheritance/best-practices.md)\n- [Associations](associations/summary.md)\n  - [Implicit definition](associations/implicit-definition.md)\n  - [Explicit definition](associations/explicit-definition.md)\n  - [Inline definition](associations/inline-definition.md)\n  - [Specifying the factory](associations/specifying-the-factory.md)\n  - [Overriding attributes](associations/overriding-attributes.md)\n  - [Association overrides](associations/association-overrides.md)\n  - [Build strategies](associations/build-strategies.md)\n- [Sequences](sequences/summary.md)\n  - [Global sequences](sequences/global-sequences.md)\n  - [With dynamic attributes](sequences/with-dynamic-attributes.md)\n  - [As implicit attributes](sequences/as-implicit-attributes.md)\n  - [Factory sequences](sequences/factory-sequences.md)\n  - [Initial value](sequences/initial-value.md)\n  - [Without a block](sequences/without-a-block.md)\n  - [Aliases](sequences/aliases.md)\n  - [Sequence URIs](sequences/sequence-uris.md)\n  - [Rewinding](sequences/rewinding.md)\n  - [Setting the value](sequences/setting-the-value.md)\n  - [Generating a sequence](sequences/generating.md)\n  - [Uniqueness](sequences/uniqueness.md)\n- [Traits](traits/summary.md)\n  - [As implicit attributes](traits/as-implicit-attributes.md)\n  - [Using traits](traits/using.md)\n  - [Enum traits](traits/enum.md)\n  - [Attribute precedence](traits/attribute-precedence.md)\n  - [In child factories](traits/in-child-factories.md)\n  - [As mixins](traits/mixins.md)\n  - [With associations](traits/with-associations.md)\n  - [Traits within traits](traits/traits-within-traits.md)\n  - [With transient attributes](traits/with-transient-attributes.md)\n- [Callbacks](callbacks/summary.md)\n  - [Multiple callbacks](callbacks/multiple-callbacks.md)\n  - [Global callbacks](callbacks/global-callbacks.md)\n  - [Symbol#to_proc](callbacks/symbol-to_proc.md)\n  - [Callback order](callbacks/callback_order.md)\n- [Modifying factories](modifying-factories/summary.md)\n- [Linting Factories](linting-factories/summary.md)\n- [Custom Construction](custom-construction/summary.md)\n- [Custom Strategies](custom-strategies/summary.md)\n- [Custom Callbacks](custom-callbacks/summary.md)\n- [Custom Methods to Persist Objects](custom-methods-to-persist-objects/summary.md)\n- [ActiveSupport Instrumentation](activesupport-instrumentation/summary.md)\n\n## Cookbook\n\n- [`has_many` associations](cookbook/has_many-associations.md)\n- [`has_and_belongs_to_many` associations](cookbook/has_and_belongs_to_many-associations.md)\n- [Polymorphic associations](cookbook/polymorphic-associations.md)\n- [Interconnected associations](cookbook/interconnected-associations.md)\n"
  },
  {
    "path": "docs/src/activesupport-instrumentation/summary.md",
    "content": "# ActiveSupport Instrumentation\n\nIn order to track what factories are created (and with what build strategy),\n`ActiveSupport::Notifications` are included to provide a way to subscribe to\nfactories being compiled and run. One example would be to track factories based on a\nthreshold of execution time.\n\n```ruby\nActiveSupport::Notifications.subscribe(\"factory_bot.run_factory\") do |name, start, finish, id, payload|\n  execution_time_in_seconds = finish - start\n\n  if execution_time_in_seconds >= 0.5\n    $stderr.puts \"Slow factory: #{payload[:name]} using strategy #{payload[:strategy]}\"\n  end\nend\n```\n\nAnother example would be tracking all factories and how they're used throughout\nyour test suite. If you're using RSpec, it's as simple as adding a\n`before(:suite)` and `after(:suite)`:\n\n```ruby\nfactory_bot_results = {}\nconfig.before(:suite) do\n  ActiveSupport::Notifications.subscribe(\"factory_bot.run_factory\") do |name, start, finish, id, payload|\n    factory_name = payload[:name]\n    strategy_name = payload[:strategy]\n    factory_bot_results[factory_name] ||= {}\n    factory_bot_results[factory_name][strategy_name] ||= 0\n    factory_bot_results[factory_name][strategy_name] += 1\n  end\nend\n\nconfig.after(:suite) do\n  puts factory_bot_results\nend\n```\n\nAnother example could involve tracking the attributes and traits that factories are compiled with. If you're using RSpec, you could add `before(:suite)` and `after(:suite)` blocks that subscribe to `factory_bot.compile_factory` notifications:\n\n```ruby\nfactory_bot_results = {}\nconfig.before(:suite) do\n  ActiveSupport::Notifications.subscribe(\"factory_bot.compile_factory\") do |name, start, finish, id, payload|\n    factory_name = payload[:name]\n    factory_class = payload[:class]\n    attributes = payload[:attributes]\n    traits = payload[:traits]\n    factory_bot_results[factory_class] ||= {}\n    factory_bot_results[factory_class][factory_name] = {\n      attributes: attributes.map(&:name)\n      traits: traits.map(&:name)\n    }\n  end\nend\n\nconfig.after(:suite) do\n  puts factory_bot_results\nend\n```\n"
  },
  {
    "path": "docs/src/aliases/summary.md",
    "content": "# Aliases\n\nfactory\\_bot allows you to define aliases to existing factories to make them\neasier to re-use. This could come in handy when, for example, your Post object\nhas an author attribute that actually refers to an instance of a User class.\nWhile normally factory\\_bot can infer the factory name from the association name,\nin this case it will look for an author factory in vain. So, alias your user\nfactory so it can be used under alias names.\n\n```ruby\nfactory :user, aliases: [:author, :commenter] do\n  first_name { \"John\" }\n  last_name { \"Doe\" }\n  date_of_birth { 18.years.ago }\nend\n\nfactory :post do\n  # The alias allows us to write author instead of\n  # association :author, factory: :user\n  author\n  title { \"How to read a book effectively\" }\n  body { \"There are five steps involved.\" }\nend\n\nfactory :comment do\n  # The alias allows us to write commenter instead of\n  # association :commenter, factory: :user\n  commenter\n  body { \"Great article!\" }\nend\n```\n"
  },
  {
    "path": "docs/src/associations/association-overrides.md",
    "content": "# Association overrides\n\nAttribute overrides can be used to link associated objects:\n\n```ruby\nFactoryBot.define do\n  factory :author do\n    name { 'Taylor' }\n  end\n\n  factory :post do\n    author\n  end\nend\n\neunji = build(:author, name: 'Eunji')\npost = build(:post, author: eunji)\n```\n\nRuby 3.1's support for [omitting values][] from `Hash` literals dovetails with\nattribute overrides, and provides an opportunity to limit the repetition of\nvariable names:\n\n```ruby\nauthor = build(:author, name: 'Eunji')\n\npost = build(:post, author:)\n```\n\n[omitting values]: https://docs.ruby-lang.org/en/3.1/syntax/literals_rdoc.html#label-Hash+Literals\n"
  },
  {
    "path": "docs/src/associations/build-strategies.md",
    "content": "# Build strategies\n\nAssociations default to using the same build strategy as their parent object:\n\n```ruby\nFactoryBot.define do\n  factory :author\n\n  factory :post do\n    author\n  end\nend\n\npost = build(:post)\npost.new_record?        # => true\npost.author.new_record? # => true\n\npost = create(:post)\npost.new_record?        # => false\npost.author.new_record? # => false\n```\n\nThis is different than the default behavior for previous versions of\nfactory\\_bot, where the association strategy would not always match the strategy\nof the parent object. If you want to continue using the old behavior, you can\nset the `use_parent_strategy` configuration option to `false`.\n\n```ruby\nFactoryBot.use_parent_strategy = false\n\n# Builds and saves a User and a Post\npost = create(:post)\npost.new_record?        # => false\npost.author.new_record? # => false\n\n# Builds and saves a User, and then builds but does not save a Post\npost = build(:post)\npost.new_record?        # => true\npost.author.new_record? # => false\n```\n\nTo not save the associated object, specify `strategy: :build` in the factory:\n\n```ruby\nFactoryBot.use_parent_strategy = false\n\nfactory :post do\n  # ...\n  association :author, factory: :user, strategy: :build\nend\n\n# Builds a User, and then builds a Post, but does not save either\npost = build(:post)\npost.new_record?        # => true\npost.author.new_record? # => true\n```\n\nNote that the `strategy: :build` option must be passed to an explicit call to\n`association`, and cannot be used with implicit associations:\n\n```ruby\nfactory :post do\n  # ...\n  author strategy: :build    # <<< this does *not* work; causes author_id to be nil\n```\n"
  },
  {
    "path": "docs/src/associations/explicit-definition.md",
    "content": "# Explicit definition\n\nYou can define associations explicitly. This can be handy especially when\n[Overriding attributes](overriding-attributes.md)\n\n```ruby\nfactory :post do\n  # ...\n  association :author\nend\n```\n"
  },
  {
    "path": "docs/src/associations/implicit-definition.md",
    "content": "# Implicit definition\n\nIt's possible to set up associations within factories. If the factory name is\nthe same as the association name, the factory name can be left out.\n\n```ruby\nfactory :post do\n  # ...\n  author\nend\n```\n"
  },
  {
    "path": "docs/src/associations/inline-definition.md",
    "content": "# Inline definition\n\nYou can also define associations inline within regular attributes, but note\nthat the value will be `nil` when using the `attributes_for` strategy.\n\n```ruby\nfactory :post do\n  # ...\n  author { association :author }\nend\n```\n"
  },
  {
    "path": "docs/src/associations/overriding-attributes.md",
    "content": "# Overriding attributes\n\nYou can also override attributes on associations.\n\nImplicitly:\n\n```ruby\nfactory :post do\n  # ...\n  author factory: :author, last_name: \"Writely\"\nend\n```\n\nExplicitly:\n\n\n```ruby\nfactory :post do\n  # ...\n  association :author, last_name: \"Writely\"\nend\n```\n\nOr inline using attributes from the factory:\n\n```rb\nfactory :post do\n  # ...\n  author_last_name { \"Writely\" }\n  author { association :author, last_name: author_last_name }\nend\n```\n"
  },
  {
    "path": "docs/src/associations/specifying-the-factory.md",
    "content": "# Specifying the factory\n\nYou can specify a different factory (although [Aliases](../aliases/summary.md)\nmight also help you out here).\n\nImplicitly:\n\n```ruby\nfactory :post do\n  # ...\n  author factory: :user\nend\n```\n\nExplicitly:\n\n```ruby\nfactory :post do\n  # ...\n  association :author, factory: :user\nend\n```\n\nInline:\n\n```ruby\nfactory :post do\n  # ...\n  author { association :user }\nend\n```\n"
  },
  {
    "path": "docs/src/associations/summary.md",
    "content": "# Associations\n"
  },
  {
    "path": "docs/src/building-or-creating-multiple-records/summary.md",
    "content": "# Building or Creating Multiple Records\n\nSometimes, you'll want to create or build multiple instances of a factory at\nonce.\n\n```ruby\nbuilt_users   = build_list(:user, 25)\ncreated_users = create_list(:user, 25)\n```\n\nThese methods will build or create a specific amount of factories and return\nthem as an array. To set the attributes for each of the factories, you can pass\nin a hash as you normally would.\n\n```ruby\ntwenty_year_olds = build_list(:user, 25, date_of_birth: 20.years.ago)\n```\n\nIn order to set different attributes for each factory, these methods may be\npassed a block, with the factory and the index as parameters:\n\n```ruby\ntwenty_somethings = build_list(:user, 10) do |user, i|\n  user.date_of_birth = (20 + i).years.ago\nend\n```\n\n`create_list` passes saved instances into the block. If you modify the\ninstance, you must save it again:\n\n```ruby\ntwenty_somethings = create_list(:user, 10) do |user, i|\n  user.date_of_birth = (20 + i).years.ago\n  user.save!\nend\n```\n\n`build_stubbed_list` will give you fully stubbed out instances:\n\n```ruby\nstubbed_users = build_stubbed_list(:user, 25) # array of stubbed users\n```\n\nThere's also a set of `*_pair` methods for creating two records at a time:\n\n```ruby\nbuilt_users   = build_pair(:user) # array of two built users\ncreated_users = create_pair(:user) # array of two created users\n```\n\nIf you need multiple attribute hashes, `attributes_for_list` will generate\nthem:\n\n```ruby\nusers_attrs = attributes_for_list(:user, 25) # array of attribute hashes\n```\n\n"
  },
  {
    "path": "docs/src/callbacks/callback_order.md",
    "content": "# Callback Order\n\nWhen a callback event like `after_build` or `before_all` is triggered, all callbacks for that event are executed in the following order:\n\n1. Global callbacks.\n2. Inherited callbacks.\n3. Factory callbacks.\n4. Trait callbacks (in the order requested).\n\n## A simple factory example:\n\n```ruby\nFactoryBot.define do\n  before(:all) { puts \"Global before(:all)\" }\n  after(:all) { puts \"Global after(:all)\" }\n\n  factory :user do\n    before(:all) { puts \"User before(:all)\" }\n    after(:all) { puts \"User after(:all)\" }\n    before(:build) { puts \"User before(:build)\" }\n    after(:build) { puts \"User after(:build)\" }\n\n    trait :trait_a do\n      before(:build) { puts \"Trait-A before(:build)\" }\n      after(:build) { puts \"Trait-A after(:build)\" }\n    end\n\n    trait :trait_b do\n      before(:build) { puts \"Trait-B before(:build)\" }\n      after(:build) { puts \"Trait-B after(:build)\" }\n    end\n  end\nend\n\nbuild(:user, :trait_b, :trait_a)\n\n# Result:\n#\n# 1. \"Global before(:all)\"\n# 2. \"User before(:all)\"\n# 3. \"User before(:build)\n# 4. \"Trait-B before(:build)\"\n# 5. \"Trait-A before(:build)\"\n# 6. \"User after(:build)\"\n# 7. \"Trait-B after(:build)\"\n# 8. \"Trait-A after(:build)\"\n# 9. \"Global after(:all)\"\n# 10. \"User after(:all)\"\n\n```\n\n\n## An inherited factory example:\n\n```ruby\nFactoryBot.define do\n  before(:all) { puts \"Global before(:all)\" }\n  before(:build) { puts \"Global before(:build)\" }\n  after(:build) { puts \"Global after(:build)\" }\n  after(:all) { puts \"Global after(:all)\" }\n\n  factory :parent do\n    before(:all) { puts \"Parent before(:all)\" }\n    before(:build) { puts \"Parent before(:build)\" }\n    after(:all) { puts \"Parent after(:all)\" }\n    after(:build) { puts \"Parent after(:build)\" }\n\n    trait :trait_a do\n      before(:build) { puts \"Trait-A before(:build)\" }\n      after(:build) { puts \"Trait-A after(:build)\" }\n    end\n\n    factory :child do\n      before(:all) { puts \"Child before(:all)\" }\n      before(:build) { puts \"Child before(:build)\" }\n      after(:build) { puts \"Child after(:build)\" }\n      after(:all) { puts \"Child after(:all)\" }\n\n      trait :trait_b do\n        before(:build) { puts \"Trait-B before(:build)\" }\n        after(:build) { puts \"Trait-B after(:build)\" }\n        after(:all) { puts \"Trait-B after(:all)\" }\n      end\n\n      trait :trait_c do\n        before(:build) { puts \"Trait-C before(:build)\" }\n        after(:build) { puts \"Trait-C after(:build)\" }\n        before(:all) { puts \"Trait-C before(:all)\" }\n      end\n    end\n  end\nend\n\nbuild(:child, :trait_c, :trait_a, :trait_b)\n\n# Result:\n#\n# 1. \"Global before(:all)\"\n# 2. \"Parent before(:all)\"\n# 3. \"Child before(:all)\"\n# 4. \"Trait-C before(:all)\"\n# 5. \"Global before(:build)\"\n# 6. \"Parent before(:build)\"\n# 7. \"Child before(:build)\"\n# 8. \"Trait-C before(:build)\"\n# 9. \"Trait-A before(:build)\"\n# 10. \"Trait-B before(:build)\"\n# 11. \"Global after(:build)\"\n# 12. \"Parent after(:build)\"\n# 13. \"Child after(:build)\"\n# 14. \"Trait-C after(:build)\"\n# 15. \"Trait-A after(:build)\"\n# 16. \"Trait-B after(:build)\"\n# 17. \"Global after(:all)\"\n# 18. \"Parent after(:all)\"\n# 19. \"Child after(:all)\"\n# 20. \"Trait-B after(:all)\"\n```\n"
  },
  {
    "path": "docs/src/callbacks/default-callbacks.md",
    "content": "# Default callbacks\n\nfactory\\_bot makes available four callbacks for injecting some code:\n\n* before(:all)    - called before any strategy is used (e.g., `FactoryBot.build`, `FactoryBot.create`, `FactoryBot.build_stubbed`)\n* before(:build)  - called before a factory is built   (via `FactoryBot.build`, `FactoryBot.create`)\n* after(:build)   - called after a factory is built    (via `FactoryBot.build`, `FactoryBot.create`)\n* before(:create) - called before a factory is saved   (via `FactoryBot.create`)\n* after(:create)  - called after a factory is saved    (via `FactoryBot.create`)\n* after(:stub)    - called after a factory is stubbed  (via `FactoryBot.build_stubbed`)\n* after(:all)     - called after any strategy is used  (e.g., `FactoryBot.build`, `FactoryBot.create`, `FactoryBot.build_stubbed`)\n\nExamples:\n\n```ruby\n# Define a factory that calls the generate_hashed_password method after it is built\nfactory :user do\n  after(:build) { |user| generate_hashed_password(user) }\nend\n```\n\nNote that you'll have an instance of the object in the block. This can be useful.\n"
  },
  {
    "path": "docs/src/callbacks/global-callbacks.md",
    "content": "# Global callbacks\n\nTo override callbacks for all factories, define them within the\n`FactoryBot.define` block:\n\n```ruby\nFactoryBot.define do\n  after(:build) { |object| puts \"Built #{object}\" }\n  after(:create) { |object| AuditLog.create(attrs: object.attributes) }\n\n  factory :user do\n    name { \"John Doe\" }\n  end\nend\n```\n"
  },
  {
    "path": "docs/src/callbacks/multiple-callbacks.md",
    "content": "# Multiple callbacks\n\nYou can also define multiple types of callbacks on the same factory:\n\n```ruby\nfactory :user do\n  after(:build)  { |user| do_something_to(user) }\n  after(:create) { |user| do_something_else_to(user) }\nend\n```\n\nFactories can also define any number of the same kind of callback.  These\ncallbacks will be executed in the order they are specified:\n\n```ruby\nfactory :user do\n  after(:create) { this_runs_first }\n  after(:create) { then_this }\nend\n```\n\nCalling `create` will invoke both `after_build` and `after_create` callbacks.\n\nAlso, like standard attributes, child factories will inherit (and can also\ndefine) callbacks from their parent factory.\n\nMultiple callbacks can be assigned to run a block; this is useful when building\nvarious strategies that run the same code (since there are no callbacks that are\nshared across all strategies).\n\n```ruby\nfactory :user do\n  callback(:after_stub, :before_create) { do_something }\n  after(:stub, :create) { do_something_else }\n  before(:create, :custom) { do_a_third_thing }\nend\n```\n"
  },
  {
    "path": "docs/src/callbacks/summary.md",
    "content": "# Callbacks\n\nfactory\\_bot makes six callbacks available:\n\n| Callback        | Timing                                                                                                                    |\n| --------------- | ------------------------------------------------------------------------------------------------------------------------- |\n| before(:all)    | called before any strategy is used to construct an object, including custom strategies                                    |\n| before(:build)  | called before a factory builds an object (via `FactoryBot.build` or `FactoryBot.create`)                                  |\n| after(:build)   | called after a factory builds an object (via `FactoryBot.build` or `FactoryBot.create`)                                   |\n| before(:create) | called before a factory saves an object (via `FactoryBot.create`)                                                         |\n| after(:create)  | called after a factory saves an object (via `FactoryBot.create`)                                                          |\n| after(:stub)    | called after a factory stubs an object (via `FactoryBot.build_stubbed`)                                                   |\n| after(:all)     | called after any strategy has completed, including custom strategies                                                      |\n\n\n## Examples\n\n### Calling an object's own method after building\n\n```ruby\n##\n# Define a factory that calls the generate_hashed_password method\n# after the user factory is built.\n#\n# Note that you'll have an instance of the object in the block\n#\nfactory :user do\n  after(:build) { |user, context| generate_hashed_password(user) }\nend\n```\n\n### Skipping an object's own :after_create callback\n\n```ruby\n##\n# Disable a model's own :after_create callback that sends an email\n# on creation, then re-enable it afterwards\n#\nfactory :user do\n  before(:all){ User.skip_callback(:create, :after, :send_welcome_email) }\n  after(:all){ User.set_callback(:create, :after, :send_welcome_email) }\nend\n```\n"
  },
  {
    "path": "docs/src/callbacks/symbol-to_proc.md",
    "content": "# Symbol#to_proc\n\nYou can call callbacks that rely on `Symbol#to_proc`:\n\n```ruby\n# app/models/user.rb\nclass User < ActiveRecord::Base\n  def confirm!\n    # confirm the user account\n  end\nend\n\n# spec/factories.rb\nFactoryBot.define do\n  factory :user do\n    after :create, &:confirm!\n  end\nend\n\ncreate(:user) # creates the user and confirms it\n```\n"
  },
  {
    "path": "docs/src/cookbook/has_and_belongs_to_many-associations.md",
    "content": "# has_and_belongs_to_many associations\n\nGenerating data for a `has_and_belongs_to_many` relationship is very similar\nto the above `has_many` relationship, with a small change: you need to pass an\narray of objects to the model's pluralized attribute name rather than a single\nobject to the singular version of the attribute name.\n\n\n```ruby\ndef profile_with_languages(languages_count: 2)\n  FactoryBot.create(:profile) do |profile|\n    FactoryBot.create_list(:language, languages_count, profiles: [profile])\n  end\nend\n```\n\nOr with the callback approach:\n\n```ruby\nfactory :profile_with_languages do\n  transient do\n    languages_count { 2 }\n  end\n\n  after(:create) do |profile, context|\n    create_list(:language, context.languages_count, profiles: [profile])\n    profile.reload\n  end\nend\n```\n\nOr the inline association approach (note the use of the `instance` method here\nto refer to the profile being built):\n\n```ruby\nfactory :profile_with_languages do\n  transient do\n    languages_count { 2 }\n  end\n\n  languages do\n    Array.new(languages_count) do\n      association(:language, profiles: [instance])\n    end\n  end\nend\n```\n"
  },
  {
    "path": "docs/src/cookbook/has_many-associations.md",
    "content": "# has_many associations\n\nThere are a few ways to generate data for a `has_many` relationship. The\nsimplest approach is to write a helper method in plain Ruby to tie together the\ndifferent records:\n\n```ruby\nFactoryBot.define do\n  factory :post do\n    title { \"Through the Looking Glass\" }\n    user\n  end\n\n  factory :user do\n    name { \"Rachel Sanchez\" }\n  end\nend\n\ndef user_with_posts(posts_count: 5)\n  FactoryBot.create(:user) do |user|\n    FactoryBot.create_list(:post, posts_count, user: user)\n  end\nend\n\ncreate(:user).posts.length # 0\nuser_with_posts.posts.length # 5\nuser_with_posts(posts_count: 15).posts.length # 15\n```\n\nIf you prefer to keep the object creation fully within factory\\_bot, you can\nbuild the posts in an `after(:create)` callback.\n\n\n```ruby\nFactoryBot.define do\n  factory :post do\n    title { \"Through the Looking Glass\" }\n    user\n  end\n\n  factory :user do\n    name { \"John Doe\" }\n\n    # user_with_posts will create post data after the user has been created\n    factory :user_with_posts do\n      # posts_count is declared as a transient attribute available in the\n      # callback via the context\n      transient do\n        posts_count { 5 }\n      end\n\n      # the after(:create) yields two values; the user instance itself and the\n      # context, which stores all values from the factory, including transient\n      # attributes; `create_list`'s second argument is the number of records\n      # to create and we make sure the user is associated properly to the post\n      after(:create) do |user, context|\n        create_list(:post, context.posts_count, user: user)\n\n        # You may need to reload the record here, depending on your application\n        user.reload\n      end\n    end\n  end\nend\n\ncreate(:user).posts.length # 0\ncreate(:user_with_posts).posts.length # 5\ncreate(:user_with_posts, posts_count: 15).posts.length # 15\n```\n\nThe following is a simple example that works without having to save to the\ndatabase. It works with `build`, `build_stubbed`, and `create` (although it\ndoesn't work well with `attributes_for`), you can use inline associations:\n\n```ruby\nFactoryBot.define do\n  factory :post do\n    title { \"Through the Looking Glass\" }\n    user\n  end\n\n  factory :user do\n    name { \"Taylor Kim\" }\n\n    factory :user_with_posts do\n      posts { [association(:post)] }\n    end\n\n    # or\n\n    trait :with_posts do\n      posts { [association(:post)] }\n    end\n  end\nend\n\ncreate(:user).posts.length # 0\ncreate(:user_with_posts).posts.length # 1\nbuild(:user_with_posts).posts.length # 1\nbuild_stubbed(:user_with_posts).posts.length # 1\n```\n\nFor more flexibility you can combine this with the `posts_count` transient\nattribute from the callback example:\n\n```ruby\nFactoryBot.define do\n  factory :post do\n    title { \"Through the Looking Glass\" }\n    user\n  end\n\n  factory :user do\n    name { \"Adiza Kumato\" }\n\n    factory :user_with_posts do\n      transient do\n        posts_count { 5 }\n      end\n\n      posts do\n        Array.new(posts_count) { association(:post) }\n      end\n    end\n  end\nend\n\ncreate(:user_with_posts).posts.length # 5\ncreate(:user_with_posts, posts_count: 15).posts.length # 15\nbuild(:user_with_posts, posts_count: 15).posts.length # 15\nbuild_stubbed(:user_with_posts, posts_count: 15).posts.length # 15\n```\n"
  },
  {
    "path": "docs/src/cookbook/interconnected-associations.md",
    "content": "# Interconnected associations\n\nThere are limitless ways objects might be interconnected, and\nfactory\\_bot may not always be suited to handle those relationships. In some\ncases it makes sense to use factory\\_bot to build each individual object, and\nthen to write helper methods in plain Ruby to tie those objects together.\n\nThat said, some more complex, interconnected relationships can be built in factory\\_bot\nusing inline associations with reference to the `instance` being built.\n\nLet's say your models look like this, where an associated `Student` and\n`Profile` should both belong to the same `School`:\n\n```ruby\nclass Student < ApplicationRecord\n  belongs_to :school\n  has_one :profile\nend\n\nclass Profile < ApplicationRecord\n  belongs_to :school\n  belongs_to :student\nend\n\nclass School < ApplicationRecord\n  has_many :students\n  has_many :profiles\nend\n```\n\nWe can ensure the student and profile are connected to each other and to the\nsame school with a factory like this:\n\n```ruby\nFactoryBot.define do\n  factory :student do\n    school\n    profile { association :profile, student: instance, school: school }\n  end\n\n  factory :profile do\n    school\n    student { association :student, profile: instance, school: school }\n  end\n\n  factory :school\nend\n```\n\nNote that this approach works with `build`, `build_stubbed`, and `create`, but\nthe associations will return `nil` when using `attributes_for`.\n\nAlso, note that if you assign any attributes inside a custom `initialize_with` \n(e.g. `initialize_with { new(**attributes) }`), those attributes should not refer to `instance`,\nsince it will be `nil`.\n"
  },
  {
    "path": "docs/src/cookbook/polymorphic-associations.md",
    "content": "# Polymorphic associations\n\nPolymorphic associations can be handled with traits:\n\n```ruby\nFactoryBot.define do\n  factory :video\n  factory :photo\n\n  factory :comment do\n    for_photo # default to the :for_photo trait if none is specified\n\n    trait :for_video do\n      association :commentable, factory: :video\n    end\n\n    trait :for_photo do\n      association :commentable, factory: :photo\n    end\n  end\nend\n```\n\nThis allows us to do:\n\n```ruby\ncreate(:comment)\ncreate(:comment, :for_video)\ncreate(:comment, :for_photo)\n```\n"
  },
  {
    "path": "docs/src/custom-callbacks/summary.md",
    "content": "# Custom Callbacks\n\nCustom callbacks can be defined if you're using custom strategies:\n\n```ruby\nclass JsonStrategy\n  def initialize\n    @strategy = FactoryBot.strategy_by_name(:create).new\n  end\n\n  delegate :association, to: :@strategy\n\n  def result(evaluation)\n    result = @strategy.result(evaluation)\n    evaluation.notify(:before_json, result)\n\n    result.to_json.tap do |json|\n      evaluation.notify(:after_json, json)\n      evaluation.notify(:make_json_awesome, json)\n    end\n  end\n\n  def to_sym\n    :json\n  end\nend\n\nFactoryBot.register_strategy(:json, JsonStrategy)\n\nFactoryBot.define do\n  factory :user do\n    before(:json)                { |user| do_something_to(user) }\n    after(:json)                 { |user_json| do_something_to(user_json) }\n    callback(:make_json_awesome) { |user_json| do_something_to(user_json) }\n  end\nend\n```\n"
  },
  {
    "path": "docs/src/custom-construction/summary.md",
    "content": "# Custom Construction\n\nIf you want to use factory\\_bot to construct an object where some attributes\nare passed to `initialize` or if you want to do something other than simply\ncalling `new` on your build class, you can override the default behavior by\ndefining `initialize_with` on your factory. Example:\n\n```ruby\n# user.rb\nclass User\n  attr_accessor :name, :email\n\n  def initialize(name)\n    @name = name\n  end\nend\n\n# factories.rb\nsequence(:email) { |n| \"person#{n}@example.com\" }\n\nfactory :user do\n  name { \"Jane Doe\" }\n  email\n\n  initialize_with { new(name) }\nend\n\nbuild(:user).name # Jane Doe\n```\n\nAlthough factory\\_bot is written to work with ActiveRecord out of the box, it\ncan also work with any Ruby class. For maximum compatibility with ActiveRecord,\nthe default initializer builds all instances by calling `new` on your build\nclass without any arguments. It then calls attribute writer methods to assign\nall the attribute values. While that works fine for ActiveRecord, it actually\ndoesn't work for almost any other Ruby class.\n\nYou can override the initializer in order to:\n\n* Build non-ActiveRecord objects that require arguments to `initialize`\n* Use a method other than `new` to instantiate the instance\n* Do wild things like decorate the instance after it's built\n\nWhen using `initialize_with`, you don't have to declare the class itself when\ncalling `new`; however, any other class methods you want to call will have to\nbe called on the class explicitly.\n\nFor example:\n\n```ruby\nfactory :user do\n  name { \"John Doe\" }\n\n  initialize_with { User.build_with_name(name) }\nend\n```\n\nYou can also access all public attributes within the `initialize_with` block\nby calling `attributes`:\n\n```ruby\nfactory :user do\n  transient do\n    comments_count { 5 }\n  end\n\n  name \"John Doe\"\n\n  initialize_with { new(**attributes) }\nend\n```\n\nThis will build a hash of all attributes to be passed to `new`. It won't\ninclude transient attributes, but everything else defined in the factory will\nbe passed (associations, evaluated sequences, etc.)\n\nYou can define `initialize_with` for all factories by including it in the\n`FactoryBot.define` block:\n\n```ruby\nFactoryBot.define do\n  initialize_with { new(\"Awesome first argument\") }\nend\n```\n\nWhen using `initialize_with`, attributes accessed from within the\n`initialize_with` block are assigned *only* in the constructor; this equates to\nroughly the following code:\n\n```ruby\nFactoryBot.define do\n  factory :user do\n    initialize_with { new(name) }\n\n    name { 'value' }\n  end\nend\n\nbuild(:user)\n# runs\nUser.new('value')\n```\n\nThis prevents duplicate assignment; in versions of factory\\_bot before 4.0, it\nwould run this:\n\n```ruby\nFactoryBot.define do\n  factory :user do\n    initialize_with { new(name) }\n\n    name { 'value' }\n  end\nend\n\nbuild(:user)\n# runs\nuser = User.new('value')\nuser.name = 'value'\n```\n"
  },
  {
    "path": "docs/src/custom-methods-to-persist-objects/summary.md",
    "content": "# Custom Methods to Persist Objects\n\nBy default, creating a record will call `save!` on the instance; since this may\nnot always be ideal, you can override that behavior by defining `to_create` on\nthe factory:\n\n```ruby\nfactory :different_orm_model do\n  to_create { |instance| instance.persist! }\nend\n```\n\nTo disable the persistence method altogether on create, you can `skip_create`\nfor that factory:\n\n```ruby\nfactory :user_without_database do\n  skip_create\nend\n```\n\nTo override `to_create` for all factories, define it within the\n`FactoryBot.define` block:\n\n```ruby\nFactoryBot.define do\n  to_create { |instance| instance.persist! }\n\n\n  factory :user do\n    name { \"John Doe\" }\n  end\nend\n```\n"
  },
  {
    "path": "docs/src/custom-strategies/summary.md",
    "content": "# Custom Strategies\n\nThere are times where you may want to extend behavior of factory\\_bot by adding\na custom build strategy.\n\nStrategies define two methods: `association` and `result`. `association`\nreceives a `FactoryBot::FactoryRunner` instance, upon which you can call `run`,\noverriding the strategy if you want. The second method, `result`, receives a\n`FactoryBot::Evaluation` instance. It provides a way to trigger callbacks (with\n`notify`), `object` or `hash` (to get the result instance or a hash based on\nthe attributes defined in the factory), and `create`, which executes the\n`to_create` callback defined on the factory.\n\nTo understand how factory\\_bot uses strategies internally, it's probably\neasiest to view the source for each of the four default strategies.\n\nHere's an example of composing a strategy using `FactoryBot::Strategy::Create`\nto build a JSON representation of your model.\n\n```ruby\nclass JsonStrategy\n  def initialize\n    @strategy = FactoryBot.strategy_by_name(:create).new\n  end\n\n  delegate :association, to: :@strategy\n\n  def result(evaluation)\n    @strategy.result(evaluation).to_json\n  end\n\n  def to_sym\n    :json\n  end\nend\n```\n\nFor factory\\_bot to recognize the new strategy, you can register it:\n\n```ruby\nFactoryBot.register_strategy(:json, JsonStrategy)\n```\n\nThis allows you to call\n\n```ruby\nFactoryBot.json(:user)\n```\n\nFinally, you can override factory\\_bot's own strategies if you'd like by\nregistering a new object in place of the strategies.\n"
  },
  {
    "path": "docs/src/defining/best-practices.md",
    "content": "# Best practices\n\nIt is recommended that you have one factory for each class that provides\nthe simplest set of attributes necessary to create an instance of that class. If\nyou're creating ActiveRecord objects, that means that you should only provide\nattributes that are required through validations and that do not have defaults.\nOther factories can be created through inheritance to cover common scenarios for\neach class.\n\nAttempting to define multiple factories with the same name will raise an error.\n"
  },
  {
    "path": "docs/src/defining/explicit-class.md",
    "content": "# Specifying the class explicitly\n\nIt is also possible to explicitly specify the class:\n\n```ruby\n# This will use the User class (otherwise Admin would have been guessed)\nfactory :admin, class: \"User\"\n```\n\nYou can pass a constant as well, if the constant is available (note that this\ncan cause test performance problems in large Rails applications, since\nreferring to the constant will cause it to be eagerly loaded).\n\n```ruby\nfactory :access_token, class: User\n```\n"
  },
  {
    "path": "docs/src/defining/file-paths.md",
    "content": "# Definition file paths\n\nFactories can be defined anywhere, but will be automatically loaded after\ncalling `FactoryBot.find_definitions` if factories are defined in files at the\nfollowing locations:\n\n    factories.rb\n    factories/**/*.rb\n    test/factories.rb\n    test/factories/**/*.rb\n    spec/factories.rb\n    spec/factories/**/*.rb\n"
  },
  {
    "path": "docs/src/defining/hash-attributes.md",
    "content": "# Hash attributes\n\nBecause of the block syntax in Ruby, defining attributes as `Hash`es (for\nserialized/JSON columns, for example) requires two sets of curly brackets:\n\n```ruby\nfactory :program do\n  configuration { { auto_resolve: false, auto_define: true } }\nend\n```\n\nAlternatively you may prefer `do`/`end` syntax:\n\n```ruby\nfactory :program do\n  configuration do\n    { auto_resolve: false, auto_define: true }\n  end\nend\n```\n\n---\n\nHowever, defining a value as a hash makes it complicated to set values within\nthe hash when constructing an object. Instead, prefer to use factory\\_bot\nitself:\n\n```ruby\nfactory :program do\n  configuration { attributes_for(:configuration) }\nend\n\nfactory :configuration do\n  auto_resolve { false }\n  auto_define { true }\nend\n```\n\nThis way you can more easily set value when building:\n\n```ruby\ncreate(\n  :program,\n  configuration: attributes_for(\n    :configuration,\n    auto_resolve: true,\n  )\n)\n```\n"
  },
  {
    "path": "docs/src/defining/name-attributes.md",
    "content": "# Factory name and attributes\n\nEach factory has a name and a set of attributes. The name is used to guess the\nclass of the object by default:\n\n```ruby\n# This will guess the User class\nFactoryBot.define do\n  factory :user do\n    first_name { \"John\" }\n    last_name  { \"Doe\" }\n    admin { false }\n  end\nend\n```\n"
  },
  {
    "path": "docs/src/defining/static-attributes.md",
    "content": "# Static Attributes\n\nStatic attributes (without a block) are no longer available in factory\\_bot 5.\nYou can read more about the decision to remove them in\n[this blog post](https://robots.thoughtbot.com/deprecating-static-attributes-in-factory_bot-4-11).\n"
  },
  {
    "path": "docs/src/defining/summary.md",
    "content": "# Defining factories\n"
  },
  {
    "path": "docs/src/dependent-attributes/summary.md",
    "content": "# Dependent Attributes\n\nAttributes can be based on the values of other attributes using the context\nthat is yielded to dynamic attribute blocks:\n\n```ruby\nfactory :user do\n  first_name { \"Joe\" }\n  last_name  { \"Blow\" }\n  email { \"#{first_name}.#{last_name}@example.com\".downcase }\nend\n\ncreate(:user, last_name: \"Doe\").email\n# => \"joe.doe@example.com\"\n```\n"
  },
  {
    "path": "docs/src/inheritance/assigning-parent-explicitly.md",
    "content": "# Assigning parent explicitly\n\nYou can also assign the parent explicitly:\n\n```ruby\nfactory :post do\n  title { \"A title\" }\nend\n\nfactory :approved_post, parent: :post do\n  approved { true }\nend\n```\n"
  },
  {
    "path": "docs/src/inheritance/best-practices.md",
    "content": "# Best practices\n\nAs mentioned above, it's good practice to define a basic factory for each class\nwith only the attributes required to create it. Then, create more specific\nfactories that inherit from this basic parent.\n"
  },
  {
    "path": "docs/src/inheritance/nested-factories.md",
    "content": "# Nested factories\n\nYou can create multiple factories for the same class without repeating common\nattributes by nesting factories:\n\n```ruby\nfactory :post do\n  title { \"A title\" }\n\n  factory :approved_post do\n    approved { true }\n  end\nend\n\napproved_post = create(:approved_post)\napproved_post.title    # => \"A title\"\napproved_post.approved # => true\n```\n"
  },
  {
    "path": "docs/src/inheritance/summary.md",
    "content": "# Inheritance\n"
  },
  {
    "path": "docs/src/intro.md",
    "content": "# Intro\n\nfactory_bot is a fixtures replacement with a straightforward definition syntax,\nsupport for multiple build strategies (saved instances, unsaved instances,\nattribute hashes, and stubbed objects), and support for multiple factories for\nthe same class (user, admin_user, and so on), including factory inheritance.\n\nIts documentation is split as such:\n\n- the [guide](setup/summary.html) is a great place to start for first-time users.\n- the [cookbook](cookbook/has_many-associations.html) is the go-to place for creative solutions to common situations.\n- the [wiki](https://github.com/thoughtbot/factory_bot/wiki) details considerations for integrating with other software.\n- the [reference](ref/build-strategies.html) is terse facts for those who use this project often.\n\n## License\n\nfactory_bot is Copyright © 2008 Joe Ferris and thoughtbot. It is free\nsoftware, and may be redistributed under the terms specified in the\n[LICENSE] file.\n\n[LICENSE]: https://github.com/thoughtbot/factory_bot/blob/main/LICENSE\n\n## About thoughtbot\n\nfactory_bot is maintained and funded by thoughtbot, inc.\nThe names and logos for thoughtbot are trademarks of thoughtbot, inc.\n\nWe love open source software!\nSee [our other projects][community] or\n[hire us][hire] to design, develop, and grow your product.\n\n[community]: https://thoughtbot.com/community?utm_source=github\n[hire]: https://thoughtbot.com/hire-us?utm_source=github\n"
  },
  {
    "path": "docs/src/linting-factories/summary.md",
    "content": "# Linting Factories\n\nfactory\\_bot allows for linting known factories:\n\n```ruby\nFactoryBot.lint\n```\n\n`FactoryBot.lint` creates each factory and catches any exceptions raised during\nthe creation process. `FactoryBot::InvalidFactoryError` is raised with a list\nof factories (and corresponding exceptions) for factories which could not be\ncreated.\n\nRecommended usage of `FactoryBot.lint` is to run this in a separate task before\nyour test suite is executed. Running it in a `before(:suite)` will negatively\nimpact the performance of your tests when running single tests.\n\nExample Rake task:\n\n```ruby\n# lib/tasks/factory_bot.rake\nnamespace :factory_bot do\n  desc \"Verify that all FactoryBot factories are valid\"\n  task lint: :environment do\n    if Rails.env.test?\n      conn = ActiveRecord::Base.connection\n      conn.transaction do\n        FactoryBot.lint\n        raise ActiveRecord::Rollback\n      end\n    else\n      system(\"bundle exec rake factory_bot:lint RAILS_ENV='test'\")\n      fail if $?.exitstatus.nonzero?\n    end\n  end\nend\n```\n\nAfter calling `FactoryBot.lint`, you'll likely want to clear out the database,\nas records will most likely be created. The provided example above uses an SQL\ntransaction and rollback to leave the database clean.\n\nYou can lint factories selectively by passing only factories you want linted:\n\n```ruby\nfactories_to_lint = FactoryBot.factories.reject do |factory|\n  factory.name =~ /^old_/\nend\n\nFactoryBot.lint factories_to_lint\n```\n\nThis would lint all factories that aren't prefixed with `old_`.\n\nTraits can also be linted. This option verifies that each and every trait of a\nfactory generates a valid object on its own. This is turned on by passing\n`traits: true` to the `lint` method:\n\n```ruby\nFactoryBot.lint traits: true\n```\n\nThis can also be combined with other arguments:\n\n```ruby\nFactoryBot.lint factories_to_lint, traits: true\n```\n\nYou can also specify the strategy used for linting:\n\n```ruby\nFactoryBot.lint strategy: :build\n```\n\nVerbose linting will include full backtraces for each error, which can be\nhelpful for debugging:\n\n```ruby\nFactoryBot.lint verbose: true\n```\n"
  },
  {
    "path": "docs/src/method-name-reserved-word-attributes/summary.md",
    "content": "# Method Name / Reserved Word Attributes\n\nIf your attributes conflict with existing methods or reserved words (all\nmethods in the\n[DefinitionProxy](https://github.com/thoughtbot/factory_bot/blob/main/lib/factory_bot/definition_proxy.rb)\nclass) you can define them with `add_attribute`.\n\n```ruby\nfactory :dna do\n  add_attribute(:sequence) { 'GATTACA' }\nend\n\nfactory :payment do\n  add_attribute(:method) { 'paypal' }\nend\n```\n"
  },
  {
    "path": "docs/src/modifying-factories/summary.md",
    "content": "# Modifying factories\n\nIf you're given a set of factories (say, from a gem developer) but want to\nchange them to fit into your application better, you can modify that factory\ninstead of creating a child factory and adding attributes there.\n\nIf a gem were to give you a User factory:\n\n```ruby\nFactoryBot.define do\n  factory :user do\n    full_name { \"John Doe\" }\n    sequence(:username) { |n| \"user#{n}\" }\n    password { \"password\" }\n  end\nend\n```\n\nInstead of creating a child factory that added additional attributes:\n\n```ruby\nFactoryBot.define do\n  factory :application_user, parent: :user do\n    full_name { \"Jane Doe\" }\n    date_of_birth { 21.years.ago }\n    health { 90 }\n  end\nend\n```\n\nYou could modify that factory instead.\n\n```ruby\nFactoryBot.modify do\n  factory :user do\n    full_name { \"Jane Doe\" }\n    date_of_birth { 21.years.ago }\n    health { 90 }\n  end\nend\n```\n\nWhen modifying a factory, you can change any of the attributes you want (aside from callbacks).\n\n`FactoryBot.modify` must be called outside of a `FactoryBot.define` block as it\noperates on factories differently.\n\nA caveat: you can only modify factories (not sequences or traits), and\ncallbacks *still compound as they normally would*. So, if the factory you're\nmodifying defines an `after(:create)` callback, you defining an\n`after(:create)` won't override it, it will instead be run after the first\ncallback.\n"
  },
  {
    "path": "docs/src/rails-preloaders-and-rspec/summary.md",
    "content": "# Rails Preloaders and RSpec\n\nWhen running RSpec with a Rails preloader such as `spring` or `zeus`, it's\npossible to encounter an `ActiveRecord::AssociationTypeMismatch` error when\ncreating a factory with associations, as below:\n\n```ruby\nFactoryBot.define do\n  factory :united_states, class: \"Location\" do\n    name { 'United States' }\n    association :location_group, factory: :north_america\n  end\n\n  factory :north_america, class: \"LocationGroup\" do\n    name { 'North America' }\n  end\nend\n```\n\nThe error occurs during the run of the test suite:\n\n```\nFailure/Error: united_states = create(:united_states)\nActiveRecord::AssociationTypeMismatch:\n  LocationGroup(#70251250797320) expected, got LocationGroup(#70251200725840)\n```\n\nThe two possible solutions are to either run the suite without the preloader,\nor to add `FactoryBot.reload` to the RSpec configuration, like so:\n\n```ruby\nRSpec.configure do |config|\n  config.before(:suite) { FactoryBot.reload }\nend\n```\n"
  },
  {
    "path": "docs/src/ref/add_attribute.md",
    "content": "# add_attribute\n\nWithin a factory definition, the `add_attribute` method defines a key/value\npair that will be set when the object is built.\n\nThe `add_attribute` method takes two arguments: a name (Symbol or String) and a\nblock. This block is called each time this object is constructed. The block is\nnot called when the attribute is overridden by a build strategy.\n\nAssignment is done by calling the Ruby attribute setter. For example, given\n\n```ruby\nFactoryBot.define do\n  factory :user do\n    add_attribute(:name) { \"Acid Burn\" }\n  end\nend\n```\n\nThis will use the `#name=` setter:\n\n```ruby\nuser = User.new\nuser.name = \"Acid Burn\"\n```\n\nAlso see [method_missing](method_missing.html) for a shorthand.\n"
  },
  {
    "path": "docs/src/ref/association.md",
    "content": "# association\n\nWithin a factory block, use the `association` method to always make an\nadditional object alongside this one. This name best makes sense within the\ncontext of ActiveRecord.\n\nThe `association` method takes a mandatory name and optional options.\n\nThe options are zero or more trait names (Symbols), followed by a hash\nof attribute overrides. When constructing this association, factory\\_bot uses\nthe trait and attribute overrides given.\n\nSee [method_missing](method_missing.html) for a shorthand. See [build\nstrategies](build-strategies.html) for an explanation of how each build\nstrategy handles associations.\n"
  },
  {
    "path": "docs/src/ref/build-and-create.md",
    "content": "# skip_create, to_create, and initialize_with\n\nThe `skip_create`, `to_create`, and `initialize_with` methods control how\nfactory\\_bot interacts with the [build strategies](build-strategies.html).\n\nThese methods can be called within a `factory` definition block, to scope their\neffects to just that factory; or within `FactoryBot.define`, to affect global\nchange.\n\n## initialize_with\n\nThe `initialize_with` method takes a block and returns an instance of the\nfactory's class. It has access to the `attributes` method, which is a hash of\nall the fields and values for the object.\n\nThe default definition is:\n\n```ruby\ninitialize_with { new }\n```\n\n## to_create\n\nThe `to_create` method lets you control the `FactoryBot.create` strategy. This\nmethod takes a block which takes the object as constructed by\n`initialize_with`, and the factory\\_bot context. The context has additional\ndata from any [`transient`] blocks.\n\n[`transient`]: transient.html\n\nThe default definition is:\n\n```ruby\nto_create { |obj, context| obj.save! }\n```\n\nThe `skip_create` method is a shorthand for turning `to_create` into a no-op.\nThis allows you to use the `create` strategy as a synonym for `build`, except\nyou additionally get any `create` hooks.\n"
  },
  {
    "path": "docs/src/ref/build-strategies.md",
    "content": "# Build strategies\n\nOnce a factory\\_bot factory is defined, it can be constructed using any of the\nbuilt-in build strategies, or a custom build strategy.\n\nAll of these strategies notify on the `factory_bot.run_factory`\ninstrumentation using [ActiveSupport::Notifications], passing a payload with\n`:name`, `:strategy`, `:traits`, `:overrides`, and `:factory` keys.\n\n[ActiveSupport::Notifications]: https://api.rubyonrails.org/classes/ActiveSupport/Notifications.html\n\nThe non-list (`.build`, `.build_pair`, `.create`, etc.) methods take one\nmandatory argument: the name of the factory. They can then optionally take\nnames of traits, and then a hash of attributes to override. Finally, they can\ntake a block. This block takes the produced object as an argument, and returns\nan updated object.\n\nThe list methods (`.build_list`, `.create_list`, etc.) have two required\narguments: the name of the factory, and the number of instances to build. They\nthen can optionally take traits and overrides. Finally, they can take a block.\nThis block takes the produced object and the zero-based index as arguments, and\nreturns an updated object.\n\n## `build`\n\nThe `FactoryBot.build` method constructs an instance of the class according to\n`initialize_with`, which defaults to calling the `.new` class method.\n`.build_list` constructs multiple instances, and `.build_pair` is a shorthand\nto construct two instances.\n\nAfter it calls `initialize_with`, it invokes the `after_build` hook.\n\nAssociations are constructed using the `build` build strategy.\n\n## `create`\n\nThe `FactoryBot.create` method constructs an instance of the class according to\n`initialize_with`, and then persists it using `to_create`. The `.create_list`\nclass method constructs multiple instances, and `.create_pair` is a shorthand\nto construct two instances.\n\nAfter it calls `initialize_with`, it invokes the following hooks in order:\n\n1. `after_build`\n1. `before_create`\n1. non-hook: `to_create`\n1. `after_create`\n\nAssociations are constructed using the `create` build strategy.\n\nThe `to_create` hook controls how objects are persisted. It takes a block with\nthe object and the factory\\_bot context, and runs it for its side effect. By\ndefault, it calls `#save!`.\n\n## `attributes_for`\n\nThe `FactoryBot.attributes_for` method constructs a Hash with the attributes\nand their values, using `initialize_with`. The `attributes_for_pair` and\n`attributes_for_list` methods work similarly as `build_pair` and `build_list`.\n\nAssociations are constructed using the `null` build strategy (they are not built).\n\nNo hooks are called.\n\n## `build_stubbed`\n\nThe `FactoryBot.build_stubbed` method returns a fake ActiveRecord object. The\n`.build_stubbed_pair` and `.build_stubbed_list` methods are defined similarly\nto `.build_pair` and `.build_list`.\n\nIt uses `initialize_with` to construct the object, but then stubs methods and\ndata as appropriate:\n\n- `id` is set sequentially (unless overridden by attributes)\n- `created_at` and `updated_at` are set to the current time (unless overridden by attributes)\n- all [ActiveModel::Dirty] change tracking is cleared\n- `persisted?` is true\n- `new_record?` is false\n- `destroyed?` is false\n- persistence methods raise a `RuntimeError` (`#connection`, `#delete`, `#save`, `#update`, etc.)\n\n[ActiveModel::Dirty]: https://api.rubyonrails.org/classes/ActiveModel/Dirty.html\n\nAfter it sets up the object it invokes the `after_stub` hook.\n\n## `null`\n\nThe `FactoryBot.null` method returns `nil`. The `.null_pair` method gives you a\npair of nils, and `.null_list` gives as many nils as you desire. This is used\ninternally.\n"
  },
  {
    "path": "docs/src/ref/define.md",
    "content": "# FactoryBot.define\n\nEach file loaded by factory\\_bot is expected to call `FactoryBot.define` with a\nblock. The block is evaluated within an instance of\n`FactoryBot::Syntax::Default::DSL`, giving access to `factory`, `sequence`,\n`trait`, and other methods.\n"
  },
  {
    "path": "docs/src/ref/factory.md",
    "content": "# factory\n\nWithin a `FactoryBot.define` block, you can define factories. Anything defined\nusing `factory` can be built using a [build strategy](build-strategies.html).\n\nThe `factory` method takes three arguments: a required name, an optional hash\nof options, and an optional block.\n\nThe name is expected to be a Symbol.\n\n## Options\n\n- `:class` - what class to construct. This can be either a class, or a String\n  or Symbol (anything that responds to `#to_s`). By default it is either the\n  parent's class name or the factory's name.\n- `:parent`- the name of another factory that this factory should inherit from.\n  Defaults to `nil`.\n- `:aliases` - alternative names for this factory. Any of these names can be\n  used with a build strategy. Defaults to the empty list.\n- `:traits` - base traits that are used by default when building this factory.\n  Defaults to the empty list.\n\n## Block\n\nYou can use the block to define your factory. Within here you have access to the following methods:\n\n- [`add_attribute`](add_attribute.md)\n- [`association`](association.md)\n- [`sequence`](sequence.md)\n- [`trait`](trait.md)\n- [`method_missing`](method_missing.md)\n- [`transient`](transient.md)\n- [`traits_for_enum`](traits_for_enum.md)\n- [`initialize_with`](build-and-create.md#initialize_with)\n- [`skip_create`](build-and-create.md)\n- [`to_create`](build-and-create.md#to_create)\n- [`before`](hooks.md#after-and-before-methods)\n- [`after`](hooks.md#after-and-before-methods)\n- [`callback`](hooks.md#callback)\n- `factory`\n\nYou can use `factory` inside a `factory` block to define a new factory with an\nimplied parent.\n"
  },
  {
    "path": "docs/src/ref/find_definitions.md",
    "content": "# FactoryBot.find_definitions\n\nThe `FactoryBot.find_definitions` method loads in all factory\\_bot definitions\nacross the project.\n\nThe load order is controlled by the `FactoryBot.definition_file_paths`\nattribute. The default load order is:\n\n1. `factories.rb`\n1. `factories/**/*.rb`\n1. `test/factories.rb`\n1. `test/factories/**/*.rb`\n1. `spec/factories.rb`\n1. `spec/factories/**/*.rb`\n\n## Rails\n\nThe `.find_definitions` method is called automatically by `factory_bot_rails`\nafter initialize. The `.definition_file_paths` can be set during initialization\n(e.g. `config/initializers`), or via\n`Rails.application.config.factory_bot.definition_file_paths`.\n"
  },
  {
    "path": "docs/src/ref/hooks.md",
    "content": "# Hooks\n\nWithin a `factory` definition block and the `FactoryBot.define` block, you have\naccess to the `after`, `before`, and `callback` methods. This allow you to hook\ninto parts of the [build strategies].\n\n[build strategies]: build-strategies.html\n\nWithin a `factory` definition block, these callbacks are scoped to just that\nfactory. Within a `FactoryBot.define` block, they are global to all factories.\n\n## `callback`\n\nThe `callback` method allows you to hook into any factory\\_bot callback by\nname. The pre-defined names, as seen in the [build strategies] reference, are\n`before_all`, `after_build`, `before_create`, `after_create`, `after_stub`, and `after_all`.\n\nThis method takes a splat of names, and a block. It invokes the block any time\none of the names is activated. The block can be anything that responds to\n`#to_proc`.\n\nThis block takes two arguments: the instance of the factory, and the\nfactory\\_bot context. The context holds [transient](transient.html)\nattributes.\n\nThe same callback name can be hooked into multiple times. Every block is run,\nin the order it was defined. Callbacks are inherited from their parents; the\nparents' callbacks are run first.\n\n## `after` and `before` methods\n\nThe `after` and `before` methods add some nice syntax to `callback`:\n\n```ruby\nafter(:create) do |user, context|\n  user.post_first_article(context.article)\nend\n\ncallback(:after_create) do |user, context|\n  user.post_first_article(context.article)\nend\n```\n"
  },
  {
    "path": "docs/src/ref/lint.md",
    "content": "# FactoryBot.lint\n\nThe `FactoryBot.lint` method tries each factory and raises\n`FactoryBot::InvalidFactoryError` on failure.\n\nIt can take the following optional arguments:\n\n- A splat of factory names. This will restrict the linting to just the ones listed. The default is all.\n- `:strategy` - the [build strategy] to use. The default is `:create`.\n- `:traits` - whether to try building each trait, too. The default is `false`.\n- `:verbose` - whether to show a stack trace on error. The default is `false`.\n\n[build strategy]: build-strategies.html\n\nSuggested techniques for hooking `.lint` into your system is discussed in [the\nguide](../linting-factories/summary.html).\n"
  },
  {
    "path": "docs/src/ref/method_missing.md",
    "content": "# method_missing\n\nWith a `factory` definition block, you can use `add_attribute`, `association`,\n`sequence`, and `trait` to define a factory. You can also level a default\n`method_missing` definition for potential shortcuts.\n\nCalling an unknown method (e.g. `name`, `admin`, `email`, `account`) connects\nan association, sequence, trait, or attribute to the factory:\n\n1. If the method missing is passed a block, it always defines an attribute.\n   This allows you to set the value for the attribute.\n\n1. If the method missing is passed a hash as a argument with the key\n   `:factory`, then it always defines an association. This allows you to\n   override the factory used for the association.\n\n1. If there is another factory of the same name, then it defines an\n   association.\n\n1. If there is a global sequence of the same name, then it defines an attribute\n   with a value that pulls from the sequence.\n\n1. If there is a trait of the same name for that factory, then it turns that\n   trait on for all builds of this factory.\n\nUsing `method_missing` can turn an explicit definition:\n\n```ruby\nFactoryBot.define do\n  sequence(:email) { |n| \"person#{n}@example.com\" }\n  factory :account\n  factory :organization\n\n  factory :user, traits: [:admin] do\n    add_attribute(:name) { \"Lord Nikon\" }\n    add_attribute(:email) { generate(:email) }\n    association :account\n    association :org, factory: :organization\n\n    trait :admin do\n      add_attribute(:admin) { true }\n    end\n  end\nend\n```\n\n... into a more implicit definition:\n\n```ruby\nFactoryBot.define do\n  sequence(:email) { |n| \"person#{n}@example.com\" }\n  factory :account\n  factory :organization\n\n  factory :user do\n    name { \"Lord Nikon\" }      # no more `add_attribute`\n    admin                      # no more :traits\n    email                      # no more `add_attribute`\n    account                    # no more `association`\n    org factory: :organization # no more `association`\n\n    trait :admin do\n      admin { true }\n    end\n  end\nend\n```\n"
  },
  {
    "path": "docs/src/ref/modify.md",
    "content": "# FactoryBot.modify\n\nThe `FactoryBot.modify` class method defines a block with an _overriding_\n`factory` method available. That is the only method you can call within the\nblock.\n\nThe `factory` method within this block takes a mandatory factory name, and a\nblock. All other arguments are ignored. The factory name must already be\ndefined. The block is a normal [factory definition block](factory.html). Take\nnote that [hooks](hooks.html) cannot be cleared and continue to compound.\n\nFor details on why you'd want to use this, see [the\nguide](../modifying-factories/summary.html).\n"
  },
  {
    "path": "docs/src/ref/register_strategy.md",
    "content": "# FactoryBot.register_strategy\n\nThe `FactoryBot.register_strategy` method is how to add a [build\nstrategy](build-strategies.html).\n\nIt takes two mandatory arguments: name and class. The name is a Symbol, and\nregistering it exposes a method under `FactoryBot::Syntax::Methods`.\n\nThe class must define the methods `association` and `result`.\n\nThe `association` method takes an instance of `FactoryRunner`. You can `#run`\nthis runner, passing a strategy name (it defaults to the current one) and an\noptional block. The block is called after the association is built, and is\npassed the object that was built.\n\nThe `result` method takes the object that was built for this factory (using\n`initalize_with`), and returns the result of this factory for this build\nstrategy.\n"
  },
  {
    "path": "docs/src/ref/sequence.md",
    "content": "# sequence\n\nA factory\\_bot set up supports two levels of sequences: global and factory-specific.\n\n## Global sequences\n\nWith a [`Factory.define`] block, use the `sequence` method to define global\nsequences that can be shared with other factories.\n\n[`Factory.define`]: define.html\n\nThe `sequence` method takes a name, optional arguments, and a block. The name\nis expected to be a Symbol.\n\nThe supported arguments are a number representing the starting value (default:\n`1`), and `:aliases` (default `[]`). The starting value must respond to `#next`.\n\nThe block takes a value as an argument, and returns a result.\n\nThe sequence value is incremented globally. Using an `:email_address` sequence\nfrom multiple places increments the value each time.\n\nSee [method_missing](method_missing.html) for a shorthand.\n\n## Factory sequences\n\nSequences can be localized within `factory` blocks. The syntax is the same as\nfor a global sequence, but the scope of the incremented value is limited to the\nfactory definition.\n\nIn addition, using `sequence` with a `factory` block implicitly calls\n`add_attribute` for that value.\n\nThese two are similar, except the second example does not cause any global\nsequences to exist:\n\n```ruby\n# A global sequence\nsequence(:user_factory_email) { |n| \"person#{n}@example.com\" }\n\nfactory :user do\n  # Using a global sequence\n  email { generate(:user_factory_email) }\nend\n```\n\n```ruby\n# A factory-scoped sequence\nfactory :user do\n  sequence(:email) { |n| \"person#{n}@example.com\" }\nend\n```\n"
  },
  {
    "path": "docs/src/ref/trait.md",
    "content": "# trait\n\nWithin a `factory` definition block, use the `trait` method to define named permutations of the factory.\n\nThe trait method takes a name (Symbol) and a block. Treat the block like you\nwould a [`factory`] definition block.\n\n[`factory`]: factory.html\n\nSee [method_missing](method_missing.html) for a shorthand.\n"
  },
  {
    "path": "docs/src/ref/traits_for_enum.md",
    "content": "# traits_for_enum\n\nWith a `factory` definition block, the `traits_for_enum` method is a helper for\nany object with an attribute that can be one of a few values. The original\ninspiration was [`ActiveRecord::Enum`] but it can apply to any attribute with a\nrestricted set of values.\n\n[`ActiveRecord::Enum`]: https://api.rubyonrails.org/classes/ActiveRecord/Enum.html\n\nThis method creates a trait for each value.\n\nThe `traits_for_enum` method takes a required attribute name and an optional\nset of values. The values can be any Enumerable, such as Array or Hash. By\ndefault, the values are `nil`.\n\nIf the values are an Array, this method defines a trait for each element in the\narray. The trait's name is the array element, and it sets the attribute to the\nsame array element.\n\nIf the values are a Hash, this method defines traits based on the keys,\nsetting the attribute to the values. The trait's name is the key, and it sets\nthe attribute to the value.\n\nIf the value is any other Enumerable, it treats it like an Array or Hash based\non whether `#each` iterates in pairs like it does for Hashes.\n\nIf the value is nil, it uses a class method named after the pluralized\nattribute name.\n\n```ruby\nFactoryBot.define do\n  factory :article do\n    traits_for_enum :visibility, [:public, :private]\n    # trait :public do\n    #   visibility { :public }\n    # end\n    # trait :private do\n    #   visibility { :private }\n    # end\n\n    traits_for_enum :collaborative, draft: 0, shared: 1\n    # trait :draft do\n    #   collaborative { 0 }\n    # end\n    # trait :shared do\n    #   collaborative { 1 }\n    # end\n\n    traits_for_enum :status\n    # Article.statuses.each do |key, value|\n    #   trait key do\n    #     status { value }\n    #   end\n    # end\n  end\nend\n```\n"
  },
  {
    "path": "docs/src/ref/transient.md",
    "content": "# transient\n\nWithin a `factory` definition block, the goal is to construct an instance of\nthe class. While factory\\_bot does this, it keeps track of data in a\ncontext. To set data on this context, use a `transient` block.\n\nTreat a `transient` block like a `factory` definition block. However, none of\nthe attributes, associations, traits, or sequences you set will impact the\nfinal object.\n\nThis is most useful when paired with [hooks](hooks.html) or\n[to_create](build-and-create.html).\n"
  },
  {
    "path": "docs/src/sequences/aliases.md",
    "content": "# Aliases\n\nSequences can also have aliases. The sequence aliases share the same counter:\n\n```ruby\nfactory :user do\n  sequence(:email, 1000, aliases: [:sender, :receiver]) { |n| \"person#{n}@example.com\" }\nend\n\n# will increase value counter for :email which is shared by :sender and :receiver\ngenerate(:sender)\n```\n\nDefine aliases and use default value (1) for the counter\n\n```ruby\nfactory :user do\n  sequence(:email, aliases: [:sender, :receiver]) { |n| \"person#{n}@example.com\" }\nend\n```\n\nSetting the value:\n\n```ruby\nfactory :user do\n  sequence(:email, 'a', aliases: [:sender, :receiver]) { |n| \"person#{n}@example.com\" }\nend\n```\n\nThe value needs to support the `#next` method. Here the next value will be 'a',\nthen 'b', etc.\n"
  },
  {
    "path": "docs/src/sequences/as-implicit-attributes.md",
    "content": "# As implicit attributes\n\nOr as implicit attributes:\n\n```ruby\nFactoryBot.define do\n  sequence :email do |n|\n    \"person#{n}@example.com\"\n  end\nend\n\nfactory :user do\n  email # Same as `email { generate(:email) }`\nend\n```\n\nNote that defining sequences as implicit attributes will not work if you have a\nfactory with the same name as the sequence.\n"
  },
  {
    "path": "docs/src/sequences/factory-sequences.md",
    "content": "# Factory sequences\n\nAnd it's also possible to define a sequence that is only used in\na particular factory:\n\n```ruby\nfactory :user do\n  sequence(:email) { |n| \"person#{n}@example.com\" }\nend\n```\n\nWith Ruby 2.7's support for [numbered parameters][], inline definitions can be\neven more abbreviated:\n\n```ruby\nfactory :user do\n  sequence(:email) { \"person#{_1}@example.com\" }\nend\n```\n\n[numbered parameters]: https://ruby-doc.org/core-2.7.1/Proc.html#class-Proc-label-Numbered+parameters\n"
  },
  {
    "path": "docs/src/sequences/generating.md",
    "content": "# Generating a Sequence\n\nBeing able to directly generate a sequence, without having to build the object can really speed up testing. This can be achieved by passing the [sequence URI](sequence-uris.md) to `:generate` for a single value or `:generate_list` for an Array of sequential values.\n\n```ruby\nFactoryBot.define do\n  sequence(:char, 'a') {|c| \"global_character_#{c}\" }\n\n  factory :user do\n    sequence(:name, %w[Jane Joe Josh Jayde John].to_enum)\n\n    trait :with_age do\n      sequence(:age, 21)\n    end\n  end\nend\n\n##\n# char\ngenerate(:char) # \"global_character_a\"\ngenerate_list(:char, 2) # [\"global_character_b\", \"global_character_c\"]\ngenerate(:char) # \"global_character_d\"\n\n##\n# user name\ngenerate(:user, :name) # \"Jane\"\ngenerate_list(:user, :name, 3) # ['Joe', 'Josh', 'Jayde']\ngenerate(:user, :name) # \"John\"\n\n##\n# user age\ngenerate(:user, :with_age, :age) # 21\ngenerate_list(:user, :with_age, :age, 5) # [22, 23, 24, 25, 26]\ngenerate(:user, :with_age, :age) # 27\n```\n\n## Scope\n\nOn occasion a sequence block may refer to a scoped attribute. In this case, the scope must be provided, or else an exception will be raised:\n\n```ruby\nFactoryBot.define do\n  factory :user do\n    sequence(:email) { |n| \"#{name}-#{n}@example.com\" }\n  end\nend\n\ngenerate(:user, :email)\n# ArgumentError, Sequence user:email failed to return a value. Perhaps it needs a scope to operate? (scope: <object>)\n\njester = build(:user, name: \"Jester\")\njester.email # \"Jester-1@example.com\"\n\ngenerate(:user, :email, scope: jester)\n# \"Jester-2@example.com\"\n\ngenerate_list(:user, :email, 2, scope: jester)\n# [\"Jester-3@example.com\", \"Jester-4@example.com\"]\n```\n\nWhen testing, the scope can be any object that responds to the referenced attributes:\n\n```ruby\nrequire 'ostruct'\n\nFactoryBot.define\n  factory :user do\n    sequence(:info) { |n| \"#{name}-#{n}-#{age + n}\" }\n  end\nend\n\ntest_scope = OpenStruct.new(name: \"Jester\", age: 23)\n\ngenerate_list('user/info', 3, scope: test_scope)\n# [\"Jester-1-24\", \"Jester-2-25\", \"Jester-3-26\"]\n```\n"
  },
  {
    "path": "docs/src/sequences/global-sequences.md",
    "content": "# Global sequences\n\nUnique values in a specific format (for example, e-mail addresses) can be\ngenerated using sequences. Sequences are defined by calling `sequence` in a\ndefinition block, and values in a sequence are generated by calling `generate`:\n\n```ruby\n# Defines a new sequence\nFactoryBot.define do\n  sequence :email do |n|\n    \"person#{n}@example.com\"\n  end\nend\n\ngenerate :email\n# => \"person1@example.com\"\n\ngenerate :email\n# => \"person2@example.com\"\n```\n"
  },
  {
    "path": "docs/src/sequences/initial-value.md",
    "content": "# Initial value\n\nYou can override the initial value. Any value that responds to the `#next`\nmethod will work (e.g. 1, 2, 3, 'a', 'b', 'c')\n\n```ruby\nfactory :user do\n  sequence(:email, 1000) { |n| \"person#{n}@example.com\" }\nend\n```\n\nThe initial value can also be lazily set by passing a Proc as the value. This Proc will be called the first time the `sequence.next` is called.\n\n```ruby\nfactory :user do\n  sequence(:email, proc { Person.count + 1 }) { |n| \"person#{n}@example.com\" }\nend\n```\n"
  },
  {
    "path": "docs/src/sequences/rewinding.md",
    "content": "# Rewinding\n\nSequences can also be rewound to their starting value:\n\n## All sequences\n\nRewind all global and factory sequences with `FactoryBot.rewind_sequences`:\n\n```ruby\nFactoryBot.define do\n  sequence(:email) {|n| \"person#{n}@example.com\" }\n\n  factory :user do\n    sequence(:email) {|n| \"user#{n}@example.com\" }\n  end\nend\n\ngenerate(:email) # \"person1@example.com\"\ngenerate(:email) # \"person2@example.com\"\ngenerate(:email) # \"person3@example.com\"\n\ngenerate(:user, :email) # \"user1@example.com\"\ngenerate(:user, :email) # \"user2@example.com\"\ngenerate(:user, :email) # \"user3@example.com\"\n\nFactoryBot.rewind_sequences\n\ngenerate(:email)        # \"person1@example.com\"\ngenerate(:user, :email) # \"user1@example.com\"\n```\n\n## Individual sequences\n\nAn individual sequence can be rewound by passing the [sequence URI](sequence-uris.md) to `FactoryBot.rewind_sequence`:\n\n```ruby\nFactoryBot.define do\n  sequence(:email) {|n| \"global_email_#{n}@example.com\" }\n\n  factory :user do\n    sequence(:email) {|n| \"user_email_#{n}@example.com\" }\n  end\nend\n\nFactoryBot.rewind_sequence(:email)\ngenerate(:email)\n#=> \"global_email_1@example.com\"\n\nfactoryBot.rewind_sequence(:user, :email)\ngenerate(:user, :email)\n#=> \"user_email_1@example.com\"\n```\n"
  },
  {
    "path": "docs/src/sequences/sequence-uris.md",
    "content": "# Sequence URIs\n\nThere are many reasons to manipulate a specific sequence:\n\n- generating a single value with: `generate`\n- generating multiple values with: `generate_list`\n- setting it to a new value with `FactoryBot.set_sequence`\n- rewinding it with: `rewind_sequence`\n\nTo accomplish this we need to be able to reference the desired sequence. This is achieved with its unique URI.\n\n## URI Composition\n\nEach URI is composed of up to three names:\n\n| position | name           | required                                                             |\n| :------: | -------------- | -------------------------------------------------------------------- |\n|    1.    | factory name:  | **if** - the sequence is defined within a Factory or a Factory Trait |\n|    2.    | trait name:    | **if** - the sequence is defined within a Trait                      |\n|    3.    | sequence name: | **always required**                                                  |\n\nThe URI can be entered as individual symbols:\n\n```ruby\ngenerate(:my_factory_name, :my_trait_name, :my_sequence_name)\n```\n\n**or** as individual strings:\n\n```ruby\ngenerate('my_factory_name', 'my_trait_name', 'my_sequence_name')\n```\n\n**or** as a single resource string:\n\n```ruby\ngenerate(\"my_factory_name/my_trait_name/my_sequence_name\")\n```\n\n## Full URI example\n\nThis example details all the possible scenarios, with the comments showing the URI used to generate a value for each specific sequence:\n\n```ruby\nFactoryBot.define do\n  sequence(:sequence) {|n| \"global_sequence_#{n}\"}\n  # generate(:sequence)\n\n  trait :global_trait do\n    sequence(:sequence) {|n| \"global_trait_sequence_#{n}\"}\n    # generate(:global_trait, :sequence)\n  end\n\n  factory :user do\n    sequence(:sequence) {|n| \"user_sequence_#{n}\"}\n    # generate(:user, :sequence)\n\n    trait :user_trait do\n      sequence(:sequence) {|n| \"user_trait_sequence_#{n}\"}\n      # generate(:user, :user_trait, :sequence)\n    end\n\n    factory :author do\n      sequence(:sequence) {|n| \"author_sequence_#{n}\"}\n      # generate(:author, :sequence)\n\n      trait :author_trait do\n        sequence(:sequence) {|n| \"author_trait_sequence_#{n}\"}\n        # generate(:author, :author_trait, :sequence)\n      end\n    end\n  end\nend\n```\n\n## Multi URIs\n\nIt is possible for a single sequence to have multiple URIs.\n\nIf the factory or trait has aliases, the sequence will have an additional URI for each alias, or combination of aliases.\n\nIn this example, the same sequence can referenced in four different ways:\n\n```ruby\nfactory :user, aliases: [:author] do\n  trait :user_trait, aliases: [:author_trait] do\n    sequence(:sequence) {|n| \"author_trait_sequence_#{n}\"}\n  end\nend\n\n# generate(:user,   :user_trait,   :sequence)\n# generate(:user,   :author_trait, :sequence)\n# generate(:author, :user_trait,   :sequence)\n# generate(:author, :author_trait, :sequence)\n```\n\n<div class='warning'>\n\n## Important\n\n- No matter how deeply nested, the factory name component of the URI is always the factory where the sequence is defined, not any parent factories.\n\n- If a factory inherits a sequence, the URI must reference the factory where it was defined, not the one in which it is used.\n\n</div>\n"
  },
  {
    "path": "docs/src/sequences/setting-the-value.md",
    "content": "# Setting the value\n\nWhen testing or working in the console, being able to set the sequence to a specific value, is incredibly helpful. This can be achieved by passing the [sequence URI](sequence-uris.md) and the new value to `FactoryBot.set_sequence`:\n\n## Global Sequences\n\nGlobal sequences are set with the sequence name and the new value:\n\n```ruby\nFactoryBot.define do\n  sequence(:char, 'a') {|c| \"global_character_#{c}\" }\n\n  factory :user do\n    sequence(:name, %w[Jane Joe Josh Jayde John].to_enum)\n\n    trait :with_email do\n      sequence(:email) {|n| \"user_#{n}@example.com\" }\n    end\n  end\nend\n\n##\n# char\ngenerate(:char) # \"global_character_a\"\nFactoryBot.set_sequence(:char, 'z')\ngenerate(:char) # \"global_character_z\"\n\n##\n# user name\ngenerate(:user, :name) # \"Jane\"\nFactoryBot.set_sequence(:user, :name, 'Jayde')\ngenerate(:user, :name) # \"Jayde\"\n\n##\n# user email\ngenerate(:user, :with_email, :email) # \"user_1@example.com\"\nFactoryBot.set_sequence(:user, :with_email, :email, 1_234_567)\ngenerate(:user, :with_email, :email) # \"user_1234567@example.com\"\n```\n\n<div class='warning'>\n\n## Note\n\n- The new value must match the sequence collection: You cannot pass a String to an Integer based sequence!\n\n- An integer based sequence, such as a record ID, can accept any positive integer as the value.\n\n- A fixed collection sequence can accept any value within the collection.\n\n- An unlimited sequence, such as a character `sequence(:unlimited,'a')` will timeout if not found within the default maximum search time of three seconds.\n\n- The timeout can be configured with: `FactoryBot.sequence_setting_timeout = 1.5`\n\n</div>\n"
  },
  {
    "path": "docs/src/sequences/summary.md",
    "content": "# Sequences\n"
  },
  {
    "path": "docs/src/sequences/uniqueness.md",
    "content": "# Uniqueness\n\nWhen working with uniqueness constraints, be careful not to pass in override\nvalues that will conflict with the generated sequence values.\n\nIn this example the email will be the same for both users. If email must be\nunique, this code will error:\n\n```rb\nfactory :user do\n  sequence(:email) { |n| \"person#{n}@example.com\" }\nend\n\nFactoryBot.create(:user, email: \"person1@example.com\")\nFactoryBot.create(:user)\n```\n"
  },
  {
    "path": "docs/src/sequences/with-dynamic-attributes.md",
    "content": "# With dynamic attributes\n\nSequences can be used in dynamic attributes:\n\n```ruby\nFactoryBot.define do\n  sequence :email do |n|\n    \"person#{n}@example.com\"\n  end\nend\n\nfactory :invite do\n  invitee { generate(:email) }\nend\n```\n"
  },
  {
    "path": "docs/src/sequences/without-a-block.md",
    "content": "# Without a block\n\nWithout a block, the value will increment itself, starting at its initial value:\n\n```ruby\nfactory :post do\n  sequence(:position)\nend\n```\n\nNote that the value for the sequence could be any Enumerable instance, as long\nas it responds to `#next`:\n\n```ruby\nfactory :task do\n  sequence :priority, %i[low medium high urgent].cycle\nend\n```\n"
  },
  {
    "path": "docs/src/setup/summary.md",
    "content": "# Setup\n\nInstallation varies based on the framework you are using, if any, and\noptionally the test framework.\n\nSince installation varies based on code that we do not control, those docs are\nkept up-to-date in [our wiki]. We encourage you to edit the wiki as the\nframeworks change.\n\nBelow we document the most common setup. However, **we go into more detail in\n[our wiki]**.\n\n[our wiki]: https://github.com/thoughtbot/factory_bot/wiki/Installation\n\n## Update Your Gemfile\n\nIf you're using Rails:\n\n```ruby\ngem \"factory_bot_rails\"\n```\n\nIf you're *not* using Rails:\n\n```ruby\ngem \"factory_bot\"\n```\n\nFor more, see [our wiki].\n\n## Configure your test suite\n\n### RSpec\n\n```ruby\nRSpec.configure do |config|\n  config.include FactoryBot::Syntax::Methods\nend\n```\n\n### Test::Unit\n\n```ruby\nclass Test::Unit::TestCase\n  include FactoryBot::Syntax::Methods\nend\n```\n\nFor more, see [our wiki].\n"
  },
  {
    "path": "docs/src/traits/as-implicit-attributes.md",
    "content": "# As implicit attributes\n\nTraits can be used as implicit attributes:\n\n```ruby\nfactory :week_long_published_story_with_title, parent: :story do\n  published\n  week_long_publishing\n  title { \"Publishing that was started at #{start_at}\" }\nend\n```\n\nNote that defining traits as implicit attributes will not work if you have a\nfactory or sequence with the same name as the trait.\n"
  },
  {
    "path": "docs/src/traits/attribute-precedence.md",
    "content": "# Attribute precedence\n\nTraits that define the same attributes won't raise AttributeDefinitionErrors;\nthe trait that defines the attribute last gets precedence.\n\n```ruby\nfactory :user do\n  name { \"Friendly User\" }\n  login { name }\n\n  trait :active do\n    name { \"John Doe\" }\n    status { :active }\n    login { \"#{name} (active)\" }\n  end\n\n  trait :inactive do\n    name { \"Jane Doe\" }\n    status { :inactive }\n    login { \"#{name} (inactive)\" }\n  end\n\n  trait :admin do\n    admin { true }\n    login { \"admin-#{name}\" }\n  end\n\n  factory :active_admin,   traits: [:active, :admin]   # login will be \"admin-John Doe\"\n  factory :inactive_admin, traits: [:admin, :inactive] # login will be \"Jane Doe (inactive)\"\nend\n```\n"
  },
  {
    "path": "docs/src/traits/defining-traits.md",
    "content": "# Defining traits\n\nTraits allow you to group attributes together and then apply them\nto any factory.\n\n```ruby\nfactory :user, aliases: [:author]\n\nfactory :story do\n  title { \"My awesome story\" }\n  author\n\n  trait :published do\n    published { true }\n  end\n\n  trait :unpublished do\n    published { false }\n  end\n\n  trait :week_long_publishing do\n    start_at { 1.week.ago }\n    end_at { Time.now }\n  end\n\n  trait :month_long_publishing do\n    start_at { 1.month.ago }\n    end_at { Time.now }\n  end\n\n  factory :week_long_published_story,    traits: [:published, :week_long_publishing]\n  factory :month_long_published_story,   traits: [:published, :month_long_publishing]\n  factory :week_long_unpublished_story,  traits: [:unpublished, :week_long_publishing]\n  factory :month_long_unpublished_story, traits: [:unpublished, :month_long_publishing]\nend\n```\n"
  },
  {
    "path": "docs/src/traits/enum.md",
    "content": "# Enum traits\n\nGiven an Active Record model with an enum attribute:\n\n```rb\nclass Task < ActiveRecord::Base\n  enum status: {queued: 0, started: 1, finished: 2}\nend\n\n```\n\nfactory\\_bot will automatically define traits for each possible value of the\nenum:\n\n```rb\nFactoryBot.define do\n  factory :task\nend\n\nFactoryBot.build(:task, :queued)\nFactoryBot.build(:task, :started)\nFactoryBot.build(:task, :finished)\n```\n\nWriting the traits out manually would be cumbersome, and is not necessary:\n\n```rb\nFactoryBot.define do\n  factory :task do\n    trait :queued do\n      status { :queued }\n    end\n\n    trait :started do\n      status { :started }\n    end\n\n    trait :finished do\n      status { :finished }\n    end\n  end\nend\n```\n\nIf automatically defining traits for enum attributes on every factory is not\ndesired, it is possible to disable the feature by setting\n`FactoryBot.automatically_define_enum_traits = false`\n\nIn that case, it is still possible to explicitly define traits for an enum\nattribute in a particular factory:\n\n```rb\nFactoryBot.automatically_define_enum_traits = false\n\nFactoryBot.define do\n  factory :task do\n    traits_for_enum(:status)\n  end\nend\n```\n\nIt is also possible to use this feature for other enumerable values, not\nspecifically tied to Active Record enum attributes.\n\nWith an array:\n\n```rb\nclass Task\n  attr_accessor :status\nend\n\nFactoryBot.define do\n  factory :task do\n    traits_for_enum(:status, [\"queued\", \"started\", \"finished\"])\n  end\nend\n```\n\nOr with a hash:\n\n```rb\nclass Task\n  attr_accessor :status\nend\n\nFactoryBot.define do\n  factory :task do\n    traits_for_enum(:status, { queued: 0, started: 1, finished: 2 })\n  end\nend\n```\n"
  },
  {
    "path": "docs/src/traits/in-child-factories.md",
    "content": "# In child factories\n\nYou can override individual attributes granted by a trait in a child factory:\n\n```ruby\nfactory :user do\n  name { \"Friendly User\" }\n  login { name }\n\n  trait :active do\n    name { \"John Doe\" }\n    status { :active }\n    login { \"#{name} (M)\" }\n  end\n\n  factory :brandon do\n    active\n    name { \"Brandon\" }\n  end\nend\n```\n"
  },
  {
    "path": "docs/src/traits/mixins.md",
    "content": "# As mixins\n\nTraits can be defined outside of factories and used as mixins to compose shared\nattributes:\n\n```ruby\nFactoryBot.define do\n  trait :timestamps do\n    created_at { 8.days.ago }\n    updated_at { 4.days.ago }\n  end\n  \n  factory :user, traits: [:timestamps] do\n    username { \"john_doe\" }\n  end\n  \n  factory :post do\n    timestamps\n    title { \"Traits rock\" }\n  end\nend\n```\n"
  },
  {
    "path": "docs/src/traits/summary.md",
    "content": "# Traits\n\nTraits allow you to group attributes together and then apply them\nto any factory.\n\n```ruby\nfactory :user, aliases: [:author]\n\nfactory :story do\n  title { \"My awesome story\" }\n  author\n\n  trait :published do\n    published { true }\n  end\n\n  trait :unpublished do\n    published { false }\n  end\n\n  trait :week_long_publishing do\n    start_at { 1.week.ago }\n    end_at { Time.now }\n  end\n\n  trait :month_long_publishing do\n    start_at { 1.month.ago }\n    end_at { Time.now }\n  end\n\n  factory :week_long_published_story,    traits: [:published, :week_long_publishing]\n  factory :month_long_published_story,   traits: [:published, :month_long_publishing]\n  factory :week_long_unpublished_story,  traits: [:unpublished, :week_long_publishing]\n  factory :month_long_unpublished_story, traits: [:unpublished, :month_long_publishing]\nend\n```\n"
  },
  {
    "path": "docs/src/traits/traits-within-traits.md",
    "content": "# Traits within traits\n\nTraits can be used within other traits to mix in their attributes.\n\n```ruby\nfactory :order do\n  trait :completed do\n    completed_at { 3.days.ago }\n  end\n\n  trait :refunded do\n    completed\n    refunded_at { 1.day.ago }\n  end\nend\n```\n"
  },
  {
    "path": "docs/src/traits/using.md",
    "content": "# Using traits\n\nTraits can also be passed in as a list of Symbols when you construct an instance\nfrom factory\\_bot.\n\n```ruby\nfactory :user do\n  name { \"Friendly User\" }\n\n  trait :active do\n    name { \"John Doe\" }\n    status { :active }\n  end\n\n  trait :admin do\n    admin { true }\n  end\nend\n\n# creates an admin user with :active status and name \"Jon Snow\"\ncreate(:user, :admin, :active, name: \"Jon Snow\")\n```\n\nThis ability works with `build`, `build_stubbed`, `attributes_for`, and `create`.\n\n`create_list` and `build_list` methods are supported as well. Remember to pass\nthe number of instances to create/build as second parameter, as documented in\nthe \"Building or Creating Multiple Records\" section of this file.\n\n```ruby\nfactory :user do\n  name { \"Friendly User\" }\n\n  trait :active do\n    name { \"John Doe\" }\n    status { :active }\n  end\n\n  trait :admin do\n    admin { true }\n  end\nend\n\n# creates 3 admin users with :active status and name \"Jon Snow\"\ncreate_list(:user, 3, :admin, :active, name: \"Jon Snow\")\n```\n"
  },
  {
    "path": "docs/src/traits/with-associations.md",
    "content": "# With associations\n\nTraits can be used with associations easily too:\n\n```ruby\nfactory :user do\n  name { \"Friendly User\" }\n\n  trait :admin do\n    admin { true }\n  end\nend\n\nfactory :post do\n  association :user, :admin, name: 'John Doe'\nend\n\n# creates an admin user with name \"John Doe\"\ncreate(:post).user\n```\n\nWhen you're using association names that are different than the factory:\n\n```ruby\nfactory :user do\n  name { \"Friendly User\" }\n\n  trait :admin do\n    admin { true }\n  end\nend\n\nfactory :post do\n  association :author, :admin, factory: :user, name: 'John Doe'\n  # or\n  association :author, factory: [:user, :admin], name: 'John Doe'\nend\n\n# creates an admin user with name \"John Doe\"\ncreate(:post).author\n```\n"
  },
  {
    "path": "docs/src/traits/with-transient-attributes.md",
    "content": "# With transient attributes\n\nTraits can accept transient attributes.\n\n```ruby\nfactory :invoice do\n  trait :with_amount do\n    transient do\n      amount { 1 }\n    end\n\n    after(:create) do |invoice, context|\n      create :line_item, invoice: invoice, amount: context.amount\n    end\n  end\nend\n\ncreate :invoice, :with_amount, amount: 2\n```\n"
  },
  {
    "path": "docs/src/transient-attributes/summary.md",
    "content": "# Transient Attributes\n\nTransient attributes are attributes only available within the factory\ndefinition, and not set on the object being built. This allows for more complex\nlogic inside factories.\n\nThese are defined within a `transient` block:\n\n```ruby\nfactory :user do\n  name { \"Zero Cool\" }\n  birth_date { age&.years.ago }\n\n  transient do\n    age { 11 } # only used to set `birth_date` above\n  end\nend\n```\n"
  },
  {
    "path": "docs/src/transient-attributes/with-associations.md",
    "content": "# With associations\n\nTransient [associations](../associations/summary.md) are not supported in\nfactory\\_bot. Associations within the transient block will be treated as\nregular, non-transient associations.\n\nIf needed, you can generally work around this by building a factory within a\ntransient attribute:\n\n```ruby\nfactory :post\n\nfactory :user do\n  transient do\n    post { build(:post) }\n  end\nend\n```\n"
  },
  {
    "path": "docs/src/transient-attributes/with-attributes_for.md",
    "content": "# With attributes_for\n\nTransient attributes will be ignored within `attributes_for` and won't be set\non the model, even if the attribute exists or you attempt to override it.\n"
  },
  {
    "path": "docs/src/transient-attributes/with-callbacks.md",
    "content": "# With callbacks\n\nIf you need to access the evaluated definition itself in a factory\\_bot callback, you'll\nneed to declare a second block argument (for the definition) and access transient\nattributes from there. This represents the final, evaluated value.\n\n```ruby\nfactory :user do\n  transient do\n    upcased { false }\n  end\n\n  name { \"John Doe\" }\n\n  after(:create) do |user, context|\n    user.name.upcase! if context.upcased\n  end\nend\n\ncreate(:user).name\n#=> \"John Doe\"\n\ncreate(:user, upcased: true).name\n#=> \"JOHN DOE\"\n```\n"
  },
  {
    "path": "docs/src/transient-attributes/with-other-attributes.md",
    "content": "# With other attributes\n\nYou can access transient attributes within other attributes (see [Dependent\nAttributes](../dependent-attributes/summary.md)):\n\n```ruby\nfactory :user do\n  transient do\n    rockstar { true }\n  end\n\n  name { \"John Doe#{\" - Rockstar\" if rockstar}\" }\nend\n\ncreate(:user).name\n#=> \"John Doe - ROCKSTAR\"\n\ncreate(:user, rockstar: false).name\n#=> \"John Doe\"\n```\n"
  },
  {
    "path": "docs/src/using-factories/attribute-overrides.md",
    "content": "# Attribute overrides\n\nNo matter which strategy is used, it's possible to override the defined\nattributes by passing a hash:\n\n```ruby\n# Build a User instance and override the first_name property\nuser = build(:user, first_name: \"Joe\")\nuser.first_name\n# => \"Joe\"\n```\n\nRuby 3.1's support for [omitting values][] from `Hash` literals dovetails with\nattribute overrides and provides an opportunity to limit the repetition of\nvariable names:\n\n```ruby\nfirst_name = \"Joe\"\n\n# Build a User instance and override the first_name property\nuser = build(:user, first_name:)\nuser.first_name\n# => \"Joe\"\n```\n\n[omitting values]: https://docs.ruby-lang.org/en/3.1/syntax/literals_rdoc.html#label-Hash+Literals\n"
  },
  {
    "path": "docs/src/using-factories/build-strategies.md",
    "content": "# Build strategies\n\nfactory\\_bot supports several different build strategies: `build`, `create`,\n`attributes_for` and `build_stubbed`:\n\n```ruby\n# Returns a User instance that's not saved\nuser = build(:user)\n\n# Returns a saved User instance\nuser = create(:user)\n\n# Returns a hash of attributes, which can be used to build a User instance for example\nattrs = attributes_for(:user)\n\n# Integrates with Ruby 3.0's support for pattern matching assignment\nattributes_for(:user) => {email:, name:, **attrs}\n\n# Returns an object with all defined attributes stubbed out\nstub = build_stubbed(:user)\n\n# Passing a block to any of the methods above will yield the return object\ncreate(:user) do |user|\n  user.posts.create(attributes_for(:post))\nend\n```\n\n# build_stubbed and Marshal.dump\n\nNote that objects created with `build_stubbed` cannot be serialized with\n`Marshal.dump`, since factory\\_bot defines singleton methods on these objects.\n"
  },
  {
    "path": "docs/src/using-factories/build_stubbed-and-marshaldump.md",
    "content": "# build_stubbed and Marshal.dump\n\nNote that objects created with `build_stubbed` cannot be serialized with\n`Marshal.dump`, since factory\\_bot defines singleton methods on these objects.\n"
  },
  {
    "path": "docs/src/using-factories/summary.md",
    "content": "# Using factories\n"
  },
  {
    "path": "docs/src/using-without-bundler/summary.md",
    "content": "# Using Without Bundler\n\nIf you're not using Bundler, be sure to have the gem installed and call:\n\n```ruby\nrequire 'factory_bot'\n```\n\nOnce required, assuming you have a directory structure of `spec/factories` or\n`test/factories`, all you'll need to do is run:\n\n```ruby\nFactoryBot.find_definitions\n```\n\nIf you're using a separate directory structure for your factories, you can\nchange the definition file paths before trying to find definitions:\n\n```ruby\nFactoryBot.definition_file_paths = %w(custom_factories_directory)\nFactoryBot.find_definitions\n```\n\nIf you don't have a separate directory of factories and would like to define\nthem inline, that's possible as well:\n\n```ruby\nrequire 'factory_bot'\n\nFactoryBot.define do\n  factory :user do\n    name { 'John Doe' }\n    date_of_birth { 21.years.ago }\n  end\nend\n```\n"
  },
  {
    "path": "factory_bot.gemspec",
    "content": "$LOAD_PATH << File.expand_path(\"lib\", __dir__)\nrequire \"factory_bot/version\"\n\nGem::Specification.new do |s|\n  s.name = \"factory_bot\"\n  s.version = FactoryBot::VERSION\n  s.summary = \"factory_bot provides a framework and DSL for defining and \" \\\n                  \"using model instance factories.\"\n  s.description = \"factory_bot provides a framework and DSL for defining and \" \\\n                  \"using factories - less error-prone, more explicit, and \" \\\n                  \"all-around easier to work with than fixtures.\"\n\n  s.files =\n    Dir.glob(\"lib/**/*\") +\n    %w[CONTRIBUTING.md GETTING_STARTED.md LICENSE NAME.md NEWS.md README.md .yardopts]\n\n  s.require_path = \"lib\"\n  s.required_ruby_version = Gem::Requirement.new(\">= 3.0.0\")\n\n  s.authors = [\"Josh Clayton\", \"Joe Ferris\"]\n  s.email = [\"jclayton@thoughtbot.com\", \"jferris@thoughtbot.com\"]\n\n  s.homepage = \"https://github.com/thoughtbot/factory_bot\"\n\n  s.metadata = {\n    \"changelog_uri\" => \"https://github.com/thoughtbot/factory_bot/blob/main/NEWS.md\"\n  }\n\n  s.add_dependency(\"activesupport\", \">= 6.1.0\")\n\n  s.add_development_dependency(\"activerecord\")\n  s.add_development_dependency(\"appraisal\")\n  s.add_development_dependency(\"aruba\")\n  s.add_development_dependency(\"mutex_m\")\n  s.add_development_dependency(\"ostruct\")\n  s.add_development_dependency(\"rake\")\n  s.add_development_dependency(\"rspec\")\n  s.add_development_dependency(\"rspec-its\")\n  s.add_development_dependency(\"standard\")\n  s.add_development_dependency(\"simplecov\")\n  s.add_development_dependency(\"yard\")\n\n  s.license = \"MIT\"\nend\n"
  },
  {
    "path": "features/find_definitions.feature",
    "content": "Feature: FactoryBot can find factory definitions correctly\n  Scenario: Find definitions with a path\n    Given a file named \"awesome_factories.rb\" with:\n    \"\"\"\n    FactoryBot.define do\n      factory :awesome_category, :class => Category do\n        name { \"awesome!!!\" }\n      end\n    end\n    \"\"\"\n    When \"awesome_factories.rb\" is added to FactoryBot's file definitions path\n    And I create a \"awesome_category\" instance from FactoryBot\n    Then I should find the following for the last category:\n      | name       |\n      | awesome!!! |\n\n  Scenario: Find definitions with an absolute path\n    Given a file named \"awesome_factories.rb\" with:\n    \"\"\"\n    FactoryBot.define do\n      factory :another_awesome_category, :class => Category do\n        name { \"awesome!!!\" }\n      end\n    end\n    \"\"\"\n    When \"awesome_factories.rb\" is added to FactoryBot's file definitions path as an absolute path\n    And I create a \"another_awesome_category\" instance from FactoryBot\n    Then I should find the following for the last category:\n      | name       |\n      | awesome!!! |\n\n  Scenario: Find definitions with a folder\n    Given a file named \"nested/great_factories.rb\" with:\n    \"\"\"\n    FactoryBot.define do\n      factory :great_category, :class => Category do\n        name { \"great!!!\" }\n      end\n    end\n    \"\"\"\n    When \"nested\" is added to FactoryBot's file definitions path\n    And I create a \"great_category\" instance from FactoryBot\n    Then I should find the following for the last category:\n      | name     |\n      | great!!! |\n\n  Scenario: Reload FactoryBot\n    Given a file named \"nested/reload_factories.rb\" with:\n    \"\"\"\n    FactoryBot.define do\n      sequence(:great)\n      trait :admin do\n        admin { true }\n      end\n\n      factory :handy_category, :class => Category do\n        name { \"handy\" }\n      end\n    end\n    \"\"\"\n    When \"nested\" is added to FactoryBot's file definitions path\n    And I append to \"nested/reload_factories.rb\" with:\n    \"\"\"\n\n    FactoryBot.modify do\n      factory :handy_category do\n        name { \"HANDY!!!\" }\n      end\n    end\n    \"\"\"\n    And I reload factories\n    And I create a \"handy_category\" instance from FactoryBot\n    Then I should find the following for the last category:\n      | name     |\n      | HANDY!!! |\n"
  },
  {
    "path": "features/step_definitions/database_steps.rb",
    "content": "Then(/^I should find the following for the last category:$/) do |table|\n  table.hashes.first.each do |key, value|\n    expect(Category.last.attributes[key].to_s).to eq value\n  end\nend\n\nBefore do\n  Category.delete_all\nend\n"
  },
  {
    "path": "features/step_definitions/factory_bot_steps.rb",
    "content": "module FactoryBotDefinitionsHelper\n  def append_file_to_factory_bot_definitions_path(path_to_file)\n    FactoryBot.definition_file_paths ||= []\n    FactoryBot.definition_file_paths << path_to_file\n  end\nend\n\nWorld(FactoryBotDefinitionsHelper)\n\nWhen(/^\"([^\"]*)\" is added to FactoryBot's file definitions path$/) do |file_name|\n  new_factory_file = File.join(expand_path(\".\"), file_name.gsub(\".rb\", \"\"))\n\n  append_file_to_factory_bot_definitions_path(new_factory_file)\n\n  step %(I find definitions)\nend\n\nWhen(/^\"([^\"]*)\" is added to FactoryBot's file definitions path as an absolute path$/) do |file_name|\n  new_factory_file = File.expand_path(File.join(expand_path(\".\"), file_name.gsub(\".rb\", \"\")))\n\n  append_file_to_factory_bot_definitions_path(new_factory_file)\n\n  step %(I find definitions)\nend\n\nWhen(/^I create a \"([^\"]*)\" instance from FactoryBot$/) do |factory_name|\n  FactoryBot.create(factory_name)\nend\n\nWhen(/^I find definitions$/) do\n  FactoryBot.find_definitions\nend\n\nWhen(/^I reload factories$/) do\n  FactoryBot.reload\nend\n"
  },
  {
    "path": "features/support/env.rb",
    "content": "PROJECT_ROOT = File.expand_path(File.join(File.dirname(__FILE__), \"..\", \"..\"))\n\nrequire \"simplecov\" if RUBY_ENGINE == \"ruby\"\n\n$: << File.join(PROJECT_ROOT, \"lib\")\n\nrequire \"active_record\"\nrequire \"factory_bot\"\n\nrequire \"aruba/cucumber\"\n"
  },
  {
    "path": "features/support/factories.rb",
    "content": "ActiveRecord::Base.establish_connection(\n  adapter: \"sqlite3\",\n  database: \":memory:\"\n)\n\nclass CreateSchema < ActiveRecord::Migration[5.0]\n  def self.up\n    create_table :categories, force: true do |t|\n      t.string :name\n    end\n  end\nend\n\nCreateSchema.suppress_messages { CreateSchema.migrate(:up) }\n\nclass Category < ActiveRecord::Base; end\n"
  },
  {
    "path": "gemfiles/7.0.gemfile",
    "content": "# This file was generated by Appraisal\n\nsource \"https://rubygems.org\"\n\ngem \"activerecord-jdbcsqlite3-adapter\", \"~> 70.0\", platforms: [:jruby]\ngem \"sqlite3\", \"~> 1.4\", platforms: [:ruby]\ngem \"activerecord\", \"~> 7.0.0\"\ngem \"concurrent-ruby\", \"< 1.3.5\"\n\ngemspec name: \"factory_bot\", path: \"../\"\n"
  },
  {
    "path": "gemfiles/7.1.gemfile",
    "content": "# This file was generated by Appraisal\n\nsource \"https://rubygems.org\"\n\ngem \"activerecord-jdbcsqlite3-adapter\", platforms: [:jruby]\ngem \"sqlite3\", \"~> 1.4\", platforms: [:ruby]\ngem \"activerecord\", \"~> 7.1.0\"\n\ngemspec name: \"factory_bot\", path: \"../\"\n"
  },
  {
    "path": "gemfiles/7.2.gemfile",
    "content": "# This file was generated by Appraisal\n\nsource \"https://rubygems.org\"\n\ngem \"activerecord-jdbcsqlite3-adapter\", platforms: [:jruby]\ngem \"sqlite3\", platforms: [:ruby]\ngem \"activerecord\", \"~> 7.2.0\"\n\ngemspec name: \"factory_bot\", path: \"../\"\n"
  },
  {
    "path": "gemfiles/8.0.gemfile",
    "content": "# This file was generated by Appraisal\n\nsource \"https://rubygems.org\"\n\ngem \"activerecord-jdbcsqlite3-adapter\", \"~> 70.0\", platforms: [:jruby]\ngem \"sqlite3\", platforms: [:ruby]\ngem \"activerecord\", \"~> 8.0\"\n\ngemspec name: \"factory_bot\", path: \"../\"\n"
  },
  {
    "path": "gemfiles/main.gemfile",
    "content": "# This file was generated by Appraisal\n\nsource \"https://rubygems.org\"\n\ngem \"activerecord-jdbcsqlite3-adapter\", \"~> 70.0\", platforms: [:jruby]\ngem \"sqlite3\", platforms: [:ruby]\ngem \"activerecord\", git: \"https://github.com/rails/rails.git\", branch: \"main\"\n\ngemspec name: \"factory_bot\", path: \"../\"\n"
  },
  {
    "path": "lib/factory_bot/aliases.rb",
    "content": "module FactoryBot\n  class << self\n    attr_accessor :aliases\n  end\n\n  self.aliases = [\n    [/(.+)_id/, '\\1'],\n    [/(.*)/, '\\1_id']\n  ]\n\n  def self.aliases_for(attribute)\n    aliases.map { |(pattern, replace)|\n      if pattern.match?(attribute)\n        attribute.to_s.sub(pattern, replace).to_sym\n      end\n    }.compact << attribute\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/attribute/association.rb",
    "content": "module FactoryBot\n  class Attribute\n    # @api private\n    class Association < Attribute\n      attr_reader :factory\n\n      def initialize(name, factory, overrides)\n        super(name, false)\n        @factory = factory\n        @overrides = overrides\n      end\n\n      def to_proc\n        factory = @factory\n        overrides = @overrides\n        traits_and_overrides = [factory, overrides].flatten\n        factory_name = traits_and_overrides.shift\n\n        -> { association(factory_name, *traits_and_overrides) }\n      end\n\n      def association?\n        true\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/attribute/dynamic.rb",
    "content": "module FactoryBot\n  class Attribute\n    # @api private\n    class Dynamic < Attribute\n      def initialize(name, ignored, block)\n        super(name, ignored)\n        @block = block\n      end\n\n      def to_proc\n        block = @block\n\n        -> {\n          value = case block.arity\n          when 1, -1, -2 then instance_exec(self, &block)\n          else instance_exec(&block)\n          end\n          raise SequenceAbuseError if FactoryBot::Sequence === value\n\n          value\n        }\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/attribute/sequence.rb",
    "content": "module FactoryBot\n  class Attribute\n    # @api private\n    class Sequence < Attribute\n      def initialize(name, sequence, ignored)\n        super(name, ignored)\n        @sequence = sequence\n      end\n\n      def to_proc\n        sequence = @sequence\n        -> { FactoryBot.generate(sequence) }\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/attribute.rb",
    "content": "require \"factory_bot/attribute/dynamic\"\nrequire \"factory_bot/attribute/association\"\nrequire \"factory_bot/attribute/sequence\"\n\nmodule FactoryBot\n  # @api private\n  class Attribute\n    attr_reader :name, :ignored\n\n    def initialize(name, ignored)\n      @name = name.to_sym\n      @ignored = ignored\n    end\n\n    def to_proc\n      -> {}\n    end\n\n    def association?\n      false\n    end\n\n    def alias_for?(attr)\n      FactoryBot.aliases_for(attr).include?(name)\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/attribute_assigner.rb",
    "content": "module FactoryBot\n  # @api private\n  class AttributeAssigner\n    def initialize(evaluator, build_class, &instance_builder)\n      @build_class = build_class\n      @instance_builder = instance_builder\n      @evaluator = evaluator\n      @attribute_list = evaluator.class.attribute_list\n      @attribute_names_assigned = []\n    end\n\n    # constructs an object-based factory product\n    def object\n      @evaluator.instance = build_class_instance\n      build_class_instance.tap do |instance|\n        attributes_to_set_on_instance.each do |attribute|\n          instance.public_send(:\"#{attribute}=\", get(attribute))\n          @attribute_names_assigned << attribute\n        end\n      end\n    end\n\n    # constructs a Hash-based factory product\n    def hash\n      @evaluator.instance = build_hash\n\n      attributes_to_set_on_hash.each_with_object({}) do |attribute, result|\n        result[attribute] = get(attribute)\n      end\n    end\n\n    private\n\n    # Track evaluation of methods on the evaluator to prevent the duplicate\n    # assignment of attributes accessed and via `initialize_with` syntax\n    def method_tracking_evaluator\n      @method_tracking_evaluator ||= Decorator::AttributeHash.new(\n        decorated_evaluator,\n        attribute_names_to_assign\n      )\n    end\n\n    def decorated_evaluator\n      Decorator::NewConstructor.new(\n        Decorator::InvocationTracker.new(@evaluator),\n        @build_class\n      )\n    end\n\n    def methods_invoked_on_evaluator\n      method_tracking_evaluator.__invoked_methods__\n    end\n\n    def build_class_instance\n      @build_class_instance ||= method_tracking_evaluator.instance_exec(&@instance_builder)\n    end\n\n    def build_hash\n      @build_hash ||= NullObject.new(hash_instance_methods_to_respond_to)\n    end\n\n    def get(attribute_name)\n      @evaluator.send(attribute_name)\n    end\n\n    def attributes_to_set_on_instance\n      (attribute_names_to_assign - @attribute_names_assigned - methods_invoked_on_evaluator).uniq\n    end\n\n    def attributes_to_set_on_hash\n      attribute_names_to_assign - association_names\n    end\n\n    # Builds a list of attributes names that should be assigned to the factory product\n    def attribute_names_to_assign\n      @attribute_names_to_assign ||= begin\n        # start a list of candidates containing non-transient attributes and overrides\n        assignment_candidates = non_ignored_attribute_names + override_names\n        # then remove any transient attributes (potentially reintroduced by the overrides),\n        # and remove ignorable aliased attributes from the candidate list\n        assignment_candidates - ignored_attribute_names - attribute_names_overriden_by_alias\n      end\n    end\n\n    def non_ignored_attribute_names\n      @attribute_list.non_ignored.names\n    end\n\n    def ignored_attribute_names\n      @attribute_list.ignored.names\n    end\n\n    def association_names\n      @attribute_list.associations.names\n    end\n\n    def override_names\n      @evaluator.__override_names__\n    end\n\n    def attribute_names\n      @attribute_list.names\n    end\n\n    def hash_instance_methods_to_respond_to\n      attribute_names + override_names + @build_class.instance_methods\n    end\n\n    # Builds a list of attribute names which are slated to be interrupted by an override.\n    def attribute_names_overriden_by_alias\n      @attribute_list\n        .non_ignored\n        .flat_map { |attribute|\n          override_names.map do |override|\n            attribute.name if ignorable_alias?(attribute, override)\n          end\n        }\n        .compact\n    end\n\n    # Is the attribute an ignorable alias of the override?\n    # An attribute is ignorable when it is an alias of the override AND it is\n    # either interrupting an assocciation OR is not the name of another attribute\n    #\n    # @note An \"alias\" is currently an overloaded term for two distinct cases:\n    #   (1) attributes which are aliases and reference the same value\n    #   (2) a logical grouping of a foreign key and an associated object\n    def ignorable_alias?(attribute, override)\n      return false unless attribute.alias_for?(override)\n\n      # The attribute alias should be ignored when the override interrupts an association\n      return true if override_interrupts_association?(attribute, override)\n\n      # Remaining aliases should be ignored when the override does not match a declared attribute.\n      # An override which is an alias to a declared attribute should not interrupt the aliased\n      # attribute and interrupt only the attribute with a matching name. This workaround allows a\n      # factory to declare both <attribute> and <attribute>_id as separate and distinct attributes.\n      !override_matches_declared_attribute?(override)\n    end\n\n    # Does this override interrupt an association?\n    # When true, this indicates the aliased attribute is related to a declared association and the\n    # override does not match the attribute name.\n    #\n    # @note Association overrides should take precedence over a declared foreign key attribute.\n    #\n    # @note An override may interrupt an association by providing the associated object or\n    #   by providing the foreign key.\n    #\n    # @param [FactoryBot::Attribute] aliased_attribute\n    # @param [Symbol] override name of an override which is an alias to the attribute name\n    def override_interrupts_association?(aliased_attribute, override)\n      (aliased_attribute.association? || association_names.include?(override)) &&\n        aliased_attribute.name != override\n    end\n\n    # Does this override match the name of any declared attribute?\n    #\n    # @note Checking against the names of all attributes, resolves any issues with having both\n    #   <attribute> and <attribute>_id in the same factory. This also takes into account ignored\n    #   attributes that should not be assigned (aka transient attributes)\n    #\n    # @param [Symbol] override the name of an override\n    def override_matches_declared_attribute?(override)\n      attribute_names.include?(override)\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/attribute_list.rb",
    "content": "module FactoryBot\n  # @api private\n  class AttributeList\n    include Enumerable\n\n    def initialize(name = nil, attributes = [])\n      @name = name\n      @attributes = attributes\n    end\n\n    def define_attribute(attribute)\n      ensure_attribute_not_self_referencing! attribute\n      ensure_attribute_not_defined! attribute\n\n      add_attribute attribute\n    end\n\n    def each(&block)\n      @attributes.each(&block)\n    end\n\n    def names\n      map(&:name)\n    end\n\n    def associations\n      AttributeList.new(@name, select(&:association?))\n    end\n\n    def ignored\n      AttributeList.new(@name, select(&:ignored))\n    end\n\n    def non_ignored\n      AttributeList.new(@name, reject(&:ignored))\n    end\n\n    def apply_attributes(attributes_to_apply)\n      attributes_to_apply.each { |attribute| add_attribute(attribute) }\n    end\n\n    private\n\n    def add_attribute(attribute)\n      @attributes << attribute\n      attribute\n    end\n\n    def ensure_attribute_not_defined!(attribute)\n      if attribute_defined?(attribute.name)\n        raise AttributeDefinitionError, \"Attribute already defined: #{attribute.name}\"\n      end\n    end\n\n    def ensure_attribute_not_self_referencing!(attribute)\n      if attribute.respond_to?(:factory) && attribute.factory == @name\n        message = \"Self-referencing association '#{attribute.name}' in '#{attribute.factory}'\"\n        raise AssociationDefinitionError, message\n      end\n    end\n\n    def attribute_defined?(attribute_name)\n      @attributes.any? do |attribute|\n        attribute.name == attribute_name\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/callback.rb",
    "content": "module FactoryBot\n  class Callback\n    attr_reader :name\n\n    def initialize(name, block)\n      @name = name.to_sym\n      @block = block\n    end\n\n    def run(instance, evaluator)\n      case block.arity\n      when 1, -1, -2 then syntax_runner.instance_exec(instance, &block)\n      when 2 then syntax_runner.instance_exec(instance, evaluator, &block)\n      else syntax_runner.instance_exec(&block)\n      end\n    end\n\n    def ==(other)\n      name == other.name &&\n        block == other.block\n    end\n\n    protected\n\n    attr_reader :block\n\n    private\n\n    def syntax_runner\n      @syntax_runner ||= SyntaxRunner.new\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/callbacks_observer.rb",
    "content": "module FactoryBot\n  # @api private\n  class CallbacksObserver\n    def initialize(callbacks, evaluator)\n      @callbacks = callbacks\n      @evaluator = evaluator\n      @completed = []\n    end\n\n    def update(name, result_instance)\n      callbacks_by_name(name).each do |callback|\n        if !completed?(result_instance, callback)\n          callback.run(result_instance, @evaluator)\n          record_completion!(result_instance, callback)\n        end\n      end\n    end\n\n    private\n\n    def callbacks_by_name(name)\n      @callbacks.select { |callback| callback.name == name }\n    end\n\n    def completed?(instance, callback)\n      key = completion_key_for(instance, callback)\n      @completed.include?(key)\n    end\n\n    def record_completion!(instance, callback)\n      key = completion_key_for(instance, callback)\n      @completed << key\n    end\n\n    def completion_key_for(instance, callback)\n      \"#{instance.object_id}-#{callback.object_id}\"\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/configuration.rb",
    "content": "module FactoryBot\n  # @api private\n  class Configuration\n    attr_reader(\n      :callback_names,\n      :factories,\n      :inline_sequences,\n      :sequences,\n      :strategies,\n      :traits\n    )\n\n    def initialize\n      @factories = Decorator::DisallowsDuplicatesRegistry.new(Registry.new(\"Factory\"))\n      @sequences = Decorator::DisallowsDuplicatesRegistry.new(Registry.new(\"Sequence\"))\n      @traits = Decorator::DisallowsDuplicatesRegistry.new(Registry.new(\"Trait\"))\n      @strategies = Registry.new(\"Strategy\")\n      @callback_names = Set.new\n      @definition = Definition.new(:configuration)\n      @inline_sequences = []\n\n      to_create(&:save!)\n      initialize_with { new }\n    end\n\n    delegate :to_create, :skip_create, :constructor, :before, :after,\n      :callback, :callbacks, to: :@definition\n\n    def initialize_with(&block)\n      @definition.define_constructor(&block)\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/declaration/association.rb",
    "content": "module FactoryBot\n  class Declaration\n    # @api private\n    class Association < Declaration\n      def initialize(name, *options)\n        super(name, false)\n        @options = options.dup\n        @overrides = options.extract_options!\n        @factory_name = @overrides.delete(:factory) || name\n        @traits = options\n      end\n\n      def ==(other)\n        self.class == other.class &&\n          name == other.name &&\n          options == other.options\n      end\n\n      protected\n\n      attr_reader :options\n\n      private\n\n      attr_reader :factory_name, :overrides, :traits\n\n      def build\n        raise_if_arguments_are_declarations!\n\n        [\n          Attribute::Association.new(\n            name,\n            factory_name,\n            [traits, overrides].flatten\n          )\n        ]\n      end\n\n      def raise_if_arguments_are_declarations!\n        if factory_name.is_a?(Declaration)\n          raise ArgumentError.new(<<~MSG)\n            Association '#{name}' received an invalid factory argument.\n            Did you mean? 'factory: :#{factory_name.name}'\n          MSG\n        end\n\n        overrides.each do |attribute, value|\n          if value.is_a?(Declaration)\n            raise ArgumentError.new(<<~MSG)\n              Association '#{name}' received an invalid attribute override.\n              Did you mean? '#{attribute}: :#{value.name}'\n            MSG\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/declaration/dynamic.rb",
    "content": "module FactoryBot\n  class Declaration\n    # @api private\n    class Dynamic < Declaration\n      def initialize(name, ignored = false, block = nil)\n        super(name, ignored)\n        @block = block\n      end\n\n      def ==(other)\n        self.class == other.class &&\n          name == other.name &&\n          ignored == other.ignored &&\n          block == other.block\n      end\n\n      protected\n\n      attr_reader :block\n\n      private\n\n      def build\n        [Attribute::Dynamic.new(name, @ignored, @block)]\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/declaration/implicit.rb",
    "content": "module FactoryBot\n  class Declaration\n    # @api private\n    class Implicit < Declaration\n      def initialize(name, factory = nil, ignored = false)\n        super(name, ignored)\n        @factory = factory\n      end\n\n      def ==(other)\n        self.class == other.class &&\n          name == other.name &&\n          factory == other.factory &&\n          ignored == other.ignored\n      end\n\n      protected\n\n      attr_reader :factory\n\n      private\n\n      def build\n        if FactoryBot.factories.registered?(name)\n          [Attribute::Association.new(name, name, {})]\n        elsif FactoryBot::Internal.sequences.registered?(name)\n          [Attribute::Sequence.new(name, name, @ignored)]\n        elsif @factory.name.to_s == name.to_s\n          message = \"Self-referencing trait '#{@name}'\"\n          raise TraitDefinitionError, message\n        else\n          @factory.inherit_traits([name])\n          []\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/declaration.rb",
    "content": "require \"factory_bot/declaration/dynamic\"\nrequire \"factory_bot/declaration/association\"\nrequire \"factory_bot/declaration/implicit\"\n\nmodule FactoryBot\n  # @api private\n  class Declaration\n    attr_reader :name\n\n    def initialize(name, ignored = false)\n      @name = name\n      @ignored = ignored\n    end\n\n    def to_attributes\n      build\n    end\n\n    protected\n\n    attr_reader :ignored\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/declaration_list.rb",
    "content": "module FactoryBot\n  # @api private\n  class DeclarationList\n    include Enumerable\n\n    def initialize(name = nil)\n      @declarations = []\n      @name = name\n      @overridable = false\n    end\n\n    def declare_attribute(declaration)\n      delete_declaration(declaration) if overridable?\n\n      @declarations << declaration\n      declaration\n    end\n\n    def overridable\n      @overridable = true\n    end\n\n    def attributes\n      @attributes ||= AttributeList.new(@name).tap do |list|\n        to_attributes.each do |attribute|\n          list.define_attribute(attribute)\n        end\n      end\n    end\n\n    def each(&block)\n      @declarations.each(&block)\n    end\n\n    private\n\n    def delete_declaration(declaration)\n      @declarations.delete_if { |decl| decl.name == declaration.name }\n    end\n\n    def to_attributes\n      @declarations.reduce([]) { |result, declaration| result + declaration.to_attributes }\n    end\n\n    def overridable?\n      @overridable\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/decorator/attribute_hash.rb",
    "content": "module FactoryBot\n  class Decorator\n    class AttributeHash < Decorator\n      def initialize(component, attributes = [])\n        super(component)\n        @attributes = attributes\n      end\n\n      def attributes\n        @attributes.each_with_object({}) do |attribute_name, result|\n          result[attribute_name] = @component.send(attribute_name)\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/decorator/disallows_duplicates_registry.rb",
    "content": "module FactoryBot\n  class Decorator\n    class DisallowsDuplicatesRegistry < Decorator\n      def register(name, item)\n        if registered?(name)\n          raise DuplicateDefinitionError, \"#{@component.name} already registered: #{name}\"\n        else\n          @component.register(name, item)\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/decorator/invocation_tracker.rb",
    "content": "module FactoryBot\n  class Decorator\n    class InvocationTracker < Decorator\n      def initialize(component)\n        super\n        @invoked_methods = []\n      end\n\n      def method_missing(name, *args, &block) # rubocop:disable Style/MissingRespondToMissing\n        @invoked_methods << name\n        super\n      end\n      ruby2_keywords :method_missing if respond_to?(:ruby2_keywords, true)\n\n      def __invoked_methods__\n        @invoked_methods.uniq\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/decorator/new_constructor.rb",
    "content": "module FactoryBot\n  class Decorator\n    class NewConstructor < Decorator\n      def initialize(component, build_class)\n        super(component)\n        @build_class = build_class\n      end\n\n      delegate :new, to: :@build_class\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/decorator.rb",
    "content": "module FactoryBot\n  class Decorator < BasicObject\n    undef_method :==\n\n    def initialize(component)\n      @component = component\n    end\n\n    def method_missing(...) # rubocop:disable Style/MethodMissingSuper\n      @component.send(...)\n    end\n\n    def send(...)\n      __send__(...)\n    end\n\n    def respond_to_missing?(name, include_private = false)\n      @component.respond_to?(name, true) || super\n    end\n\n    def self.const_missing(name)\n      ::Object.const_get(name)\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/definition.rb",
    "content": "module FactoryBot\n  # @api private\n  class Definition\n    attr_reader :defined_traits, :declarations, :name, :registered_enums, :uri_manager\n    attr_accessor :klass\n\n    def initialize(name, base_traits = [], **opts)\n      @name = name\n      @uri_manager = opts[:uri_manager]\n      @declarations = DeclarationList.new(name)\n      @callbacks = []\n      @defined_traits = Set.new\n      @registered_enums = []\n      @to_create = nil\n      @base_traits = base_traits\n      @additional_traits = []\n      @constructor = nil\n      @attributes = nil\n      @compiled = false\n      @expanded_enum_traits = false\n    end\n\n    delegate :declare_attribute, to: :declarations\n\n    def attributes\n      @attributes ||= AttributeList.new.tap do |attribute_list|\n        attribute_lists = aggregate_from_traits_and_self(:attributes) { declarations.attributes }\n        attribute_lists.each do |attributes|\n          attribute_list.apply_attributes attributes\n        end\n      end\n    end\n\n    def to_create(&block)\n      if block\n        @to_create = block\n      else\n        aggregate_from_traits_and_self(:to_create) { @to_create }.last\n      end\n    end\n\n    def constructor\n      aggregate_from_traits_and_self(:constructor) { @constructor }.last\n    end\n\n    def callbacks\n      aggregate_from_traits_and_self(:callbacks) { @callbacks }\n    end\n\n    def compile(klass = nil)\n      unless @compiled\n        expand_enum_traits(klass) unless klass.nil?\n\n        declarations.attributes\n\n        self.klass ||= klass\n        defined_traits.each do |defined_trait|\n          defined_trait.klass ||= klass\n          base_traits.each { |bt| bt.define_trait defined_trait }\n          additional_traits.each { |at| at.define_trait defined_trait }\n        end\n\n        @compiled = true\n\n        ActiveSupport::Notifications.instrument \"factory_bot.compile_factory\", {\n          name: name,\n          attributes: declarations.attributes,\n          traits: defined_traits,\n          class: klass || self.klass\n        }\n      end\n    end\n\n    def overridable\n      declarations.overridable\n      self\n    end\n\n    def inherit_traits(new_traits)\n      @base_traits += new_traits\n    end\n\n    def append_traits(new_traits)\n      @additional_traits += new_traits\n    end\n\n    def add_callback(callback)\n      @callbacks << callback\n    end\n\n    def skip_create\n      @to_create = ->(instance) {}\n    end\n\n    def define_trait(trait)\n      @defined_traits.add(trait)\n    end\n\n    def defined_traits_names\n      @defined_traits.map(&:name)\n    end\n\n    def register_enum(enum)\n      @registered_enums << enum\n    end\n\n    def define_constructor(&block)\n      @constructor = block\n    end\n\n    def before(*names, &block)\n      callback(*names.map { |name| \"before_#{name}\" }, &block)\n    end\n\n    def after(*names, &block)\n      callback(*names.map { |name| \"after_#{name}\" }, &block)\n    end\n\n    def callback(*names, &block)\n      names.each do |name|\n        add_callback(Callback.new(name, block))\n      end\n    end\n\n    private\n\n    def base_traits\n      @base_traits.map { |name| trait_by_name(name) }\n    rescue KeyError => error\n      raise error_with_definition_name(error)\n    end\n\n    # detailed_message introduced in Ruby 3.2 for cleaner integration with\n    # did_you_mean. See https://bugs.ruby-lang.org/issues/18564\n    if KeyError.method_defined?(:detailed_message)\n      def error_with_definition_name(error)\n        message = error.message + \" referenced within \\\"#{name}\\\" definition\"\n\n        error.class.new(message, key: error.key, receiver: error.receiver)\n          .tap { |new_error| new_error.set_backtrace(error.backtrace) }\n      end\n    else\n      def error_with_definition_name(error)\n        message = error.message\n        message.insert(\n          message.index(\"\\nDid you mean?\") || message.length,\n          \" referenced within \\\"#{name}\\\" definition\"\n        )\n\n        error.class.new(message).tap do |new_error|\n          new_error.set_backtrace(error.backtrace)\n        end\n      end\n    end\n\n    def additional_traits\n      @additional_traits.map { |name| trait_by_name(name) }\n    end\n\n    def trait_by_name(name)\n      trait_for(name) || Internal.trait_by_name(name, klass)\n    end\n\n    def trait_for(name)\n      @defined_traits_by_name ||= defined_traits.each_with_object({}) { |t, memo| memo[t.name] ||= t }\n      @defined_traits_by_name[name.to_s]\n    end\n\n    def initialize_copy(source)\n      super\n      @attributes = nil\n      @compiled = false\n      @defined_traits_by_name = nil\n    end\n\n    def aggregate_from_traits_and_self(method_name, &block)\n      compile\n\n      [\n        base_traits.map(&method_name),\n        instance_exec(&block),\n        additional_traits.map(&method_name)\n      ].flatten.compact\n    end\n\n    def expand_enum_traits(klass)\n      return if @expanded_enum_traits\n\n      if automatically_register_defined_enums?(klass)\n        automatically_register_defined_enums(klass)\n      end\n\n      registered_enums.each do |enum|\n        traits = enum.build_traits(klass)\n        traits.each { |trait| define_trait(trait) }\n      end\n\n      @expanded_enum_traits = true\n    end\n\n    def automatically_register_defined_enums(klass)\n      klass.defined_enums.each_key { |name| register_enum(Enum.new(name)) }\n    end\n\n    def automatically_register_defined_enums?(klass)\n      FactoryBot.automatically_define_enum_traits &&\n        klass.respond_to?(:defined_enums)\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/definition_hierarchy.rb",
    "content": "module FactoryBot\n  class DefinitionHierarchy\n    delegate :callbacks, :constructor, :to_create, to: Internal\n\n    def self.build_from_definition(definition)\n      build_to_create(&definition.to_create)\n      build_constructor(&definition.constructor)\n      add_callbacks definition.callbacks\n    end\n\n    def self.add_callbacks(callbacks)\n      if callbacks.any?\n        define_method :callbacks do\n          super() + callbacks\n        end\n      end\n    end\n    private_class_method :add_callbacks\n\n    def self.build_constructor(&block)\n      if block\n        define_method(:constructor) do\n          block\n        end\n      end\n    end\n    private_class_method :build_constructor\n\n    def self.build_to_create(&block)\n      if block\n        define_method(:to_create) do\n          block\n        end\n      end\n    end\n    private_class_method :build_to_create\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/definition_proxy.rb",
    "content": "module FactoryBot\n  class DefinitionProxy\n    UNPROXIED_METHODS = %w[\n      __send__\n      __id__\n      nil?\n      send\n      object_id\n      extend\n      instance_eval\n      initialize\n      block_given?\n      raise\n      caller\n      method\n    ].freeze\n\n    (instance_methods + private_instance_methods).each do |method|\n      undef_method(method) unless UNPROXIED_METHODS.include?(method.to_s)\n    end\n\n    delegate :before, :after, :callback, to: :@definition\n\n    attr_reader :child_factories\n\n    def initialize(definition, ignore = false)\n      @definition = definition\n      @ignore = ignore\n      @child_factories = []\n    end\n\n    def singleton_method_added(name)\n      message = \"Defining methods in blocks (trait or factory) is not supported (#{name})\"\n      raise FactoryBot::MethodDefinitionError, message\n    end\n\n    # Adds an attribute to the factory.\n    # The attribute value will be generated \"lazily\"\n    # by calling the block whenever an instance is generated.\n    # The block will not be called if the\n    # attribute is overridden for a specific instance.\n    #\n    # Arguments:\n    # * name: +Symbol+ or +String+\n    #   The name of this attribute. This will be assigned using \"name=\" for\n    #   generated instances.\n    def add_attribute(name, &block)\n      declaration = Declaration::Dynamic.new(name, @ignore, block)\n      @definition.declare_attribute(declaration)\n    end\n\n    def transient(&block)\n      proxy = DefinitionProxy.new(@definition, true)\n      proxy.instance_eval(&block)\n    end\n\n    # Calls add_attribute using the missing method name as the name of the\n    # attribute, so that:\n    #\n    #   factory :user do\n    #     name { 'Billy Idol' }\n    #   end\n    #\n    # and:\n    #\n    #   factory :user do\n    #     add_attribute(:name) { 'Billy Idol' }\n    #   end\n    #\n    # are equivalent.\n    #\n    # If no argument or block is given, factory_bot will first look for an\n    # association, then for a sequence, and finally for a trait with the same\n    # name. This means that given an \"admin\" trait, an \"email\" sequence, and an\n    # \"account\" factory:\n    #\n    #   factory :user, traits: [:admin] do\n    #     email { generate(:email) }\n    #     association :account\n    #   end\n    #\n    # and:\n    #\n    #   factory :user do\n    #     admin\n    #     email\n    #     account\n    #   end\n    #\n    # are equivalent.\n    def method_missing(name, *args, &block) # rubocop:disable Style/MissingRespondToMissing\n      association_options = args.first\n\n      if association_options.nil?\n        __declare_attribute__(name, block)\n      elsif __valid_association_options?(association_options)\n        association(name, association_options)\n      else\n        raise NoMethodError.new(<<~MSG)\n          undefined method '#{name}' in '#{@definition.name}' factory\n          Did you mean? '#{name} { #{association_options.inspect} }'\n        MSG\n      end\n    end\n\n    # Adds an attribute that will have unique values generated by a sequence with\n    # a specified format.\n    #\n    # The result of:\n    #   factory :user do\n    #     sequence(:email) { |n| \"person#{n}@example.com\" }\n    #   end\n    #\n    # Is equal to:\n    #   sequence(:email) { |n| \"person#{n}@example.com\" }\n    #\n    #   factory :user do\n    #     email { FactoryBot.generate(:email) }\n    #   end\n    #\n    # Except that no globally available sequence will be defined.\n    def sequence(name, *args, &block)\n      options = args.extract_options!\n      options[:uri_paths] = @definition.uri_manager.to_a\n      args << options\n\n      new_sequence = Sequence.new(name, *args, &block)\n      registered_sequence = __fetch_or_register_sequence(new_sequence)\n      add_attribute(name) { increment_sequence(registered_sequence) }\n    end\n\n    # Adds an attribute that builds an association. The associated instance will\n    # be built using the same build strategy as the parent instance.\n    #\n    # Example:\n    #   factory :user do\n    #     name 'Joey'\n    #   end\n    #\n    #   factory :post do\n    #     association :author, factory: :user\n    #   end\n    #\n    # Arguments:\n    # * name: +Symbol+\n    #   The name of this attribute.\n    # * options: +Hash+\n    #\n    # Options:\n    # * factory: +Symbol+ or +String+\n    #    The name of the factory to use when building the associated instance.\n    #    If no name is given, the name of the attribute is assumed to be the\n    #    name of the factory. For example, a \"user\" association will by\n    #    default use the \"user\" factory.\n    def association(name, *options)\n      if block_given?\n        raise AssociationDefinitionError.new(\n          \"Unexpected block passed to '#{name}' association \" \\\n          \"in '#{@definition.name}' factory\"\n        )\n      else\n        declaration = Declaration::Association.new(name, *options)\n        @definition.declare_attribute(declaration)\n      end\n    end\n\n    def to_create(&block)\n      @definition.to_create(&block)\n    end\n\n    def skip_create\n      @definition.skip_create\n    end\n\n    def factory(name, options = {}, &block)\n      child_factories << [name, options, block]\n    end\n\n    def trait(name, &block)\n      @definition.define_trait(Trait.new(name, uri_paths: @definition.uri_manager.to_a, &block))\n    end\n\n    # Creates traits for enumerable values.\n    #\n    # Example:\n    #   factory :task do\n    #     traits_for_enum :status, [:started, :finished]\n    #   end\n    #\n    # Equivalent to:\n    #   factory :task do\n    #     trait :started do\n    #       status { :started }\n    #     end\n    #\n    #     trait :finished do\n    #       status { :finished }\n    #     end\n    #   end\n    #\n    # Example:\n    #   factory :task do\n    #     traits_for_enum :status, {started: 1, finished: 2}\n    #   end\n    #\n    # Example:\n    #   class Task\n    #     def statuses\n    #       {started: 1, finished: 2}\n    #     end\n    #   end\n    #\n    #   factory :task do\n    #     traits_for_enum :status\n    #   end\n    #\n    # Both equivalent to:\n    #   factory :task do\n    #     trait :started do\n    #       status { 1 }\n    #     end\n    #\n    #     trait :finished do\n    #       status { 2 }\n    #     end\n    #   end\n    #\n    #\n    # Arguments:\n    #   attribute_name: +Symbol+ or +String+\n    #     the name of the attribute these traits will set the value of\n    #   values: +Array+, +Hash+, or other +Enumerable+\n    #     An array of trait names, or a mapping of trait names to values for\n    #     those traits. When this argument is not provided, factory_bot will\n    #     attempt to get the values by calling the pluralized `attribute_name`\n    #     class method.\n    def traits_for_enum(attribute_name, values = nil)\n      @definition.register_enum(Enum.new(attribute_name, values))\n    end\n\n    def initialize_with(&block)\n      @definition.define_constructor(&block)\n    end\n\n    private\n\n    def __declare_attribute__(name, block)\n      if block.nil?\n        declaration = Declaration::Implicit.new(name, @definition, @ignore)\n        @definition.declare_attribute(declaration)\n      else\n        add_attribute(name, &block)\n      end\n    end\n\n    def __valid_association_options?(options)\n      options.respond_to?(:has_key?) && options.has_key?(:factory)\n    end\n\n    ##\n    # If the inline sequence has already been registered by a parent,\n    # return that one, otherwise register and return the given sequence\n    #\n    def __fetch_or_register_sequence(sequence)\n      FactoryBot::Sequence.find_by_uri(sequence.uri_manager.first) ||\n        FactoryBot::Internal.register_inline_sequence(sequence)\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/enum.rb",
    "content": "module FactoryBot\n  # @api private\n  class Enum\n    def initialize(attribute_name, values = nil)\n      @attribute_name = attribute_name\n      @values = values\n    end\n\n    def build_traits(klass)\n      enum_values(klass).map do |trait_name, value|\n        build_trait(trait_name, @attribute_name, value || trait_name)\n      end\n    end\n\n    private\n\n    def enum_values(klass)\n      @values || klass.send(@attribute_name.to_s.pluralize)\n    end\n\n    def build_trait(trait_name, attribute_name, value)\n      Trait.new(trait_name) do\n        add_attribute(attribute_name) { value }\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/errors.rb",
    "content": "module FactoryBot\n  # Raised when a factory is defined that attempts to instantiate itself.\n  class AssociationDefinitionError < RuntimeError; end\n\n  # Raised when a trait is defined that references itself.\n  class TraitDefinitionError < RuntimeError; end\n\n  # Raised when a callback is defined that has an invalid name\n  class InvalidCallbackNameError < RuntimeError; end\n\n  # Raised when a factory is defined with the same name as a previously-defined factory.\n  class DuplicateDefinitionError < RuntimeError; end\n\n  # Raised when attempting to register a sequence from a dynamic attribute block\n  class SequenceAbuseError < RuntimeError; end\n\n  # Raised when defining an attribute twice in the same factory\n  class AttributeDefinitionError < RuntimeError; end\n\n  # Raised when attempting to pass a block to an association definition\n  class AssociationDefinitionError < RuntimeError; end\n\n  # Raised when a method is defined in a factory or trait with arguments\n  class MethodDefinitionError < RuntimeError; end\n\n  # Raised when any factory is considered invalid\n  class InvalidFactoryError < RuntimeError; end\nend\n"
  },
  {
    "path": "lib/factory_bot/evaluation.rb",
    "content": "module FactoryBot\n  class Evaluation\n    def initialize(evaluator, attribute_assigner, to_create, observer)\n      @evaluator = evaluator\n      @attribute_assigner = attribute_assigner\n      @to_create = to_create\n      @observer = observer\n    end\n\n    delegate :object, :hash, to: :@attribute_assigner\n\n    def create(result_instance)\n      case @to_create.arity\n      when 2 then @to_create[result_instance, @evaluator]\n      else @to_create[result_instance]\n      end\n    end\n\n    def notify(name, result_instance)\n      @observer.update(name, result_instance)\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/evaluator.rb",
    "content": "require \"active_support/core_ext/class/attribute\"\n\nmodule FactoryBot\n  # @api private\n  class Evaluator\n    class_attribute :attribute_lists\n\n    private_instance_methods.each do |method|\n      undef_method(method) unless method.match?(/^__|initialize/)\n    end\n\n    def initialize(build_strategy, overrides = {})\n      @build_strategy = build_strategy\n      @overrides = overrides\n      @cached_attributes = overrides\n      @instance = nil\n\n      @overrides.each do |name, value|\n        singleton_class.define_attribute(name) { value }\n      end\n    end\n\n    def association(factory_name, *traits_and_overrides)\n      overrides = traits_and_overrides.extract_options!\n      strategy_override = overrides.fetch(:strategy) {\n        FactoryBot.use_parent_strategy ? @build_strategy.to_sym : :create\n      }\n\n      traits_and_overrides += [overrides.except(:strategy)]\n\n      runner = FactoryRunner.new(factory_name, strategy_override, traits_and_overrides)\n      @build_strategy.association(runner)\n    end\n\n    attr_accessor :instance\n\n    def method_missing(method_name, ...)\n      if @instance.respond_to?(method_name)\n        @instance.send(method_name, ...)\n      else\n        SyntaxRunner.new.send(method_name, ...)\n      end\n    end\n\n    def respond_to_missing?(method_name, _include_private = false)\n      @instance.respond_to?(method_name) || SyntaxRunner.new.respond_to?(method_name)\n    end\n\n    def __override_names__\n      @overrides.keys\n    end\n\n    def increment_sequence(sequence, scope: self)\n      value = sequence.next(scope)\n\n      raise if value.respond_to?(:start_with?) && value.start_with?(\"#<FactoryBot::Declaration\")\n\n      value\n    rescue\n      raise ArgumentError, \"Sequence '#{sequence.uri_manager.first}' failed to \" \\\n                          \"return a value. Perhaps it needs a scope to operate? (scope: <object>)\"\n    end\n\n    def self.attribute_list\n      AttributeList.new.tap do |list|\n        attribute_lists.each do |attribute_list|\n          list.apply_attributes attribute_list.to_a\n        end\n      end\n    end\n\n    def self.define_attribute(name, &block)\n      if instance_methods(false).include?(name) || private_instance_methods(false).include?(name)\n        undef_method(name)\n      end\n\n      define_method(name) do\n        if @cached_attributes.key?(name)\n          @cached_attributes[name]\n        else\n          @cached_attributes[name] = instance_exec(&block)\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/evaluator_class_definer.rb",
    "content": "module FactoryBot\n  # @api private\n  class EvaluatorClassDefiner\n    def initialize(attributes, parent_class)\n      @parent_class = parent_class\n      @attributes = attributes\n\n      attributes.each do |attribute|\n        evaluator_class.define_attribute(attribute.name, &attribute.to_proc)\n      end\n    end\n\n    def evaluator_class\n      @evaluator_class ||= Class.new(@parent_class).tap do |klass|\n        klass.attribute_lists ||= []\n        klass.attribute_lists += [@attributes]\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/factory.rb",
    "content": "require \"active_support/core_ext/hash/keys\"\nrequire \"active_support/inflector\"\n\nmodule FactoryBot\n  # @api private\n  class Factory\n    attr_reader :name, :definition\n\n    def initialize(name, options = {})\n      assert_valid_options(options)\n      @name = name.respond_to?(:to_sym) ? name.to_sym : name.to_s.underscore.to_sym\n      @parent = options[:parent]\n      @aliases = options[:aliases] || []\n      @class_name = options[:class]\n      @uri_manager = FactoryBot::UriManager.new(names)\n      @definition = Definition.new(@name, options[:traits] || [], uri_manager: @uri_manager)\n      @compiled = false\n    end\n\n    delegate :add_callback, :declare_attribute, :to_create, :define_trait, :constructor,\n      :defined_traits, :defined_traits_names, :inherit_traits, :append_traits,\n      to: :@definition\n\n    def build_class\n      @build_class ||= if class_name.is_a? Class\n        class_name\n      elsif class_name.to_s.safe_constantize\n        class_name.to_s.safe_constantize\n      else\n        class_name.to_s.camelize.constantize\n      end\n    end\n\n    def run(build_strategy, overrides, &block)\n      block ||= ->(result) { result }\n\n      compile\n\n      strategy = Strategy.lookup_strategy(build_strategy).new\n\n      evaluator = evaluator_class.new(strategy, overrides.symbolize_keys)\n      attribute_assigner = AttributeAssigner.new(evaluator, build_class, &compiled_constructor)\n\n      observer = CallbacksObserver.new(callbacks, evaluator)\n      evaluation = Evaluation.new(evaluator, attribute_assigner, compiled_to_create, observer)\n\n      evaluation.notify(:before_all, nil)\n      instance = strategy.result(evaluation).tap(&block)\n      evaluation.notify(:after_all, instance)\n\n      instance\n    end\n\n    def human_names\n      names.map { |name| name.to_s.humanize.downcase }\n    end\n\n    def associations\n      evaluator_class.attribute_list.associations\n    end\n\n    # Names for this factory, including aliases.\n    #\n    # Example:\n    #\n    #   factory :user, aliases: [:author] do\n    #     # ...\n    #   end\n    #\n    #   FactoryBot.create(:author).class\n    #   # => User\n    #\n    # Because an attribute defined without a value or block will build an\n    # association with the same name, this allows associations to be defined\n    # without factories, such as:\n    #\n    #   factory :user, aliases: [:author] do\n    #     # ...\n    #   end\n    #\n    #   factory :post do\n    #     author\n    #   end\n    #\n    #   FactoryBot.create(:post).author.class\n    #   # => User\n    def names\n      [name] + @aliases\n    end\n\n    def compile\n      unless @compiled\n        parent.compile\n        inherit_parent_traits\n        @definition.compile(build_class)\n        build_hierarchy\n        @compiled = true\n      end\n    end\n\n    def with_traits(traits)\n      clone.tap do |factory_with_traits|\n        factory_with_traits.append_traits traits\n      end\n    end\n\n    protected\n\n    def class_name\n      @class_name || parent.class_name || name\n    end\n\n    def evaluator_class\n      @evaluator_class ||= EvaluatorClassDefiner.new(attributes, parent.evaluator_class).evaluator_class\n    end\n\n    def attributes\n      compile\n      AttributeList.new(@name).tap do |list|\n        list.apply_attributes definition.attributes\n      end\n    end\n\n    def hierarchy_class\n      @hierarchy_class ||= Class.new(parent.hierarchy_class)\n    end\n\n    def hierarchy_instance\n      @hierarchy_instance ||= hierarchy_class.new\n    end\n\n    def build_hierarchy\n      hierarchy_class.build_from_definition definition\n    end\n\n    def callbacks\n      hierarchy_instance.callbacks\n    end\n\n    def compiled_to_create\n      hierarchy_instance.to_create\n    end\n\n    def compiled_constructor\n      hierarchy_instance.constructor\n    end\n\n    private\n\n    def assert_valid_options(options)\n      options.assert_valid_keys(:class, :parent, :aliases, :traits)\n    end\n\n    def parent\n      if @parent\n        FactoryBot::Internal.factory_by_name(@parent)\n      else\n        NullFactory.new\n      end\n    end\n\n    def inherit_parent_traits\n      parent.defined_traits.each do |trait|\n        next if defined_traits_names.include?(trait.name)\n        define_trait(trait.clone)\n      end\n    end\n\n    def initialize_copy(source)\n      super\n      @definition = @definition.clone\n      @evaluator_class = nil\n      @hierarchy_class = nil\n      @hierarchy_instance = nil\n      @compiled = false\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/factory_runner.rb",
    "content": "module FactoryBot\n  class FactoryRunner\n    def initialize(name, strategy, traits_and_overrides)\n      @name = name\n      @strategy = strategy\n\n      @overrides = traits_and_overrides.extract_options!\n      @traits = traits_and_overrides\n    end\n\n    def run(runner_strategy = @strategy, &block)\n      factory = FactoryBot::Internal.factory_by_name(@name)\n\n      factory.compile\n\n      if @traits.any?\n        factory = factory.with_traits(@traits)\n      end\n\n      instrumentation_payload = {\n        name: @name,\n        strategy: runner_strategy,\n        traits: @traits,\n        overrides: @overrides,\n        factory: factory\n      }\n\n      ActiveSupport::Notifications.instrument(\"factory_bot.run_factory\", instrumentation_payload) do\n        factory.run(runner_strategy, @overrides, &block)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/find_definitions.rb",
    "content": "module FactoryBot\n  class << self\n    # An Array of strings specifying locations that should be searched for\n    # factory definitions. By default, factory_bot will attempt to require\n    # \"factories.rb\", \"factories/**/*.rb\", \"test/factories.rb\",\n    # \"test/factories/**.rb\", \"spec/factories.rb\", and \"spec/factories/**.rb\".\n    attr_accessor :definition_file_paths\n  end\n\n  self.definition_file_paths = %w[factories test/factories spec/factories]\n\n  def self.find_definitions\n    absolute_definition_file_paths = definition_file_paths.map { |path| File.expand_path(path) }\n\n    absolute_definition_file_paths.uniq.each do |path|\n      load(\"#{path}.rb\") if File.exist?(\"#{path}.rb\")\n\n      if File.directory? path\n        Dir[File.join(path, \"**\", \"*.rb\")].sort.each do |file|\n          load file\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/internal.rb",
    "content": "module FactoryBot\n  # @api private\n  module Internal\n    class << self\n      delegate :after,\n        :before,\n        :callbacks,\n        :constructor,\n        :factories,\n        :initialize_with,\n        :inline_sequences,\n        :sequences,\n        :skip_create,\n        :strategies,\n        :to_create,\n        :traits,\n        to: :configuration\n\n      def configuration\n        @configuration ||= Configuration.new\n      end\n\n      def reset_configuration\n        @configuration = nil\n      end\n\n      def register_inline_sequence(sequence)\n        inline_sequences.push(sequence)\n        sequence\n      end\n\n      def rewind_inline_sequences\n        inline_sequences.each(&:rewind)\n      end\n\n      def register_trait(trait)\n        trait.names.each do |name|\n          traits.register(name, trait)\n        end\n        trait\n      end\n\n      def trait_by_name(name, klass)\n        traits.find(name).tap { |t| t.klass = klass }\n      end\n\n      def register_sequence(sequence)\n        sequence.names.each do |name|\n          sequences.register(name, sequence)\n        end\n        sequence\n      end\n\n      def sequence_by_name(name)\n        sequences.find(name)\n      end\n\n      def rewind_sequences\n        sequences.each(&:rewind)\n        rewind_inline_sequences\n      end\n\n      def rewind_sequence(*uri_parts)\n        fail_argument_count(0, \"1+\") if uri_parts.empty?\n\n        uri = build_uri(uri_parts)\n        sequence = Sequence.find_by_uri(uri) || fail_unregistered_sequence(uri)\n\n        sequence.rewind\n      end\n\n      def set_sequence(*uri_parts, value)\n        uri = build_uri(uri_parts) || fail_argument_count(uri_parts.size, \"2+\")\n        sequence = Sequence.find(*uri) || fail_unregistered_sequence(uri)\n\n        sequence.set_value(value)\n      end\n\n      def register_factory(factory)\n        factory.names.each do |name|\n          factories.register(name, factory)\n        end\n        factory\n      end\n\n      def factory_by_name(name)\n        factories.find(name)\n      end\n\n      def register_strategy(strategy_name, strategy_class)\n        strategies.register(strategy_name, strategy_class)\n        StrategySyntaxMethodRegistrar.new(strategy_name).define_strategy_methods\n      end\n\n      def strategy_by_name(name)\n        strategies.find(name)\n      end\n\n      def register_default_strategies\n        register_strategy(:build, FactoryBot::Strategy::Build)\n        register_strategy(:create, FactoryBot::Strategy::Create)\n        register_strategy(:attributes_for, FactoryBot::Strategy::AttributesFor)\n        register_strategy(:build_stubbed, FactoryBot::Strategy::Stub)\n        register_strategy(:null, FactoryBot::Strategy::Null)\n      end\n\n      private\n\n      def build_uri(...)\n        FactoryBot::UriManager.build_uri(...)\n      end\n\n      def fail_argument_count(received, expected)\n        fail ArgumentError,\n          \"wrong number of arguments (given #{received}, expected #{expected})\"\n      end\n\n      def fail_unregistered_sequence(uri)\n        fail KeyError,\n          \"Sequence not registered: '#{uri}'.\"\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/linter.rb",
    "content": "module FactoryBot\n  class Linter\n    def initialize(factories, strategy: :create, traits: false, verbose: false)\n      @factories_to_lint = factories\n      @factory_strategy = strategy\n      @traits = traits\n      @verbose = verbose\n      @invalid_factories = calculate_invalid_factories\n    end\n\n    def lint!\n      if invalid_factories.any?\n        raise InvalidFactoryError, error_message\n      end\n    end\n\n    private\n\n    attr_reader :factories_to_lint, :invalid_factories, :factory_strategy\n\n    def calculate_invalid_factories\n      factories_to_lint.each_with_object(Hash.new([])) do |factory, result|\n        errors = lint(factory)\n        result[factory] |= errors unless errors.empty?\n      end\n    end\n\n    class FactoryError\n      def initialize(wrapped_error, factory)\n        @wrapped_error = wrapped_error\n        @factory = factory\n      end\n\n      def message\n        message = @wrapped_error.message\n        \"* #{location} - #{message} (#{@wrapped_error.class.name})\"\n      end\n\n      def verbose_message\n        <<~MESSAGE\n          #{message}\n            #{@wrapped_error.backtrace.join(\"\\n  \")}\n        MESSAGE\n      end\n\n      def location\n        @factory.name\n      end\n    end\n\n    class FactoryTraitError < FactoryError\n      def initialize(wrapped_error, factory, trait_name)\n        super(wrapped_error, factory)\n        @trait_name = trait_name\n      end\n\n      def location\n        \"#{@factory.name}+#{@trait_name}\"\n      end\n    end\n\n    def lint(factory)\n      if @traits\n        lint_factory(factory) + lint_traits(factory)\n      else\n        lint_factory(factory)\n      end\n    end\n\n    def lint_factory(factory)\n      result = []\n      begin\n        in_transaction { FactoryBot.public_send(factory_strategy, factory.name) }\n      rescue => e\n        result |= [FactoryError.new(e, factory)]\n      end\n      result\n    end\n\n    def lint_traits(factory)\n      result = []\n      factory.definition.defined_traits.map(&:name).each do |trait_name|\n        in_transaction { FactoryBot.public_send(factory_strategy, factory.name, trait_name) }\n      rescue => e\n        result |= [FactoryTraitError.new(e, factory, trait_name)]\n      end\n      result\n    end\n\n    def error_message\n      lines = invalid_factories.map { |_factory, exceptions|\n        exceptions.map(&error_message_type)\n      }.flatten\n\n      <<~ERROR_MESSAGE.strip\n        The following factories are invalid:\n\n        #{lines.join(\"\\n\")}\n      ERROR_MESSAGE\n    end\n\n    def error_message_type\n      if @verbose\n        :verbose_message\n      else\n        :message\n      end\n    end\n\n    def in_transaction\n      if defined?(ActiveRecord::Base)\n        ActiveRecord::Base.transaction(joinable: false) do\n          yield\n          raise ActiveRecord::Rollback\n        end\n      else\n        yield\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/null_factory.rb",
    "content": "module FactoryBot\n  # @api private\n  class NullFactory\n    attr_reader :definition\n\n    def initialize\n      @definition = Definition.new(:null_factory)\n    end\n\n    delegate :defined_traits, :callbacks, :attributes, :constructor,\n      :to_create, to: :definition\n\n    def compile\n    end\n\n    def class_name\n    end\n\n    def evaluator_class\n      FactoryBot::Evaluator\n    end\n\n    def hierarchy_class\n      FactoryBot::DefinitionHierarchy\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/null_object.rb",
    "content": "module FactoryBot\n  # @api private\n  class NullObject < ::BasicObject\n    def initialize(methods_to_respond_to)\n      @methods_to_respond_to = methods_to_respond_to.map(&:to_s)\n    end\n\n    def method_missing(name, *args, &block) # rubocop:disable Style/MissingRespondToMissing\n      if respond_to?(name)\n        nil\n      else\n        super\n      end\n    end\n\n    def respond_to?(method)\n      @methods_to_respond_to.include? method.to_s\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/registry.rb",
    "content": "require \"active_support/hash_with_indifferent_access\"\n\nmodule FactoryBot\n  class Registry\n    include Enumerable\n\n    attr_reader :name\n\n    def initialize(name)\n      @name = name\n      @items = ActiveSupport::HashWithIndifferentAccess.new\n    end\n\n    def clear\n      @items.clear\n    end\n\n    def each(&block)\n      @items.values.uniq.each(&block)\n    end\n\n    def find(name)\n      @items.fetch(name)\n    rescue KeyError => e\n      raise key_error_with_custom_message(e)\n    end\n\n    alias_method :[], :find\n\n    def register(name, item)\n      @items[name] = item\n    end\n\n    def registered?(name)\n      @items.key?(name)\n    end\n\n    private\n\n    def key_error_with_custom_message(key_error)\n      message = key_error.message.sub(\"key not found\", \"#{@name} not registered\")\n      new_key_error(message, key_error).tap do |error|\n        error.set_backtrace(key_error.backtrace)\n      end\n    end\n\n    # detailed_message introduced in Ruby 3.2 for cleaner integration with\n    # did_you_mean. See https://bugs.ruby-lang.org/issues/18564\n    if KeyError.method_defined?(:detailed_message)\n      def new_key_error(message, key_error)\n        KeyError.new(message, key: key_error.key, receiver: key_error.receiver)\n      end\n    else\n      def new_key_error(message, _)\n        KeyError.new(message)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/reload.rb",
    "content": "module FactoryBot\n  def self.reload\n    Internal.reset_configuration\n    Internal.register_default_strategies\n    find_definitions\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/sequence.rb",
    "content": "require \"timeout\"\n\nmodule FactoryBot\n  # Sequences are defined using sequence within a FactoryBot.define block.\n  # Sequence values are generated using next.\n  # @api private\n  class Sequence\n    attr_reader :name, :uri_manager, :aliases\n\n    def self.find(*uri_parts)\n      if uri_parts.empty?\n        fail ArgumentError, \"wrong number of arguments, expected 1+)\"\n      else\n        find_by_uri FactoryBot::UriManager.build_uri(*uri_parts)\n      end\n    end\n\n    def self.find_by_uri(uri)\n      uri = uri.to_sym\n      FactoryBot::Internal.sequences.to_a.find { |seq| seq.has_uri?(uri) } ||\n        FactoryBot::Internal.inline_sequences.find { |seq| seq.has_uri?(uri) }\n    end\n\n    def initialize(name, *args, &proc)\n      options = args.extract_options!\n      @name = name\n      @proc = proc\n      @aliases = options.fetch(:aliases, []).map(&:to_sym)\n      @uri_manager = FactoryBot::UriManager.new(names, paths: options[:uri_paths])\n      @value = args.first || 1\n\n      unless @value.respond_to?(:peek)\n        @value = EnumeratorAdapter.new(@value)\n      end\n    end\n\n    def next(scope = nil)\n      if @proc && scope\n        scope.instance_exec(value, &@proc)\n      elsif @proc\n        @proc.call(value)\n      else\n        value\n      end\n    ensure\n      increment_value\n    end\n\n    def names\n      [@name] + @aliases\n    end\n\n    def has_name?(test_name)\n      names.include?(test_name.to_sym)\n    end\n\n    def has_uri?(uri)\n      uri_manager.include?(uri)\n    end\n\n    def for_factory?(test_factory_name)\n      FactoryBot::Internal.factory_by_name(factory_name).names.include?(test_factory_name.to_sym)\n    end\n\n    def rewind\n      @value.rewind\n    end\n\n    ##\n    # If it's an Integer based sequence, set the new value directly,\n    # else rewind and seek from the beginning until a match is found.\n    #\n    def set_value(new_value)\n      if can_set_value_directly?(new_value)\n        @value.set_value(new_value)\n      elsif can_set_value_by_index?\n        set_value_by_index(new_value)\n      else\n        seek_value(new_value)\n      end\n    end\n\n    protected\n\n    attr_reader :proc\n\n    private\n\n    def value\n      @value.peek\n    end\n\n    def increment_value\n      @value.next\n    end\n\n    def can_set_value_by_index?\n      @value.respond_to?(:find_index)\n    end\n\n    ##\n    # Set to the given value, or fail if not found\n    #\n    def set_value_by_index(value)\n      index = @value.find_index(value) || fail_value_not_found(value)\n      @value.rewind\n      index.times { @value.next }\n    end\n\n    ##\n    # Rewind index and seek until the value is found or the max attempts\n    # have been tried. If not found, the sequence is rewound to its original value\n    #\n    def seek_value(value)\n      original_value = @value.peek\n\n      # rewind and search for the new value\n      @value.rewind\n      Timeout.timeout(FactoryBot.sequence_setting_timeout) do\n        loop do\n          return if @value.peek == value\n          increment_value\n        end\n\n        # loop auto-recues a StopIteration error, so if we\n        # reached this point, re-raise it now\n        fail StopIteration\n      end\n    rescue Timeout::Error, StopIteration\n      reset_original_value(original_value)\n      fail_value_not_found(value)\n    end\n\n    def reset_original_value(original_value)\n      @value.rewind\n\n      until @value.peek == original_value\n        increment_value\n      end\n    end\n\n    def can_set_value_directly?(value)\n      return false unless value.is_a?(Integer)\n      return false unless @value.is_a?(EnumeratorAdapter)\n      @value.integer_value?\n    end\n\n    def fail_value_not_found(value)\n      fail ArgumentError, \"Unable to find '#{value}' in the sequence.\"\n    end\n\n    class EnumeratorAdapter\n      def initialize(initial_value)\n        @initial_value = initial_value\n      end\n\n      def peek\n        value\n      end\n\n      def next\n        @value = value.next\n      end\n\n      def rewind\n        @value = first_value\n      end\n\n      def set_value(new_value)\n        if new_value >= first_value\n          @value = new_value\n        else\n          fail ArgumentError, \"Value cannot be less than: #{@first_value}\"\n        end\n      end\n\n      def integer_value?\n        first_value.is_a?(Integer)\n      end\n\n      private\n\n      def first_value\n        @first_value ||= initial_value\n      end\n\n      def value\n        @value ||= initial_value\n      end\n\n      def initial_value\n        @value = @initial_value.respond_to?(:call) ? @initial_value.call : @initial_value\n        @first_value = @value\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/strategy/attributes_for.rb",
    "content": "module FactoryBot\n  module Strategy\n    class AttributesFor\n      def association(runner)\n        runner.run(:null)\n      end\n\n      def result(evaluation)\n        evaluation.hash\n      end\n\n      def to_sym\n        :attributes_for\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/strategy/build.rb",
    "content": "module FactoryBot\n  module Strategy\n    class Build\n      def association(runner)\n        runner.run\n      end\n\n      def result(evaluation)\n        evaluation.notify(:before_build, nil)\n\n        evaluation.object.tap do |instance|\n          evaluation.notify(:after_build, instance)\n        end\n      end\n\n      def to_sym\n        :build\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/strategy/create.rb",
    "content": "module FactoryBot\n  module Strategy\n    class Create\n      def association(runner)\n        runner.run\n      end\n\n      def result(evaluation)\n        evaluation.notify(:before_build, nil)\n\n        evaluation.object.tap do |instance|\n          evaluation.notify(:after_build, instance)\n          evaluation.notify(:before_create, instance)\n          evaluation.create(instance)\n          evaluation.notify(:after_create, instance)\n        end\n      end\n\n      def to_sym\n        :create\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/strategy/null.rb",
    "content": "module FactoryBot\n  module Strategy\n    class Null\n      def association(runner)\n      end\n\n      def result(evaluation)\n      end\n\n      def to_sym\n        :null\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/strategy/stub.rb",
    "content": "module FactoryBot\n  module Strategy\n    class Stub\n      @@next_id = 1000\n\n      DISABLED_PERSISTENCE_METHODS = [\n        :connection,\n        :decrement!,\n        :delete,\n        :destroy!,\n        :destroy,\n        :increment!,\n        :reload,\n        :save!,\n        :save,\n        :toggle!,\n        :touch,\n        :update!,\n        :update,\n        :update_attribute,\n        :update_attributes!,\n        :update_attributes,\n        :update_column,\n        :update_columns\n      ].freeze\n\n      def self.next_id=(id)\n        @@next_id = id\n      end\n\n      def association(runner)\n        runner.run(:build_stubbed)\n      end\n\n      def result(evaluation)\n        evaluation.object.tap do |instance|\n          stub_database_interaction_on_result(instance)\n          set_timestamps(instance)\n          clear_changes_information(instance)\n          evaluation.notify(:after_stub, instance)\n        end\n      end\n\n      def to_sym\n        :stub\n      end\n\n      private\n\n      def next_id(result_instance)\n        if uuid_primary_key?(result_instance)\n          SecureRandom.uuid\n        else\n          @@next_id += 1\n        end\n      end\n\n      def stub_database_interaction_on_result(result_instance)\n        if has_settable_id?(result_instance)\n          result_instance.id ||= next_id(result_instance)\n        end\n\n        result_instance.instance_eval do\n          def persisted?\n            true\n          end\n\n          def new_record?\n            false\n          end\n\n          def destroyed?\n            false\n          end\n\n          DISABLED_PERSISTENCE_METHODS.each do |write_method|\n            define_singleton_method(write_method) do |*args|\n              raise \"stubbed models are not allowed to access the database - \" \\\n                    \"#{self.class}##{write_method}(#{args.join(\",\")})\"\n            end\n          end\n        end\n      end\n\n      def has_settable_id?(result_instance)\n        result_instance.respond_to?(:id=) &&\n          (!result_instance.class.respond_to?(:primary_key) ||\n          result_instance.class.primary_key)\n      end\n\n      def uuid_primary_key?(result_instance)\n        result_instance.respond_to?(:column_for_attribute) &&\n          (column = result_instance.column_for_attribute(result_instance.class.primary_key)) &&\n          column.respond_to?(:sql_type) &&\n          column.sql_type == \"uuid\"\n      end\n\n      def clear_changes_information(result_instance)\n        if result_instance.respond_to?(:clear_changes_information)\n          result_instance.clear_changes_information\n        end\n      end\n\n      def set_timestamps(result_instance)\n        timestamp = Time.current\n\n        if missing_created_at?(result_instance)\n          result_instance.created_at = timestamp\n        end\n\n        if missing_updated_at?(result_instance)\n          result_instance.updated_at = timestamp\n        end\n      end\n\n      def missing_created_at?(result_instance)\n        result_instance.respond_to?(:created_at) &&\n          result_instance.respond_to?(:created_at=) &&\n          result_instance.created_at.blank?\n      end\n\n      def missing_updated_at?(result_instance)\n        result_instance.respond_to?(:updated_at) &&\n          result_instance.respond_to?(:updated_at=) &&\n          result_instance.updated_at.blank?\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/strategy.rb",
    "content": "require \"factory_bot/strategy/build\"\nrequire \"factory_bot/strategy/create\"\nrequire \"factory_bot/strategy/attributes_for\"\nrequire \"factory_bot/strategy/stub\"\nrequire \"factory_bot/strategy/null\"\n\nmodule FactoryBot\n  module Strategy\n    def self.lookup_strategy(name_or_object)\n      return name_or_object if name_or_object.is_a?(Class)\n\n      FactoryBot::Internal.strategy_by_name(name_or_object)\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/strategy_syntax_method_registrar.rb",
    "content": "module FactoryBot\n  # @api private\n  class StrategySyntaxMethodRegistrar\n    def initialize(strategy_name)\n      @strategy_name = strategy_name\n    end\n\n    def define_strategy_methods\n      define_singular_strategy_method\n      define_list_strategy_method\n      define_pair_strategy_method\n    end\n\n    def self.with_index(block, index)\n      if block&.arity == 2\n        ->(instance) { block.call(instance, index) }\n      else\n        block\n      end\n    end\n\n    private\n\n    def define_singular_strategy_method\n      strategy_name = @strategy_name\n\n      define_syntax_method(strategy_name) do |name, *traits_and_overrides, &block|\n        FactoryRunner.new(name, strategy_name, traits_and_overrides).run(&block)\n      end\n    end\n\n    def define_list_strategy_method\n      strategy_name = @strategy_name\n\n      define_syntax_method(\"#{strategy_name}_list\") do |name, amount, *traits_and_overrides, &block|\n        unless amount.respond_to?(:times)\n          raise ArgumentError, \"count missing for #{strategy_name}_list\"\n        end\n\n        Array.new(amount) do |i|\n          block_with_index = StrategySyntaxMethodRegistrar.with_index(block, i)\n          send(strategy_name, name, *traits_and_overrides, &block_with_index)\n        end\n      end\n    end\n\n    def define_pair_strategy_method\n      strategy_name = @strategy_name\n\n      define_syntax_method(\"#{strategy_name}_pair\") do |name, *traits_and_overrides, &block|\n        Array.new(2) { send(strategy_name, name, *traits_and_overrides, &block) }\n      end\n    end\n\n    def define_syntax_method(name, &block)\n      FactoryBot::Syntax::Methods.module_exec do\n        if method_defined?(name) || private_method_defined?(name)\n          undef_method(name)\n        end\n\n        define_method(name, &block)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/syntax/default.rb",
    "content": "module FactoryBot\n  module Syntax\n    module Default\n      include Methods\n\n      def define(&block)\n        DSL.run(block)\n      end\n\n      def modify(&block)\n        ModifyDSL.run(block)\n      end\n\n      class DSL\n        def factory(name, options = {}, &block)\n          factory = Factory.new(name, options)\n          proxy = FactoryBot::DefinitionProxy.new(factory.definition)\n          proxy.instance_eval(&block) if block\n\n          Internal.register_factory(factory)\n\n          proxy.child_factories.each do |(child_name, child_options, child_block)|\n            parent_factory = child_options.delete(:parent) || name\n            factory(child_name, child_options.merge(parent: parent_factory), &child_block)\n          end\n        end\n\n        def sequence(name, ...)\n          Internal.register_sequence(Sequence.new(name, ...))\n        end\n\n        def trait(name, &block)\n          Internal.register_trait(Trait.new(name, &block))\n        end\n\n        def self.run(block)\n          new.instance_eval(&block)\n        end\n\n        delegate :after,\n          :before,\n          :callback,\n          :initialize_with,\n          :skip_create,\n          :to_create,\n          to: FactoryBot::Internal\n      end\n\n      class ModifyDSL\n        def factory(name, _options = {}, &block)\n          factory = Internal.factory_by_name(name)\n          proxy = FactoryBot::DefinitionProxy.new(factory.definition.overridable)\n          proxy.instance_eval(&block)\n        end\n\n        def self.run(block)\n          new.instance_eval(&block)\n        end\n      end\n    end\n  end\n\n  extend Syntax::Default\nend\n"
  },
  {
    "path": "lib/factory_bot/syntax/methods.rb",
    "content": "module FactoryBot\n  module Syntax\n    ## This module is a container for all strategy methods provided by\n    ## FactoryBot. This includes all the default strategies provided ({Methods#build},\n    ## {Methods#create}, {Methods#build_stubbed}, and {Methods#attributes_for}), as\n    ## well as the complementary *_list and *_pair methods.\n    ## @example singular factory execution\n    ##   # basic use case\n    ##   build(:completed_order)\n    ##\n    ##   # factory yielding its result to a block\n    ##   create(:post) do |post|\n    ##     create(:comment, post: post)\n    ##   end\n    ##\n    ##   # factory with attribute override\n    ##   attributes_for(:post, title: \"I love Ruby!\")\n    ##\n    ##   # factory with traits and attribute override\n    ##   build_stubbed(:user, :admin, :male, name: \"John Doe\")\n    ##\n    ## @example multiple factory execution\n    ##   # basic use case\n    ##   build_list(:completed_order, 2)\n    ##   create_list(:completed_order, 2)\n    ##\n    ##   # factory with attribute override\n    ##   attributes_for_list(:post, 4, title: \"I love Ruby!\")\n    ##\n    ##   # factory with traits and attribute override\n    ##   build_stubbed_list(:user, 15, :admin, :male, name: \"John Doe\")\n    module Methods\n      # @!parse FactoryBot::Internal.register_default_strategies\n      # @!method build(name, *traits_and_overrides, &block)\n      # (see #strategy_method)\n      # Builds a registered factory by name.\n      # @return [Object] instantiated object defined by the factory\n\n      # @!method create(name, *traits_and_overrides, &block)\n      # (see #strategy_method)\n      # Creates a registered factory by name.\n      # @return [Object] instantiated object defined by the factory\n\n      # @!method build_stubbed(name, *traits_and_overrides, &block)\n      # (see #strategy_method)\n      # Builds a stubbed registered factory by name.\n      # @return [Object] instantiated object defined by the factory\n\n      # @!method attributes_for(name, *traits_and_overrides, &block)\n      # (see #strategy_method)\n      # Generates a hash of attributes for a registered factory by name.\n      # @return [Hash] hash of attributes for the factory\n\n      # @!method build_list(name, amount, *traits_and_overrides, &block)\n      # (see #strategy_method_list)\n      # @return [Array] array of built objects defined by the factory\n\n      # @!method create_list(name, amount, *traits_and_overrides, &block)\n      # (see #strategy_method_list)\n      # @return [Array] array of created objects defined by the factory\n\n      # @!method build_stubbed_list(name, amount, *traits_and_overrides, &block)\n      # (see #strategy_method_list)\n      # @return [Array] array of stubbed objects defined by the factory\n\n      # @!method attributes_for_list(name, amount, *traits_and_overrides, &block)\n      # (see #strategy_method_list)\n      # @return [Array<Hash>] array of attribute hashes for the factory\n\n      # @!method build_pair(name, *traits_and_overrides, &block)\n      # (see #strategy_method_pair)\n      # @return [Array] pair of built objects defined by the factory\n\n      # @!method create_pair(name, *traits_and_overrides, &block)\n      # (see #strategy_method_pair)\n      # @return [Array] pair of created objects defined by the factory\n\n      # @!method build_stubbed_pair(name, *traits_and_overrides, &block)\n      # (see #strategy_method_pair)\n      # @return [Array] pair of stubbed objects defined by the factory\n\n      # @!method attributes_for_pair(name, *traits_and_overrides, &block)\n      # (see #strategy_method_pair)\n      # @return [Array<Hash>] pair of attribute hashes for the factory\n\n      # @!method strategy_method(name, traits_and_overrides, &block)\n      # @!visibility private\n      # @param [Symbol] name the name of the factory to build\n      # @param [Array<Symbol, Symbol, Hash>] traits_and_overrides splat args traits and a hash of overrides\n      # @param [Proc] block block to be executed\n\n      # @!method strategy_method_list(name, amount, traits_and_overrides, &block)\n      # @!visibility private\n      # @param [Symbol] name the name of the factory to execute\n      # @param [Integer] amount the number of instances to execute\n      # @param [Array<Symbol, Symbol, Hash>] traits_and_overrides splat args traits and a hash of overrides\n      # @param [Proc] block block to be executed\n\n      # @!method strategy_method_pair(name, traits_and_overrides, &block)\n      # @!visibility private\n      # @param [Symbol] name the name of the factory to execute\n      # @param [Array<Symbol, Symbol, Hash>] traits_and_overrides splat args traits and a hash of overrides\n      # @param [Proc] block block to be executed\n\n      # Generates and returns the next value in a global or factory sequence.\n      #\n      # Arguments:\n      #   context: (Array of Symbols)\n      #     The definition context of the sequence, with the sequence name\n      #     as the final entry\n      #   scope: (object)(optional)\n      #     The object the sequence should be evaluated within\n      #\n      # Returns:\n      #   The next value in the sequence. (Object)\n      #\n      # Example:\n      #   generate(:my_factory, :my_trair, :my_sequence)\n      #\n      def generate(*uri_parts, scope: nil)\n        uri = FactoryBot::UriManager.build_uri(uri_parts)\n        sequence = Sequence.find_by_uri(uri) ||\n          raise(KeyError,\n            \"Sequence not registered: #{FactoryBot::UriManager.build_uri(uri_parts)}\")\n\n        increment_sequence(sequence, scope: scope)\n      end\n\n      # Generates and returns the list of values in a global or factory sequence.\n      #\n      # Arguments:\n      #   uri_parts: (Array of Symbols)\n      #     The definition context of the sequence, with the sequence name\n      #     as the final entry\n      #   scope: (object)(optional)\n      #     The object the sequence should be evaluated within\n      #\n      # Returns:\n      #   The next value in the sequence. (Object)\n      #\n      # Example:\n      #   generate_list(:my_factory, :my_trair, :my_sequence, 5)\n      #\n      def generate_list(*uri_parts, count, scope: nil)\n        uri = FactoryBot::UriManager.build_uri(uri_parts)\n        sequence = Sequence.find_by_uri(uri) ||\n          raise(KeyError, \"Sequence not registered: '#{uri}'\")\n\n        (1..count).map do\n          increment_sequence(sequence, scope: scope)\n        end\n      end\n\n      # ======================================================================\n      # = PRIVATE\n      # ======================================================================\n      #\n      private\n\n      ##\n      # Increments the given sequence and returns the value.\n      #\n      # Arguments:\n      #   sequence:\n      #     The sequence instance\n      #   scope: (object)(optional)\n      #     The object the sequence should be evaluated within\n      #\n      def increment_sequence(sequence, scope: nil)\n        value = sequence.next(scope)\n\n        raise if value.respond_to?(:start_with?) && value.start_with?(\"#<FactoryBot::Declaration\")\n\n        value\n      rescue\n        raise ArgumentError, \"Sequence '#{sequence.uri_manager.first}' failed to \" \\\n                            \"return a value. Perhaps it needs a scope to operate? (scope: <object>)\"\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/syntax.rb",
    "content": "require \"factory_bot/syntax/methods\"\nrequire \"factory_bot/syntax/default\"\n\nmodule FactoryBot\n  module Syntax\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/syntax_runner.rb",
    "content": "module FactoryBot\n  # @api private\n  class SyntaxRunner\n    include Syntax::Methods\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/trait.rb",
    "content": "module FactoryBot\n  # @api private\n  class Trait\n    attr_reader :name, :uid, :definition\n\n    delegate :add_callback, :declare_attribute, :to_create, :define_trait, :constructor,\n      :callbacks, :attributes, :klass, :klass=, to: :@definition\n\n    def initialize(name, **options, &block)\n      @name = name.to_s\n      @block = block\n      @uri_manager = FactoryBot::UriManager.new(names, paths: options[:uri_paths])\n\n      @definition = Definition.new(@name, uri_manager: @uri_manager)\n      proxy = FactoryBot::DefinitionProxy.new(@definition)\n\n      if block\n        proxy.instance_eval(&@block)\n      end\n    end\n\n    def clone\n      Trait.new(name, uri_paths: definition.uri_manager.paths, &block)\n    end\n\n    def names\n      [@name]\n    end\n\n    def ==(other)\n      name == other.name &&\n        block == other.block\n    end\n\n    protected\n\n    attr_reader :block\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/uri_manager.rb",
    "content": "module FactoryBot\n  # @api private\n  class UriManager\n    attr_reader :endpoints, :paths, :uri_list\n\n    delegate :size, :any?, :empty?, :each?, :include?, :first, to: :@uri_list\n    delegate :build_uri, to: :class\n\n    # Concatenate the parts, sripping leading/following slashes\n    # and returning a Symbolized String or nil.\n    #\n    # Example:\n    #   build_uri(:my_factory, :my_trait, :my_sequence)\n    #   #=> :\"myfactory/my_trait/my_sequence\"\n    #\n    def self.build_uri(*parts)\n      return nil if parts.empty?\n\n      parts.join(\"/\")\n        .sub(/\\A\\/+/, \"\")\n        .sub(/\\/+\\z/, \"\")\n        .tr(\" \", \"_\")\n        .to_sym\n    end\n\n    # Configures the new UriManager\n    #\n    # Arguments:\n    #   endpoints: (Array of Strings or Symbols)\n    #     the objects endpoints.\n    #\n    #   paths: (Array of Strings or Symbols)\n    #     the parent URIs to prepend to each endpoint\n    #\n    def initialize(*endpoints, paths: [])\n      if endpoints.empty?\n        fail ArgumentError, \"wrong number of arguments (given 0, expected 1+)\"\n      end\n\n      @uri_list = []\n      @endpoints = endpoints.flatten\n      @paths = Array(paths).flatten\n\n      build_uri_list\n    end\n\n    def to_a\n      @uri_list.dup\n    end\n\n    private\n\n    def build_uri_list\n      @endpoints.each do |endpoint|\n        if @paths.any?\n          @paths.each { |path| @uri_list << build_uri(path, endpoint) }\n        else\n          @uri_list << build_uri(endpoint)\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/factory_bot/version.rb",
    "content": "module FactoryBot\n  VERSION = \"6.5.6\".freeze\nend\n"
  },
  {
    "path": "lib/factory_bot.rb",
    "content": "require \"set\"\nrequire \"active_support\"\nrequire \"active_support/core_ext/module/delegation\"\nrequire \"active_support/core_ext/module/attribute_accessors\"\nrequire \"active_support/deprecation\"\nrequire \"active_support/notifications\"\n\nrequire \"factory_bot/internal\"\nrequire \"factory_bot/definition_hierarchy\"\nrequire \"factory_bot/configuration\"\nrequire \"factory_bot/errors\"\nrequire \"factory_bot/factory_runner\"\nrequire \"factory_bot/strategy_syntax_method_registrar\"\nrequire \"factory_bot/strategy\"\nrequire \"factory_bot/registry\"\nrequire \"factory_bot/null_factory\"\nrequire \"factory_bot/null_object\"\nrequire \"factory_bot/evaluation\"\nrequire \"factory_bot/factory\"\nrequire \"factory_bot/attribute_assigner\"\nrequire \"factory_bot/evaluator\"\nrequire \"factory_bot/evaluator_class_definer\"\nrequire \"factory_bot/attribute\"\nrequire \"factory_bot/callback\"\nrequire \"factory_bot/callbacks_observer\"\nrequire \"factory_bot/declaration_list\"\nrequire \"factory_bot/declaration\"\nrequire \"factory_bot/sequence\"\nrequire \"factory_bot/attribute_list\"\nrequire \"factory_bot/trait\"\nrequire \"factory_bot/enum\"\nrequire \"factory_bot/aliases\"\nrequire \"factory_bot/definition\"\nrequire \"factory_bot/definition_proxy\"\nrequire \"factory_bot/syntax\"\nrequire \"factory_bot/syntax_runner\"\nrequire \"factory_bot/find_definitions\"\nrequire \"factory_bot/reload\"\nrequire \"factory_bot/decorator\"\nrequire \"factory_bot/decorator/attribute_hash\"\nrequire \"factory_bot/decorator/disallows_duplicates_registry\"\nrequire \"factory_bot/decorator/invocation_tracker\"\nrequire \"factory_bot/decorator/new_constructor\"\nrequire \"factory_bot/uri_manager\"\nrequire \"factory_bot/linter\"\nrequire \"factory_bot/version\"\n\nmodule FactoryBot\n  Deprecation = ActiveSupport::Deprecation.new(\"7.0\", \"factory_bot\")\n\n  mattr_accessor :use_parent_strategy, instance_accessor: false\n  self.use_parent_strategy = true\n\n  mattr_accessor :automatically_define_enum_traits, instance_accessor: false\n  self.automatically_define_enum_traits = true\n\n  mattr_accessor :sequence_setting_timeout, instance_accessor: false\n  self.sequence_setting_timeout = 3\n\n  # Look for errors in factories and (optionally) their traits.\n  # Parameters:\n  # factories - which factories to lint; omit for all factories\n  # options:\n  #   traits: true - to lint traits as well as factories\n  #   strategy: :create - to specify the strategy for linting\n  #   verbose: true - to include full backtraces for each linting error\n  def self.lint(*args)\n    options = args.extract_options!\n    factories_to_lint = args[0] || FactoryBot.factories\n    Linter.new(factories_to_lint, **options).lint!\n  end\n\n  # Set the starting value for ids when using the build_stubbed strategy\n  #\n  # @param [Integer] starting_id The new starting id value.\n  def self.build_stubbed_starting_id=(starting_id)\n    Strategy::Stub.next_id = starting_id - 1\n  end\n\n  class << self\n    # @!method rewind_sequence(*uri_parts)\n    #   Rewind an individual global or inline sequence.\n    #\n    #   @param [Array<Symbol>, String] uri_parts The components of the sequence URI.\n    #\n    #   @example Rewinding a sequence by its URI parts\n    #     rewind_sequence(:factory_name, :trait_name, :sequence_name)\n    #\n    #   @example Rewinding a sequence by its URI string\n    #     rewind_sequence(\"factory_name/trait_name/sequence_name\")\n    #\n    # @!method set_sequence(*uri_parts, value)\n    #   Set the sequence to a specific value, providing the new value is within\n    #   the sequence set.\n    #\n    #   @param [Array<Symbol>, String] uri_parts The components of the sequence URI.\n    #   @param [Object] value The new value for the sequence. This must be a value that is\n    #     within the sequence definition. For example, you cannot set\n    #     a String sequence to an Integer value.\n    #\n    #   @example\n    #     set_sequence(:factory_name, :trait_name, :sequence_name, 450)\n    #   @example\n    #     set_sequence([:factory_name, :trait_name, :sequence_name], 450)\n    #   @example\n    #     set_sequence(\"factory_name/trait_name/sequence_name\", 450)\n    delegate :factories,\n      :register_strategy,\n      :rewind_sequences,\n      :rewind_sequence,\n      :set_sequence,\n      :strategy_by_name,\n      to: Internal\n  end\nend\n\nFactoryBot::Internal.register_default_strategies\n"
  },
  {
    "path": "spec/acceptance/activesupport_instrumentation_spec.rb",
    "content": "unless ActiveSupport::Notifications.respond_to?(:subscribed)\n  module SubscribedBehavior\n    def subscribed(callback, *args)\n      subscriber = subscribe(*args, &callback)\n      yield\n    ensure\n      unsubscribe(subscriber)\n    end\n  end\n\n  ActiveSupport::Notifications.extend SubscribedBehavior\nend\n\ndescribe \"using ActiveSupport::Instrumentation to track run_factory interaction\" do\n  let(:slow_user_factory) { FactoryBot::Internal.factory_by_name(\"slow_user\") }\n  let(:user_factory) { FactoryBot::Internal.factory_by_name(\"user\") }\n  before do\n    define_model(\"User\", email: :string)\n    define_model(\"Post\", user_id: :integer) do\n      belongs_to :user\n    end\n\n    FactoryBot.define do\n      factory :user do\n        email { \"john@example.com\" }\n\n        factory :slow_user do\n          after(:build) { Kernel.sleep(0.1) }\n        end\n      end\n\n      factory :post do\n        trait :with_user do\n          user\n        end\n      end\n    end\n  end\n\n  it \"tracks proper time of creating the record\" do\n    time_to_execute = 0\n    callback = ->(_name, start, finish, _id, _payload) { time_to_execute = finish - start }\n    ActiveSupport::Notifications.subscribed(callback, \"factory_bot.run_factory\") do\n      FactoryBot.build(:slow_user)\n    end\n\n    expect(time_to_execute).to be >= 0.1\n  end\n\n  it \"builds the correct payload\", :slow do\n    tracked_invocations = {}\n\n    callback = ->(_name, _start, _finish, _id, payload) do\n      factory_name = payload[:name]\n      strategy_name = payload[:strategy]\n      factory = payload[:factory]\n      tracked_invocations[factory_name] ||= {}\n      tracked_invocations[factory_name][strategy_name] ||= 0\n      tracked_invocations[factory_name][strategy_name] += 1\n      tracked_invocations[factory_name][:factory] = factory\n    end\n\n    ActiveSupport::Notifications.subscribed(callback, \"factory_bot.run_factory\") do\n      FactoryBot.build_list(:slow_user, 2)\n      FactoryBot.build_list(:user, 5)\n      FactoryBot.create_list(:user, 2)\n      FactoryBot.attributes_for(:slow_user)\n      user = FactoryBot.create(:user)\n      FactoryBot.create(:post, user: user)\n      FactoryBot.create_list(:post, 2, :with_user)\n    end\n\n    expect(tracked_invocations[:slow_user][:build]).to eq(2)\n    expect(tracked_invocations[:slow_user][:attributes_for]).to eq(1)\n    expect(tracked_invocations[:slow_user][:factory]).to eq(slow_user_factory)\n    expect(tracked_invocations[:user][:build]).to eq(5)\n    expect(tracked_invocations[:user][:factory]).to eq(user_factory)\n    expect(tracked_invocations[:user][:create]).to eq(5)\n  end\nend\n\ndescribe \"using ActiveSupport::Instrumentation to track compile_factory interaction\" do\n  before do\n    define_model(\"User\", name: :string, email: :string)\n\n    FactoryBot.define do\n      factory :user do\n        sequence(:email) { |n| \"user_#{n}@example.com\" }\n\n        name { \"User\" }\n\n        trait :special do\n          name { \"Special User\" }\n        end\n      end\n    end\n  end\n\n  it \"tracks proper time of compiling the factory\" do\n    time_to_execute = {user: 0}\n    callback = ->(_name, start, finish, _id, payload) {\n      time_to_execute[payload[:name]] = (finish - start)\n    }\n    ActiveSupport::Notifications.subscribed(callback, \"factory_bot.compile_factory\") do\n      FactoryBot.build(:user)\n    end\n\n    expect(time_to_execute[:user]).to be > 0\n  end\n\n  it \"builds the correct payload\" do\n    tracked_payloads = []\n    callback = ->(_name, _start, _finish, _id, payload) { tracked_payloads << payload }\n\n    ActiveSupport::Notifications.subscribed(callback, \"factory_bot.compile_factory\") do\n      FactoryBot.build(:user, :special)\n    end\n\n    factory_payload = tracked_payloads.detect { |payload| payload[:name] == :user }\n    expect(factory_payload[:class]).to eq(User)\n    expect(factory_payload[:attributes].map(&:name)).to eq([:email, :name])\n    expect(factory_payload[:traits].map(&:name)).to eq([\"special\"])\n\n    trait_payload = tracked_payloads.detect { |payload| payload[:name] == \"special\" }\n    expect(trait_payload[:class]).to eq(User)\n    expect(trait_payload[:attributes].map(&:name)).to eq([:name])\n    expect(trait_payload[:traits].map(&:name)).to eq([\"special\"])\n  end\n\n  context \"when factory with base traits\" do\n    before do\n      define_model(\"Company\", name: :string, email: :string)\n\n      FactoryBot.define do\n        trait :email do\n          email { \"#{name}@example.com\" }\n        end\n\n        factory :company, traits: [:email] do\n          name { \"Charlie\" }\n        end\n      end\n    end\n\n    it \"builds the correct payload\" do\n      tracked_payloads = []\n      callback = ->(_name, _start, _finish, _id, payload) { tracked_payloads << payload }\n\n      ActiveSupport::Notifications.subscribed(callback, \"factory_bot.compile_factory\") do\n        FactoryBot.build(:company)\n      end\n\n      factory_payload = tracked_payloads.detect { |payload| payload[:name] == :company }\n      expect(factory_payload[:class]).to eq(Company)\n      expect(factory_payload[:attributes].map(&:name)).to eq([:name])\n      expect(factory_payload[:traits].map(&:name)).to eq([])\n\n      trait_payload = tracked_payloads.detect { |payload| payload[:name] == \"email\" }\n      expect(trait_payload[:class]).to eq(Company)\n      expect(trait_payload[:attributes].map(&:name)).to eq([:email])\n      expect(trait_payload[:traits].map(&:name)).to eq([])\n    end\n  end\n\n  context \"when factory with additional traits\" do\n    before do\n      define_model(\"Company\", name: :string, email: :string)\n\n      FactoryBot.define do\n        trait :email do\n          email { \"#{name}@example.com\" }\n        end\n\n        factory :company do\n          name { \"Charlie\" }\n        end\n      end\n    end\n\n    it \"builds the correct payload\" do\n      tracked_payloads = []\n      callback = ->(_name, _start, _finish, _id, payload) { tracked_payloads << payload }\n\n      ActiveSupport::Notifications.subscribed(callback, \"factory_bot.compile_factory\") do\n        FactoryBot.build(:company, :email)\n      end\n\n      factory_payload = tracked_payloads.detect { |payload| payload[:name] == :company }\n      expect(factory_payload[:class]).to eq(Company)\n      expect(factory_payload[:attributes].map(&:name)).to eq([:name])\n      expect(factory_payload[:traits].map(&:name)).to eq([])\n\n      trait_payload = tracked_payloads.detect { |payload| payload[:name] == \"email\" }\n      expect(trait_payload[:class]).to eq(Company)\n      expect(trait_payload[:attributes].map(&:name)).to eq([:email])\n      expect(trait_payload[:traits].map(&:name)).to eq([])\n    end\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/add_attribute_spec.rb",
    "content": "describe \"#add_attribute\" do\n  it \"assigns attributes for reserved words on .build\" do\n    define_model(\"Post\", title: :string, sequence: :string, new: :boolean)\n\n    FactoryBot.define do\n      factory :post do\n        add_attribute(:title) { \"Title\" }\n        add_attribute(:sequence) { \"Sequence\" }\n        add_attribute(:new) { true }\n      end\n    end\n\n    post = FactoryBot.build(:post)\n\n    expect(post.title).to eq \"Title\"\n    expect(post.sequence).to eq \"Sequence\"\n    expect(post.new).to eq true\n  end\n\n  it \"assigns attributes for reserved words on .attributes_for\" do\n    define_model(\"Post\", title: :string, sequence: :string, new: :boolean)\n\n    FactoryBot.define do\n      factory :post do\n        add_attribute(:title) { \"Title\" }\n        add_attribute(:sequence) { \"Sequence\" }\n        add_attribute(:new) { true }\n      end\n    end\n\n    post = FactoryBot.attributes_for(:post)\n\n    expect(post[:title]).to eq \"Title\"\n    expect(post[:sequence]).to eq \"Sequence\"\n    expect(post[:new]).to eq true\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/associations_spec.rb",
    "content": "describe \"associations\" do\n  context \"when accidentally using an implicit declaration for the factory\" do\n    it \"raises an error\" do\n      define_class(\"Post\")\n\n      FactoryBot.define do\n        factory :post do\n          author factory: user\n        end\n      end\n\n      expect { FactoryBot.build(:post) }.to raise_error(\n        ArgumentError,\n        \"Association 'author' received an invalid factory argument.\\n\" \\\n        \"Did you mean? 'factory: :user'\\n\"\n      )\n    end\n  end\n\n  context \"when accidentally using an implicit declaration as an override\" do\n    it \"raises an error\" do\n      define_class(\"Post\")\n\n      FactoryBot.define do\n        factory :post do\n          author factory: :user, invalid_attribute: implicit_trait\n        end\n      end\n\n      expect { FactoryBot.build(:post) }.to raise_error(\n        ArgumentError,\n        \"Association 'author' received an invalid attribute override.\\n\" \\\n        \"Did you mean? 'invalid_attribute: :implicit_trait'\\n\"\n      )\n    end\n  end\n\n  context \"when building interrelated associations\" do\n    it \"assigns the instance passed as an association attribute\" do\n      define_class(\"Supplier\") do\n        attr_accessor :account\n      end\n\n      define_class(\"Account\") do\n        attr_accessor :supplier\n      end\n\n      FactoryBot.define do\n        factory :supplier\n\n        factory :account do\n          supplier { association(:supplier, account: instance) }\n        end\n      end\n\n      account = FactoryBot.build(:account)\n\n      expect(account.supplier.account).to eq(account)\n    end\n\n    it \"connects records with interdependent relationships\" do\n      define_model(\"Student\", school_id: :integer) do\n        belongs_to :school\n        has_one :profile\n      end\n\n      define_model(\"Profile\", school_id: :integer, student_id: :integer) do\n        belongs_to :school\n        belongs_to :student\n      end\n\n      define_model(\"School\") do\n        has_many :students\n        has_many :profiles\n      end\n\n      FactoryBot.define do\n        factory :student do\n          school\n          profile { association :profile, student: instance, school: school }\n        end\n\n        factory :profile do\n          school\n          student { association :student, profile: instance, school: school }\n        end\n\n        factory :school\n      end\n\n      student = FactoryBot.create(:student)\n\n      expect(student.profile.school).to eq(student.school)\n      expect(student.profile.student).to eq(student)\n      expect(student.school.students.map(&:id)).to eq([student.id])\n      expect(student.school.profiles.map(&:id)).to eq([student.profile.id])\n\n      profile = FactoryBot.create(:profile)\n\n      expect(profile.student.school).to eq(profile.school)\n      expect(profile.student.profile).to eq(profile)\n      expect(profile.school.profiles.map(&:id)).to eq([profile.id])\n      expect(profile.school.students.map(&:id)).to eq([profile.student.id])\n    end\n  end\n\n  context \"when building collection associations\" do\n    it \"builds the association according to the given strategy\" do\n      define_model(\"Photo\", listing_id: :integer) do\n        belongs_to :listing\n        attr_accessor :name\n      end\n\n      define_model(\"Listing\") do\n        has_many :photos\n      end\n\n      FactoryBot.define do\n        factory :photo\n\n        factory :listing do\n          photos { [association(:photo)] }\n        end\n      end\n\n      created_listing = FactoryBot.create(:listing)\n\n      expect(created_listing.photos.first).to be_a Photo\n      expect(created_listing.photos.first).to be_persisted\n\n      built_listing = FactoryBot.build(:listing)\n\n      expect(built_listing.photos.first).to be_a Photo\n      expect(built_listing.photos.first).not_to be_persisted\n\n      stubbed_listing = FactoryBot.build_stubbed(:listing)\n\n      expect(stubbed_listing.photos.first).to be_a Photo\n      expect(stubbed_listing.photos.first).to be_persisted\n      expect { stubbed_listing.photos.first.save! }.to raise_error(\n        \"stubbed models are not allowed to access the database - Photo#save!()\"\n      )\n    end\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/attribute_aliases_spec.rb",
    "content": "describe \"attribute aliases\" do\n  around do |example|\n    original_aliases = FactoryBot.aliases.dup\n    example.run\n  ensure\n    FactoryBot.aliases.clear\n    FactoryBot.aliases.concat(original_aliases)\n  end\n\n  describe \"basic alias functionality\" do\n    it \"allows using different parameter names that map to model attributes\" do\n      FactoryBot.aliases << [/author_name/, \"name\"]\n      define_model(\"User\", name: :string, author_name: :string)\n\n      FactoryBot.define do\n        factory :user do\n          name { \"Default Name\" }\n        end\n      end\n\n      user = FactoryBot.create(:user, author_name: \"Custom Name\")\n\n      expect(user.author_name).to eq \"Custom Name\"\n      expect(user.name).to be_nil\n    end\n\n    it \"ignores factory defaults when alias is used\" do\n      FactoryBot.aliases << [/display_name/, \"name\"]\n      define_model(\"User\", name: :string, display_name: :string)\n\n      FactoryBot.define do\n        factory :user do\n          name { \"Factory Name\" }\n        end\n      end\n\n      user = FactoryBot.create(:user, display_name: \"Override Name\")\n\n      expect(user.display_name).to eq \"Override Name\"\n      expect(user.name).to be_nil\n    end\n  end\n\n  describe \"built-in _id aliases\" do\n    it \"automatically alias between associations and foreign keys\" do\n      define_model(\"User\", name: :string)\n      define_model(\"Post\", user_id: :integer) do\n        belongs_to :user, optional: true\n      end\n\n      FactoryBot.define do\n        factory :user do\n          name { \"Test User\" }\n        end\n\n        factory :post\n      end\n\n      user = FactoryBot.create(:user)\n\n      post_with_direct_id = FactoryBot.create(:post, user_id: user.id)\n      expect(post_with_direct_id.user_id).to eq user.id\n\n      post_with_association = FactoryBot.create(:post, user: user)\n      expect(post_with_association.user_id).to eq user.id\n    end\n\n    it \"prevents conflicts between associations and foreign keys\" do\n      define_model(\"User\", name: :string, age: :integer)\n      define_model(\"Post\", user_id: :integer) do\n        belongs_to :user\n      end\n\n      FactoryBot.define do\n        factory :user do\n          factory :user_with_name do\n            name { \"John Doe\" }\n          end\n        end\n\n        factory :post do\n          user\n        end\n      end\n\n      post_with_foreign_key = FactoryBot.build(:post, user_id: 1)\n\n      expect(post_with_foreign_key.user_id).to eq 1\n    end\n\n    it \"allows passing attributes to associated factories\" do\n      define_model(\"User\", name: :string, age: :integer)\n      define_model(\"Post\", user_id: :integer) do\n        belongs_to :user\n      end\n\n      FactoryBot.define do\n        factory :user do\n          factory :user_with_name do\n            name { \"John Doe\" }\n          end\n        end\n\n        factory :post do\n          user\n        end\n\n        factory :post_with_named_user, class: Post do\n          user factory: :user_with_name, age: 20\n        end\n      end\n\n      created_user = FactoryBot.create(:post_with_named_user).user\n\n      expect(created_user.name).to eq \"John Doe\"\n      expect(created_user.age).to eq 20\n    end\n  end\n\n  describe \"custom alias patterns\" do\n    it \"supports regex patterns with capture groups\" do\n      FactoryBot.aliases << [/(.+)_alias/, '\\1']\n      define_model(\"User\", name: :string, name_alias: :string, email: :string, email_alias: :string)\n\n      FactoryBot.define do\n        factory :user do\n          name { \"Default Name\" }\n          email { \"default@example.com\" }\n        end\n      end\n\n      user = FactoryBot.create(:user, name_alias: \"Aliased Name\", email_alias: \"aliased@example.com\")\n\n      expect(user.name).to be_nil\n      expect(user.email).to be_nil\n      expect(user.name_alias).to eq \"Aliased Name\"\n      expect(user.email_alias).to eq \"aliased@example.com\"\n    end\n\n    it \"supports multiple alias patterns working together\" do\n      FactoryBot.aliases << [/primary_(.+)/, '\\1']\n      FactoryBot.aliases << [/alt_name/, \"name\"]\n      define_model(\"User\", name: :string, email: :string, primary_email: :string, alt_name: :string)\n\n      FactoryBot.define do\n        factory :user do\n          name { \"Default Name\" }\n          email { \"default@example.com\" }\n        end\n      end\n\n      user = FactoryBot.create(:user, primary_email: \"primary@example.com\", alt_name: \"Alternative Name\")\n\n      expect(user.name).to be_nil\n      expect(user.email).to be_nil\n      expect(user.primary_email).to eq \"primary@example.com\"\n      expect(user.alt_name).to eq \"Alternative Name\"\n    end\n\n    it \"works with custom foreign key names\" do\n      FactoryBot.aliases << [/owner_id/, \"user_id\"]\n      define_model(\"User\", name: :string)\n      define_model(\"Document\", user_id: :integer, owner_id: :integer, title: :string) do\n        belongs_to :user, optional: true\n      end\n\n      FactoryBot.define do\n        factory :user do\n          name { \"Test User\" }\n        end\n\n        factory :document do\n          title { \"Test Document\" }\n        end\n      end\n\n      document_owner = FactoryBot.create(:user)\n      document = FactoryBot.create(:document, owner_id: document_owner.id)\n\n      expect(document.user_id).to be_nil\n      expect(document.owner_id).to eq document_owner.id\n      expect(document.title).to eq \"Test Document\"\n    end\n  end\n\n  describe \"edge cases\" do\n    it \"allows setting nil values through aliases\" do\n      FactoryBot.aliases << [/clear_name/, \"name\"]\n      define_model(\"User\", name: :string, clear_name: :string)\n\n      FactoryBot.define do\n        factory :user do\n          name { \"Default Name\" }\n        end\n      end\n\n      user = FactoryBot.create(:user, clear_name: nil)\n\n      expect(user.name).to be_nil\n      expect(user.clear_name).to be_nil\n    end\n\n    context \"when both alias and target attributes exist on model\" do\n      it \"ignores factory defaults for target when alias is used\" do\n        FactoryBot.aliases << [/one/, \"two\"]\n        define_model(\"User\", two: :string, one: :string)\n\n        FactoryBot.define do\n          factory :user do\n            two { \"set value\" }\n          end\n        end\n\n        user = FactoryBot.create(:user, one: \"override\")\n\n        expect(user.one).to eq \"override\"\n        expect(user.two).to be_nil\n      end\n    end\n  end\n\n  describe \"with attributes_for strategy\" do\n    it \"includes alias names in hash and ignores aliased factory defaults\" do\n      FactoryBot.aliases << [/author_name/, \"name\"]\n      define_model(\"User\", name: :string, author_name: :string)\n\n      FactoryBot.define do\n        factory :user do\n          name { \"Default Name\" }\n        end\n      end\n\n      attributes = FactoryBot.attributes_for(:user, author_name: \"Custom Name\")\n\n      expect(attributes[:author_name]).to eq \"Custom Name\"\n      expect(attributes[:name]).to be_nil\n    end\n  end\n\n  describe \"attribute conflicts with _id patterns\" do\n    it \"doesn't set factory defaults when alias is used instead of target attribute\" do\n      define_model(\"User\", name: :string, response_id: :integer)\n\n      FactoryBot.define do\n        factory :user do\n          name { \"orig name\" }\n          response_id { 42 }\n        end\n      end\n\n      attributes = FactoryBot.attributes_for(:user, name: \"new name\", response: 13.75)\n\n      expect(attributes[:name]).to eq \"new name\"\n      expect(attributes[:response]).to eq 13.75\n      expect(attributes[:response_id]).to be_nil\n    end\n\n    it \"allows setting both attribute and attribute_id without conflicts\" do\n      define_model(\"User\", name: :string, response: :string, response_id: :float)\n\n      FactoryBot.define do\n        factory :user do\n          name { \"orig name\" }\n          response { \"orig response\" }\n          response_id { 42 }\n        end\n      end\n\n      user = FactoryBot.build(:user, name: \"new name\", response: \"new response\", response_id: 13.75)\n\n      expect(user.name).to eq \"new name\"\n      expect(user.response).to eq \"new response\"\n      expect(user.response_id).to eq 13.75\n    end\n\n    context \"when association overrides trait foreign key\" do\n      before do\n        define_model(\"User\", name: :string)\n        define_model(\"Post\", user_id: :integer, title: :string) do\n          belongs_to :user, optional: true\n        end\n\n        FactoryBot.define do\n          factory :user do\n            name { \"Test User\" }\n          end\n          factory :post do\n            association :user\n            title { \"Test Post\" }\n\n            trait :with_system_user_id do\n              user_id { 999 }\n            end\n\n            trait :with_user_id_100 do\n              user_id { 100 }\n            end\n\n            trait :with_user_id_200 do\n              user_id { 200 }\n            end\n          end\n        end\n      end\n\n      it \"prefers association override over trait foreign key\" do\n        user = FactoryBot.create(:user)\n        post = FactoryBot.build(:post, :with_system_user_id, user: user)\n\n        expect(post.user).to be user\n        expect(post.user_id).to eq user.id\n      end\n\n      it \"uses trait foreign key when no association override is provided\" do\n        post = FactoryBot.build(:post, :with_system_user_id)\n\n        expect(post.user).to be nil\n        expect(post.user_id).to eq 999\n      end\n\n      it \"handles multiple traits with foreign keys correctly\" do\n        user = FactoryBot.create(:user)\n        post = FactoryBot.build(:post, :with_user_id_100, :with_user_id_200, user: user)\n\n        expect(post.user).to be user\n        expect(post.user_id).to eq user.id\n      end\n    end\n  end\n\n  context \"when a factory defines attributes for both sides of an association\" do\n    before do\n      define_model(\"User\", name: :string, age: :integer)\n      define_model(\"Post\", user_id: :integer, title: :string) do\n        belongs_to :user\n      end\n    end\n\n    context \"when using the build strategy\" do\n      it \"prefers the :user association when defined after the :user_id attribute\" do\n        FactoryBot.define do\n          factory :user\n          factory :post do\n            user_id { 999 }\n            user\n          end\n        end\n\n        user = FactoryBot.build_stubbed(:user)\n        post = FactoryBot.build(:post, user_id: user.id)\n\n        # A regression from v6.5.5 resulted in an extraneous user instance being\n        # built and assigned to post.user; it also failed to use the user_id override\n        expect(post.user).to be nil\n        expect(post.user_id).to eq user.id\n      end\n\n      it \"prefers the :user_id attribute when defined after the :user attribute\" do\n        FactoryBot.define do\n          factory :user\n          factory :post do\n            user\n            user_id { 999 }\n          end\n        end\n\n        user = FactoryBot.build_stubbed(:user)\n        post = FactoryBot.build(:post, user: user)\n\n        # A regression from v6.5.5 erroneously assigns the value of 999 to post.user_id\n        # and fails to assign the user override\n        expect(post.user).to be user\n        expect(post.user_id).to be user.id\n      end\n    end\n\n    context \"when using the create strategy\" do\n      it \"handles an override of the foreign key when the :user association is declared last\" do\n        FactoryBot.define do\n          factory :user\n          factory :post do\n            user_id { 999 }\n            user\n          end\n        end\n\n        user = FactoryBot.create(:user)\n        post = FactoryBot.create(:post, user_id: user.id)\n\n        # A regression in v6.5.5 created an erroneous second user and assigned\n        # that to post.user and post.user_id.\n        expect(post.user.id).to be user.id\n        expect(post.user_id).to eq user.id\n        expect(User.count).to eq 1\n      end\n\n      it \"handles an override of the associated object when the :user association is declared last\" do\n        FactoryBot.define do\n          factory :user\n          factory :post do\n            user_id { 999 }\n            user\n          end\n        end\n\n        user = FactoryBot.create(:user)\n        post = FactoryBot.create(:post, user: user)\n\n        # This worked fine in v6.5.5, no regression behavior exhibited\n        expect(post.user).to eq user\n        expect(post.user_id).to eq user.id\n        expect(User.count).to eq 1\n      end\n\n      it \"handles an override of the associated object when :user_id is declared last\" do\n        FactoryBot.define do\n          factory :user\n          factory :post do\n            user\n            # this :user_id attribute is purposely declared after :user\n            user_id { 999 }\n          end\n        end\n\n        user = FactoryBot.create(:user)\n        post = FactoryBot.create(:post, user: user)\n\n        # A regression from v6.5.5 erroneously asignes 999 to post.user_id\n        # and leaves post.user assigned to nil\n        expect(post.user_id).to eq user.id\n        expect(post.user).to eq user\n        expect(User.count).to eq 1\n      end\n\n      it \"handles an override of the foreign key when :user_id is declared last\" do\n        FactoryBot.define do\n          factory :user do\n            name { \"tester\" }\n            age { 99 }\n          end\n          factory :post do\n            user\n            # this :user_id attribute is purposely declared after :user\n            user_id { 999 }\n          end\n        end\n\n        user = FactoryBot.create(:user)\n        post = FactoryBot.create(:post, user_id: user.id)\n\n        # A regression from v6.5.5 assigns the expected values to post.user and post.user_id\n        # An erroneous second user instance, however, is created in the background\n        expect(post.user_id).to eq user.id\n        expect(post.user.id).to be user.id\n        expect(User.count).to eq 1\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/attribute_existing_on_object_spec.rb",
    "content": "describe \"declaring attributes on a Factory that are private methods on Object\" do\n  before do\n    define_model(\"Website\", system: :boolean, link: :string, sleep: :integer)\n\n    FactoryBot.define do\n      factory :website do\n        system { false }\n        link { \"http://example.com\" }\n        sleep { 15 }\n      end\n    end\n  end\n\n  subject { FactoryBot.build(:website, sleep: -5) }\n\n  its(:system) { should eq false }\n  its(:link) { should eq \"http://example.com\" }\n  its(:sleep) { should eq(-5) }\nend\n\ndescribe \"assigning overrides that are also private methods on object\" do\n  before do\n    define_model(\"Website\", format: :string, y: :integer, more_format: :string, some_funky_method: :string)\n\n    Object.class_eval do\n      private\n\n      def some_funky_method(args)\n      end\n    end\n\n    FactoryBot.define do\n      factory :website do\n        more_format { \"format: #{format}\" }\n      end\n    end\n  end\n\n  after do\n    Object.send(:undef_method, :some_funky_method)\n  end\n\n  subject { FactoryBot.build(:website, format: \"Great\", y: 12345, some_funky_method: \"foobar!\") }\n  its(:format) { should eq \"Great\" }\n  its(:y) { should eq 12345 }\n  its(:more_format) { should eq \"format: Great\" }\n  its(:some_funky_method) { should eq \"foobar!\" }\nend\n\ndescribe \"accessing methods from the instance within a dynamic attribute \" \\\n         \"that is also a private method on object\" do\n  before do\n    define_model(\"Website\", more_format: :string) do\n      def format\n        \"This is an awesome format\"\n      end\n    end\n\n    FactoryBot.define do\n      factory :website do\n        more_format { \"format: #{format}\" }\n      end\n    end\n  end\n\n  subject { FactoryBot.build(:website) }\n  its(:more_format) { should eq \"format: This is an awesome format\" }\nend\n"
  },
  {
    "path": "spec/acceptance/attributes_for_destructuring.rb",
    "content": "describe \"Ruby 3.0: attributes_for destructuring syntax\" do\n  include FactoryBot::Syntax::Methods\n\n  before do\n    define_model(\"User\", name: :string)\n\n    FactoryBot.define do\n      factory :user do\n        sequence(:email) { \"email_#{_1}@example.com\" }\n        name { \"John Doe\" }\n      end\n    end\n  end\n\n  it \"supports being destructured\" do\n    # rubocop:disable Lint/Syntax\n    attributes_for(:user) => {name:, **attributes}\n    # rubocop:enable Lint/Syntax\n\n    expect(name).to eq(\"John Doe\")\n    expect(attributes.keys).to eq([:email])\n    expect(attributes.fetch(:email)).to match(/email_\\d+@example.com/)\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/attributes_for_spec.rb",
    "content": "if RUBY_ENGINE != \"truffleruby\"\n  require_relative \"attributes_for_destructuring\"\nend\n\ndescribe \"a generated attributes hash\" do\n  include FactoryBot::Syntax::Methods\n\n  before do\n    define_model(\"User\")\n    define_model(\"Comment\")\n\n    define_model(\"Post\", title: :string,\n      body: :string,\n      summary: :string,\n      user_id: :integer) do\n      belongs_to :user\n      has_many :comments\n    end\n\n    FactoryBot.define do\n      factory :user\n      factory :comment\n\n      factory :post do\n        title { \"default title\" }\n        body { \"default body\" }\n        summary { title }\n        user\n        comments do |c|\n          [c.association(:comment)]\n        end\n      end\n    end\n  end\n\n  subject { attributes_for(:post, title: \"overridden title\") }\n\n  it \"assigns an overridden value\" do\n    expect(subject[:title]).to eq \"overridden title\"\n  end\n\n  it \"assigns a default value\" do\n    expect(subject[:body]).to eq \"default body\"\n  end\n\n  it \"assigns a lazy, dependent attribute\" do\n    expect(subject[:summary]).to eq \"overridden title\"\n  end\n\n  it \"doesn't assign associations\" do\n    expect(subject).not_to have_key(:user_id)\n    expect(subject).not_to have_key(:user)\n  end\nend\n\ndescribe \"calling `attributes_for` with a block\" do\n  include FactoryBot::Syntax::Methods\n\n  before do\n    define_model(\"Company\", name: :string)\n\n    FactoryBot.define do\n      factory :company\n    end\n  end\n\n  it \"passes the hash of attributes\" do\n    attributes_for(:company, name: \"thoughtbot\") do |attributes|\n      expect(attributes[:name]).to eq(\"thoughtbot\")\n    end\n  end\n\n  it \"returns the hash of attributes\" do\n    expected = nil\n\n    result = attributes_for(:company) { |attributes|\n      expected = attributes\n      \"hello!\"\n    }\n    expect(result).to eq expected\n  end\nend\n\ndescribe \"`attributes_for` for a class whose constructor has required params\" do\n  before do\n    define_model(\"User\", name: :string) do\n      def initialize(arg1, arg2)\n        # Constructor requesting params to be used for testing\n      end\n    end\n\n    FactoryBot.define do\n      factory :user do\n        name { \"John Doe\" }\n      end\n    end\n  end\n\n  subject { FactoryBot.attributes_for(:user) }\n  its([:name]) { should eq \"John Doe\" }\nend\n"
  },
  {
    "path": "spec/acceptance/attributes_from_instance_spec.rb",
    "content": "describe \"calling methods on the model instance\" do\n  before do\n    define_model(\"User\", age: :integer, age_copy: :integer) do\n      def age\n        read_attribute(:age) || 18\n      end\n    end\n\n    FactoryBot.define do\n      factory :user do\n        age_copy { age }\n      end\n    end\n  end\n\n  context \"without the attribute being overridden\" do\n    it \"returns the correct value from the instance\" do\n      expect(FactoryBot.build(:user).age_copy).to eq 18\n    end\n\n    it \"returns nil during attributes_for\" do\n      expect(FactoryBot.attributes_for(:user)[:age_copy]).to be_nil\n    end\n\n    it \"doesn't instantiate a record with attributes_for\" do\n      allow(User).to receive(:new)\n      FactoryBot.attributes_for(:user)\n      expect(User).to_not have_received(:new)\n    end\n  end\n\n  context \"with the attribute being overridden\" do\n    it \"uses the overridden value\" do\n      expect(FactoryBot.build(:user, age_copy: nil).age_copy).to be_nil\n    end\n\n    it \"uses the overridden value during attributes_for\" do\n      expect(FactoryBot.attributes_for(:user, age_copy: 25)[:age_copy]).to eq 25\n    end\n  end\n\n  context \"with the referenced attribute being overridden\" do\n    it \"uses the overridden value\" do\n      expect(FactoryBot.build(:user, age: nil).age_copy).to be_nil\n    end\n\n    it \"uses the overridden value during attributes_for\" do\n      expect(FactoryBot.attributes_for(:user, age: 25)[:age_copy]).to eq 25\n    end\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/attributes_ordered_spec.rb",
    "content": "describe \"a generated attributes hash where order matters\" do\n  include FactoryBot::Syntax::Methods\n\n  before do\n    define_model(\"ParentModel\", static: :integer,\n      evaluates_first: :integer,\n      evaluates_second: :integer,\n      evaluates_third: :integer)\n\n    FactoryBot.define do\n      factory :parent_model do\n        evaluates_first { static }\n        evaluates_second { evaluates_first }\n        evaluates_third { evaluates_second }\n\n        factory :child_model do\n          static { 1 }\n        end\n      end\n\n      factory :without_parent, class: ParentModel do\n        evaluates_first { static }\n        evaluates_second { evaluates_first }\n        evaluates_third { evaluates_second }\n        static { 1 }\n      end\n    end\n  end\n\n  context \"factory with a parent\" do\n    subject { FactoryBot.build(:child_model) }\n\n    it \"assigns attributes in the order they're defined\" do\n      expect(subject[:evaluates_first]).to eq 1\n      expect(subject[:evaluates_second]).to eq 1\n      expect(subject[:evaluates_third]).to eq 1\n    end\n  end\n\n  context \"factory without a parent\" do\n    subject { FactoryBot.build(:without_parent) }\n\n    it \"assigns attributes in the order they're defined without a parent class\" do\n      expect(subject[:evaluates_first]).to eq 1\n      expect(subject[:evaluates_second]).to eq 1\n      expect(subject[:evaluates_third]).to eq 1\n    end\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/build_list_spec.rb",
    "content": "describe \"build multiple instances\" do\n  before do\n    define_model(\"Post\", title: :string, position: :integer)\n\n    FactoryBot.define do\n      factory(:post) do |post|\n        post.title { \"Through the Looking Glass\" }\n        post.position { rand(10**4) }\n      end\n    end\n  end\n\n  context \"without default attributes\" do\n    subject { FactoryBot.build_list(:post, 20) }\n\n    its(:length) { should eq 20 }\n\n    it \"builds (but doesn't save) all the posts\" do\n      subject.each do |record|\n        expect(record).to be_new_record\n      end\n    end\n\n    it \"uses the default factory values\" do\n      subject.each do |record|\n        expect(record.title).to eq \"Through the Looking Glass\"\n      end\n    end\n  end\n\n  context \"with default attributes\" do\n    subject { FactoryBot.build_list(:post, 20, title: \"The Hunting of the Snark\") }\n\n    it \"overrides the default values\" do\n      subject.each do |record|\n        expect(record.title).to eq \"The Hunting of the Snark\"\n      end\n    end\n  end\n\n  context \"with a block\" do\n    subject do\n      FactoryBot.build_list(:post, 20, title: \"The Listing of the Block\") do |post|\n        post.position = post.id\n      end\n    end\n\n    it \"correctly uses the set value\" do\n      subject.each do |record|\n        expect(record.position).to eq record.id\n      end\n    end\n  end\n\n  context \"with a block that receives both the object and an index\" do\n    subject do\n      FactoryBot.build_list(:post, 20, title: \"The Indexed Block\") do |post, index|\n        post.position = index\n      end\n    end\n\n    it \"correctly uses the set value\" do\n      subject.each_with_index do |record, index|\n        expect(record.position).to eq index\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/build_spec.rb",
    "content": "describe \"a built instance\" do\n  include FactoryBot::Syntax::Methods\n\n  before do\n    define_model(\"User\")\n\n    define_model(\"Post\", user_id: :integer) do\n      belongs_to :user\n    end\n\n    FactoryBot.define do\n      factory :user\n\n      factory :post do\n        user\n      end\n    end\n  end\n\n  subject { build(:post) }\n\n  it { should be_new_record }\n\n  context \"when the :use_parent_strategy config option is set to false\" do\n    it \"assigns and saves associations\" do\n      with_temporary_assignment(FactoryBot, :use_parent_strategy, false) do\n        expect(subject.user).to be_kind_of(User)\n        expect(subject.user).not_to be_new_record\n      end\n    end\n  end\n\n  context \"when the :use_parent_strategy config option is set to true\" do\n    it \"assigns but does not save associations\" do\n      with_temporary_assignment(FactoryBot, :use_parent_strategy, true) do\n        expect(subject.user).to be_kind_of(User)\n        expect(subject.user).to be_new_record\n      end\n    end\n  end\nend\n\ndescribe \"a built instance with strategy: :create\" do\n  include FactoryBot::Syntax::Methods\n\n  before do\n    define_model(\"User\")\n\n    define_model(\"Post\", user_id: :integer) do\n      belongs_to :user\n    end\n\n    FactoryBot.define do\n      factory :user\n\n      factory :post do\n        association(:user, strategy: :create)\n      end\n    end\n  end\n\n  subject { build(:post) }\n\n  it { should be_new_record }\n\n  it \"assigns and saves associations\" do\n    expect(subject.user).to be_kind_of(User)\n    expect(subject.user).not_to be_new_record\n  end\nend\n\ndescribe \"calling `build` with a block\" do\n  include FactoryBot::Syntax::Methods\n\n  before do\n    define_model(\"Company\", name: :string)\n\n    FactoryBot.define do\n      factory :company\n    end\n  end\n\n  it \"passes the built instance\" do\n    build(:company, name: \"thoughtbot\") do |company|\n      expect(company.name).to eq(\"thoughtbot\")\n    end\n  end\n\n  it \"returns the built instance\" do\n    expected = nil\n    result = build(:company) { |company|\n      expected = company\n      \"hello!\"\n    }\n    expect(result).to eq expected\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/build_stubbed_spec.rb",
    "content": "describe \"a generated stub instance\" do\n  include FactoryBot::Syntax::Methods\n\n  before do\n    define_model(\"User\")\n\n    define_model(\"Post\", title: :string,\n      body: :string,\n      age: :integer,\n      user_id: :integer,\n      draft: :boolean) do\n      belongs_to :user\n    end\n\n    FactoryBot.define do\n      factory :user\n\n      factory :post do\n        title { \"default title\" }\n        body { \"default body\" }\n        user\n      end\n    end\n  end\n\n  subject { build_stubbed(:post, title: \"overridden title\") }\n\n  it \"assigns a default attribute\" do\n    expect(subject.body).to eq \"default body\"\n  end\n\n  it \"assigns an overridden attribute\" do\n    expect(subject.title).to eq \"overridden title\"\n  end\n\n  it \"assigns associations\" do\n    expect(subject.user).to be_kind_of(User)\n  end\n\n  it \"has an id\" do\n    expect(subject.id).to be > 0\n  end\n\n  it \"generates unique ids\" do\n    other_stub = build_stubbed(:post)\n    expect(subject.id).not_to eq other_stub.id\n  end\n\n  it \"isn't a new record\" do\n    expect(subject).not_to be_new_record\n  end\n\n  it \"assigns associations that aren't new records\" do\n    expect(subject.user).not_to be_new_record\n  end\n\n  it \"isn't changed\" do\n    expect(subject).not_to be_changed\n  end\n\n  it \"disables connection\" do\n    expect { subject.connection }.to raise_error(RuntimeError)\n  end\n\n  it \"disables update_attribute\" do\n    expect { subject.update_attribute(:title, \"value\") }.to raise_error(RuntimeError)\n  end\n\n  it \"disables reload\" do\n    expect { subject.reload }.to raise_error(RuntimeError)\n  end\n\n  it \"disables destroy\" do\n    expect { subject.destroy }.to raise_error(RuntimeError)\n  end\n\n  it \"disables save\" do\n    expect { subject.save }.to raise_error(RuntimeError)\n  end\n\n  it \"disables increment!\" do\n    expect { subject.increment!(:age) }.to raise_error(RuntimeError)\n  end\n\n  it \"disables decrement!\" do\n    expect { subject.decrement!(:age) }.to raise_error(RuntimeError)\n  end\n\n  it \"disables toggle!\" do\n    expect { subject.toggle!(:draft) }.to raise_error(RuntimeError)\n  end\n\n  it \"allows increment\" do\n    subject.age = 1\n    subject.increment(:age)\n    expect(subject.age).to eq(2)\n  end\n\n  it \"allows decrement\" do\n    subject.age = 1\n    subject.decrement(:age)\n    expect(subject.age).to eq(0)\n  end\n\n  it \"allows toggle\" do\n    subject.draft = true\n    subject.toggle(:draft)\n    expect(subject).not_to be_draft\n  end\nend\n\ndescribe \"calling `build_stubbed` with a block\" do\n  include FactoryBot::Syntax::Methods\n\n  before do\n    define_model(\"Company\", name: :string)\n\n    FactoryBot.define do\n      factory :company\n    end\n  end\n\n  it \"passes the stub instance\" do\n    build_stubbed(:company, name: \"thoughtbot\") do |company|\n      expect(company.name).to eq(\"thoughtbot\")\n      expect { company.save }.to raise_error(RuntimeError)\n    end\n  end\n\n  it \"returns the stub instance\" do\n    expected = nil\n    result = build_stubbed(:company) { |company|\n      expected = company\n      \"hello!\"\n    }\n    expect(result).to eq expected\n  end\nend\n\ndescribe \"defaulting `created_at`\" do\n  include FactoryBot::Syntax::Methods\n\n  before do\n    define_model(\"ThingWithTimestamp\", created_at: :datetime)\n    define_model(\"ThingWithoutTimestamp\")\n\n    FactoryBot.define do\n      factory :thing_with_timestamp\n      factory :thing_without_timestamp\n    end\n  end\n\n  it \"defaults created_at for objects with created_at\" do\n    expect(build_stubbed(:thing_with_timestamp).created_at).to be_about_now\n  end\n\n  it \"is doesn't mark the object as changed\" do\n    stub = build_stubbed(:thing_with_timestamp)\n    expect(stub).not_to be_changed\n  end\n\n  it \"doesn't add created_at to objects who don't have the method\" do\n    expect(build_stubbed(:thing_without_timestamp))\n      .not_to respond_to(:created_at)\n  end\n\n  it \"allows overriding created_at for objects with created_at\" do\n    created_at = 3.days.ago\n    stubbed = build_stubbed(:thing_with_timestamp, created_at: created_at)\n    expect(stubbed.created_at).to be_within(1.second).of created_at\n  end\n\n  it \"doesn't allow setting created_at on an object that doesn't define it\" do\n    expect { build_stubbed(:thing_without_timestamp, created_at: Time.now) }\n      .to raise_error(NoMethodError, /created_at=/)\n  end\n\n  it \"allows assignment of created_at\" do\n    stub = build_stubbed(:thing_with_timestamp)\n    expect(stub.created_at).to be_about_now\n    past_time = 3.days.ago\n    stub.created_at = past_time\n    expect(stub.created_at).to be_within(1.second).of past_time\n  end\n\n  it \"behaves the same as a non-stubbed created_at\" do\n    define_model(\"ThingWithCreatedAt\", created_at: :datetime) do\n      def created_at\n        :the_real_created_at\n      end\n    end\n\n    FactoryBot.define do\n      factory :thing_with_created_at\n    end\n\n    stub = build_stubbed(:thing_with_created_at)\n    persisted = create(:thing_with_created_at)\n\n    expect(stub.created_at).to eq(persisted.created_at)\n  end\nend\n\ndescribe \"defaulting `updated_at`\" do\n  include FactoryBot::Syntax::Methods\n\n  before do\n    define_model(\"ThingWithTimestamp\", updated_at: :datetime)\n    define_model(\"ThingWithoutTimestamp\")\n\n    FactoryBot.define do\n      factory :thing_with_timestamp\n      factory :thing_without_timestamp\n    end\n  end\n\n  it \"defaults updated_at for objects with updated_at\" do\n    expect(build_stubbed(:thing_with_timestamp).updated_at).to be_about_now\n  end\n\n  it \"is doesn't mark the object as changed\" do\n    stub = build_stubbed(:thing_with_timestamp)\n    expect(stub).not_to be_changed\n  end\n\n  it \"doesn't add updated_at to objects who don't have the method\" do\n    expect(build_stubbed(:thing_without_timestamp))\n      .not_to respond_to(:updated_at)\n  end\n\n  it \"allows overriding updated_at for objects with updated_at\" do\n    past_time = 3.days.ago\n    stubbed = build_stubbed(:thing_with_timestamp, updated_at: past_time)\n    expect(stubbed.updated_at).to be_within(1.second).of past_time\n  end\n\n  it \"doesn't allow setting updated_at on an object that doesn't define it\" do\n    expect {\n      build_stubbed(:thing_without_timestamp, updated_at: Time.now)\n    }.to raise_error(NoMethodError, /updated_at=/)\n  end\n\n  it \"allows assignment of updated_at\" do\n    stub = build_stubbed(:thing_with_timestamp)\n    expect(stub.updated_at).to be_about_now\n    past_time = 3.days.ago\n    stub.updated_at = past_time\n    expect(stub.updated_at).to be_within(1.second).of past_time\n  end\n\n  it \"behaves the same as a non-stubbed updated_at\" do\n    define_model(\"ThingWithUpdatedAt\", updated_at: :datetime) do\n      def updated_at\n        :the_real_updated_at\n      end\n    end\n\n    FactoryBot.define do\n      factory :thing_with_updated_at\n    end\n\n    stub = build_stubbed(:thing_with_updated_at)\n    persisted = create(:thing_with_updated_at)\n\n    expect(stub.updated_at).to eq(persisted.updated_at)\n  end\nend\n\ndescribe \"defaulting `id`\" do\n  before do\n    define_model(\"Post\")\n\n    FactoryBot.define do\n      factory :post\n    end\n  end\n\n  it \"allows overriding id\" do\n    expect(FactoryBot.build_stubbed(:post, id: 12).id).to eq 12\n  end\nend\n\ndescribe \"configuring the starting id\" do\n  it \"defines which id build_stubbed instances start with\" do\n    define_model(\"Post\")\n\n    FactoryBot.define do\n      factory :post\n    end\n\n    FactoryBot.build_stubbed_starting_id = 1000\n\n    expect(FactoryBot.build_stubbed(:post).id).to eq 1000\n\n    FactoryBot.build_stubbed_starting_id = 3000\n\n    expect(FactoryBot.build_stubbed(:post).id).to eq 3000\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/callbacks_spec.rb",
    "content": "describe \"callbacks\" do\n  before do\n    define_model(\"User\", first_name: :string, last_name: :string)\n  end\n\n  context \"with strategy callbacks\" do\n    before do\n      FactoryBot.define do\n        factory :user_with_callbacks, class: :user do\n          after(:stub) { |user| user.first_name = \"Stubby\" }\n          after(:build) { |user| user.first_name = \"Buildy\" }\n          after(:create) { |user| user.last_name = \"Createy\" }\n        end\n\n        factory :user_with_inherited_callbacks, parent: :user_with_callbacks do\n          after(:stub) { |user| user.last_name = \"Double-Stubby\" }\n          after(:build) { |user| user.first_name = \"Child-Buildy\" }\n        end\n\n        factory :user_with_multi_called_callbacks, class: :user do\n          first_name { \"Jane\" }\n          trait(:alias_2) { alias_1 }\n          trait(:alias_1) { surname }\n          trait :surname do\n            after(:build) { |user| user.first_name += \" Doe\" }\n          end\n        end\n      end\n    end\n\n    it \"runs the after(:stub) callback when stubbing\" do\n      user = FactoryBot.build_stubbed(:user_with_callbacks)\n      expect(user.first_name).to eq \"Stubby\"\n    end\n\n    it \"runs the after(:build) callback when building\" do\n      user = FactoryBot.build(:user_with_callbacks)\n      expect(user.first_name).to eq \"Buildy\"\n    end\n\n    it \"runs both the after(:build) and after(:create) callbacks when creating\" do\n      user = FactoryBot.create(:user_with_callbacks)\n      expect(user.first_name).to eq \"Buildy\"\n      expect(user.last_name).to eq \"Createy\"\n    end\n\n    it \"runs both the after(:stub) callback on the factory and the inherited after(:stub) callback\" do\n      user = FactoryBot.build_stubbed(:user_with_inherited_callbacks)\n      expect(user.first_name).to eq \"Stubby\"\n      expect(user.last_name).to eq \"Double-Stubby\"\n    end\n\n    it \"runs child callback after parent callback\" do\n      user = FactoryBot.build(:user_with_inherited_callbacks)\n      expect(user.first_name).to eq \"Child-Buildy\"\n    end\n\n    it \"only runs each callback once per instance\" do\n      user_1 = FactoryBot.build(:user_with_multi_called_callbacks, :surname, :alias_1, :alias_2)\n      user_2 = FactoryBot.build(:user_with_multi_called_callbacks, :alias_1, :alias_2, :surname)\n      user_3 = FactoryBot.build(:user_with_multi_called_callbacks, :alias_2, :surname, :alias_1)\n      expect(user_1.first_name).to eq \"Jane Doe\"\n      expect(user_2.first_name).to eq \"Jane Doe\"\n      expect(user_3.first_name).to eq \"Jane Doe\"\n    end\n  end # with strategy callbacks\n\n  context \"with before(:all) and after(:all) included\" do\n    context \"are executed in the correct order\" do\n      before do\n        FactoryBot.define do\n          before(:all) { TestLog << \"global before-all called\" }\n          after(:all) { TestLog << \"global after-all called\" }\n          before(:build) { TestLog << \"global before-build called\" }\n          after(:build) { TestLog << \"global after-build called\" }\n          before(:create) { TestLog << \"global before-create called\" }\n          after(:create) { TestLog << \"global after-create called\" }\n\n          factory :parent, class: :user do\n            before(:all) { TestLog << \"parent before-all called\" }\n            after(:all) { TestLog << \"parent after-all called\" }\n            before(:build) { TestLog << \"parent before-build called\" }\n            after(:build) { TestLog << \"parent after-build called\" }\n            before(:create) { TestLog << \"parent before-create called\" }\n            after(:create) { TestLog << \"parent after-create called\" }\n\n            trait :parent_trait_1 do\n              before(:all) { TestLog << \"parent-trait-1 before-all called\" }\n              after(:all) { TestLog << \"parent-trait-1 after-all called\" }\n              before(:build) { TestLog << \"parent-trait-1 before-build called\" }\n              after(:build) { TestLog << \"parent-trait-1 after-build called\" }\n              before(:create) { TestLog << \"parent-trait-1 before-create called\" }\n              after(:create) { TestLog << \"parent-trait-1 after-create called\" }\n            end\n\n            trait :parent_trait_2 do\n              before(:all) { TestLog << \"parent-trait-2 before-all called\" }\n              after(:all) { TestLog << \"parent-trait-2 after-all called\" }\n              before(:build) { TestLog << \"parent-trait-2 before-build called\" }\n              after(:build) { TestLog << \"parent-trait-2 after-build called\" }\n              before(:create) { TestLog << \"parent-trait-2 before-create called\" }\n              after(:create) { TestLog << \"parent-trait-2 after-create called\" }\n            end\n          end\n\n          factory :child, parent: :parent do\n            before(:all) { TestLog << \"child before-all called\" }\n            after(:create) { TestLog << \"child after-create called\" }\n            after(:build) { TestLog << \"child after-build called\" }\n            before(:build) { TestLog << \"child before-build called\" }\n            before(:create) { TestLog << \"child before-create called\" }\n            after(:all) { TestLog << \"child after-all called\" }\n\n            trait :child_trait do\n              before(:all) { TestLog << \"child-trait before-all called\" }\n              after(:all) { TestLog << \"child-trait after-all called\" }\n              before(:build) { TestLog << \"child-trait before-build called\" }\n              after(:build) { TestLog << \"child-trait after-build called\" }\n              before(:create) { TestLog << \"child-trait before-create called\" }\n              after(:create) { TestLog << \"child-trait after-create called\" }\n            end\n          end\n        end\n      end\n\n      before(:each) { TestLog.reset! }\n\n      it \"with trait callbacks executed in the order requested\" do\n        # Note: trait callbacks are executed AFTER any factory callbacks and\n        #       in the order they are requested.\n        #\n        FactoryBot.create(:child, :parent_trait_2, :child_trait, :parent_trait_1)\n\n        expect(TestLog.size).to eq 36\n\n        # before(:all)\n        expect(TestLog[0..5]).to eq [\n          \"global before-all called\",\n          \"parent before-all called\",\n          \"child before-all called\",\n          \"parent-trait-2 before-all called\",\n          \"child-trait before-all called\",\n          \"parent-trait-1 before-all called\"\n        ]\n\n        # before(:build)\n        expect(TestLog[6..11]).to eq [\n          \"global before-build called\",\n          \"parent before-build called\",\n          \"child before-build called\",\n          \"parent-trait-2 before-build called\",\n          \"child-trait before-build called\",\n          \"parent-trait-1 before-build called\"\n        ]\n\n        # after(:build)\n        expect(TestLog[12..17]).to eq [\n          \"global after-build called\",\n          \"parent after-build called\",\n          \"child after-build called\",\n          \"parent-trait-2 after-build called\",\n          \"child-trait after-build called\",\n          \"parent-trait-1 after-build called\"\n        ]\n\n        # before(:create)\n        expect(TestLog[18..23]).to eq [\n          \"global before-create called\",\n          \"parent before-create called\",\n          \"child before-create called\",\n          \"parent-trait-2 before-create called\",\n          \"child-trait before-create called\",\n          \"parent-trait-1 before-create called\"\n        ]\n\n        # after(:create)\n        expect(TestLog[24..29]).to eq [\n          \"global after-create called\",\n          \"parent after-create called\",\n          \"child after-create called\",\n          \"parent-trait-2 after-create called\",\n          \"child-trait after-create called\",\n          \"parent-trait-1 after-create called\"\n        ]\n\n        # after(:all)\n        expect(TestLog[30..35]).to eq [\n          \"global after-all called\",\n          \"parent after-all called\",\n          \"child after-all called\",\n          \"parent-trait-2 after-all called\",\n          \"child-trait after-all called\",\n          \"parent-trait-1 after-all called\"\n        ]\n      end\n    end # ordered correctly\n\n    context \"with context provided to before(:all)\" do\n      before(:each) { TestLog.reset! }\n\n      it \"receives 'nil' as the instance\" do\n        FactoryBot.define do\n          before(:all) { |user| TestLog << \"Global instance: #{user}\" }\n\n          factory :user do\n            before(:all) { |user| TestLog << \"Factory instance: #{user}\" }\n          end\n        end\n\n        FactoryBot.build(:user)\n        expect(TestLog.first).to eq \"Global instance: \"\n        expect(TestLog.last).to eq \"Factory instance: \"\n      end\n\n      it \"receives the context, without an instance\" do\n        FactoryBot.define do\n          before(:all) do |user, context|\n            TestLog << \"Global strategy: #{context.instance_values[\"build_strategy\"].to_sym}\"\n            TestLog << \"Global instance: #{context.instance}\"\n          end\n\n          factory :user do\n            before(:all) do |user, context|\n              TestLog << \"Factory strategy: #{context.instance_values[\"build_strategy\"].to_sym}\"\n              TestLog << \"Factory instance: #{context.instance}\"\n            end\n          end\n        end\n\n        FactoryBot.build(:user)\n        expect(TestLog.all).to eq [\n          \"Global strategy: build\",\n          \"Global instance: \",\n          \"Factory strategy: build\",\n          \"Factory instance: \"\n        ]\n      end\n    end # context: with context provided to before(:all)\n\n    context \"with context provided to after(:all)\" do\n      it \"succeeds with the instance provided\" do\n        FactoryBot.define do\n          after(:all) { |user| user.first_name = \"Globy\" }\n\n          factory :user do\n            after(:all) { |user| user.last_name = \"Lasty\" }\n          end\n        end\n\n        user = FactoryBot.build(:user)\n        expect(user.first_name).to eq \"Globy\"\n        expect(user.last_name).to eq \"Lasty\"\n      end\n\n      it \"succeeds with both the instance and context provided\" do\n        FactoryBot.define do\n          after(:all) { |user, context| user.first_name = context.new_first_name }\n\n          factory :user do\n            transient do\n              new_first_name { \"New First Name\" }\n              new_last_name { \"New Last Name\" }\n            end\n\n            after(:all) { |user, context| user.last_name = context.new_last_name }\n          end\n        end\n\n        user = FactoryBot.build(:user)\n        expect(user.first_name).to eq \"New First Name\"\n        expect(user.last_name).to eq \"New Last Name\"\n      end\n    end # context: with context provided to after(:all)\n  end # context: with before(:all) and after(:all) callbacks included\nend # describe: callbacks\n\ndescribe \"callbacks using Symbol#to_proc\" do\n  before do\n    define_model(\"User\") do\n      def confirmed?\n        !!@confirmed\n      end\n\n      def confirm!\n        @confirmed = true\n      end\n    end\n\n    FactoryBot.define do\n      factory :user do\n        after :build, &:confirm!\n      end\n    end\n  end\n\n  it \"runs the callback correctly\" do\n    user = FactoryBot.build(:user)\n    expect(user).to be_confirmed\n  end\nend\n\ndescribe \"callbacks using syntax methods without referencing FactoryBot explicitly\" do\n  before do\n    define_model(\"User\", first_number: :integer, last_number: :integer)\n\n    FactoryBot.define do\n      sequence(:sequence_1)\n      sequence(:sequence_2)\n      sequence(:sequence_3)\n\n      factory :user do\n        after(:stub) { generate(:sequence_3) }\n        after(:build) { |user| user.first_number = generate(:sequence_1) }\n        after(:create) { |user, _evaluator| user.last_number = generate(:sequence_2) }\n      end\n    end\n  end\n\n  it \"works when the callback has no variables\" do\n    FactoryBot.build_stubbed(:user)\n    expect(FactoryBot.generate(:sequence_3)).to eq 2\n  end\n\n  it \"works when the callback has one variable\" do\n    expect(FactoryBot.build(:user).first_number).to eq 1\n  end\n\n  it \"works when the callback has two variables\" do\n    expect(FactoryBot.create(:user).last_number).to eq 1\n  end\nend\n\ndescribe \"custom callbacks\" do\n  let(:custom_before) do\n    Class.new do\n      def result(evaluation)\n        evaluation.object.tap do |instance|\n          evaluation.notify(:before_custom, instance)\n        end\n      end\n    end\n  end\n\n  let(:custom_after) do\n    Class.new do\n      def result(evaluation)\n        evaluation.object.tap do |instance|\n          evaluation.notify(:after_custom, instance)\n        end\n      end\n    end\n  end\n\n  let(:totally_custom) do\n    Class.new do\n      def result(evaluation)\n        evaluation.object.tap do |instance|\n          evaluation.notify(:totally_custom, instance)\n        end\n      end\n    end\n  end\n\n  before do\n    define_model(\"User\", first_name: :string, last_name: :string) do\n      def name\n        [first_name, last_name].join(\" \")\n      end\n    end\n\n    FactoryBot.register_strategy(:custom_before, custom_before)\n    FactoryBot.register_strategy(:custom_after, custom_after)\n    FactoryBot.register_strategy(:totally_custom, totally_custom)\n\n    FactoryBot.define do\n      factory :user do\n        first_name { \"John\" }\n        last_name { \"Doe\" }\n\n        before(:custom) { |instance| instance.first_name = \"Overridden First\" }\n        after(:custom) { |instance| instance.last_name = \"Overridden Last\" }\n        callback(:totally_custom) do |instance|\n          instance.first_name = \"Totally\"\n          instance.last_name = \"Custom\"\n        end\n      end\n    end\n  end\n\n  it \"runs a custom before callback when the proper strategy executes\" do\n    expect(FactoryBot.build(:user).name).to eq \"John Doe\"\n    expect(FactoryBot.custom_before(:user).name).to eq \"Overridden First Doe\"\n  end\n\n  it \"runs a custom after callback when the proper strategy executes\" do\n    expect(FactoryBot.build(:user).name).to eq \"John Doe\"\n    expect(FactoryBot.custom_after(:user).name).to eq \"John Overridden Last\"\n  end\n\n  it \"runs a custom callback without prepending before or after when the proper strategy executes\" do\n    expect(FactoryBot.build(:user).name).to eq \"John Doe\"\n    expect(FactoryBot.totally_custom(:user).name).to eq \"Totally Custom\"\n  end\nend\n\ndescribe \"binding a callback to multiple callbacks\" do\n  before do\n    define_model(\"User\", name: :string)\n\n    FactoryBot.define do\n      factory :user do\n        callback(:before_create, :after_stub) do |instance|\n          instance.name = instance.name.upcase\n        end\n      end\n    end\n  end\n\n  it \"binds the callback to creation\" do\n    expect(FactoryBot.create(:user, name: \"John Doe\").name).to eq \"JOHN DOE\"\n  end\n\n  it \"does not bind the callback to building\" do\n    expect(FactoryBot.build(:user, name: \"John Doe\").name).to eq \"John Doe\"\n  end\n\n  it \"binds the callback to stubbing\" do\n    expect(FactoryBot.build_stubbed(:user, name: \"John Doe\").name).to eq \"JOHN DOE\"\n  end\nend\n\ndescribe \"global callbacks\" do\n  include FactoryBot::Syntax::Methods\n\n  before do\n    define_model(\"User\", name: :string)\n    define_model(\"Company\", name: :string)\n\n    FactoryBot.define do\n      after :build do |object|\n        object.name = case object.class.to_s\n        when \"User\" then \"John Doe\"\n        when \"Company\" then \"Acme Suppliers\"\n        end\n      end\n\n      after :create do |object|\n        object.name = \"#{object.name}!!!\"\n      end\n\n      trait :awesome do\n        after :build do |object|\n          object.name = \"___#{object.name}___\"\n        end\n\n        after :create do |object|\n          object.name = \"A#{object.name}Z\"\n        end\n      end\n\n      factory :user do\n        after :build do |user|\n          user.name = user.name.downcase\n        end\n      end\n\n      factory :company do\n        after :build do |company|\n          company.name = company.name.upcase\n        end\n      end\n    end\n  end\n\n  it \"triggers after build callbacks for all factories\" do\n    expect(build(:user).name).to eq \"john doe\"\n    expect(create(:user).name).to eq \"john doe!!!\"\n    expect(create(:user, :awesome).name).to eq \"A___john doe___!!!Z\"\n    expect(build(:company).name).to eq \"ACME SUPPLIERS\"\n  end\nend\n\ndescribe \"before build callback\" do\n  before do\n    define_class(\"TitleSetter\") do\n      def self.title=(new_title)\n        class_variable_set(:@@title, new_title)\n      end\n\n      def self.title\n        class_variable_get(:@@title)\n      end\n    end\n\n    define_model(\"Article\", title: :string)\n\n    FactoryBot.define do\n      factory :article_with_before_callbacks, class: :article do\n        before(:build) { TitleSetter.title = \"title from before build\" }\n        after(:build) { TitleSetter.title = \"title from after build\" }\n\n        title { TitleSetter.title }\n      end\n    end\n  end\n\n  it \"runs the before callback\" do\n    article = FactoryBot.build(:article_with_before_callbacks)\n    expect(article.title).to eq(\"title from before build\")\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/create_list_spec.rb",
    "content": "describe \"create multiple instances\" do\n  before do\n    define_model(\"Post\", title: :string, position: :integer)\n\n    FactoryBot.define do\n      factory(:post) do |post|\n        post.title { \"Through the Looking Glass\" }\n        post.position { rand(10**4) }\n      end\n    end\n  end\n\n  context \"without default attributes\" do\n    subject { FactoryBot.create_list(:post, 20) }\n\n    its(:length) { should eq 20 }\n\n    it \"creates all the posts\" do\n      subject.each do |record|\n        expect(record).not_to be_new_record\n      end\n    end\n\n    it \"uses the default factory values\" do\n      subject.each do |record|\n        expect(record.title).to eq \"Through the Looking Glass\"\n      end\n    end\n  end\n\n  context \"with default attributes\" do\n    subject { FactoryBot.create_list(:post, 20, title: \"The Hunting of the Snark\") }\n\n    it \"overrides the default values\" do\n      subject.each do |record|\n        expect(record.title).to eq \"The Hunting of the Snark\"\n      end\n    end\n  end\n\n  context \"with a block\" do\n    subject do\n      FactoryBot.create_list(:post, 20, title: \"The Listing of the Block\") do |post|\n        post.position = post.id\n      end\n    end\n\n    it \"uses the new values\" do\n      subject.each do |record|\n        expect(record.position).to eq record.id\n      end\n    end\n  end\n\n  context \"with a block that receives both the object and an index\" do\n    subject do\n      FactoryBot.create_list(:post, 20, title: \"The Indexed Block\") do |post, index|\n        post.position = index\n      end\n    end\n\n    it \"uses the new values\" do\n      subject.each_with_index do |record, index|\n        expect(record.position).to eq index\n      end\n    end\n  end\n\n  context \"without the count\" do\n    subject { FactoryBot.create_list(:post, title: \"The Hunting of the Bear\") }\n\n    it \"raise ArgumentError with the proper error message\" do\n      expect { subject }.to raise_error(ArgumentError, /count missing/)\n    end\n  end\nend\n\ndescribe \"multiple creates and transient attributes to dynamically build attribute lists\" do\n  before do\n    define_model(\"User\", name: :string) do\n      has_many :posts\n    end\n\n    define_model(\"Post\", title: :string, user_id: :integer) do\n      belongs_to :user\n    end\n\n    FactoryBot.define do\n      factory :post do\n        title { \"Through the Looking Glass\" }\n        user\n      end\n\n      factory :user do\n        name { \"John Doe\" }\n\n        factory :user_with_posts do\n          transient do\n            posts_count { 5 }\n          end\n\n          after(:create) do |user, evaluator|\n            FactoryBot.create_list(:post, evaluator.posts_count, user: user)\n          end\n        end\n      end\n    end\n  end\n\n  it \"generates the correct number of posts\" do\n    expect(FactoryBot.create(:user_with_posts).posts.length).to eq 5\n  end\n\n  it \"allows the number of posts to be modified\" do\n    expect(FactoryBot.create(:user_with_posts, posts_count: 2).posts.length).to eq 2\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/create_pair_spec.rb",
    "content": "describe \"create multiple instances\" do\n  before do\n    define_model(\"Post\", title: :string, position: :integer)\n\n    FactoryBot.define do\n      factory(:post) do |post|\n        post.title { \"Through the Looking Glass\" }\n        post.position { rand(10**4) }\n      end\n    end\n  end\n\n  context \"without default attributes\" do\n    subject { FactoryBot.create_pair(:post) }\n\n    its(:length) { should eq 2 }\n\n    it \"creates all the posts\" do\n      subject.each do |record|\n        expect(record).not_to be_new_record\n      end\n    end\n\n    it \"uses the default factory values\" do\n      subject.each do |record|\n        expect(record.title).to eq \"Through the Looking Glass\"\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/create_spec.rb",
    "content": "describe \"a created instance\" do\n  include FactoryBot::Syntax::Methods\n\n  before do\n    define_model(\"User\")\n\n    define_model(\"Post\", user_id: :integer) do\n      belongs_to :user\n    end\n\n    FactoryBot.define do\n      factory :user\n\n      factory :post do\n        user\n      end\n    end\n  end\n\n  subject { create(\"post\") }\n\n  it { should_not be_new_record }\n\n  it \"assigns and saves associations\" do\n    expect(subject.user).to be_kind_of(User)\n    expect(subject.user).not_to be_new_record\n  end\nend\n\ndescribe \"a created instance, specifying strategy: :build\" do\n  include FactoryBot::Syntax::Methods\n\n  before do\n    define_model(\"User\")\n\n    define_model(\"Post\", user_id: :integer) do\n      belongs_to :user\n    end\n\n    FactoryBot.define do\n      factory :user\n\n      factory :post do\n        association(:user, strategy: :build)\n      end\n    end\n  end\n\n  subject { create(:post) }\n\n  it \"saves associations (strategy: :build only affects build, not create)\" do\n    expect(subject.user).to be_kind_of(User)\n    expect(subject.user).not_to be_new_record\n  end\nend\n\ndescribe \"a custom create\" do\n  include FactoryBot::Syntax::Methods\n\n  before do\n    define_class(\"User\") do\n      def initialize\n        @persisted = false\n      end\n\n      def persist\n        @persisted = true\n      end\n\n      def persisted?\n        @persisted\n      end\n    end\n\n    FactoryBot.define do\n      factory :user do\n        to_create(&:persist)\n      end\n    end\n  end\n\n  it \"uses the custom create block instead of save\" do\n    expect(FactoryBot.create(:user)).to be_persisted\n  end\nend\n\ndescribe \"a custom create passing in an evaluator\" do\n  before do\n    define_class(\"User\") do\n      attr_accessor :name\n    end\n\n    FactoryBot.define do\n      factory :user do\n        transient { creation_name { \"evaluator\" } }\n\n        to_create do |user, evaluator|\n          user.name = evaluator.creation_name\n        end\n      end\n    end\n  end\n\n  it \"passes the evaluator to the custom create block\" do\n    expect(FactoryBot.create(:user).name).to eq \"evaluator\"\n  end\nend\n\ndescribe \"calling `create` with a block\" do\n  include FactoryBot::Syntax::Methods\n\n  before do\n    define_model(\"Company\", name: :string)\n\n    FactoryBot.define do\n      factory :company\n    end\n  end\n\n  it \"passes the created instance\" do\n    create(:company, name: \"thoughtbot\") do |company|\n      expect(company.name).to eq(\"thoughtbot\")\n    end\n  end\n\n  it \"returns the created instance\" do\n    expected = nil\n    result = create(:company) { |company|\n      expected = company\n      \"hello!\"\n    }\n    expect(result).to eq expected\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/define_child_before_parent_spec.rb",
    "content": "describe \"defining a child factory before a parent\" do\n  before do\n    define_model(\"User\", name: :string, admin: :boolean, email: :string, upper_email: :string, login: :string)\n\n    FactoryBot.define do\n      factory :admin, parent: :user do\n        admin { true }\n      end\n\n      factory :user do\n        name { \"awesome\" }\n      end\n    end\n  end\n\n  it \"creates admin factories correctly\" do\n    expect(FactoryBot.create(:admin)).to be_admin\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/defining_methods_inside_a_factory_spec.rb",
    "content": "describe \"defining methods inside FactoryBot\" do\n  it \"raises with a meaningful message\" do\n    define_model(\"User\")\n\n    bad_factory_definition = -> do\n      FactoryBot.define do\n        factory :user do\n          def generate_name\n            \"John Doe\"\n          end\n        end\n      end\n    end\n\n    expect(&bad_factory_definition).to raise_error(\n      FactoryBot::MethodDefinitionError,\n      /Defining methods in blocks \\(trait or factory\\) is not supported \\(generate_name\\)/\n    )\n  end\n\n  it \"accepts a method named :definition when set through :method_missing\" do\n    define_model(\"User\", definition: :string)\n\n    FactoryBot.define do\n      factory :user do\n        definition do\n          \"Jester\"\n        end\n      end\n    end\n\n    user = FactoryBot.build(:user)\n    expect(user.definition).to eq(\"Jester\")\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/definition_camel_string_spec.rb",
    "content": "describe \"an instance generated by a factory named a camel case string \" do\n  before do\n    define_model(\"UserModel\")\n\n    FactoryBot.define do\n      factory \"UserModel\", class: UserModel\n    end\n  end\n\n  it \"registers the UserModel factory\" do\n    expect(FactoryBot::Internal.factory_by_name(\"UserModel\"))\n      .to be_a(FactoryBot::Factory)\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/definition_spec.rb",
    "content": "describe \"an instance generated by a factory with a custom class name\" do\n  before do\n    define_model(\"User\", admin: :boolean)\n\n    FactoryBot.define do\n      factory :user\n\n      factory :admin, class: User do\n        admin { true }\n      end\n    end\n  end\n\n  subject { FactoryBot.create(:admin) }\n\n  it { should be_kind_of(User) }\n  it { should be_admin }\nend\n\ndescribe \"attributes defined using Symbol#to_proc\" do\n  before do\n    define_model(\"User\", password: :string, password_confirmation: :string)\n\n    FactoryBot.define do\n      factory :user do\n        password { \"foo\" }\n        password_confirmation(&:password)\n      end\n    end\n  end\n\n  it \"assigns values correctly\" do\n    user = FactoryBot.build(:user)\n\n    expect(user.password).to eq \"foo\"\n    expect(user.password_confirmation).to eq \"foo\"\n  end\n\n  it \"assigns value with override correctly\" do\n    user = FactoryBot.build(:user, password: \"bar\")\n\n    expect(user.password).to eq \"bar\"\n    expect(user.password_confirmation).to eq \"bar\"\n  end\n\n  it \"assigns overridden value correctly\" do\n    user = FactoryBot.build(:user, password_confirmation: \"bar\")\n\n    expect(user.password).to eq \"foo\"\n    expect(user.password_confirmation).to eq \"bar\"\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/definition_without_block_spec.rb",
    "content": "describe \"an instance generated by a factory\" do\n  before do\n    define_model(\"User\")\n\n    FactoryBot.define do\n      factory :user\n    end\n  end\n\n  it \"registers the user factory\" do\n    expect(FactoryBot::Internal.factory_by_name(:user))\n      .to be_a(FactoryBot::Factory)\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/enum_traits_spec.rb",
    "content": "describe \"enum traits\" do\n  def define_model_with_enum(class_name, field, values)\n    define_model(class_name, status: :integer) do\n      if ActiveRecord::VERSION::STRING >= \"7.0\"\n        enum field, values\n      else\n        enum field => values\n      end\n    end\n  end\n\n  context \"when automatically_define_enum_traits is true\" do\n    it \"builds traits automatically for model enum field\" do\n      define_model_with_enum(\"Task\", :status, {queued: 0, started: 1, finished: 2})\n\n      FactoryBot.define do\n        factory :task\n      end\n\n      Task.statuses.each_key do |trait_name|\n        task = FactoryBot.build(:task, trait_name)\n\n        expect(task.status).to eq(trait_name)\n      end\n\n      Task.reset_column_information\n    end\n\n    it \"prefers user defined traits over automatically built traits\" do\n      define_model_with_enum(\"Task\", :status, {queued: 0, started: 1, finished: 2})\n\n      FactoryBot.define do\n        factory :task do\n          trait :queued do\n            status { :finished }\n          end\n\n          trait :started do\n            status { :finished }\n          end\n\n          trait :finished do\n            status { :finished }\n          end\n        end\n      end\n\n      Task.statuses.each_key do |trait_name|\n        task = FactoryBot.build(:task, trait_name)\n\n        expect(task.status).to eq(\"finished\")\n      end\n\n      Task.reset_column_information\n    end\n\n    it \"builds traits for each enumerated value using a provided list of values as a Hash\" do\n      statuses = {queued: 0, started: 1, finished: 2}\n\n      define_class \"Task\" do\n        attr_accessor :status\n      end\n\n      FactoryBot.define do\n        factory :task do\n          traits_for_enum :status, statuses\n        end\n      end\n\n      statuses.each do |trait_name, trait_value|\n        task = FactoryBot.build(:task, trait_name)\n\n        expect(task.status).to eq(trait_value)\n      end\n    end\n\n    it \"builds traits for each enumerated value using a provided list of values as an Array\" do\n      statuses = %w[queued started finished]\n\n      define_class \"Task\" do\n        attr_accessor :status\n      end\n\n      FactoryBot.define do\n        factory :task do\n          traits_for_enum :status, statuses\n        end\n      end\n\n      statuses.each do |trait_name|\n        task = FactoryBot.build(:task, trait_name)\n\n        expect(task.status).to eq(trait_name)\n      end\n    end\n\n    it \"builds traits for each enumerated value using a custom enumerable\" do\n      statuses = define_class(\"Statuses\") {\n        include Enumerable\n\n        def each(&block)\n          [\"queued\", \"started\", \"finished\"].each(&block)\n        end\n      }.new\n\n      define_class \"Task\" do\n        attr_accessor :status\n      end\n\n      FactoryBot.define do\n        factory :task do\n          traits_for_enum :status, statuses\n        end\n      end\n\n      statuses.each do |trait_name|\n        task = FactoryBot.build(:task, trait_name)\n\n        expect(task.status).to eq(trait_name)\n      end\n    end\n  end\n\n  context \"when automatically_define_enum_traits is false\" do\n    it \"raises an error for undefined traits\" do\n      with_temporary_assignment(FactoryBot, :automatically_define_enum_traits, false) do\n        define_model_with_enum(\"Task\", :status, {queued: 0, started: 1, finished: 2})\n\n        FactoryBot.define do\n          factory :task\n        end\n\n        Task.statuses.each_key do |trait_name|\n          expect { FactoryBot.build(:task, trait_name) }.to raise_error(\n            KeyError, \"Trait not registered: \\\"#{trait_name}\\\"\"\n          )\n        end\n\n        Task.reset_column_information\n      end\n    end\n\n    it \"builds traits for each enumerated value when traits_for_enum are specified\" do\n      with_temporary_assignment(FactoryBot, :automatically_define_enum_traits, false) do\n        define_model_with_enum(\"Task\", :status, {queued: 0, started: 1, finished: 2})\n\n        FactoryBot.define do\n          factory :task do\n            traits_for_enum(:status)\n          end\n        end\n\n        Task.statuses.each_key do |trait_name|\n          task = FactoryBot.build(:task, trait_name)\n\n          expect(task.status).to eq(trait_name)\n        end\n\n        Task.reset_column_information\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/global_initialize_with_spec.rb",
    "content": "describe \"global initialize_with\" do\n  before do\n    define_class(\"User\") do\n      attr_accessor :name\n\n      def initialize(name)\n        @name = name\n      end\n    end\n\n    define_class(\"Post\") do\n      attr_reader :name\n\n      def initialize(name)\n        @name = name\n      end\n    end\n\n    FactoryBot.define do\n      initialize_with { new(\"initialize_with\") }\n\n      trait :with_initialize_with do\n        initialize_with { new(\"trait initialize_with\") }\n      end\n\n      factory :user do\n        factory :child_user\n\n        factory :child_user_with_trait do\n          with_initialize_with\n        end\n      end\n\n      factory :post do\n        factory :child_post\n\n        factory :child_post_with_trait do\n          with_initialize_with\n        end\n      end\n    end\n  end\n\n  it \"handles base initialize_with\" do\n    expect(FactoryBot.build(:user).name).to eq \"initialize_with\"\n    expect(FactoryBot.build(:post).name).to eq \"initialize_with\"\n  end\n\n  it \"handles child initialize_with\" do\n    expect(FactoryBot.build(:child_user).name).to eq \"initialize_with\"\n    expect(FactoryBot.build(:child_post).name).to eq \"initialize_with\"\n  end\n\n  it \"handles child initialize_with with trait\" do\n    expect(FactoryBot.build(:child_user_with_trait).name).to eq \"trait initialize_with\"\n    expect(FactoryBot.build(:child_post_with_trait).name).to eq \"trait initialize_with\"\n  end\n\n  it \"handles inline trait override\" do\n    expect(FactoryBot.build(:child_user, :with_initialize_with).name).to eq \"trait initialize_with\"\n    expect(FactoryBot.build(:child_post, :with_initialize_with).name).to eq \"trait initialize_with\"\n  end\n\n  it \"uses initialize_with globally across FactoryBot.define\" do\n    define_class(\"Company\") do\n      attr_reader :name\n\n      def initialize(name)\n        @name = name\n      end\n    end\n\n    FactoryBot.define do\n      factory :company\n    end\n\n    expect(FactoryBot.build(:company).name).to eq \"initialize_with\"\n    expect(FactoryBot.build(:company, :with_initialize_with).name).to eq \"trait initialize_with\"\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/global_to_create_spec.rb",
    "content": "describe \"global to_create\" do\n  before do\n    define_model(\"User\", name: :string)\n    define_model(\"Post\", name: :string)\n\n    FactoryBot.define do\n      to_create { |instance| instance.name = \"persisted!\" }\n\n      trait :override_to_create do\n        to_create { |instance| instance.name = \"override\" }\n      end\n\n      factory :user do\n        name { \"John Doe\" }\n\n        factory :child_user\n\n        factory :child_user_with_trait do\n          override_to_create\n        end\n      end\n\n      factory :post do\n        name { \"Great title\" }\n\n        factory :child_post\n\n        factory :child_post_with_trait do\n          override_to_create\n        end\n      end\n    end\n  end\n\n  it \"handles base to_create\" do\n    expect(FactoryBot.create(:user).name).to eq \"persisted!\"\n    expect(FactoryBot.create(:post).name).to eq \"persisted!\"\n  end\n\n  it \"handles child to_create\" do\n    expect(FactoryBot.create(:child_user).name).to eq \"persisted!\"\n    expect(FactoryBot.create(:child_post).name).to eq \"persisted!\"\n  end\n\n  it \"handles child to_create with trait\" do\n    expect(FactoryBot.create(:child_user_with_trait).name).to eq \"override\"\n    expect(FactoryBot.create(:child_post_with_trait).name).to eq \"override\"\n  end\n\n  it \"handles inline trait override\" do\n    user = FactoryBot.create(:child_user, :override_to_create)\n    post = FactoryBot.create(:child_post, :override_to_create)\n\n    expect(user.name).to eq \"override\"\n    expect(post.name).to eq \"override\"\n  end\n\n  it \"uses to_create globally across FactoryBot.define\" do\n    define_model(\"Company\", name: :string)\n\n    FactoryBot.define do\n      factory :company\n    end\n\n    company = FactoryBot.create(:company)\n    override_company = FactoryBot.create(:company, :override_to_create)\n\n    expect(company.name).to eq \"persisted!\"\n    expect(override_company.name).to eq \"override\"\n  end\nend\n\ndescribe \"global skip_create\" do\n  before do\n    define_model(\"User\", name: :string)\n    define_model(\"Post\", name: :string)\n\n    FactoryBot.define do\n      skip_create\n\n      trait :override_to_create do\n        to_create { |instance| instance.name = \"override\" }\n      end\n\n      factory :user do\n        name { \"John Doe\" }\n\n        factory :child_user\n\n        factory :child_user_with_trait do\n          override_to_create\n        end\n      end\n\n      factory :post do\n        name { \"Great title\" }\n\n        factory :child_post\n\n        factory :child_post_with_trait do\n          override_to_create\n        end\n      end\n    end\n  end\n\n  it \"does not persist any record\" do\n    expect(FactoryBot.create(:user)).to be_new_record\n    expect(FactoryBot.create(:post)).to be_new_record\n  end\n\n  it \"does not persist child records\" do\n    expect(FactoryBot.create(:child_user)).to be_new_record\n    expect(FactoryBot.create(:child_post)).to be_new_record\n  end\n\n  it \"honors overridden to_create\" do\n    expect(FactoryBot.create(:child_user_with_trait).name).to eq \"override\"\n    expect(FactoryBot.create(:child_post_with_trait).name).to eq \"override\"\n  end\n\n  it \"honors inline trait to_create\" do\n    expect(FactoryBot.create(:child_user, :override_to_create).name).to eq \"override\"\n    expect(FactoryBot.create(:child_post, :override_to_create).name).to eq \"override\"\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/initialize_with_spec.rb",
    "content": "describe \"initialize_with with non-FG attributes\" do\n  include FactoryBot::Syntax::Methods\n\n  before do\n    define_model(\"User\", name: :string, age: :integer) do\n      def self.construct(name, age)\n        new(name: name, age: age)\n      end\n    end\n\n    FactoryBot.define do\n      factory :user do\n        initialize_with { User.construct(\"John Doe\", 21) }\n      end\n    end\n  end\n\n  subject { build(:user) }\n  its(:name) { should eq \"John Doe\" }\n  its(:age) { should eq 21 }\nend\n\ndescribe \"initialize_with with FG attributes that are transient\" do\n  include FactoryBot::Syntax::Methods\n\n  before do\n    define_model(\"User\", name: :string) do\n      def self.construct(name)\n        new(name: \"#{name} from .construct\")\n      end\n    end\n\n    FactoryBot.define do\n      factory :user do\n        transient do\n          name { \"Handsome Chap\" }\n        end\n\n        initialize_with { User.construct(name) }\n      end\n    end\n  end\n\n  subject { build(:user) }\n  its(:name) { should eq \"Handsome Chap from .construct\" }\nend\n\ndescribe \"initialize_with non-ORM-backed objects\" do\n  include FactoryBot::Syntax::Methods\n\n  before do\n    define_class(\"ReportGenerator\") do\n      attr_reader :name, :data\n\n      def initialize(name, data)\n        @name = name\n        @data = data\n      end\n    end\n\n    FactoryBot.define do\n      sequence(:random_data) { Array.new(5) { Kernel.rand(200) } }\n\n      factory :report_generator do\n        transient do\n          name { \"My Awesome Report\" }\n        end\n\n        initialize_with { ReportGenerator.new(name, FactoryBot.generate(:random_data)) }\n      end\n    end\n  end\n\n  it \"allows for overrides\" do\n    expect(build(:report_generator, name: \"Overridden\").name).to eq \"Overridden\"\n  end\n\n  it \"generates random data\" do\n    expect(build(:report_generator).data.length).to eq 5\n  end\nend\n\ndescribe \"initialize_with parent and child factories\" do\n  before do\n    define_class(\"Awesome\") do\n      attr_reader :name\n\n      def initialize(name)\n        @name = name\n      end\n    end\n\n    FactoryBot.define do\n      factory :awesome do\n        transient do\n          name { \"Great\" }\n        end\n\n        initialize_with { Awesome.new(name) }\n\n        factory :sub_awesome do\n          transient do\n            name { \"Sub\" }\n          end\n        end\n\n        factory :super_awesome do\n          initialize_with { Awesome.new(\"Super\") }\n        end\n      end\n    end\n  end\n\n  it \"uses the parent's constructor when the child factory doesn't assign it\" do\n    expect(FactoryBot.build(:sub_awesome).name).to eq \"Sub\"\n  end\n\n  it \"allows child factories to override initialize_with\" do\n    expect(FactoryBot.build(:super_awesome).name).to eq \"Super\"\n  end\nend\n\ndescribe \"initialize_with implicit constructor\" do\n  before do\n    define_class(\"Awesome\") do\n      attr_reader :name\n\n      def initialize(name)\n        @name = name\n      end\n    end\n\n    FactoryBot.define do\n      factory :awesome do\n        transient do\n          name { \"Great\" }\n        end\n\n        initialize_with { new(name) }\n      end\n    end\n  end\n\n  it \"instantiates the correct object\" do\n    expect(FactoryBot.build(:awesome, name: \"Awesome name\").name).to eq \"Awesome name\"\n  end\nend\n\ndescribe \"initialize_with doesn't duplicate assignment on attributes accessed from initialize_with\" do\n  before do\n    define_class(\"User\") do\n      attr_reader :name\n      attr_accessor :email\n\n      def initialize(name)\n        @name = name\n      end\n    end\n\n    FactoryBot.define do\n      sequence(:email) { |n| \"person#{n}@example.com\" }\n\n      factory :user do\n        email\n\n        name { email.gsub(/@.+/, \"\") }\n\n        initialize_with { new(name) }\n      end\n    end\n  end\n\n  it \"instantiates the correct object\" do\n    built_user = FactoryBot.build(:user)\n    expect(built_user.name).to eq \"person1\"\n    expect(built_user.email).to eq \"person1@example.com\"\n  end\nend\n\ndescribe \"initialize_with has access to all attributes for construction\" do\n  it \"assigns attributes correctly\" do\n    define_class(\"User\") do\n      attr_reader :name, :email, :ignored\n\n      def initialize(attributes = {})\n        @name = attributes[:name]\n        @email = attributes[:email]\n        @ignored = attributes[:ignored]\n      end\n    end\n\n    FactoryBot.define do\n      sequence(:email) { |n| \"person#{n}@example.com\" }\n\n      factory :user do\n        transient do\n          ignored { \"of course!\" }\n        end\n\n        email\n\n        name { email.gsub(/@.+/, \"\") }\n\n        initialize_with { new(**attributes) }\n      end\n    end\n\n    user_with_attributes = FactoryBot.build(:user)\n    expect(user_with_attributes.email).to eq \"person1@example.com\"\n    expect(user_with_attributes.name).to eq \"person1\"\n    expect(user_with_attributes.ignored).to be_nil\n  end\nend\n\ndescribe \"initialize_with with an 'attributes' attribute\" do\n  it \"assigns attributes correctly\" do\n    define_class(\"User\") do\n      attr_reader :name\n\n      def initialize(attributes:)\n        @name = attributes[:name]\n      end\n    end\n\n    FactoryBot.define do\n      factory :user do\n        attributes { {name: \"Daniel\"} }\n        initialize_with { new(**attributes) }\n      end\n    end\n\n    user = FactoryBot.build(:user)\n\n    expect(user.name).to eq(\"Daniel\")\n  end\nend\n\ndescribe \"initialize_with for a constructor that requires a block\" do\n  it \"executes the block correctly\" do\n    define_class(\"Awesome\") do\n      attr_reader :output\n\n      def initialize(&block)\n        @output = instance_exec(&block)\n      end\n    end\n\n    FactoryBot.define do\n      factory :awesome do\n        initialize_with { new { \"Output\" } }\n      end\n    end\n\n    expect(FactoryBot.build(:awesome).output).to eq \"Output\"\n  end\nend\n\ndescribe \"initialize_with with a hash argument\" do\n  it \"builds the object correctly\" do\n    define_class(\"Container\") do\n      attr_reader :contents\n\n      def initialize(contents)\n        @contents = contents\n      end\n    end\n\n    FactoryBot.define do\n      factory :container do\n        initialize_with { new({key: :value}) }\n      end\n    end\n\n    expect(FactoryBot.build(:container).contents).to eq({key: :value})\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/keyed_by_class_spec.rb",
    "content": "describe \"finding factories keyed by class instead of symbol\" do\n  before do\n    define_model(\"User\") do\n      attr_accessor :name, :email\n    end\n\n    FactoryBot.define do\n      factory :user\n    end\n  end\n\n  it \"doesn't find the factory\" do\n    expect { FactoryBot.create(User) }.to(\n      raise_error(KeyError, /Factory not registered: User/)\n    )\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/lint_spec.rb",
    "content": "describe \"FactoryBot.lint\" do\n  it \"raises when a factory is invalid\" do\n    define_model \"User\", name: :string do\n      validates :name, presence: true\n    end\n\n    define_model \"AlwaysValid\"\n\n    FactoryBot.define do\n      factory :user do\n        factory :admin_user\n      end\n\n      factory :always_valid\n    end\n\n    error_message = <<~ERROR_MESSAGE.strip\n      The following factories are invalid:\n\n      * user - Validation failed: Name can't be blank (ActiveRecord::RecordInvalid)\n      * admin_user - Validation failed: Name can't be blank (ActiveRecord::RecordInvalid)\n    ERROR_MESSAGE\n\n    expect {\n      FactoryBot.lint\n    }.to raise_error FactoryBot::InvalidFactoryError, error_message\n  end\n\n  it \"executes linting in an ActiveRecord::Base transaction\" do\n    define_model \"User\", name: :string do\n      validates :name, uniqueness: true\n    end\n\n    define_model \"AlwaysValid\"\n\n    FactoryBot.define do\n      factory :user do\n        factory :admin_user\n      end\n\n      factory :always_valid\n    end\n\n    expect { FactoryBot.lint }.to_not raise_error\n  end\n\n  it \"runs after_commit callbacks when linting in a ActiveRecord::Base transaction\" do\n    define_model \"ModelWithAfterCommitCallbacks\" do\n      class_attribute :after_commit_callbacks_received\n\n      after_commit do\n        self.class.after_commit_callbacks_received = true\n      end\n    end\n\n    FactoryBot.define do\n      factory :model_with_after_commit_callbacks\n    end\n\n    FactoryBot.lint\n    expect(ModelWithAfterCommitCallbacks.after_commit_callbacks_received).to be true\n  end\n\n  it \"does not raise when all factories are valid\" do\n    define_model \"User\", name: :string do\n      validates :name, presence: true\n    end\n\n    FactoryBot.define do\n      factory :user do\n        name { \"assigned\" }\n      end\n    end\n\n    expect { FactoryBot.lint }.not_to raise_error\n  end\n\n  it \"allows for selective linting\" do\n    define_model \"InvalidThing\", name: :string do\n      validates :name, presence: true\n    end\n\n    define_model \"ValidThing\", name: :string\n\n    FactoryBot.define do\n      factory :valid_thing\n      factory :invalid_thing\n    end\n\n    expect {\n      only_valid_factories = FactoryBot.factories.reject { |factory|\n        factory.name =~ /invalid/\n      }\n\n      FactoryBot.lint only_valid_factories\n    }.not_to raise_error\n  end\n\n  describe \"trait validation\" do\n    context \"enabled\" do\n      it \"raises if a trait produces an invalid object\" do\n        define_model \"User\", name: :string do\n          validates :name, presence: true\n        end\n\n        FactoryBot.define do\n          factory :user do\n            name { \"Yep\" }\n            trait :unnamed do\n              name { nil }\n            end\n          end\n        end\n\n        error_message = <<~ERROR_MESSAGE.strip\n          The following factories are invalid:\n\n          * user+unnamed - Validation failed: Name can't be blank (ActiveRecord::RecordInvalid)\n        ERROR_MESSAGE\n\n        expect {\n          FactoryBot.lint traits: true\n        }.to raise_error FactoryBot::InvalidFactoryError, error_message\n      end\n\n      it \"does not raise if a trait produces a valid object\" do\n        define_model \"User\", name: :string do\n          validates :name, presence: true\n        end\n\n        FactoryBot.define do\n          factory :user do\n            name { \"Yep\" }\n            trait :renamed do\n              name { \"Yessir\" }\n            end\n          end\n        end\n\n        expect {\n          FactoryBot.lint traits: true\n        }.not_to raise_error\n      end\n    end\n\n    context \"disabled\" do\n      it \"does not raises if a trait produces an invalid object\" do\n        define_model \"User\", name: :string do\n          validates :name, presence: true\n        end\n\n        FactoryBot.define do\n          factory :user do\n            name { \"Yep\" }\n            trait :unnamed do\n              name { nil }\n            end\n          end\n        end\n\n        expect {\n          FactoryBot.lint traits: false\n          FactoryBot.lint\n        }.not_to raise_error\n      end\n    end\n  end\n\n  describe \"factory strategy for linting\" do\n    it \"uses the requested strategy\" do\n      define_class \"User\" do\n        attr_accessor :name\n\n        def save!\n          raise \"expected :build strategy, #save! shouldn't be invoked\"\n        end\n      end\n\n      FactoryBot.define do\n        factory :user do\n          name { \"Barbara\" }\n        end\n      end\n\n      expect {\n        FactoryBot.lint strategy: :build\n      }.not_to raise_error\n    end\n\n    it \"uses the requested strategy during trait validation\" do\n      define_class \"User\" do\n        attr_accessor :name\n\n        def save!\n          raise \"expected :build strategy, #save! shouldn't be invoked\"\n        end\n      end\n\n      FactoryBot.define do\n        factory :user do\n          name { \"Barbara\" }\n\n          trait :male do\n            name { \"Bob\" }\n          end\n        end\n      end\n\n      expect {\n        FactoryBot.lint traits: true, strategy: :build\n      }.not_to raise_error\n    end\n  end\n\n  describe \"verbose linting\" do\n    it \"prints the backtrace for each factory error\" do\n      define_class(\"InvalidThing\") do\n        def save!\n          raise \"invalid\"\n        end\n      end\n\n      FactoryBot.define do\n        factory :invalid_thing\n      end\n\n      expect {\n        FactoryBot.lint(verbose: true)\n      }.to raise_error(\n        FactoryBot::InvalidFactoryError,\n        %r{#{__FILE__}:\\d*:in ('InvalidThing#save!'|`save!')}\n      )\n    end\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/modify_factories_spec.rb",
    "content": "describe \"modifying factories\" do\n  include FactoryBot::Syntax::Methods\n\n  before do\n    define_model(\"User\", name: :string, admin: :boolean, email: :string, login: :string)\n\n    FactoryBot.define do\n      sequence(:email) { |n| \"user#{n}@example.com\" }\n\n      factory :user do\n        email\n\n        after(:create) do |user|\n          user.login = user.name.upcase if user.name\n        end\n\n        factory :admin do\n          admin { true }\n        end\n      end\n    end\n  end\n\n  context \"simple modification\" do\n    before do\n      FactoryBot.modify do\n        factory :user do\n          name { \"Great User\" }\n        end\n      end\n    end\n\n    subject { create(:user) }\n    its(:name) { should eq \"Great User\" }\n    its(:login) { should eq \"GREAT USER\" }\n\n    it \"doesn't allow the factory to be subsequently defined\" do\n      expect {\n        FactoryBot.define { factory :user }\n      }.to raise_error(FactoryBot::DuplicateDefinitionError, \"Factory already registered: user\")\n    end\n\n    it \"does allow the factory to be subsequently modified\" do\n      FactoryBot.modify do\n        factory :user do\n          name { \"Overridden again!\" }\n        end\n      end\n\n      expect(create(:user).name).to eq \"Overridden again!\"\n    end\n  end\n\n  context \"adding callbacks\" do\n    before do\n      FactoryBot.modify do\n        factory :user do\n          name { \"Great User\" }\n          after(:create) do |user|\n            user.name = user.name.downcase\n            user.login = nil\n          end\n        end\n      end\n    end\n\n    subject { create(:user) }\n\n    its(:name) { should eq \"great user\" }\n    its(:login) { should be_nil }\n  end\n\n  context \"reusing traits\" do\n    before do\n      FactoryBot.define do\n        trait :rockstar do\n          name { \"Johnny Rockstar!!!\" }\n        end\n      end\n\n      FactoryBot.modify do\n        factory :user do\n          rockstar\n          email { \"#{name}@example.com\" }\n        end\n      end\n    end\n\n    subject { create(:user) }\n\n    its(:name) { should eq \"Johnny Rockstar!!!\" }\n    its(:email) { should eq \"Johnny Rockstar!!!@example.com\" }\n    its(:login) { should eq \"JOHNNY ROCKSTAR!!!\" }\n  end\n\n  context \"redefining attributes\" do\n    before do\n      FactoryBot.modify do\n        factory :user do\n          email { \"#{name}-modified@example.com\" }\n          name { \"Great User\" }\n        end\n      end\n    end\n\n    context \"creating user\" do\n      context \"without overrides\" do\n        subject { create(:user) }\n\n        its(:name) { should eq \"Great User\" }\n        its(:email) { should eq \"Great User-modified@example.com\" }\n      end\n\n      context \"overriding the email\" do\n        subject { create(:user, email: \"perfect@example.com\") }\n\n        its(:name) { should eq \"Great User\" }\n        its(:email) { should eq \"perfect@example.com\" }\n      end\n\n      context \"overriding the name\" do\n        subject { create(:user, name: \"wonderful\") }\n\n        its(:name) { should eq \"wonderful\" }\n        its(:email) { should eq \"wonderful-modified@example.com\" }\n      end\n    end\n\n    context \"creating admin\" do\n      context \"without overrides\" do\n        subject { create(:admin) }\n\n        its(:name) { should eq \"Great User\" }\n        its(:email) { should eq \"Great User-modified@example.com\" }\n        its(:admin) { should be true }\n      end\n\n      context \"overriding the email\" do\n        subject { create(:admin, email: \"perfect@example.com\") }\n\n        its(:name) { should eq \"Great User\" }\n        its(:email) { should eq \"perfect@example.com\" }\n        its(:admin) { should be true }\n      end\n\n      context \"overriding the name\" do\n        subject { create(:admin, name: \"wonderful\") }\n\n        its(:name) { should eq \"wonderful\" }\n        its(:email) { should eq \"wonderful-modified@example.com\" }\n        its(:admin) { should be true }\n      end\n    end\n  end\n\n  it \"doesn't overwrite already defined child's attributes\" do\n    FactoryBot.modify do\n      factory :user do\n        admin { false }\n      end\n    end\n    expect(create(:admin)).to be_admin\n  end\n\n  it \"allows for overriding child classes\" do\n    FactoryBot.modify do\n      factory :admin do\n        admin { false }\n      end\n    end\n\n    expect(create(:admin)).not_to be_admin\n  end\n\n  it \"raises an exception if the factory was not defined before\" do\n    modify_unknown_factory = -> do\n      FactoryBot.modify do\n        factory :unknown_factory\n      end\n    end\n\n    expect(&modify_unknown_factory).to raise_error(KeyError)\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/modify_inherited_spec.rb",
    "content": "describe \"modifying inherited factories with traits\" do\n  before do\n    define_model(\"User\", gender: :string, admin: :boolean, age: :integer)\n    FactoryBot.define do\n      factory :user do\n        trait(:female) { gender { \"Female\" } }\n        trait(:male) { gender { \"Male\" } }\n\n        trait(:young_admin) do\n          admin { true }\n          age { 17 }\n        end\n\n        female\n        young_admin\n\n        factory :female_user do\n          gender { \"Female\" }\n          age { 25 }\n        end\n\n        factory :male_user do\n          gender { \"Male\" }\n        end\n      end\n    end\n  end\n\n  it \"returns the correct value for overridden attributes from traits\" do\n    expect(FactoryBot.build(:male_user).gender).to eq \"Male\"\n  end\n\n  it \"returns the correct value for overridden attributes from traits defining multiple attributes\" do\n    expect(FactoryBot.build(:female_user).gender).to eq \"Female\"\n    expect(FactoryBot.build(:female_user).age).to eq 25\n    expect(FactoryBot.build(:female_user).admin).to eq true\n  end\n\n  it \"allows modification of attributes created via traits\" do\n    FactoryBot.modify do\n      factory :male_user do\n        age { 20 }\n      end\n    end\n\n    expect(FactoryBot.build(:male_user).gender).to eq \"Male\"\n    expect(FactoryBot.build(:male_user).age).to eq 20\n    expect(FactoryBot.build(:male_user).admin).to eq true\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/nested_attributes_spec.rb",
    "content": "describe \"association assignment from nested attributes\" do\n  before do\n    define_model(\"Post\", title: :string) do\n      has_many :comments\n      accepts_nested_attributes_for :comments\n    end\n\n    define_model(\"Comment\", post_id: :integer, body: :text) do\n      belongs_to :post\n    end\n\n    FactoryBot.define do\n      factory :post do\n        comments_attributes { [FactoryBot.attributes_for(:comment), FactoryBot.attributes_for(:comment)] }\n      end\n\n      factory :comment do\n        sequence(:body) { |n| \"Body #{n}\" }\n      end\n    end\n  end\n\n  it \"assigns the correct amount of comments\" do\n    expect(FactoryBot.create(:post).comments.count).to eq 2\n  end\n\n  it \"assigns the correct amount of comments when overridden\" do\n    post = FactoryBot.create(:post, comments_attributes: [FactoryBot.attributes_for(:comment)])\n\n    expect(post.comments.count).to eq 1\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/overrides_spec.rb",
    "content": "describe \"attribute overrides\" do\n  before do\n    define_model(\"User\", admin: :boolean)\n    define_model(\"Post\", title: :string,\n      secure: :boolean,\n      user_id: :integer) do\n      belongs_to :user\n\n      def secure=(value)\n        return unless user&.admin?\n\n        write_attribute(:secure, value)\n      end\n    end\n\n    FactoryBot.define do\n      factory :user do\n        factory :admin do\n          admin { true }\n        end\n      end\n\n      factory :post do\n        user\n        title { \"default title\" }\n      end\n    end\n  end\n\n  let(:admin) { FactoryBot.create(:admin) }\n\n  let(:post_attributes) do\n    {secure: false}\n  end\n\n  let(:non_admin_post_attributes) do\n    post_attributes[:user] = FactoryBot.create(:user)\n    post_attributes\n  end\n\n  let(:admin_post_attributes) do\n    post_attributes[:user] = admin\n    post_attributes\n  end\n\n  context \"with an admin posting\" do\n    subject { FactoryBot.create(:post, admin_post_attributes) }\n    its(:secure) { should eq false }\n  end\n\n  context \"with a non-admin posting\" do\n    subject { FactoryBot.create(:post, non_admin_post_attributes) }\n    its(:secure) { should be_nil }\n  end\n\n  context \"with no user posting\" do\n    subject { FactoryBot.create(:post, post_attributes) }\n    its(:secure) { should be_nil }\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/parent_spec.rb",
    "content": "describe \"an instance generated by a factory that inherits from another factory\" do\n  before do\n    define_model(\"User\", name: :string, admin: :boolean, email: :string, upper_email: :string, login: :string)\n\n    FactoryBot.define do\n      factory :user do\n        name { \"John\" }\n        email { \"#{name.downcase}@example.com\" }\n        login { email }\n\n        factory :admin do\n          name { \"admin\" }\n          admin { true }\n          upper_email { email.upcase }\n        end\n      end\n    end\n  end\n\n  describe \"the parent class\" do\n    subject { FactoryBot.create(:user) }\n    it { should_not be_admin }\n    its(:name) { should eq \"John\" }\n    its(:email) { should eq \"john@example.com\" }\n    its(:login) { should eq \"john@example.com\" }\n  end\n\n  describe \"the child class redefining parent's attributes\" do\n    subject { FactoryBot.create(:admin) }\n    it { should be_kind_of(User) }\n    it { should be_admin }\n    its(:name) { should eq \"admin\" }\n    its(:email) { should eq \"admin@example.com\" }\n    its(:login) { should eq \"admin@example.com\" }\n    its(:upper_email) { should eq \"ADMIN@EXAMPLE.COM\" }\n  end\nend\n\ndescribe \"nested factories with different parents\" do\n  before do\n    define_model(\"User\", name: :string)\n\n    FactoryBot.define do\n      factory :user do\n        name { \"Basic User\" }\n\n        factory :male_user do\n          name { \"John Doe\" }\n        end\n\n        factory :uppercase_male_user, parent: :male_user do\n          after(:build) { |user| user.name = user.name.upcase }\n        end\n      end\n    end\n  end\n\n  it \"honors :parent over the factory block nesting\" do\n    expect(FactoryBot.build(:uppercase_male_user).name).to eq \"JOHN DOE\"\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/private_attributes_spec.rb",
    "content": "describe \"setting private attributes\" do\n  it \"raises a NoMethodError\" do\n    define_class(\"User\") do\n      private\n\n      attr_accessor :foo\n    end\n\n    FactoryBot.define do\n      factory :user do\n        foo { 123 }\n      end\n    end\n\n    expect {\n      FactoryBot.build(:user)\n    }.to raise_error NoMethodError, /foo=/\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/register_strategies_spec.rb",
    "content": "shared_context \"registering custom strategies\" do\n  before do\n    define_class(\"NamedObject\") do\n      attr_accessor :name\n    end\n  end\n\n  let(:custom_strategy) do\n    Class.new do\n      def result(evaluation)\n        evaluation.object.tap do |instance|\n          instance.name = \"Custom strategy\"\n        end\n      end\n    end\n  end\nend\n\ndescribe \"register custom strategies\" do\n  include_context \"registering custom strategies\"\n\n  before do\n    FactoryBot.define do\n      factory :named_object do\n        name { \"Great\" }\n      end\n    end\n  end\n\n  it \"allows overriding default strategies\" do\n    expect(FactoryBot.build(:named_object).name).to eq \"Great\"\n    FactoryBot.register_strategy(:build, custom_strategy)\n    expect(FactoryBot.build(:named_object).name).to eq \"Custom strategy\"\n  end\n\n  it \"allows adding additional strategies\" do\n    FactoryBot.register_strategy(:insert, custom_strategy)\n\n    expect(FactoryBot.build(:named_object).name).to eq \"Great\"\n    expect(FactoryBot.insert(:named_object).name).to eq \"Custom strategy\"\n  end\n\n  it \"allows using the *_list method to build a list using a custom strategy\" do\n    FactoryBot.register_strategy(:insert, custom_strategy)\n\n    inserted_items = FactoryBot.insert_list(:named_object, 2)\n    expect(inserted_items.length).to eq 2\n    expect(inserted_items.map(&:name)).to eq [\"Custom strategy\", \"Custom strategy\"]\n  end\n\n  it \"allows using the *_pair method to build a list using a custom strategy\" do\n    FactoryBot.register_strategy(:insert, custom_strategy)\n\n    inserted_items = FactoryBot.insert_pair(:named_object)\n    expect(inserted_items.length).to eq 2\n    expect(inserted_items.map(&:name)).to eq [\"Custom strategy\", \"Custom strategy\"]\n  end\nend\n\ndescribe \"including FactoryBot::Syntax::Methods when custom strategies have been declared\" do\n  include FactoryBot::Syntax::Methods\n\n  include_context \"registering custom strategies\"\n\n  before do\n    FactoryBot.define do\n      factory :named_object do\n        name { \"Great\" }\n      end\n    end\n  end\n\n  it \"allows adding additional strategies\" do\n    FactoryBot.register_strategy(:insert, custom_strategy)\n\n    expect(insert(:named_object).name).to eq \"Custom strategy\"\n  end\nend\n\ndescribe \"associations without overriding :strategy\" do\n  include_context \"registering custom strategies\"\n\n  before do\n    define_model(\"Post\", user_id: :integer) do\n      belongs_to :user\n    end\n\n    define_model(\"User\", name: :string)\n\n    FactoryBot.define do\n      factory :post do\n        user\n      end\n\n      factory :user do\n        name { \"John Doe\" }\n      end\n    end\n  end\n\n  context \"when the :use_parent_strategy config option is set to false\" do\n    it \"uses the overridden strategy on the association\" do\n      FactoryBot.register_strategy(:create, custom_strategy)\n\n      with_temporary_assignment(FactoryBot, :use_parent_strategy, false) do\n        post = FactoryBot.build(:post)\n        expect(post.user.name).to eq \"Custom strategy\"\n      end\n    end\n  end\n\n  context \"when the :use_parent_strategy config option is set to true\" do\n    it \"uses the parent strategy on the association\" do\n      FactoryBot.register_strategy(:create, custom_strategy)\n\n      with_temporary_assignment(FactoryBot, :use_parent_strategy, true) do\n        post = FactoryBot.build(:post)\n        expect(post.user.name).to eq \"John Doe\"\n      end\n    end\n  end\nend\n\ndescribe \"associations overriding :strategy\" do\n  include_context \"registering custom strategies\"\n\n  before do\n    define_model(\"Post\", user_id: :integer) do\n      belongs_to :user\n    end\n\n    define_model(\"User\", name: :string)\n\n    FactoryBot.define do\n      factory :post do\n        association :user, strategy: :insert\n      end\n\n      factory :user do\n        name { \"John Doe\" }\n      end\n    end\n  end\n\n  it \"uses the overridden create strategy to create the association\" do\n    FactoryBot.register_strategy(:insert, custom_strategy)\n    post = FactoryBot.build(:post)\n    expect(post.user.name).to eq \"Custom strategy\"\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/reload_spec.rb",
    "content": "describe \"reload\" do\n  it \"does not reset the value of use_parent_strategy\" do\n    custom_strategy = :custom_use_parent_strategy_value\n\n    with_temporary_assignment(FactoryBot, :use_parent_strategy, custom_strategy) do\n      FactoryBot.reload\n      expect(FactoryBot.use_parent_strategy).to eq custom_strategy\n    end\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/sequence_context_spec.rb",
    "content": "describe \"sequences are evaluated in the correct context, directly & implicitly\" do\n  include FactoryBot::Syntax::Methods\n\n  before do\n    define_class(\"User\") do\n      attr_accessor :id, :name\n\n      def awesome\n        \"aw yeah\"\n      end\n    end\n  end\n\n  it \"builds a sequence calling sprintf correctly\" do\n    FactoryBot.define do\n      factory :sequence_with_sprintf, class: User do\n        sequence(:id) { |n| sprintf(\"foo%d\", n) }\n      end\n    end\n\n    expect(FactoryBot.build(:sequence_with_sprintf).id).to eq \"foo1\"\n    expect(build(:sequence_with_sprintf).id).to eq \"foo2\"\n  end\n\n  it \"invokes the correct method on the instance\" do\n    FactoryBot.define do\n      factory :sequence_with_public_method, class: User do\n        sequence(:id) { public_method(:awesome).call }\n      end\n    end\n\n    expect(FactoryBot.build(:sequence_with_public_method).id).to eq \"aw yeah\"\n    expect(build(:sequence_with_public_method).id).to eq \"aw yeah\"\n  end\n\n  it \"invokes a method with no arguments on the instance\" do\n    FactoryBot.define do\n      factory :sequence_with_frozen, class: User do\n        sequence(:id) { frozen? }\n      end\n    end\n\n    expect(FactoryBot.build(:sequence_with_frozen).id).to be false\n    expect(build(:sequence_with_frozen).id).to be false\n  end\n\n  it \"allows direct reference of a method in a sequence\" do\n    FactoryBot.define do\n      factory :sequence_referencing_attribute_directly, class: User do\n        sequence(:id) { |n| \"#{awesome}#{n}\" }\n      end\n    end\n    expect(FactoryBot.build(:sequence_referencing_attribute_directly).id).to eq \"aw yeah1\"\n    expect(build(:sequence_referencing_attribute_directly).id).to eq \"aw yeah2\"\n  end\n\n  context \"with inherited factories\" do\n    it \"uses the parent's sequenced attribute\" do\n      FactoryBot.define do\n        factory :parent, class: User do\n          sequence(:id) { |n| \"id_#{n}\" }\n          factory :child, class: User\n        end\n      end\n\n      parents = FactoryBot.build_list(:parent, 3)\n      expect(parents[0].id).to eq \"id_1\"\n      expect(parents[1].id).to eq \"id_2\"\n      expect(parents[2].id).to eq \"id_3\"\n\n      children = build_list(:child, 3)\n      expect(children[0].id).to eq \"id_4\"\n      expect(children[1].id).to eq \"id_5\"\n      expect(children[2].id).to eq \"id_6\"\n    end\n\n    it \"invokes the parent's sequenced trait from within a child's inherited trait\" do\n      FactoryBot.define do\n        sequence :global_seq\n        factory :parent, class: User do\n          trait :with_sequenced_id do\n            sequence(:id) { |n| \"id_#{n}\" }\n          end\n\n          factory :child, class: User\n        end\n      end\n\n      parent_ids = FactoryBot.build_list(:parent, 3, :with_sequenced_id).map(&:id)\n      expect(parent_ids).to eq [\"id_1\", \"id_2\", \"id_3\"]\n\n      child_ids = build_list(:child, 3, :with_sequenced_id).map(&:id)\n      expect(child_ids).to eq [\"id_4\", \"id_5\", \"id_6\"]\n    end\n\n    it \"invokes the child's sequenced trait from within the child's own trait\" do\n      FactoryBot.define do\n        sequence :global_sequence\n        factory :parent, class: User do\n          trait :with_sequenced_id do\n            sequence(:id) { |n| \"id_#{n}\" }\n          end\n\n          factory :child, class: User, aliases: [:toddler, :teen] do\n            sequence(:id) { |n| \"id_#{n}\" }\n            trait :with_own_sequence do\n              sequence(:id, 1000, aliases: [:woo_hoo, :woo_hoo_2]) { |n| \"id_#{n}\" }\n            end\n          end\n        end\n      end\n\n      parents = FactoryBot.build_list(:parent, 3, :with_sequenced_id)\n      expect(parents[0].id).to eq \"id_1\"\n      expect(parents[1].id).to eq \"id_2\"\n      expect(parents[2].id).to eq \"id_3\"\n\n      children = build_list(:child, 3)\n      expect(children[0].id).to eq \"id_1\"\n      expect(children[1].id).to eq \"id_2\"\n      expect(children[2].id).to eq \"id_3\"\n\n      children = FactoryBot.build_list(:child, 3, :with_sequenced_id, :with_own_sequence)\n      expect(children[0].id).to eq \"id_1000\"\n      expect(children[1].id).to eq \"id_1001\"\n      expect(children[2].id).to eq \"id_1002\"\n    end\n\n    it \"redefines a child's sequence\" do\n      FactoryBot.define do\n        factory :parent, class: User do\n          sequence(:id) { |n| \"parent_#{n}\" }\n\n          factory :child, class: User do\n            sequence(:id) { |n| \"child_#{n}\" }\n          end\n        end\n      end\n\n      parents = FactoryBot.build_list(:parent, 3)\n      expect(parents[0].id).to eq \"parent_1\"\n      expect(parents[1].id).to eq \"parent_2\"\n      expect(parents[2].id).to eq \"parent_3\"\n\n      children = build_list(:child, 3)\n      expect(children[0].id).to eq \"child_1\"\n      expect(children[1].id).to eq \"child_2\"\n      expect(children[2].id).to eq \"child_3\"\n    end\n\n    it \"maintains context separation\" do\n      FactoryBot.define do\n        sequence(:id) { |n| \"global_#{n}\" }\n\n        factory :parent, class: User do\n          sequence(:id) { |n| \"parent_#{n}\" }\n\n          factory :child, class: User do\n            sequence(:id) { |n| \"child_#{n}\" }\n          end\n        end\n\n        factory :sibling, class: User do\n          sequence(:id) { |n| \"sibling_#{n}\" }\n        end\n      end\n\n      globals = FactoryBot.generate_list(:id, 3)\n      expect(globals[0]).to eq \"global_1\"\n      expect(globals[1]).to eq \"global_2\"\n      expect(globals[2]).to eq \"global_3\"\n\n      parents = build_list(:parent, 3)\n      expect(parents[0].id).to eq \"parent_1\"\n      expect(parents[1].id).to eq \"parent_2\"\n      expect(parents[2].id).to eq \"parent_3\"\n\n      children = FactoryBot.build_list(:child, 3)\n      expect(children[0].id).to eq \"child_1\"\n      expect(children[1].id).to eq \"child_2\"\n      expect(children[2].id).to eq \"child_3\"\n\n      siblings = build_list(:sibling, 3)\n      expect(siblings[0].id).to eq \"sibling_1\"\n      expect(siblings[1].id).to eq \"sibling_2\"\n      expect(siblings[2].id).to eq \"sibling_3\"\n    end\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/sequence_setting_spec.rb",
    "content": "describe \"FactoryBot.set_sequence\" do\n  include FactoryBot::Syntax::Methods\n\n  describe \"on success\" do\n    describe \"setting sequence to correct value\" do\n      it \"works with Integer sequences\" do\n        FactoryBot.define do\n          sequence(:email) { |n| \"somebody#{n}@example.com\" }\n        end\n\n        expect(generate_list(:email, 3).last).to eq \"somebody3@example.com\"\n        FactoryBot.set_sequence(:email, 54321)\n        expect(generate_list(:email, 3).last).to eq \"somebody54323@example.com\"\n      end\n\n      it \"works with negative Integer sequences\" do\n        FactoryBot.define do\n          sequence(:email, -50) { |n| \"somebody#{n}@example.com\" }\n        end\n\n        expect(generate_list(:email, 3).last).to eq \"somebody-48@example.com\"\n        FactoryBot.set_sequence(:email, -25)\n        expect(generate_list(:email, 3).last).to eq \"somebody-23@example.com\"\n      end\n\n      it \"works with Enumerable sequences\" do\n        define_class(\"User\") { attr_accessor :name }\n\n        FactoryBot.define do\n          factory :user do\n            sequence(:name, %w[Jane Joe Josh Jayde John].to_enum)\n          end\n        end\n\n        expect(generate(:user, :name)).to eq \"Jane\"\n        FactoryBot.set_sequence(:user, :name, \"Jayde\")\n        expect(generate(:user, :name)).to eq \"Jayde\"\n        expect(generate(:user, :name)).to eq \"John\"\n      end\n\n      it \"works with String sequences\" do\n        define_class(\"User\") { attr_accessor :initial }\n\n        FactoryBot.define do\n          factory :user do\n            factory :pilot do\n              sequence(:initial, \"a\")\n            end\n          end\n        end\n\n        expect(generate_list(:pilot, :initial, 3)).to eq [\"a\", \"b\", \"c\"]\n        FactoryBot.set_sequence(:pilot, :initial, \"z\")\n        expect(generate_list(:pilot, :initial, 3)).to eq [\"z\", \"aa\", \"ab\"]\n      end\n\n      it \"works with Date sequences\" do\n        define_class(\"User\") { attr_accessor :dob }\n\n        FactoryBot.define do\n          factory :user do\n            factory :pilot do\n              factory :jet_pilot do\n                sequence(:dob, Date.parse(\"2025-04-01\"))\n              end\n            end\n          end\n        end\n\n        expect(generate(:jet_pilot, :dob)).to eq Date.parse(\"2025-04-01\")\n        FactoryBot.set_sequence(:jet_pilot, :dob, Date.parse(\"2025-05-01\"))\n        expect(generate_list(:jet_pilot, :dob, 3).last).to eq Date.parse(\"2025-05-03\")\n      end\n\n      it \"works with lazy Integer sequences\" do\n        FactoryBot.define do\n          sequence(:email, proc { 42 }) { |n| \"somebody#{n}@example.com\" }\n        end\n\n        expect(generate_list(:email, 3).last).to eq \"somebody44@example.com\"\n        FactoryBot.set_sequence(:email, 54321)\n        expect(generate_list(:email, 3).last).to eq \"somebody54323@example.com\"\n      end\n\n      it \"does not collide with other factory or global sequences\" do\n        define_class(\"User\") { attr_accessor :email }\n        define_class(\"Admin\") { attr_accessor :email }\n\n        FactoryBot.define do\n          sequence(:email) { |n| \"global#{n}@example.com\" }\n          factory :user do\n            sequence(:email) { |n| \"user#{n}@example.com\" }\n\n            factory :admin do\n              sequence(:email) { |n| \"admin#{n}@example.com\" }\n            end\n          end\n        end\n\n        generate_list :email, 2\n        generate_list :user, :email, 2\n        generate_list :admin, :email, 2\n\n        expect(generate(:email)).to eq \"global3@example.com\"\n        expect(generate(:user, :email)).to eq \"user3@example.com\"\n        expect(generate(:admin, :email)).to eq \"admin3@example.com\"\n\n        FactoryBot.set_sequence(:user, :email, 22222)\n        FactoryBot.set_sequence(:admin, :email, 33333)\n\n        expect(generate(:email)).to eq \"global4@example.com\"\n        expect(generate(:user, :email)).to eq \"user22222@example.com\"\n        expect(generate(:admin, :email)).to eq \"admin33333@example.com\"\n      end\n    end\n\n    describe \"sequence targeting by URI\" do\n      before do\n        define_class(\"User\")\n\n        FactoryBot.define do\n          sequence :counter\n\n          trait :global_trait do\n            sequence :counter\n          end\n\n          factory :parent, class: \"User\" do\n            sequence :counter\n\n            trait :parent_trait do\n              sequence :counter\n            end\n\n            factory :child do\n              sequence :counter\n\n              trait :child_trait do\n                sequence :counter\n              end\n            end\n          end\n        end\n      end\n\n      it \"accepts symbolic URIs\" do\n        expect(generate(:counter)).to eq 1\n        expect(generate(:global_trait, :counter)).to eq 1\n        expect(generate(:parent, :counter)).to eq 1\n        expect(generate(:parent, :parent_trait, :counter)).to eq 1\n        expect(generate(:child, :counter)).to eq 1\n        expect(generate(:child, :child_trait, :counter)).to eq 1\n\n        FactoryBot.set_sequence :counter, 1000\n        FactoryBot.set_sequence :global_trait, :counter, 3000\n        FactoryBot.set_sequence :parent, :counter, 6000\n        FactoryBot.set_sequence :parent, :parent_trait, :counter, 9000\n        FactoryBot.set_sequence :child, :counter, 12_000\n        FactoryBot.set_sequence :child, :child_trait, :counter, 15_000\n\n        expect(generate(:counter)).to eq 1000\n        expect(generate(:global_trait, :counter)).to eq 3000\n        expect(generate(:parent, :counter)).to eq 6000\n        expect(generate(:parent, :parent_trait, :counter)).to eq 9000\n        expect(generate(:child, :counter)).to eq 12_000\n        expect(generate(:child, :child_trait, :counter)).to eq 15_000\n      end\n\n      it \"accepts string URIs\" do\n        expect(generate(\"counter\")).to eq 1\n        expect(generate(\"global_trait/counter\")).to eq 1\n        expect(generate(\"parent/counter\")).to eq 1\n        expect(generate(\"parent/parent_trait/counter\")).to eq 1\n        expect(generate(\"child/counter\")).to eq 1\n        expect(generate(\"child/child_trait/counter\")).to eq 1\n\n        FactoryBot.set_sequence \"counter\", 1000\n        FactoryBot.set_sequence \"global_trait/counter\", 3000\n        FactoryBot.set_sequence \"parent/counter\", 6000\n        FactoryBot.set_sequence \"parent/parent_trait/counter\", 9000\n        FactoryBot.set_sequence \"child/counter\", 12_000\n        FactoryBot.set_sequence \"child/child_trait/counter\", 15_000\n\n        expect(generate(\"counter\")).to eq 1000\n        expect(generate(\"global_trait/counter\")).to eq 3000\n        expect(generate(\"parent/counter\")).to eq 6000\n        expect(generate(\"parent/parent_trait/counter\")).to eq 9000\n        expect(generate(\"child/counter\")).to eq 12_000\n        expect(generate(\"child/child_trait/counter\")).to eq 15_000\n      end\n    end\n\n    describe \"name format support\" do\n      it \"accepts String or Symbol sequence names\" do\n        FactoryBot.define do\n          sequence(:email) { |n| \"user#{n}@example.com\" }\n        end\n\n        FactoryBot.set_sequence(:email, 54321)\n        expect(generate(:email)).to eq \"user54321@example.com\"\n\n        FactoryBot.set_sequence(\"email\", 777)\n        expect(generate(:email)).to eq \"user777@example.com\"\n      end\n\n      it \"accepts String or Symbol factory names\" do\n        define_class(\"User\") { attr_accessor :email }\n\n        FactoryBot.define do\n          factory :user do\n            sequence(:email) { |n| \"user#{n}@example.com\" }\n          end\n        end\n\n        FactoryBot.set_sequence(:user, :email, 54321)\n        expect(generate(:user, :email)).to eq \"user54321@example.com\"\n\n        FactoryBot.set_sequence(\"user\", \"email\", 777)\n        expect(generate(\"user\", \"email\")).to eq \"user777@example.com\"\n      end\n    end\n\n    describe \"alias support\" do\n      it \"works with aliases for both sequence and factory\" do\n        define_class(\"User\") { attr_accessor :email }\n\n        FactoryBot.define do\n          factory :user, aliases: [:author, :commenter] do\n            sequence(:email, aliases: [\"primary_email\", :alt_email]) { |n| \"user#{n}@example.com\" }\n          end\n        end\n\n        generate_list :user, :email, 2\n        expect(generate(:user, :email)).to eq \"user3@example.com\"\n\n        FactoryBot.set_sequence(:user, :email, 11111)\n        expect(generate(:user, :email)).to eq \"user11111@example.com\"\n\n        FactoryBot.set_sequence(:author, :primary_email, 22222)\n        expect(generate(:user, :email)).to eq \"user22222@example.com\"\n\n        FactoryBot.set_sequence(:commenter, :alt_email, 33333)\n        expect(generate(:user, :email)).to eq \"user33333@example.com\"\n      end\n    end\n  end\n\n  describe \"error handling\" do\n    describe \"unknown sequence names\" do\n      it \"raises an error for unknown global sequences\" do\n        expect { FactoryBot.set_sequence(:test, 54321) }\n          .to raise_error KeyError, /Sequence not registered: 'test'/\n      end\n\n      it \"raises an error for unknown factory sequences\" do\n        FactoryBot.define do\n          factory :user do\n            sequence(:email) { |n| \"alt_user#{n}@example.com\" }\n          end\n        end\n\n        expect { FactoryBot.set_sequence(:user, :test, 54321) }\n          .to raise_error KeyError, /Sequence not registered: 'user\\/test'/\n      end\n\n      it \"raises an error when factory sequence doesn't exist but global does\" do\n        FactoryBot.define do\n          sequence(:email) { |n| \"global#{n}@example.com\" }\n\n          factory :user do\n            sequence(:alt_email) { |n| \"alt_user#{n}@example.com\" }\n          end\n        end\n\n        expect { FactoryBot.set_sequence(:user, :email, 54321) }\n          .to raise_error KeyError, /Sequence not registered: 'user\\/email'/\n      end\n\n      it \"raises an error for inherited sequences\" do\n        define_class(\"User\") { attr_accessor :email }\n\n        FactoryBot.define do\n          sequence(:email) { |n| \"global#{n}@example.com\" }\n\n          factory :user do\n            sequence(:email) { |n| \"user#{n}@example.com\" }\n            factory :admin\n          end\n        end\n\n        admin = build(:admin)\n        expect(admin.email).to eq \"user1@example.com\"\n\n        expect { FactoryBot.set_sequence(:admin, :email, 54321) }\n          .to raise_error KeyError, /Sequence not registered: 'admin\\/email'/\n      end\n    end\n\n    describe \"invalid values\" do\n      it \"raises an error when value is below minimum for Integer sequences\" do\n        FactoryBot.define do\n          sequence(:counter, 1000)\n        end\n\n        expect { FactoryBot.set_sequence(:counter, 999) }\n          .to raise_error ArgumentError, /Value cannot be less than: 1000/\n      end\n\n      it \"raises an error for unmatched String values\", :slow do\n        FactoryBot.define do\n          sequence(:char, \"c\")\n        end\n\n        expect { FactoryBot.set_sequence(:char, \"a\") }\n          .to raise_error ArgumentError, /Unable to find 'a' in the sequence/\n      end\n\n      it \"raises an error for unmatched Enumerable values\" do\n        names = %w[Jane Joe Josh Jayde John].to_enum\n\n        allow_any_instance_of(FactoryBot::Sequence).to receive(:can_set_value_by_index?).and_return(false)\n\n        FactoryBot.define do\n          sequence(:name, names)\n        end\n\n        expect { FactoryBot.set_sequence(:name, \"Jester\") }\n          .to raise_error ArgumentError, /Unable to find 'Jester' in the sequence/\n      end\n\n      it \"times out when value cannot be found within timeout period\", :slow do\n        with_temporary_assignment(FactoryBot, :sequence_setting_timeout, 3) do\n          FactoryBot.define do\n            sequence(:test, \"a\")\n          end\n\n          start = Time.now\n          expect { FactoryBot.set_sequence(:test, \"zzzzzzzzzz\") }\n            .to raise_error ArgumentError, /Unable to find 'zzzzzzzzzz' in the sequence/\n\n          duration = Time.now - start\n          expect(duration >= 3.seconds).to be_truthy\n          expect(duration < 4.seconds).to be_truthy\n        end\n      end\n\n      it \"leaves sequence unchanged when value is not found\" do\n        FactoryBot.define do\n          sequence(:name, %w[Jane Joe Josh Jayde John].to_enum)\n        end\n\n        generate_list :name, 2\n        expect(generate(:name)).to eq \"Josh\"\n\n        expect { FactoryBot.set_sequence(:name, \"Jester\") }\n          .to raise_error ArgumentError, /Unable to find 'Jester' in the sequence/\n\n        expect(generate(:name)).to eq \"Jayde\"\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/sequence_spec.rb",
    "content": "describe \"sequences\" do\n  include FactoryBot::Syntax::Methods\n\n  require \"ostruct\"\n\n  # = On Success\n  # ======================================================================\n  #\n  describe \"on success\" do\n    it \"generates several values in the correct format\" do\n      define_class(\"User\") { attr_accessor :email }\n\n      FactoryBot.define do\n        sequence(:email) { |n| \"global-#{n}@example.com\" }\n\n        factory :user do\n          sequence(:email) { |n| \"user-#{n}@example.com\" }\n        end\n      end\n\n      expect(generate(:email)).to eq \"global-1@example.com\"\n      expect(generate(:email)).to eq \"global-2@example.com\"\n      expect(generate(:email)).to eq \"global-3@example.com\"\n\n      expect(generate(:user, :email)).to eq \"user-1@example.com\"\n      expect(generate(:user, :email)).to eq \"user-2@example.com\"\n      expect(generate(:user, :email)).to eq \"user-3@example.com\"\n    end\n\n    it \"generates sequential numbers if no block is given\" do\n      define_class(\"User\") { attr_accessor :email }\n\n      FactoryBot.define do\n        sequence :global_order\n\n        factory :user do\n          sequence :user_order\n        end\n      end\n\n      expect(generate(:global_order)).to eq 1\n      expect(generate(:global_order)).to eq 2\n      expect(generate(:global_order)).to eq 3\n\n      expect(generate(:user, :user_order)).to eq 1\n      expect(generate(:user, :user_order)).to eq 2\n      expect(generate(:user, :user_order)).to eq 3\n    end\n\n    it \"generates aliases for the sequence that reference the same block\" do\n      define_class(\"User\") { attr_accessor :email }\n\n      FactoryBot.define do\n        sequence(:size, aliases: [:count, :length]) { |n| \"global-called-#{n}\" }\n\n        factory :user, aliases: [:author, :commenter] do\n          sequence(:size, aliases: [:count, :length]) { |n| \"user-called-#{n}\" }\n        end\n      end\n\n      expect(generate(:size)).to eq \"global-called-1\"\n      expect(generate(:count)).to eq \"global-called-2\"\n      expect(generate(:length)).to eq \"global-called-3\"\n\n      expect(generate(:user, :size)).to eq \"user-called-1\"\n      expect(generate(:author, :count)).to eq \"user-called-2\"\n      expect(generate(:commenter, :length)).to eq \"user-called-3\"\n    end\n\n    it \"generates aliases for the sequence that reference the same block and retains value\" do\n      define_class(\"User\") { attr_accessor :email }\n\n      FactoryBot.define do\n        sequence(:size, \"a\", aliases: [:count, :length]) { |n| \"global-called-#{n}\" }\n\n        factory :user, aliases: [:author, :commenter] do\n          sequence(:size, \"x\", aliases: [:count, :length]) { |n| \"user-called-#{n}\" }\n        end\n      end\n\n      expect(generate(:size)).to eq \"global-called-a\"\n      expect(generate(:count)).to eq \"global-called-b\"\n      expect(generate(:length)).to eq \"global-called-c\"\n\n      expect(generate(:user, :size)).to eq \"user-called-x\"\n      expect(generate(:author, :count)).to eq \"user-called-y\"\n      expect(generate(:commenter, :length)).to eq \"user-called-z\"\n    end\n\n    it \"generates sequences after lazy loading an initial value from a proc\" do\n      loaded = false\n\n      FactoryBot.define do\n        sequence :count, proc {\n          loaded = true\n          \"d\"\n        }\n      end\n\n      expect(loaded).to be false\n\n      first_value = generate(:count)\n      another_value = generate(:count)\n\n      expect(loaded).to be true\n\n      expect(first_value).to eq \"d\"\n      expect(another_value).to eq \"e\"\n    end\n\n    it \"generates sequences after lazy loading an initial value from an object responding to call\" do\n      define_class(\"HasCallMethod\") do\n        def initialise\n          @called = false\n        end\n\n        def called?\n          @called\n        end\n\n        def call\n          @called = true\n          \"ABC\"\n        end\n      end\n\n      has_call_method_instance = HasCallMethod.new\n\n      FactoryBot.define do\n        sequence :letters, has_call_method_instance\n      end\n\n      expect(has_call_method_instance).not_to be_called\n\n      first_value = generate(:letters)\n      another_value = generate(:letters)\n\n      expect(has_call_method_instance).to be_called\n\n      expect(first_value).to eq \"ABC\"\n      expect(another_value).to eq \"ABD\"\n    end\n\n    it \"generates few values of the sequence\" do\n      define_class(\"User\") { attr_accessor :email }\n\n      FactoryBot.define do\n        sequence(:email) { |n| \"global-#{n}@example.com\" }\n\n        factory :user do\n          sequence(:email) { |n| \"user-#{n}@example.com\" }\n        end\n      end\n\n      global_values = generate_list(:email, 3)\n      expect(global_values[0]).to eq \"global-1@example.com\"\n      expect(global_values[1]).to eq \"global-2@example.com\"\n      expect(global_values[2]).to eq \"global-3@example.com\"\n\n      user_values = generate_list(:user, :email, 3)\n      expect(user_values[0]).to eq \"user-1@example.com\"\n      expect(user_values[1]).to eq \"user-2@example.com\"\n      expect(user_values[2]).to eq \"user-3@example.com\"\n    end\n\n    it \"generates few values of the sequence with a given scope\" do\n      define_class(\"User\") { attr_accessor :name, :email }\n\n      FactoryBot.define do\n        factory :user do\n          sequence(:email) { |n| \"#{name}-#{n}@example.com\" }\n        end\n      end\n\n      test_scope = OpenStruct.new(name: \"Jester\")\n      user_values = generate_list(:user, :email, 3, scope: test_scope)\n\n      expect(user_values[0]).to eq \"Jester-1@example.com\"\n      expect(user_values[1]).to eq \"Jester-2@example.com\"\n      expect(user_values[2]).to eq \"Jester-3@example.com\"\n    end\n  end # \"on success\"\n\n  # = On Failure\n  # ======================================================================\n  #\n  describe \"on failure\" do\n    it \"it fails with an unknown sequence or factory name\" do\n      define_class(\"User\") { attr_accessor :email }\n\n      FactoryBot.define do\n        sequence :counter\n        factory :user do\n          sequence counter\n        end\n      end\n\n      expect { generate(:test).to raise_error KeyError, /Sequence not registered: :test/ }\n      expect { generate(:user, :test).to raise_error KeyError, /Sequence not registered: user:test/ }\n      expect { generate(:admin, :counter).to raise_error KeyError, /Sequence not registered: \"admin:counter\"/ }\n    end\n\n    it \"it fails with a sequence that references a scoped attribute, but no scope given\" do\n      define_class(\"User\") { attr_accessor :name, :age, :info }\n\n      FactoryBot.define do\n        factory :user do\n          sequence(:info) { |n| \"#{name}:#{age + n}\" }\n        end\n      end\n\n      jester = FactoryBot.build(:user, name: \"Jester\", age: 21)\n\n      expect(generate(:user, :info, scope: jester)).to eq \"Jester:23\"\n\n      expect { generate(:user, :info) }\n        .to raise_error ArgumentError, \"Sequence 'user/info' failed to return a value. \" \\\n                                       \"Perhaps it needs a scope to operate? (scope: <object>)\"\n    end\n  end # \"on failure\"\nend\n"
  },
  {
    "path": "spec/acceptance/skip_create_spec.rb",
    "content": "describe \"skipping the default create\" do\n  before do\n    define_model(\"User\", email: :string)\n\n    FactoryBot.define do\n      factory :user do\n        skip_create\n\n        email { \"john@example.com\" }\n      end\n    end\n  end\n\n  it \"doesn't execute anything when creating the instance\" do\n    expect(FactoryBot.create(:user)).not_to be_persisted\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/stub_spec.rb",
    "content": "describe \"a stubbed instance\" do\n  include FactoryBot::Syntax::Methods\n\n  before do\n    define_model(\"User\")\n\n    define_model(\"Post\", user_id: :integer) do\n      belongs_to :user\n    end\n\n    FactoryBot.define do\n      factory :user\n\n      factory :post do\n        user\n      end\n    end\n  end\n\n  subject { build_stubbed(:post) }\n\n  it \"acts as if it came from the database\" do\n    should_not be_new_record\n  end\n\n  it \"assigns associations and acts as if it is saved\" do\n    expect(subject.user).to be_kind_of(User)\n    expect(subject.user).not_to be_new_record\n  end\nend\n\ndescribe \"a stubbed instance with timestamps\" do\n  include FactoryBot::Syntax::Methods\n\n  before do\n    define_model(\"ModelWithTimestamps\", created_at: :datetime, updated_at: :datetime)\n\n    FactoryBot.define do\n      factory :model_with_timestamps\n    end\n  end\n\n  subject { build_stubbed(:model_with_timestamps) }\n\n  it \"assigns the exact same datetime\" do\n    expect(subject.created_at).to eq(subject.updated_at)\n  end\nend\n\ndescribe \"a stubbed instance overriding strategy\" do\n  include FactoryBot::Syntax::Methods\n\n  before do\n    define_model(\"User\")\n    define_model(\"Post\", user_id: :integer) do\n      belongs_to :user\n    end\n\n    FactoryBot.define do\n      factory :user\n\n      factory :post do\n        association(:user, strategy: :build)\n      end\n    end\n  end\n\n  subject { build_stubbed(:post) }\n\n  it \"acts as if it is saved in the database\" do\n    should_not be_new_record\n  end\n\n  it \"assigns associations and acts as if it is saved\" do\n    expect(subject.user).to be_kind_of(User)\n    expect(subject.user).not_to be_new_record\n  end\nend\n\ndescribe \"overridden primary keys conventions\" do\n  describe \"a stubbed instance with a uuid primary key\" do\n    it \"builds a stubbed instance\" do\n      using_model(\"ModelWithUuid\", primary_key: :uuid) do\n        FactoryBot.define do\n          factory :model_with_uuid\n        end\n\n        model = FactoryBot.build_stubbed(:model_with_uuid)\n        expect(model).to be_truthy\n      end\n    end\n\n    it \"behaves like a persisted record\" do\n      using_model(\"ModelWithUuid\", primary_key: :uuid) do\n        FactoryBot.define do\n          factory :model_with_uuid\n        end\n\n        model = FactoryBot.build_stubbed(:model_with_uuid)\n        expect(model).to be_persisted\n        expect(model).not_to be_new_record\n      end\n    end\n\n    it \"has a uuid primary key\" do\n      using_model(\"ModelWithUuid\", primary_key: :uuid) do\n        FactoryBot.define do\n          factory :model_with_uuid\n        end\n\n        model = FactoryBot.build_stubbed(:model_with_uuid)\n        expect(model.id).to be_a(String)\n      end\n    end\n  end\n\n  describe \"a stubbed instance with no primary key\" do\n    it \"builds a stubbed instance\" do\n      using_model(\"ModelWithoutPk\", primary_key: false) do\n        FactoryBot.define do\n          factory :model_without_pk\n        end\n\n        model = FactoryBot.build_stubbed(:model_without_pk)\n        expect(model).to be_truthy\n      end\n    end\n\n    it \"behaves like a persisted record\" do\n      using_model(\"ModelWithoutPk\", primary_key: false) do\n        FactoryBot.define do\n          factory :model_without_pk\n        end\n\n        model = FactoryBot.build_stubbed(:model_without_pk)\n        expect(model).to be_persisted\n        expect(model).not_to be_new_record\n      end\n    end\n  end\n\n  describe \"a stubbed instance with no id setter\" do\n    it \"builds a stubbed instance\" do\n      FactoryBot.define do\n        factory :model_hash, class: Hash\n      end\n\n      model = FactoryBot.build_stubbed(:model_hash)\n      expect(model).to be_truthy\n    end\n  end\n\n  def using_model(name, primary_key:)\n    define_class(name, ActiveRecord::Base)\n\n    connection = ActiveRecord::Base.connection\n    begin\n      clear_generated_table(name.tableize)\n      connection.create_table(name.tableize, id: primary_key) do |t|\n        t.column :updated_at, :datetime\n      end\n\n      yield\n    ensure\n      clear_generated_table(name.tableize)\n    end\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/syntax_methods_within_dynamic_attributes_spec.rb",
    "content": "describe \"syntax methods within dynamic attributes\" do\n  before do\n    define_model(\"Post\", title: :string, user_id: :integer) do\n      belongs_to :user\n\n      def generate\n        \"generate result\"\n      end\n    end\n    define_model(\"User\", email: :string)\n\n    FactoryBot.define do\n      sequence(:email_address) { |n| \"person-#{n}@example.com\" }\n\n      factory :user do\n        email { generate(:email_address) }\n      end\n\n      factory :post do\n        title { generate }\n        user { build(:user) }\n      end\n    end\n  end\n\n  it \"can access syntax methods from dynamic attributes\" do\n    expect(FactoryBot.build(:user).email).to eq \"person-1@example.com\"\n    expect(FactoryBot.attributes_for(:user)[:email]).to eq \"person-2@example.com\"\n  end\n\n  it \"can access syntax methods from dynamic attributes\" do\n    expect(FactoryBot.build(:post).user).to be_instance_of(User)\n  end\n\n  it \"can access methods already existing on the class\" do\n    expect(FactoryBot.build(:post).title).to eq \"generate result\"\n    expect(FactoryBot.attributes_for(:post)[:title]).to be_nil\n  end\n\n  it \"allows syntax methods to be used when the block has an arity of 1\" do\n    FactoryBot.define do\n      factory :post_using_block_with_variable, parent: :post do\n        user { |_| build(:user) }\n      end\n    end\n\n    expect(FactoryBot.build(:post_using_block_with_variable).user).to be_instance_of(User)\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/traits_spec.rb",
    "content": "describe \"an instance generated by a factory with multiple traits\" do\n  before do\n    define_model(\"User\",\n      name: :string,\n      admin: :boolean,\n      gender: :string,\n      email: :string,\n      date_of_birth: :date,\n      great: :string)\n\n    FactoryBot.define do\n      factory :user do\n        name { \"John\" }\n\n        trait :great do\n          great { \"GREAT!!!\" }\n        end\n\n        trait :great do\n          great { \"EVEN GREATER!!!\" }\n        end\n\n        trait :admin do\n          admin { true }\n        end\n\n        trait :admin_trait do\n          admin { true }\n        end\n\n        trait :male do\n          name { \"Joe\" }\n          gender { \"Male\" }\n        end\n\n        trait :female do\n          name { \"Jane\" }\n          gender { \"Female\" }\n        end\n\n        trait :make_it_great do\n          great\n        end\n\n        factory :great_user do\n          great\n        end\n\n        factory :even_greater_user do\n          great\n\n          trait :great do\n            great { \"EVEN GREATER!!!\" }\n          end\n        end\n\n        factory :greatest_user do\n          trait :great do\n            great { \"GREATEST EVER!!!\" }\n          end\n        end\n\n        factory :admin, traits: [:admin]\n\n        factory :male_user do\n          male\n\n          factory :child_male_user do\n            date_of_birth { Date.parse(\"1/1/2000\") }\n          end\n        end\n\n        factory :female, traits: [:female] do\n          trait :admin do\n            admin { true }\n            name { \"Judy\" }\n          end\n\n          factory :female_great_user do\n            great\n          end\n\n          factory :female_admin_judy, traits: [:admin]\n        end\n\n        factory :female_admin, traits: [:female, :admin]\n        factory :female_after_male_admin, traits: [:male, :female, :admin]\n        factory :male_after_female_admin, traits: [:female, :male, :admin]\n      end\n\n      trait :email do\n        email { \"#{name}@example.com\" }\n      end\n\n      factory :user_with_email, class: User, traits: [:email] do\n        name { \"Bill\" }\n      end\n    end\n  end\n\n  context \"the parent class\" do\n    subject { FactoryBot.create(:user) }\n    its(:name) { should eq \"John\" }\n    its(:gender) { should be_nil }\n    it { should_not be_admin }\n  end\n\n  context \"the child class with one trait\" do\n    subject { FactoryBot.create(:admin) }\n    its(:name) { should eq \"John\" }\n    its(:gender) { should be_nil }\n    it { should be_admin }\n  end\n\n  context \"the other child class with one trait\" do\n    subject { FactoryBot.create(:female) }\n    its(:name) { should eq \"Jane\" }\n    its(:gender) { should eq \"Female\" }\n    it { should_not be_admin }\n  end\n\n  context \"the child with multiple traits\" do\n    subject { FactoryBot.create(:female_admin) }\n    its(:name) { should eq \"Jane\" }\n    its(:gender) { should eq \"Female\" }\n    it { should be_admin }\n  end\n\n  context \"the child with multiple traits and overridden attributes\" do\n    subject { FactoryBot.create(:female_admin, name: \"Jill\", gender: nil) }\n    its(:name) { should eq \"Jill\" }\n    its(:gender) { should be_nil }\n    it { should be_admin }\n  end\n\n  context \"the child with multiple traits who override the same attribute\" do\n    context \"when the male assigns name after female\" do\n      subject { FactoryBot.create(:male_after_female_admin) }\n      its(:name) { should eq \"Joe\" }\n      its(:gender) { should eq \"Male\" }\n      it { should be_admin }\n    end\n\n    context \"when the female assigns name after male\" do\n      subject { FactoryBot.create(:female_after_male_admin) }\n      its(:name) { should eq \"Jane\" }\n      its(:gender) { should eq \"Female\" }\n      it { should be_admin }\n    end\n  end\n\n  context \"child class with scoped trait and inherited trait\" do\n    subject { FactoryBot.create(:female_admin_judy) }\n    its(:name) { should eq \"Judy\" }\n    its(:gender) { should eq \"Female\" }\n    it { should be_admin }\n  end\n\n  context \"factory using global trait\" do\n    subject { FactoryBot.create(:user_with_email) }\n    its(:name) { should eq \"Bill\" }\n    its(:email) { should eq \"Bill@example.com\" }\n  end\n\n  context \"factory created with alternate syntax for specifying trait\" do\n    subject { FactoryBot.create(:male_user) }\n    its(:gender) { should eq \"Male\" }\n\n    context \"where trait name and attribute are the same\" do\n      subject { FactoryBot.create(:great_user) }\n      its(:great) { should eq \"GREAT!!!\" }\n    end\n\n    context \"where trait name and attribute are the same and attribute is overridden\" do\n      subject { FactoryBot.create(:great_user, great: \"SORT OF!!!\") }\n      its(:great) { should eq \"SORT OF!!!\" }\n    end\n  end\n\n  context \"factory with trait defined multiple times\" do\n    subject { FactoryBot.create(:great_user) }\n    its(:great) { should eq \"GREAT!!!\" }\n\n    context \"child factory redefining trait\" do\n      subject { FactoryBot.create(:even_greater_user) }\n      its(:great) { should eq \"EVEN GREATER!!!\" }\n    end\n  end\n\n  context \"factory with implicit traits called by child\" do\n    it \"calls the correct trait when parent built first\" do\n      user = FactoryBot.create(:user, :make_it_great)\n\n      expect(user.great).to eq \"GREAT!!!\"\n    end\n\n    it \"calls the correct trait when child built first\" do\n      greatest = FactoryBot.create(:greatest_user, :make_it_great)\n      user = FactoryBot.create(:user, :make_it_great)\n\n      expect(user.great).to eq \"GREAT!!!\"\n      expect(greatest.great).to eq \"GREATEST EVER!!!\"\n    end\n  end\n\n  context \"child factory created where trait attributes are inherited\" do\n    subject { FactoryBot.create(:child_male_user) }\n    its(:gender) { should eq \"Male\" }\n    its(:date_of_birth) { should eq Date.parse(\"1/1/2000\") }\n  end\n\n  context \"child factory using grandparents' trait\" do\n    subject { FactoryBot.create(:female_great_user) }\n    its(:great) { should eq \"GREAT!!!\" }\n  end\nend\n\ndescribe \"trait indifferent access\" do\n  context \"when trait is defined as a string\" do\n    it \"can be invoked with a string\" do\n      build_user_factory_with_admin_trait(\"admin\")\n\n      user = FactoryBot.build(:user, \"admin\")\n\n      expect(user).to be_admin\n    end\n\n    it \"can be invoked with a symbol\" do\n      build_user_factory_with_admin_trait(\"admin\")\n\n      user = FactoryBot.build(:user, :admin)\n\n      expect(user).to be_admin\n    end\n  end\n\n  context \"when trait is defined as a symbol\" do\n    it \"can be invoked with a string\" do\n      build_user_factory_with_admin_trait(:admin)\n\n      user = FactoryBot.build(:user, \"admin\")\n\n      expect(user).to be_admin\n    end\n\n    it \"can be invoked with a symbol\" do\n      build_user_factory_with_admin_trait(:admin)\n\n      user = FactoryBot.build(:user, :admin)\n\n      expect(user).to be_admin\n    end\n  end\n\n  context \"when trait is defined as integer\" do\n    it \"can be invoked with a string\" do\n      build_user_factory_with_admin_trait(42)\n\n      user = FactoryBot.build(:user, \"42\")\n\n      expect(user).to be_admin\n    end\n\n    it \"can be invoked with as integer\" do\n      build_user_factory_with_admin_trait(42)\n\n      user = FactoryBot.build(:user, 42)\n\n      expect(user).to be_admin\n    end\n  end\n\n  context \"when trait is defined as struct\" do\n    it \"can be invoked with a string\" do\n      instance = Struct.new(:a, :b).new(1, \"x\")\n      build_user_factory_with_admin_trait(instance)\n\n      user = FactoryBot.build(:user, '#<struct a=1, b=\"x\">')\n\n      expect(user).to be_admin\n    end\n\n    it \"can be invoked with a struct\" do\n      instance = Struct.new(:a, :b).new(1, \"x\")\n      build_user_factory_with_admin_trait(instance)\n\n      user = FactoryBot.build(:user, instance)\n\n      expect(user).to be_admin\n    end\n  end\n\n  def build_user_factory_with_admin_trait(trait_name)\n    define_model(\"User\", admin: :boolean)\n\n    FactoryBot.define do\n      factory :user do\n        admin { false }\n\n        trait trait_name do\n          admin { true }\n        end\n      end\n    end\n  end\nend\n\ndescribe \"looking up traits that don't exist\" do\n  context \"when passing an invalid override trait\" do\n    it \"raises a KeyError\" do\n      define_class(\"User\")\n\n      FactoryBot.define do\n        factory :user\n      end\n\n      expect { FactoryBot.build(:user, double(\"not a trait\")) }\n        .to raise_error(KeyError)\n    end\n  end\n\n  context \"when the factory includes an invalid default trait\" do\n    it \"raises a KeyError including the factory name\" do\n      define_class(\"User\")\n\n      FactoryBot.define do\n        factory :user do\n          inaccessible_trait\n        end\n\n        factory :some_other_factory do\n          trait :inaccessible_trait\n        end\n      end\n\n      expect { FactoryBot.build(:user) }.to raise_error(\n        KeyError,\n        'Trait not registered: \"inaccessible_trait\" referenced within \"user\" definition'\n      )\n    end\n\n    it \"maintains 'Did you mean?' suggestions at the end of the error message\" do\n      define_class(\"User\")\n\n      FactoryBot.define do\n        trait :not_quit\n\n        factory :user do\n          not_quite\n        end\n      end\n\n      expect { FactoryBot.build(:user) }.to raise_did_you_mean_error\n    end\n  end\n\n  context \"when a trait includes an invalid default trait\" do\n    it \"raises a KeyError including the factory name\" do\n      define_class(\"User\")\n\n      FactoryBot.define do\n        factory :user do\n          trait :admin do\n            inaccessible_trait\n          end\n        end\n\n        factory :some_other_factory do\n          trait :inaccessible_trait\n        end\n      end\n\n      expect { FactoryBot.build(:user, :admin) }.to raise_error(\n        KeyError,\n        'Trait not registered: \"inaccessible_trait\" referenced within \"admin\" definition'\n      )\n    end\n  end\nend\n\ndescribe \"traits with callbacks\" do\n  before do\n    define_model(\"User\", name: :string)\n\n    FactoryBot.define do\n      factory :user do\n        name { \"John\" }\n\n        trait :great do\n          after(:create) { |user| user.name.upcase! }\n        end\n\n        trait :awesome do\n          after(:create) { |user| user.name = \"awesome\" }\n        end\n\n        factory :caps_user, traits: [:great]\n        factory :awesome_user, traits: [:great, :awesome]\n\n        factory :caps_user_implicit_trait do\n          great\n        end\n      end\n    end\n  end\n\n  context \"when the factory has a trait passed via arguments\" do\n    subject { FactoryBot.create(:caps_user) }\n    its(:name) { should eq \"JOHN\" }\n  end\n\n  context \"when the factory has an implicit trait\" do\n    subject { FactoryBot.create(:caps_user_implicit_trait) }\n    its(:name) { should eq \"JOHN\" }\n  end\n\n  it \"executes callbacks in the order assigned\" do\n    expect(FactoryBot.create(:awesome_user).name).to eq \"awesome\"\n  end\nend\n\ndescribe \"traits added via strategy\" do\n  before do\n    define_model(\"User\", name: :string, admin: :boolean)\n\n    FactoryBot.define do\n      factory :user do\n        name { \"John\" }\n\n        trait :admin do\n          admin { true }\n        end\n\n        trait :great do\n          after(:create) { |user| user.name.upcase! }\n        end\n      end\n    end\n  end\n\n  context \"adding traits in create\" do\n    subject { FactoryBot.create(:user, :admin, :great, name: \"Joe\") }\n\n    its(:admin) { should be true }\n    its(:name) { should eq \"JOE\" }\n\n    it \"doesn't modify the user factory\" do\n      subject\n      expect(FactoryBot.create(:user)).not_to be_admin\n      expect(FactoryBot.create(:user).name).to eq \"John\"\n    end\n  end\n\n  context \"adding traits in build\" do\n    subject { FactoryBot.build(:user, :admin, :great, name: \"Joe\") }\n\n    its(:admin) { should be true }\n    its(:name) { should eq \"Joe\" }\n  end\n\n  context \"adding traits in attributes_for\" do\n    subject { FactoryBot.attributes_for(:user, :admin, :great) }\n\n    its([:admin]) { should be true }\n    its([:name]) { should eq \"John\" }\n  end\n\n  context \"adding traits in build_stubbed\" do\n    subject { FactoryBot.build_stubbed(:user, :admin, :great, name: \"Jack\") }\n\n    its(:admin) { should be true }\n    its(:name) { should eq \"Jack\" }\n  end\n\n  context \"adding traits in create_list\" do\n    subject { FactoryBot.create_list(:user, 2, :admin, :great, name: \"Joe\") }\n\n    its(:length) { should eq 2 }\n\n    it \"creates all the records\" do\n      subject.each do |record|\n        expect(record.admin).to be true\n        expect(record.name).to eq \"JOE\"\n      end\n    end\n  end\n\n  context \"adding traits in build_list\" do\n    subject { FactoryBot.build_list(:user, 2, :admin, :great, name: \"Joe\") }\n\n    its(:length) { should eq 2 }\n\n    it \"builds all the records\" do\n      subject.each do |record|\n        expect(record.admin).to be true\n        expect(record.name).to eq \"Joe\"\n      end\n    end\n  end\nend\n\ndescribe \"traits and dynamic attributes that are applied simultaneously\" do\n  before do\n    define_model(\"User\", name: :string, email: :string, combined: :string)\n\n    FactoryBot.define do\n      trait :email do\n        email { \"#{name}@example.com\" }\n      end\n\n      factory :user do\n        name { \"John\" }\n        email\n        combined { \"#{name} <#{email}>\" }\n      end\n    end\n  end\n\n  subject { FactoryBot.build(:user) }\n  its(:name) { should eq \"John\" }\n  its(:email) { should eq \"John@example.com\" }\n  its(:combined) { should eq \"John <John@example.com>\" }\nend\n\ndescribe \"applying inline traits\" do\n  before do\n    define_model(\"User\") do\n      has_many :posts\n    end\n\n    define_model(\"Post\", user_id: :integer) do\n      belongs_to :user\n    end\n\n    FactoryBot.define do\n      factory :user do\n        trait :with_post do\n          posts { [Post.new] }\n        end\n      end\n    end\n  end\n\n  it \"applies traits only to the instance generated for that call\" do\n    expect(FactoryBot.create(:user, :with_post).posts).not_to be_empty\n    expect(FactoryBot.create(:user).posts).to be_empty\n    expect(FactoryBot.create(:user, :with_post).posts).not_to be_empty\n  end\nend\n\ndescribe \"inline traits overriding existing attributes\" do\n  before do\n    define_model(\"User\", status: :string)\n\n    FactoryBot.define do\n      factory :user do\n        status { \"pending\" }\n\n        trait(:accepted) { status { \"accepted\" } }\n        trait(:declined) { status { \"declined\" } }\n\n        factory :declined_user, traits: [:declined]\n        factory :extended_declined_user, traits: [:declined] do\n          status { \"extended_declined\" }\n        end\n      end\n    end\n  end\n\n  it \"returns the default status\" do\n    expect(FactoryBot.build(:user).status).to eq \"pending\"\n  end\n\n  it \"prefers inline trait attributes over default attributes\" do\n    expect(FactoryBot.build(:user, :accepted).status).to eq \"accepted\"\n  end\n\n  it \"prefers traits on a factory over default attributes\" do\n    expect(FactoryBot.build(:declined_user).status).to eq \"declined\"\n  end\n\n  it \"prefers inline trait attributes over traits on a factory\" do\n    expect(FactoryBot.build(:declined_user, :accepted).status).to eq \"accepted\"\n  end\n\n  it \"prefers attributes on factories over attributes from non-inline traits\" do\n    expect(FactoryBot.build(:extended_declined_user).status).to eq \"extended_declined\"\n  end\n\n  it \"prefers inline traits over attributes on factories\" do\n    expect(FactoryBot.build(:extended_declined_user, :accepted).status).to eq \"accepted\"\n  end\n\n  it \"prefers overridden attributes over attributes from traits, inline traits, or attributes on factories\" do\n    user = FactoryBot.build(:extended_declined_user, :accepted, status: \"completely overridden\")\n\n    expect(user.status).to eq \"completely overridden\"\n  end\nend\n\ndescribe \"making sure the factory is properly compiled the first time we want to instantiate it\" do\n  before do\n    define_model(\"User\", role: :string, gender: :string, age: :integer)\n\n    FactoryBot.define do\n      factory :user do\n        trait(:female) { gender { \"female\" } }\n        trait(:admin) { role { \"admin\" } }\n\n        factory :female_user do\n          female\n        end\n      end\n    end\n  end\n\n  it \"can honor traits on the very first call\" do\n    user = FactoryBot.build(:female_user, :admin, age: 30)\n    expect(user.gender).to eq \"female\"\n    expect(user.age).to eq 30\n    expect(user.role).to eq \"admin\"\n  end\nend\n\ndescribe \"traits with to_create\" do\n  before do\n    define_model(\"User\", name: :string)\n\n    FactoryBot.define do\n      factory :user do\n        trait :with_to_create do\n          to_create { |instance| instance.name = \"to_create\" }\n        end\n\n        factory :sub_user do\n          to_create { |instance| instance.name = \"sub\" }\n\n          factory :child_user\n        end\n\n        factory :sub_user_with_trait do\n          with_to_create\n\n          factory :child_user_with_trait\n        end\n\n        factory :sub_user_with_trait_and_override do\n          with_to_create\n          to_create { |instance| instance.name = \"sub with trait and override\" }\n\n          factory :child_user_with_trait_and_override\n        end\n      end\n    end\n  end\n\n  it \"can apply to_create from traits\" do\n    expect(FactoryBot.create(:user, :with_to_create).name).to eq \"to_create\"\n  end\n\n  it \"can apply to_create from the definition\" do\n    expect(FactoryBot.create(:sub_user).name).to eq \"sub\"\n    expect(FactoryBot.create(:child_user).name).to eq \"sub\"\n  end\n\n  it \"gives additional traits higher priority than to_create from the definition\" do\n    expect(FactoryBot.create(:sub_user, :with_to_create).name).to eq \"to_create\"\n    expect(FactoryBot.create(:child_user, :with_to_create).name).to eq \"to_create\"\n  end\n\n  it \"gives base traits normal priority\" do\n    expect(FactoryBot.create(:sub_user_with_trait).name).to eq \"to_create\"\n    expect(FactoryBot.create(:child_user_with_trait).name).to eq \"to_create\"\n  end\n\n  it \"gives base traits lower priority than overrides\" do\n    expect(FactoryBot.create(:sub_user_with_trait_and_override).name).to eq \"sub with trait and override\"\n    expect(FactoryBot.create(:child_user_with_trait_and_override).name).to eq \"sub with trait and override\"\n  end\n\n  it \"gives additional traits higher priority than base traits and factory definition\" do\n    FactoryBot.define do\n      trait :overridden do\n        to_create { |instance| instance.name = \"completely overridden\" }\n      end\n    end\n\n    sub_user = FactoryBot.create(:sub_user_with_trait_and_override, :overridden)\n    child_user = FactoryBot.create(:child_user_with_trait_and_override, :overridden)\n    expect(sub_user.name).to eq \"completely overridden\"\n    expect(child_user.name).to eq \"completely overridden\"\n  end\nend\n\ndescribe \"traits with initialize_with\" do\n  before do\n    define_class(\"User\") do\n      attr_reader :name\n\n      def initialize(name)\n        @name = name\n      end\n    end\n\n    FactoryBot.define do\n      factory :user do\n        trait :with_initialize_with do\n          initialize_with { new(\"initialize_with\") }\n        end\n\n        factory :sub_user do\n          initialize_with { new(\"sub\") }\n\n          factory :child_user\n        end\n\n        factory :sub_user_with_trait do\n          with_initialize_with\n\n          factory :child_user_with_trait\n        end\n\n        factory :sub_user_with_trait_and_override do\n          with_initialize_with\n          initialize_with { new(\"sub with trait and override\") }\n\n          factory :child_user_with_trait_and_override\n        end\n      end\n    end\n  end\n\n  it \"can apply initialize_with from traits\" do\n    expect(FactoryBot.build(:user, :with_initialize_with).name).to eq \"initialize_with\"\n  end\n\n  it \"can apply initialize_with from the definition\" do\n    expect(FactoryBot.build(:sub_user).name).to eq \"sub\"\n    expect(FactoryBot.build(:child_user).name).to eq \"sub\"\n  end\n\n  it \"gives additional traits higher priority than initialize_with from the definition\" do\n    expect(FactoryBot.build(:sub_user, :with_initialize_with).name).to eq \"initialize_with\"\n    expect(FactoryBot.build(:child_user, :with_initialize_with).name).to eq \"initialize_with\"\n  end\n\n  it \"gives base traits normal priority\" do\n    expect(FactoryBot.build(:sub_user_with_trait).name).to eq \"initialize_with\"\n    expect(FactoryBot.build(:child_user_with_trait).name).to eq \"initialize_with\"\n  end\n\n  it \"gives base traits lower priority than overrides\" do\n    expect(FactoryBot.build(:sub_user_with_trait_and_override).name).to eq \"sub with trait and override\"\n    expect(FactoryBot.build(:child_user_with_trait_and_override).name).to eq \"sub with trait and override\"\n  end\n\n  it \"gives additional traits higher priority than base traits and factory definition\" do\n    FactoryBot.define do\n      trait :overridden do\n        initialize_with { new(\"completely overridden\") }\n      end\n    end\n\n    sub_user = FactoryBot.build(:sub_user_with_trait_and_override, :overridden)\n    child_user = FactoryBot.build(:child_user_with_trait_and_override, :overridden)\n    expect(sub_user.name).to eq \"completely overridden\"\n    expect(child_user.name).to eq \"completely overridden\"\n  end\nend\n\ndescribe \"nested implicit traits\" do\n  before do\n    define_class(\"User\") do\n      attr_accessor :gender, :role\n      attr_reader :name\n\n      def initialize(name)\n        @name = name\n      end\n    end\n  end\n\n  shared_examples_for \"assigning data from traits\" do\n    it \"assigns the correct values\" do\n      user = FactoryBot.create(:user, :female_admin)\n      expect(user.gender).to eq \"FEMALE\"\n      expect(user.role).to eq \"ADMIN\"\n      expect(user.name).to eq \"Jane Doe\"\n    end\n  end\n\n  context \"defined outside the factory\" do\n    before do\n      FactoryBot.define do\n        trait :female do\n          gender { \"female\" }\n          to_create { |instance| instance.gender = instance.gender.upcase }\n        end\n\n        trait :jane_doe do\n          initialize_with { new(\"Jane Doe\") }\n        end\n\n        trait :admin do\n          role { \"admin\" }\n          after(:build) { |instance| instance.role = instance.role.upcase }\n        end\n\n        trait :female_admin do\n          female\n          admin\n          jane_doe\n        end\n\n        factory :user\n      end\n    end\n\n    it_should_behave_like \"assigning data from traits\"\n  end\n\n  context \"defined inside the factory\" do\n    before do\n      FactoryBot.define do\n        factory :user do\n          trait :female do\n            gender { \"female\" }\n            to_create { |instance| instance.gender = instance.gender.upcase }\n          end\n\n          trait :jane_doe do\n            initialize_with { new(\"Jane Doe\") }\n          end\n\n          trait :admin do\n            role { \"admin\" }\n            after(:build) { |instance| instance.role = instance.role.upcase }\n          end\n\n          trait :female_admin do\n            female\n            admin\n            jane_doe\n          end\n        end\n      end\n    end\n\n    it_should_behave_like \"assigning data from traits\"\n  end\nend\n\ndescribe \"implicit traits containing callbacks\" do\n  before do\n    define_model(\"User\", value: :integer)\n\n    FactoryBot.define do\n      factory :user do\n        value { 0 }\n\n        trait :trait_with_callback do\n          after(:build) { |user| user.value += 1 }\n        end\n\n        factory :user_with_trait_with_callback do\n          trait_with_callback\n        end\n      end\n    end\n  end\n\n  it \"only runs the callback once\" do\n    expect(FactoryBot.build(:user_with_trait_with_callback).value).to eq 1\n  end\nend\n\ndescribe \"traits used in associations\" do\n  before do\n    define_model(\"User\", admin: :boolean, name: :string)\n\n    define_model(\"Comment\", user_id: :integer) do\n      belongs_to :user\n    end\n\n    define_model(\"Order\", creator_id: :integer) do\n      belongs_to :creator, class_name: \"User\"\n    end\n\n    define_model(\"Post\", author_id: :integer) do\n      belongs_to :author, class_name: \"User\"\n    end\n\n    FactoryBot.define do\n      factory :user do\n        admin { false }\n\n        trait :admin do\n          admin { true }\n        end\n      end\n\n      factory :post do\n        association :author, factory: [:user, :admin], name: \"John Doe\"\n      end\n\n      factory :comment do\n        association :user, :admin, name: \"Joe Slick\"\n      end\n\n      factory :order do\n        association :creator, :admin, factory: :user, name: \"Joe Creator\"\n      end\n    end\n  end\n\n  it \"allows assigning traits for the factory of an association\" do\n    author = FactoryBot.create(:post).author\n    expect(author).to be_admin\n    expect(author.name).to eq \"John Doe\"\n  end\n\n  it \"allows inline traits with the default association\" do\n    user = FactoryBot.create(:comment).user\n    expect(user).to be_admin\n    expect(user.name).to eq \"Joe Slick\"\n  end\n\n  it \"allows inline traits with a specific factory for an association\" do\n    creator = FactoryBot.create(:order).creator\n    expect(creator).to be_admin\n    expect(creator.name).to eq \"Joe Creator\"\n  end\nend\n\ndescribe \"when a self-referential trait is defined\" do\n  it \"raises a TraitDefinitionError\" do\n    define_model(\"User\", name: :string)\n    FactoryBot.define do\n      factory :user do\n        trait :admin do\n          admin\n        end\n      end\n    end\n\n    expect { FactoryBot.build(:user, :admin) }.to raise_error(\n      FactoryBot::TraitDefinitionError,\n      \"Self-referencing trait 'admin'\"\n    )\n  end\n\n  it \"raises a TraitDefinitionError\" do\n    define_model(\"User\", name: :string)\n    FactoryBot.define do\n      factory :user do\n        trait :admin do\n          admin\n          name { \"name\" }\n        end\n      end\n    end\n\n    expect { FactoryBot.build(:user, :admin) }.to raise_error(\n      FactoryBot::TraitDefinitionError,\n      \"Self-referencing trait 'admin'\"\n    )\n  end\nend\n"
  },
  {
    "path": "spec/acceptance/transient_attributes_spec.rb",
    "content": "describe \"transient attributes\" do\n  before do\n    define_model(\"User\", name: :string, email: :string)\n\n    FactoryBot.define do\n      sequence(:name) { |n| \"John #{n}\" }\n\n      factory :user do\n        transient do\n          four { 2 + 2 }\n          rockstar { true }\n          upcased { false }\n        end\n\n        name { \"#{FactoryBot.generate(:name)}#{\" - Rockstar\" if rockstar}\" }\n        email { \"#{name.downcase}#{four}@example.com\" }\n\n        after(:create) do |user, evaluator|\n          user.name.upcase! if evaluator.upcased\n        end\n      end\n    end\n  end\n\n  context \"returning attributes for a factory\" do\n    subject { FactoryBot.attributes_for(:user, rockstar: true) }\n    it { should_not have_key(:four) }\n    it { should_not have_key(:rockstar) }\n    it { should_not have_key(:upcased) }\n    it { should have_key(:name) }\n    it { should have_key(:email) }\n  end\n\n  context \"with a transient variable assigned\" do\n    let(:rockstar) { FactoryBot.create(:user, rockstar: true, four: \"1234\") }\n    let(:rockstar_with_name) { FactoryBot.create(:user, name: \"Jane Doe\", rockstar: true) }\n    let(:upcased_rockstar) { FactoryBot.create(:user, rockstar: true, upcased: true) }\n    let(:groupie) { FactoryBot.create(:user, rockstar: false) }\n\n    it \"generates the correct attributes on a rockstar\" do\n      expect(rockstar.name).to eq \"John 1 - Rockstar\"\n      expect(rockstar.email).to eq \"john 1 - rockstar1234@example.com\"\n    end\n\n    it \"generates the correct attributes on an upcased rockstar\" do\n      expect(upcased_rockstar.name).to eq \"JOHN 1 - ROCKSTAR\"\n      expect(upcased_rockstar.email).to eq \"john 1 - rockstar4@example.com\"\n    end\n\n    it \"generates the correct attributes on a groupie\" do\n      expect(groupie.name).to eq \"John 1\"\n      expect(groupie.email).to eq \"john 14@example.com\"\n    end\n\n    it \"generates the correct attributes on a rockstar with a name\" do\n      expect(rockstar_with_name.name).to eq \"Jane Doe\"\n      expect(rockstar_with_name.email).to eq \"jane doe4@example.com\"\n    end\n  end\n\n  context \"without transient variables assigned\" do\n    let(:rockstar) { FactoryBot.create(:user) }\n\n    it \"uses the default value of the attribute\" do\n      expect(rockstar.name).to eq \"John 1 - Rockstar\"\n    end\n  end\nend\n\ndescribe \"transient sequences\" do\n  before do\n    define_model(\"User\", name: :string)\n\n    FactoryBot.define do\n      factory :user do\n        transient do\n          sequence(:counter)\n        end\n\n        name { \"John Doe #{counter}\" }\n      end\n    end\n  end\n\n  it \"increments sequences correctly\" do\n    expect(FactoryBot.build(:user).name).to eq \"John Doe 1\"\n    expect(FactoryBot.build(:user).name).to eq \"John Doe 2\"\n  end\nend\n\ndescribe \"assigning values from a transient attribute\" do\n  before do\n    define_class(\"User\") do\n      attr_accessor :foo_id, :foo_name\n    end\n\n    define_class(\"Foo\") do\n      attr_accessor :id, :name\n      def initialize(id, name)\n        @id = id\n        @name = name\n      end\n    end\n\n    FactoryBot.define do\n      factory :user do\n        transient do\n          foo { Foo.new(\"id-of-foo\", \"name-of-foo\") }\n        end\n\n        foo_id { foo.id }\n        foo_name { foo.name }\n      end\n    end\n  end\n\n  it \"does not ignore an _id attribute that is an alias for a transient attribute\" do\n    user = FactoryBot.build(:user, foo: Foo.new(\"passed-in-id-of-foo\", \"passed-in-name-of-foo\"))\n    expect(user.foo_id).to eq \"passed-in-id-of-foo\"\n    expect(user.foo_name).to eq \"passed-in-name-of-foo\"\n  end\nend\n"
  },
  {
    "path": "spec/factory_bot/aliases_spec.rb",
    "content": "describe FactoryBot, \"aliases\" do\n  it \"for an attribute should include the original attribute and a version suffixed with '_id'\" do\n    aliases = FactoryBot.aliases_for(:test)\n\n    expect(aliases).to include(:test, :test_id)\n  end\n\n  it \"for a foreign key should include both the suffixed and un-suffixed variants\" do\n    aliases = FactoryBot.aliases_for(:test_id)\n\n    expect(aliases).to include(:test, :test_id)\n  end\n\n  it \"for an attribute which starts with an underscore should not include a non-underscored version\" do\n    aliases = FactoryBot.aliases_for(:_id)\n\n    expect(aliases).not_to include(:id)\n  end\nend\n\ndescribe FactoryBot, \"after defining an alias\" do\n  it \"the list of aliases should include a variant with no suffix at all, and one with an '_id' suffix\" do\n    FactoryBot.aliases << [/(.*)_suffix/, '\\1']\n    aliases = FactoryBot.aliases_for(:test_suffix)\n\n    expect(aliases).to include(:test, :test_suffix_id)\n  end\nend\n"
  },
  {
    "path": "spec/factory_bot/attribute/association_spec.rb",
    "content": "describe FactoryBot::Attribute::Association do\n  let(:name) { :author }\n  let(:factory) { :user }\n  let(:overrides) { {first_name: \"John\"} }\n  let(:association) { double(\"association\") }\n\n  subject { FactoryBot::Attribute::Association.new(name, factory, overrides) }\n\n  before do\n    # Define an '#association' instance method allowing it to be mocked.\n    # Usually this is determined via '#method_missing'\n    missing_methods = Module.new {\n      def association(*args)\n      end\n    }\n    subject.extend(missing_methods)\n\n    allow(subject)\n      .to receive(:association).with(any_args).and_return association\n  end\n\n  it { should be_association }\n  its(:name) { should eq name }\n\n  it \"builds the association when calling the proc\" do\n    expect(subject.to_proc.call).to eq association\n  end\n\n  it \"builds the association when calling the proc\" do\n    subject.to_proc.call\n    expect(subject).to have_received(:association).with(factory, overrides)\n  end\nend\n\ndescribe FactoryBot::Attribute::Association, \"with a string name\" do\n  subject { FactoryBot::Attribute::Association.new(\"name\", :user, {}) }\n  its(:name) { should eq :name }\nend\n"
  },
  {
    "path": "spec/factory_bot/attribute/dynamic_spec.rb",
    "content": "describe FactoryBot::Attribute::Dynamic do\n  let(:name) { :first_name }\n  let(:block) { -> {} }\n\n  subject { FactoryBot::Attribute::Dynamic.new(name, false, block) }\n\n  its(:name) { should eq name }\n\n  context \"with a block returning a static value\" do\n    let(:block) { -> { \"value\" } }\n\n    it \"returns the value when executing the proc\" do\n      expect(subject.to_proc.call).to eq \"value\"\n    end\n  end\n\n  context \"with a block returning its block-level variable\" do\n    let(:block) { ->(thing) { thing } }\n\n    it \"returns self when executing the proc\" do\n      expect(subject.to_proc.call).to eq subject\n    end\n  end\n\n  context \"with a block referencing an attribute on the attribute\" do\n    let(:block) { -> { attribute_defined_on_attribute } }\n    let(:result) { \"other attribute value\" }\n\n    before do\n      # Define an '#attribute_defined_on_attribute' instance method allowing it\n      # be mocked. Usually this is determined via '#method_missing'\n      missing_methods = Module.new {\n        def attribute_defined_on_attribute(*args)\n        end\n      }\n      subject.extend(missing_methods)\n\n      allow(subject)\n        .to receive(:attribute_defined_on_attribute).and_return result\n    end\n\n    it \"evaluates the attribute from the attribute\" do\n      expect(subject.to_proc.call).to eq result\n    end\n  end\n\n  context \"with a block returning a sequence\" do\n    let(:block) do\n      -> do\n        FactoryBot::Internal.register_sequence(\n          FactoryBot::Sequence.new(:email, 1) { |n| \"foo#{n}\" }\n        )\n      end\n    end\n\n    it \"raises a sequence abuse error\" do\n      expect { subject.to_proc.call }.to raise_error(FactoryBot::SequenceAbuseError)\n    end\n  end\nend\n\ndescribe FactoryBot::Attribute::Dynamic, \"with a string name\" do\n  subject { FactoryBot::Attribute::Dynamic.new(\"name\", false, -> {}) }\n  its(:name) { should eq :name }\nend\n"
  },
  {
    "path": "spec/factory_bot/attribute/sequence_spec.rb",
    "content": "describe FactoryBot::Attribute::Sequence do\n  let(:sequence_name) { :name }\n  let(:name) { :first_name }\n  let(:sequence) { FactoryBot::Sequence.new(sequence_name, 5) { |n| \"Name #{n}\" } }\n\n  subject { FactoryBot::Attribute::Sequence.new(name, sequence_name, false) }\n  before { FactoryBot::Internal.register_sequence(sequence) }\n\n  its(:name) { should eq name }\n\n  it \"assigns the next value in the sequence\" do\n    expect(subject.to_proc.call).to eq \"Name 5\"\n  end\nend\n"
  },
  {
    "path": "spec/factory_bot/attribute_assignment_spec.rb",
    "content": "describe \"Attribute Assignment\" do\n  it \"sets the <attribute> default value if not overridden\" do\n    name = :user\n    define_class(\"User\") { attr_accessor :name, :response }\n    factory = FactoryBot::Factory.new(name)\n    FactoryBot::Internal.register_factory(factory)\n\n    attr_1 = FactoryBot::Declaration::Dynamic.new(:name, false, -> { \"orig name\" })\n    attr_2 = FactoryBot::Declaration::Dynamic.new(:response, false, -> { \"orig response\" })\n    factory.declare_attribute(attr_1)\n    factory.declare_attribute(attr_2)\n\n    user = factory.run(FactoryBot::Strategy::Build, {})\n\n    expect(user.name).to eq \"orig name\"\n    expect(user.response).to eq \"orig response\"\n  end\n\n  it \"sets the <attribute> when directly named\" do\n    name = :user\n    define_class(\"User\") { attr_accessor :name, :response }\n    factory = FactoryBot::Factory.new(name)\n    FactoryBot::Internal.register_factory(factory)\n\n    attr_1 = FactoryBot::Declaration::Dynamic.new(:name, false, -> { \"orig name\" })\n    attr_2 = FactoryBot::Declaration::Dynamic.new(:response, false, -> { \"orig response\" })\n    factory.declare_attribute(attr_1)\n    factory.declare_attribute(attr_2)\n\n    user = factory.run(\n      FactoryBot::Strategy::Build,\n      name: \"new name\",\n      response: \"new response\"\n    )\n\n    expect(user.name).to eq \"new name\"\n    expect(user.response).to eq \"new response\"\n  end\nend\n"
  },
  {
    "path": "spec/factory_bot/attribute_list_spec.rb",
    "content": "module AttributeList\n  def build_attribute_list(*attributes)\n    FactoryBot::AttributeList.new.tap do |list|\n      attributes.each { |attribute| list.define_attribute(attribute) }\n    end\n  end\nend\n\ndescribe FactoryBot::AttributeList, \"#define_attribute\" do\n  it \"maintains a list of attributes\" do\n    attribute = double(:attribute, name: :attribute_name)\n    another_attribute = double(:attribute, name: :another_attribute_name)\n    list = FactoryBot::AttributeList.new\n\n    list.define_attribute(attribute)\n    expect(list.to_a).to eq [attribute]\n\n    list.define_attribute(another_attribute)\n    expect(list.to_a).to eq [attribute, another_attribute]\n  end\n\n  it \"returns the attribute\" do\n    attribute = double(:attribute, name: :attribute_name)\n    list = FactoryBot::AttributeList.new\n\n    expect(list.define_attribute(attribute)).to eq attribute\n  end\n\n  it \"raises if an attribute has already been defined\" do\n    attribute = double(:attribute, name: :attribute_name)\n    list = FactoryBot::AttributeList.new\n\n    expect {\n      2.times { list.define_attribute(attribute) }\n    }.to raise_error(\n      FactoryBot::AttributeDefinitionError,\n      \"Attribute already defined: attribute_name\"\n    )\n  end\nend\n\ndescribe FactoryBot::AttributeList, \"#define_attribute with a named attribute list\" do\n  it \"raises when the attribute is a self-referencing association\" do\n    association_with_same_name = FactoryBot::Attribute::Association.new(:author, :author, {})\n    list = FactoryBot::AttributeList.new(:author)\n\n    expect {\n      list.define_attribute(association_with_same_name)\n    }.to raise_error(\n      FactoryBot::AssociationDefinitionError,\n      \"Self-referencing association 'author' in 'author'\"\n    )\n  end\n\n  it \"does not raise when the attribute is not a self-referencing association\" do\n    association_with_different_name = FactoryBot::Attribute::Association.new(:author, :post, {})\n    list = FactoryBot::AttributeList.new\n\n    expect { list.define_attribute(association_with_different_name) }.to_not raise_error\n  end\nend\n\ndescribe FactoryBot::AttributeList, \"#apply_attributes\" do\n  include AttributeList\n\n  it \"adds attributes in the order defined\" do\n    attribute1 = double(:attribute1, name: :attribute1)\n    attribute2 = double(:attribute2, name: :attribute2)\n    list = FactoryBot::AttributeList.new\n\n    list.define_attribute(attribute1)\n    list.apply_attributes(build_attribute_list(attribute2))\n    expect(list.to_a).to eq [attribute1, attribute2]\n  end\nend\n\ndescribe FactoryBot::AttributeList, \"#associations\" do\n  include AttributeList\n\n  it \"returns associations\" do\n    email_attribute = FactoryBot::Attribute::Dynamic.new(\n      :email,\n      false,\n      ->(u) { \"#{u.full_name}@example.com\" }\n    )\n    author_attribute = FactoryBot::Attribute::Association.new(:author, :user, {})\n    profile_attribute = FactoryBot::Attribute::Association.new(:profile, :profile, {})\n    list = build_attribute_list(email_attribute, author_attribute, profile_attribute)\n\n    expect(list.associations.to_a).to eq [author_attribute, profile_attribute]\n  end\nend\n\ndescribe FactoryBot::AttributeList, \"filter based on ignored attributes\" do\n  include AttributeList\n\n  def build_ignored_attribute(name)\n    FactoryBot::Attribute::Dynamic.new(name, true, -> { \"value\" })\n  end\n\n  def build_non_ignored_attribute(name)\n    FactoryBot::Attribute::Dynamic.new(name, false, -> { \"value\" })\n  end\n\n  it \"filters #ignored attributes\" do\n    list = build_attribute_list(\n      build_ignored_attribute(:comments_count),\n      build_non_ignored_attribute(:email)\n    )\n\n    expect(list.ignored.names).to eq [:comments_count]\n  end\n\n  it \"filters #non_ignored attributes\" do\n    list = build_attribute_list(\n      build_ignored_attribute(:comments_count),\n      build_non_ignored_attribute(:email)\n    )\n\n    expect(list.non_ignored.names).to eq [:email]\n  end\nend\n\ndescribe FactoryBot::AttributeList, \"generating names\" do\n  include AttributeList\n\n  def build_ignored_attribute(name)\n    FactoryBot::Attribute::Dynamic.new(name, true, -> { \"value\" })\n  end\n\n  def build_non_ignored_attribute(name)\n    FactoryBot::Attribute::Dynamic.new(name, false, -> { \"value\" })\n  end\n\n  def build_association(name)\n    FactoryBot::Attribute::Association.new(name, :user, {})\n  end\n\n  it \"knows all its #names\" do\n    list = build_attribute_list(\n      build_ignored_attribute(:comments_count),\n      build_non_ignored_attribute(:last_name),\n      build_association(:avatar)\n    )\n\n    expect(list.names).to eq [:comments_count, :last_name, :avatar]\n  end\n\n  it \"knows all its #names for #ignored attributes\" do\n    list = build_attribute_list(\n      build_ignored_attribute(:posts_count),\n      build_non_ignored_attribute(:last_name),\n      build_association(:avatar)\n    )\n\n    expect(list.ignored.names).to eq [:posts_count]\n  end\n\n  it \"knows all its #names for #non_ignored attributes\" do\n    list = build_attribute_list(\n      build_ignored_attribute(:posts_count),\n      build_non_ignored_attribute(:last_name),\n      build_association(:avatar)\n    )\n\n    expect(list.non_ignored.names).to eq [:last_name, :avatar]\n  end\n\n  it \"knows all its #names for #associations\" do\n    list = build_attribute_list(\n      build_ignored_attribute(:posts_count),\n      build_non_ignored_attribute(:last_name),\n      build_association(:avatar)\n    )\n\n    expect(list.associations.names).to eq [:avatar]\n  end\nend\n"
  },
  {
    "path": "spec/factory_bot/attribute_spec.rb",
    "content": "describe FactoryBot::Attribute do\n  it \"converts the name attribute to a symbol\" do\n    name = \"user\"\n    attribute = FactoryBot::Attribute.new(name, false)\n\n    expect(attribute.name).to eq name.to_sym\n  end\n\n  it \"is not an association\" do\n    name = \"user\"\n    attribute = FactoryBot::Attribute.new(name, false)\n\n    expect(attribute).not_to be_association\n  end\nend\n"
  },
  {
    "path": "spec/factory_bot/callback_spec.rb",
    "content": "describe FactoryBot::Callback do\n  it \"has a name\" do\n    expect(FactoryBot::Callback.new(:after_create, -> {}).name).to eq :after_create\n  end\n\n  it \"converts strings to symbols\" do\n    expect(FactoryBot::Callback.new(\"after_create\", -> {}).name).to eq :after_create\n  end\n\n  it \"runs its block with no parameters\" do\n    ran_with = nil\n    FactoryBot::Callback.new(:after_create, -> { ran_with = [] }).run(:one, :two)\n    expect(ran_with).to eq []\n  end\n\n  it \"runs its block with one parameter\" do\n    ran_with = nil\n    FactoryBot::Callback.new(:after_create, ->(one) { ran_with = [one] }).run(:one, :two)\n    expect(ran_with).to eq [:one]\n  end\n\n  it \"runs its block with two parameters\" do\n    ran_with = nil\n    FactoryBot::Callback.new(:after_create, ->(one, two) { ran_with = [one, two] }).run(:one, :two)\n    expect(ran_with).to eq [:one, :two]\n  end\nend\n"
  },
  {
    "path": "spec/factory_bot/declaration/association_spec.rb",
    "content": "describe FactoryBot::Declaration::Association do\n  describe \"#==\" do\n    context \"when the attributes are equal\" do\n      it \"the objects are equal\" do\n        declaration = described_class.new(:name, options: true)\n        other_declaration = described_class.new(:name, options: true)\n\n        expect(declaration).to eq(other_declaration)\n      end\n    end\n\n    context \"when the names are different\" do\n      it \"the objects are NOT equal\" do\n        declaration = described_class.new(:name, options: true)\n        other_declaration = described_class.new(:other_name, options: true)\n\n        expect(declaration).not_to eq(other_declaration)\n      end\n    end\n\n    context \"when the options are different\" do\n      it \"the objects are NOT equal\" do\n        declaration = described_class.new(:name, options: true)\n        other_declaration = described_class.new(:name, other_options: true)\n\n        expect(declaration).not_to eq(other_declaration)\n      end\n    end\n\n    context \"when comparing against another type of object\" do\n      it \"the objects are NOT equal\" do\n        declaration = described_class.new(:name)\n\n        expect(declaration).not_to eq(:not_a_declaration)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/factory_bot/declaration/dynamic_spec.rb",
    "content": "describe FactoryBot::Declaration::Dynamic do\n  describe \"#==\" do\n    context \"when the attributes are equal\" do\n      it \"the objects are equal\" do\n        block = -> {}\n        declaration = described_class.new(:name, false, block)\n        other_declaration = described_class.new(:name, false, block)\n\n        expect(declaration).to eq(other_declaration)\n      end\n    end\n\n    context \"when the names are different\" do\n      it \"the objects are NOT equal\" do\n        block = -> {}\n        declaration = described_class.new(:name, false, block)\n        other_declaration = described_class.new(:other_name, false, block)\n\n        expect(declaration).not_to eq(other_declaration)\n      end\n    end\n\n    context \"when the blocks are different\" do\n      it \"the objects are NOT equal\" do\n        declaration = described_class.new(:name, false, -> {})\n        other_declaration = described_class.new(:name, false, -> {})\n\n        expect(declaration).not_to eq(other_declaration)\n      end\n    end\n\n    context \"when one is ignored and the other isn't\" do\n      it \"the objects are NOT equal\" do\n        block = -> {}\n        declaration = described_class.new(:name, false, block)\n        other_declaration = described_class.new(:name, true, block)\n\n        expect(declaration).not_to eq(other_declaration)\n      end\n    end\n\n    context \"when comparing against another type of object\" do\n      it \"the objects are NOT equal\" do\n        declaration = described_class.new(:name, false, -> {})\n\n        expect(declaration).not_to eq(:not_a_declaration)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/factory_bot/declaration/implicit_spec.rb",
    "content": "describe FactoryBot::Declaration::Implicit do\n  context \"with a known factory\" do\n    it \"creates an association attribute\" do\n      allow(FactoryBot.factories).to receive(:registered?).and_return true\n\n      declaration = FactoryBot::Declaration::Implicit.new(:name)\n      attribute = declaration.to_attributes.first\n\n      expect(attribute).to be_association\n    end\n\n    it \"has the correct factory name\" do\n      allow(FactoryBot.factories).to receive(:registered?).and_return true\n      name = :factory_name\n\n      declaration = FactoryBot::Declaration::Implicit.new(name)\n      attribute = declaration.to_attributes.first\n\n      expect(attribute.factory).to eq(name)\n    end\n  end\n\n  context \"with a known sequence\" do\n    it \"does not create an association attribute\" do\n      allow(FactoryBot::Internal.sequences).to receive(:registered?).and_return true\n\n      declaration = FactoryBot::Declaration::Implicit.new(:name)\n      attribute = declaration.to_attributes.first\n\n      expect(attribute).not_to be_association\n    end\n\n    it \"creates a sequence attribute\" do\n      allow(FactoryBot::Internal.sequences).to receive(:registered?).and_return true\n\n      declaration = FactoryBot::Declaration::Implicit.new(:name)\n      attribute = declaration.to_attributes.first\n\n      expect(attribute).to be_a(FactoryBot::Attribute::Sequence)\n    end\n  end\n\n  describe \"#==\" do\n    context \"when the attributes are equal\" do\n      it \"the objects are equal\" do\n        declaration = described_class.new(:name, :factory, false)\n        other_declaration = described_class.new(:name, :factory, false)\n\n        expect(declaration).to eq(other_declaration)\n      end\n    end\n\n    context \"when the names are different\" do\n      it \"the objects are NOT equal\" do\n        declaration = described_class.new(:name, :factory, false)\n        other_declaration = described_class.new(:other_name, :factory, false)\n\n        expect(declaration).not_to eq(other_declaration)\n      end\n    end\n\n    context \"when the factories are different\" do\n      it \"the objects are NOT equal\" do\n        declaration = described_class.new(:name, :factory, false)\n        other_declaration = described_class.new(:name, :other_factory, false)\n\n        expect(declaration).not_to eq(other_declaration)\n      end\n    end\n\n    context \"when one is ignored and the other isn't\" do\n      it \"the objects are NOT equal\" do\n        declaration = described_class.new(:name, :factory, false)\n        other_declaration = described_class.new(:name, :factory, true)\n\n        expect(declaration).not_to eq(other_declaration)\n      end\n    end\n\n    context \"when comparing against another type of object\" do\n      it \"the objects are NOT equal\" do\n        declaration = described_class.new(:name, :factory, false)\n\n        expect(declaration).not_to eq(:not_a_declaration)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/factory_bot/declaration_list_spec.rb",
    "content": "describe FactoryBot::DeclarationList, \"#attributes\" do\n  it \"returns an AttributeList\" do\n    declaration_list = FactoryBot::DeclarationList.new\n\n    expect(declaration_list.attributes).to be_a(FactoryBot::AttributeList)\n  end\n\n  it \"defines each attribute on the attribute list\" do\n    attribute1 = double(\"attribute 1\")\n    attribute2 = double(\"attribute 2\")\n    attribute3 = double(\"attribute 3\")\n    declaration1 = double(\"declaration 1\", to_attributes: [attribute1, attribute2])\n    declaration2 = double(\"declaration2\", to_attributes: [attribute3])\n    attribute_list = double(\"attribute list\", define_attribute: true)\n    declaration_list = FactoryBot::DeclarationList.new\n\n    allow(FactoryBot::AttributeList).to receive(:new).and_return attribute_list\n\n    declaration_list.declare_attribute(declaration1)\n    declaration_list.declare_attribute(declaration2)\n\n    declaration_list.attributes\n\n    expect(attribute_list).to have_received(:define_attribute).with(attribute1)\n    expect(attribute_list).to have_received(:define_attribute).with(attribute2)\n    expect(attribute_list).to have_received(:define_attribute).with(attribute3)\n  end\nend\n\ndescribe FactoryBot::DeclarationList, \"#declare_attribute\" do\n  it \"adds the declaration to the list when not overridable\" do\n    declaration1 = double(\"declaration\", name: \"declaration 1\")\n    declaration2 = double(\"declaration\", name: \"declaration 2\")\n    declaration_list = FactoryBot::DeclarationList.new\n\n    declaration_list.declare_attribute(declaration1)\n    expect(declaration_list.to_a).to eq [declaration1]\n\n    declaration_list.declare_attribute(declaration2)\n    expect(declaration_list.to_a).to eq [declaration1, declaration2]\n  end\n\n  it \"adds the declaration to the list when overridable\" do\n    declaration1 = double(\"declaration\", name: \"declaration 1\")\n    declaration2 = double(\"declaration\", name: \"declaration 2\")\n    declaration_list = FactoryBot::DeclarationList.new\n    declaration_list.overridable\n\n    declaration_list.declare_attribute(declaration1)\n    expect(declaration_list.to_a).to eq [declaration1]\n\n    declaration_list.declare_attribute(declaration2)\n    expect(declaration_list.to_a).to eq [declaration1, declaration2]\n  end\n\n  it \"deletes declarations with the same name when overridable\" do\n    declaration1 = double(\"declaration\", name: \"declaration 1\")\n    declaration2 = double(\"declaration\", name: \"declaration 2\")\n    declaration_with_same_name = double(\"declaration\", name: \"declaration 1\")\n    declaration_list = FactoryBot::DeclarationList.new\n    declaration_list.overridable\n\n    declaration_list.declare_attribute(declaration1)\n    expect(declaration_list.to_a).to eq [declaration1]\n\n    declaration_list.declare_attribute(declaration2)\n    expect(declaration_list.to_a).to eq [declaration1, declaration2]\n\n    declaration_list.declare_attribute(declaration_with_same_name)\n    expect(declaration_list.to_a).to eq [declaration2, declaration_with_same_name]\n  end\n\n  it \"appends declarations with the same name when NOT overridable\" do\n    declaration1 = double(\"declaration\", name: \"declaration 1\")\n    declaration2 = double(\"declaration\", name: \"declaration 2\")\n    declaration_with_same_name = double(\"declaration\", name: \"declaration 1\")\n\n    # DeclarationList's `@overridable` attr is set to false by default\n    declaration_list = FactoryBot::DeclarationList.new\n\n    declaration_list.declare_attribute(declaration1)\n    expect(declaration_list.to_a).to eq [declaration1]\n\n    declaration_list.declare_attribute(declaration2)\n    expect(declaration_list.to_a).to eq [declaration1, declaration2]\n\n    declaration_list.declare_attribute(declaration_with_same_name)\n    expect(declaration_list.to_a).to eq [declaration1, declaration2, declaration_with_same_name]\n  end\nend\n"
  },
  {
    "path": "spec/factory_bot/decorator/attribute_hash_spec.rb",
    "content": "describe FactoryBot::Decorator::AttributeHash do\n  describe \"#attributes\" do\n    it \"returns a hash of attributes\" do\n      attributes = {attribute_1: :value, attribute_2: :value}\n      component = double(:component, attributes)\n\n      decorator = described_class.new(component, [:attribute_1, :attribute_2])\n\n      expect(decorator.attributes).to eq(attributes)\n    end\n\n    context \"with an attribute called 'attributes'\" do\n      it \"does not call itself recursively\" do\n        attributes = {attributes: :value}\n        component = double(:component, attributes)\n\n        decorator = described_class.new(component, [:attributes])\n\n        expect(decorator.attributes).to eq(attributes)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/factory_bot/definition_proxy_spec.rb",
    "content": "describe FactoryBot::DefinitionProxy, \"#add_attribute\" do\n  it \"declares a dynamic attribute on the factory when the proxy respects attributes\" do\n    definition = FactoryBot::Definition.new(:name)\n    proxy = FactoryBot::DefinitionProxy.new(definition)\n    attribute_value = -> { \"dynamic attribute\" }\n    proxy.add_attribute(:attribute_name, &attribute_value)\n\n    expect(definition).to have_dynamic_declaration(:attribute_name)\n      .with_value(attribute_value)\n  end\n\n  it \"declares a dynamic attribute on the factory when the proxy ignores attributes\" do\n    definition = FactoryBot::Definition.new(:name)\n    proxy = FactoryBot::DefinitionProxy.new(definition, true)\n    attribute_value = -> { \"dynamic attribute\" }\n    proxy.add_attribute(:attribute_name, &attribute_value)\n    expect(definition).to have_dynamic_declaration(:attribute_name)\n      .ignored\n      .with_value(attribute_value)\n  end\nend\n\ndescribe FactoryBot::DefinitionProxy, \"#transient\" do\n  it \"makes all attributes added ignored\" do\n    definition = FactoryBot::Definition.new(:name)\n    proxy = FactoryBot::DefinitionProxy.new(definition)\n    attribute_value = -> { \"dynamic_attribute\" }\n    proxy.transient do\n      add_attribute(:attribute_name, &attribute_value)\n    end\n\n    expect(definition).to have_dynamic_declaration(:attribute_name)\n      .ignored\n      .with_value(attribute_value)\n  end\nend\n\ndescribe FactoryBot::DefinitionProxy, \"#method_missing\" do\n  it \"declares an implicit declaration when called without args or a block\" do\n    definition = FactoryBot::Definition.new(:name)\n    proxy = FactoryBot::DefinitionProxy.new(definition)\n    proxy.bogus\n\n    expect(definition).to have_implicit_declaration(:bogus).with_factory(definition)\n  end\n\n  it \"declares an association when called with a ':factory' key\" do\n    definition = FactoryBot::Definition.new(:name)\n    proxy = FactoryBot::DefinitionProxy.new(definition)\n    proxy.author factory: :user\n\n    expect(definition).to have_association_declaration(:author)\n      .with_options(factory: :user)\n  end\n\n  it \"declares a dynamic attribute when called with a block\" do\n    definition = FactoryBot::Definition.new(:name)\n    proxy = FactoryBot::DefinitionProxy.new(definition)\n    attribute_value = -> { \"dynamic attribute\" }\n    proxy.attribute_name(&attribute_value)\n\n    expect(definition).to have_dynamic_declaration(:attribute_name)\n      .with_value(attribute_value)\n  end\n\n  it \"raises a NoMethodError when called with a static-attribute-like argument\" do\n    definition = FactoryBot::Definition.new(:broken)\n    proxy = FactoryBot::DefinitionProxy.new(definition)\n    invalid_call = -> { proxy.static_attributes_are_gone \"true\" }\n\n    expect(&invalid_call).to raise_error(\n      NoMethodError,\n      /'static_attributes_are_gone'.*'broken' factory.*Did you mean\\? 'static_attributes_are_gone \\{ \"true\" \\}'/m\n    )\n  end\nend\n\ndescribe FactoryBot::DefinitionProxy, \"#sequence\" do\n  def build_proxy(factory_name)\n    definition = FactoryBot::Definition.new(factory_name)\n    FactoryBot::DefinitionProxy.new(definition)\n  end\n\n  it \"creates a new sequence starting at 1\" do\n    allow(FactoryBot::Sequence).to receive(:new).and_call_original\n    proxy = build_proxy(:factory)\n\n    proxy.sequence(:sequence)\n\n    expect(FactoryBot::Sequence).to have_received(:new).with(:sequence, {uri_paths: []})\n  end\n\n  it \"creates a new sequence with an overridden starting value\" do\n    allow(FactoryBot::Sequence).to receive(:new).and_call_original\n    proxy = build_proxy(:factory)\n    override = \"override\"\n\n    proxy.sequence(:sequence, override)\n\n    expect(FactoryBot::Sequence).to have_received(:new)\n      .with(:sequence, override, {uri_paths: []})\n  end\n\n  it \"creates a new sequence with a block\" do\n    allow(FactoryBot::Sequence).to receive(:new).and_call_original\n    sequence_block = proc { |n| \"user+#{n}@example.com\" }\n    proxy = build_proxy(:factory)\n    proxy.sequence(:sequence, 1, &sequence_block)\n\n    expect(FactoryBot::Sequence).to have_received(:new)\n      .with(:sequence, 1, {uri_paths: []}, &sequence_block)\n  end\nend\n\ndescribe FactoryBot::DefinitionProxy, \"#association\" do\n  it \"declares an association\" do\n    definition = FactoryBot::Definition.new(:definition_name)\n    proxy = FactoryBot::DefinitionProxy.new(definition)\n\n    proxy.association(:association_name)\n\n    expect(definition).to have_association_declaration(:association_name)\n  end\n\n  it \"declares an association with options\" do\n    definition = FactoryBot::Definition.new(:definition_name)\n    proxy = FactoryBot::DefinitionProxy.new(definition)\n\n    proxy.association(:association_name, name: \"Awesome\")\n\n    expect(definition).to have_association_declaration(:association_name)\n      .with_options(name: \"Awesome\")\n  end\n\n  it \"when passing a block raises an error\" do\n    definition = FactoryBot::Definition.new(:post)\n    proxy = FactoryBot::DefinitionProxy.new(definition)\n\n    expect { proxy.association(:author) {} }\n      .to raise_error(\n        FactoryBot::AssociationDefinitionError,\n        \"Unexpected block passed to 'author' association in 'post' factory\"\n      )\n  end\nend\n\ndescribe FactoryBot::DefinitionProxy, \"adding callbacks\" do\n  it \"adding a :before_all callback succeeds\" do\n    definition = FactoryBot::Definition.new(:name)\n    proxy = FactoryBot::DefinitionProxy.new(definition)\n    callback = -> { \"my awesome callback!\" }\n\n    proxy.before(:all, &callback)\n\n    expect(definition).to have_callback(:before_all).with_block(callback)\n  end\n\n  it \"adding an :after_all callback succeeds\" do\n    definition = FactoryBot::Definition.new(:name)\n    proxy = FactoryBot::DefinitionProxy.new(definition)\n    callback = -> { \"my awesome callback!\" }\n\n    proxy.after(:all, &callback)\n\n    expect(definition).to have_callback(:after_all).with_block(callback)\n  end\n\n  it \"adding an :after_build callback succeeds\" do\n    definition = FactoryBot::Definition.new(:name)\n    proxy = FactoryBot::DefinitionProxy.new(definition)\n    callback = -> { \"my awesome callback!\" }\n\n    proxy.after(:build, &callback)\n\n    expect(definition).to have_callback(:after_build).with_block(callback)\n  end\n\n  it \"adding an :after_create callback succeeds\" do\n    definition = FactoryBot::Definition.new(:name)\n    proxy = FactoryBot::DefinitionProxy.new(definition)\n    callback = -> { \"my awesome callback!\" }\n\n    proxy.after(:create, &callback)\n\n    expect(definition).to have_callback(:after_create).with_block(callback)\n  end\n\n  it \"adding an :after_stub callback succeeds\" do\n    definition = FactoryBot::Definition.new(:name)\n    proxy = FactoryBot::DefinitionProxy.new(definition)\n    callback = -> { \"my awesome callback!\" }\n\n    proxy.after(:stub, &callback)\n    expect(definition).to have_callback(:after_stub).with_block(callback)\n  end\n\n  it \"adding both an :after_stub and an :after_create callback succeeds\" do\n    definition = FactoryBot::Definition.new(:name)\n    proxy = FactoryBot::DefinitionProxy.new(definition)\n    callback = -> { \"my awesome callback!\" }\n\n    proxy.after(:stub, :create, &callback)\n\n    expect(definition).to have_callback(:after_stub).with_block(callback)\n    expect(definition).to have_callback(:after_create).with_block(callback)\n  end\n\n  it \"adding both a :before_stub and a :before_create callback succeeds\" do\n    definition = FactoryBot::Definition.new(:name)\n    proxy = FactoryBot::DefinitionProxy.new(definition)\n    callback = -> { \"my awesome callback!\" }\n\n    proxy.before(:stub, :create, &callback)\n\n    expect(definition).to have_callback(:before_stub).with_block(callback)\n    expect(definition).to have_callback(:before_create).with_block(callback)\n  end\n\n  it \"adding both an :after_stub and a :before_create callback succeeds\" do\n    definition = FactoryBot::Definition.new(:name)\n    proxy = FactoryBot::DefinitionProxy.new(definition)\n    callback = -> { \"my awesome callback!\" }\n\n    proxy.callback(:after_stub, :before_create, &callback)\n\n    expect(definition).to have_callback(:after_stub).with_block(callback)\n    expect(definition).to have_callback(:before_create).with_block(callback)\n  end\nend\n\ndescribe FactoryBot::DefinitionProxy, \"#to_create\" do\n  it \"accepts a block to run in place of #save!\" do\n    definition = FactoryBot::Definition.new(:name)\n    proxy = FactoryBot::DefinitionProxy.new(definition)\n    to_create_block = ->(record) { record.persist }\n    proxy.to_create(&to_create_block)\n\n    expect(definition.to_create).to eq to_create_block\n  end\nend\n\ndescribe FactoryBot::DefinitionProxy, \"#factory\" do\n  it \"without options\" do\n    definition = FactoryBot::Definition.new(:name)\n    proxy = FactoryBot::DefinitionProxy.new(definition)\n    proxy.factory(:child)\n\n    expect(proxy.child_factories).to include([:child, {}, nil])\n  end\n\n  it \"with options\" do\n    definition = FactoryBot::Definition.new(:name)\n    proxy = FactoryBot::DefinitionProxy.new(definition)\n    proxy.factory(:child, awesome: true)\n\n    expect(proxy.child_factories).to include([:child, {awesome: true}, nil])\n  end\n\n  it \"with a block\" do\n    definition = FactoryBot::Definition.new(:name)\n    proxy = FactoryBot::DefinitionProxy.new(definition)\n    child_block = -> {}\n    proxy.factory(:child, {}, &child_block)\n\n    expect(proxy.child_factories).to include([:child, {}, child_block])\n  end\nend\n\ndescribe FactoryBot::DefinitionProxy, \"#trait\" do\n  it \"declares a trait\" do\n    definition = FactoryBot::Definition.new(:name)\n    proxy = FactoryBot::DefinitionProxy.new(definition)\n    male_trait = proc { gender { \"Male\" } }\n    proxy.trait(:male, &male_trait)\n\n    expect(definition).to have_trait(:male).with_block(male_trait)\n  end\nend\n\ndescribe FactoryBot::DefinitionProxy, \"#initialize_with\" do\n  it \"defines the constructor on the definition\" do\n    definition = FactoryBot::Definition.new(:name)\n    proxy = FactoryBot::DefinitionProxy.new(definition)\n    constructor = proc { [] }\n    proxy.initialize_with(&constructor)\n\n    expect(definition.constructor).to eq constructor\n  end\nend\n"
  },
  {
    "path": "spec/factory_bot/definition_spec.rb",
    "content": "describe FactoryBot::Definition do\n  it \"delegates :declare_attribute to declarations\" do\n    definition = described_class.new(:name)\n\n    expect(definition).to delegate(:declare_attribute).to(:declarations)\n  end\n\n  it \"creates a new attribute list with the name passed when given a name\" do\n    name = \"great name\"\n    allow(FactoryBot::DeclarationList).to receive(:new)\n\n    FactoryBot::Definition.new(name)\n\n    expect(FactoryBot::DeclarationList).to have_received(:new).with(name)\n  end\n\n  it \"has a name\" do\n    name = \"factory name\"\n    definition = described_class.new(name)\n\n    expect(definition.name).to eq(name)\n  end\n\n  it \"has an overridable declaration list\" do\n    list = double(\"declaration list\", overridable: true)\n    allow(FactoryBot::DeclarationList).to receive(:new).and_return list\n    definition = described_class.new(:name)\n\n    expect(definition.overridable).to eq definition\n    expect(list).to have_received(:overridable).once\n  end\n\n  it \"maintains a list of traits\" do\n    trait1 = double(:trait)\n    trait2 = double(:trait)\n    definition = described_class.new(:name)\n    definition.define_trait(trait1)\n    definition.define_trait(trait2)\n\n    expect(definition.defined_traits).to include(trait1, trait2)\n  end\n\n  it \"adds only unique traits\" do\n    trait1 = double(:trait)\n    definition = described_class.new(:name)\n    definition.define_trait(trait1)\n    definition.define_trait(trait1)\n\n    expect(definition.defined_traits.size).to eq 1\n  end\n\n  it \"maintains a list of callbacks\" do\n    callback1 = \"callback1\"\n    callback2 = \"callback2\"\n    definition = described_class.new(:name)\n    definition.add_callback(callback1)\n    definition.add_callback(callback2)\n\n    expect(definition.callbacks).to eq [callback1, callback2]\n  end\n\n  it \"doesn't expose a separate create strategy when none is specified\" do\n    definition = described_class.new(:name)\n\n    expect(definition.to_create).to be_nil\n  end\n\n  it \"exposes a non-default create strategy when one is provided by the user\" do\n    definition = described_class.new(:name)\n    block = proc {}\n    definition.to_create(&block)\n\n    expect(definition.to_create).to eq block\n  end\n\n  it \"maintains a list of enum fields\" do\n    definition = described_class.new(:name)\n\n    enum_field = double(\"enum_field\")\n\n    definition.register_enum(enum_field)\n\n    expect(definition.registered_enums).to include(enum_field)\n  end\nend\n"
  },
  {
    "path": "spec/factory_bot/disallows_duplicates_registry_spec.rb",
    "content": "describe FactoryBot::Decorator::DisallowsDuplicatesRegistry do\n  it \"delegates #register to the registry when not registered\" do\n    registry = double(\"registry\", name: \"Great thing\", register: true)\n    decorator = FactoryBot::Decorator::DisallowsDuplicatesRegistry.new(registry)\n    allow(registry).to receive(:registered?).and_return false\n    decorator.register(:awesome, {})\n\n    expect(registry).to have_received(:register).with(:awesome, {})\n  end\n\n  it \"raises when attempting to #register a previously registered strategy\" do\n    registry = double(\"registry\", name: \"Great thing\", register: true)\n    decorator = FactoryBot::Decorator::DisallowsDuplicatesRegistry.new(registry)\n    allow(registry).to receive(:registered?).and_return true\n\n    expect { decorator.register(:same_name, {}) }\n      .to raise_error(FactoryBot::DuplicateDefinitionError, \"Great thing already registered: same_name\")\n  end\nend\n"
  },
  {
    "path": "spec/factory_bot/evaluator_class_definer_spec.rb",
    "content": "describe FactoryBot::EvaluatorClassDefiner do\n  it \"returns an evaluator when accessing the evaluator class\" do\n    evaluator = define_evaluator(parent_class: FactoryBot::Evaluator)\n\n    expect(evaluator).to be_a(FactoryBot::Evaluator)\n  end\n\n  it \"adds each attribute to the evaluator\" do\n    attribute = stub_attribute(:attribute) { 1 }\n    evaluator = define_evaluator(attributes: [attribute])\n\n    expect(evaluator.attribute).to eq 1\n  end\n\n  it \"evaluates the block in the context of the evaluator\" do\n    dependency_attribute = stub_attribute(:dependency) { 1 }\n    attribute = stub_attribute(:attribute) { dependency + 1 }\n    evaluator = define_evaluator(attributes: [dependency_attribute, attribute])\n\n    expect(evaluator.attribute).to eq 2\n  end\n\n  it \"only instance_execs the block once even when returning nil\" do\n    count = 0\n    attribute = stub_attribute(:attribute) {\n      count += 1\n      nil\n    }\n    evaluator = define_evaluator(attributes: [attribute])\n\n    2.times { evaluator.attribute }\n\n    expect(count).to eq 1\n  end\n\n  it \"sets attributes on the evaluator class\" do\n    attributes = [stub_attribute, stub_attribute]\n    evaluator = define_evaluator(attributes: attributes)\n\n    expect(evaluator.attribute_lists).to eq [attributes]\n  end\n\n  context \"with a custom evaluator as a parent class\" do\n    it \"bases its attribute lists on itself and its parent evaluator\" do\n      parent_attributes = [stub_attribute, stub_attribute]\n      parent_evaluator_class = define_evaluator_class(attributes: parent_attributes)\n      child_attributes = [stub_attribute, stub_attribute]\n      child_evaluator = define_evaluator(\n        attributes: child_attributes,\n        parent_class: parent_evaluator_class\n      )\n\n      expect(child_evaluator.attribute_lists).to eq [parent_attributes, child_attributes]\n    end\n  end\n\n  def define_evaluator(arguments = {})\n    evaluator_class = define_evaluator_class(arguments)\n    evaluator_class.new(FactoryBot::Strategy::Null)\n  end\n\n  def define_evaluator_class(arguments = {})\n    evaluator_class_definer = FactoryBot::EvaluatorClassDefiner.new(\n      arguments[:attributes] || [],\n      arguments[:parent_class] || FactoryBot::Evaluator\n    )\n    evaluator_class_definer.evaluator_class\n  end\n\n  def stub_attribute(name = :attribute, &value)\n    value ||= -> {}\n    double(name.to_s, name: name.to_sym, to_proc: value)\n  end\nend\n"
  },
  {
    "path": "spec/factory_bot/factory_spec.rb",
    "content": "describe FactoryBot::Factory do\n  it \"has a factory name\" do\n    name = :user\n    factory = FactoryBot::Factory.new(name)\n    FactoryBot::Internal.register_factory(factory)\n\n    expect(factory.name).to eq name\n  end\n\n  it \"has a build class\" do\n    name = :user\n    klass = define_class(\"User\")\n    factory = FactoryBot::Factory.new(name)\n    FactoryBot::Internal.register_factory(factory)\n\n    expect(factory.build_class).to eq klass\n  end\n\n  it \"returns associations\" do\n    define_class(\"Post\")\n    factory = FactoryBot::Factory.new(:post)\n    FactoryBot::Internal.register_factory(FactoryBot::Factory.new(:admin))\n    factory.declare_attribute(FactoryBot::Declaration::Association.new(:author, {}))\n    factory.declare_attribute(FactoryBot::Declaration::Association.new(:editor, {}))\n    factory.declare_attribute(FactoryBot::Declaration::Implicit.new(:admin, factory))\n    factory.associations.each do |association|\n      expect(association).to be_association\n    end\n    expect(factory.associations.to_a.length).to eq 3\n  end\n\n  it \"includes associations from the parent factory\" do\n    association_on_parent = FactoryBot::Declaration::Association.new(:association_on_parent, {})\n    association_on_child = FactoryBot::Declaration::Association.new(:association_on_child, {})\n\n    define_class(\"Post\")\n    factory = FactoryBot::Factory.new(:post)\n    factory.declare_attribute(association_on_parent)\n    FactoryBot::Internal.register_factory(factory)\n\n    child_factory = FactoryBot::Factory.new(:child_post, parent: :post)\n    child_factory.declare_attribute(association_on_child)\n\n    expect(child_factory.associations.map(&:name)).to eq [:association_on_parent, :association_on_child]\n  end\n\n  describe \"when overriding generated attributes with a hash\" do\n    it \"returns the overridden value in the generated attributes\" do\n      name = :name\n      value = \"The price is right!\"\n      hash = {name => value}\n      define_class(\"Name\")\n      factory = FactoryBot::Factory.new(name)\n      declaration =\n        FactoryBot::Declaration::Dynamic.new(name, false, -> { flunk })\n      factory.declare_attribute(declaration)\n      result = factory.run(FactoryBot::Strategy::AttributesFor, hash)\n      expect(result[name]).to eq value\n    end\n\n    it \"overrides a symbol parameter with a string parameter\" do\n      name = :name\n      define_class(\"Name\")\n      value = \"The price is right!\"\n      factory = FactoryBot::Factory.new(name)\n      FactoryBot::Internal.register_factory(factory)\n      declaration =\n        FactoryBot::Declaration::Dynamic.new(name, false, -> { flunk })\n      factory.declare_attribute(declaration)\n      hash = {name.to_s => value}\n      result = factory.run(FactoryBot::Strategy::AttributesFor, hash)\n\n      expect(result[name]).to eq value\n    end\n  end\n\n  describe \"overriding an attribute with an alias\" do\n    it \"uses the passed in value for the alias\" do\n      name = :user\n      define_class(\"User\")\n      factory = FactoryBot::Factory.new(name)\n      FactoryBot::Internal.register_factory(factory)\n      attribute = FactoryBot::Declaration::Dynamic.new(\n        :test,\n        false, -> { \"original\" }\n      )\n      factory.declare_attribute(attribute)\n      FactoryBot.aliases << [/(.*)_alias/, '\\1']\n      result = factory.run(\n        FactoryBot::Strategy::AttributesFor,\n        test_alias: \"new\"\n      )\n\n      expect(result[:test_alias]).to eq \"new\"\n    end\n\n    it \"discards the predefined value for the attribute\" do\n      name = :user\n      define_class(\"User\")\n      factory = FactoryBot::Factory.new(name)\n      FactoryBot::Internal.register_factory(factory)\n      attribute = FactoryBot::Declaration::Dynamic.new(\n        :test,\n        false, -> { \"original\" }\n      )\n      factory.declare_attribute(attribute)\n      FactoryBot.aliases << [/(.*)_alias/, '\\1']\n      result = factory.run(\n        FactoryBot::Strategy::AttributesFor,\n        test_alias: \"new\"\n      )\n\n      expect(result[:test]).to be_nil\n    end\n  end\n\n  it \"guesses the build class from the factory name\" do\n    name = :user\n    define_class(\"User\")\n    factory = FactoryBot::Factory.new(name)\n    FactoryBot::Internal.register_factory(factory)\n\n    expect(factory.build_class).to eq User\n  end\n\n  it \"creates a new factory using the class of the parent\" do\n    name = :user\n    define_class(\"User\")\n    factory = FactoryBot::Factory.new(name)\n    FactoryBot::Internal.register_factory(factory)\n\n    child = FactoryBot::Factory.new(:child, parent: factory.name)\n    child.compile\n    expect(child.build_class).to eq factory.build_class\n  end\n\n  it \"creates a new factory while overriding the parent class\" do\n    name = :user\n    define_class(\"User\")\n    factory = FactoryBot::Factory.new(name)\n    FactoryBot::Internal.register_factory(factory)\n\n    child = FactoryBot::Factory.new(:child, class: String, parent: factory.name)\n    child.compile\n    expect(child.build_class).to eq String\n  end\nend\n\ndescribe FactoryBot::Factory, \"when defined with a custom class\" do\n  it \"is an instance of that custom class\" do\n    factory = FactoryBot::Factory.new(:author, class: Float)\n    expect(factory.build_class).to eq Float\n  end\nend\n\ndescribe FactoryBot::Factory, \"when given a class that overrides #to_s\" do\n  it \"sets build_class correctly\" do\n    define_class(\"Overriding\")\n    define_class(\"Overriding::Class\") do\n      def self.to_s\n        \"Overriding\"\n      end\n    end\n    overriding_class = Overriding::Class\n    factory = FactoryBot::Factory.new(:overriding_class, class: Overriding::Class)\n\n    expect(factory.build_class).to eq overriding_class\n  end\nend\n\ndescribe FactoryBot::Factory, \"when defined with a class instead of a name\" do\n  it \"has a name\" do\n    klass = ArgumentError\n    name = :argument_error\n    factory = FactoryBot::Factory.new(klass)\n\n    expect(factory.name).to eq name\n  end\n\n  it \"has a build_class\" do\n    klass = ArgumentError\n    factory = FactoryBot::Factory.new(klass)\n\n    expect(factory.build_class).to eq klass\n  end\nend\n\ndescribe FactoryBot::Factory, \"when defined with a custom class name\" do\n  it \"has a build_class equal to its custom class name\" do\n    factory = FactoryBot::Factory.new(:author, class: :argument_error)\n\n    expect(factory.build_class).to eq ArgumentError\n  end\nend\n\ndescribe FactoryBot::Factory, \"with a name ending in s\" do\n  it \"has a name\" do\n    factory = FactoryBot::Factory.new(:business)\n\n    expect(factory.name).to eq :business\n  end\n\n  it \"has a build class\" do\n    define_class(\"Business\")\n    factory = FactoryBot::Factory.new(:business)\n\n    expect(factory.build_class).to eq Business\n  end\nend\n\ndescribe FactoryBot::Factory, \"with a string for a name\" do\n  it \"has a name\" do\n    name = :string\n    factory = FactoryBot::Factory.new(name.to_s)\n\n    expect(factory.name).to eq name\n  end\n\n  it \"sets build_class correctly with a class with an underscore\" do\n    name = :settings\n    define_class(\"Admin_Settings_1\")\n    settings_class = Admin_Settings_1\n    factory = FactoryBot::Factory.new(name, class: \"Admin_Settings_1\")\n\n    expect(factory.build_class).to eq settings_class\n  end\nend\n\ndescribe FactoryBot::Factory, \"for namespaced class\" do\n  it \"sets build_class correctly with a namespaced class with Namespace::Class syntax\" do\n    name = :settings\n    define_class(\"Admin\")\n    define_class(\"Admin::Settings\")\n    settings_class = Admin::Settings\n    factory = FactoryBot::Factory.new(name, class: \"Admin::Settings\")\n\n    expect(factory.build_class).to eq settings_class\n  end\n\n  it \"sets build_class correctly with a namespaced class with namespace/class syntax\" do\n    name = :settings\n    define_class(\"Admin\")\n    define_class(\"Admin::Settings\")\n    settings_class = Admin::Settings\n    factory = FactoryBot::Factory.new(name, class: \"admin/settings\")\n\n    expect(factory.build_class).to eq settings_class\n  end\nend\n\ndescribe FactoryBot::Factory, \"human names\" do\n  it \"parses names without underscores\" do\n    factory = FactoryBot::Factory.new(:user)\n\n    expect(factory.names).to eq [:user]\n  end\n\n  it \"parses human names without underscores\" do\n    factory = FactoryBot::Factory.new(:user)\n\n    expect(factory.human_names).to eq [\"user\"]\n  end\n\n  it \"parses names with underscores\" do\n    factory = FactoryBot::Factory.new(:happy_user)\n\n    expect(factory.names).to eq [:happy_user]\n  end\n\n  it \"parses human names with underscores\" do\n    factory = FactoryBot::Factory.new(:happy_user)\n\n    expect(factory.human_names).to eq [\"happy user\"]\n  end\n\n  it \"parses names with big letters\" do\n    factory = FactoryBot::Factory.new(:LoL)\n\n    expect(factory.names).to eq [:LoL]\n  end\n\n  it \"parses human names with big letters\" do\n    factory = FactoryBot::Factory.new(:LoL)\n\n    expect(factory.human_names).to eq [\"lol\"]\n  end\n\n  it \"parses names with aliases\" do\n    factory = FactoryBot::Factory.new(:happy_user, aliases: [:gleeful_user, :person])\n\n    expect(factory.names).to eq [:happy_user, :gleeful_user, :person]\n  end\n\n  it \"parses human names with aliases\" do\n    factory = FactoryBot::Factory.new(:happy_user, aliases: [:gleeful_user, :person])\n\n    expect(factory.human_names).to eq [\"happy user\", \"gleeful user\", \"person\"]\n  end\nend\n\ndescribe FactoryBot::Factory, \"running a factory\" do\n  def build_factory\n    attribute = FactoryBot::Attribute::Dynamic.new(:name, false, -> { \"value\" })\n    attributes = [attribute]\n    declaration = FactoryBot::Declaration::Dynamic.new(:name, false, -> { \"value\" })\n    strategy = double(\"strategy\", result: \"result\")\n    define_model(\"User\", name: :string)\n    allow(FactoryBot::Declaration::Dynamic).to receive(:new)\n      .and_return declaration\n    allow(declaration).to receive(:to_attributes).and_return attributes\n    allow(FactoryBot::Strategy::Build).to receive(:new).and_return strategy\n    factory = FactoryBot::Factory.new(:user)\n    factory.declare_attribute(declaration)\n    factory\n  end\n\n  it \"creates the right strategy using the build class when running\" do\n    factory = build_factory\n    factory.run(FactoryBot::Strategy::Build, {})\n\n    expect(FactoryBot::Strategy::Build).to have_received(:new).once\n  end\n\n  it \"returns the result from the strategy when running\" do\n    factory = build_factory\n\n    expect(factory.run(FactoryBot::Strategy::Build, {})).to eq \"result\"\n  end\n\n  it \"calls the block and returns the result\" do\n    factory = build_factory\n\n    block_run = nil\n    block = ->(_result) { block_run = \"changed\" }\n    factory.run(FactoryBot::Strategy::Build, {}, &block)\n    expect(block_run).to eq \"changed\"\n  end\nend\n"
  },
  {
    "path": "spec/factory_bot/find_definitions_spec.rb",
    "content": "require \"fileutils\"\n\nshared_examples_for \"finds definitions\" do\n  before do\n    allow(FactoryBot).to receive(:load)\n    FactoryBot.find_definitions\n  end\n\n  subject { FactoryBot }\nend\n\nRSpec::Matchers.define :load_definitions_from do |file|\n  match do |given|\n    @has_received = have_received(:load).with(File.expand_path(file))\n    @has_received.matches?(given)\n  end\n\n  description do\n    \"load definitions from #{file}\"\n  end\n\n  failure_message do\n    @has_received.failure_message\n  end\nend\n\ndescribe \"definition loading\" do\n  def self.in_directory_with_files(*files)\n    before do\n      @pwd = Dir.pwd\n      @tmp_dir = File.join(File.dirname(__FILE__), \"tmp\")\n      FileUtils.mkdir_p @tmp_dir\n      Dir.chdir(@tmp_dir)\n\n      files.each do |file|\n        FileUtils.mkdir_p File.dirname(file)\n        FileUtils.touch file\n      end\n    end\n\n    after do\n      Dir.chdir(@pwd)\n      FileUtils.rm_rf(@tmp_dir)\n    end\n  end\n\n  describe \"with factories.rb\" do\n    in_directory_with_files \"factories.rb\"\n    it_should_behave_like \"finds definitions\" do\n      it { should load_definitions_from(\"factories.rb\") }\n    end\n  end\n\n  %w[spec test].each do |dir|\n    describe \"with a factories file under #{dir}\" do\n      in_directory_with_files File.join(dir, \"factories.rb\")\n      it_should_behave_like \"finds definitions\" do\n        it { should load_definitions_from(\"#{dir}/factories.rb\") }\n      end\n    end\n\n    describe \"with a factories file under #{dir}/factories\" do\n      in_directory_with_files File.join(dir, \"factories\", \"post_factory.rb\")\n      it_should_behave_like \"finds definitions\" do\n        it { should load_definitions_from(\"#{dir}/factories/post_factory.rb\") }\n      end\n    end\n\n    describe \"with several factories files under #{dir}/factories\" do\n      in_directory_with_files File.join(dir, \"factories\", \"post_factory.rb\"),\n        File.join(dir, \"factories\", \"person_factory.rb\")\n      it_should_behave_like \"finds definitions\" do\n        it { should load_definitions_from(\"#{dir}/factories/post_factory.rb\") }\n        it { should load_definitions_from(\"#{dir}/factories/person_factory.rb\") }\n      end\n    end\n\n    describe \"with several factories files under #{dir}/factories in non-alphabetical order\" do\n      in_directory_with_files File.join(dir, \"factories\", \"b.rb\"),\n        File.join(dir, \"factories\", \"a.rb\")\n      it \"loads the files in the right order\" do\n        allow(FactoryBot).to receive(:load)\n        wd = File.dirname(__FILE__)\n        file_b = File.join(wd, \"tmp\", dir, \"factories\", \"b.rb\")\n        file_a = File.join(wd, \"tmp\", dir, \"factories\", \"a.rb\")\n\n        FactoryBot.find_definitions\n\n        expect(FactoryBot).to have_received(:load).with(file_a).ordered\n        expect(FactoryBot).to have_received(:load).with(file_b).ordered\n      end\n    end\n\n    describe \"with nested and unnested factories files under #{dir}\" do\n      in_directory_with_files File.join(dir, \"factories.rb\"),\n        File.join(dir, \"factories\", \"post_factory.rb\"),\n        File.join(dir, \"factories\", \"person_factory.rb\")\n      it_should_behave_like \"finds definitions\" do\n        it { should load_definitions_from(\"#{dir}/factories.rb\") }\n        it { should load_definitions_from(\"#{dir}/factories/post_factory.rb\") }\n        it { should load_definitions_from(\"#{dir}/factories/person_factory.rb\") }\n      end\n    end\n\n    describe \"with deeply nested factory files under #{dir}\" do\n      in_directory_with_files File.join(dir, \"factories\", \"subdirectory\", \"post_factory.rb\"),\n        File.join(dir, \"factories\", \"subdirectory\", \"person_factory.rb\")\n      it_should_behave_like \"finds definitions\" do\n        it { should load_definitions_from(\"#{dir}/factories/subdirectory/post_factory.rb\") }\n        it { should load_definitions_from(\"#{dir}/factories/subdirectory/person_factory.rb\") }\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/factory_bot/internal_spec.rb",
    "content": "describe FactoryBot::Internal do\n  describe \".register_trait\" do\n    it \"registers the provided trait\" do\n      trait = FactoryBot::Trait.new(:admin)\n      configuration = FactoryBot::Internal.configuration\n\n      expect { FactoryBot::Internal.register_trait(trait) }\n        .to change { configuration.traits.count }\n        .from(0)\n        .to(1)\n    end\n\n    it \"returns the registered trait\" do\n      trait = FactoryBot::Trait.new(:admin)\n\n      expect(FactoryBot::Internal.register_trait(trait)).to eq trait\n    end\n  end\n\n  describe \".trait_by_name\" do\n    it \"finds a previously registered trait\" do\n      trait = FactoryBot::Trait.new(:admin)\n      klass = instance_double(\"klass\")\n      FactoryBot::Internal.register_trait(trait)\n\n      expect(trait.klass).to be_nil\n      expect(FactoryBot::Internal.trait_by_name(trait.name, klass)).to eq trait\n      expect(trait.klass).to eq klass\n    end\n  end\n\n  describe \".register_sequence\" do\n    it \"registers the provided sequence\" do\n      sequence = FactoryBot::Sequence.new(:email)\n      configuration = FactoryBot::Internal.configuration\n\n      expect { FactoryBot::Internal.register_sequence(sequence) }\n        .to change { configuration.sequences.count }\n        .from(0)\n        .to(1)\n    end\n\n    it \"returns the registered sequence\" do\n      sequence = FactoryBot::Sequence.new(:email)\n\n      expect(FactoryBot::Internal.register_sequence(sequence)).to eq sequence\n    end\n  end\n\n  describe \".sequence_by_name\" do\n    it \"finds a registered sequence\" do\n      sequence = FactoryBot::Sequence.new(:email)\n      FactoryBot::Internal.register_sequence(sequence)\n\n      expect(FactoryBot::Internal.sequence_by_name(sequence.name)).to eq sequence\n    end\n  end\n\n  describe \".rewind_sequences\" do\n    it \"rewinds the sequences and the internal sequences\" do\n      sequence = instance_double(FactoryBot::Sequence, names: [\"email\"])\n      allow(sequence).to receive(:rewind)\n      FactoryBot::Internal.register_sequence(sequence)\n\n      inline_sequence = instance_double(FactoryBot::Sequence)\n      allow(inline_sequence).to receive(:rewind)\n      FactoryBot::Internal.register_inline_sequence(inline_sequence)\n\n      FactoryBot::Internal.rewind_sequences\n\n      expect(sequence).to have_received(:rewind).exactly(:once)\n      expect(inline_sequence).to have_received(:rewind).exactly(:once)\n    end\n  end\n\n  describe \".register_factory\" do\n    it \"registers the provided factory\" do\n      factory = FactoryBot::Factory.new(:object)\n      configuration = FactoryBot::Internal.configuration\n\n      expect { FactoryBot::Internal.register_factory(factory) }\n        .to change { configuration.factories.count }\n        .from(0)\n        .to(1)\n    end\n\n    it \"returns the registered factory\" do\n      factory = FactoryBot::Factory.new(:object)\n\n      expect(FactoryBot::Internal.register_factory(factory)).to eq factory\n    end\n  end\n\n  describe \".factory_by_name\" do\n    it \"finds a registered factory\" do\n      factory = FactoryBot::Factory.new(:object)\n      FactoryBot::Internal.register_factory(factory)\n\n      expect(FactoryBot::Internal.factory_by_name(factory.name)).to eq factory\n    end\n  end\n\n  describe \".register_factory\" do\n    it \"registers the provided factory\" do\n      factory = FactoryBot::Factory.new(:object)\n      configuration = FactoryBot::Internal.configuration\n      expect { FactoryBot::Internal.register_factory(factory) }\n        .to change { configuration.factories.count }\n        .from(0)\n        .to(1)\n    end\n\n    it \"returns the registered factory\" do\n      factory = FactoryBot::Factory.new(:object)\n      expect(FactoryBot::Internal.register_factory(factory)).to eq factory\n    end\n  end\n\n  describe \".factory_by_name\" do\n    it \"finds a registered factory\" do\n      factory = FactoryBot::Factory.new(:object)\n      FactoryBot::Internal.register_factory(factory)\n      expect(FactoryBot::Internal.factory_by_name(factory.name)).to eq factory\n    end\n  end\n\n  describe \".register_strategy\" do\n    it \"register the provided strategy name with the class\" do\n      configuration = FactoryBot::Internal.configuration\n      initial_strategies_count = configuration.strategies.count\n      expect {\n        FactoryBot::Internal.register_strategy(:strategy_name, :strategy_class)\n      }.to change { configuration.strategies.count }\n        .from(initial_strategies_count)\n        .to(initial_strategies_count + 1)\n    end\n  end\n\n  describe \".strategy_by_name\" do\n    it \"finds a registered strategy\" do\n      FactoryBot::Internal.register_strategy(:strategy_name, :strategy_class)\n      expect(FactoryBot::Internal.strategy_by_name(:strategy_name))\n        .to eq :strategy_class\n    end\n  end\nend\n"
  },
  {
    "path": "spec/factory_bot/null_factory_spec.rb",
    "content": "describe FactoryBot::NullFactory do\n  it \"delegates defined traits to its definition\" do\n    null_factory = FactoryBot::NullFactory.new\n\n    expect(null_factory).to delegate(:defined_traits).to(:definition)\n  end\n\n  it \"delegates callbacks to its definition\" do\n    null_factory = FactoryBot::NullFactory.new\n\n    expect(null_factory).to delegate(:callbacks).to(:definition)\n  end\n\n  it \"delegates attributes to its definition\" do\n    null_factory = FactoryBot::NullFactory.new\n\n    expect(null_factory).to delegate(:attributes).to(:definition)\n  end\n\n  it \"delegates constructor to its definition\" do\n    null_factory = FactoryBot::NullFactory.new\n\n    expect(null_factory).to delegate(:constructor).to(:definition)\n  end\n\n  it \"has a nil value for its compile attribute\" do\n    null_factory = FactoryBot::NullFactory.new\n\n    expect(null_factory.compile).to be_nil\n  end\n\n  it \"has a nil value for its class_name attribute\" do\n    null_factory = FactoryBot::NullFactory.new\n\n    expect(null_factory.class_name).to be_nil\n  end\n\n  it \"has an instance of FactoryBot::AttributeList for its attributes attribute\" do\n    null_factory = FactoryBot::NullFactory.new\n\n    expect(null_factory.attributes).to be_an_instance_of(FactoryBot::AttributeList)\n  end\n\n  it \"has FactoryBot::Evaluator as its evaluator class\" do\n    null_factory = FactoryBot::NullFactory.new\n\n    expect(null_factory.evaluator_class).to eq FactoryBot::Evaluator\n  end\nend\n"
  },
  {
    "path": "spec/factory_bot/null_object_spec.rb",
    "content": "describe FactoryBot::NullObject do\n  it \"responds to the given methods\" do\n    methods_to_respond_to = %w[id age name admin?]\n    null_object = FactoryBot::NullObject.new(methods_to_respond_to)\n\n    methods_to_respond_to.each do |method_name|\n      expect(null_object.__send__(method_name)).to be_nil\n      expect(null_object).to respond_to(method_name)\n    end\n  end\n\n  it \"does not respond to other methods\" do\n    methods_to_respond_to = %w[id age name admin?]\n    methods_to_not_respond_to = %w[email date_of_birth title]\n    null_object = FactoryBot::NullObject.new(methods_to_respond_to)\n\n    methods_to_not_respond_to.each do |method_name|\n      expect { null_object.__send__(method_name) }.to raise_error(NoMethodError)\n      expect(null_object).not_to respond_to(method_name)\n    end\n  end\nend\n"
  },
  {
    "path": "spec/factory_bot/registry_spec.rb",
    "content": "describe FactoryBot::Registry do\n  it \"is an enumerable\" do\n    registry = FactoryBot::Registry.new(\"Great thing\")\n\n    expect(registry).to be_kind_of(Enumerable)\n  end\n\n  it \"finds a registered object\" do\n    registry = FactoryBot::Registry.new(\"Great thing\")\n    registered_object = double(\"registered object\")\n    registry.register(:object_name, registered_object)\n\n    expect(registry.find(:object_name)).to eq registered_object\n  end\n\n  it \"finds a registered object with square brackets\" do\n    registry = FactoryBot::Registry.new(\"Great thing\")\n    registered_object = double(\"registered object\")\n    registry.register(:object_name, registered_object)\n\n    expect(registry[:object_name]).to eq registered_object\n  end\n\n  it \"raises when an object cannot be found\" do\n    registry = FactoryBot::Registry.new(\"Great thing\")\n\n    expect { registry.find(:object_name) }\n      .to raise_error(KeyError, \"Great thing not registered: \\\"object_name\\\"\")\n  end\n\n  it \"includes a did_you_mean message\" do\n    registry = FactoryBot::Registry.new(:registry)\n    registered_object = double(:registered_object)\n    registry.register(:factory_bot, registered_object)\n\n    expect { registry.find(:factory_bit) }.to raise_did_you_mean_error\n  end\n\n  it \"adds and returns the object registered\" do\n    registry = FactoryBot::Registry.new(\"Great thing\")\n    registered_object = double(\"registered object\")\n\n    expect(registry.register(:object_name, registered_object)).to eq registered_object\n  end\n\n  it \"knows that an object is registered by symbol\" do\n    registry = FactoryBot::Registry.new(\"Great thing\")\n    registered_object = double(\"registered object\")\n    registry.register(:object_name, registered_object)\n\n    expect(registry).to be_registered(:object_name)\n  end\n\n  it \"knows that an object is registered by string\" do\n    registry = FactoryBot::Registry.new(\"Great thing\")\n    registered_object = double(\"registered object\")\n    registry.register(:object_name, registered_object)\n\n    expect(registry).to be_registered(\"object_name\")\n  end\n\n  it \"knows when an object is not registered\" do\n    registry = FactoryBot::Registry.new(\"Great thing\")\n\n    expect(registry).not_to be_registered(\"bogus\")\n  end\n\n  it \"iterates registered objects\" do\n    registry = FactoryBot::Registry.new(\"Great thing\")\n    registered_object = double(\"registered object\")\n    second_registered_object = double(\"second registered object\")\n    registry.register(:first_object, registered_object)\n    registry.register(:second_object, second_registered_object)\n\n    expect(registry.to_a).to eq [registered_object, second_registered_object]\n  end\n\n  it \"does not include duplicate objects with registered under different names\" do\n    registry = FactoryBot::Registry.new(\"Great thing\")\n    registered_object = double(\"registered object\")\n    registry.register(:first_object, registered_object)\n    registry.register(:second_object, registered_object)\n\n    expect(registry.to_a).to eq [registered_object]\n  end\n\n  it \"clears registered factories\" do\n    registry = FactoryBot::Registry.new(\"Great thing\")\n    registered_object = double(\"registered object\")\n    registry.register(:object_name, registered_object)\n    registry.clear\n\n    expect(registry.count).to be_zero\n  end\nend\n"
  },
  {
    "path": "spec/factory_bot/sequence_spec.rb",
    "content": "shared_examples \"a sequence\" do |options|\n  first_value = options[:first_value]\n  second_value = options[:second_value]\n\n  it \"has a next value equal to its first value\" do\n    expect(subject.next).to eq first_value\n  end\n\n  it \"has a next value equal to the 2nd value after being incremented\" do\n    subject.next\n\n    expect(subject.next).to eq second_value\n  end\n\n  it \"has a next value equal to the 1st value after rewinding\" do\n    subject.next\n    subject.rewind\n\n    expect(subject.next).to eq first_value\n  end\nend\n\ndescribe FactoryBot::Sequence do\n  describe \".find\" do\n    before(:each) do\n      define_class(\"User\") { attr_accessor :name }\n\n      FactoryBot.define do\n        factory :user do\n          trait :with_email do\n            sequence(:email) { |n| \"user_#{n}@example.com\" }\n          end\n        end\n      end\n    end\n\n    it \"accepts a list of symbols\" do\n      expect(described_class.find(:user, :with_email, :email)).to be_truthy\n    end\n\n    it \"accepts a list of strings\" do\n      expect(described_class.find(\"user\", \"with_email\", \"email\")).to be_truthy\n    end\n\n    it \"accepts a mixture of symbols & strings\" do\n      expect(described_class.find(:user, \"with_email\", :email)).to be_truthy\n    end\n\n    it \"returns nil with a non-matching URI\" do\n      expect(described_class.find(:user, :email)).to be_nil\n    end\n\n    it \"raises an exception with no arguments given\" do\n      expect { described_class.find }\n        .to raise_error ArgumentError, /wrong number of arguments, expected 1\\+/\n    end\n  end\n\n  describe \".find_by_uri\" do\n    before(:each) do\n      define_class(\"User\") { attr_accessor :name }\n\n      FactoryBot.define do\n        factory :user do\n          trait :with_email do\n            sequence(:email) { |n| \"user_#{n}@example.com\" }\n          end\n        end\n      end\n    end\n\n    it \"accepts a String\" do\n      expect(described_class.find_by_uri(\"user/with_email/email\")).to be_truthy\n    end\n\n    it \"accepts a Symbol\" do\n      expect(described_class.find_by_uri(:\"user/with_email/email\")).to be_truthy\n    end\n\n    it \"returns nil with a non-matching URI\" do\n      expect(described_class.find_by_uri(\"user/email\")).to be_nil\n    end\n\n    it \"raises an exception with no arguments given\" do\n      expect { described_class.find_by_uri }\n        .to raise_error ArgumentError, /wrong number of arguments \\(given 0, expected 1\\)/\n    end\n  end\n\n  describe \"a basic sequence\" do\n    let(:name) { :test }\n    subject { FactoryBot::Sequence.new(name) { |n| \"=#{n}\" } }\n\n    its(:name) { should eq name }\n    its(:names) { should eq [name] }\n\n    it_behaves_like \"a sequence\", first_value: \"=1\", second_value: \"=2\"\n  end\n\n  describe \"a custom sequence\" do\n    subject { FactoryBot::Sequence.new(:name, \"A\") { |n| \"=#{n}\" } }\n\n    it_behaves_like \"a sequence\", first_value: \"=A\", second_value: \"=B\"\n  end\n\n  describe \"a sequence with aliases using default value\" do\n    subject do\n      FactoryBot::Sequence.new(:test, aliases: [:alias, :other]) do |n|\n        \"=#{n}\"\n      end\n    end\n\n    it \"has the expected names as its names\" do\n      names = [:foo, :bar, :baz]\n      sequence = FactoryBot::Sequence.new(names.first, aliases: names.last(2)) {\n        \"=#{n}\"\n      }\n\n      expect(sequence.names).to eq names\n    end\n\n    it_behaves_like \"a sequence\", first_value: \"=1\", second_value: \"=2\"\n  end\n\n  describe \"a sequence with custom value and aliases\" do\n    subject do\n      FactoryBot::Sequence.new(:test, 3, aliases: [:alias, :other]) do |n|\n        \"=#{n}\"\n      end\n    end\n\n    it \"has the expected names as its names\" do\n      names = [:foo, :bar, :baz]\n      sequence = FactoryBot::Sequence.new(names.first, 3, aliases: names.last(2)) {\n        \"=#{n}\"\n      }\n      expect(sequence.names).to eq names\n    end\n\n    it_behaves_like \"a sequence\", first_value: \"=3\", second_value: \"=4\"\n  end\n\n  describe \"a basic sequence without a block\" do\n    subject { FactoryBot::Sequence.new(:name) }\n\n    it_behaves_like \"a sequence\", first_value: 1, second_value: 2\n  end\n\n  describe \"a custom sequence without a block\" do\n    subject { FactoryBot::Sequence.new(:name, \"A\") }\n\n    it_behaves_like \"a sequence\", first_value: \"A\", second_value: \"B\"\n  end\n\n  describe \"a sequence with lazy initial value and a block\" do\n    subject do\n      FactoryBot::Sequence.new(:test, proc { \"J\" }) do |n|\n        \"=#{n}\"\n      end\n    end\n\n    it_behaves_like \"a sequence\", first_value: \"=J\", second_value: \"=K\"\n  end\n\n  describe \"a sequence with a lazy initial value without a block\" do\n    subject do\n      FactoryBot::Sequence.new(:test, proc { 3 })\n    end\n\n    it_behaves_like \"a sequence\", first_value: 3, second_value: 4\n  end\n\n  describe \"iterating over items in an enumerator\" do\n    subject do\n      FactoryBot::Sequence.new(:name, %w[foo bar].to_enum) { |n| \"=#{n}\" }\n    end\n\n    it \"navigates to the next items until no items remain\" do\n      sequence = FactoryBot::Sequence.new(:name, %w[foo bar].to_enum) { |n| \"=#{n}\" }\n      expect(sequence.next).to eq \"=foo\"\n      expect(sequence.next).to eq \"=bar\"\n\n      expect { sequence.next }.to raise_error(StopIteration)\n    end\n\n    it_behaves_like \"a sequence\", first_value: \"=foo\", second_value: \"=bar\"\n  end\n\n  it \"a custom sequence and scope increments within the correct scope\" do\n    sequence = FactoryBot::Sequence.new(:name, \"A\") { |n| \"=#{n}#{foo}\" }\n    scope = double(\"scope\", foo: \"attribute\")\n\n    expect(sequence.next(scope)).to eq \"=Aattribute\"\n  end\n\n  it \"a custom lazy sequence and scope increments within the correct scope\" do\n    sequence = FactoryBot::Sequence.new(:name, proc { \"A\" }) { |n| \"=#{n}#{foo}\" }\n    scope = double(\"scope\", foo: \"attribute\")\n\n    expect(sequence.next(scope)).to eq \"=Aattribute\"\n    expect(sequence.next(scope)).to eq \"=Battribute\"\n  end\n\n  it \"a custom sequence and scope increments within the correct scope when incrementing\" do\n    sequence = FactoryBot::Sequence.new(:name, \"A\") { |n| \"=#{n}#{foo}\" }\n    scope = double(\"scope\", foo: \"attribute\")\n    sequence.next(scope)\n\n    expect(sequence.next(scope)).to eq \"=Battribute\"\n  end\n\n  it \"a custom lazy sequence and scope increments within the correct scope when incrementing\" do\n    sequence = FactoryBot::Sequence.new(:name, proc { \"A\" }) { |n| \"=#{n}#{foo}\" }\n    scope = double(\"scope\", foo: \"attribute\")\n    sequence.next(scope)\n\n    expect(sequence.next(scope)).to eq \"=Battribute\"\n  end\n\n  it \"a custom scope increments within the correct scope after rewinding\" do\n    sequence = FactoryBot::Sequence.new(:name, \"A\") { |n| \"=#{n}#{foo}\" }\n    scope = double(\"scope\", foo: \"attribute\")\n    sequence.next(scope)\n    sequence.rewind\n\n    expect(sequence.next(scope)).to eq \"=Aattribute\"\n  end\n\n  it \"a custom scope with a lazy sequence increments within the correct scope after rewinding\" do\n    sequence = FactoryBot::Sequence.new(:name, proc { \"A\" }) { |n| \"=#{n}#{foo}\" }\n    scope = double(\"scope\", foo: \"attribute\")\n    sequence.next(scope)\n    sequence.rewind\n\n    expect(sequence.next(scope)).to eq \"=Aattribute\"\n  end\nend\n"
  },
  {
    "path": "spec/factory_bot/strategy/attributes_for_spec.rb",
    "content": "describe FactoryBot::Strategy::AttributesFor do\n  let(:result) { {name: \"John Doe\", gender: \"Male\", admin: false} }\n  let(:evaluation) { double(\"evaluation\", hash: result) }\n\n  it_should_behave_like \"strategy without association support\"\n\n  it \"returns the hash from the evaluation\" do\n    expect(subject.result(evaluation)).to eq result\n  end\n\n  it \"does not run the to_create block\" do\n    expect {\n      subject.result(evaluation)\n    }.to_not raise_error\n  end\nend\n"
  },
  {
    "path": "spec/factory_bot/strategy/build_spec.rb",
    "content": "describe FactoryBot::Strategy::Build do\n  it_should_behave_like \"strategy with association support\", :create\n  it_should_behave_like \"strategy with callbacks\", :after_build\n  it_should_behave_like \"strategy with strategy: :build\", :build\nend\n"
  },
  {
    "path": "spec/factory_bot/strategy/create_spec.rb",
    "content": "describe FactoryBot::Strategy::Create do\n  it_should_behave_like \"strategy with association support\", :create\n  it_should_behave_like \"strategy with callbacks\", :after_build, :before_create, :after_create\n\n  it \"runs a custom create block\" do\n    evaluation = double(\n      \"evaluation\",\n      object: nil,\n      notify: nil,\n      create: nil\n    )\n\n    subject.result(evaluation)\n\n    expect(evaluation).to have_received(:create).once\n  end\nend\n"
  },
  {
    "path": "spec/factory_bot/strategy/stub_spec.rb",
    "content": "shared_examples \"disabled persistence method\" do |method_name|\n  let(:instance) { described_class.new.result(evaluation) }\n\n  describe \"overriding persistence method: ##{method_name}\" do\n    it \"overrides the method with any arity\" do\n      method = instance.method(method_name)\n\n      expect(method.arity).to eq(-1)\n    end\n\n    it \"raises an informative error if the method is called\" do\n      expect { instance.send(method_name) }.to raise_error(\n        RuntimeError,\n        \"stubbed models are not allowed to access the database - #{instance.class}##{method_name}()\"\n      )\n    end\n  end\nend\n\ndescribe FactoryBot::Strategy::Stub do\n  it_should_behave_like \"strategy with association support\", :build_stubbed\n  it_should_behave_like \"strategy with callbacks\", :after_stub\n  it_should_behave_like \"strategy with strategy: :build\", :build_stubbed\n\n  context \"asking for a result\" do\n    let(:result_instance) do\n      define_class(\"ResultInstance\") {\n        attr_accessor :id, :created_at\n      }.new\n    end\n\n    let(:evaluation) do\n      double(\"evaluation\", object: result_instance, notify: true)\n    end\n\n    it { expect(subject.result(evaluation)).not_to be_new_record }\n    it { expect(subject.result(evaluation)).to be_persisted }\n    it { expect(subject.result(evaluation)).not_to be_destroyed }\n\n    it \"assigns created_at\" do\n      created_at1 = subject.result(evaluation).created_at\n      created_at2 = subject.result(evaluation).created_at\n\n      expect(created_at1).to equal created_at2\n    end\n\n    include_examples \"disabled persistence method\", :connection\n    include_examples \"disabled persistence method\", :decrement!\n    include_examples \"disabled persistence method\", :delete\n    include_examples \"disabled persistence method\", :destroy\n    include_examples \"disabled persistence method\", :destroy!\n    include_examples \"disabled persistence method\", :increment!\n    include_examples \"disabled persistence method\", :reload\n    include_examples \"disabled persistence method\", :save\n    include_examples \"disabled persistence method\", :save!\n    include_examples \"disabled persistence method\", :toggle!\n    include_examples \"disabled persistence method\", :touch\n    include_examples \"disabled persistence method\", :update\n    include_examples \"disabled persistence method\", :update!\n    include_examples \"disabled persistence method\", :update_attribute\n    include_examples \"disabled persistence method\", :update_attributes\n    include_examples \"disabled persistence method\", :update_attributes!\n    include_examples \"disabled persistence method\", :update_column\n    include_examples \"disabled persistence method\", :update_columns\n  end\nend\n"
  },
  {
    "path": "spec/factory_bot/strategy_spec.rb",
    "content": "describe FactoryBot::Strategy do\n  it \"returns the class passed when it is instantiated with a class\" do\n    strategy = define_class(\"MyAwesomeClass\")\n    result = described_class.lookup_strategy(strategy)\n\n    expect(result).to eq strategy\n  end\n\n  it \"finds the strategy by name when instantiated with a symbol\" do\n    strategy = define_class(\"MyAwesomeClass\")\n    allow(FactoryBot::Internal).to receive(:strategy_by_name).and_return(strategy)\n    described_class.lookup_strategy(:build)\n\n    expect(FactoryBot::Internal).to have_received(:strategy_by_name).with(:build)\n  end\n\n  it \"returns the strategy found when instantiated with a symbol\" do\n    strategy = define_class(\"MyAwesomeClass\")\n    allow(FactoryBot::Internal).to receive(:strategy_by_name).and_return(strategy)\n    result = described_class.lookup_strategy(:build)\n\n    expect(result).to eq strategy\n  end\nend\n"
  },
  {
    "path": "spec/factory_bot/uri_manager_spec.rb",
    "content": "describe FactoryBot::UriManager do\n  describe \".build_uri\" do\n    it \"combines the parts to form a Symbol\" do\n      expect(described_class.build_uri(:ep1, :ep2, :ep3))\n        .to eq :\"ep1/ep2/ep3\"\n    end\n\n    it \"works with a single part\" do\n      expect(described_class.build_uri(:ep1))\n        .to eq :ep1\n    end\n\n    it \"works with multiple arrays of parts\" do\n      expect(described_class.build_uri(%i[ep1 ep2], %i[ep3 ep4]))\n        .to eq :\"ep1/ep2/ep3/ep4\"\n    end\n\n    it \"returns nil when no parts provided\" do\n      expect(described_class.build_uri).to be_nil\n    end\n\n    it \"removes leading and trailing slashes\" do\n      expect(described_class.build_uri(\"/start\", \"end/\"))\n        .to eq :\"start/end\"\n    end\n\n    it \"converts space to underlines\" do\n      expect(described_class.build_uri(\"starting   now\", \"the end is     nigh\"))\n        .to eq :\"starting___now/the_end_is_____nigh\"\n    end\n  end\n\n  describe \"#initialize\" do\n    context \"when only endpoints are provided\" do\n      it \"creates one URI for each endpoint\" do\n        uri_manager = FactoryBot::UriManager.new(:ep1, :ep2, :ep3)\n        expect(uri_manager.uri_list).to eq %i[ep1 ep2 ep3]\n      end\n\n      it \"each URI is a Symbol\" do\n        uri_manager = FactoryBot::UriManager.new(\"ep1\", \"ep2\", \"ep3\")\n        expect(uri_manager.uri_list).to eq %i[ep1 ep2 ep3]\n      end\n\n      it \"accepts a combination of Symbols & Strings\" do\n        uri_manager = FactoryBot::UriManager.new(:ep1, \"ep2\", :ep3)\n        expect(uri_manager.uri_list).to eq %i[ep1 ep2 ep3]\n      end\n\n      it \"replaces spaces with underlines\" do\n        uri_manager = FactoryBot::UriManager.new(\"ep 1\", \"e p 2\", :ep3)\n        expect(uri_manager.uri_list).to eq %i[ep_1 e_p_2 ep3]\n      end\n\n      it \"stringifies endpoints with non-symbol characters\" do\n        uri_manager = FactoryBot::UriManager.new(\"ep @ 1\", \"e + 2\")\n        expect(uri_manager.uri_list).to eq %i[ep_@_1 e_+_2]\n      end\n\n      it \"accepts a single endpoint\" do\n        uri_manager = FactoryBot::UriManager.new(:ep1)\n        expect(uri_manager.uri_list).to eq [:ep1]\n      end\n\n      it \"accepts an array of endpoints\" do\n        uri_manager = FactoryBot::UriManager.new([:ep1, \"ep2\", :ep3])\n        expect(uri_manager.uri_list).to eq %i[ep1 ep2 ep3]\n      end\n\n      it \"fails with no endpoints given\" do\n        expect { FactoryBot::UriManager.new }\n          .to raise_error ArgumentError, /wrong number of arguments \\(given 0, expected 1\\+\\)/\n      end\n    end\n\n    context \"when paths are also provided\" do\n      it \"creates one URI for each path/endpoint combination\" do\n        uri_manager = FactoryBot::UriManager.new(:e1, :e2, paths: %i[p1 p2])\n        expect(uri_manager.uri_list).to eq %i[p1/e1 p2/e1 p1/e2 p2/e2]\n      end\n\n      it \"accepts a combination of Symbol & String paths\" do\n        uri_manager = FactoryBot::UriManager.new(:e1, \"e2\", paths: [:p1, \"path\"])\n        expect(uri_manager.uri_list).to eq %i[p1/e1 path/e1 p1/e2 path/e2]\n      end\n\n      it \"replaces spaces with underlines\" do\n        uri_manager = FactoryBot::UriManager.new(:e1, paths: [\"path 1\", \"path 2\"])\n        expect(uri_manager.uri_list).to eq %i[path_1/e1 path_2/e1]\n      end\n\n      it \"accepts a single path\" do\n        uri_manager = FactoryBot::UriManager.new(:e1, :e2, paths: :test_path)\n        expect(uri_manager.uri_list).to eq %i[test_path/e1 test_path/e2]\n      end\n\n      it \"accepts an array of arrays of paths\" do\n        uri_manager = FactoryBot::UriManager.new(:e1, paths: [%i[p1 p2], [:p3]])\n        expect(uri_manager.uri_list).to eq %i[p1/e1 p2/e1 p3/e1]\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "spec/factory_bot_spec.rb",
    "content": "describe FactoryBot do\n  it \"finds a registered strategy\" do\n    FactoryBot.register_strategy(:strategy_name, :strategy_class)\n    expect(FactoryBot.strategy_by_name(:strategy_name))\n      .to eq :strategy_class\n  end\n\n  describe \".use_parent_strategy\" do\n    it \"is true by default\" do\n      expect(FactoryBot.use_parent_strategy).to be true\n    end\n  end\nend\n"
  },
  {
    "path": "spec/spec_helper.rb",
    "content": "# Set timeout when setting sequences\nrequire \"rspec\"\nrequire \"rspec/its\"\n\nrequire \"simplecov\" if RUBY_ENGINE == \"ruby\"\n\nrequire \"factory_bot\"\n\nFactoryBot.sequence_setting_timeout = 0.5\n\nif RUBY_ENGINE == \"jruby\"\n  # Workaround for issue in I18n/JRuby combo.\n  # See https://github.com/jruby/jruby/issues/6547 and\n  # https://github.com/ruby-i18n/i18n/issues/555\n  require \"i18n/backend\"\n  require \"i18n/backend/simple\"\nend\n\nDir[\"spec/support/**/*.rb\"].each { |f| require File.expand_path(f) }\n\nRSpec.configure do |config|\n  config.mock_with :rspec do |mocks|\n    # Prevents you from mocking or stubbing a method that does not exist on a\n    # real object. This is generally recommended, and will default to `true` in\n    # RSpec 4.\n    mocks.verify_partial_doubles = true\n  end\n\n  config.include DeclarationMatchers\n\n  config.before do\n    FactoryBot.reload\n  end\n\n  config.order = :random\n  Kernel.srand config.seed\n\n  config.example_status_persistence_file_path = \"tmp/rspec_examples.txt\"\nend\n"
  },
  {
    "path": "spec/support/containers/test_log.rb",
    "content": "require \"forwardable\"\n\n##\n# Designed for tests to log output for later evaluation\n#\nmodule TestLog\n  class << self\n    extend Forwardable\n\n    def_delegators :log_array, :<<, :[], :size, :first, :last\n    def_delegators :log_array, :map, :in?, :include?, :inspect\n\n    def all\n      Thread.current[:my_thread_safe_test_log] ||= []\n    end\n\n    def reset!\n      Thread.current[:my_thread_safe_test_log] = []\n    end\n\n    private\n\n    def log_array\n      Thread.current[:my_thread_safe_test_log] ||= []\n    end\n  end\nend\n"
  },
  {
    "path": "spec/support/macros/define_constant.rb",
    "content": "require \"active_record\"\n\nmodule DefineConstantMacros\n  def define_class(path, base = Object, &block)\n    const = stub_const(path, Class.new(base))\n    const.class_eval(&block) if block\n    const\n  end\n\n  def define_model(name, columns = {}, &block)\n    model = define_class(name, ActiveRecord::Base, &block)\n    create_table(model.table_name) do |table|\n      columns.each do |column_name, type|\n        table.column column_name, type\n      end\n    end\n    model\n  end\n\n  def create_table(table_name, &block)\n    connection = ActiveRecord::Base.connection\n\n    begin\n      connection.execute(\"DROP TABLE IF EXISTS #{table_name}\")\n      connection.create_table(table_name, &block)\n      created_tables << table_name\n      connection\n    rescue Exception => e # rubocop:disable Lint/RescueException\n      connection.execute(\"DROP TABLE IF EXISTS #{table_name}\")\n      raise e\n    end\n  end\n\n  def clear_generated_tables\n    created_tables.each do |table_name|\n      clear_generated_table(table_name)\n    end\n    created_tables.clear\n  end\n\n  def clear_generated_table(table_name)\n    ActiveRecord::Base\n      .connection\n      .execute(\"DROP TABLE IF EXISTS #{table_name}\")\n  end\n\n  private\n\n  def created_tables\n    @created_tables ||= []\n  end\nend\n\nRSpec.configure do |config|\n  config.include DefineConstantMacros\n\n  config.before(:all) do\n    ActiveRecord::Base.establish_connection(\n      adapter: \"sqlite3\",\n      database: \":memory:\"\n    )\n  end\n\n  config.after do\n    clear_generated_tables\n  end\nend\n"
  },
  {
    "path": "spec/support/macros/deprecation.rb",
    "content": "require \"active_support\"\n\nRSpec.configure do |config|\n  config.around :example, silence_deprecation: true do |example|\n    with_temporary_assignment(FactoryBot::Deprecation, :silenced, true) do\n      example.run\n    end\n  end\nend\n"
  },
  {
    "path": "spec/support/macros/temporary_assignment.rb",
    "content": "module TemporaryAssignment\n  def with_temporary_assignment(assignee, attribute, temporary_value)\n    original_value = assignee.public_send(attribute)\n    attribute_setter = \"#{attribute}=\"\n    assignee.public_send(attribute_setter, temporary_value)\n    yield\n  ensure\n    assignee.public_send(attribute_setter, original_value)\n  end\nend\n\nRSpec.configure do |config|\n  config.include TemporaryAssignment\nend\n"
  },
  {
    "path": "spec/support/matchers/be_about_now.rb",
    "content": "RSpec::Matchers.define :be_about_now do\n  match do |actual|\n    expect(actual).to be_within(2.seconds).of(Time.now)\n  end\nend\n"
  },
  {
    "path": "spec/support/matchers/callback.rb",
    "content": "RSpec::Matchers.define :have_callback do |callback_name|\n  match do |instance|\n    instance.callbacks.include?(FactoryBot::Callback.new(callback_name, @block))\n  end\n\n  chain :with_block do |block|\n    @block = block\n  end\nend\n"
  },
  {
    "path": "spec/support/matchers/declaration.rb",
    "content": "module DeclarationMatchers\n  def have_dynamic_declaration(name)\n    DeclarationMatcher.new(:dynamic).named(name)\n  end\n\n  def have_association_declaration(name)\n    DeclarationMatcher.new(:association).named(name)\n  end\n\n  def have_implicit_declaration(name)\n    DeclarationMatcher.new(:implicit).named(name)\n  end\n\n  class DeclarationMatcher\n    def initialize(declaration_type)\n      @declaration_type = declaration_type\n    end\n\n    def matches?(subject)\n      subject.declarations.include?(expected_declaration)\n    end\n\n    def named(name)\n      @name = name\n      self\n    end\n\n    def ignored\n      @ignored = true\n      self\n    end\n\n    def with_value(value)\n      @value = value\n      self\n    end\n\n    def with_factory(factory)\n      @factory = factory\n      self\n    end\n\n    def with_options(options)\n      @options = options\n      self\n    end\n\n    def failure_message\n      [\n        \"expected declarations to include declaration of type #{@declaration_type}\",\n        @options ? \"with options #{options}\" : nil\n      ].compact.join \" \"\n    end\n\n    private\n\n    def expected_declaration\n      case @declaration_type\n      when :dynamic then FactoryBot::Declaration::Dynamic.new(@name, ignored?, @value)\n      when :implicit then FactoryBot::Declaration::Implicit.new(@name, @factory, ignored?)\n      when :association\n        if @options\n          FactoryBot::Declaration::Association.new(@name, options)\n        else\n          FactoryBot::Declaration::Association.new(@name)\n        end\n      end\n    end\n\n    def ignored?\n      !!@ignored\n    end\n\n    def options\n      @options || {}\n    end\n  end\nend\n"
  },
  {
    "path": "spec/support/matchers/delegate.rb",
    "content": "RSpec::Matchers.define :delegate do |delegated_method|\n  chain :to do |target_method|\n    @target_method = target_method\n  end\n\n  chain :as do |method_on_target|\n    @method_on_target = method_on_target\n  end\n\n  chain :with_arguments do |args|\n    @args = args\n  end\n\n  match do |instance|\n    @instance = instance\n    @args ||= []\n    return_value = \"stubbed return value\"\n    method_on_target = @method_on_target || delegated_method\n    stubbed_target = double(\"stubbed_target\", method_on_target => return_value)\n    allow(@instance).to receive(@target_method).and_return stubbed_target\n    begin\n      @instance.send(delegated_method, *@args) == return_value\n    rescue NoMethodError\n      false\n    end\n  end\n\n  failure_message do\n    if Class === @instance\n      message = \"expected #{@instance.name} \"\n      prefix = \".\"\n    else\n      message = \"expected #{@instance.class.name} \"\n      prefix = \"#\"\n    end\n    message << \"to delegate #{prefix}#{delegated_method} to #{prefix}#{@target_method}\"\n    if @method_on_target\n      message << \".#{@method_on_target}\"\n    end\n    message\n  end\nend\n"
  },
  {
    "path": "spec/support/matchers/raise_did_you_mean_error.rb",
    "content": "RSpec::Matchers.define :raise_did_you_mean_error do\n  supports_block_expectations\n\n  match do |actual|\n    # detailed_message introduced in Ruby 3.2 for cleaner integration with\n    # did_you_mean. See https://bugs.ruby-lang.org/issues/18564\n    matcher = if KeyError.method_defined?(:detailed_message)\n      raise_error(\n        an_instance_of(KeyError)\n        .and(having_attributes(detailed_message: /Did you mean\\?/))\n      )\n    else\n      raise_error(KeyError, /Did you mean\\?/)\n    end\n\n    expect(&actual).to matcher\n  end\nend\n"
  },
  {
    "path": "spec/support/matchers/trait.rb",
    "content": "RSpec::Matchers.define :have_trait do |trait_name|\n  match do |instance|\n    instance.defined_traits.any? do |trait|\n      trait.name == trait_name.to_s && trait.send(:block) == @block\n    end\n  end\n\n  chain :with_block do |block|\n    @block = block\n  end\nend\n"
  },
  {
    "path": "spec/support/shared_examples/strategy.rb",
    "content": "shared_examples_for \"strategy without association support\" do\n  let(:factory) { double(\"associate_factory\") }\n  let(:attribute) { FactoryBot::Attribute::Association.new(:user, :user, {}) }\n\n  def association_named(name, overrides)\n    runner = FactoryBot::FactoryRunner.new(name, :build, [overrides])\n    subject.association(runner)\n  end\n\n  before do\n    allow(FactoryBot::Internal).to receive(:factory_by_name).and_return factory\n    allow(factory).to receive(:compile)\n    allow(factory).to receive(:run)\n  end\n\n  it \"returns nil when accessing an association\" do\n    expect(association_named(:user, {})).to be_nil\n  end\nend\n\nshared_examples_for \"strategy with association support\" do |factory_bot_strategy_name|\n  let(:factory) { double(\"associate_factory\") }\n\n  def association_named(name, strategy, overrides)\n    runner = FactoryBot::FactoryRunner.new(name, strategy, [overrides])\n    subject.association(runner)\n  end\n\n  before do\n    allow(FactoryBot::Internal).to receive(:factory_by_name).and_return factory\n    allow(factory).to receive(:compile)\n    allow(factory).to receive(:run)\n  end\n\n  it \"runs the factory with the correct overrides\" do\n    association_named(:author, factory_bot_strategy_name, great: \"value\")\n    expect(factory).to have_received(:run).with(factory_bot_strategy_name, great: \"value\")\n  end\n\n  it \"finds the factory with the correct factory name\" do\n    association_named(:author, factory_bot_strategy_name, great: \"value\")\n    expect(FactoryBot::Internal).to have_received(:factory_by_name).with(:author)\n  end\nend\n\nshared_examples_for \"strategy with strategy: :build\" do |factory_bot_strategy_name|\n  let(:factory) { double(\"associate_factory\") }\n\n  def association_named(name, overrides)\n    runner = FactoryBot::FactoryRunner.new(name, overrides[:strategy], [overrides.except(:strategy)])\n    subject.association(runner)\n  end\n\n  before do\n    allow(FactoryBot::Internal).to receive(:factory_by_name).and_return factory\n    allow(factory).to receive(:compile)\n    allow(factory).to receive(:run)\n  end\n\n  it \"runs the factory with the correct overrides\" do\n    association_named(:author, strategy: :build, great: \"value\")\n    expect(factory).to have_received(:run).with(factory_bot_strategy_name, great: \"value\")\n  end\n\n  it \"finds the factory with the correct factory name\" do\n    association_named(:author, strategy: :build, great: \"value\")\n    expect(FactoryBot::Internal).to have_received(:factory_by_name).with(:author)\n  end\nend\n\nshared_examples_for \"strategy with callbacks\" do |*callback_names|\n  let(:result_instance) do\n    define_class(\"ResultInstance\") {\n      attr_accessor :id\n    }.new\n  end\n\n  let(:evaluation) do\n    double(\"evaluation\", object: result_instance, notify: true, create: nil)\n  end\n\n  it \"runs the callbacks #{callback_names} with the evaluation's object\" do\n    subject.result(evaluation)\n    callback_names.each do |name|\n      expect(evaluation).to have_received(:notify).with(name, evaluation.object)\n    end\n  end\n\n  it \"returns the object from the evaluation\" do\n    expect(subject.result(evaluation)).to eq evaluation.object\n  end\nend\n"
  }
]