ears 0.22.2 → 0.23.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f6483233146640e82b3de7c02e3429615e31a7b231109846528735068054f9bb
4
- data.tar.gz: 54a0f5b927c41292232f8f4c0926da9d7a9fd44457bc618ad99bf028ce13c41e
3
+ metadata.gz: 47ba90195072b718e5d0b371dfa46500416c466522ee035aaca493453556d3a6
4
+ data.tar.gz: 5d2d73b8503c82553c8f070b0fcf24b9b8843179f8fedec1f089b8cfc5aaa5c7
5
5
  SHA512:
6
- metadata.gz: da2668020244abab87e630625ea191f61cc2aacc45f08f59a194c0d4fc3e1e25445842f20349d8919c04738f3dcfecbb0979ea71d7b0249220e3f8148cfb1e7e
7
- data.tar.gz: 525197d5ee63152fcaddb09af9339ad0c4ff054fcb8c0a3c74069b08f6a6f7beab5755522c13ae1c18be15716979badb0b9dd536e64ced620cf5ad537ae20a75
6
+ metadata.gz: e97b11468d7d90d10147c3ac327149cd1333e4684439c1f1b587a4e6765357857fa4d96c37f3df486dfbeb536515ab198e46139c36c13e8354334f45e5f45ada
7
+ data.tar.gz: d042ae7b9a0a0460c085b2b617e2671a3dea383197588ece367e9ecc60bb0cf5b4a39a2ad027aa38f346f1c3c35131d4e6f900330dcd3e83fb6516a7ca68e298
@@ -21,7 +21,7 @@ jobs:
21
21
  with:
22
22
  ruby-version: ${{ matrix.ruby-version }}
23
23
  bundler-cache: true
24
- - uses: actions/setup-node@v5
24
+ - uses: actions/setup-node@v6
25
25
  with:
26
26
  node-version: '24'
27
27
  - name: Run prettier
@@ -45,7 +45,7 @@ jobs:
45
45
 
46
46
  # Initializes the CodeQL tools for scanning.
47
47
  - name: Initialize CodeQL
48
- uses: github/codeql-action/init@v3
48
+ uses: github/codeql-action/init@v4
49
49
  with:
50
50
  languages: ${{ matrix.language }}
51
51
  # If you wish to specify custom queries, you can do so here or in a config file.
@@ -58,7 +58,7 @@ jobs:
58
58
  # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java).
59
59
  # If this step fails, then you should remove it and run the build manually (see below)
60
60
  - name: Autobuild
61
- uses: github/codeql-action/autobuild@v3
61
+ uses: github/codeql-action/autobuild@v4
62
62
 
63
63
  # ℹ️ Command-line programs to run using the OS shell.
64
64
  # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
@@ -71,6 +71,6 @@ jobs:
71
71
  # ./location_of_script_within_repo/buildscript.sh
72
72
 
73
73
  - name: Perform CodeQL Analysis
74
- uses: github/codeql-action/analyze@v3
74
+ uses: github/codeql-action/analyze@v4
75
75
  with:
76
76
  category: '/language:${{matrix.language}}'
data/CHANGELOG.md CHANGED
@@ -1,6 +1,10 @@
1
1
  # Changelog
2
2
 
3
- ## 0.22.2 (2025-01-19)
3
+ ## 0.23.0 (2025-11-06)
4
+
5
+ - Add `have_been_published` rspec matcher
6
+
7
+ ## 0.22.2 (2025-09-19)
4
8
 
5
9
  ### Fixed
6
10
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ears (0.22.2)
4
+ ears (0.23.0)
5
5
  bunny (>= 2.22.0)
6
6
  connection_pool (~> 2.4)
7
7
  multi_json
@@ -111,7 +111,7 @@ CHECKSUMS
111
111
  connection_pool (2.5.4) sha256=e9e1922327416091f3f6542f5f4446c2a20745276b9aa796dd0bb2fd0ea1e70a
112
112
  diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962
113
113
  docile (1.4.1) sha256=96159be799bfa73cdb721b840e9802126e4e03dfc26863db73647204c727f21e
114
- ears (0.22.2)
114
+ ears (0.23.0)
115
115
  json (2.13.2) sha256=02e1f118d434c6b230a64ffa5c8dee07e3ec96244335c392eaed39e1199dbb68
116
116
  language_server-protocol (3.17.0.5) sha256=fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc
117
117
  lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87
data/README.md CHANGED
@@ -663,6 +663,83 @@ Each captured message has the following properties:
663
663
  - `timestamp` - When the message was captured
664
664
  - `thread_id` - Thread that published the message
665
665
 
666
+ ### Custom RSpec Matcher: `have_been_published`
667
+
668
+ To make tests more expressive, Ears provides a custom RSpec matcher that allows you to easily assert that a specific message was published to a mocked exchange.
669
+
670
+ #### Usage
671
+
672
+ Include the matcher by requiring `ears/testing` in your RSpec tests and including the helper module:
673
+
674
+ ```ruby
675
+ require 'ears/testing'
676
+
677
+ RSpec.describe MyPublisher do
678
+ include Ears::Testing::TestHelper
679
+
680
+ before { mock_ears('events') }
681
+ after { ears_reset! }
682
+
683
+ it 'publishes a user.created message' do
684
+ publisher = Ears::Publisher.new('events', :topic)
685
+ publisher.publish({ user_id: 1 }, routing_key: 'user.created')
686
+
687
+ expect(
688
+ exchange_name: 'events',
689
+ routing_key: 'user.created',
690
+ data: {
691
+ user_id: 1,
692
+ },
693
+ ).to have_been_published
694
+ end
695
+
696
+ # also works with negative assertions
697
+ it 'does not publish a user.deleted message' do
698
+ publisher = Ears::Publisher.new('events', :topic)
699
+ publisher.publish({ user_id: 1 }, routing_key: 'user.created')
700
+
701
+ expect(
702
+ exchange_name: 'events',
703
+ routing_key: 'user.deleted',
704
+ data: {
705
+ user_id: 1,
706
+ },
707
+ ).not_to have_been_published
708
+ end
709
+ end
710
+ ```
711
+
712
+ #### Supported Keys
713
+
714
+ You can match on any or all of the following attributes:
715
+
716
+ | Key | Description | Example |
717
+ | ---------------- | ---------------------------------------------- | --------------------------------------------------- |
718
+ | `:exchange_name` | The exchange where the message was published | `'events'` |
719
+ | `:routing_key` | The routing key used for the message | `'user.created'` |
720
+ | `:data` | The message payload (exact match) | `{ user_id: 1 }` |
721
+ | `:options` | Message options such as headers or persistence | `{ persistent: true, headers: { version: '1.0' } }` |
722
+
723
+ If a key is omitted, it will not be checked — allowing partial matches (for example, matching only on `exchange_name` and `routing_key`).
724
+
725
+ #### Example: Matching with Options
726
+
727
+ > **Note:** When matching `:options`, you only need to specify the options you want to verify — the matcher will ignore any additional options present in the published message.
728
+
729
+ ```ruby
730
+ expect(
731
+ exchange_name: 'events',
732
+ routing_key: 'user.created',
733
+ data: {
734
+ id: 42,
735
+ name: 'Alice',
736
+ },
737
+ options: {
738
+ persistent: true,
739
+ },
740
+ ).to have_been_published
741
+ ```
742
+
666
743
  ### Error Handling
667
744
 
668
745
  By default, publishing to unmocked exchanges raises an error:
@@ -0,0 +1,43 @@
1
+ module Ears
2
+ module Testing
3
+ module Matchers
4
+ RSpec::Matchers.define :have_been_published do # rubocop:disable Metrics/BlockLength
5
+ include Ears::Testing::TestHelper
6
+
7
+ match do |expected|
8
+ exchange_name = expected[:exchange_name]
9
+ messages = published_messages(exchange_name)
10
+
11
+ messages.any? { |message| matches_message?(message, expected) }
12
+ end
13
+
14
+ failure_message do |expected|
15
+ "expected a message with #{expected.inspect} to have been published, " \
16
+ "but published were:\n" \
17
+ "#{published_messages(expected[:exchange_name]).map(&:inspect).join("\n")}"
18
+ end
19
+
20
+ failure_message_when_negated do |expected|
21
+ matching =
22
+ published_messages(expected[:exchange_name]).select do |m|
23
+ matches_message?(m, expected)
24
+ end
25
+ "expected no message with #{expected.inspect} to have been published, but found:\n" \
26
+ "#{matching.map(&:inspect).join("\n")}"
27
+ end
28
+
29
+ def matches_message?(published, expected)
30
+ routing_key = expected[:routing_key]
31
+ data = expected[:data]
32
+ options = expected[:options]
33
+
34
+ [
35
+ (routing_key.nil? || published.routing_key == routing_key),
36
+ (data.nil? || published.data == data),
37
+ (options.nil? || options.all? { |k, v| published.options[k] == v }),
38
+ ].all?
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
data/lib/ears/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Ears
2
- VERSION = '0.22.2'
2
+ VERSION = '0.23.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ears
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.22.2
4
+ version: 0.23.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - InVision AG
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-09-22 00:00:00.000000000 Z
11
+ date: 2025-11-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bunny
@@ -93,6 +93,7 @@ files:
93
93
  - lib/ears/publisher_retry_handler.rb
94
94
  - lib/ears/setup.rb
95
95
  - lib/ears/testing.rb
96
+ - lib/ears/testing/matchers.rb
96
97
  - lib/ears/testing/message_capture.rb
97
98
  - lib/ears/testing/publisher_mock.rb
98
99
  - lib/ears/testing/test_helper.rb