<commit_before>RSpec.shared_examples "a historical model" do |fixture, updated_attributes|
  let(:model) { build fixture }

  describe "versioning", versioning: true do
    before { model.save }

    it "is enabled for a #{fixture}" do
      expect(PaperTrail).to be_enabled
      expect(model).to be_versioned
    end

    it "creates a version when the #{fixture} is created" do
      expect(model.versions.count).to eq 1
    end
  end

  describe "#has_history?", versioning: true do
    it "returns false if there is no history" do
      expect(model).to_not have_history
    end

    it "returns true if there is history" do
      model.save
      expect(model).to have_history
    end
  end

  describe "#history", versioning: true do
    let(:user) { create :user }

    before do
      PaperTrail.whodunnit = user.id
      model.save
    end

    it "returns the history for the created #{fixture}" do
      expect(model.history.length).to eq 1
      expect(model.history.first.changeset.keys).to include("created_at")
      expect(model.history.first.changeset).to include({ "object" => described_class.name })
      expect(model.history.first.changeset).to include({ "event" => "create" })
      expect(model.history.first.changeset).to include({ "actor_id" => user.id.to_s })
      expect(model.history.first.changeset).to include({ "recorded_at" => model.versions.last.created_at })
    end

    it "returns the changesets for an updated #{fixture}" do
      model.update_attributes updated_attributes
      expect(model.history.length).to eq 2
      updated_attributes.each do |key, value|
        expect(model.history.first.changeset).to include({ key.to_s => [nil, value] })
      end
      expect(model.history.first.changeset).to include({ "object" => described_class.name })
      expect(model.history.first.changeset).to include({ "event" => "update" })
      expect(model.history.first.changeset).to include({ "actor_id" => user.id.to_s })
      expect(model.history.first.changeset).to include({ "recorded_at" => model.versions.last.created_at })
    end

    it "orders the changesets so the newest changes are at the top" do
      model.update_attributes updated_attributes
      expect(model.history.length).to eq 2
      expect(model.history.first.changeset["event"]).to eq "update"
      expect(model.history.last.changeset["event"]).to eq "create"
    end
  end

  describe "#historical_merge", versioning: true do
    let(:another_model) { build fixture }

    it "returns new history with 2 histories for 2 creation events" do<commit_msg>Extracted the multiple expectations where it made sense so they only test one behavior at a time<commit_after>RSpec.shared_examples "a historical model" do |fixture, updated_attributes|
  let(:model) { build fixture }

  describe "versioning", versioning: true do
    before { model.save }

    it "is enabled for a #{fixture}" do
      expect(PaperTrail).to be_enabled
      expect(model).to be_versioned
    end

    it "creates a version when the #{fixture} is created" do
      expect(model.versions.count).to eq 1
    end
  end

  describe "#has_history?", versioning: true do
    it "returns false if there is no history" do
      expect(model).to_not have_history
    end

    it "returns true if there is history" do
      model.save
      expect(model).to have_history
    end
  end

  describe "#history", versioning: true do
    let(:user) { create :user }

    before do
      PaperTrail.whodunnit = user.id
      model.save
    end

    subject { model.history }

    it "only contains the one event" do
      expect(subject.length).to eq 1
    end

    context "the changeset for the #{fixture}" do
      subject { model.history.first.changeset }

      it "includes a created at date" do
        expect(subject.keys).to include("created_at")
      end

      it "includes the class name" do
        expect(subject).to include({ "object" => described_class.name })
      end

      it "includes the event" do
        expect(subject).to include({ "event" => "create" })
      end

      it "includes the actor id" do
        expect(subject).to include({ "actor_id" => user.id.to_s })
      end

      it "includes the timestamp of when the changeset occured" do
        expect(subject).to include({ "recorded_at" => model.versions.last.created_at })
      end
    end

    context "with an updated changeset" do
      subject { model.history }

      before { model.update_attributes updated_attributes }

      it "contains the updated event" do
        expect(subject.length).to eq 2
      end

      context "the changeset for the #{fixture}" do
        subject { model.history.first.changeset }

        it "returns the changesets for an updated #{fixture}" do
          updated_attributes.each do |key, value|
            expect(subject).to include({ key.to_s => [nil, value] })
          end
        end

        it "includes the class name" do
          expect(subject).to include({ "object" => described_class.name })
        end

        it "includes the event" do
          expect(subject).to include({ "event" => "update" })
        end

        it "includes the actor id" do
          expect(subject).to include({ "actor_id" => user.id.to_s })
        end

        it "includes the timestamp of when the changeset occured" do
          expect(subject).to include({ "recorded_at" => model.versions.last.created_at })
        end
      end
    end

    it "orders the changesets so the newest changes are at the top" do
      model.update_attributes updated_attributes
      expect(model.history.length).to eq 2
      expect(model.history.first.changeset["event"]).to eq "update"
      expect(model.history.last.changeset["event"]).to eq "create"
    end
  end

  describe "#historical_merge", versioning: true do
    let(:another_model) { build fixture }

    it "returns new history with 2 histories for 2 creation events" do
{'fraction_non_alphanumeric': 0.10326178806827785, 'fraction_numerical': 0.002028054757478452, 'mean_word_length': 2.835385612443292, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 21, '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': '4105681', 'n_tokens_mistral': 1741, 'n_tokens_neox': 1673, 'n_words': 534}