<commit_before>describe "an instance generated by a factory with multiple traits" do
  before do
    define_model("User",
                 name:          :string,
                 admin:         :boolean,
                 gender:        :string,
                 email:         :string,
                 date_of_birth: :date,
                 great:         :string)

    FactoryBot.define do
      factory :user_without_admin_scoping, class: User do
        admin_trait
      end

      factory :user do
        name { "John" }

        trait :great do
          great { "GREAT!!!" }
        end

        trait :admin do
          admin { true }
        end

        trait "admin_string" do
          admin true
        end

        trait :admin_trait do
          admin { true }
        end

        trait :male do
          name   { "Joe" }
          gender { "Male" }
        end

        trait :female do
          name   { "Jane" }
          gender { "Female" }
        end

        factory :great_user do
          great
        end

        factory :admin, traits: [:admin]

        factory :male_user do
          male

          factory :child_male_user do
            date_of_birth { Date.parse("1/1/2000") }
          end
        end

        factory :female, traits: [:female] do
          trait :admin do
            admin { true }
            name { "Judy" }
          end

          factory :female_great_user do
            great
          end

          factory :female_admin_judy, traits: [:admin]
        end

        factory :female_admin,            traits: [:female, :admin]
        factory :female_after_male_admin, traits: [:male, :female, :admin]
        factory :male_after_female_admin, traits: [:female, :male, :admin]
      end

      trait :email do
        email { <EMAIL>" }
      end

      factory :user_with_email, class: User, traits: [:email] do
        name { "Bill" }
      end
    end
  end

  context "the parent class" do
    subject      { FactoryBot.create(:user) }
    its(:name)   { should eq "John" }
    its(:gender) { should be_nil }
    it           { should_not be_admin }
  end

  context "the child class with one trait" do
    subject      { FactoryBot.create(:admin) }
    its(:name)   { should eq "John" }
    its(:gender) { should be_nil }
    it           { should be_admin }
  end

  context "the other child class with one trait" do
    subject      { FactoryBot.create(:female) }
    its(:name)   { should eq "Jane" }
    its(:gender) { should eq "Female" }
    it           { should_not be_admin }
  end

  context "the child with multiple traits" do
    subject      { FactoryBot.create(:female_admin) }
    its(:name)   { should eq "Jane" }
    its(:gender) { should eq "Female" }
    it           { should be_admin }
  end

  context "the child with multiple traits and overridden attributes" do
    subject      { FactoryBot.create(:female_admin, name: "Jill", gender: nil) }
    its(:name)   { should eq "Jill" }
    its(:gender) { should be_nil }
    it           { should be_admin }
  end

  context "the child with multiple traits who override the same attribute" do
    context "when the male assigns name after female" do
      subject      { FactoryBot.create(:male_after_female_admin) }
      its(:name)   { should eq "Joe" }
      its(:gender) { should eq "Male" }
      it           { should be_admin }
    end

    context "when the female assigns name after male" do
      subject      { FactoryBot.create(:female_after_male_admin) }
      its(:name)   { should eq "Jane" }
      its(:gender) { should eq "Female" }
      it           { should be_admin }
    end
  end

  context "child class with scoped trait and inherited trait" do
    subject      { FactoryBot.create(:female_admin_judy) }
    its(:name)   { should eq "Judy" }
    its(:gender) { should eq "Female" }
    it           { should be_admin }
  end

  context "factory using global trait" do
    subject     { FactoryBot.create(:user_with_email) }
    its(:name)  { should eq "Bill" }
    its(:email) { should eq "<EMAIL>" }
  end

  context "factory created with alternate syntax for specifying trait" do
    subject      { FactoryBot.create(:male_user) }
    its(:gender) { should eq "Male" }

    context "where trait name and attribute are the same" do
      subject     { FactoryBot.create(:great_user) }
      its(:great) { should eq "GREAT!!!" }
    end

    context "where trait name and attribute are the same and attribute is overridden" do
      subject     { FactoryBot.create(:great_user, great: "SORT OF!!!") }
      its(:great) { should eq "SORT OF!!!" }
    end
  end

  context "child factory created where trait attributes are inherited" do
    subject             { FactoryBot.create(:child_male_user) }
    its(:gender)        { should eq "Male" }
    its(:date_of_birth) { should eq Date.parse("1/1/2000") }
  end

  context "when trait is defined as string" do
    context "when is called as symbol" do
      subject            { FactoryBot.create(:user, :admin_string) }
      its(:admin)        { should be_truthy }
    end

    context "when is called as string" do
      subject            { FactoryBot.create(:user, "admin_string") }
      its(:admin)        { should be_truthy }
    end
  end

  context "factory outside of scope" do
    subject     { FactoryBot.create(:user_without_admin_scoping) }
    it { expect { subject }.to raise_error(ArgumentError, "Trait not registered: admin_trait") }
  end

  context "child factory using grandparents' trait" do
    subject     { FactoryBot.create(:female_great_user) }
    its(:great) { should eq "GREAT!!!" }
  end
end<commit_msg>Test all combinations of indifferent trait access<commit_after>describe "an instance generated by a factory with multiple traits" do
  before do
    define_model("User",
                 name:          :string,
                 admin:         :boolean,
                 gender:        :string,
                 email:         :string,
                 date_of_birth: :date,
                 great:         :string)

    FactoryBot.define do
      factory :user_without_admin_scoping, class: User do
        admin_trait
      end

      factory :user do
        name { "John" }

        trait :great do
          great { "GREAT!!!" }
        end

        trait :admin do
          admin { true }
        end

        trait :admin_trait do
          admin { true }
        end

        trait :male do
          name   { "Joe" }
          gender { "Male" }
        end

        trait :female do
          name   { "Jane" }
          gender { "Female" }
        end

        factory :great_user do
          great
        end

        factory :admin, traits: [:admin]

        factory :male_user do
          male

          factory :child_male_user do
            date_of_birth { Date.parse("1/1/2000") }
          end
        end

        factory :female, traits: [:female] do
          trait :admin do
            admin { true }
            name { "Judy" }
          end

          factory :female_great_user do
            great
          end

          factory :female_admin_judy, traits: [:admin]
        end

        factory :female_admin,            traits: [:female, :admin]
        factory :female_after_male_admin, traits: [:male, :female, :admin]
        factory :male_after_female_admin, traits: [:female, :male, :admin]
      end

      trait :email do
        email { <EMAIL>" }
      end

      factory :user_with_email, class: User, traits: [:email] do
        name { "Bill" }
      end
    end
  end

  context "the parent class" do
    subject      { FactoryBot.create(:user) }
    its(:name)   { should eq "John" }
    its(:gender) { should be_nil }
    it           { should_not be_admin }
  end

  context "the child class with one trait" do
    subject      { FactoryBot.create(:admin) }
    its(:name)   { should eq "John" }
    its(:gender) { should be_nil }
    it           { should be_admin }
  end

  context "the other child class with one trait" do
    subject      { FactoryBot.create(:female) }
    its(:name)   { should eq "Jane" }
    its(:gender) { should eq "Female" }
    it           { should_not be_admin }
  end

  context "the child with multiple traits" do
    subject      { FactoryBot.create(:female_admin) }
    its(:name)   { should eq "Jane" }
    its(:gender) { should eq "Female" }
    it           { should be_admin }
  end

  context "the child with multiple traits and overridden attributes" do
    subject      { FactoryBot.create(:female_admin, name: "Jill", gender: nil) }
    its(:name)   { should eq "Jill" }
    its(:gender) { should be_nil }
    it           { should be_admin }
  end

  context "the child with multiple traits who override the same attribute" do
    context "when the male assigns name after female" do
      subject      { FactoryBot.create(:male_after_female_admin) }
      its(:name)   { should eq "Joe" }
      its(:gender) { should eq "Male" }
      it           { should be_admin }
    end

    context "when the female assigns name after male" do
      subject      { FactoryBot.create(:female_after_male_admin) }
      its(:name)   { should eq "Jane" }
      its(:gender) { should eq "Female" }
      it           { should be_admin }
    end
  end

  context "child class with scoped trait and inherited trait" do
    subject      { FactoryBot.create(:female_admin_judy) }
    its(:name)   { should eq "Judy" }
    its(:gender) { should eq "Female" }
    it           { should be_admin }
  end

  context "factory using global trait" do
    subject     { FactoryBot.create(:user_with_email) }
    its(:name)  { should eq "Bill" }
    its(:email) { should eq "<EMAIL>" }
  end

  context "factory created with alternate syntax for specifying trait" do
    subject      { FactoryBot.create(:male_user) }
    its(:gender) { should eq "Male" }

    context "where trait name and attribute are the same" do
      subject     { FactoryBot.create(:great_user) }
      its(:great) { should eq "GREAT!!!" }
    end

    context "where trait name and attribute are the same and attribute is overridden" do
      subject     { FactoryBot.create(:great_user, great: "SORT OF!!!") }
      its(:great) { should eq "SORT OF!!!" }
    end
  end

  context "child factory created where trait attributes are inherited" do
    subject             { FactoryBot.create(:child_male_user) }
    its(:gender)        { should eq "Male" }
    its(:date_of_birth) { should eq Date.parse("1/1/2000") }
  end

  context "factory outside of scope" do
    subject     { FactoryBot.create(:user_without_admin_scoping) }
    it { expect { subject }.to raise_error(ArgumentError, "Trait not registered: admin_trait") }
  end

  context "child factory using grandparents' trait" do
    subject     { FactoryBot.create(:female_great_user) }
    its(:great) { should eq "GREAT!!!" }
  end
end

describe "trait indifferent access" do
  context "when trait is defined as a string" do
    it "can be invoked with a string" do
      build_user_factory_with_admin_trait("admin")

      user = FactoryBot.build(:user, "admin")

      expect(user).to be_admin
    end

    it "can be invoked with a symbol" do
      build_user_factory_with_admin_trait("admin")

      user = FactoryBot.build(:user, :admin)

      expect(user).to be_admin
    end
  end

  context "when trait is defined as a symbol" do
    it "can be invoked with a string" do
      build_user_factory_with_admin_trait(:admin)

      user = FactoryBot.build(:user, "admin")

      expect(user).to be_admin
    end

    it "can be invoked with a symbol" do
      build_user_factory_with_admin_trait(:admin)

      user = FactoryBot.build(:user, :admin)

      expect(user).to be_admin
    end
  end

  def build_user_factory_with_admin_trait(trait_name)
    define_model("User", admin: :boolean)

    FactoryBot.define do
      factory :user do
        admin { false }

        trait trait_name do
          admin { true }
        end
      end
    end
  end
end
{'fraction_non_alphanumeric': 0.09202096680256261, 'fraction_numerical': 0.0019968383392961146, 'mean_word_length': 2.0170682730923697, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5900125', 'n_tokens_mistral': 3661, 'n_tokens_neox': 3449, 'n_words': 1107}