gcr 0.0.1
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 +7 -0
- data/lib/gcr.rb +85 -0
- data/lib/gcr/cassette.rb +105 -0
- metadata +105 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 654092852f61d95659958cc4b7bdc57863d92474
|
4
|
+
data.tar.gz: 1475ecc16fb24ca8c8b69e63ff5ff63fcfc3cbea
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 14a2b562b9238808de93eea48fbb2ced1cf8a5ba0d52b1c8bdb009f1bcf38179c5387d29a57be9c1ab4efca4efd99e99ed4f60b7c86e3909d681703fce8f5f95
|
7
|
+
data.tar.gz: 8b8a4c32de38ba8dffa4801db17076617e8763080825e4b7e4942531490adbcde99f9a69f4fe99389836ed502969f32d3992ce4883f7d9dd09d02ac2fbc6bdb8
|
data/lib/gcr.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
module GCR
|
2
|
+
Error = Class.new(StandardError)
|
3
|
+
ConfigError = Class.new(Error)
|
4
|
+
RunningError = Class.new(Error)
|
5
|
+
NoRecording = Class.new(Error)
|
6
|
+
|
7
|
+
# Specify where GCR should store cassettes.
|
8
|
+
#
|
9
|
+
# path - The String path to a directory.
|
10
|
+
#
|
11
|
+
# Returns nothing.
|
12
|
+
def cassette_dir=(path)
|
13
|
+
raise RunningError, "cannot configure GCR within #with_cassette block" if @running
|
14
|
+
@cassette_dir = path
|
15
|
+
end
|
16
|
+
|
17
|
+
# Where GCR stores cassettes.
|
18
|
+
#
|
19
|
+
# Returns a String path to a directory. Raises ConfigError if not configured.
|
20
|
+
def cassette_dir
|
21
|
+
@cassette_dir || (raise ConfigError, "no cassette dir configured")
|
22
|
+
end
|
23
|
+
|
24
|
+
# Specify the stub to intercept calls to.
|
25
|
+
#
|
26
|
+
# stub - A GRPC::ClientStub instance.
|
27
|
+
#
|
28
|
+
# Returns nothing.
|
29
|
+
def stub=(stub)
|
30
|
+
raise RunningError, "cannot configure GCR within #with_cassette block" if @running
|
31
|
+
@stub = stub
|
32
|
+
end
|
33
|
+
|
34
|
+
# The stub that is being mocked.
|
35
|
+
#
|
36
|
+
# Returns a A GRPC::ClientStub instance. Raises ConfigError if not configured.
|
37
|
+
def stub
|
38
|
+
@stub || (raise ConfigError, "no cassette dir configured")
|
39
|
+
end
|
40
|
+
|
41
|
+
def cassette
|
42
|
+
@cassette
|
43
|
+
end
|
44
|
+
|
45
|
+
# If a cassette with the given name exists, play that cassette for the
|
46
|
+
# provided block. Otherwise, record a cassette with the provided block.
|
47
|
+
#
|
48
|
+
# Returns nothing.
|
49
|
+
def with_cassette(name, &blk)
|
50
|
+
@cassette = Cassette.new(name)
|
51
|
+
if @cassette.exist?
|
52
|
+
@cassette.play(&blk)
|
53
|
+
else
|
54
|
+
@cassette.record(&blk)
|
55
|
+
end
|
56
|
+
ensure
|
57
|
+
@cassette = nil
|
58
|
+
end
|
59
|
+
|
60
|
+
def serialize_request(route, req, marshal, unmarshal, metadata)
|
61
|
+
JSON.dump(
|
62
|
+
"route" => route,
|
63
|
+
"req" => Base64.strict_encode64(req.to_proto)
|
64
|
+
)
|
65
|
+
end
|
66
|
+
|
67
|
+
def serialize_response(resp)
|
68
|
+
JSON.dump(
|
69
|
+
"type" => resp.class.name,
|
70
|
+
"buf" => Base64.strict_encode64(resp.to_proto)
|
71
|
+
)
|
72
|
+
end
|
73
|
+
|
74
|
+
def deserialize_response(str)
|
75
|
+
hsh = JSON.parse(str)
|
76
|
+
klass = Google::Protobuf::DescriptorPool.generated_pool.lookup(hsh["type"]).msgclass
|
77
|
+
klass.decode(Base64.strict_decode64(hsh["buf"]))
|
78
|
+
end
|
79
|
+
|
80
|
+
extend self
|
81
|
+
end
|
82
|
+
|
83
|
+
require "json"
|
84
|
+
require "base64"
|
85
|
+
require "gcr/cassette"
|
data/lib/gcr/cassette.rb
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
class GCR::Cassette
|
2
|
+
attr_reader :data
|
3
|
+
|
4
|
+
# Delete all recorded cassettes.
|
5
|
+
#
|
6
|
+
# Returns nothing.
|
7
|
+
def self.delete_all
|
8
|
+
Dir[File.join(GCR.cassette_dir, "*.json")].each do |path|
|
9
|
+
File.unlink(path)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# Initialize a new cassette.
|
14
|
+
#
|
15
|
+
# name - The String name of the recording, from which the path is derived.
|
16
|
+
#
|
17
|
+
# Returns nothing.
|
18
|
+
def initialize(name)
|
19
|
+
@path = File.join(GCR.cassette_dir, "#{name}.json")
|
20
|
+
@data = {}
|
21
|
+
end
|
22
|
+
|
23
|
+
# Does this cassette exist?
|
24
|
+
#
|
25
|
+
# Returns boolean.
|
26
|
+
def exist?
|
27
|
+
File.exist?(@path)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Load this cassette.
|
31
|
+
#
|
32
|
+
# Returns nothing.
|
33
|
+
def load
|
34
|
+
@data = JSON.parse(File.read(@path))
|
35
|
+
end
|
36
|
+
|
37
|
+
# Persist this cassette.
|
38
|
+
#
|
39
|
+
# Returns nothing.
|
40
|
+
def save
|
41
|
+
File.open(@path, "w") do |f|
|
42
|
+
f.write(JSON.pretty_generate(data))
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Record all GRPC calls made while calling the provided block.
|
47
|
+
#
|
48
|
+
# Returns nothing.
|
49
|
+
def record(&blk)
|
50
|
+
install_record_hook
|
51
|
+
blk.call
|
52
|
+
save
|
53
|
+
ensure
|
54
|
+
remove_hook
|
55
|
+
end
|
56
|
+
|
57
|
+
# Play recorded GRPC responses.
|
58
|
+
#
|
59
|
+
# Returns nothing.
|
60
|
+
def play(&blk)
|
61
|
+
load
|
62
|
+
install_play_hook
|
63
|
+
blk.call
|
64
|
+
ensure
|
65
|
+
remove_hook
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def install_record_hook
|
71
|
+
GCR.stub.class.class_eval do
|
72
|
+
alias_method :orig_request_response, :request_response
|
73
|
+
|
74
|
+
def request_response(*args)
|
75
|
+
orig_request_response(*args).tap do |resp|
|
76
|
+
key = GCR.serialize_request(*args)
|
77
|
+
GCR.cassette.data[key] ||= []
|
78
|
+
GCR.cassette.data[key] << GCR.serialize_response(resp)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def install_play_hook
|
85
|
+
GCR.stub.class.class_eval do
|
86
|
+
alias_method :orig_request_response, :request_response
|
87
|
+
|
88
|
+
def request_response(*args)
|
89
|
+
key = GCR.serialize_request(*args)
|
90
|
+
GCR.cassette.data[key] ||= []
|
91
|
+
if resp = GCR.cassette.data[key].shift
|
92
|
+
GCR.deserialize_response(resp)
|
93
|
+
else
|
94
|
+
raise GCR::NoRecording
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def remove_hook
|
101
|
+
GCR.stub.class.class_eval do
|
102
|
+
alias_method :request_response, :orig_request_response
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
metadata
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gcr
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- mastahyeti
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-05-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: google-protobuf
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.3'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 3.3.0
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '3.3'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 3.3.0
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: grpc
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '1.2'
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 1.2.5
|
43
|
+
type: :development
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '1.2'
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 1.2.5
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: rspec
|
55
|
+
requirement: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - "~>"
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '3.5'
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 3.5.0
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '3.5'
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 3.5.0
|
73
|
+
description:
|
74
|
+
email:
|
75
|
+
executables: []
|
76
|
+
extensions: []
|
77
|
+
extra_rdoc_files: []
|
78
|
+
files:
|
79
|
+
- "./lib/gcr.rb"
|
80
|
+
- "./lib/gcr/cassette.rb"
|
81
|
+
homepage: https://github.com/mastahyeti/gcr
|
82
|
+
licenses:
|
83
|
+
- MIT
|
84
|
+
metadata: {}
|
85
|
+
post_install_message:
|
86
|
+
rdoc_options: []
|
87
|
+
require_paths:
|
88
|
+
- lib
|
89
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
requirements: []
|
100
|
+
rubyforge_project:
|
101
|
+
rubygems_version: 2.5.2
|
102
|
+
signing_key:
|
103
|
+
specification_version: 4
|
104
|
+
summary: GRPC test helpers
|
105
|
+
test_files: []
|