Skip to content

Commit

Permalink
No-op for Projection when no handlers have been provided
Browse files Browse the repository at this point in the history
In case there is a projection with no handlers we'd still traverse given streams only to produce no result. It's an unusual case but still we're able to produce "no result" much faster.
  • Loading branch information
mpraglowski committed Jul 22, 2020
1 parent 682c27f commit d40829c
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 4 deletions.
1 change: 1 addition & 0 deletions ruby_event_store/lib/ruby_event_store/projection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ def handled_events
end

def run(event_store, start: nil, count: PAGE_SIZE)
return initial_state if handled_events.empty?
if streams.any?
reduce_from_streams(event_store, start, count)
else
Expand Down
41 changes: 37 additions & 4 deletions ruby_event_store/spec/projection_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ module RubyEventStore

specify "raises proper errors when wrong argument were passed (stream mode)" do
projection = Projection.from_stream("Customer$1", "Customer$2")
.init( -> { { total: 0 } })
.when(MoneyDeposited, ->(state, event) { state[:total] += event.data[:amount] })
.when(MoneyWithdrawn, ->(state, event) { state[:total] -= event.data[:amount] })
expect {
projection.run(event_store, start: :last)
}.to raise_error ArgumentError, 'Start must be an array with event ids'
Expand Down Expand Up @@ -72,6 +75,9 @@ module RubyEventStore

specify "raises proper errors when wrong argument were pass (all streams mode)" do
projection = Projection.from_all_streams
.init( -> { { total: 0 } })
.when(MoneyDeposited, ->(state, event) { state[:total] += event.data[:amount] })
.when(MoneyWithdrawn, ->(state, event) { state[:total] -= event.data[:amount] })
expect {
projection.run(event_store, start: :last)
}.to raise_error ArgumentError, 'Start must be valid event id'
Expand Down Expand Up @@ -240,18 +246,45 @@ module RubyEventStore

specify do
specification = Specification.new(SpecificationReader.new(repository, mapper))
expected = specification.in_batches(2).of_type([]).result
expected = specification.in_batches(2).of_type([MoneyDeposited, MoneyWithdrawn]).result
expect(repository).to receive(:read).with(expected).and_return([])

Projection.from_all_streams.run(event_store, count: 2)
Projection.from_all_streams
.init( -> { { total: 0 } })
.when(MoneyDeposited, ->(state, event) { state[:total] += event.data[:amount] })
.when(MoneyWithdrawn, ->(state, event) { state[:total] -= event.data[:amount] })
.run(event_store, count: 2)
end

specify do
specification = Specification.new(SpecificationReader.new(repository, mapper))
expected = specification.in_batches(2).of_type([]).stream("FancyStream").result
expected = specification.in_batches(2).of_type([MoneyDeposited, MoneyWithdrawn]).stream("FancyStream").result
expect(repository).to receive(:read).with(expected).and_return([])

Projection.from_stream("FancyStream").run(event_store, count: 2)
Projection.from_stream("FancyStream")
.init( -> { { total: 0 } })
.when(MoneyDeposited, ->(state, event) { state[:total] += event.data[:amount] })
.when(MoneyWithdrawn, ->(state, event) { state[:total] -= event.data[:amount] })
.run(event_store, count: 2)
end

specify do
expect(repository).not_to receive(:read)

state = Projection.from_all_streams
.init( -> { { total: 0 } })
.run(event_store, count: 2)

expect(state).to eq({ total: 0 })
end

specify do
expect(repository).not_to receive(:read)

state = Projection.from_all_streams
.run(event_store)

expect(state).to eq({})
end
end
end

0 comments on commit d40829c

Please sign in to comment.