ruby_event_store-rspec 2.0.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +3 -203
- data/lib/ruby_event_store/rspec/apply.rb +32 -46
- data/lib/ruby_event_store/rspec/be_event.rb +15 -13
- data/lib/ruby_event_store/rspec/crude_failure_message_formatter.rb +130 -0
- data/lib/ruby_event_store/rspec/expected_collection.rb +43 -0
- data/lib/ruby_event_store/rspec/fetch_events.rb +33 -0
- data/lib/ruby_event_store/rspec/fetch_unpublished_events.rb +19 -0
- data/lib/ruby_event_store/rspec/have_applied.rb +15 -22
- data/lib/ruby_event_store/rspec/have_published.rb +28 -24
- data/lib/ruby_event_store/rspec/have_subscribed_to_events.rb +2 -2
- data/lib/ruby_event_store/rspec/match_events.rb +32 -0
- data/lib/ruby_event_store/rspec/matchers.rb +5 -5
- data/lib/ruby_event_store/rspec/publish.rb +47 -48
- data/lib/ruby_event_store/rspec/step_by_step_failure_message_formatter.rb +218 -0
- data/lib/ruby_event_store/rspec/version.rb +1 -1
- data/lib/ruby_event_store/rspec.rb +27 -9
- metadata +14 -15
- data/.mutant.yml +0 -1
- data/Gemfile +0 -10
- data/Gemfile.lock +0 -113
- data/Makefile +0 -21
- data/lib/rails_event_store/rspec.rb +0 -13
- data/rails_event_store-rspec.gemspec +0 -36
- data/ruby_event_store-rspec.gemspec +0 -26
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module RubyEventStore
|
|
2
|
+
module RSpec
|
|
3
|
+
class ExpectedCollection
|
|
4
|
+
def initialize(events)
|
|
5
|
+
@events = events
|
|
6
|
+
@strict = false
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def exactly(count)
|
|
10
|
+
raise NotSupported if !events.size.equal?(1)
|
|
11
|
+
raise NotSupported if count < 1
|
|
12
|
+
@count = count
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def empty?
|
|
16
|
+
events.empty?
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def once
|
|
20
|
+
exactly(1)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def specified_count?
|
|
24
|
+
!count.nil?
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def strict
|
|
28
|
+
@strict = true
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def strict?
|
|
32
|
+
@strict
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def event
|
|
36
|
+
raise NotSupported if !events.size.equal?(1)
|
|
37
|
+
events.first
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
attr_reader :events, :count
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module RubyEventStore
|
|
2
|
+
module RSpec
|
|
3
|
+
class FetchEvents
|
|
4
|
+
MissingEventStore = Class.new(StandardError)
|
|
5
|
+
|
|
6
|
+
def from(event_id)
|
|
7
|
+
@start = event_id
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def stream(stream_name)
|
|
11
|
+
@stream_name = stream_name
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def in(event_store)
|
|
15
|
+
@event_store = event_store
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def from_last
|
|
19
|
+
@start = call.last&.event_id
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def call
|
|
23
|
+
raise MissingEventStore if event_store.nil?
|
|
24
|
+
events = event_store.read
|
|
25
|
+
events = events.stream(stream_name) if stream_name
|
|
26
|
+
events = events.from(start) if start
|
|
27
|
+
events
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
attr_reader :start, :stream_name, :event_store
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module RubyEventStore
|
|
2
|
+
module RSpec
|
|
3
|
+
class FetchUnpublishedEvents
|
|
4
|
+
def in(aggregate)
|
|
5
|
+
@aggregate = aggregate
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def call
|
|
9
|
+
aggregate.unpublished_events.to_a
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def aggregate?
|
|
13
|
+
!aggregate.nil?
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
attr_reader :aggregate
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -3,20 +3,21 @@
|
|
|
3
3
|
module RubyEventStore
|
|
4
4
|
module RSpec
|
|
5
5
|
class HaveApplied
|
|
6
|
-
def initialize(
|
|
7
|
-
@expected =
|
|
8
|
-
@
|
|
9
|
-
@differ = differ
|
|
6
|
+
def initialize(*expected, phraser:, failure_message_formatter:)
|
|
7
|
+
@expected = ExpectedCollection.new(expected)
|
|
8
|
+
@failure_message_formatter = failure_message_formatter
|
|
10
9
|
@phraser = phraser
|
|
10
|
+
@fetch_events = FetchUnpublishedEvents.new
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def matches?(aggregate_root)
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
fetch_events.in(aggregate_root)
|
|
15
|
+
@events = fetch_events.call
|
|
16
|
+
MatchEvents.new.call(expected, events)
|
|
16
17
|
end
|
|
17
18
|
|
|
18
19
|
def exactly(count)
|
|
19
|
-
|
|
20
|
+
expected.exactly(count)
|
|
20
21
|
self
|
|
21
22
|
end
|
|
22
23
|
|
|
@@ -26,38 +27,30 @@ module RubyEventStore
|
|
|
26
27
|
alias :time :times
|
|
27
28
|
|
|
28
29
|
def once
|
|
29
|
-
|
|
30
|
+
expected.once
|
|
31
|
+
self
|
|
30
32
|
end
|
|
31
33
|
|
|
32
34
|
def strict
|
|
33
|
-
|
|
35
|
+
expected.strict
|
|
34
36
|
self
|
|
35
37
|
end
|
|
36
38
|
|
|
37
39
|
def failure_message
|
|
38
|
-
|
|
39
|
-
differ.diff_as_string(expected.to_s, events.to_s)
|
|
40
|
+
failure_message_formatter.failure_message(expected, events)
|
|
40
41
|
end
|
|
41
42
|
|
|
42
43
|
def failure_message_when_negated
|
|
43
|
-
|
|
44
|
-
differ.diff_as_string(expected.inspect, events.inspect)
|
|
44
|
+
failure_message_formatter.failure_message_when_negated(expected, events)
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
def description
|
|
48
|
-
"have applied events that have to (#{phraser.(expected)})"
|
|
48
|
+
"have applied events that have to (#{phraser.(expected.events)})"
|
|
49
49
|
end
|
|
50
50
|
|
|
51
51
|
private
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
return true unless count
|
|
55
|
-
raise NotSupported if expected.size > 1
|
|
56
|
-
events.select { |e| expected.first === e }.size.equal?(count)
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
attr_reader :differ, :phraser, :expected, :events, :count, :matcher
|
|
53
|
+
attr_reader :phraser, :expected, :events, :failure_message_formatter, :fetch_events
|
|
60
54
|
end
|
|
61
55
|
end
|
|
62
56
|
end
|
|
63
|
-
|
|
@@ -3,28 +3,35 @@
|
|
|
3
3
|
module RubyEventStore
|
|
4
4
|
module RSpec
|
|
5
5
|
class HavePublished
|
|
6
|
-
def initialize(
|
|
7
|
-
@expected =
|
|
8
|
-
@matcher = ::RSpec::Matchers::BuiltIn::Include.new(*expected)
|
|
9
|
-
@differ = differ
|
|
6
|
+
def initialize(*expected, phraser:, failure_message_formatter:)
|
|
7
|
+
@expected = ExpectedCollection.new(expected)
|
|
10
8
|
@phraser = phraser
|
|
9
|
+
@failure_message_formatter = failure_message_formatter
|
|
10
|
+
@fetch_events = FetchEvents.new
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def matches?(event_store)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
stream_names.all? do |stream_name|
|
|
15
|
+
fetch_events.stream(stream_name)
|
|
16
|
+
fetch_events.in(event_store)
|
|
17
|
+
@published_events = fetch_events.call.to_a
|
|
18
|
+
@failed_on_stream = stream_name
|
|
19
|
+
MatchEvents.new.call(expected, published_events)
|
|
20
|
+
end
|
|
19
21
|
end
|
|
20
22
|
|
|
21
23
|
def exactly(count)
|
|
22
|
-
|
|
24
|
+
expected.exactly(count)
|
|
23
25
|
self
|
|
24
26
|
end
|
|
25
27
|
|
|
26
28
|
def in_stream(stream_name)
|
|
27
|
-
@
|
|
29
|
+
@stream_names = [stream_name]
|
|
30
|
+
self
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def in_streams(stream_names)
|
|
34
|
+
@stream_names = Array(stream_names)
|
|
28
35
|
self
|
|
29
36
|
end
|
|
30
37
|
|
|
@@ -34,42 +41,39 @@ module RubyEventStore
|
|
|
34
41
|
alias :time :times
|
|
35
42
|
|
|
36
43
|
def from(event_id)
|
|
37
|
-
|
|
44
|
+
fetch_events.from(event_id)
|
|
38
45
|
self
|
|
39
46
|
end
|
|
40
47
|
|
|
41
48
|
def once
|
|
42
|
-
|
|
49
|
+
expected.once
|
|
50
|
+
self
|
|
43
51
|
end
|
|
44
52
|
|
|
45
53
|
def failure_message
|
|
46
|
-
|
|
47
|
-
differ.diff_as_string(expected.to_s, events.to_a.to_s)
|
|
54
|
+
failure_message_formatter.failure_message(expected, published_events, failed_on_stream)
|
|
48
55
|
end
|
|
49
56
|
|
|
50
57
|
def failure_message_when_negated
|
|
51
|
-
|
|
52
|
-
differ.diff_as_string(expected.to_s, events.to_a.to_s)
|
|
58
|
+
failure_message_formatter.failure_message_when_negated(expected, published_events, failed_on_stream)
|
|
53
59
|
end
|
|
54
60
|
|
|
55
61
|
def description
|
|
56
|
-
"have published events that have to (#{phraser.(expected)})"
|
|
62
|
+
"have published events that have to (#{phraser.(expected.events)})"
|
|
57
63
|
end
|
|
58
64
|
|
|
59
65
|
def strict
|
|
60
|
-
|
|
66
|
+
expected.strict
|
|
61
67
|
self
|
|
62
68
|
end
|
|
63
69
|
|
|
64
70
|
private
|
|
65
71
|
|
|
66
|
-
def
|
|
67
|
-
|
|
68
|
-
raise NotSupported if expected.size > 1
|
|
69
|
-
events.select { |e| expected.first === e }.size.equal?(count)
|
|
72
|
+
def stream_names
|
|
73
|
+
@stream_names || [nil]
|
|
70
74
|
end
|
|
71
75
|
|
|
72
|
-
attr_reader :
|
|
76
|
+
attr_reader :phraser, :expected, :published_events, :failed_on_stream, :failure_message_formatter, :fetch_events
|
|
73
77
|
end
|
|
74
78
|
end
|
|
75
79
|
end
|
|
@@ -26,12 +26,12 @@ module RubyEventStore
|
|
|
26
26
|
|
|
27
27
|
def failure_message
|
|
28
28
|
"expected #{handler} to be subscribed to events, diff:" +
|
|
29
|
-
differ.
|
|
29
|
+
differ.diff(expected.to_s + "\n", subscribed_to)
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
def failure_message_when_negated
|
|
33
33
|
"expected #{handler} not to be subscribed to events, diff:" +
|
|
34
|
-
differ.
|
|
34
|
+
differ.diff(expected.to_s + "\n", subscribed_to)
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
def description
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module RubyEventStore
|
|
2
|
+
module RSpec
|
|
3
|
+
class MatchEvents
|
|
4
|
+
def call(expected, events)
|
|
5
|
+
if match_events?(expected)
|
|
6
|
+
matcher(expected).matches?(events) && matches_count?(expected, events)
|
|
7
|
+
else
|
|
8
|
+
!events.empty?
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
def matches_count?(expected, events)
|
|
15
|
+
return true unless expected.specified_count?
|
|
16
|
+
events.select { |e| expected.event === e }.size.equal?(expected.count)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def matcher(expected)
|
|
20
|
+
if expected.strict?
|
|
21
|
+
::RSpec::Matchers::BuiltIn::Match.new(expected.events)
|
|
22
|
+
else
|
|
23
|
+
::RSpec::Matchers::BuiltIn::Include.new(*expected.events)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def match_events?(expected)
|
|
28
|
+
!expected.empty?
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -39,11 +39,11 @@ module RubyEventStore
|
|
|
39
39
|
alias :event :be_an_event
|
|
40
40
|
|
|
41
41
|
def have_published(*expected)
|
|
42
|
-
HavePublished.new(*expected,
|
|
42
|
+
HavePublished.new(*expected, phraser: phraser, failure_message_formatter: RSpec.default_formatter.have_published(differ))
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
def have_applied(*expected)
|
|
46
|
-
HaveApplied.new(*expected,
|
|
46
|
+
HaveApplied.new(*expected, phraser: phraser, failure_message_formatter: RSpec.default_formatter.have_applied(differ))
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
def have_subscribed_to_events(*expected)
|
|
@@ -51,11 +51,11 @@ module RubyEventStore
|
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
def publish(*expected)
|
|
54
|
-
Publish.new(*expected)
|
|
54
|
+
Publish.new(*expected, failure_message_formatter: RSpec.default_formatter.publish(differ))
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
def apply(*expected)
|
|
58
|
-
Apply.new(*expected)
|
|
58
|
+
Apply.new(*expected, failure_message_formatter: RSpec.default_formatter.apply(differ))
|
|
59
59
|
end
|
|
60
60
|
|
|
61
61
|
private
|
|
@@ -65,7 +65,7 @@ module RubyEventStore
|
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
def differ
|
|
68
|
-
::RSpec::
|
|
68
|
+
::RSpec::Expectations.differ
|
|
69
69
|
end
|
|
70
70
|
|
|
71
71
|
def phraser
|
|
@@ -3,61 +3,66 @@
|
|
|
3
3
|
module RubyEventStore
|
|
4
4
|
module RSpec
|
|
5
5
|
class Publish
|
|
6
|
+
def initialize(*expected, failure_message_formatter:)
|
|
7
|
+
@expected = ExpectedCollection.new(expected)
|
|
8
|
+
@failure_message_formatter = failure_message_formatter
|
|
9
|
+
@fetch_events = FetchEvents.new
|
|
10
|
+
end
|
|
11
|
+
|
|
6
12
|
def in(event_store)
|
|
7
|
-
|
|
13
|
+
fetch_events.in(event_store)
|
|
8
14
|
self
|
|
9
15
|
end
|
|
10
16
|
|
|
11
|
-
def in_stream(
|
|
12
|
-
@
|
|
17
|
+
def in_stream(stream_name)
|
|
18
|
+
@stream_names = [stream_name]
|
|
13
19
|
self
|
|
14
20
|
end
|
|
15
21
|
|
|
16
|
-
def
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
spec = spec.stream(@stream) if @stream
|
|
20
|
-
last_event_before_block = spec.last
|
|
21
|
-
event_proc.call
|
|
22
|
-
spec = spec.from(last_event_before_block.event_id) if last_event_before_block
|
|
23
|
-
@published_events = spec.to_a
|
|
24
|
-
if match_events?
|
|
25
|
-
::RSpec::Matchers::BuiltIn::Include.new(*@expected).matches?(@published_events)
|
|
26
|
-
else
|
|
27
|
-
!@published_events.empty?
|
|
28
|
-
end
|
|
22
|
+
def in_streams(stream_names)
|
|
23
|
+
@stream_names = Array(stream_names)
|
|
24
|
+
self
|
|
29
25
|
end
|
|
30
26
|
|
|
31
|
-
def
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
#{@expected}
|
|
27
|
+
def exactly(count)
|
|
28
|
+
expected.exactly(count)
|
|
29
|
+
self
|
|
30
|
+
end
|
|
37
31
|
|
|
38
|
-
|
|
32
|
+
def once
|
|
33
|
+
expected.once
|
|
34
|
+
self
|
|
35
|
+
end
|
|
39
36
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
else
|
|
43
|
-
"expected block to have published any events"
|
|
44
|
-
end
|
|
37
|
+
def times
|
|
38
|
+
self
|
|
45
39
|
end
|
|
40
|
+
alias :time :times
|
|
46
41
|
|
|
47
|
-
def
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
42
|
+
def strict
|
|
43
|
+
expected.strict
|
|
44
|
+
self
|
|
45
|
+
end
|
|
51
46
|
|
|
52
|
-
|
|
47
|
+
def matches?(event_proc)
|
|
48
|
+
fetch_events.from_last
|
|
49
|
+
event_proc.call
|
|
50
|
+
stream_names.all? do |stream_name|
|
|
51
|
+
fetch_events.stream(stream_name)
|
|
52
|
+
@published_events = fetch_events.call.to_a
|
|
53
|
+
@failed_on_stream = stream_name
|
|
54
|
+
MatchEvents.new.call(expected, published_events)
|
|
55
|
+
end
|
|
56
|
+
rescue FetchEvents::MissingEventStore
|
|
57
|
+
raise "You have to set the event store instance with `in`, e.g. `expect { ... }.to publish(an_event(MyEvent)).in(event_store)`"
|
|
58
|
+
end
|
|
53
59
|
|
|
54
|
-
|
|
60
|
+
def failure_message
|
|
61
|
+
failure_message_formatter.failure_message(expected, published_events, failed_on_stream)
|
|
62
|
+
end
|
|
55
63
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
else
|
|
59
|
-
"expected block not to have published any events"
|
|
60
|
-
end
|
|
64
|
+
def failure_message_when_negated
|
|
65
|
+
failure_message_formatter.failure_message_when_negated(expected, published_events, fetch_events.stream_name)
|
|
61
66
|
end
|
|
62
67
|
|
|
63
68
|
def description
|
|
@@ -70,17 +75,11 @@ EOS
|
|
|
70
75
|
|
|
71
76
|
private
|
|
72
77
|
|
|
73
|
-
def
|
|
74
|
-
@
|
|
78
|
+
def stream_names
|
|
79
|
+
@stream_names || [nil]
|
|
75
80
|
end
|
|
76
81
|
|
|
77
|
-
|
|
78
|
-
!@expected.empty?
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
def raise_event_store_not_set
|
|
82
|
-
raise SyntaxError, "You have to set the event store instance with `in`, e.g. `expect { ... }.to publish(an_event(MyEvent)).in(event_store)`"
|
|
83
|
-
end
|
|
82
|
+
attr_reader :fetch_events, :expected, :failure_message_formatter, :published_events, :failed_on_stream
|
|
84
83
|
end
|
|
85
84
|
end
|
|
86
85
|
end
|