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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bc8bcb870839377b9462083dd9bfba0799140c9c
4
- data.tar.gz: e273d0e31fb034dd00d63805c81595352c69f011
3
+ metadata.gz: a287464e10ba8e1c1fe77848e417c197ab79ebfb
4
+ data.tar.gz: d4131657599c3008bc8ac4c8f7b3ebafc382b5c7
5
5
  SHA512:
6
- metadata.gz: 51b729c8b9e0d87e4a85845dc4e7df93afa0264858703ad62bd946b96a307d7a739a10a5bc1f1fdcde7de915c58ce5cf32b745cc0b6d559fe2ed919c9e0c03b1
7
- data.tar.gz: c6085701a5c4ffdb6cc5156429acf6f7b39d6708430c5acc6cd7165c1a845011ec83cdef167b4548837fd2a8299c6bad94b159b79447033b6819010064df1b7c
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"
@@ -1,5 +1,7 @@
1
1
  class GCR::Cassette
2
- attr_reader :data
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
- @data = {}
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
- @data = JSON.parse(File.read(@path))
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(data))
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
- key = GCR.serialize_request(*args)
73
- GCR.cassette.data[key] ||= GCR.serialize_response(resp)
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
- key = GCR.serialize_request(*args)
94
- if resp = GCR.cassette.data[key]
95
- GCR.deserialize_response(resp)
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
@@ -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
@@ -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.5
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-06 00:00:00.000000000 Z
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.4.5.1
131
+ rubygems_version: 2.6.14
116
132
  signing_key:
117
133
  specification_version: 4
118
134
  summary: GRPC test helpers