gcr 0.0.5 → 1.0.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/lib/gcr.rb +20 -22
- data/lib/gcr/cassette.rb +33 -11
- data/lib/gcr/request.rb +47 -0
- data/lib/gcr/response.rb +34 -0
- metadata +19 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a287464e10ba8e1c1fe77848e417c197ab79ebfb
|
4
|
+
data.tar.gz: d4131657599c3008bc8ac4c8f7b3ebafc382b5c7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 207d6bb496e0a10a095763fb454ddef54002c1121fb4699b629161971b638f31e7f5128d81964bb6cb5bbee2c356c48fa6f2fdd7da734b70e795c36abd613e8d
|
7
|
+
data.tar.gz: '09403d61c03c953b111f0429a5f0a380c4948637cdf0ef06fce73f24c5e6b6c6a403e5af89fca34b284551eadc4345289a12f1381c438f1e76a03099f8525c35'
|
data/lib/gcr.rb
CHANGED
@@ -1,9 +1,27 @@
|
|
1
|
+
require "json"
|
2
|
+
|
1
3
|
module GCR
|
2
4
|
Error = Class.new(StandardError)
|
3
5
|
ConfigError = Class.new(Error)
|
4
6
|
RunningError = Class.new(Error)
|
5
7
|
NoRecording = Class.new(Error)
|
6
8
|
|
9
|
+
# Ignore these fields when matching requests.
|
10
|
+
#
|
11
|
+
# *fields - String field names (eg. "token").
|
12
|
+
#
|
13
|
+
# Returns nothing.
|
14
|
+
def ignore(*fields)
|
15
|
+
ignored_fields.concat(fields.map(&:to_s))
|
16
|
+
end
|
17
|
+
|
18
|
+
# Fields that are ignored when matching requests.
|
19
|
+
#
|
20
|
+
# Returns an Array of Strings.
|
21
|
+
def ignored_fields
|
22
|
+
@ignored_fields ||= []
|
23
|
+
end
|
24
|
+
|
7
25
|
# Specify where GCR should store cassettes.
|
8
26
|
#
|
9
27
|
# path - The String path to a directory.
|
@@ -75,29 +93,9 @@ module GCR
|
|
75
93
|
@cassette = nil
|
76
94
|
end
|
77
95
|
|
78
|
-
def serialize_request(route, req, marshal, unmarshal, metadata)
|
79
|
-
JSON.dump(
|
80
|
-
"route" => route,
|
81
|
-
"req" => Base64.strict_encode64(req.to_proto)
|
82
|
-
)
|
83
|
-
end
|
84
|
-
|
85
|
-
def serialize_response(resp)
|
86
|
-
JSON.dump(
|
87
|
-
"type" => resp.class.descriptor.name,
|
88
|
-
"buf" => Base64.strict_encode64(resp.to_proto)
|
89
|
-
)
|
90
|
-
end
|
91
|
-
|
92
|
-
def deserialize_response(str)
|
93
|
-
hsh = JSON.parse(str)
|
94
|
-
klass = Google::Protobuf::DescriptorPool.generated_pool.lookup(hsh["type"]).msgclass
|
95
|
-
klass.decode(Base64.strict_decode64(hsh["buf"]))
|
96
|
-
end
|
97
|
-
|
98
96
|
extend self
|
99
97
|
end
|
100
98
|
|
101
|
-
require "json"
|
102
|
-
require "base64"
|
103
99
|
require "gcr/cassette"
|
100
|
+
require "gcr/request"
|
101
|
+
require "gcr/response"
|
data/lib/gcr/cassette.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
class GCR::Cassette
|
2
|
-
|
2
|
+
VERSION = 2
|
3
|
+
|
4
|
+
attr_reader :reqs
|
3
5
|
|
4
6
|
# Delete all recorded cassettes.
|
5
7
|
#
|
@@ -17,7 +19,7 @@ class GCR::Cassette
|
|
17
19
|
# Returns nothing.
|
18
20
|
def initialize(name)
|
19
21
|
@path = File.join(GCR.cassette_dir, "#{name}.json")
|
20
|
-
@
|
22
|
+
@reqs = []
|
21
23
|
end
|
22
24
|
|
23
25
|
# Does this cassette exist?
|
@@ -31,7 +33,15 @@ class GCR::Cassette
|
|
31
33
|
#
|
32
34
|
# Returns nothing.
|
33
35
|
def load
|
34
|
-
|
36
|
+
data = JSON.parse(File.read(@path))
|
37
|
+
|
38
|
+
if data["version"] != VERSION
|
39
|
+
raise "GCR cassette version #{data["version"]} not supported"
|
40
|
+
end
|
41
|
+
|
42
|
+
@reqs = data["reqs"].map do |req, resp|
|
43
|
+
[GCR::Request.from_hash(req), GCR::Response.from_hash(resp)]
|
44
|
+
end
|
35
45
|
end
|
36
46
|
|
37
47
|
# Persist this cassette.
|
@@ -39,7 +49,10 @@ class GCR::Cassette
|
|
39
49
|
# Returns nothing.
|
40
50
|
def save
|
41
51
|
File.open(@path, "w") do |f|
|
42
|
-
f.write(JSON.pretty_generate(
|
52
|
+
f.write(JSON.pretty_generate(
|
53
|
+
"version" => VERSION,
|
54
|
+
"reqs" => reqs,
|
55
|
+
))
|
43
56
|
end
|
44
57
|
end
|
45
58
|
|
@@ -69,8 +82,10 @@ class GCR::Cassette
|
|
69
82
|
|
70
83
|
def request_response(*args)
|
71
84
|
orig_request_response(*args).tap do |resp|
|
72
|
-
|
73
|
-
GCR.cassette.
|
85
|
+
req = GCR::Request.from_proto(*args)
|
86
|
+
if GCR.cassette.reqs.none? { |r, _| r == req }
|
87
|
+
GCR.cassette.reqs << [req, GCR::Response.from_proto(resp)]
|
88
|
+
end
|
74
89
|
end
|
75
90
|
end
|
76
91
|
end
|
@@ -90,12 +105,11 @@ class GCR::Cassette
|
|
90
105
|
alias_method :orig_request_response, :request_response
|
91
106
|
|
92
107
|
def request_response(*args)
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
else
|
97
|
-
raise GCR::NoRecording
|
108
|
+
req = GCR::Request.from_proto(*args)
|
109
|
+
GCR.cassette.reqs.each do |other_req, resp|
|
110
|
+
return resp.to_proto if req == other_req
|
98
111
|
end
|
112
|
+
raise GCR::NoRecording
|
99
113
|
end
|
100
114
|
end
|
101
115
|
end
|
@@ -105,4 +119,12 @@ class GCR::Cassette
|
|
105
119
|
alias_method :request_response, :orig_request_response
|
106
120
|
end
|
107
121
|
end
|
122
|
+
|
123
|
+
def [](req)
|
124
|
+
reqs.find { |r| r == req }
|
125
|
+
end
|
126
|
+
|
127
|
+
def []=(req, resp)
|
128
|
+
reqs << [req, resp]
|
129
|
+
end
|
108
130
|
end
|
data/lib/gcr/request.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
class GCR::Request
|
2
|
+
def self.from_proto(route, proto_req, *_)
|
3
|
+
new(
|
4
|
+
"route" => route,
|
5
|
+
"class_name" => proto_req.class.name,
|
6
|
+
"body" => proto_req.to_json,
|
7
|
+
)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.from_hash(hash_req)
|
11
|
+
new(
|
12
|
+
"route" => hash_req["route"],
|
13
|
+
"class_name" => hash_req["class_name"],
|
14
|
+
"body" => hash_req["body"],
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_reader :route, :class_name, :body
|
19
|
+
|
20
|
+
def initialize(opts)
|
21
|
+
@route = opts["route"]
|
22
|
+
@class_name = opts["class_name"]
|
23
|
+
@body = opts["body"]
|
24
|
+
end
|
25
|
+
|
26
|
+
def parsed_body
|
27
|
+
@parsed_body ||= JSON.parse(body)
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_json(*_)
|
31
|
+
JSON.dump("route" => route, "class_name" => class_name, "body" => body)
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_proto
|
35
|
+
[route, Object.const_get(class_name).decode_json(body)]
|
36
|
+
end
|
37
|
+
|
38
|
+
def ==(other)
|
39
|
+
return false unless route == other.route
|
40
|
+
return false unless class_name == other.class_name
|
41
|
+
|
42
|
+
parsed_body.keys.all? do |k|
|
43
|
+
next true if GCR.ignored_fields.include?(k)
|
44
|
+
parsed_body[k] == other.parsed_body[k]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/gcr/response.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
class GCR::Response
|
2
|
+
def self.from_proto(proto_resp)
|
3
|
+
new(
|
4
|
+
"class_name" => proto_resp.class.name,
|
5
|
+
"body" => proto_resp.to_json,
|
6
|
+
)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.from_hash(hash_resp)
|
10
|
+
new(
|
11
|
+
"class_name" => hash_resp["class_name"],
|
12
|
+
"body" => hash_resp["body"],
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :class_name, :body
|
17
|
+
|
18
|
+
def initialize(opts)
|
19
|
+
@class_name = opts["class_name"]
|
20
|
+
@body = opts["body"]
|
21
|
+
end
|
22
|
+
|
23
|
+
def parsed_body
|
24
|
+
@parsed_body ||= JSON.decode(body)
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_json(*_)
|
28
|
+
JSON.dump("class_name" => class_name, "body" => body)
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_proto
|
32
|
+
Object.const_get(class_name).decode_json(body)
|
33
|
+
end
|
34
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gcr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- mastahyeti
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-04-
|
11
|
+
date: 2018-04-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: google-protobuf
|
@@ -84,6 +84,20 @@ dependencies:
|
|
84
84
|
- - ">="
|
85
85
|
- !ruby/object:Gem::Version
|
86
86
|
version: '0'
|
87
|
+
- !ruby/object:Gem::Dependency
|
88
|
+
name: pry
|
89
|
+
requirement: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
type: :development
|
95
|
+
prerelease: false
|
96
|
+
version_requirements: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '0'
|
87
101
|
description:
|
88
102
|
email:
|
89
103
|
executables: []
|
@@ -92,6 +106,8 @@ extra_rdoc_files: []
|
|
92
106
|
files:
|
93
107
|
- "./lib/gcr.rb"
|
94
108
|
- "./lib/gcr/cassette.rb"
|
109
|
+
- "./lib/gcr/request.rb"
|
110
|
+
- "./lib/gcr/response.rb"
|
95
111
|
homepage: https://github.com/mastahyeti/gcr
|
96
112
|
licenses:
|
97
113
|
- MIT
|
@@ -112,7 +128,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
112
128
|
version: '0'
|
113
129
|
requirements: []
|
114
130
|
rubyforge_project:
|
115
|
-
rubygems_version: 2.
|
131
|
+
rubygems_version: 2.6.14
|
116
132
|
signing_key:
|
117
133
|
specification_version: 4
|
118
134
|
summary: GRPC test helpers
|