webmock-twirp 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 165be6973cc98a0dcfb538746766610afa45c02a344bf3c79f0567c36ab92d4c
4
- data.tar.gz: 65a3021683eff819b8a5e1ca6e54d8d4eed63ed9364fd2631cb5308772243ade
3
+ metadata.gz: 961de376102cbbb75708a544bb34e42c065beab4ad92ef4e4441036d47569d1d
4
+ data.tar.gz: 0de10400686561ba24d597d06ea23c4b77ca3445af78c7f7a98997e1bd32d86c
5
5
  SHA512:
6
- metadata.gz: e5c02e2bfbe249a15af9aa36b1701e894550a330a72da318bec451a142e2d053ce40bc7c112e43057f1f216c8a0429dc3a670b8c112d136cd167ab482dbc9585
7
- data.tar.gz: 6e1839bcd0cf51cb664cdda48408e8bcb89aec4dfbe60ba142cdd33f19b3462257ed56b5096fd9f338996257ec76b5121a2a8028f9e2ae848d2b1e79efd2d433
6
+ metadata.gz: e1edcd51eff12eb65d75dd96713ff202410447cdd9ef3ddfbf1fff7c090cc94d370ec381a6bf4966b7e1cd0034c59552f1ed1953e498f7b24b06df4bf1beaad9
7
+ data.tar.gz: b6a646485bc5d8a49f27229cddfc55d3045fb000a0d0186ed03216dbd8436331186d058dcd4257ca15ee5d6ebd757026d7fb5a9fb4be69f4c1d512e4efd0286e
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ ### v0.1.0 (2022-10-09)
2
+ - dynamic client/rpc lookup
3
+
1
4
  ### v0.0.1 (2022-10-07)
2
5
  - stub_twirp_request
3
6
 
data/README.md CHANGED
@@ -4,25 +4,35 @@ Twirp support for [WebMock](https://github.com/bblimke/webmock). All our favori
4
4
 
5
5
 
6
6
  ```ruby
7
- require "webmock-twirp"
7
+ require "webmock/twirp"
8
8
 
9
- stub_twirp_request(MyTwirpClient, :optional_rpc_method)
9
+ it "stubs twirp calls" do
10
+ stub_twirp_request
11
+
12
+ client.my_rpc_method(request)
13
+ end
14
+
15
+ it "matches calls from specific twirp clients and rpc methods" do
16
+ stub_twirp_request(MyTwirpClient, :optional_rpc_method)
17
+ end
10
18
 
11
- stub_twirp_request(...).with(my_request_message: /^foo/)
19
+ # match parameters
20
+ stub_twirp_request.with(my_request_message: /^foo/)
12
21
 
13
22
  # or use block mode
14
- stub_twirp_request(...).with do |request|
23
+ stub_twirp_request.with do |request|
15
24
  request # the Twirp request, aka. proto message, used to initiate the request
16
25
  request.my_request_message == "hello"
17
26
  end
18
27
 
19
28
 
20
- stub_twirp_request(...).and_return(return_message: "yo yo")
21
- stub_twirp_request(...).and_return(404) # results in a Twirp::Error.not_found
29
+ # stub responses
30
+ stub_twirp_request.and_return(return_message: "yo yo")
31
+ stub_twirp_request.and_return(404) # results in a Twirp::Error.not_found
22
32
 
23
33
  # or use block mode
24
- stub_twirp_request(...).and_return do |request|
25
- { response_message: "oh hi" } # will get properly packaged up automagically
34
+ stub_twirp_request.and_return do |request|
35
+ { response_message: "oh hi" } # will get properly packaged up
26
36
  end
27
37
  ```
28
38
 
@@ -0,0 +1,11 @@
1
+ module WebMock
2
+ module Twirp
3
+ module Refinements
4
+ refine Array do
5
+ def snag(&block)
6
+ find(&block)&.tap { |x| delete(x) }
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,29 +1,59 @@
1
1
  module WebMock
2
2
  module Twirp
3
3
  class RequestStub < WebMock::RequestStub
4
- def initialize(client_or_service, rpc_name = nil)
5
- klass = client_or_service.is_a?(Class) ? client_or_service : client_or_service.class
4
+ using Refinements
6
5
 
7
- unless klass < ::Twirp::Client || klass < ::Twirp::Service
8
- raise TypeError, "expected Twirp Client or Service, found: #{client_or_service}"
6
+ def initialize(*filters)
7
+ rpc_name = filters.snag { |x| x.is_a?(Symbol) }
8
+
9
+ client = filters.snag { |x| x.is_a?(::Twirp::Client) }
10
+
11
+ klass = client&.class
12
+ klass ||= filters.snag do |x|
13
+ x.is_a?(Class) && (x < ::Twirp::Client || x < ::Twirp::Service)
14
+ end
15
+
16
+ unless filters.empty?
17
+ raise ArgumentError, "unexpected arguments: #{filters}"
9
18
  end
10
19
 
11
- @rpcs = klass.rpcs
12
- uri = "/#{klass.service_full_name}"
20
+ uri = ""
21
+
22
+ if client
23
+ conn = client.instance_variable_get(:@conn)
24
+ uri += conn.url_prefix.to_s if conn
25
+ end
26
+
27
+ if klass
28
+ @rpcs = klass.rpcs
29
+ uri += "/#{klass.service_full_name}"
30
+ else
31
+ uri += "/[^/]+"
32
+ end
13
33
 
14
34
  if rpc_name
15
- rpc_info = rpcs.values.find do |x|
16
- x[:rpc_method] == rpc_name.to_sym || x[:ruby_method] == rpc_name.to_sym
17
- end
35
+ if klass
36
+ # kindly convert ruby method to rpc method name
37
+ rpc_info = klass.rpcs.values.find do |x|
38
+ x[:rpc_method] == rpc_name || x[:ruby_method] == rpc_name
39
+ end
18
40
 
19
- raise ArgumentError, "invalid rpc method: #{rpc_name}" unless rpc_info
41
+ raise ArgumentError, "invalid rpc method: #{rpc_name}" unless rpc_info
20
42
 
21
- uri += "/#{rpc_info[:rpc_method]}"
43
+ uri += "/#{rpc_info[:rpc_method]}"
44
+ else
45
+ uri += "/#{rpc_name}"
46
+ end
22
47
  else
23
48
  uri += "/[^/]+"
24
49
  end
25
50
 
26
51
  super(:post, /#{uri}$/)
52
+
53
+ # filter on Twirp header
54
+ @request_pattern.with(
55
+ headers: { "Content-Type" => ::Twirp::Encoding::PROTO },
56
+ )
27
57
  end
28
58
 
29
59
  def with(request = nil, **attrs, &block)
@@ -94,10 +124,24 @@ module WebMock
94
124
 
95
125
  private
96
126
 
97
- attr_reader :rpcs
98
-
99
127
  def rpc_from_request(request_signature)
100
- rpcs[request_signature.uri.path.split("/").last]
128
+ service_full_name, rpc_name = request_signature.uri.path.split("/").last(2)
129
+
130
+ rpcs = @rpcs || begin
131
+ # find matching client instance
132
+ client = ObjectSpace.each_object(::Twirp::Client).find do |client|
133
+ service_full_name == client.class.service_full_name && \
134
+ client.class.rpcs.key?(rpc_name)
135
+ end
136
+
137
+ unless client
138
+ raise "could not determine Twirp::Client for call to: #{service_full_name}/#{rpc_name}"
139
+ end
140
+
141
+ client.class.rpcs
142
+ end
143
+
144
+ rpcs[rpc_name]
101
145
  end
102
146
 
103
147
  def generate_http_response(msg_class, obj)
@@ -1,5 +1,5 @@
1
1
  module WebMock
2
2
  module Twirp
3
- VERSION = "0.0.1"
3
+ VERSION = "0.1.0"
4
4
  end
5
5
  end
data/lib/webmock/twirp.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require "google/protobuf"
2
2
  require "twirp"
3
3
  require "webmock"
4
+ require "webmock/twirp/refinements"
4
5
  require "webmock/twirp/request_stub"
5
6
  require "webmock/twirp/version"
6
7
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: webmock-twirp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.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-10-08 00:00:00.000000000 Z
11
+ date: 2022-10-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: webmock
@@ -105,6 +105,7 @@ files:
105
105
  - README.md
106
106
  - lib/webmock-twirp.rb
107
107
  - lib/webmock/twirp.rb
108
+ - lib/webmock/twirp/refinements.rb
108
109
  - lib/webmock/twirp/request_stub.rb
109
110
  - lib/webmock/twirp/version.rb
110
111
  - webmock-twirp.gemspec