grpc_mock 0.4.1 → 0.4.5

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: 128da2bce960f7416a796a0b96bd0866a79bf30decc85e064d5c951b2f93a939
4
- data.tar.gz: 7086f3897090c64f0d97aaa0cfbda4138787921929be89495f820dbeb866e533
3
+ metadata.gz: b2061779fc0f48faecd97933713277ba734d97c7d1581b0aee12899f54c1ec0c
4
+ data.tar.gz: 78ef2ecb1199bb9e0dedddcfb2aa32ac6d3af6afedd8055396600174d008e17a
5
5
  SHA512:
6
- metadata.gz: 23511c5cacc91af0c26eafceee5f0a986605cb44feccf169608a35ff8f353a6f0933bc8ea0af22fbb9f04f190b5791ce6b76825040cb49e9655815bdb0f7b1a1
7
- data.tar.gz: b069f76b458a0d95c7006a9f079e2c6bcd7c600ef563355716aa15f9208f79e3262a49a3efea6e7bc09169e5e2a8d60945f6bd772683896f44323bf3fbe7f5f4
6
+ metadata.gz: d50395ad65d30b8284628ed6a26d1234c99767a4bc8bee47452ae8c018a6e43aadcbf08cc9a04d130c92f3c5c749be53260c823b1238ae2977aca0f135869f8c
7
+ data.tar.gz: 6d93f5de445f48b68128b4c0d4f01f287289fb2f63e882de12e2446500c7fe00682a6af858033e0aa3e531173b1dccae8b59527d2357a8950c8b5eba99ec0cfb
@@ -0,0 +1,25 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - master
7
+ pull_request: {}
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ ruby-version:
15
+ - '2.5'
16
+ - '2.6'
17
+ - '2.7'
18
+ steps:
19
+ - uses: actions/checkout@v2
20
+ - uses: ruby/setup-ruby@v1
21
+ with:
22
+ ruby-version: ${{ matrix.ruby-version }}
23
+ bundler-cache: true
24
+
25
+ - run: 'bundle exec rake'
data/README.md CHANGED
@@ -28,7 +28,7 @@ require 'grpc_mock/rspec'
28
28
 
29
29
  ## Examples
30
30
 
31
- See definition of protocol buffers and gRPC generated code in [spec/exmaples/hello](https://github.com/ganmacs/grpc_mock/tree/master/spec/examples/hello)
31
+ See definition of protocol buffers and gRPC generated code in [spec/examples/hello](https://github.com/ganmacs/grpc_mock/tree/master/spec/examples/hello)
32
32
 
33
33
  ### Stubbed request based on path and with the default response
34
34
 
@@ -52,7 +52,7 @@ client client.hello(Hello::HelloRequest.new(msg: 'hi')) # => Hello::HelloResp
52
52
  ### Responding dynamically to the stubbed requests
53
53
 
54
54
  ```ruby
55
- GrpcMock.stub_request("/hello.hello/Hello").to_return do |req|
55
+ GrpcMock.stub_request("/hello.hello/Hello").to_return do |req, call|
56
56
  Hello::HelloResponse.new(msg: "#{req.msg} too")
57
57
  end
58
58
 
@@ -2,20 +2,30 @@
2
2
 
3
3
  require 'grpc'
4
4
  require 'grpc_mock/errors'
5
+ require 'grpc_mock/mocked_call'
5
6
 
6
7
  module GrpcMock
7
8
  class GrpcStubAdapter
8
9
  # To make hook point for GRPC::ClientStub
9
10
  # https://github.com/grpc/grpc/blob/bec3b5ada2c5e5d782dff0b7b5018df646b65cb0/src/ruby/lib/grpc/generic/service.rb#L150-L186
10
- class AdapterClass < GRPC::ClientStub
11
- def request_response(method, request, *args)
11
+ module Adapter
12
+ def request_response(method, request, *args, metadata: {}, return_op: false, **kwargs)
12
13
  unless GrpcMock::GrpcStubAdapter.enabled?
13
14
  return super
14
15
  end
15
16
 
16
17
  mock = GrpcMock.stub_registry.response_for_request(method, request)
17
18
  if mock
18
- mock.evaluate(request)
19
+ call = GrpcMock::MockedCall.new(metadata: metadata)
20
+ if return_op
21
+ operation = call.operation
22
+ operation.define_singleton_method(:execute) do
23
+ mock.evaluate(request, call.single_req_view)
24
+ end
25
+ operation
26
+ else
27
+ mock.evaluate(request, call.single_req_view)
28
+ end
19
29
  elsif GrpcMock.config.allow_net_connect
20
30
  super
21
31
  else
@@ -24,7 +34,7 @@ module GrpcMock
24
34
  end
25
35
 
26
36
  # TODO
27
- def client_streamer(method, requests, *args)
37
+ def client_streamer(method, requests, *args, metadata: {}, return_op: false, **kwargs)
28
38
  unless GrpcMock::GrpcStubAdapter.enabled?
29
39
  return super
30
40
  end
@@ -32,7 +42,16 @@ module GrpcMock
32
42
  r = requests.to_a # FIXME: this may not work
33
43
  mock = GrpcMock.stub_registry.response_for_request(method, r)
34
44
  if mock
35
- mock.evaluate(r)
45
+ call = GrpcMock::MockedCall.new(metadata: metadata)
46
+ if return_op
47
+ operation = call.operation
48
+ operation.define_singleton_method(:execute) do
49
+ mock.evaluate(r, call.multi_req_view)
50
+ end
51
+ operation
52
+ else
53
+ mock.evaluate(r, call.multi_req_view)
54
+ end
36
55
  elsif GrpcMock.config.allow_net_connect
37
56
  super
38
57
  else
@@ -40,14 +59,22 @@ module GrpcMock
40
59
  end
41
60
  end
42
61
 
43
- def server_streamer(method, request, *args)
62
+ def server_streamer(method, request, *args, metadata: {}, return_op: false, **kwargs)
44
63
  unless GrpcMock::GrpcStubAdapter.enabled?
45
64
  return super
46
65
  end
47
66
 
48
67
  mock = GrpcMock.stub_registry.response_for_request(method, request)
49
68
  if mock
50
- mock.evaluate(request)
69
+ if return_op
70
+ operation = call.operation
71
+ operation.define_singleton_method(:execute) do
72
+ mock.evaluate(request, call.single_req_view)
73
+ end
74
+ operation
75
+ else
76
+ mock.evaluate(request, call.single_req_view)
77
+ end
51
78
  elsif GrpcMock.config.allow_net_connect
52
79
  super
53
80
  else
@@ -55,7 +82,7 @@ module GrpcMock
55
82
  end
56
83
  end
57
84
 
58
- def bidi_streamer(method, requests, *args)
85
+ def bidi_streamer(method, requests, *args, metadata: {}, return_op: false, **kwargs)
59
86
  unless GrpcMock::GrpcStubAdapter.enabled?
60
87
  return super
61
88
  end
@@ -63,7 +90,15 @@ module GrpcMock
63
90
  r = requests.to_a # FIXME: this may not work
64
91
  mock = GrpcMock.stub_registry.response_for_request(method, r)
65
92
  if mock
66
- mock.evaluate(r)
93
+ if return_op
94
+ operation = call.operation
95
+ operation.define_singleton_method(:execute) do
96
+ mock.evaluate(r, nil) # FIXME: provide BidiCall equivalent
97
+ end
98
+ operation
99
+ else
100
+ mock.evaluate(r, nil) # FIXME: provide BidiCall equivalent
101
+ end
67
102
  elsif GrpcMock.config.allow_net_connect
68
103
  super
69
104
  else
@@ -71,8 +106,6 @@ module GrpcMock
71
106
  end
72
107
  end
73
108
  end
74
- GRPC.send(:remove_const, :ClientStub)
75
- GRPC.send(:const_set, :ClientStub, AdapterClass)
76
109
 
77
110
  def self.disable!
78
111
  @enabled = false
@@ -95,3 +128,9 @@ module GrpcMock
95
128
  end
96
129
  end
97
130
  end
131
+
132
+ module GRPC
133
+ class ClientStub
134
+ prepend GrpcMock::GrpcStubAdapter::Adapter
135
+ end
136
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'grpc'
4
+ require 'grpc_mock/mocked_operation'
5
+
6
+ module GrpcMock
7
+ class MockedCall
8
+ attr_reader :deadline, :metadata
9
+
10
+ def initialize(metadata: {}, deadline: nil)
11
+ @metadata = sanitize_metadata(metadata)
12
+ @deadline = deadline
13
+ end
14
+
15
+ def multi_req_view
16
+ GRPC::ActiveCall::MultiReqView.new(self)
17
+ end
18
+
19
+ def single_req_view
20
+ GRPC::ActiveCall::SingleReqView.new(self)
21
+ end
22
+
23
+ def operation
24
+ GrpcMock::MockedOperation.new(self, metadata, deadline)
25
+ end
26
+
27
+ private
28
+
29
+ def sanitize_metadata(metadata)
30
+ # Largely based on
31
+ # - grpc_rb_md_ary_fill_hash_cb https://github.com/grpc/grpc/blob/v1.29.1/src/ruby/ext/grpc/rb_call.c#L390-L465
32
+ # - grpc_rb_md_ary_convert https://github.com/grpc/grpc/blob/v1.29.1/src/ruby/ext/grpc/rb_call.c#L490-L511
33
+ # - grpc_rb_md_ary_to_h https://github.com/grpc/grpc/blob/v1.29.1/src/ruby/ext/grpc/rb_call.c#L513-L541
34
+ # See also https://github.com/grpc/grpc/blob/v1.29.1/doc/PROTOCOL-HTTP2.md for specification
35
+
36
+ raise TypeError, "got <#{metadata.class}>, want <Hash>" unless metadata.is_a?(Hash)
37
+
38
+ headers = []
39
+ metadata.each do |key, value|
40
+ raise TypeError, "bad type for key parameter" unless key.is_a?(String) || key.is_a?(Symbol)
41
+
42
+ key = key.to_s
43
+ # https://github.com/grpc/grpc/blob/v1.29.1/src/core/lib/surface/validate_metadata.cc#L61-L79
44
+ raise ArgumentError, "'#{key}' is an invalid header key" unless key.match?(/\A[a-z0-9\-_.]+\z/) && key != ''
45
+ raise ArgumentError, "Header values must be of type string or array" unless value.is_a?(String) || value.is_a?(Array)
46
+
47
+ Array(value).each do |elem|
48
+ raise TypeError, "Header value must be of type string" unless elem.is_a?(String)
49
+
50
+ unless key.end_with?('-bin')
51
+ # Non-binary metadata are translated as plain HTTP2 headers, thus this requirement.
52
+ # https://github.com/grpc/grpc/blob/v1.29.1/src/core/lib/surface/validate_metadata.cc#L85-L92
53
+ raise ArgumentError, "Header value '#{elem}' has invalid characters" unless elem.match(/\A[ -~]+\z/)
54
+
55
+ # "ASCII-Value should not have leading or trailing whitespace. If it contains leading or trailing whitespace, it may be stripped."
56
+ # https://github.com/grpc/grpc/blob/v1.29.1/doc/PROTOCOL-HTTP2.md
57
+ elem = elem.strip
58
+ end
59
+ headers << [key, elem]
60
+ end
61
+ end
62
+
63
+ metadata = {}
64
+ headers.each do |key, elem|
65
+ if metadata[key].nil?
66
+ metadata[key] = elem
67
+ elsif metadata[key].is_a?(Array)
68
+ metadata[key] << elem
69
+ else
70
+ metadata[key] = [metadata[key], elem]
71
+ end
72
+ end
73
+
74
+ metadata
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GrpcMock
4
+ MockedOperation = Struct.new(:call, :metadata, :deadline)
5
+ end
@@ -16,7 +16,7 @@ module GrpcMock
16
16
  end
17
17
  end
18
18
 
19
- def evaluate(_request = nil)
19
+ def evaluate(_request = nil, _call = nil)
20
20
  raise @exception.dup
21
21
  end
22
22
  end
@@ -26,7 +26,7 @@ module GrpcMock
26
26
  @value = value
27
27
  end
28
28
 
29
- def evaluate(_request = nil)
29
+ def evaluate(_request = nil, _call = nil)
30
30
  @value.dup
31
31
  end
32
32
  end
@@ -36,8 +36,8 @@ module GrpcMock
36
36
  @block = block
37
37
  end
38
38
 
39
- def evaluate(request)
40
- @block.call(request)
39
+ def evaluate(request, call = nil)
40
+ @block.call(request, call)
41
41
  end
42
42
  end
43
43
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GrpcMock
4
- VERSION = '0.4.1'
4
+ VERSION = '0.4.5'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grpc_mock
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.4.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yuta Iwama
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-06-10 00:00:00.000000000 Z
11
+ date: 2021-11-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: grpc
@@ -121,10 +121,10 @@ executables: []
121
121
  extensions: []
122
122
  extra_rdoc_files: []
123
123
  files:
124
+ - ".github/workflows/ci.yml"
124
125
  - ".gitignore"
125
126
  - ".rspec"
126
127
  - ".rubocop.yml"
127
- - ".travis.yml"
128
128
  - Gemfile
129
129
  - LICENSE.txt
130
130
  - README.md
@@ -140,6 +140,8 @@ files:
140
140
  - lib/grpc_mock/grpc_stub_adapter.rb
141
141
  - lib/grpc_mock/matchers/hash_argument_matcher.rb
142
142
  - lib/grpc_mock/matchers/request_including_matcher.rb
143
+ - lib/grpc_mock/mocked_call.rb
144
+ - lib/grpc_mock/mocked_operation.rb
143
145
  - lib/grpc_mock/request_pattern.rb
144
146
  - lib/grpc_mock/request_stub.rb
145
147
  - lib/grpc_mock/response.rb
@@ -151,7 +153,7 @@ homepage: https://github.com/ganmacs/grpc_mock
151
153
  licenses:
152
154
  - MIT
153
155
  metadata: {}
154
- post_install_message:
156
+ post_install_message:
155
157
  rdoc_options: []
156
158
  require_paths:
157
159
  - lib
@@ -167,7 +169,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
167
169
  version: '0'
168
170
  requirements: []
169
171
  rubygems_version: 3.0.3
170
- signing_key:
172
+ signing_key:
171
173
  specification_version: 4
172
174
  summary: Library for stubbing grpc in Ruby
173
175
  test_files: []
data/.travis.yml DELETED
@@ -1,7 +0,0 @@
1
- sudo: false
2
- language: ruby
3
- rvm:
4
- - 2.6.3
5
- - 2.5.3
6
- - 2.4.5
7
- before_install: gem install bundler -v 1.16.1