rails_event_store-rspec 1.2.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 423fac8f9b88ddd6eb218e780bd75fbfca415712af91cdb1a5b77f29cf002d96
4
- data.tar.gz: b3e1e45b28a863f9779778a5d18663e812a234446d170bb1c1679a88a7fdb09e
3
+ metadata.gz: 2c95b7db6717db69badde15ba43c2ccb135c05a2e80eb92e805994995f26b874
4
+ data.tar.gz: 9c8f0a8d5c15eb3b2a01becd177ccbe689df15a1925816b884bcbb7f72009f25
5
5
  SHA512:
6
- metadata.gz: 3c5c513a50dc86b2e01f024dfeaaf1e8c7ccb4fed8bc0469632cdc2be908ac925bb90a32b6b824747f4e300c6ebcbc489fe40bce3a33e54098d78fe63f68eb1d
7
- data.tar.gz: 52533c481ed01efe0a95d578b6f835e94bd1dddb11c77f8e54b580365b191835fe69295a9f12fbad37a2a9a4525fdf7b7bbe40445fd11f983bee06574394ad2f
6
+ metadata.gz: f61dc21b907b91bd13c282beb1f43428d08ded5c85207347f6fdc0222269b1a24f4c0610cf031500bc79cb21ab365aa4546515292bc2fa03a44d415a19f05148
7
+ data.tar.gz: f00077b88d89fad39d62b97625310f84d5397d080cfc445236d021e7eb135f6da6c963ecb3f7b3cc2a558422e618ba76c61e444c5b13a74287f1503f9e313b06
@@ -1,21 +1,13 @@
1
- # frozen_string_literal: true
1
+ require 'ruby_event_store/rspec'
2
2
 
3
- require 'rspec'
3
+ warn <<~EOW
4
+ The 'rails_event_store-rspec' gem has been renamed.
4
5
 
5
- module RailsEventStore
6
- module RSpec
7
- NotSupported = Class.new(StandardError)
8
- end
9
- end
6
+ Please change your Gemfile or gemspec
7
+ to reflect its new name:
10
8
 
11
- require "rails_event_store/rspec/version"
12
- require "rails_event_store/rspec/be_event"
13
- require "rails_event_store/rspec/have_published"
14
- require "rails_event_store/rspec/have_applied"
15
- require "rails_event_store/rspec/publish"
16
- require "rails_event_store/rspec/apply"
17
- require "rails_event_store/rspec/matchers"
9
+ 'ruby_event_store-rspec'
18
10
 
19
- ::RSpec.configure do |config|
20
- config.include ::RailsEventStore::RSpec::Matchers
21
- end
11
+ EOW
12
+
13
+ RailsEventStore::RSpec = RubyEventStore::RSpec
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_event_store-rspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arkency
8
8
  autorequire:
9
- bindir: exe
9
+ bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-30 00:00:00.000000000 Z
11
+ date: 2021-01-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -25,19 +25,19 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '3.0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: diff-lcs
28
+ name: ruby_event_store-rspec
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - '='
32
32
  - !ruby/object:Gem::Version
33
- version: 1.4.4
33
+ version: 2.0.1
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - '='
39
39
  - !ruby/object:Gem::Version
40
- version: 1.4.4
40
+ version: 2.0.1
41
41
  description:
42
42
  email:
43
43
  - dev@arkency.com
@@ -45,21 +45,7 @@ executables: []
45
45
  extensions: []
46
46
  extra_rdoc_files: []
47
47
  files:
48
- - ".gitignore"
49
- - Gemfile
50
- - Makefile
51
- - README.md
52
- - bin/console
53
- - bin/setup
54
48
  - lib/rails_event_store/rspec.rb
55
- - lib/rails_event_store/rspec/apply.rb
56
- - lib/rails_event_store/rspec/be_event.rb
57
- - lib/rails_event_store/rspec/have_applied.rb
58
- - lib/rails_event_store/rspec/have_published.rb
59
- - lib/rails_event_store/rspec/matchers.rb
60
- - lib/rails_event_store/rspec/publish.rb
61
- - lib/rails_event_store/rspec/version.rb
62
- - rails_event_store-rspec.gemspec
63
49
  homepage: https://railseventstore.org
64
50
  licenses:
65
51
  - MIT
@@ -68,7 +54,14 @@ metadata:
68
54
  changelog_uri: https://github.com/RailsEventStore/rails_event_store/releases
69
55
  source_code_uri: https://github.com/RailsEventStore/rails_event_store
70
56
  bug_tracker_uri: https://github.com/RailsEventStore/rails_event_store/issues
71
- post_install_message:
57
+ post_install_message: |+
58
+ The 'rails_event_store-rspec' gem has been renamed.
59
+
60
+ Please change your Gemfile or gemspec
61
+ to reflect its new name:
62
+
63
+ 'ruby_event_store-rspec'
64
+
72
65
  rdoc_options: []
73
66
  require_paths:
74
67
  - lib
@@ -88,3 +81,4 @@ signing_key:
88
81
  specification_version: 4
89
82
  summary: RSpec matchers for RailsEventStore
90
83
  test_files: []
84
+ ...
data/.gitignore DELETED
@@ -1,12 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /Gemfile.lock
4
- /_yardoc/
5
- /coverage/
6
- /doc/
7
- /pkg/
8
- /spec/reports/
9
- /tmp/
10
-
11
- # rspec failure tracking
12
- .rspec_status
data/Gemfile DELETED
@@ -1,13 +0,0 @@
1
- source 'https://rubygems.org'
2
- git_source(:github) { |repo| "https://github.com/#{repo}.git" }
3
- gemspec
4
-
5
- eval_gemfile File.expand_path('../support/bundler/Gemfile.shared', __dir__)
6
-
7
- gem 'rails_event_store', path: '../rails_event_store'
8
- gem 'rails_event_store_active_record', path: '../rails_event_store_active_record'
9
- gem 'ruby_event_store', path: '../ruby_event_store'
10
- gem 'ruby_event_store-browser', path: '../ruby_event_store-browser'
11
- gem 'aggregate_root', path: '../aggregate_root'
12
- gem 'bounded_context', path: '../bounded_context'
13
- gem 'rails', ENV['RAILS_VERSION']
data/Makefile DELETED
@@ -1,18 +0,0 @@
1
- GEM_VERSION = $(shell cat ../RES_VERSION)
2
- GEM_NAME = rails_event_store-rspec
3
- REQUIRE = rails_event_store/rspec
4
- IGNORE = RailsEventStore::RSpec::Matchers\#differ \
5
- RailsEventStore::RSpec::Matchers\#formatter \
6
- RailsEventStore::RSpec::Matchers\#have_published \
7
- RailsEventStore::RSpec::Matchers\#have_applied \
8
- RailsEventStore::RSpec::Matchers\#publish \
9
- RailsEventStore::RSpec::Matchers\#be_an_event \
10
- RailsEventStore::RSpec::Publish\#last_event
11
- SUBJECT ?= RailsEventStore::RSpec*
12
- DATABASE_URL ?= sqlite3::memory:
13
-
14
- include ../support/make/install.mk
15
- include ../support/make/test.mk
16
- include ../support/make/mutant.mk
17
- include ../support/make/gem.mk
18
- include ../support/make/help.mk
data/README.md DELETED
@@ -1,192 +0,0 @@
1
- # RailsEventStore::RSpec
2
-
3
- ## Installation
4
-
5
- Add this line to your application's Gemfile:
6
-
7
- ```ruby
8
- group :test do
9
- gem 'rails_event_store-rspec'
10
- end
11
- ```
12
-
13
- ## Usage
14
-
15
- ### be_event
16
-
17
- The `be_event` matcher enables you to make expectations on a domain event. It exposes fluent interface.
18
-
19
- ```ruby
20
- OrderPlaced = Class.new(RailsEventStore::Event)
21
- domain_event = OrderPlaced.new(
22
- data: {
23
- order_id: 42,
24
- net_value: BigDecimal.new("1999.0")
25
- },
26
- metadata: {
27
- remote_ip: '1.2.3.4'
28
- }
29
- )
30
-
31
- expect(domain_event)
32
- .to(be_an_event(OrderPlaced)
33
- .with_data(order_id: 42, net_value: BigDecimal.new("1999.0"))
34
- .with_metadata(remote_ip: '1.2.3.4'))
35
- ```
36
-
37
- By default the behaviour of `with_data` and `with_metadata` is not strict, that is the expectation is met when all specified values for keys match. Additional data or metadata that is not specified to be expected does not change the outcome.
38
-
39
- ```ruby
40
- domain_event = OrderPlaced.new(
41
- data: {
42
- order_id: 42,
43
- net_value: BigDecimal.new("1999.0")
44
- }
45
- )
46
-
47
- # this would pass even though data contains also net_value
48
- expect(domain_event).to be_an_event(OrderPlaced).with_data(order_id: 42)
49
- ```
50
-
51
- This matcher is both [composable](http://rspec.info/blog/2014/01/new-in-rspec-3-composable-matchers/) and accepting [built-in matchers](https://relishapp.com/rspec/rspec-expectations/v/3-6/docs/built-in-matchers) as a part of an expectation.
52
-
53
- ```ruby
54
- expect(domain_event).to be_an_event(OrderPlaced).with_data(order_id: kind_of(Integer))
55
- expect([domain_event]).to include(an_event(OrderPlaced))
56
- ```
57
-
58
- If you depend on matching the exact data or metadata, there's a `strict` modifier.
59
-
60
- ```ruby
61
- domain_event = OrderPlaced.new(
62
- data: {
63
- order_id: 42,
64
- net_value: BigDecimal.new("1999.0")
65
- }
66
- )
67
-
68
- # this would fail as data contains unexpected net_value
69
- expect(domain_event).to be_an_event(OrderPlaced).with_data(order_id: 42).strict
70
- ```
71
-
72
- Mind that `strict` makes both `with_data` and `with_metadata` behave in a stricter way. If you need to mix both, i.e. strict data but non-strict metadata then consider composing matchers.
73
-
74
- ```ruby
75
- expect(domain_event)
76
- .to(be_event(OrderPlaced).with_data(order_id: 42, net_value: BigDecimal.new("1999.0")).strict
77
- .and(an_event(OrderPlaced).with_metadata(timestamp: kind_of(Time)))
78
- ```
79
-
80
- You may have noticed the same matcher being referenced as `be_event`, `be_an_event` and `an_event`. There's also just `event`. Use whichever reads better grammatically.
81
-
82
- ### have_published
83
-
84
- Use this matcher to target `event_store` and reading from streams specifically.
85
- In a simplest form it would read all streams backward up to a page limit (100 events) and check whether the expectation holds true. Its behaviour can be best compared to the `include` matcher — it is satisfied by at least one element present in the collection. You're encouraged to compose it with `be_event`.
86
-
87
- ```ruby
88
- event_store = RailsEventStore::Client.new
89
- event_store.publish(OrderPlaced.new(data: { order_id: 42 }))
90
-
91
- expect(event_store).to have_published(an_event(OrderPlaced))
92
- ```
93
-
94
- Expectation can be narrowed to the specific stream.
95
-
96
- ```ruby
97
- event_store = RailsEventStore::Client.new
98
- event_store.publish(OrderPlaced.new(data: { order_id: 42 }), stream_name: "Order$42")
99
-
100
- expect(event_store).to have_published(an_event(OrderPlaced)).in_stream("Order$42")
101
- ```
102
-
103
- It is sometimes important to ensure no additional events have been published. Luckliy there's a modifier to cover that usecase.
104
-
105
- ```ruby
106
- expect(event_store).not_to have_published(an_event(OrderPlaced)).once
107
- expect(event_store).to have_published(an_event(OrderPlaced)).exactly(2).times
108
- ```
109
-
110
- Finally you can make expectation on several events at once.
111
-
112
- ```ruby
113
- expect(event_store).to have_published(
114
- an_event(OrderPlaced),
115
- an_event(OrderExpired).with_data(expired_at: be_between(Date.yesterday, Date.tomorrow))
116
- )
117
- ```
118
-
119
- If there's a usecase not covered by examples above or you need a different set of events to make expectations on you can always resort to a more verbose approach and skip `have_published`.
120
-
121
- ```ruby
122
- expect(event_store.read_events_forward("OrderAuditLog$42", count: 2)).to eq([
123
- an_event(OrderPlaced),
124
- an_event(OrderExpired)
125
- ])
126
- ```
127
-
128
- ### have_applied
129
-
130
- This matcher is intended to be used on [aggregate root](https://github.com/RailsEventStore/rails_event_store/tree/master/aggregate_root#usage). Behaviour is almost identical to `have_published` counterpart, except the concept of stream. Expecations are made against internal unpublished events collection.
131
-
132
- ```ruby
133
- class Order
134
- include AggregateRoot
135
- HasBeenAlreadySubmitted = Class.new(StandardError)
136
- HasExpired = Class.new(StandardError)
137
-
138
- def initialize
139
- self.state = :new
140
- # any other code here
141
- end
142
-
143
- def submit
144
- raise HasBeenAlreadySubmitted if state == :submitted
145
- raise HasExpired if state == :expired
146
- apply OrderSubmitted.new(data: {delivery_date: Time.now + 24.hours})
147
- end
148
-
149
- def expire
150
- apply OrderExpired.new
151
- end
152
-
153
- private
154
- attr_accessor :state
155
-
156
- def apply_order_submitted(event)
157
- self.state = :submitted
158
- end
159
-
160
- def apply_order_expired(event)
161
- self.state = :expired
162
- end
163
- end
164
- ```
165
-
166
- ```ruby
167
- aggregate_root = Order.new
168
- aggregate_root.submit
169
-
170
- expect(aggregate_root).to have_applied(event(OrderSubmitted)).once
171
- ```
172
- ## Code status
173
-
174
- [![Build Status](https://travis-ci.org/RailsEventStore/rails_event_store-rspec.svg?branch=master)](https://travis-ci.org/RailsEventStore/rails_event_store-rspec)
175
- [![Gem Version](https://badge.fury.io/rb/rails_event_store-rspec.svg)](https://badge.fury.io/rb/rails_event_store-rspec)
176
-
177
- We're aiming for 100% mutation coverage in this project. This is why:
178
-
179
- * [Why I want to introduce mutation testing to the rails_event_store gem](https://blog.arkency.com/2015/04/why-i-want-to-introduce-mutation-testing-to-the-rails-event-store-gem/)
180
- * [Mutation testing and continuous integration](https://blog.arkency.com/2015/05/mutation-testing-and-continuous-integration/)
181
-
182
- Whenever you fix a bug or add a new feature, we require that the coverage doesn't go down.
183
-
184
- ## Development
185
-
186
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
187
-
188
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
189
-
190
- ## Contributing
191
-
192
- Bug reports and pull requests are welcome on GitHub at https://github.com/RailsEventStore/rails_event_store-rspec.
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "bundler/setup"
4
- require "rails_event_store/rspec"
5
-
6
- # You can add fixtures and/or initialization code here to make experimenting
7
- # with your gem easier. You can also use a different console, if you like.
8
-
9
- # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
12
-
13
- require "irb"
14
- IRB.start(__FILE__)
data/bin/setup DELETED
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install
7
-
8
- # Do any other automated setup that you need to do here
@@ -1,84 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RailsEventStore
4
- module RSpec
5
- class Apply
6
- def in(aggregate)
7
- @aggregate = aggregate
8
- self
9
- end
10
-
11
- def strict
12
- @matcher = ::RSpec::Matchers::BuiltIn::Match.new(@expected)
13
- self
14
- end
15
-
16
- def matches?(event_proc)
17
- raise_aggregate_not_set unless @aggregate
18
- before = @aggregate.unpublished_events.to_a
19
- event_proc.call
20
- @applied_events = @aggregate.unpublished_events.to_a - before
21
- if match_events?
22
- @matcher.matches?(@applied_events)
23
- else
24
- !@applied_events.empty?
25
- end
26
- end
27
-
28
- def failure_message
29
- if match_events?
30
- <<-EOS
31
- expected block to have applied:
32
-
33
- #{@expected}
34
-
35
- but applied:
36
-
37
- #{@applied_events}
38
- EOS
39
- else
40
- "expected block to have applied any events"
41
- end
42
- end
43
-
44
- def failure_message_when_negated
45
- if match_events?
46
- <<-EOS
47
- expected block not to have applied:
48
-
49
- #{@expected}
50
-
51
- but applied:
52
-
53
- #{@applied_events}
54
- EOS
55
- else
56
- "expected block not to have applied any events"
57
- end
58
- end
59
-
60
- def description
61
- "apply events"
62
- end
63
-
64
- def supports_block_expectations?
65
- true
66
- end
67
-
68
- private
69
-
70
- def initialize(*expected)
71
- @expected = expected
72
- @matcher = ::RSpec::Matchers::BuiltIn::Include.new(*expected)
73
- end
74
-
75
- def match_events?
76
- !@expected.empty?
77
- end
78
-
79
- def raise_aggregate_not_set
80
- raise SyntaxError, "You have to set the aggregate instance with `in`, e.g. `expect { ... }.to apply(an_event(MyEvent)).in(aggregate)`"
81
- end
82
- end
83
- end
84
- end
@@ -1,190 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RailsEventStore
4
- module RSpec
5
- class BeEvent
6
- class KindMatcher
7
- def initialize(expected)
8
- @expected = expected
9
- end
10
-
11
- def matches?(actual)
12
- @expected === actual
13
- end
14
- end
15
-
16
- class DataMatcher
17
- def initialize(expected, strict:)
18
- @strict = strict
19
- @expected = expected
20
- end
21
-
22
- def matches?(actual)
23
- return true unless @expected
24
- matcher = @strict ? ::RSpec::Matchers::BuiltIn::Match : ::RSpec::Matchers::BuiltIn::Include
25
- matcher.new(@expected).matches?(actual)
26
- end
27
- end
28
-
29
- class FailureMessage
30
- class ExpectedLine
31
- def initialize(expected_klass, expected_metadata, expected_data)
32
- @expected_klass = expected_klass
33
- @expected_metadata = expected_metadata
34
- @expected_data = expected_data
35
- end
36
-
37
- def to_s
38
- ["\nexpected: ", @expected_klass, with, metadata, data]
39
- end
40
-
41
- private
42
-
43
- def with
44
- " with" if [@expected_data, @expected_metadata].any?
45
- end
46
-
47
- def data
48
- [" data: ", @expected_data] if @expected_data
49
- end
50
-
51
- def metadata
52
- [" metadata: ", @expected_metadata] if @expected_metadata
53
- end
54
- end
55
-
56
- class ActualLine
57
- def initialize(actual_klass, actual_metadata, actual_data, expected_metadata, expected_data)
58
- @actual_klass = actual_klass
59
- @actual_metadata = actual_metadata
60
- @actual_data = actual_data
61
- @expected_metadata = expected_metadata
62
- @expected_data = expected_data
63
- end
64
-
65
- def to_s
66
- ["\n got: ", @actual_klass, with, metadata, data, "\n"]
67
- end
68
-
69
- private
70
-
71
- def with
72
- " with" if [@expected_data, @expected_metadata].any?
73
- end
74
-
75
- def data
76
- [" data: ", @actual_data] if @expected_data
77
- end
78
-
79
- def metadata
80
- [" metadata: ", @actual_metadata] if @expected_metadata
81
- end
82
- end
83
-
84
- class Diff
85
- def initialize(actual, expected, label, differ:)
86
- @actual = actual
87
- @expected = expected
88
- @label = label
89
- @differ = differ
90
- end
91
-
92
- def to_s
93
- @expected && ["\n#{@label} diff:", @differ.diff_as_string(@actual.to_s, @expected.to_s)]
94
- end
95
- end
96
-
97
- def initialize(expected_klass, actual_klass, expected_data, actual_data, expected_metadata, actual_metadata, differ:)
98
- @expected_klass = expected_klass
99
- @actual_klass = actual_klass
100
- @expected_data = expected_data
101
- @actual_data = actual_data
102
- @expected_metadata = expected_metadata
103
- @actual_metadata = actual_metadata
104
- @differ = differ
105
- end
106
-
107
- def to_s
108
- [
109
- ExpectedLine.new(@expected_klass, @expected_metadata, @expected_data),
110
- ActualLine.new(@actual_klass, @actual_metadata.to_h, @actual_data, @expected_metadata, @expected_data),
111
- Diff.new(@actual_metadata.to_h, @expected_metadata, "Metadata", differ: @differ),
112
- Diff.new(@actual_data, @expected_data, "Data", differ: @differ)
113
- ].map(&:to_s).join
114
- end
115
- end
116
-
117
- include ::RSpec::Matchers::Composable
118
-
119
- def initialize(expected, differ:, formatter:)
120
- @expected = expected
121
- @differ = differ
122
- @formatter = formatter
123
- end
124
-
125
- def matches?(actual)
126
- @actual = actual
127
- matches_kind && matches_data && matches_metadata
128
- end
129
-
130
- def with_data(expected_data)
131
- @expected_data = expected_data
132
- self
133
- end
134
-
135
- def with_metadata(expected_metadata)
136
- @expected_metadata = expected_metadata
137
- self
138
- end
139
-
140
- def failure_message
141
- FailureMessage.new(expected, actual.class, expected_data, actual.try(:data), expected_metadata, actual.try(:metadata), differ: differ).to_s
142
- end
143
-
144
- def failure_message_when_negated
145
- %Q{
146
- expected: not a kind of #{expected}
147
- got: #{actual.class}
148
- }
149
- end
150
-
151
- def strict
152
- @strict = true
153
- self
154
- end
155
-
156
- def description
157
- "be an event #{formatter.(expected)}#{data_and_metadata_expectations_description}"
158
- end
159
-
160
- def data_and_metadata_expectations_description
161
- predicate = strict? ? "matching" : "including"
162
- expectation_list = []
163
- expectation_list << "with data #{predicate} #{formatter.(expected_data)}" if expected_data
164
- expectation_list << "with metadata #{predicate} #{formatter.(expected_metadata)}" if expected_metadata
165
- " (#{expectation_list.join(" and ")})" if expectation_list.any?
166
- end
167
-
168
- private
169
-
170
- def matches_kind
171
- KindMatcher.new(expected).matches?(actual)
172
- end
173
-
174
- def matches_data
175
- DataMatcher.new(expected_data, strict: strict?).matches?(actual.data)
176
- end
177
-
178
- def matches_metadata
179
- DataMatcher.new(expected_metadata, strict: strict?).matches?(actual.metadata.to_h)
180
- end
181
-
182
- attr_reader :expected_metadata, :expected_data, :actual, :expected, :differ, :formatter
183
-
184
- def strict?
185
- @strict
186
- end
187
- end
188
- end
189
- end
190
-
@@ -1,66 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RailsEventStore
4
- module RSpec
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
10
- @phraser = phraser
11
- end
12
-
13
- def matches?(aggregate_root)
14
- @events = aggregate_root.unpublished_events.to_a
15
- matcher.matches?(events) && matches_count?
16
- end
17
-
18
- def exactly(count)
19
- @count = count
20
- self
21
- end
22
-
23
- def times
24
- self
25
- end
26
- alias :time :times
27
-
28
- def once
29
- exactly(1)
30
- end
31
-
32
- def strict
33
- @matcher = ::RSpec::Matchers::BuiltIn::Match.new(expected)
34
- self
35
- end
36
-
37
- def failure_message
38
- "expected #{expected} to be applied, diff:" +
39
- differ.diff_as_string(expected.to_s, events.to_s)
40
- end
41
-
42
- def failure_message_when_negated
43
- "expected #{expected} not to be applied, diff:" +
44
- differ.diff_as_string(expected.inspect, events.inspect)
45
- end
46
-
47
- def description
48
- "have applied events that have to (#{phraser.(expected)})"
49
- end
50
-
51
- private
52
-
53
- def matches_count?
54
- return true unless count
55
- raise NotSupported if expected.size > 1
56
-
57
- expected.all? do |event_or_matcher|
58
- events.select { |e| event_or_matcher === e }.size.equal?(count)
59
- end
60
- end
61
-
62
- attr_reader :differ, :phraser, :expected, :events, :count, :matcher
63
- end
64
- end
65
- end
66
-
@@ -1,78 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RailsEventStore
4
- module RSpec
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
10
- @phraser = phraser
11
- end
12
-
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?
19
- end
20
-
21
- def exactly(count)
22
- @count = count
23
- self
24
- end
25
-
26
- def in_stream(stream_name)
27
- @stream_name = stream_name
28
- self
29
- end
30
-
31
- def times
32
- self
33
- end
34
- alias :time :times
35
-
36
- def from(event_id)
37
- @start = event_id
38
- self
39
- end
40
-
41
- def once
42
- exactly(1)
43
- end
44
-
45
- def failure_message
46
- "expected #{expected} to be published, diff:" +
47
- differ.diff_as_string(expected.to_s, events.to_a.to_s)
48
- end
49
-
50
- 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)
53
- end
54
-
55
- def description
56
- "have published events that have to (#{phraser.(expected)})"
57
- end
58
-
59
- def strict
60
- @matcher = ::RSpec::Matchers::BuiltIn::Match.new(expected)
61
- self
62
- end
63
-
64
- private
65
-
66
- def matches_count?
67
- return true unless count
68
- raise NotSupported if expected.size > 1
69
-
70
- expected.all? do |event_or_matcher|
71
- events.select { |e| event_or_matcher === e }.size.equal?(count)
72
- end
73
- end
74
-
75
- attr_reader :differ, :phraser, :stream_name, :expected, :count, :events, :start
76
- end
77
- end
78
- end
@@ -1,68 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RailsEventStore
4
- module RSpec
5
- module Matchers
6
- class ListPhraser
7
- class << self
8
- def call(object)
9
- items = Array(object).compact.map { |o| format(o) }
10
- return "" if items.empty?
11
- if items.one?
12
- items.join
13
- else
14
- "#{items[0...-1].join(", ")} and #{items.fetch(-1)}"
15
- end
16
- end
17
-
18
- private
19
-
20
- def format(object)
21
- if object.respond_to?(:description)
22
- ::RSpec::Support::ObjectFormatter.format(object)
23
- else
24
- "be a #{object}"
25
- end
26
- end
27
- end
28
- end
29
-
30
- def be_an_event(expected)
31
- BeEvent.new(expected, differ: differ, formatter: formatter)
32
- end
33
- alias :be_event :be_an_event
34
- alias :an_event :be_an_event
35
- alias :event :be_an_event
36
-
37
- def have_published(*expected)
38
- HavePublished.new(*expected, differ: differ, phraser: phraser)
39
- end
40
-
41
- def have_applied(*expected)
42
- HaveApplied.new(*expected, differ: differ, phraser: phraser)
43
- end
44
-
45
- def publish(*expected)
46
- Publish.new(*expected)
47
- end
48
-
49
- def apply(*expected)
50
- Apply.new(*expected)
51
- end
52
-
53
- private
54
-
55
- def formatter
56
- ::RSpec::Support::ObjectFormatter.public_method(:format)
57
- end
58
-
59
- def differ
60
- ::RSpec::Support::Differ.new(color: ::RSpec::Matchers.configuration.color?)
61
- end
62
-
63
- def phraser
64
- ListPhraser
65
- end
66
- end
67
- end
68
- end
@@ -1,86 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RailsEventStore
4
- module RSpec
5
- class Publish
6
- def in(event_store)
7
- @event_store = event_store
8
- self
9
- end
10
-
11
- def in_stream(stream)
12
- @stream = stream
13
- self
14
- end
15
-
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
29
- end
30
-
31
- def failure_message
32
- if match_events?
33
- <<-EOS
34
- expected block to have published:
35
-
36
- #{@expected}
37
-
38
- #{"in stream #{@stream} " if @stream}but published:
39
-
40
- #{@published_events}
41
- EOS
42
- else
43
- "expected block to have published any events"
44
- end
45
- end
46
-
47
- def failure_message_when_negated
48
- if match_events?
49
- <<-EOS
50
- expected block not to have published:
51
-
52
- #{@expected}
53
-
54
- #{"in stream #{@stream} " if @stream}but published:
55
-
56
- #{@published_events}
57
- EOS
58
- else
59
- "expected block not to have published any events"
60
- end
61
- end
62
-
63
- def description
64
- "publish events"
65
- end
66
-
67
- def supports_block_expectations?
68
- true
69
- end
70
-
71
- private
72
-
73
- def initialize(*expected)
74
- @expected = expected
75
- end
76
-
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
84
- end
85
- end
86
- end
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RailsEventStore
4
- module RSpec
5
- VERSION = "1.2.0"
6
- end
7
- end
@@ -1,31 +0,0 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'rails_event_store/rspec/version'
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = 'rails_event_store-rspec'
8
- spec.version = RailsEventStore::RSpec::VERSION
9
- spec.licenses = ['MIT']
10
- spec.authors = ['Arkency']
11
- spec.email = ['dev@arkency.com']
12
-
13
- spec.summary = %q{RSpec matchers for RailsEventStore}
14
- spec.homepage = 'https://railseventstore.org'
15
- spec.metadata = {
16
- "homepage_uri" => "https://railseventstore.org/",
17
- "changelog_uri" => "https://github.com/RailsEventStore/rails_event_store/releases",
18
- "source_code_uri" => "https://github.com/RailsEventStore/rails_event_store",
19
- "bug_tracker_uri" => "https://github.com/RailsEventStore/rails_event_store/issues",
20
- }
21
-
22
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
23
- f.match(%r{^(test|spec|features)/})
24
- end
25
- spec.bindir = 'exe'
26
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
- spec.require_paths = ['lib']
28
-
29
- spec.add_runtime_dependency 'rspec', '~> 3.0'
30
- spec.add_runtime_dependency 'diff-lcs', '>= 1.4.4'
31
- end