rspec-twirp 0.1.0 → 0.2.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.
@@ -0,0 +1,181 @@
1
+ describe "make_twirp_request" do
2
+ let(:client) { HelloWorldClient.new(conn) }
3
+ let(:conn) { mock_twirp_connection(response) }
4
+ let!(:other_client) { HelloWorldClient.new(conn) }
5
+ let(:request) { HelloRequest.new(name: "World", count: 3) }
6
+ let(:response) { HelloResponse.new(message: ["Hello", "Hello", "Hello World"]) }
7
+
8
+ def hello
9
+ client.hello(request)
10
+ end
11
+
12
+ describe "block mode" do
13
+ it { expect { hello }.to make_twirp_request }
14
+
15
+ it "returns nil" do
16
+ expect {
17
+ expect(hello).to be_nil
18
+ }.to make_twirp_request
19
+ end
20
+
21
+ context "with client instance matcher" do
22
+ it "matches a client instance" do
23
+ expect { hello }.to make_twirp_request(client)
24
+ end
25
+
26
+ it "matches a pre-existing client instance" do
27
+ expect {
28
+ other_client.hello(HelloRequest.new)
29
+ }.to make_twirp_request(other_client)
30
+ end
31
+
32
+ it "catches client mismaches" do
33
+ expect {
34
+ expect { hello }.to make_twirp_request(other_client)
35
+ }.to fail
36
+ end
37
+ end
38
+
39
+ context "with client class matcher" do
40
+ it "matches a client class" do
41
+ expect { hello }.to make_twirp_request(HelloWorldClient)
42
+ end
43
+
44
+ it "matches subclasses" do
45
+ expect { hello }.to make_twirp_request(Twirp::Client)
46
+ end
47
+
48
+ it "catches mismatches" do
49
+ expect {
50
+ expect { hello }.to make_twirp_request(GoodbyeClient)
51
+ }.to fail
52
+ end
53
+
54
+ it "catches type errors" do
55
+ expect {
56
+ expect { hello }.to make_twirp_request(Object)
57
+ }.to raise_error(TypeError)
58
+ end
59
+ end
60
+
61
+ context "with rpc name matcher" do
62
+ it { expect { hello }.to make_twirp_request(:Hello) }
63
+ it { expect { hello }.to make_twirp_request("Hello") }
64
+ it { expect { hello }.to make_twirp_request(/^He/) }
65
+
66
+ it "catches mismatches" do
67
+ expect {
68
+ expect { hello }.to make_twirp_request(:Bye)
69
+ }.to fail
70
+
71
+ expect {
72
+ expect { hello }.to make_twirp_request(/B/)
73
+ }.to fail
74
+ end
75
+ end
76
+
77
+ context "with input matcher" do
78
+ it "matches messages" do
79
+ expect { hello }.to make_twirp_request.with(request)
80
+ end
81
+
82
+ it "matches message type" do
83
+ expect { hello }.to make_twirp_request.with(HelloRequest)
84
+ end
85
+
86
+ it "matches with attrs" do
87
+ expect { hello }.to make_twirp_request.with(count: 3)
88
+ end
89
+
90
+ context "with json request" do
91
+ it "matches messages" do
92
+ expect {
93
+ client.hello(name: "World")
94
+ }.to make_twirp_request.with(HelloRequest.new(name: "World"))
95
+ end
96
+
97
+ it "matches attrs" do
98
+ expect {
99
+ client.hello(name: "World")
100
+ }.to make_twirp_request.with(name: "World")
101
+ end
102
+ end
103
+
104
+ it "catches mismatches" do
105
+ expect {
106
+ expect { hello }.to make_twirp_request.with(count: 1)
107
+ }.to fail
108
+ end
109
+ end
110
+
111
+ context "with service matcher" do
112
+ it { expect { hello }.to make_twirp_request(HelloWorldService) }
113
+
114
+ it "catches mismatches" do
115
+ expect {
116
+ expect { hello }.to make_twirp_request(GoodbyeService)
117
+ }.to fail
118
+ end
119
+ end
120
+
121
+ describe ".and_call_original" do
122
+ it "calls original" do
123
+ expect {
124
+ expect(hello).to be_a_twirp_response(response)
125
+ }.to make_twirp_request.and_call_original
126
+ end
127
+ end
128
+
129
+ describe ".and_return" do
130
+ it "returns the specified value" do
131
+ expect {
132
+ expect(hello).to be_a_twirp_response(HelloRequest.new)
133
+ }.to make_twirp_request.and_return(HelloRequest.new)
134
+ end
135
+
136
+ it "returns the specified value" do
137
+ expect {
138
+ expect(hello).to be_a_twirp_response(HelloRequest.new)
139
+ }.to make_twirp_request.and_return(HelloRequest)
140
+ end
141
+ end
142
+ end
143
+
144
+ describe "inline mode" do
145
+ after { hello }
146
+
147
+ it { expect(client).to make_twirp_request }
148
+
149
+ it "matches a specific rpc method" do
150
+ expect(client).to make_twirp_request(:hello)
151
+ end
152
+
153
+ it "matches a specific rpc method by rpc name" do
154
+ expect(client).to make_twirp_request(:Hello)
155
+ end
156
+
157
+ it "fails when client is not called within scope" do
158
+ expect_expectation_failure {
159
+ expect(client).to make_twirp_request
160
+ }
161
+ end
162
+
163
+ describe ".with" do
164
+ let(:request) { HelloRequest.new(name: "Daniel") }
165
+
166
+ it "matches the request message" do
167
+ expect(client).to make_twirp_request(:hello).with(request)
168
+ end
169
+
170
+ it "matches the request arguments" do
171
+ expect(client).to make_twirp_request(:hello).with(name: "Daniel")
172
+ end
173
+
174
+ it "fails when params don't match" do
175
+ expect_expectation_failure {
176
+ expect(client).to make_twirp_request.with(name: "Bob")
177
+ }
178
+ end
179
+ end
180
+ end
181
+ end
@@ -0,0 +1,83 @@
1
+ describe "be_a_twirp_message" do
2
+ subject { HelloRequest.new(**attrs) }
3
+
4
+ let(:attrs) { {} }
5
+
6
+ it { is_expected.to be_a_twirp_message }
7
+
8
+ it "works with responses also" do
9
+ expect(HelloResponse.new).to be_a_twirp_message
10
+ end
11
+
12
+ it "supports compound matchers" do
13
+ expect([ subject ]).to include(a_twirp_message)
14
+ end
15
+
16
+ it "catches non-twirp subjects" do
17
+ expect {
18
+ expect(Object).to be_a_twirp_message
19
+ }.to fail_with /Expected a Twirp message, found Object/
20
+ end
21
+
22
+ it "matches a specific message type" do
23
+ is_expected.to be_a_twirp_message(HelloRequest)
24
+ end
25
+
26
+ it "catches type mismatches" do
27
+ expect {
28
+ is_expected.to be_a_twirp_message(GoodbyeRequest)
29
+ }.to fail_with /message of type GoodbyeRequest/
30
+ end
31
+
32
+ it "catches erroneous message types" do
33
+ expect {
34
+ is_expected.to be_a_twirp_message(Object)
35
+ }.to raise_error(TypeError, /Object/)
36
+ end
37
+
38
+ context "with attributes" do
39
+ let(:attrs) { { name: "Bob", count: 3 } }
40
+
41
+ it "can match attributes" do
42
+ is_expected.to be_a_twirp_message(HelloRequest, **attrs)
43
+ end
44
+
45
+ it "supports regex matches" do
46
+ is_expected.to be_a_twirp_message(name: /^B/)
47
+ end
48
+
49
+ it "supports range matches" do
50
+ is_expected.to be_a_twirp_message(count: 1..5)
51
+ end
52
+
53
+ it "catches mismatches" do
54
+ expect {
55
+ is_expected.to be_a_twirp_message(GoodbyeRequest, name: "Bob")
56
+ }.to fail_with /message of type/
57
+
58
+ expect {
59
+ is_expected.to be_a_twirp_message(name: "nope")
60
+ }.to fail_with /to have name: "nope"/
61
+
62
+ expect {
63
+ is_expected.to be_a_twirp_message(name: /no/)
64
+ }.to fail_with /to have name: \/no\//
65
+
66
+ expect {
67
+ is_expected.to be_a_twirp_message(count: 1)
68
+ }.to fail_with /to have count: 1/
69
+ end
70
+
71
+ it "catches the erroneous attribute matches" do
72
+ expect {
73
+ is_expected.to be_a_twirp_message(namezzz: "Bob")
74
+ }.to raise_error(ArgumentError, /namezzz/)
75
+ end
76
+
77
+ it "catches type mismatches" do
78
+ expect {
79
+ is_expected.to be_a_twirp_message(name: 123)
80
+ }.to raise_error(TypeError, /string field.*given Integer/)
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,103 @@
1
+ describe :mock_twirp_connection do
2
+ subject { client.bye(request) }
3
+
4
+ let(:client) { GoodbyeClient.new(conn) }
5
+ let(:request) { GoodbyeRequest.new }
6
+ let(:response) { GoodbyeResponse.new(**response_attrs) }
7
+ let(:response_attrs) { { message: "bye" } }
8
+
9
+ context "without a mock" do
10
+ let(:conn) { "http://localhost:3000/twirp/Goodbye/Bye" }
11
+
12
+ it { expect { subject }.to raise_error(Faraday::Error) }
13
+ end
14
+
15
+ describe "with a response instance" do
16
+ let(:conn) { mock_twirp_connection(response) }
17
+
18
+ it { is_expected.to be_a(Twirp::ClientResp) }
19
+ it { is_expected.to be_a_twirp_response }
20
+ it { is_expected.to be_a_twirp_response(response) }
21
+ it { is_expected.to be_a_twirp_response(message: "bye") }
22
+
23
+ it "catches mismatches" do
24
+ expect {
25
+ is_expected.to be_a_twirp_response(message: "nope")
26
+ }.to fail
27
+ end
28
+ end
29
+
30
+ describe "with a response type" do
31
+ let(:conn) { mock_twirp_connection(GoodbyeResponse) }
32
+
33
+ it { is_expected.to be_a_twirp_response(GoodbyeResponse) }
34
+
35
+ it "catches mismatches" do
36
+ expect {
37
+ is_expected.to be_a_twirp_response(HelloResponse)
38
+ }.to fail
39
+ end
40
+ end
41
+
42
+ describe "with default response" do
43
+ let(:conn) { mock_twirp_connection }
44
+
45
+ it { is_expected.to be_a_twirp_response(GoodbyeResponse) }
46
+
47
+ context "and with attrs" do
48
+ let(:conn) { mock_twirp_connection(message: "adios") }
49
+
50
+ it { is_expected.to be_a_twirp_response(message: "adios") }
51
+ end
52
+ end
53
+
54
+ describe "with an error" do
55
+ let(:conn) { mock_twirp_connection(error) }
56
+ let(:error) { Twirp::Error.not_found("nope") }
57
+
58
+ it { is_expected.to be_a_twirp_response.with_error(error) }
59
+
60
+ context "when error is symbol" do
61
+ let(:error) { :not_found }
62
+
63
+ it { is_expected.to be_a_twirp_response.with_error(404) }
64
+ it { is_expected.to be_a_twirp_response.with_error(:not_found) }
65
+ end
66
+
67
+ context "when error is integer" do
68
+ let(:error) { 500 }
69
+
70
+ it { is_expected.to be_a_twirp_response.with_error(500) }
71
+ it { is_expected.to be_a_twirp_response.with_error(:internal) }
72
+ end
73
+ end
74
+
75
+ describe "with a block" do
76
+ context "with a response object" do
77
+ let(:conn) { mock_twirp_connection { response } }
78
+
79
+ it { is_expected.to be_a_twirp_response(response) }
80
+ end
81
+
82
+ context "with response attrs" do
83
+ let(:conn) { mock_twirp_connection { response_attrs } }
84
+
85
+ it "determines the correct response type and incorporates the attrs" do
86
+ is_expected.to be_a_twirp_response(GoodbyeResponse, **response_attrs)
87
+ end
88
+ end
89
+
90
+ context "with error" do
91
+ let(:conn) { mock_twirp_connection { error } }
92
+ let(:error) { Twirp::Error.not_found("nope") }
93
+
94
+ it { is_expected.to be_a_twirp_response.with_error(error) }
95
+ end
96
+
97
+ context "with error code" do
98
+ let(:conn) { mock_twirp_connection { :not_found } }
99
+
100
+ it { is_expected.to be_a_twirp_response.with_error(:not_found) }
101
+ end
102
+ end
103
+ end
@@ -1,56 +1,124 @@
1
1
  describe "be_a_twirp_response" do
2
- subject { HelloResponse.new(**attrs) }
2
+ context "with a response" do
3
+ subject { Twirp::ClientResp.new(response, nil) }
3
4
 
4
- let(:attrs) { {} }
5
+ let(:response) { GoodbyeResponse.new }
5
6
 
6
- it { is_expected.to be_a_twirp_response }
7
+ it { is_expected.to be_a_twirp_response }
7
8
 
8
- it "catches non-twirp response" do
9
- expect {
10
- expect(Object).to be_a_twirp_response
11
- }.to fail_with /Expected a Twirp response, found Object/
12
- end
9
+ it "catches non-twirp response" do
10
+ expect {
11
+ expect(Object).to be_a_twirp_response
12
+ }.to fail_with /found Object/
13
+ end
13
14
 
14
- it "matches a specific response type" do
15
- is_expected.to be_a_twirp_request(HelloResponse)
16
- end
15
+ it "matches a specific response type" do
16
+ is_expected.to be_a_twirp_response(GoodbyeResponse)
17
+ end
17
18
 
18
- it "catches type mismatches" do
19
- expect {
20
- is_expected.to be_a_twirp_request(GoodbyeResponse)
21
- }.to fail_with /request of type GoodbyeResponse/
22
- end
19
+ it "matches a specific response" do
20
+ is_expected.to be_a_twirp_response(response)
21
+ end
22
+
23
+ it "catches type mismatches" do
24
+ expect {
25
+ is_expected.to be_a_twirp_response(HelloResponse)
26
+ }.to fail_with /of type HelloResponse/
27
+ end
28
+
29
+ it "catches erroneous response types" do
30
+ expect {
31
+ is_expected.to be_a_twirp_response(Object)
32
+ }.to raise_error(ArgumentError, /Object/)
33
+ end
34
+
35
+ context "with attributes" do
36
+ subject { Twirp::ClientResp.new(GoodbyeResponse.new(**attrs), nil) }
23
37
 
24
- context "with attributes" do
25
- let(:attrs) { { message: msg } }
26
- let(:msg) { [ "Hello World" ] }
38
+ let(:attrs) { { message: "bye", name: "Bob" } }
27
39
 
28
- it { is_expected.to be_a_twirp_response(**attrs) }
40
+ it "can match attributes" do
41
+ is_expected.to be_a_twirp_response(GoodbyeResponse, **attrs)
42
+ end
29
43
 
30
- it "supports regex matches" do
31
- is_expected.to be_a_twirp_response(message: include(/Hello/))
44
+ it "supports regex matches" do
45
+ is_expected.to be_a_twirp_response(name: /^B/)
46
+ end
47
+
48
+ it "catches mismatches" do
49
+ expect {
50
+ is_expected.to be_a_twirp_response(name: "nope")
51
+ }.to fail_with /to have name: "nope"/
52
+
53
+ expect {
54
+ is_expected.to be_a_twirp_response(name: /no/)
55
+ }.to fail_with /to have name: \/no\//
56
+ end
57
+
58
+ it "catches the erroneous attributes" do
59
+ expect {
60
+ is_expected.to be_a_twirp_response(namezzz: "Bob")
61
+ }.to raise_error(ArgumentError, /namezzz/)
62
+ end
63
+
64
+ it "catches type mismatches" do
65
+ expect {
66
+ is_expected.to be_a_twirp_response(name: 123)
67
+ }.to raise_error(TypeError, /string field.*given Integer/)
68
+ end
69
+
70
+ it "can't also match a specific response" do
71
+ expect {
72
+ is_expected.to be_a_twirp_response(response, name: "Bob")
73
+ }.to raise_error(ArgumentError, /but not both/)
74
+ end
32
75
  end
76
+ end
77
+
78
+ context "with error" do
79
+ subject { Twirp::ClientResp.new(nil, error) }
80
+
81
+ let(:error) { Twirp::Error.new(code, msg, meta) }
82
+ let(:code) { :not_found }
83
+ let(:msg) { "Not Found" }
84
+ let(:meta) { { is_meta: "true" } }
85
+
86
+ it { is_expected.to be_a_twirp_response.with_error }
87
+ it { is_expected.to be_a_twirp_response.with_error(code) }
88
+ it { is_expected.to be_a_twirp_response.with_error(msg) }
89
+ it { is_expected.to be_a_twirp_response.with_error(**meta) }
90
+ it { is_expected.to be_a_twirp_response.with_error(/Not/) }
33
91
 
34
92
  it "catches mismatches" do
35
93
  expect {
36
- is_expected.to be_a_twirp_response(message: [ "" ])
37
- }.to fail_with /to have message/
94
+ is_expected.to be_a_twirp_response.with_error(:internal)
95
+ }.to fail_with /code: :internal/
96
+ end
97
+ end
98
+
99
+ context "with neither response nor error" do
100
+ subject { Twirp::ClientResp.new(nil, nil) }
38
101
 
102
+ it "fails the response match" do
39
103
  expect {
40
- is_expected.to be_a_twirp_response(message: [ "Hello" ])
41
- }.to fail_with /to have message/
104
+ is_expected.to be_a_twirp_response
105
+ }.to fail_with /to have data/
42
106
  end
43
107
 
44
- it "catches the erroneous attributes" do
108
+ it "fails the error match" do
45
109
  expect {
46
- is_expected.to be_a_twirp_response(msg: [])
47
- }.to raise_error(ArgumentError, /msg/)
110
+ is_expected.to be_a_twirp_response.with_error
111
+ }.to fail_with /to have an error/
48
112
  end
113
+ end
49
114
 
50
- it "catches type mismatches" do
115
+ context "with both response and error" do
116
+ subject { Twirp::ClientResp.new(GoodbyeResponse.new, Twirp::Error.not_found("Not Found")) }
117
+
118
+ it "fails" do
51
119
  expect {
52
- is_expected.to be_a_twirp_response(message: "Hello World")
53
- }.to raise_error(ArgumentError, /Expected array/)
120
+ is_expected.to be_a_twirp_response(name: "Bob").with_error
121
+ }.to raise_error(ArgumentError, /but not both/)
54
122
  end
55
123
  end
56
124
  end
metadata CHANGED
@@ -1,31 +1,31 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-twirp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Pepper
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-09-25 00:00:00.000000000 Z
11
+ date: 2022-10-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: twirp
14
+ name: google-protobuf
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: '3'
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'
26
+ version: '3'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rspec-expectations
28
+ name: rspec
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -39,21 +39,21 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '3'
41
41
  - !ruby/object:Gem::Dependency
42
- name: byebug
42
+ name: twirp
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :development
47
+ version: '1'
48
+ type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: '1'
55
55
  - !ruby/object:Gem::Dependency
56
- name: codecov
56
+ name: byebug
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -67,7 +67,7 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: rspec
70
+ name: codecov
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
@@ -102,14 +102,18 @@ extra_rdoc_files: []
102
102
  files:
103
103
  - lib/rspec-twirp.rb
104
104
  - lib/rspec/twirp.rb
105
- - lib/rspec/twirp/client_response_matcher.rb
106
105
  - lib/rspec/twirp/error_matcher.rb
107
- - lib/rspec/twirp/request_matcher.rb
106
+ - lib/rspec/twirp/helpers.rb
107
+ - lib/rspec/twirp/make_request_matcher.rb
108
+ - lib/rspec/twirp/message_matcher.rb
109
+ - lib/rspec/twirp/mock_client.rb
110
+ - lib/rspec/twirp/mock_connection.rb
108
111
  - lib/rspec/twirp/response_matcher.rb
109
112
  - lib/rspec/twirp/version.rb
110
- - spec/client_response_spec.rb
111
113
  - spec/error_spec.rb
112
- - spec/request_spec.rb
114
+ - spec/make_request_spec.rb
115
+ - spec/message_spec.rb
116
+ - spec/mock_connection_spec.rb
113
117
  - spec/response_spec.rb
114
118
  homepage: https://github.com/dpep/rspec-twirp_rb
115
119
  licenses:
@@ -130,12 +134,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
130
134
  - !ruby/object:Gem::Version
131
135
  version: '0'
132
136
  requirements: []
133
- rubygems_version: 3.1.6
137
+ rubygems_version: 3.3.7
134
138
  signing_key:
135
139
  specification_version: 4
136
140
  summary: Gem::Specification::RSpec::Twirp
137
141
  test_files:
138
142
  - spec/error_spec.rb
139
- - spec/request_spec.rb
143
+ - spec/make_request_spec.rb
144
+ - spec/message_spec.rb
145
+ - spec/mock_connection_spec.rb
140
146
  - spec/response_spec.rb
141
- - spec/client_response_spec.rb
@@ -1,48 +0,0 @@
1
- RSpec::Matchers.define :be_a_twirp_client_response do |type = nil, **attrs|
2
- chain :with_error do |*matchers, **meta_matchers|
3
- # code, msg, meta
4
- @with_error = [ matchers, meta_matchers ]
5
- end
6
-
7
- match do |actual|
8
- # ensure type is a valid twirp request type
9
- if type && !(type < Google::Protobuf::MessageExts)
10
- raise ArgumentError, "Expected `type` to be a Twirp response, found: #{type}"
11
- end
12
-
13
- @fail_msg = "Expected a Twirp::ClientResp, found #{actual}"
14
- return false unless actual.is_a?(Twirp::ClientResp)
15
-
16
- # match expected response type
17
- @fail_msg = "Expected a Twirp::ClientResp of type #{type}, found #{actual.data&.class}"
18
- return false if type && actual.data&.class != type
19
-
20
- if @with_error
21
- unless attrs.empty?
22
- raise ArgumentError, "match data attributes or error, but not both"
23
- end
24
-
25
- @fail_msg = "Expected #{actual} to have an error"
26
- return false unless actual.error
27
-
28
- matchers, meta_matchers = @with_error
29
- expect(actual.error).to be_a_twirp_error(*matchers, **meta_matchers)
30
- else
31
- @fail_msg = "Expected #{actual} to have data"
32
- return false unless actual.data
33
-
34
- expect(actual.data).to be_a_twirp_response(**attrs)
35
- end
36
- rescue RSpec::Expectations::ExpectationNotMetError => err
37
- @fail_msg = err.message
38
- false
39
- end
40
-
41
- description do
42
- type ? "a #{type} Twirp response" : "a Twirp response"
43
- end
44
-
45
- failure_message { @fail_msg }
46
- end
47
-
48
- RSpec::Matchers.alias_matcher :a_twirp_client_response, :be_a_twirp_client_response