gcr 0.0.5 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|