Skip to content

Commit d74ed34

Browse files
committed
Reduce API surface.
Let's have one completely tested syntax before expanding options.
1 parent bd289d0 commit d74ed34

File tree

5 files changed

+150
-75
lines changed

5 files changed

+150
-75
lines changed

rails_event_store-rspec/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ IGNORE = RailsEventStore::RSpec::Matchers\#differ \
66
RailsEventStore::RSpec::Matchers\#have_published \
77
RailsEventStore::RSpec::Matchers\#have_applied \
88
RailsEventStore::RSpec::Matchers\#publish \
9-
RailsEventStore::RSpec::Matchers\#be_an_event
9+
RailsEventStore::RSpec::Matchers\#be_an_event \
10+
RailsEventStore::RSpec::Publish\#last_event
1011
SUBJECT ?= RailsEventStore::RSpec*
1112

1213
install: ## Install gem dependencies

rails_event_store-rspec/lib/rails_event_store/rspec/matchers.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ def have_applied(*expected)
3838
HaveApplied.new(*expected, differ: differ, phraser: phraser)
3939
end
4040

41-
def publish(event = nil, &block)
42-
Publish.new(event, &block)
41+
def publish(*expected)
42+
Publish.new(*expected)
4343
end
4444

4545
private

rails_event_store-rspec/lib/rails_event_store/rspec/publish.rb

Lines changed: 28 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,69 +2,59 @@
22

33
module RailsEventStore
44
module RSpec
5-
class Publish < ::RSpec::Matchers::BuiltIn::BaseMatcher
6-
def in(event_store, &block)
5+
class Publish
6+
def in(event_store)
77
@event_store = event_store
8-
@block = block if block_given?
98
self
109
end
1110

12-
def in_stream(stream, &block)
11+
def in_stream(stream)
1312
@stream = stream
14-
@block = block if block_given?
1513
self
1614
end
1715

1816
def matches?(event_proc)
1917
raise_event_store_not_set unless @event_store
20-
@event_proc = event_proc
21-
return false unless Proc === event_proc
2218
spec = @event_store.read
2319
spec = spec.stream(@stream) if @stream
24-
last_event_before_block = spec.backward.limit(1).each.to_a.first
20+
last_event_before_block = last_event(spec)
2521
event_proc.call
2622
spec = spec.from(last_event_before_block.event_id) if last_event_before_block
2723
@published_events = spec.each.to_a
28-
if @block
29-
@block.call(@published_events)
30-
elsif @event
31-
::RSpec::Matchers::BuiltIn::Include.new(*@event).matches?(@published_events)
24+
if match_events?
25+
::RSpec::Matchers::BuiltIn::Include.new(*@expected).matches?(@published_events)
3226
else
3327
!@published_events.empty?
3428
end
3529
end
3630

37-
def does_not_match?(event_proc)
38-
!matches?(event_proc) && Proc === event_proc
39-
end
40-
4131
def failure_message
42-
if @event
32+
if match_events?
4333
<<-EOS
44-
expected block to have published:
34+
expected block to have published:
4535
46-
#{@event.inspect}
36+
#{@expected}
4737
48-
#{"in stream #{@stream} " if @stream}but published:
38+
#{"in stream #{@stream} " if @stream}but published:
4939
50-
#{@published_events.inspect}
51-
EOS
40+
#{@published_events}
41+
EOS
5242
else
5343
"expected block to have published any events"
5444
end
5545
end
5646

5747
def failure_message_when_negated
58-
if @event
48+
if match_events?
5949
<<-EOS
60-
expected block not to have published:
50+
expected block not to have published:
6151
62-
#{@event.inspect}
52+
#{@expected}
6353
64-
#{"in stream #{@stream} " if @stream}but published:
54+
#{"in stream #{@stream} " if @stream}but published:
6555
66-
#{@published_events.inspect}
67-
EOS
56+
#{@published_events}
57+
EOS
6858
else
6959
"expected block not to have published any events"
7060
end
@@ -80,11 +70,16 @@ def supports_block_expectations?
8070

8171
private
8272

83-
def initialize(event = nil, &block)
84-
@event = event
85-
@stream = nil
86-
@event_store = nil
87-
@block = block
73+
def initialize(*expected)
74+
@expected = expected
75+
end
76+
77+
def match_events?
78+
!@expected.empty?
79+
end
80+
81+
def last_event(spec)
82+
spec.backward.limit(1).each.first
8883
end
8984

9085
def raise_event_store_not_set

rails_event_store-rspec/spec/rails_event_store/rspec/matchers_spec.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ module RSpec
6868
aggregate_root.bar
6969
expect(aggregate_root).to matchers.have_applied(matchers.an_event(FooEvent), matchers.an_event(BarEvent))
7070
end
71+
72+
specify do
73+
expect(matchers.publish).to be_a(Publish)
74+
end
7175
end
7276

7377
module Matchers

rails_event_store-rspec/spec/rails_event_store/rspec/publish_spec.rb

Lines changed: 114 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -11,58 +11,64 @@ module RSpec
1111
)
1212
end
1313

14-
def matcher(*events, &block)
15-
Publish.new(events, &block)
14+
def matcher(*expected)
15+
Publish.new(*expected)
1616
end
1717

1818
specify do
1919
expect {
2020
expect {
2121
true
22-
}.to Publish.new()
22+
}.to matcher
2323
}.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)`")
2424
end
2525

2626
specify do
2727
expect {
2828
true
29-
}.not_to Publish.new.in(event_store)
29+
}.not_to matcher.in(event_store)
3030
end
3131

3232
specify do
3333
expect {
3434
event_store.publish_event(FooEvent.new)
35-
}.to Publish.new.in(event_store)
35+
}.to matcher.in(event_store)
3636
end
3737

3838
specify do
3939
expect {
40-
true
41-
}.to Publish.new{ |events|
42-
expect(events).to eq []
43-
}.in(event_store)
40+
event_store.publish_event(FooEvent.new, stream_name: 'Foo$1')
41+
}.to matcher.in(event_store).in_stream('Foo$1')
4442
end
4543

4644
specify do
47-
foo_event = FooEvent.new
48-
bar_event = BarEvent.new
4945
expect {
50-
event_store.publish_event(foo_event)
51-
event_store.publish_event(bar_event)
52-
}.to Publish.new.in(event_store){ |events|
53-
expect(events).to eq [foo_event, bar_event]
54-
}
46+
event_store.publish_event(FooEvent.new, stream_name: 'Foo$1')
47+
}.not_to matcher.in(event_store).in_stream('Bar$1')
5548
end
5649

5750
specify do
58-
foo_event = FooEvent.new
59-
bar_event = BarEvent.new
60-
event_store.publish_event(foo_event)
6151
expect {
62-
event_store.publish_event(bar_event)
63-
}.to Publish.new.in(event_store){ |events|
64-
expect(events).to eq [bar_event]
65-
}
52+
event_store.publish_event(FooEvent.new)
53+
}.not_to matcher(matchers.an_event(BarEvent)).in(event_store)
54+
end
55+
56+
specify do
57+
expect {
58+
event_store.publish_event(FooEvent.new)
59+
}.to matcher(matchers.an_event(FooEvent)).in(event_store)
60+
end
61+
62+
specify do
63+
expect {
64+
event_store.publish_event(FooEvent.new, stream_name: "Foo$1")
65+
}.to matcher(matchers.an_event(FooEvent)).in(event_store).in_stream("Foo$1")
66+
end
67+
68+
specify do
69+
expect {
70+
event_store.publish_event(FooEvent.new)
71+
}.not_to matcher(matchers.an_event(FooEvent)).in(event_store).in_stream("Foo$1")
6672
end
6773

6874
specify do
@@ -71,39 +77,108 @@ def matcher(*events, &block)
7177
expect {
7278
event_store.publish_event(foo_event, stream_name: "Foo$1")
7379
event_store.publish_event(bar_event, stream_name: "Bar$1")
74-
}.to Publish.new.in(event_store).in_stream("Foo$1"){ |events|
75-
expect(events).to eq [foo_event]
76-
}
80+
}.to matcher(matchers.an_event(FooEvent), matchers.an_event(BarEvent)).in(event_store)
7781
end
7882

7983
specify do
84+
foo_event = FooEvent.new
85+
bar_event = BarEvent.new
86+
87+
event_store.publish_event(foo_event)
8088
expect {
81-
event_store.publish_event(FooEvent.new, stream_name: 'Foo$1')
82-
}.to Publish.new.in(event_store).in_stream('Foo$1')
89+
event_store.publish_event(bar_event)
90+
}.not_to matcher(matchers.an_event(FooEvent)).in(event_store)
8391
end
8492

8593
specify do
8694
expect {
87-
event_store.publish_event(FooEvent.new, stream_name: 'Foo$1')
88-
}.not_to Publish.new.in(event_store).in_stream('Bar$1')
95+
true
96+
}.not_to matcher.in(event_store)
8997
end
9098

9199
specify do
92-
expect {
93-
event_store.publish_event(FooEvent.new)
94-
}.to Publish.new(matchers.an_event(FooEvent)).in(event_store)
100+
_matcher = matcher.in(event_store)
101+
_matcher.matches?(Proc.new { })
102+
103+
expect(_matcher.failure_message_when_negated.to_s).to eq(<<~EOS.strip)
104+
expected block not to have published any events
105+
EOS
95106
end
96107

97108
specify do
98-
expect {
99-
event_store.publish_event(FooEvent.new, stream_name: "Foo$1")
100-
}.to Publish.new(matchers.an_event(FooEvent)).in(event_store).in_stream("Foo$1")
109+
_matcher = matcher.in(event_store)
110+
_matcher.matches?(Proc.new { })
111+
112+
expect(_matcher.failure_message.to_s).to eq(<<~EOS.strip)
113+
expected block to have published any events
114+
EOS
101115
end
102116

103117
specify do
104-
expect {
105-
event_store.publish_event(FooEvent.new)
106-
}.not_to Publish.new(matchers.an_event(FooEvent)).in(event_store).in_stream("Foo$1")
118+
_matcher = matcher(actual = matchers.an_event(FooEvent)).in(event_store)
119+
_matcher.matches?(Proc.new { })
120+
121+
expect(_matcher.failure_message.to_s).to eq(<<~EOS)
122+
expected block to have published:
123+
124+
#{[actual].inspect}
125+
126+
but published:
127+
128+
[]
129+
EOS
130+
end
131+
132+
specify do
133+
_matcher = matcher(actual = matchers.an_event(FooEvent)).in_stream('foo').in(event_store)
134+
_matcher.matches?(Proc.new { })
135+
136+
expect(_matcher.failure_message.to_s).to eq(<<~EOS)
137+
expected block to have published:
138+
139+
#{[actual].inspect}
140+
141+
in stream foo but published:
142+
143+
[]
144+
EOS
145+
end
146+
147+
specify do
148+
foo_event = FooEvent.new
149+
_matcher = matcher(actual = matchers.an_event(FooEvent)).in(event_store)
150+
_matcher.matches?(Proc.new { event_store.publish_event(foo_event) })
151+
152+
expect(_matcher.failure_message_when_negated.to_s).to eq(<<~EOS)
153+
expected block not to have published:
154+
155+
#{[actual].inspect}
156+
157+
but published:
158+
159+
#{[foo_event].inspect}
160+
EOS
161+
end
162+
163+
specify do
164+
foo_event = FooEvent.new
165+
_matcher = matcher(actual = matchers.an_event(FooEvent)).in_stream('foo').in(event_store)
166+
_matcher.matches?(Proc.new { event_store.publish_event(foo_event, stream_name: 'foo') })
167+
168+
expect(_matcher.failure_message_when_negated.to_s).to eq(<<~EOS)
169+
expected block not to have published:
170+
171+
#{[actual].inspect}
172+
173+
in stream foo but published:
174+
175+
#{[foo_event].inspect}
176+
EOS
177+
end
178+
179+
specify do
180+
_matcher = matcher
181+
expect(_matcher.description).to eq("publish events")
107182
end
108183
end
109184
end

0 commit comments

Comments
 (0)