active_event_store 0.1.0 → 1.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: 79a390bc7f50283a2ed74f34d62ae845dfa5208a19a2a174238a5ebf4a684203
4
- data.tar.gz: cfd5584f0a8c56a645fdb58fb1dfe6b35252d1c23481898974a6c333233d59a1
3
+ metadata.gz: e19560b568e8765b86d3925070dd1414b0de0545107e1dc1c7df4e3402148690
4
+ data.tar.gz: 87816ce897dc26614f8834993373bb271345c25934142f055547ad0f5023fe22
5
5
  SHA512:
6
- metadata.gz: 91d3ecb6b2635ff0e895176e687d3fa3820d519b3d50cbba6d3d4ec9a79c632c527fd17817317d9eddf15d3c6fdff6a581f729bdcc1df55231e9250bb7332c74
7
- data.tar.gz: ce974d79cd1989cfdd86e1ecfdfbf408b1facae1b9ab0be50c72f644f9abb32a0ce0c8a024752b3f2450c921d1f3c0ec5b0a8bc31c311ff814aa0cbd8dba89df
6
+ metadata.gz: acf6017590c69d26066617c86ab63cd658c2307e8da89c53ec0afe18ebb4b384430bde9f632806f4e92a26293ed37cffa1c7abaa55ca2cd5f312d70d98ba873a
7
+ data.tar.gz: 181e900564fb3640a5484045ebbe6170b3871e05ea10a8e443bcadf7a530bf58bc227f4101d998a92ff96b82b569d1d24adcc1f97d3195c57fa2f0023c7db7db
data/CHANGELOG.md CHANGED
@@ -2,8 +2,27 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 1.0.1 (2021-09-16)
6
+
7
+ - Add minitest assertions: `assert_event_published`, `refute_event_published`, `assert_async_event_subscriber_enqueued` ([@chriscz][])
8
+
9
+ ## 1.0.0 (2021-09-14)
10
+
11
+ - Ruby 2.6+, Rails 6+ and RailsEventStore 2.1+ is required.
12
+
13
+ ## 0.2.1 (2020-09-30)
14
+
15
+ - Fix Active Support load hook name. ([@palkan][])
16
+
17
+ Now `ActiveSupport.on_load(:active_event_store) { ... }` works.
18
+
19
+ ## 0.2.0 (2020-05-11)
20
+
21
+ - Update Event API to support both RES 1.0 and 0.42+. ([@palkan][])
22
+
5
23
  ## 0.1.0 (2020-04-22)
6
24
 
7
25
  - Open source Active Event Store. ([@palkan][])
8
26
 
9
27
  [@palkan]: https://github.com/palkan
28
+ [@chriscz]: https://github.com/chriscz
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2020 Vladimir Dementyev
1
+ Copyright (c) 2020-2021 Vladimir Dementyev
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -17,11 +17,11 @@ Secondly, we wanted to have a store implementation independent API that would al
17
17
 
18
18
  ## Installation
19
19
 
20
- Add gem to your project:
20
+ Add the gem to your project:
21
21
 
22
22
  ```ruby
23
23
  # Gemfile
24
- gem "active_event_store"
24
+ gem "active_event_store", "~> 1.0"
25
25
  ```
26
26
 
27
27
  Setup database according to the [Rails Event Store docs](https://railseventstore.org/docs/install/#setup-data-model):
@@ -33,8 +33,9 @@ rails db:migrate
33
33
 
34
34
  ### Requirements
35
35
 
36
- - Ruby (MRI) >= 2.5.0
37
- - Rails >= 5.0
36
+ - Ruby (MRI) >= 2.6
37
+ - Rails >= 6.0
38
+ - RailsEventStore >= 2.1
38
39
 
39
40
  ## Usage
40
41
 
@@ -143,24 +144,40 @@ Subscribers could be any callable Ruby objects that accept a single argument (ev
143
144
 
144
145
  We suggest putting subscribers to the `app/subscribers` folder using the following convention: `app/subscribers/on_<event_type>/<subscriber.rb>`, e.g. `app/subscribers/on_profile_created/create_chat_user.rb`.
145
146
 
147
+ **NOTE:** Active Job must be loaded to use async subscribers (i.e., `require "active_job/railtie"` or `require "rails/all"` in your `config/application.rb`).
148
+
146
149
  ### Testing
147
150
 
148
151
  You can test subscribers as normal Ruby objects.
149
152
 
150
- **NOTE:** Currently, we provide additional matchers only for RSpec. PRs with Minitest support are welcomed!
153
+ **NOTE** To test using minitest include the `ActiveEventStore::TestHelpers` module in your tests.
151
154
 
152
155
  To test that a given subscriber exists, you can use the `have_enqueued_async_subscriber_for` matcher:
153
156
 
154
157
  ```ruby
155
- # for asynchronous subscriptions
158
+ # for asynchronous subscriptions (rspec)
156
159
  it "is subscribed to some event" do
157
160
  event = MyEvent.new(some: "data")
158
161
  expect { ActiveEventStore.publish event }
159
162
  .to have_enqueued_async_subscriber_for(MySubscriberService)
160
163
  .with(event)
161
164
  end
165
+
166
+ # for asynchronous subscriptions (minitest)
167
+ def test_is_subscribed_to_some_event
168
+ event = MyEvent.new(some: "data")
169
+
170
+ assert_async_event_subscriber_enqueued(MySubscriberService, event: event) do
171
+ ActiveEventStore.publish event
172
+ end
173
+ end
162
174
  ```
163
175
 
176
+ **NOTE** Async event subscribers are queued only after the current transaction has committed so when using `assert_enqued_async_subcriber` in rails
177
+ make sure to have `self.use_transactional_fixtures = false` at the top of your test class.
178
+
179
+ **NOTE:** You must have `rspec-rails` gem in your bundle to use `have_enqueued_async_subscriber_for` matcher.
180
+
164
181
  For synchronous subscribers using `have_received` is enough:
165
182
 
166
183
  ```ruby
@@ -178,10 +195,14 @@ end
178
195
  To test event publishing, use `have_published_event` matcher:
179
196
 
180
197
  ```ruby
198
+ # rspec
181
199
  expect { subject }.to have_published_event(ProfileCreated).with(user_id: user.id)
200
+
201
+ # minitest
202
+ assert_event_published(ProfileCreated, with: {user_id: user.id}) { subject }
182
203
  ```
183
204
 
184
- **NOTE:** `have_published_event` only supports block expectations.
205
+ **NOTE:** `have_published_event` and `assert_event_published` only supports block expectations.
185
206
 
186
207
  **NOTE 2** `with` modifier works like `have_attributes` matcher (not `contain_exactly`); you can only specify serializable attributes in `with` (i.e. sync attributes are not supported, 'cause they are not persistent).
187
208
 
@@ -1,11 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "json"
4
+
3
5
  module ActiveEventStore
4
6
  class Config
5
- attr_writer :repository, :job_queue_name, :store_options
7
+ attr_writer :repository, :serializer, :job_queue_name, :store_options
6
8
 
7
9
  def repository
8
- @repository ||= RailsEventStoreActiveRecord::EventRepository.new
10
+ @repository ||= RailsEventStoreActiveRecord::EventRepository.new(serializer: serializer)
11
+ end
12
+
13
+ def serializer
14
+ @serializer ||= JSON
9
15
  end
10
16
 
11
17
  def job_queue_name
@@ -18,7 +18,11 @@ module ActiveEventStore
18
18
  # See https://railseventstore.org/docs/subscribe/#scheduling-async-handlers-after-commit
19
19
  ActiveEventStore.event_store = RailsEventStore::Client.new(
20
20
  dispatcher: RubyEventStore::ComposedDispatcher.new(
21
- RailsEventStore::AfterCommitAsyncDispatcher.new(scheduler: RailsEventStore::ActiveJobScheduler.new),
21
+ RailsEventStore::AfterCommitAsyncDispatcher.new(
22
+ scheduler: RailsEventStore::ActiveJobScheduler.new(
23
+ serializer: ActiveEventStore.config.serializer
24
+ )
25
+ ),
22
26
  RubyEventStore::Dispatcher.new
23
27
  ),
24
28
  repository: ActiveEventStore.config.repository,
@@ -26,7 +30,7 @@ module ActiveEventStore
26
30
  **ActiveEventStore.config.store_options
27
31
  )
28
32
 
29
- ActiveSupport.run_load_hooks("active_event_store", ActiveEventStore)
33
+ ActiveSupport.run_load_hooks(:active_event_store, ActiveEventStore)
30
34
  end
31
35
  end
32
36
  end
@@ -72,8 +72,20 @@ module ActiveEventStore
72
72
  self.class.identifier
73
73
  end
74
74
 
75
+ alias_method :event_type, :type
76
+
75
77
  def inspect
76
- "#{self.class.name}<#{type}##{message_id}>, data: #{data}, metadata: #{metadata}"
78
+ "#{self.class.name}<#{event_type}##{message_id}>, data: #{data}, metadata: #{metadata}"
79
+ end
80
+
81
+ # Has been removed from RES: https://github.com/RailsEventStore/rails_event_store/pull/726
82
+ def to_h
83
+ {
84
+ event_id: event_id,
85
+ metadata: metadata.to_h,
86
+ data: data,
87
+ type: event_type
88
+ }
77
89
  end
78
90
 
79
91
  protected
@@ -1,44 +1,44 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "json"
4
-
5
3
  module ActiveEventStore
6
- using(Module.new do
4
+ using(Module.new {
7
5
  refine Hash do
8
6
  def symbolize_keys
9
7
  RubyEventStore::TransformKeys.symbolize(self)
10
8
  end
11
9
  end
12
- end)
10
+ })
13
11
 
14
12
  # Custom mapper for RES events.
15
13
  #
16
14
  # See https://github.com/RailsEventStore/rails_event_store/blob/v0.35.0/ruby_event_store/lib/ruby_event_store/mappers/default.rb
17
15
  class Mapper
18
- def initialize(mapping:, serializer: JSON)
16
+ def initialize(mapping:, serializer: ActiveEventStore.config.serializer)
19
17
  @serializer = serializer
20
18
  @mapping = mapping
21
19
  end
22
20
 
23
- def event_to_serialized_record(domain_event)
21
+ def event_to_record(domain_event)
24
22
  # lazily add type to mapping
25
23
  # NOTE: use class name instead of a class to handle code reload
26
24
  # in development (to avoid accessing orphaned classes)
27
- mapping.register(domain_event.type, domain_event.class.name) unless mapping.exist?(domain_event.type)
25
+ mapping.register(domain_event.event_type, domain_event.class.name) unless mapping.exist?(domain_event.event_type)
28
26
 
29
- RubyEventStore::SerializedRecord.new(
27
+ RubyEventStore::Record.new(
30
28
  event_id: domain_event.event_id,
31
29
  metadata: serializer.dump(domain_event.metadata.to_h),
32
30
  data: serializer.dump(domain_event.data),
33
- event_type: domain_event.type
31
+ event_type: domain_event.event_type,
32
+ timestamp: domain_event.timestamp,
33
+ valid_at: domain_event.valid_at
34
34
  )
35
35
  end
36
36
 
37
- def serialized_record_to_event(record)
38
- event_class = mapping.fetch(record.event_type) do
37
+ def record_to_event(record)
38
+ event_class = mapping.fetch(record.event_type) {
39
39
  raise "Don't know how to deserialize event: \"#{record.event_type}\". " \
40
- "Add explicit mapping: ActiveEventStore.mapper.register \"#{record.event_type}\", \"<Class Name>\""
41
- end
40
+ "Add explicit mapping: ActiveEventStore.mapping.register \"#{record.event_type}\", \"<Class Name>\""
41
+ }
42
42
 
43
43
  Object.const_get(event_class).new(
44
44
  **serializer.load(record.data).symbolize_keys,
@@ -21,9 +21,12 @@ module ActiveEventStore
21
21
  end
22
22
 
23
23
  def matches?(actual_serialized)
24
- actual = ActiveEventStore.event_store.deserialize(actual_serialized)
24
+ actual = ActiveEventStore.event_store.deserialize(
25
+ **actual_serialized,
26
+ serializer: ActiveEventStore.config.serializer
27
+ )
25
28
 
26
- actual.type == event.type && data_matches?(actual.data)
29
+ actual.event_type == event.event_type && data_matches?(actual.data)
27
30
  end
28
31
 
29
32
  def description
@@ -62,9 +65,9 @@ module ActiveEventStore
62
65
  end
63
66
 
64
67
  RSpec.configure do |config|
65
- config.include(Module.new do
68
+ config.include(Module.new {
66
69
  def have_enqueued_async_subscriber_for(*args)
67
70
  ActiveEventStore::HaveEnqueuedAsyncSubscriberFor.new(*args)
68
71
  end
69
- end)
72
+ })
70
73
  end
@@ -66,7 +66,7 @@ module ActiveEventStore
66
66
 
67
67
  @matching_events, @unmatching_events =
68
68
  in_block_events.partition do |actual_event|
69
- (event_class.identifier == actual_event.type) &&
69
+ (event_class.identifier == actual_event.event_type) &&
70
70
  (attributes.nil? || attributes_match?(actual_event))
71
71
  end
72
72
 
@@ -38,7 +38,7 @@ module ActiveEventStore
38
38
  end
39
39
 
40
40
  def perform(payload)
41
- event = event_store.deserialize(payload)
41
+ event = event_store.deserialize(**payload, serializer: ActiveEventStore.config.serializer)
42
42
 
43
43
  event_store.with_metadata(**event.metadata.to_h) do
44
44
  subscriber.call(event)
@@ -0,0 +1,150 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveEventStore
4
+ module TestHelper
5
+ class EventPublishedMatcher
6
+ attr_reader :attributes,
7
+ :matching_events
8
+
9
+ def initialize(expected_event_class, store: nil, with: nil, exactly: nil, at_least: nil, at_most: nil, refute: false)
10
+ @event_class = expected_event_class
11
+ @store = store || ActiveEventStore.event_store
12
+ @attributes = with
13
+ @refute = refute
14
+
15
+ count_expectations = {
16
+ exactly: exactly,
17
+ at_most: at_most,
18
+ at_least: at_least
19
+ }.reject { |_, v| v.nil? }
20
+
21
+ if count_expectations.length > 1
22
+ raise ArgumentError("Only one of :exactly, :at_least or :at_most can be specified")
23
+ elsif count_expectations.length == 0
24
+ @count_expectation_kind = :at_least
25
+ @expected_count = 1
26
+ else
27
+ @count_expectation_kind = count_expectations.keys.first
28
+ @expected_count = count_expectations.values.first
29
+ end
30
+ end
31
+
32
+ def with_published_events(&block)
33
+ original_count = @store.read.count
34
+ block.call
35
+ in_block_events(original_count, @store.read.count)
36
+ end
37
+
38
+ def matches?(block)
39
+ raise ArgumentError, "#{assertion_name} only support block assertions" if block.nil?
40
+
41
+ events = with_published_events do
42
+ block.call
43
+ end
44
+
45
+ @matching_events, @unmatching_events = partition_events(events)
46
+
47
+ mismatch_message = count_mismatch_message(@matching_events.size)
48
+
49
+ if mismatch_message
50
+ expectations = [
51
+ "Expected #{mismatch_message} #{@event_class.identifier}"
52
+ ]
53
+
54
+ expectations << if refute?
55
+ report_events = @matching_events
56
+ "not to have been published"
57
+ else
58
+ report_events = @unmatching_events
59
+ "to have been published"
60
+ end
61
+
62
+ expectations << "with attributes #{attributes.inspect}" unless attributes.nil?
63
+
64
+ expectations << expectations.pop + ", but"
65
+
66
+ expectations << if report_events.any?
67
+ report_events.inject("published the following events instead:") do |msg, event|
68
+ msg + "\n #{event.inspect}"
69
+ end
70
+ else
71
+ "hasn't published anything"
72
+ end
73
+
74
+ return expectations.join(" ")
75
+ end
76
+
77
+ nil
78
+ end
79
+
80
+ private
81
+
82
+ def refute?
83
+ @refute
84
+ end
85
+
86
+ def assertion_name
87
+ if refute?
88
+ "refute_event_published"
89
+ else
90
+ "assert_event_published"
91
+ end
92
+ end
93
+
94
+ def negate_on_refute(cond)
95
+ if refute?
96
+ !cond
97
+ else
98
+ cond
99
+ end
100
+ end
101
+
102
+ def in_block_events(before_block_count, after_block_count)
103
+ count_difference = after_block_count - before_block_count
104
+ if count_difference.positive?
105
+ @store.read.backward.limit(count_difference).to_a
106
+ else
107
+ []
108
+ end
109
+ end
110
+
111
+ # Partitions events into matching and unmatching
112
+ def partition_events(events)
113
+ events.partition { |e| self.class.event_matches?(@event_class, @attributes, e) }
114
+ end
115
+
116
+ def count_mismatch_message(actual_count)
117
+ case @count_expectation_kind
118
+ when :exactly
119
+ if negate_on_refute(actual_count != @expected_count)
120
+ "exactly #{@expected_count}"
121
+ end
122
+ when :at_most
123
+ if negate_on_refute(actual_count > @expected_count)
124
+ "at most #{@expected_count}"
125
+ end
126
+ when :at_least
127
+ if negate_on_refute(actual_count < @expected_count)
128
+ "at least #{@expected_count}"
129
+ end
130
+ else
131
+ raise ArgumentError, "Unrecognized expectation kind: #{@count_expectation_kind}"
132
+ end
133
+ end
134
+
135
+ class << self
136
+ def event_matches?(event_class, attributes, event)
137
+ event_type_matches?(event_class, event) && event_data_matches?(attributes, event)
138
+ end
139
+
140
+ def event_type_matches?(event_class, event)
141
+ event_class.identifier == event.event_type
142
+ end
143
+
144
+ def event_data_matches?(attributes, event)
145
+ (attributes.nil? || attributes.all? { |k, v| v == event.public_send(k) })
146
+ end
147
+ end
148
+ end
149
+ end
150
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_event_store/test_helper/event_published_matcher"
4
+
5
+ module ActiveEventStore
6
+ module TestHelper
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ include ActiveJob::TestHelper
11
+ end
12
+
13
+ # Asserts that the given event was published `exactly`, `at_least` or `at_most` number of times
14
+ # to a specific `store` `with` a particular hash of attributes.
15
+ def assert_event_published(expected_event, store: nil, with: nil, exactly: nil, at_least: nil, at_most: nil, &block)
16
+ matcher = EventPublishedMatcher.new(
17
+ expected_event,
18
+ store: store,
19
+ with: with,
20
+ exactly: exactly,
21
+ at_least: at_least,
22
+ at_most: at_most
23
+ )
24
+
25
+ if (msg = matcher.matches?(block))
26
+ fail(msg)
27
+ end
28
+
29
+ matcher.matching_events
30
+ end
31
+
32
+ # Asserts that the given event was *not* published `exactly`, `at_least` or `at_most` number of times
33
+ # to a specific `store` `with` a particular hash of attributes.
34
+ def refute_event_published(expected_event, store: nil, with: nil, exactly: nil, at_least: nil, at_most: nil, &block)
35
+ matcher = EventPublishedMatcher.new(
36
+ expected_event,
37
+ store: store,
38
+ with: with,
39
+ exactly: exactly,
40
+ at_least: at_least,
41
+ at_most: at_most,
42
+ refute: true
43
+ )
44
+
45
+ if (msg = matcher.matches?(block))
46
+ fail(msg)
47
+ end
48
+ end
49
+
50
+ def assert_async_event_subscriber_enqueued(subscriber_class, event: nil, queue: "events_subscribers", &block)
51
+ subscriber_job = ActiveEventStore::SubscriberJob.for(subscriber_class)
52
+ if subscriber_job.nil?
53
+ fail("No such async subscriber: #{subscriber_class.name}")
54
+ end
55
+
56
+ expected_event = event
57
+ event_matcher = ->(actual_event) { EventPublishedMatcher.event_matches?(expected_event, expected_event.data, actual_event) }
58
+
59
+ expected_args = if expected_event
60
+ event_matcher
61
+ end
62
+
63
+ assert_enqueued_with(job: subscriber_job, queue: queue, args: expected_args) do
64
+ ActiveRecord::Base.transaction do
65
+ block.call
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveEventStore # :nodoc:
4
- VERSION = "0.1.0"
4
+ VERSION = "1.0.1"
5
5
  end
@@ -24,8 +24,8 @@ module ActiveEventStore
24
24
  @config ||= Config.new
25
25
  end
26
26
 
27
- def subscribe(subscriber = nil, to: nil, sync: false)
28
- subscriber ||= Proc.new
27
+ def subscribe(subscriber = nil, to: nil, sync: false, &block)
28
+ subscriber ||= block
29
29
 
30
30
  to ||= infer_event_from_subscriber(subscriber) if subscriber.is_a?(Module)
31
31
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_event_store
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Dementyev
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-04-22 00:00:00.000000000 Z
11
+ date: 2021-09-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails_event_store
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.42.0
19
+ version: 2.1.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 0.42.0
26
+ version: 2.1.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '3.8'
83
+ - !ruby/object:Gem::Dependency
84
+ name: minitest
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '5.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '5.0'
83
97
  description: Wrapper over Rails Event Store with conventions and transparent Rails
84
98
  integration
85
99
  email:
@@ -101,6 +115,8 @@ files:
101
115
  - lib/active_event_store/rspec/have_enqueued_async_subscriber_for.rb
102
116
  - lib/active_event_store/rspec/have_published_event.rb
103
117
  - lib/active_event_store/subscriber_job.rb
118
+ - lib/active_event_store/test_helper.rb
119
+ - lib/active_event_store/test_helper/event_published_matcher.rb
104
120
  - lib/active_event_store/version.rb
105
121
  homepage: http://github.com/palkan/active_event_store
106
122
  licenses:
@@ -111,7 +127,7 @@ metadata:
111
127
  documentation_uri: http://github.com/palkan/active_event_store
112
128
  homepage_uri: http://github.com/palkan/active_event_store
113
129
  source_code_uri: http://github.com/palkan/active_event_store
114
- post_install_message:
130
+ post_install_message:
115
131
  rdoc_options: []
116
132
  require_paths:
117
133
  - lib
@@ -119,15 +135,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
119
135
  requirements:
120
136
  - - ">="
121
137
  - !ruby/object:Gem::Version
122
- version: '2.5'
138
+ version: '2.6'
123
139
  required_rubygems_version: !ruby/object:Gem::Requirement
124
140
  requirements:
125
141
  - - ">="
126
142
  - !ruby/object:Gem::Version
127
143
  version: '0'
128
144
  requirements: []
129
- rubygems_version: 3.0.6
130
- signing_key:
145
+ rubygems_version: 3.2.15
146
+ signing_key:
131
147
  specification_version: 4
132
148
  summary: Rails Event Store in a more Rails way
133
149
  test_files: []