rspec-sse-matchers 0.0.1 → 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 +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +53 -53
- data/examples/sse_spec.rb +7 -7
- data/lib/rspec/sse/matchers/version.rb +1 -1
- data/lib/rspec/sse/matchers.rb +34 -32
- data/sig/generated/rspec/sse/matchers.rbs +36 -32
- metadata +3 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 17656eeed4d488ddf391e1e28408bdc5725db0e8e5c8995b7dbe0e3110e6bbfe
|
4
|
+
data.tar.gz: f64e736388e0d1ed6c9456ab6e6b9fbc270a63601302a184e61e42e9cfbdb4d1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e8552d575c0766d036c158e8a1444d605ec5808cc9e656c60af85cb61156de91504d50810c04eaa61990b13706adf7516bf49d92c3e191f092d069489bd784eb
|
7
|
+
data.tar.gz: 160aeef4b96028fe0fc43d2627ddf98856d1f5b127f790f12fda8bff0f117dac77f747f422a902a6812904aeaf2d236aa7da372c4eae4fc4694054bcf2d6fbac
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -35,7 +35,7 @@ def index
|
|
35
35
|
response.headers['Cache-Control'] = 'no-store'
|
36
36
|
response.headers['Content-Type'] = 'text/event-stream'
|
37
37
|
sse = SSE.new(response.stream)
|
38
|
-
|
38
|
+
|
39
39
|
sse.write({id: 1, message: 'Hello'}, event: 'message', id: 1)
|
40
40
|
sse.write({id: 2, message: 'World'}, event: 'update', id: 2)
|
41
41
|
sse.close
|
@@ -45,15 +45,15 @@ end
|
|
45
45
|
RSpec.describe 'SSE endpoint', type: :request do
|
46
46
|
it 'sends the expected events' do
|
47
47
|
get '/events', headers: { 'Accept' => 'text/event-stream' }
|
48
|
-
|
48
|
+
|
49
49
|
# Verify the response indicates a successful SSE connection
|
50
|
-
expect(response).to
|
51
|
-
|
50
|
+
expect(response).to be_sse_successfully_opened
|
51
|
+
|
52
52
|
# Verify the event types
|
53
|
-
expect(response).to
|
54
|
-
|
53
|
+
expect(response).to be_sse_event_types(['message', 'update'])
|
54
|
+
|
55
55
|
# Verify that the response is properly closed
|
56
|
-
expect(response).to
|
56
|
+
expect(response).to be_sse_gracefully_closed
|
57
57
|
end
|
58
58
|
end
|
59
59
|
```
|
@@ -64,38 +64,38 @@ end
|
|
64
64
|
|
65
65
|
These matchers check that the specified values appear in the exact order:
|
66
66
|
|
67
|
-
- `
|
68
|
-
- `
|
69
|
-
- `
|
70
|
-
- `
|
71
|
-
- `
|
67
|
+
- `be_sse_events`: Check that the events exactly match the expected events
|
68
|
+
- `be_sse_event_types`: Check that the event types exactly match the expected types
|
69
|
+
- `be_sse_event_data`: Check that the event data exactly match the expected data
|
70
|
+
- `be_sse_event_ids`: Check that the event IDs exactly match the expected IDs
|
71
|
+
- `be_sse_reconnection_times`: Check that the reconnection times exactly match the expected times
|
72
72
|
|
73
|
-
All event data matchers (`
|
73
|
+
All event data matchers (`be_sse_event_data`, `contain_exactly_sse_event_data`, `have_sse_event_data`) and event matchers (`be_sse_events`, `contain_exactly_sse_events`, `have_sse_events`) accept a `json: true` option that will parse the JSON in event data for comparison.
|
74
74
|
|
75
75
|
#### Order-Independent Matchers
|
76
76
|
|
77
77
|
These matchers check that the specified values appear in any order:
|
78
78
|
|
79
|
-
- `
|
80
|
-
- `
|
81
|
-
- `
|
82
|
-
- `
|
83
|
-
- `
|
79
|
+
- `contain_exactly_sse_events`: Check that the events match the expected events regardless of order
|
80
|
+
- `contain_exactly_sse_event_types`: Check that the event types match the expected types regardless of order
|
81
|
+
- `contain_exactly_sse_event_data`: Check that the event data match the expected data regardless of order
|
82
|
+
- `contain_exactly_sse_event_ids`: Check that the event IDs match the expected IDs regardless of order
|
83
|
+
- `contain_exactly_sse_reconnection_times`: Check that the reconnection times match the expected times regardless of order
|
84
84
|
|
85
85
|
#### Inclusion Matchers
|
86
86
|
|
87
87
|
These matchers check that all the expected values are included:
|
88
88
|
|
89
|
-
- `
|
90
|
-
- `
|
91
|
-
- `
|
92
|
-
- `
|
93
|
-
- `
|
89
|
+
- `have_sse_events`: Check that all the expected events are included
|
90
|
+
- `have_sse_event_types`: Check that all the expected event types are included
|
91
|
+
- `have_sse_event_data`: Check that all the expected event data are included
|
92
|
+
- `have_sse_event_ids`: Check that all the expected event IDs are included
|
93
|
+
- `have_sse_reconnection_times`: Check that all the expected reconnection times are included
|
94
94
|
|
95
95
|
#### Miscellaneous Matchers
|
96
96
|
|
97
|
-
- `
|
98
|
-
- `
|
97
|
+
- `be_sse_successfully_opened`: Check that the response indicates the SSE connection has been opened successfully
|
98
|
+
- `be_sse_gracefully_closed`: Check that the response body ends with "\n\n" (indicating proper SSE close)
|
99
99
|
|
100
100
|
### Argument Formats
|
101
101
|
|
@@ -103,8 +103,8 @@ All matchers can accept their arguments either as individual arguments or as an
|
|
103
103
|
|
104
104
|
```ruby
|
105
105
|
# These are equivalent:
|
106
|
-
expect(response).to
|
107
|
-
expect(response).to
|
106
|
+
expect(response).to have_sse_event_types('message', 'update', 'close')
|
107
|
+
expect(response).to have_sse_event_types(['message', 'update', 'close'])
|
108
108
|
```
|
109
109
|
|
110
110
|
### JSON Parsing Option
|
@@ -113,15 +113,15 @@ Event data matchers and event matchers accept a `json: true` option that automat
|
|
113
113
|
|
114
114
|
```ruby
|
115
115
|
# Without JSON parsing (string comparison)
|
116
|
-
expect(response).to
|
116
|
+
expect(response).to be_sse_event_data(['{"id":1,"name":"Alice"}', '{"id":2,"name":"Bob"}'])
|
117
117
|
|
118
118
|
# With JSON parsing (object comparison)
|
119
|
-
expect(response).to
|
119
|
+
expect(response).to be_sse_event_data([{"id" => 1, "name" => "Alice"}, {"id" => 2, "name" => "Bob"}], json: true)
|
120
120
|
|
121
121
|
# This also works with event matchers
|
122
|
-
expect(response).to
|
123
|
-
{
|
124
|
-
{
|
122
|
+
expect(response).to be_sse_events([
|
123
|
+
{type: 'message', data: {"id" => 1, "name" => "Alice"}, id: '1'},
|
124
|
+
{type: 'update', data: {"id" => 2, "name" => "Bob"}, id: '2'}
|
125
125
|
], json: true)
|
126
126
|
```
|
127
127
|
|
@@ -133,80 +133,80 @@ When the `json: true` option is enabled, the matcher attempts to parse each even
|
|
133
133
|
|
134
134
|
```ruby
|
135
135
|
# Exact order
|
136
|
-
expect(response).to
|
136
|
+
expect(response).to be_sse_event_types(['message', 'update', 'close'])
|
137
137
|
|
138
138
|
# Any order
|
139
|
-
expect(response).to
|
139
|
+
expect(response).to contain_exactly_sse_event_types(['update', 'message', 'close'])
|
140
140
|
|
141
141
|
# Inclusion
|
142
|
-
expect(response).to
|
142
|
+
expect(response).to have_sse_event_types(['message', 'update'])
|
143
143
|
```
|
144
144
|
|
145
145
|
### Testing Event Data
|
146
146
|
|
147
147
|
```ruby
|
148
148
|
# Exact order
|
149
|
-
expect(response).to
|
149
|
+
expect(response).to be_sse_event_data(['{"id":1}', '{"id":2}', '{"id":3}'])
|
150
150
|
|
151
151
|
# Any order
|
152
|
-
expect(response).to
|
152
|
+
expect(response).to contain_exactly_sse_event_data(['{"id":2}', '{"id":1}', '{"id":3}'])
|
153
153
|
|
154
154
|
# Inclusion
|
155
|
-
expect(response).to
|
155
|
+
expect(response).to have_sse_event_data(['{"id":1}', '{"id":2}'])
|
156
156
|
|
157
157
|
# With JSON parsing
|
158
|
-
expect(response).to
|
158
|
+
expect(response).to be_sse_event_data([{"id" => 1}, {"id" => 2}, {"id" => 3}], json: true)
|
159
159
|
```
|
160
160
|
|
161
161
|
### Testing Event IDs
|
162
162
|
|
163
163
|
```ruby
|
164
164
|
# Exact order
|
165
|
-
expect(response).to
|
165
|
+
expect(response).to be_sse_event_ids(['1', '2', '3'])
|
166
166
|
|
167
167
|
# Any order
|
168
|
-
expect(response).to
|
168
|
+
expect(response).to contain_exactly_sse_event_ids(['2', '1', '3'])
|
169
169
|
|
170
170
|
# Inclusion
|
171
|
-
expect(response).to
|
171
|
+
expect(response).to have_sse_event_ids(['1', '2'])
|
172
172
|
```
|
173
173
|
|
174
174
|
### Testing Reconnection Times
|
175
175
|
|
176
176
|
```ruby
|
177
177
|
# Exact order
|
178
|
-
expect(response).to
|
178
|
+
expect(response).to be_sse_reconnection_times([1000, 2000, 3000])
|
179
179
|
|
180
180
|
# Any order
|
181
|
-
expect(response).to
|
181
|
+
expect(response).to contain_exactly_sse_reconnection_times([2000, 1000, 3000])
|
182
182
|
|
183
183
|
# Inclusion
|
184
|
-
expect(response).to
|
184
|
+
expect(response).to have_sse_reconnection_times([1000, 2000])
|
185
185
|
```
|
186
186
|
|
187
187
|
### Testing Complete Events
|
188
188
|
|
189
189
|
```ruby
|
190
190
|
events = [
|
191
|
-
{
|
192
|
-
{
|
191
|
+
{type: 'message', data: '{"id":1}', id: '1', retry: 1000},
|
192
|
+
{type: 'update', data: '{"id":2}', id: '2', retry: 2000}
|
193
193
|
]
|
194
194
|
|
195
195
|
# Exact order
|
196
|
-
expect(response).to
|
196
|
+
expect(response).to be_sse_events(events)
|
197
197
|
|
198
198
|
# Any order
|
199
|
-
expect(response).to
|
199
|
+
expect(response).to contain_exactly_sse_events(events)
|
200
200
|
|
201
201
|
# Inclusion
|
202
|
-
expect(response).to
|
202
|
+
expect(response).to have_sse_events([events.first])
|
203
203
|
|
204
204
|
# With JSON parsing
|
205
205
|
json_events = [
|
206
|
-
{
|
207
|
-
{
|
206
|
+
{type: 'message', data: {"id" => 1}, id: '1', retry: 1000},
|
207
|
+
{type: 'update', data: {"id" => 2}, id: '2', retry: 2000}
|
208
208
|
]
|
209
|
-
expect(response).to
|
209
|
+
expect(response).to be_sse_events(json_events, json: true)
|
210
210
|
```
|
211
211
|
|
212
212
|
## Development
|
data/examples/sse_spec.rb
CHANGED
@@ -82,31 +82,31 @@ RSpec.describe "SSE Matchers Examples" do
|
|
82
82
|
describe "Order-Independent Matchers" do
|
83
83
|
context "contain_exactly_events" do
|
84
84
|
it "passes when events match in any order" do
|
85
|
-
expect(multiple_events_response).to
|
85
|
+
expect(multiple_events_response).to contain_exactly_sse_events([event3, event1, event2])
|
86
86
|
end
|
87
87
|
end
|
88
88
|
|
89
89
|
context "contain_exactly_event_types" do
|
90
90
|
it "passes when event types match in any order" do
|
91
|
-
expect(multiple_events_response).to
|
91
|
+
expect(multiple_events_response).to contain_exactly_sse_event_types(%w[close message update])
|
92
92
|
end
|
93
93
|
end
|
94
94
|
|
95
95
|
context "contain_exactly_event_data" do
|
96
96
|
it "passes when event data match in any order" do
|
97
|
-
expect(multiple_events_response).to
|
97
|
+
expect(multiple_events_response).to contain_exactly_sse_event_data(%w[{"id":3,"message":"Goodbye"} {"id":1,"message":"Hello"} {"id":2,"message":"World"}])
|
98
98
|
end
|
99
99
|
end
|
100
100
|
|
101
101
|
context "contain_exactly_event_ids" do
|
102
102
|
it "passes when event IDs match in any order" do
|
103
|
-
expect(multiple_events_response).to
|
103
|
+
expect(multiple_events_response).to contain_exactly_sse_event_ids(%w[3 1 2])
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
107
107
|
context "contain_exactly_reconnection_times" do
|
108
108
|
it "passes when reconnection times match in any order" do
|
109
|
-
expect(multiple_events_response).to
|
109
|
+
expect(multiple_events_response).to contain_exactly_sse_reconnection_times([3000, 1000, 2000])
|
110
110
|
end
|
111
111
|
end
|
112
112
|
end
|
@@ -156,7 +156,7 @@ RSpec.describe "SSE Matchers Examples" do
|
|
156
156
|
|
157
157
|
it "fails when the response body doesn't end with a double newline" do
|
158
158
|
incomplete_response = MockResponse.new("event: message\ndata: test\n")
|
159
|
-
expect(incomplete_response).not_to
|
159
|
+
expect(incomplete_response).not_to be_sse_gracefully_closed
|
160
160
|
end
|
161
161
|
end
|
162
162
|
end
|
@@ -186,7 +186,7 @@ RSpec.describe "SSE Matchers Examples" do
|
|
186
186
|
end
|
187
187
|
|
188
188
|
it "works with contain_exactly matchers" do
|
189
|
-
expect(multiple_events_response).to
|
189
|
+
expect(multiple_events_response).to contain_exactly_sse_event_data([
|
190
190
|
{"id" => 3, "message" => "Goodbye"},
|
191
191
|
{"id" => 1, "message" => "Hello"},
|
192
192
|
{"id" => 2, "message" => "World"}
|
data/lib/rspec/sse/matchers.rb
CHANGED
@@ -5,29 +5,32 @@ require "event_stream_parser"
|
|
5
5
|
require "json"
|
6
6
|
|
7
7
|
# @rbs!
|
8
|
-
# type
|
8
|
+
# type jsonParsedData = Hash[String, untyped]
|
9
|
+
# type ssePayload = {type: String?, data: String, id: String?, retry: Integer?}
|
10
|
+
# type ssePayloadWithJSONParsedData = {type: String?, data: jsonParsedData, id: String?, retry: Integer?}
|
9
11
|
|
10
12
|
module RSpec
|
11
13
|
module Matchers
|
12
|
-
# Matches if the response body ends with "\n\n"
|
14
|
+
# Matches if the response body ends with "\n\n"(SSE graceful close)
|
15
|
+
#
|
13
16
|
# @rbs return: RSpec::SSE::Matchers::BeGracefullyClosed
|
14
|
-
def
|
17
|
+
def be_sse_gracefully_closed
|
15
18
|
RSpec::SSE::Matchers::BeGracefullyClosed.new
|
16
19
|
end
|
17
20
|
|
18
21
|
# Matches if the response indicates successfully SSE connection opened
|
19
22
|
#
|
20
23
|
# @rbs return: RSpec::SSE::Matchers::BeSuccessfullyOpened
|
21
|
-
def
|
24
|
+
def be_sse_successfully_opened
|
22
25
|
RSpec::SSE::Matchers::BeSuccessfullyOpened.new
|
23
26
|
end
|
24
27
|
|
25
28
|
# Matches if the response's events match the expected events in order
|
26
29
|
#
|
27
|
-
# @rbs *events: ssePayload | Array[ssePayload]
|
30
|
+
# @rbs *events: ssePayload | Array[ssePayload] | ssePayloadWithJSONParsedData | Array[ssePayloadWithJSONParsedData]
|
28
31
|
# @rbs json: bool
|
29
32
|
# @rbs return: RSpec::SSE::Matchers::BeEvents
|
30
|
-
def
|
33
|
+
def be_sse_events(*events, json: false)
|
31
34
|
RSpec::SSE::Matchers::BeEvents.new(events.flatten, json:)
|
32
35
|
end
|
33
36
|
|
@@ -35,24 +38,24 @@ module RSpec
|
|
35
38
|
#
|
36
39
|
# @rbs *types: String | Array[String]
|
37
40
|
# @rbs return: RSpec::SSE::Matchers::BeEventTypes
|
38
|
-
def
|
41
|
+
def be_sse_event_types(*types)
|
39
42
|
RSpec::SSE::Matchers::BeEventTypes.new(types.flatten)
|
40
43
|
end
|
41
44
|
|
42
45
|
# Matches if the response's event data match the expected data in order
|
43
46
|
#
|
44
|
-
# @rbs *data: String | Array[String] | Array[
|
47
|
+
# @rbs *data: String | Array[String] | jsonParsedData | Array[jsonParsedData]
|
45
48
|
# @rbs json: bool
|
46
49
|
# @rbs return: RSpec::SSE::Matchers::BeEventData
|
47
|
-
def
|
50
|
+
def be_sse_event_data(*data, json: false)
|
48
51
|
RSpec::SSE::Matchers::BeEventData.new(data.flatten, json:)
|
49
52
|
end
|
50
53
|
|
51
54
|
# Matches if the response's event IDs match the expected IDs in order
|
52
55
|
#
|
53
|
-
# @rbs *ids: String
|
56
|
+
# @rbs *ids: String | Array[String]
|
54
57
|
# @rbs return: RSpec::SSE::Matchers::BeEventIds
|
55
|
-
def
|
58
|
+
def be_sse_event_ids(*ids)
|
56
59
|
RSpec::SSE::Matchers::BeEventIds.new(ids.flatten)
|
57
60
|
end
|
58
61
|
|
@@ -60,16 +63,16 @@ module RSpec
|
|
60
63
|
#
|
61
64
|
# @rbs *times: Integer | Array[Integer]
|
62
65
|
# @rbs return: RSpec::SSE::Matchers::BeReconnectionTimes
|
63
|
-
def
|
66
|
+
def be_sse_reconnection_times(*times)
|
64
67
|
RSpec::SSE::Matchers::BeReconnectionTimes.new(times.flatten)
|
65
68
|
end
|
66
69
|
|
67
70
|
# Matches if the response's events contain the expected events regardless of order
|
68
71
|
#
|
69
|
-
# @rbs *events: ssePayload | Array[ssePayload]
|
72
|
+
# @rbs *events: ssePayload | Array[ssePayload] | ssePayloadWithJSONParsedData | Array[ssePayloadWithJSONParsedData]
|
70
73
|
# @rbs json: bool
|
71
74
|
# @rbs return: RSpec::SSE::Matchers::ContainExactlyEvents
|
72
|
-
def
|
75
|
+
def contain_exactly_sse_events(*events, json: false)
|
73
76
|
RSpec::SSE::Matchers::ContainExactlyEvents.new(events.flatten, json:)
|
74
77
|
end
|
75
78
|
|
@@ -77,16 +80,16 @@ module RSpec
|
|
77
80
|
#
|
78
81
|
# @rbs *types: String | Array[String]
|
79
82
|
# @rbs return: RSpec::SSE::Matchers::ContainExactlyEventTypes
|
80
|
-
def
|
83
|
+
def contain_exactly_sse_event_types(*types)
|
81
84
|
RSpec::SSE::Matchers::ContainExactlyEventTypes.new(types.flatten)
|
82
85
|
end
|
83
86
|
|
84
87
|
# Matches if the response's event data contain the expected data regardless of order
|
85
88
|
#
|
86
|
-
# @rbs *data: String | Array[String] | Array[
|
89
|
+
# @rbs *data: String | Array[String] | jsonParsedData | Array[jsonParsedData]
|
87
90
|
# @rbs json: bool
|
88
91
|
# @rbs return: RSpec::SSE::Matchers::ContainExactlyEventData
|
89
|
-
def
|
92
|
+
def contain_exactly_sse_event_data(*data, json: false)
|
90
93
|
RSpec::SSE::Matchers::ContainExactlyEventData.new(data.flatten, json:)
|
91
94
|
end
|
92
95
|
|
@@ -94,7 +97,7 @@ module RSpec
|
|
94
97
|
#
|
95
98
|
# @rbs *ids: String | Array[String]
|
96
99
|
# @rbs return: RSpec::SSE::Matchers::ContainExactlyEventIds
|
97
|
-
def
|
100
|
+
def contain_exactly_sse_event_ids(*ids)
|
98
101
|
RSpec::SSE::Matchers::ContainExactlyEventIds.new(ids.flatten)
|
99
102
|
end
|
100
103
|
|
@@ -102,16 +105,16 @@ module RSpec
|
|
102
105
|
#
|
103
106
|
# @rbs *times: Integer | Array[Integer]
|
104
107
|
# @rbs return: RSpec::SSE::Matchers::ContainExactlyReconnectionTimes
|
105
|
-
def
|
108
|
+
def contain_exactly_sse_reconnection_times(*times)
|
106
109
|
RSpec::SSE::Matchers::ContainExactlyReconnectionTimes.new(times.flatten)
|
107
110
|
end
|
108
111
|
|
109
112
|
# Matches if the response's events include all the expected events
|
110
113
|
#
|
111
|
-
# @rbs *events: ssePayload
|
114
|
+
# @rbs *events: ssePayload | Array[ssePayload] | ssePayloadWithJSONParsedData | Array[ssePayloadWithJSONParsedData]
|
112
115
|
# @rbs json: bool
|
113
116
|
# @rbs return: RSpec::SSE::Matchers::HaveEvents
|
114
|
-
def
|
117
|
+
def have_sse_events(*events, json: false)
|
115
118
|
RSpec::SSE::Matchers::HaveEvents.new(events.flatten, json:)
|
116
119
|
end
|
117
120
|
|
@@ -119,32 +122,32 @@ module RSpec
|
|
119
122
|
#
|
120
123
|
# @rbs *types: String | Array[String]
|
121
124
|
# @rbs return: RSpec::SSE::Matchers::HaveEventTypes
|
122
|
-
def
|
125
|
+
def have_sse_event_types(*types)
|
123
126
|
RSpec::SSE::Matchers::HaveEventTypes.new(types.flatten)
|
124
127
|
end
|
125
128
|
|
126
129
|
# Matches if the response's event data include all the expected data
|
127
130
|
#
|
128
|
-
# @rbs *data: String | Array[String] | Array[
|
131
|
+
# @rbs *data: String | Array[String] | jsonParsedData | Array[jsonParsedData]
|
129
132
|
# @rbs json: bool
|
130
133
|
# @rbs return: RSpec::SSE::Matchers::HaveEventData
|
131
|
-
def
|
134
|
+
def have_sse_event_data(*data, json: false)
|
132
135
|
RSpec::SSE::Matchers::HaveEventData.new(data.flatten, json:)
|
133
136
|
end
|
134
137
|
|
135
138
|
# Matches if the response's event IDs include all the expected IDs
|
136
139
|
#
|
137
|
-
# @rbs *ids: String
|
140
|
+
# @rbs *ids: String | Array[String]
|
138
141
|
# @rbs return: RSpec::SSE::Matchers::HaveEventIds
|
139
|
-
def
|
142
|
+
def have_sse_event_ids(*ids)
|
140
143
|
RSpec::SSE::Matchers::HaveEventIds.new(ids.flatten)
|
141
144
|
end
|
142
145
|
|
143
146
|
# Matches if the response's reconnection times include all the expected times
|
144
147
|
#
|
145
|
-
# @rbs *times: Integer
|
148
|
+
# @rbs *times: Integer | Array[Integer]
|
146
149
|
# @rbs return: RSpec::SSE::Matchers::HaveReconnectionTimes
|
147
|
-
def
|
150
|
+
def have_sse_reconnection_times(*times)
|
148
151
|
RSpec::SSE::Matchers::HaveReconnectionTimes.new(times.flatten)
|
149
152
|
end
|
150
153
|
end
|
@@ -179,7 +182,6 @@ module RSpec
|
|
179
182
|
# Initialize the matcher with expected values
|
180
183
|
#
|
181
184
|
# @rbs expected: Array[Object]
|
182
|
-
# @rbs return: RSpec::SSE::Matchers::BaseMatcher
|
183
185
|
def initialize(expected, json: false)
|
184
186
|
@expected = expected
|
185
187
|
@json = json
|
@@ -240,7 +242,7 @@ module RSpec
|
|
240
242
|
class BeGracefullyClosed
|
241
243
|
# @rbs @actual: Object
|
242
244
|
|
243
|
-
# Match if the response body ends with "\n\n"
|
245
|
+
# Match if the response body ends with "\n\n"(SSE graceful close)
|
244
246
|
#
|
245
247
|
# @rbs actual: Object
|
246
248
|
# @rbs return: bool
|
@@ -405,12 +407,12 @@ module RSpec
|
|
405
407
|
private
|
406
408
|
|
407
409
|
# Extract event data from parsed events
|
408
|
-
# If
|
410
|
+
# If `:json` option is enabled, attempt to parse the data as JSON
|
409
411
|
#
|
410
412
|
# @rbs return: Array[String|Hash[String, untyped]]
|
411
413
|
def extract_actual
|
412
414
|
@parsed_events.map do |event|
|
413
|
-
# JSON parsing is enabled if json
|
415
|
+
# JSON parsing is enabled if `json:` true is passed
|
414
416
|
if @json
|
415
417
|
JSON.parse(event[:data])
|
416
418
|
else
|
@@ -2,110 +2,111 @@
|
|
2
2
|
|
3
3
|
module RSpec
|
4
4
|
module Matchers
|
5
|
-
# Matches if the response body ends with "\n\n"
|
5
|
+
# Matches if the response body ends with "\n\n"(SSE graceful close)
|
6
|
+
#
|
6
7
|
# @rbs return: RSpec::SSE::Matchers::BeGracefullyClosed
|
7
|
-
def
|
8
|
+
def be_sse_gracefully_closed: () -> RSpec::SSE::Matchers::BeGracefullyClosed
|
8
9
|
|
9
10
|
# Matches if the response indicates successfully SSE connection opened
|
10
11
|
#
|
11
12
|
# @rbs return: RSpec::SSE::Matchers::BeSuccessfullyOpened
|
12
|
-
def
|
13
|
+
def be_sse_successfully_opened: () -> RSpec::SSE::Matchers::BeSuccessfullyOpened
|
13
14
|
|
14
15
|
# Matches if the response's events match the expected events in order
|
15
16
|
#
|
16
|
-
# @rbs *events: ssePayload | Array[ssePayload]
|
17
|
+
# @rbs *events: ssePayload | Array[ssePayload] | ssePayloadWithJSONParsedData | Array[ssePayloadWithJSONParsedData]
|
17
18
|
# @rbs json: bool
|
18
19
|
# @rbs return: RSpec::SSE::Matchers::BeEvents
|
19
|
-
def
|
20
|
+
def be_sse_events: (*ssePayload | Array[ssePayload] | ssePayloadWithJSONParsedData | Array[ssePayloadWithJSONParsedData] events, ?json: bool) -> RSpec::SSE::Matchers::BeEvents
|
20
21
|
|
21
22
|
# Matches if the response's event types match the expected types in order
|
22
23
|
#
|
23
24
|
# @rbs *types: String | Array[String]
|
24
25
|
# @rbs return: RSpec::SSE::Matchers::BeEventTypes
|
25
|
-
def
|
26
|
+
def be_sse_event_types: (*String | Array[String] types) -> RSpec::SSE::Matchers::BeEventTypes
|
26
27
|
|
27
28
|
# Matches if the response's event data match the expected data in order
|
28
29
|
#
|
29
|
-
# @rbs *data: String | Array[String] | Array[
|
30
|
+
# @rbs *data: String | Array[String] | jsonParsedData | Array[jsonParsedData]
|
30
31
|
# @rbs json: bool
|
31
32
|
# @rbs return: RSpec::SSE::Matchers::BeEventData
|
32
|
-
def
|
33
|
+
def be_sse_event_data: (*String | Array[String] | jsonParsedData | Array[jsonParsedData] data, ?json: bool) -> RSpec::SSE::Matchers::BeEventData
|
33
34
|
|
34
35
|
# Matches if the response's event IDs match the expected IDs in order
|
35
36
|
#
|
36
|
-
# @rbs *ids: String
|
37
|
+
# @rbs *ids: String | Array[String]
|
37
38
|
# @rbs return: RSpec::SSE::Matchers::BeEventIds
|
38
|
-
def
|
39
|
+
def be_sse_event_ids: (*String | Array[String] ids) -> RSpec::SSE::Matchers::BeEventIds
|
39
40
|
|
40
41
|
# Matches if the response's reconnection times match the expected times in order
|
41
42
|
#
|
42
43
|
# @rbs *times: Integer | Array[Integer]
|
43
44
|
# @rbs return: RSpec::SSE::Matchers::BeReconnectionTimes
|
44
|
-
def
|
45
|
+
def be_sse_reconnection_times: (*Integer | Array[Integer] times) -> RSpec::SSE::Matchers::BeReconnectionTimes
|
45
46
|
|
46
47
|
# Matches if the response's events contain the expected events regardless of order
|
47
48
|
#
|
48
|
-
# @rbs *events: ssePayload | Array[ssePayload]
|
49
|
+
# @rbs *events: ssePayload | Array[ssePayload] | ssePayloadWithJSONParsedData | Array[ssePayloadWithJSONParsedData]
|
49
50
|
# @rbs json: bool
|
50
51
|
# @rbs return: RSpec::SSE::Matchers::ContainExactlyEvents
|
51
|
-
def
|
52
|
+
def contain_exactly_sse_events: (*ssePayload | Array[ssePayload] | ssePayloadWithJSONParsedData | Array[ssePayloadWithJSONParsedData] events, ?json: bool) -> RSpec::SSE::Matchers::ContainExactlyEvents
|
52
53
|
|
53
54
|
# Matches if the response's event types contain the expected types regardless of order
|
54
55
|
#
|
55
56
|
# @rbs *types: String | Array[String]
|
56
57
|
# @rbs return: RSpec::SSE::Matchers::ContainExactlyEventTypes
|
57
|
-
def
|
58
|
+
def contain_exactly_sse_event_types: (*String | Array[String] types) -> RSpec::SSE::Matchers::ContainExactlyEventTypes
|
58
59
|
|
59
60
|
# Matches if the response's event data contain the expected data regardless of order
|
60
61
|
#
|
61
|
-
# @rbs *data: String | Array[String] | Array[
|
62
|
+
# @rbs *data: String | Array[String] | jsonParsedData | Array[jsonParsedData]
|
62
63
|
# @rbs json: bool
|
63
64
|
# @rbs return: RSpec::SSE::Matchers::ContainExactlyEventData
|
64
|
-
def
|
65
|
+
def contain_exactly_sse_event_data: (*String | Array[String] | jsonParsedData | Array[jsonParsedData] data, ?json: bool) -> RSpec::SSE::Matchers::ContainExactlyEventData
|
65
66
|
|
66
67
|
# Matches if the response's event IDs contain the expected IDs regardless of order
|
67
68
|
#
|
68
69
|
# @rbs *ids: String | Array[String]
|
69
70
|
# @rbs return: RSpec::SSE::Matchers::ContainExactlyEventIds
|
70
|
-
def
|
71
|
+
def contain_exactly_sse_event_ids: (*String | Array[String] ids) -> RSpec::SSE::Matchers::ContainExactlyEventIds
|
71
72
|
|
72
73
|
# Matches if the response's reconnection times contain the expected times regardless of order
|
73
74
|
#
|
74
75
|
# @rbs *times: Integer | Array[Integer]
|
75
76
|
# @rbs return: RSpec::SSE::Matchers::ContainExactlyReconnectionTimes
|
76
|
-
def
|
77
|
+
def contain_exactly_sse_reconnection_times: (*Integer | Array[Integer] times) -> RSpec::SSE::Matchers::ContainExactlyReconnectionTimes
|
77
78
|
|
78
79
|
# Matches if the response's events include all the expected events
|
79
80
|
#
|
80
|
-
# @rbs *events: ssePayload
|
81
|
+
# @rbs *events: ssePayload | Array[ssePayload] | ssePayloadWithJSONParsedData | Array[ssePayloadWithJSONParsedData]
|
81
82
|
# @rbs json: bool
|
82
83
|
# @rbs return: RSpec::SSE::Matchers::HaveEvents
|
83
|
-
def
|
84
|
+
def have_sse_events: (*ssePayload | Array[ssePayload] | ssePayloadWithJSONParsedData | Array[ssePayloadWithJSONParsedData] events, ?json: bool) -> RSpec::SSE::Matchers::HaveEvents
|
84
85
|
|
85
86
|
# Matches if the response's event types include all the expected types
|
86
87
|
#
|
87
88
|
# @rbs *types: String | Array[String]
|
88
89
|
# @rbs return: RSpec::SSE::Matchers::HaveEventTypes
|
89
|
-
def
|
90
|
+
def have_sse_event_types: (*String | Array[String] types) -> RSpec::SSE::Matchers::HaveEventTypes
|
90
91
|
|
91
92
|
# Matches if the response's event data include all the expected data
|
92
93
|
#
|
93
|
-
# @rbs *data: String | Array[String] | Array[
|
94
|
+
# @rbs *data: String | Array[String] | jsonParsedData | Array[jsonParsedData]
|
94
95
|
# @rbs json: bool
|
95
96
|
# @rbs return: RSpec::SSE::Matchers::HaveEventData
|
96
|
-
def
|
97
|
+
def have_sse_event_data: (*String | Array[String] | jsonParsedData | Array[jsonParsedData] data, ?json: bool) -> RSpec::SSE::Matchers::HaveEventData
|
97
98
|
|
98
99
|
# Matches if the response's event IDs include all the expected IDs
|
99
100
|
#
|
100
|
-
# @rbs *ids: String
|
101
|
+
# @rbs *ids: String | Array[String]
|
101
102
|
# @rbs return: RSpec::SSE::Matchers::HaveEventIds
|
102
|
-
def
|
103
|
+
def have_sse_event_ids: (*String | Array[String] ids) -> RSpec::SSE::Matchers::HaveEventIds
|
103
104
|
|
104
105
|
# Matches if the response's reconnection times include all the expected times
|
105
106
|
#
|
106
|
-
# @rbs *times: Integer
|
107
|
+
# @rbs *times: Integer | Array[Integer]
|
107
108
|
# @rbs return: RSpec::SSE::Matchers::HaveReconnectionTimes
|
108
|
-
def
|
109
|
+
def have_sse_reconnection_times: (*Integer | Array[Integer] times) -> RSpec::SSE::Matchers::HaveReconnectionTimes
|
109
110
|
end
|
110
111
|
end
|
111
112
|
|
@@ -130,8 +131,7 @@ module RSpec
|
|
130
131
|
# Initialize the matcher with expected values
|
131
132
|
#
|
132
133
|
# @rbs expected: Array[Object]
|
133
|
-
|
134
|
-
def initialize: (Array[Object] expected, ?json: untyped) -> RSpec::SSE::Matchers::BaseMatcher
|
134
|
+
def initialize: (Array[Object] expected, ?json: untyped) -> untyped
|
135
135
|
|
136
136
|
# @rbs actual: Object
|
137
137
|
# @rbs return: bool
|
@@ -162,7 +162,7 @@ module RSpec
|
|
162
162
|
class BeGracefullyClosed
|
163
163
|
@actual: Object
|
164
164
|
|
165
|
-
# Match if the response body ends with "\n\n"
|
165
|
+
# Match if the response body ends with "\n\n"(SSE graceful close)
|
166
166
|
#
|
167
167
|
# @rbs actual: Object
|
168
168
|
# @rbs return: bool
|
@@ -284,7 +284,7 @@ module RSpec
|
|
284
284
|
private
|
285
285
|
|
286
286
|
# Extract event data from parsed events
|
287
|
-
# If
|
287
|
+
# If `:json` option is enabled, attempt to parse the data as JSON
|
288
288
|
#
|
289
289
|
# @rbs return: Array[String|Hash[String, untyped]]
|
290
290
|
def extract_actual: () -> Array[String | Hash[String, untyped]]
|
@@ -401,4 +401,8 @@ module RSpec
|
|
401
401
|
end
|
402
402
|
end
|
403
403
|
|
404
|
-
type
|
404
|
+
type jsonParsedData = Hash[String, untyped]
|
405
|
+
|
406
|
+
type ssePayload = { type: String?, data: String, id: String?, retry: Integer? }
|
407
|
+
|
408
|
+
type ssePayloadWithJSONParsedData = { type: String?, data: jsonParsedData, id: String?, retry: Integer? }
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec-sse-matchers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- moznion
|
8
|
-
autorequire:
|
9
8
|
bindir: exe
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: event_stream_parser
|
@@ -51,7 +50,6 @@ metadata:
|
|
51
50
|
homepage_uri: https://github.com/moznion/rspec-sse-matchers
|
52
51
|
source_code_uri: https://github.com/moznion/rspec-sse-matchers
|
53
52
|
changelog_uri: https://github.com/moznion/rspec-sse-matchers/blob/main/CHANGELOG.md
|
54
|
-
post_install_message:
|
55
53
|
rdoc_options: []
|
56
54
|
require_paths:
|
57
55
|
- lib
|
@@ -66,8 +64,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
66
64
|
- !ruby/object:Gem::Version
|
67
65
|
version: '0'
|
68
66
|
requirements: []
|
69
|
-
rubygems_version: 3.
|
70
|
-
signing_key:
|
67
|
+
rubygems_version: 3.6.7
|
71
68
|
specification_version: 4
|
72
69
|
summary: RSpec matchers for Server-Sent Events (SSE)
|
73
70
|
test_files: []
|