rspec-notifications 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 2a6a99147391a7c47e824a7d9b7aa3517feb8725926193f28bfda6a329fea44f
4
+ data.tar.gz: b45d825be7f67e08b68973745c48a2993f468f733563c6e368c7df95d6d557db
5
+ SHA512:
6
+ metadata.gz: eb2e953a251fc0e7da9b5b8218efcb033cb78573f9b24dcd888def44a6131624c200f4555364d4e450d5524b4d9e311ee104a01be16b9e005ef85a8ce5c2cefd
7
+ data.tar.gz: 0f593443c3cb6123d2de099fd965d4c51207b351cb5ffb3d583a1a41842e6df4aa3334c9490e104797e118fd0d2894e7c77098a6fae402a91b690d4a4e559303
data/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ ## 0.1.0
2
+ - initial release
3
+ - `emit_notification` matcher for `ActiveSupport::Notifications`
4
+ - payload matching via `.with` (partial, nested, embedded matchers)
5
+ - count assertions: `.once`, `.twice`, `.exactly`, `.at_least`, `.at_most`
6
+ - wildcard and regexp notification names
7
+ - `instrument_notification` alias
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,137 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rspec-notifications (0.1.0)
5
+ activesupport (>= 7)
6
+ rspec-expectations (>= 3)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ activesupport (8.1.3)
12
+ base64
13
+ bigdecimal
14
+ concurrent-ruby (~> 1.0, >= 1.3.1)
15
+ connection_pool (>= 2.2.5)
16
+ drb
17
+ i18n (>= 1.6, < 2)
18
+ json
19
+ logger (>= 1.4.2)
20
+ minitest (>= 5.1)
21
+ securerandom (>= 0.3)
22
+ tzinfo (~> 2.0, >= 2.0.5)
23
+ uri (>= 0.13.1)
24
+ base64 (0.3.0)
25
+ bigdecimal (4.1.2)
26
+ concurrent-ruby (1.3.6)
27
+ connection_pool (3.0.2)
28
+ date (3.5.1)
29
+ debug (1.11.1)
30
+ irb (~> 1.10)
31
+ reline (>= 0.3.8)
32
+ diff-lcs (1.6.2)
33
+ docile (1.4.1)
34
+ drb (2.2.3)
35
+ erb (6.0.4)
36
+ i18n (1.14.8)
37
+ concurrent-ruby (~> 1.0)
38
+ io-console (0.8.2)
39
+ irb (1.17.0)
40
+ pp (>= 0.6.0)
41
+ prism (>= 1.3.0)
42
+ rdoc (>= 4.0.0)
43
+ reline (>= 0.4.2)
44
+ json (2.19.8)
45
+ logger (1.7.0)
46
+ minitest (6.0.6)
47
+ drb (~> 2.0)
48
+ prism (~> 1.5)
49
+ pp (0.6.3)
50
+ prettyprint
51
+ prettyprint (0.2.0)
52
+ prism (1.9.0)
53
+ psych (5.3.1)
54
+ date
55
+ stringio
56
+ rdoc (7.2.0)
57
+ erb
58
+ psych (>= 4.0.0)
59
+ tsort
60
+ reline (0.6.3)
61
+ io-console (~> 0.5)
62
+ rspec (3.13.2)
63
+ rspec-core (~> 3.13.0)
64
+ rspec-expectations (~> 3.13.0)
65
+ rspec-mocks (~> 3.13.0)
66
+ rspec-core (3.13.6)
67
+ rspec-support (~> 3.13.0)
68
+ rspec-expectations (3.13.5)
69
+ diff-lcs (>= 1.2.0, < 2.0)
70
+ rspec-support (~> 3.13.0)
71
+ rspec-mocks (3.13.8)
72
+ diff-lcs (>= 1.2.0, < 2.0)
73
+ rspec-support (~> 3.13.0)
74
+ rspec-support (3.13.7)
75
+ securerandom (0.4.1)
76
+ simplecov (0.22.0)
77
+ docile (~> 1.1)
78
+ simplecov-html (~> 0.11)
79
+ simplecov_json_formatter (~> 0.1)
80
+ simplecov-html (0.13.2)
81
+ simplecov_json_formatter (0.1.4)
82
+ stringio (3.2.0)
83
+ tsort (0.2.0)
84
+ tzinfo (2.0.6)
85
+ concurrent-ruby (~> 1.0)
86
+ uri (1.1.1)
87
+
88
+ PLATFORMS
89
+ ruby
90
+
91
+ DEPENDENCIES
92
+ debug
93
+ rspec
94
+ rspec-notifications!
95
+ simplecov
96
+
97
+ CHECKSUMS
98
+ activesupport (8.1.3) sha256=21a5e0dfbd4c3ddd9e1317ec6a4d782fa226e7867dc70b0743acda81a1dca20e
99
+ base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b
100
+ bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd
101
+ concurrent-ruby (1.3.6) sha256=6b56837e1e7e5292f9864f34b69c5a2cbc75c0cf5338f1ce9903d10fa762d5ab
102
+ connection_pool (3.0.2) sha256=33fff5ba71a12d2aa26cb72b1db8bba2a1a01823559fb01d29eb74c286e62e0a
103
+ date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0
104
+ debug (1.11.1) sha256=2e0b0ac6119f2207a6f8ac7d4a73ca8eb4e440f64da0a3136c30343146e952b6
105
+ diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962
106
+ docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e
107
+ drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373
108
+ erb (6.0.4) sha256=38e3803694be357fe2bfe312487c74beaf9fb4e5beb3e22498952fe1645b95d9
109
+ i18n (1.14.8) sha256=285778639134865c5e0f6269e0b818256017e8cde89993fdfcbfb64d088824a5
110
+ io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc
111
+ irb (1.17.0) sha256=168c4ddb93d8a361a045c41d92b2952c7a118fa73f23fe14e55609eb7a863aae
112
+ json (2.19.8) sha256=6354310fd76ef69b87d5bd1f38b40d730613baf90b6803d2d0a48f618d32dfaa
113
+ logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203
114
+ minitest (6.0.6) sha256=153ea36d1d987a62942382b61075745042a2b3123b1cd48f4c3675af9cc7d6f1
115
+ pp (0.6.3) sha256=2951d514450b93ccfeb1df7d021cae0da16e0a7f95ee1e2273719669d0ab9df6
116
+ prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193
117
+ prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85
118
+ psych (5.3.1) sha256=eb7a57cef10c9d70173ff74e739d843ac3b2c019a003de48447b2963d81b1974
119
+ rdoc (7.2.0) sha256=8650f76cd4009c3b54955eb5d7e3a075c60a57276766ebf36f9085e8c9f23192
120
+ reline (0.6.3) sha256=1198b04973565b36ec0f11542ab3f5cfeeec34823f4e54cebde90968092b1835
121
+ rspec (3.13.2) sha256=206284a08ad798e61f86d7ca3e376718d52c0bc944626b2349266f239f820587
122
+ rspec-core (3.13.6) sha256=a8823c6411667b60a8bca135364351dda34cd55e44ff94c4be4633b37d828b2d
123
+ rspec-expectations (3.13.5) sha256=33a4d3a1d95060aea4c94e9f237030a8f9eae5615e9bd85718fe3a09e4b58836
124
+ rspec-mocks (3.13.8) sha256=086ad3d3d17533f4237643de0b5c42f04b66348c28bf6b9c2d3f4a3b01af1d47
125
+ rspec-notifications (0.1.0)
126
+ rspec-support (3.13.7) sha256=0640e5570872aafefd79867901deeeeb40b0c9875a36b983d85f54fb7381c47c
127
+ securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1
128
+ simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5
129
+ simplecov-html (0.13.2) sha256=bd0b8e54e7c2d7685927e8d6286466359b6f16b18cb0df47b508e8d73c777246
130
+ simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428
131
+ stringio (3.2.0) sha256=c37cb2e58b4ffbd33fe5cd948c05934af997b36e0b6ca6fdf43afa234cf222e1
132
+ tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f
133
+ tzinfo (2.0.6) sha256=8daf828cc77bcf7d63b0e3bdb6caa47e2272dcfaf4fbfe46f8c3a9df087a829b
134
+ uri (1.1.1) sha256=379fa58d27ffb1387eaada68c749d1426738bd0f654d812fcc07e7568f5c57c6
135
+
136
+ BUNDLED WITH
137
+ 4.0.9
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2026 Daniel Pepper
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,106 @@
1
+ rspec-notifications
2
+ ======
3
+ ![Gem](https://img.shields.io/gem/dt/rspec-notifications?style=plastic)
4
+ [![codecov](https://codecov.io/gh/dpep/rspec-notifications/branch/main/graph/badge.svg)](https://codecov.io/gh/dpep/rspec-notifications)
5
+
6
+
7
+ RSpec matchers for testing `ActiveSupport::Notifications`.
8
+
9
+ ```ruby
10
+ require "rspec/notifications"
11
+
12
+ expect {
13
+ service.call
14
+ }.to emit_notification("user.created")
15
+ ```
16
+
17
+ The matcher subscribes to `ActiveSupport::Notifications` before running the
18
+ block and unsubscribes afterward, so there is nothing to set up or tear down.
19
+
20
+
21
+ ## Payloads
22
+
23
+ Match the payload with `.with`. Matching is partial — only the keys you name
24
+ are checked, so extra payload keys are ignored.
25
+
26
+ ```ruby
27
+ expect {
28
+ service.call
29
+ }.to emit_notification("user.created").with(user_id: user.id)
30
+ ```
31
+
32
+ Values support embedded RSpec matchers, nested hashes, and any composable
33
+ matcher:
34
+
35
+ ```ruby
36
+ expect {
37
+ service.call
38
+ }.to emit_notification("user.created").with(user_id: kind_of(Integer))
39
+
40
+ # nested hashes match exactly; use a_hash_including for a nested subset
41
+ expect {
42
+ service.call
43
+ }.to emit_notification("user.created").with(user: a_hash_including(role: "admin"))
44
+ ```
45
+
46
+
47
+ ## Counts
48
+
49
+ ```ruby
50
+ expect { service.call }.to emit_notification("user.created").once
51
+ expect { service.call }.to emit_notification("user.created").twice
52
+ expect { service.call }.to emit_notification("user.created").exactly(3).times
53
+ expect { service.call }.to emit_notification("user.created").at_least(2).times
54
+ expect { service.call }.to emit_notification("user.created").at_most(2).times
55
+ ```
56
+
57
+ Without a count, the matcher passes when the notification is emitted at least
58
+ once. Counts apply to events matching both the name and the payload.
59
+
60
+
61
+ ## Names
62
+
63
+ Names can be matched exactly, with a `*` wildcard, or with a `Regexp`:
64
+
65
+ ```ruby
66
+ emit_notification("user.created") # exact
67
+ emit_notification("user.*") # wildcard
68
+ emit_notification(/user\./) # regexp
69
+ ```
70
+
71
+
72
+ ## Negation
73
+
74
+ ```ruby
75
+ expect { service.call }.not_to emit_notification("user.created")
76
+ ```
77
+
78
+
79
+ ## Aliases
80
+
81
+ `instrument_notification` is an alias for `emit_notification`.
82
+
83
+
84
+ ## Edge cases
85
+
86
+ - **Nested notifications** — each instrumented event is captured independently,
87
+ including notifications instrumented within the block of another.
88
+ - **Exceptions** — if the block raises, the exception propagates (the matcher
89
+ still unsubscribes). When `ActiveSupport::Notifications.instrument` re-raises,
90
+ it adds `:exception` / `:exception_object` to the payload, which you can match
91
+ on with `.with`.
92
+ - **Concurrency** — notifications delivered from other threads during the block
93
+ are captured too; appends are guarded by a mutex.
94
+
95
+
96
+ ----
97
+ ## Contributing
98
+
99
+ Yes please :)
100
+
101
+ 1. Fork it
102
+ 1. Create your feature branch (`git checkout -b my-feature`)
103
+ 1. Ensure the tests pass (`bundle exec rspec`)
104
+ 1. Commit your changes (`git commit -am 'awesome new feature'`)
105
+ 1. Push your branch (`git push origin my-feature`)
106
+ 1. Create a Pull Request
@@ -0,0 +1,140 @@
1
+ module RSpec
2
+ module Notifications
3
+ # RSpec matcher asserting that a block emits an ActiveSupport::Notifications
4
+ # event. See RSpec::Matchers#emit_notification for the public entry point.
5
+ class Matcher
6
+ include RSpec::Matchers::Composable
7
+
8
+ def initialize(pattern)
9
+ @pattern = pattern
10
+ @expected_payload = nil
11
+ @count_type = nil
12
+ @count = nil
13
+ end
14
+
15
+ # --- chained expectations ------------------------------------------
16
+
17
+ def with(payload)
18
+ @expected_payload = payload
19
+ self
20
+ end
21
+
22
+ def once
23
+ exactly(1)
24
+ end
25
+
26
+ def twice
27
+ exactly(2)
28
+ end
29
+
30
+ def exactly(count)
31
+ set_count(:exactly, count)
32
+ end
33
+
34
+ def at_least(count)
35
+ set_count(:at_least, count)
36
+ end
37
+
38
+ def at_most(count)
39
+ set_count(:at_most, count)
40
+ end
41
+
42
+ # syntactic sugar: exactly(n).times
43
+ def times
44
+ self
45
+ end
46
+
47
+ # --- matcher protocol ----------------------------------------------
48
+
49
+ def matches?(block)
50
+ @events = Subscriber.capture(subscribe_pattern, &block)
51
+ @matching_events = @events.select do |event|
52
+ PayloadMatcher.matches?(@expected_payload, event.payload)
53
+ end
54
+
55
+ count_satisfied?(@matching_events.size)
56
+ end
57
+
58
+ def does_not_match?(block)
59
+ !matches?(block)
60
+ end
61
+
62
+ def supports_block_expectations?
63
+ true
64
+ end
65
+
66
+ def description
67
+ desc = "emit #{@pattern.inspect} notification"
68
+ desc += " with payload #{description_of(@expected_payload)}" if @expected_payload
69
+ desc += " #{count_description}" if @count_type
70
+ desc
71
+ end
72
+
73
+ def failure_message
74
+ "expected block to #{description}, but #{observed_summary}#{emitted_breakdown}"
75
+ end
76
+
77
+ def failure_message_when_negated
78
+ "expected block not to #{description}, but #{observed_summary}#{emitted_breakdown}"
79
+ end
80
+
81
+ private
82
+
83
+ def set_count(type, count)
84
+ @count_type = type
85
+ @count = count
86
+ self
87
+ end
88
+
89
+ # ActiveSupport::Notifications.subscribe natively matches a String exactly
90
+ # or a Regexp via ===. A String containing "*" is treated as a wildcard
91
+ # and converted to an anchored Regexp.
92
+ def subscribe_pattern
93
+ return @pattern unless @pattern.is_a?(String) && @pattern.include?("*")
94
+
95
+ segments = @pattern.split("*", -1).map { |segment| Regexp.escape(segment) }
96
+ Regexp.new("\\A#{segments.join(".*")}\\z")
97
+ end
98
+
99
+ def count_satisfied?(count)
100
+ case @count_type
101
+ when :exactly then count == @count
102
+ when :at_least then count >= @count
103
+ when :at_most then count <= @count
104
+ else count >= 1
105
+ end
106
+ end
107
+
108
+ def count_description
109
+ "#{@count_type.to_s.tr("_", " ")} #{pluralize(@count, "time")}"
110
+ end
111
+
112
+ def observed_summary
113
+ matched = @matching_events.size
114
+
115
+ if @expected_payload && @events.any?
116
+ "#{pluralize(matched, "matching notification")} were emitted " \
117
+ "(#{pluralize(@events.size, "notification")} matched the name)"
118
+ elsif matched.zero?
119
+ "no matching notifications were emitted"
120
+ else
121
+ "it was emitted #{pluralize(matched, "time")}"
122
+ end
123
+ end
124
+
125
+ def emitted_breakdown
126
+ return "" if @events.empty?
127
+
128
+ lines = @events.map do |event|
129
+ " - #{event.name.inspect} #{event.payload.inspect}"
130
+ end
131
+
132
+ "\nemitted notifications:\n#{lines.join("\n")}"
133
+ end
134
+
135
+ def pluralize(count, noun)
136
+ "#{count} #{noun}#{"s" unless count == 1}"
137
+ end
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,27 @@
1
+ require "rspec/support/fuzzy_matcher"
2
+
3
+ module RSpec
4
+ module Notifications
5
+ # Matches an expected payload against an actual notification payload.
6
+ #
7
+ # Matching is partial at the top level: only the keys named in +expected+
8
+ # are checked, so unrelated payload keys are ignored. Values are compared
9
+ # with RSpec's fuzzy matching, which supports embedded matchers (e.g.
10
+ # +kind_of(Integer)+), regexps, ranges, and nested structures. Nested
11
+ # hashes are compared exactly -- use +a_hash_including(...)+ for a nested
12
+ # partial match.
13
+ module PayloadMatcher
14
+ module_function
15
+
16
+ def matches?(expected, actual)
17
+ return true if expected.nil?
18
+ return false unless actual.is_a?(Hash)
19
+
20
+ expected.all? do |key, value|
21
+ actual.key?(key) &&
22
+ RSpec::Support::FuzzyMatcher.values_match?(value, actual.fetch(key))
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,63 @@
1
+ module RSpec
2
+ module Notifications
3
+ # Subscribes to ActiveSupport::Notifications for the duration of a block,
4
+ # capturing every matching event, then unsubscribes.
5
+ #
6
+ # Thread-safe: notifications may be delivered from threads other than the
7
+ # one running the block, so appends are guarded by a mutex.
8
+ class Subscriber
9
+ Event = Struct.new(
10
+ :name,
11
+ :payload,
12
+ :started,
13
+ :finished,
14
+ :transaction_id,
15
+ keyword_init: true,
16
+ ) do
17
+ # Duration in milliseconds, when both timestamps are available.
18
+ def duration
19
+ return unless started && finished
20
+
21
+ (finished - started) * 1_000.0
22
+ end
23
+ end
24
+
25
+ # Subscribe to +pattern+, run +block+, and return the captured events.
26
+ def self.capture(pattern, &block)
27
+ new(pattern).capture(&block)
28
+ end
29
+
30
+ def initialize(pattern)
31
+ @pattern = pattern
32
+ @events = []
33
+ @mutex = Mutex.new
34
+ end
35
+
36
+ def capture
37
+ subscription = subscribe
38
+ yield
39
+ @mutex.synchronize { @events.dup }
40
+ ensure
41
+ ActiveSupport::Notifications.unsubscribe(subscription) if subscription
42
+ end
43
+
44
+ private
45
+
46
+ def subscribe
47
+ # A 5-arity block opts into the "timed" subscriber, which yields the
48
+ # start and finish times along with the transaction id and payload.
49
+ ActiveSupport::Notifications.subscribe(@pattern) do |name, started, finished, id, payload|
50
+ event = Event.new(
51
+ name: name,
52
+ payload: payload.dup,
53
+ started: started,
54
+ finished: finished,
55
+ transaction_id: id,
56
+ )
57
+
58
+ @mutex.synchronize { @events << event }
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,5 @@
1
+ module RSpec
2
+ module Notifications
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,27 @@
1
+ require "active_support/isolated_execution_state"
2
+ require "active_support/notifications"
3
+ require "rspec/expectations"
4
+
5
+ require_relative "notifications/version"
6
+ require_relative "notifications/subscriber"
7
+ require_relative "notifications/payload_matcher"
8
+ require_relative "notifications/matcher"
9
+
10
+ module RSpec
11
+ module Matchers
12
+ # Asserts that the block emits a matching ActiveSupport::Notifications event.
13
+ #
14
+ # expect { service.call }.to emit_notification("user.created")
15
+ # expect { service.call }.to emit_notification("user.created").with(user_id: 1)
16
+ # expect { service.call }.to emit_notification("user.created").twice
17
+ # expect { service.call }.to emit_notification("user.*")
18
+ # expect { service.call }.to emit_notification(/user\./)
19
+ #
20
+ # +pattern+ may be an exact String, a String with "*" wildcards, or a Regexp.
21
+ def emit_notification(pattern)
22
+ RSpec::Notifications::Matcher.new(pattern)
23
+ end
24
+
25
+ alias_method :instrument_notification, :emit_notification
26
+ end
27
+ end
@@ -0,0 +1 @@
1
+ require "rspec/notifications"
@@ -0,0 +1,21 @@
1
+ require_relative "lib/rspec/notifications/version"
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "rspec-notifications"
5
+ s.version = RSpec::Notifications::VERSION
6
+ s.authors = ["Daniel Pepper"]
7
+ s.description = "RSpec matchers for ActiveSupport::Notifications"
8
+ s.files = `git ls-files * ':!:spec'`.split("\n")
9
+ s.homepage = "https://github.com/dpep/rspec-notifications"
10
+ s.license = "MIT"
11
+ s.summary = "RSpec::Notifications"
12
+
13
+ s.required_ruby_version = ">= 3.2"
14
+
15
+ s.add_dependency "activesupport", ">= 7"
16
+ s.add_dependency "rspec-expectations", ">= 3"
17
+
18
+ s.add_development_dependency "debug"
19
+ s.add_development_dependency "rspec"
20
+ s.add_development_dependency "simplecov"
21
+ end
metadata ADDED
@@ -0,0 +1,120 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rspec-notifications
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Daniel Pepper
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: activesupport
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '7'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '7'
26
+ - !ruby/object:Gem::Dependency
27
+ name: rspec-expectations
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '3'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '3'
40
+ - !ruby/object:Gem::Dependency
41
+ name: debug
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ type: :development
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: rspec
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ - !ruby/object:Gem::Dependency
69
+ name: simplecov
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ description: RSpec matchers for ActiveSupport::Notifications
83
+ executables: []
84
+ extensions: []
85
+ extra_rdoc_files: []
86
+ files:
87
+ - CHANGELOG.md
88
+ - Gemfile
89
+ - Gemfile.lock
90
+ - LICENSE.txt
91
+ - README.md
92
+ - lib/rspec-notifications.rb
93
+ - lib/rspec/notifications.rb
94
+ - lib/rspec/notifications/matcher.rb
95
+ - lib/rspec/notifications/payload_matcher.rb
96
+ - lib/rspec/notifications/subscriber.rb
97
+ - lib/rspec/notifications/version.rb
98
+ - rspec-notifications.gemspec
99
+ homepage: https://github.com/dpep/rspec-notifications
100
+ licenses:
101
+ - MIT
102
+ metadata: {}
103
+ rdoc_options: []
104
+ require_paths:
105
+ - lib
106
+ required_ruby_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '3.2'
111
+ required_rubygems_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ requirements: []
117
+ rubygems_version: 3.6.9
118
+ specification_version: 4
119
+ summary: RSpec::Notifications
120
+ test_files: []