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.
@@ -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(mandatory_expected, *optional_expected, differ:, phraser:)
7
- @expected = [mandatory_expected, *optional_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)
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
- @events = aggregate_root.unpublished_events.to_a
15
- matcher.matches?(events) && matches_count?
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
- @count = count
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
- exactly(1)
30
+ expected.once
31
+ self
30
32
  end
31
33
 
32
34
  def strict
33
- @matcher = ::RSpec::Matchers::BuiltIn::Match.new(expected)
35
+ expected.strict
34
36
  self
35
37
  end
36
38
 
37
39
  def failure_message
38
- "expected #{expected} to be applied, diff:" +
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
- "expected #{expected} not to be applied, diff:" +
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
- def matches_count?
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(mandatory_expected, *optional_expected, differ:, phraser:)
7
- @expected = [mandatory_expected, *optional_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
- @events = event_store.read
15
- @events = events.stream(stream_name) if stream_name
16
- @events = events.from(start) if start
17
- @events = events.each
18
- @matcher.matches?(events) && matches_count?
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
- @count = count
24
+ expected.exactly(count)
23
25
  self
24
26
  end
25
27
 
26
28
  def in_stream(stream_name)
27
- @stream_name = stream_name
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
- @start = event_id
44
+ fetch_events.from(event_id)
38
45
  self
39
46
  end
40
47
 
41
48
  def once
42
- exactly(1)
49
+ expected.once
50
+ self
43
51
  end
44
52
 
45
53
  def failure_message
46
- "expected #{expected} to be published, diff:" +
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
- "expected #{expected} not to be published, diff:" +
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
- @matcher = ::RSpec::Matchers::BuiltIn::Match.new(expected)
66
+ expected.strict
61
67
  self
62
68
  end
63
69
 
64
70
  private
65
71
 
66
- def matches_count?
67
- return true unless count
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 :differ, :phraser, :stream_name, :expected, :count, :events, :start
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.diff_as_string(expected.to_s, subscribed_to.to_s)
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.diff_as_string(expected.to_s, subscribed_to.to_s)
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, differ: differ, phraser: phraser)
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, differ: differ, phraser: phraser)
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::Support::Differ.new(color: ::RSpec::Matchers.configuration.color?)
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
- @event_store = event_store
13
+ fetch_events.in(event_store)
8
14
  self
9
15
  end
10
16
 
11
- def in_stream(stream)
12
- @stream = stream
17
+ def in_stream(stream_name)
18
+ @stream_names = [stream_name]
13
19
  self
14
20
  end
15
21
 
16
- def matches?(event_proc)
17
- raise_event_store_not_set unless @event_store
18
- spec = @event_store.read
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 failure_message
32
- if match_events?
33
- <<-EOS
34
- expected block to have published:
35
-
36
- #{@expected}
27
+ def exactly(count)
28
+ expected.exactly(count)
29
+ self
30
+ end
37
31
 
38
- #{"in stream #{@stream} " if @stream}but published:
32
+ def once
33
+ expected.once
34
+ self
35
+ end
39
36
 
40
- #{@published_events}
41
- EOS
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 failure_message_when_negated
48
- if match_events?
49
- <<-EOS
50
- expected block not to have published:
42
+ def strict
43
+ expected.strict
44
+ self
45
+ end
51
46
 
52
- #{@expected}
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
- #{"in stream #{@stream} " if @stream}but published:
60
+ def failure_message
61
+ failure_message_formatter.failure_message(expected, published_events, failed_on_stream)
62
+ end
55
63
 
56
- #{@published_events}
57
- EOS
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 initialize(*expected)
74
- @expected = expected
78
+ def stream_names
79
+ @stream_names || [nil]
75
80
  end
76
81
 
77
- def match_events?
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