<commit_before>require 'spec_helper'
require 'ruby_event_store'
require 'ruby_event_store/spec/event_repository_lint'
require 'rails_event_store_active_record/event'

module RailsEventStoreActiveRecord
  RSpec.describe EventRepository do
    include SchemaHelper

    around(:each) do |example|
      begin
        establish_database_connection
        load_database_schema
        example.run
      ensure
        drop_database
      end
    end

    let(:test_race_conditions_auto)  { !ENV['DATABASE_URL'].include?("sqlite") }
    let(:test_race_conditions_any)   { !ENV['DATABASE_URL'].include?("sqlite") }
    let(:test_expected_version_auto) { true }
    let(:test_link_events_to_stream) { true }
    let(:test_binary)                { true }
    let(:test_change)                { !ENV['DATABASE_URL'].include?("sqlite") }
    let(:mapper)                     { RubyEventStore::Mappers::NullMapper.new }
    let(:repository)                 { EventRepository.new }
    let(:reader)                     { RubyEventStore::SpecificationReader.new(repository, mapper) }
    let(:specification)              { RubyEventStore::Specification.new(reader) }

    it_behaves_like :event_repository, EventRepository

    specify "all considered internal detail" do
      repository.append_to_stream(
        [RubyEventStore::SRecord.new],
        RubyEventStore::Stream.new(RubyEventStore::GLOBAL_STREAM),
        RubyEventStore::ExpectedVersion.any
      )

      expect do
        repository.read(specification.stream("all").result)
      end.to raise_error(RubyEventStore::ReservedInternalName)

      expect do
        repository.read(specification.stream("all").backward.result)
      end.to raise_error(RubyEventStore::ReservedInternalName)

      expect do
        repository.read(specification.stream("all").from(:head).limit(5).result)
      end.to raise_error(RubyEventStore::ReservedInternalName)

      expect do
        repository.read(specification.stream("all").from(:head).limit(5).backward.result)
      end.to raise_error(RubyEventStore::ReservedInternalName)
    end

    specify "using preload()" do
      repository.append_to_stream([
        event0 = RubyEventStore::SRecord.new,
        event1 = RubyEventStore::SRecord.new,
      ], RubyEventStore::Stream.new('stream'), RubyEventStore::ExpectedVersion.auto)
      c1 = count_queries{ repository.read(specification.from(:head).limit(2).result) }
      expect(c1).to eq(2)

      c2 = count_queries{ repository.read(specification.from(:head).limit(2).backward.result) }
      expect(c2).to eq(2)

      c3 = count_queries{ repository.read(specification.stream("stream").result) }
      expect(c3).to eq(2)

      c4 = count_queries{ repository.read(specification.stream("stream").backward.result) }
      expect(c4).to eq(2)

      c5 = count_queries{ repository.read(specification.stream("stream").from(:head).limit(2).result) }
      expect(c5).to eq(2)

      c6 = count_queries{ repository.read(specification.stream("stream").from(:head).limit(2).backward.result) }
      expect(c6).to eq(2)
    end

    specify "explicit sorting by position rather than accidental" do
      e1 = Event.create!(
        id: u1 = SecureRandom.uuid,
        data: {},
        metadata: {},
        event_type: "TestDomainEvent",
      )
      e2 = Event.create!(
        id: u2 = SecureRandom.uuid,
        data: {},
        metadata: {},
        event_type: "TestDomainEvent",
      )
      e3 = Event.create!(
        id: u3 = SecureRandom.uuid,
        data: {},
        metadata: {},
        event_type: "TestDomainEvent",
      )
      EventInStream.create!(
        stream:   "stream",
        position: 1,
        event_id: e2.id,
      )
      EventInStream.create!(
        stream:   "stream",
        position: 0,
        event_id: e1.id,
      )
      EventInStream.create!(
        stream:   "stream",
        position: 2,
        event_id: e3.id,
      )
      ActiveRecord::Schema.define do
        self.verbose = false
        remove_index :event_store_events_in_streams, [:stream, :position]
      end

      expect(repository.read(specification.stream("stream").from(:head).limit(3).result).map(&:event_id)).to eq([u1,u2,u3])
      expect(repository.read(specification.stream("stream").result).map(&:event_id)).to eq([u1,u2,u3])

      expect(repository.read(specification.stream("stream").backward.from(:head).limit(3).result).map(&:event_id)).to eq([u3,u2,u1])
      expect(repository.read(specification.stream("stream").backward.result).map(&:event_id)).to eq([u3,u2,u1])
    end

    specify "explicit sorting by id rather than accidental for all events" do
      e1 = Event.create!(
        id: u1 = SecureRandom.uuid,
        data: {},
        metadata: {},
        event_type: "TestDomainEvent",
      )
      e2 = Event.create!(
        id: u2 = SecureRandom.uuid,
        data: {},
        metadata: {},
        event_type: "TestDomainEvent",
      )
      e3 = Event.create!(
        id: u3 = SecureRandom.uuid,
        data: {},
        metadata: {},
        event_type: "TestDomainEvent",
      )
      EventInStream.create!(
        stream:   "all",
        position: 1,
        event_id: e1.id,
      )
      EventInStream.create!(<commit_msg>Repository interacts with serialized data and metadata.<commit_after>require 'spec_helper'
require 'ruby_event_store'
require 'ruby_event_store/spec/event_repository_lint'
require 'rails_event_store_active_record/event'

module RailsEventStoreActiveRecord
  RSpec.describe EventRepository do
    include SchemaHelper

    around(:each) do |example|
      begin
        establish_database_connection
        load_database_schema
        example.run
      ensure
        drop_database
      end
    end

    let(:test_race_conditions_auto)  { !ENV['DATABASE_URL'].include?("sqlite") }
    let(:test_race_conditions_any)   { !ENV['DATABASE_URL'].include?("sqlite") }
    let(:test_expected_version_auto) { true }
    let(:test_link_events_to_stream) { true }
    let(:test_binary)                { true }
    let(:test_change)                { !ENV['DATABASE_URL'].include?("sqlite") }
    let(:mapper)                     { RubyEventStore::Mappers::NullMapper.new }
    let(:repository)                 { EventRepository.new }
    let(:reader)                     { RubyEventStore::SpecificationReader.new(repository, mapper) }
    let(:specification)              { RubyEventStore::Specification.new(reader) }

    it_behaves_like :event_repository, EventRepository

    specify "all considered internal detail" do
      repository.append_to_stream(
        [RubyEventStore::SRecord.new],
        RubyEventStore::Stream.new(RubyEventStore::GLOBAL_STREAM),
        RubyEventStore::ExpectedVersion.any
      )

      expect do
        repository.read(specification.stream("all").result)
      end.to raise_error(RubyEventStore::ReservedInternalName)

      expect do
        repository.read(specification.stream("all").backward.result)
      end.to raise_error(RubyEventStore::ReservedInternalName)

      expect do
        repository.read(specification.stream("all").from(:head).limit(5).result)
      end.to raise_error(RubyEventStore::ReservedInternalName)

      expect do
        repository.read(specification.stream("all").from(:head).limit(5).backward.result)
      end.to raise_error(RubyEventStore::ReservedInternalName)
    end

    specify "using preload()" do
      repository.append_to_stream([
        event0 = RubyEventStore::SRecord.new,
        event1 = RubyEventStore::SRecord.new,
      ], RubyEventStore::Stream.new('stream'), RubyEventStore::ExpectedVersion.auto)
      c1 = count_queries{ repository.read(specification.from(:head).limit(2).result) }
      expect(c1).to eq(2)

      c2 = count_queries{ repository.read(specification.from(:head).limit(2).backward.result) }
      expect(c2).to eq(2)

      c3 = count_queries{ repository.read(specification.stream("stream").result) }
      expect(c3).to eq(2)

      c4 = count_queries{ repository.read(specification.stream("stream").backward.result) }
      expect(c4).to eq(2)

      c5 = count_queries{ repository.read(specification.stream("stream").from(:head).limit(2).result) }
      expect(c5).to eq(2)

      c6 = count_queries{ repository.read(specification.stream("stream").from(:head).limit(2).backward.result) }
      expect(c6).to eq(2)
    end

    specify "explicit sorting by position rather than accidental" do
      e1 = Event.create!(
        id: u1 = SecureRandom.uuid,
        data: '{}',
        metadata: '{}',
        event_type: "TestDomainEvent",
      )
      e2 = Event.create!(
        id: u2 = SecureRandom.uuid,
        data: '{}',
        metadata: '{}',
        event_type: "TestDomainEvent",
      )
      e3 = Event.create!(
        id: u3 = SecureRandom.uuid,
        data: '{}',
        metadata: '{}',
        event_type: "TestDomainEvent",
      )
      EventInStream.create!(
        stream:   "stream",
        position: 1,
        event_id: e2.id,
      )
      EventInStream.create!(
        stream:   "stream",
        position: 0,
        event_id: e1.id,
      )
      EventInStream.create!(
        stream:   "stream",
        position: 2,
        event_id: e3.id,
      )
      ActiveRecord::Schema.define do
        self.verbose = false
        remove_index :event_store_events_in_streams, [:stream, :position]
      end

      expect(repository.read(specification.stream("stream").from(:head).limit(3).result).map(&:event_id)).to eq([u1,u2,u3])
      expect(repository.read(specification.stream("stream").result).map(&:event_id)).to eq([u1,u2,u3])

      expect(repository.read(specification.stream("stream").backward.from(:head).limit(3).result).map(&:event_id)).to eq([u3,u2,u1])
      expect(repository.read(specification.stream("stream").backward.result).map(&:event_id)).to eq([u3,u2,u1])
    end

    specify "explicit sorting by id rather than accidental for all events" do
      e1 = Event.create!(
        id: u1 = SecureRandom.uuid,
        data: '{}',
        metadata: '{}',
        event_type: "TestDomainEvent",
      )
      e2 = Event.create!(
        id: u2 = SecureRandom.uuid,
        data: '{}',
        metadata: '{}',
        event_type: "TestDomainEvent",
      )
      e3 = Event.create!(
        id: u3 = SecureRandom.uuid,
        data: '{}',
        metadata: '{}',
        event_type: "TestDomainEvent",
      )
      EventInStream.create!(
        stream:   "all",
        position: 1,
        event_id: e1.id,
      )
      EventInStream.create!(
{'fraction_non_alphanumeric': 0.1308686561490211, 'fraction_numerical': 0.011404675917126022, 'mean_word_length': 2.782530553558591, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '4822301', 'n_tokens_mistral': 3284, 'n_tokens_neox': 3180, 'n_words': 495}