-
Notifications
You must be signed in to change notification settings - Fork 122
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #370 from RailsEventStore/publish-matcher
Publish rspec matcher
- Loading branch information
Showing
6 changed files
with
295 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
90 changes: 90 additions & 0 deletions
90
rails_event_store-rspec/lib/rails_event_store/rspec/publish.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
require 'rspec/matchers/built_in/base_matcher' | ||
|
||
module RailsEventStore | ||
module RSpec | ||
class Publish | ||
def in(event_store) | ||
@event_store = event_store | ||
self | ||
end | ||
|
||
def in_stream(stream) | ||
@stream = stream | ||
self | ||
end | ||
|
||
def matches?(event_proc) | ||
raise_event_store_not_set unless @event_store | ||
spec = @event_store.read | ||
spec = spec.stream(@stream) if @stream | ||
last_event_before_block = last_event(spec) | ||
event_proc.call | ||
spec = spec.from(last_event_before_block.event_id) if last_event_before_block | ||
@published_events = spec.each.to_a | ||
if match_events? | ||
::RSpec::Matchers::BuiltIn::Include.new(*@expected).matches?(@published_events) | ||
else | ||
!@published_events.empty? | ||
end | ||
end | ||
|
||
def failure_message | ||
if match_events? | ||
<<-EOS | ||
expected block to have published: | ||
#{@expected} | ||
#{"in stream #{@stream} " if @stream}but published: | ||
#{@published_events} | ||
EOS | ||
else | ||
"expected block to have published any events" | ||
end | ||
end | ||
|
||
def failure_message_when_negated | ||
if match_events? | ||
<<-EOS | ||
expected block not to have published: | ||
#{@expected} | ||
#{"in stream #{@stream} " if @stream}but published: | ||
#{@published_events} | ||
EOS | ||
else | ||
"expected block not to have published any events" | ||
end | ||
end | ||
|
||
def description | ||
"publish events" | ||
end | ||
|
||
def supports_block_expectations? | ||
true | ||
end | ||
|
||
private | ||
|
||
def initialize(*expected) | ||
@expected = expected | ||
end | ||
|
||
def match_events? | ||
!@expected.empty? | ||
end | ||
|
||
def last_event(spec) | ||
spec.backward.limit(1).each.first | ||
end | ||
|
||
def raise_event_store_not_set | ||
raise SyntaxError, "You have to set the event store instance with `in`, e.g. `expect { ... }.to publish(an_event(MyEvent)).in(event_store)`" | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
185 changes: 185 additions & 0 deletions
185
rails_event_store-rspec/spec/rails_event_store/rspec/publish_spec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
require "spec_helper" | ||
|
||
module RailsEventStore | ||
module RSpec | ||
::RSpec.describe Publish do | ||
let(:matchers) { Object.new.tap { |o| o.extend(Matchers) } } | ||
let(:event_store) do | ||
RailsEventStore::Client.new( | ||
repository: RailsEventStore::InMemoryRepository.new, | ||
mapper: RubyEventStore::Mappers::NullMapper.new | ||
) | ||
end | ||
|
||
def matcher(*expected) | ||
Publish.new(*expected) | ||
end | ||
|
||
specify do | ||
expect { | ||
expect { | ||
true | ||
}.to matcher | ||
}.to raise_error(SyntaxError, "You have to set the event store instance with `in`, e.g. `expect { ... }.to publish(an_event(MyEvent)).in(event_store)`") | ||
end | ||
|
||
specify do | ||
expect { | ||
true | ||
}.not_to matcher.in(event_store) | ||
end | ||
|
||
specify do | ||
expect { | ||
event_store.publish_event(FooEvent.new) | ||
}.to matcher.in(event_store) | ||
end | ||
|
||
specify do | ||
expect { | ||
event_store.publish_event(FooEvent.new, stream_name: 'Foo$1') | ||
}.to matcher.in(event_store).in_stream('Foo$1') | ||
end | ||
|
||
specify do | ||
expect { | ||
event_store.publish_event(FooEvent.new, stream_name: 'Foo$1') | ||
}.not_to matcher.in(event_store).in_stream('Bar$1') | ||
end | ||
|
||
specify do | ||
expect { | ||
event_store.publish_event(FooEvent.new) | ||
}.not_to matcher(matchers.an_event(BarEvent)).in(event_store) | ||
end | ||
|
||
specify do | ||
expect { | ||
event_store.publish_event(FooEvent.new) | ||
}.to matcher(matchers.an_event(FooEvent)).in(event_store) | ||
end | ||
|
||
specify do | ||
expect { | ||
event_store.publish_event(FooEvent.new, stream_name: "Foo$1") | ||
}.to matcher(matchers.an_event(FooEvent)).in(event_store).in_stream("Foo$1") | ||
end | ||
|
||
specify do | ||
expect { | ||
event_store.publish_event(FooEvent.new) | ||
}.not_to matcher(matchers.an_event(FooEvent)).in(event_store).in_stream("Foo$1") | ||
end | ||
|
||
specify do | ||
foo_event = FooEvent.new | ||
bar_event = BarEvent.new | ||
expect { | ||
event_store.publish_event(foo_event, stream_name: "Foo$1") | ||
event_store.publish_event(bar_event, stream_name: "Bar$1") | ||
}.to matcher(matchers.an_event(FooEvent), matchers.an_event(BarEvent)).in(event_store) | ||
end | ||
|
||
specify do | ||
foo_event = FooEvent.new | ||
bar_event = BarEvent.new | ||
|
||
event_store.publish_event(foo_event) | ||
expect { | ||
event_store.publish_event(bar_event) | ||
}.not_to matcher(matchers.an_event(FooEvent)).in(event_store) | ||
end | ||
|
||
specify do | ||
expect { | ||
true | ||
}.not_to matcher.in(event_store) | ||
end | ||
|
||
specify do | ||
_matcher = matcher.in(event_store) | ||
_matcher.matches?(Proc.new { }) | ||
|
||
expect(_matcher.failure_message_when_negated.to_s).to eq(<<~EOS.strip) | ||
expected block not to have published any events | ||
EOS | ||
end | ||
|
||
specify do | ||
_matcher = matcher.in(event_store) | ||
_matcher.matches?(Proc.new { }) | ||
|
||
expect(_matcher.failure_message.to_s).to eq(<<~EOS.strip) | ||
expected block to have published any events | ||
EOS | ||
end | ||
|
||
specify do | ||
_matcher = matcher(actual = matchers.an_event(FooEvent)).in(event_store) | ||
_matcher.matches?(Proc.new { }) | ||
|
||
expect(_matcher.failure_message.to_s).to eq(<<~EOS) | ||
expected block to have published: | ||
#{[actual].inspect} | ||
but published: | ||
[] | ||
EOS | ||
end | ||
|
||
specify do | ||
_matcher = matcher(actual = matchers.an_event(FooEvent)).in_stream('foo').in(event_store) | ||
_matcher.matches?(Proc.new { }) | ||
|
||
expect(_matcher.failure_message.to_s).to eq(<<~EOS) | ||
expected block to have published: | ||
#{[actual].inspect} | ||
in stream foo but published: | ||
[] | ||
EOS | ||
end | ||
|
||
specify do | ||
foo_event = FooEvent.new | ||
_matcher = matcher(actual = matchers.an_event(FooEvent)).in(event_store) | ||
_matcher.matches?(Proc.new { event_store.publish_event(foo_event) }) | ||
|
||
expect(_matcher.failure_message_when_negated.to_s).to eq(<<~EOS) | ||
expected block not to have published: | ||
#{[actual].inspect} | ||
but published: | ||
#{[foo_event].inspect} | ||
EOS | ||
end | ||
|
||
specify do | ||
foo_event = FooEvent.new | ||
_matcher = matcher(actual = matchers.an_event(FooEvent)).in_stream('foo').in(event_store) | ||
_matcher.matches?(Proc.new { event_store.publish_event(foo_event, stream_name: 'foo') }) | ||
|
||
expect(_matcher.failure_message_when_negated.to_s).to eq(<<~EOS) | ||
expected block not to have published: | ||
#{[actual].inspect} | ||
in stream foo but published: | ||
#{[foo_event].inspect} | ||
EOS | ||
end | ||
|
||
specify do | ||
_matcher = matcher | ||
expect(_matcher.description).to eq("publish events") | ||
end | ||
end | ||
end | ||
end |