reynard 0.2.0 → 0.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 95ca8eb7744c1550bfcf705a92d97331d9c558b08dec5f2369b166b285b38edc
4
- data.tar.gz: a140a0dbe5f74c95f43d2aa785dd3c96a322eab2893b2d8a629abd3b9859724e
3
+ metadata.gz: 7df788fc69d73d417d6b9490299d2552befb4fa4764ebc4621e9d20cd27cab49
4
+ data.tar.gz: 053775ac81400f50ad28436a122fc0316c3b6037afb1fe41b4c1638a80912509
5
5
  SHA512:
6
- metadata.gz: 77148ca6897e1e7b0479348cfe536ff94afc5c1741b6fe59afea7940b442d7c46a71914868f572f3588b7d85d95f38446bd8d28885a22a032c91a86e71e3da28
7
- data.tar.gz: eab59f1738c99af0f2c8fba6a4fb09f15a5a26f31f86de91125d9f299d2d50844060bd3c13db33b260f267a82e269175e0c69d2cdeb4f32d397e99bca74e9694
6
+ metadata.gz: 5d2bee0211247407c99e0d5fd180bca0738230c89024cdddaae96de8eaa3afdf1b41fd2e11d95ef4c8c2210ff8f269ad7b4070959065ac48063f1ba8355056c0
7
+ data.tar.gz: f81ba585b5db0cea43659269ebdffc73ac4e234353f902a663e43203985a576e55874ccf2a6524eba9e029c04bf3174cf53f6ea3a35f44393ed036a37e66adc9
data/README.md CHANGED
@@ -81,6 +81,22 @@ response['Content-Type'] #=> 'application/json'
81
81
  response.body #=> '{"name":"Sam Seven"}'
82
82
  ```
83
83
 
84
+ ## Logging
85
+
86
+ When you want to know what the Reynard client is doing you can enable logging.
87
+
88
+ ```ruby
89
+ logger = Logger.new($stdout)
90
+ logger.level = Logger::INFO
91
+ reynard.logger(logger).execute
92
+ ```
93
+
94
+ The logging should be compatible with the Ruby on Rails logger.
95
+
96
+ ```ruby
97
+ reynard.logger(Rails.logger).execute
98
+ ```
99
+
84
100
  ## Mocking
85
101
 
86
102
  You can mock Reynard requests by changing the HTTP implementation. The class **must** implement a single `request` method that accepts an URI and net/http request object. It **must** return a net/http response object or an object with the exact same interface.
@@ -97,4 +113,4 @@ end
97
113
 
98
114
  ## Copyright and other legal
99
115
 
100
- See LICENCE.
116
+ See LICENCE.
@@ -42,6 +42,10 @@ class Reynard
42
42
  copy(headers: @request_context.headers.merge(headers))
43
43
  end
44
44
 
45
+ def logger(logger)
46
+ copy(logger: logger)
47
+ end
48
+
45
49
  def execute
46
50
  build_response(build_request.perform)
47
51
  end
@@ -15,50 +15,23 @@ class Reynard
15
15
  end
16
16
 
17
17
  def perform
18
+ @request_context.logger&.info { "#{@request_context.verb.upcase} #{uri}" }
18
19
  Reynard.http.request(uri, build_request)
19
20
  end
20
21
 
21
22
  private
22
23
 
23
- def build_request
24
- case @request_context.verb
25
- when 'get'
26
- build_http_get
27
- when 'post'
28
- build_http_post
29
- when 'put'
30
- build_http_put
31
- when 'patch'
32
- build_http_patch
33
- when 'delete'
34
- build_http_delete
35
- end
36
- end
37
-
38
- def build_http_get
39
- Net::HTTP::Get.new(uri, @request_context.headers)
40
- end
41
-
42
- def build_http_post
43
- post = Net::HTTP::Post.new(uri, @request_context.headers)
44
- post.body = @request_context.body
45
- post
24
+ def request_class
25
+ Net::HTTP.const_get(@request_context.verb.capitalize)
46
26
  end
47
27
 
48
- def build_http_put
49
- put = Net::HTTP::Put.new(uri, @request_context.headers)
50
- put.body = @request_context.body
51
- put
52
- end
53
-
54
- def build_http_patch
55
- patch = Net::HTTP::Patch.new(uri, @request_context.headers)
56
- patch.body = @request_context.body
57
- patch
58
- end
59
-
60
- def build_http_delete
61
- Net::HTTP::Delete.new(uri, @request_context.headers)
28
+ def build_request
29
+ request = request_class.new(uri, @request_context.headers)
30
+ if @request_context.body
31
+ @request_context.logger&.debug { @request_context.body }
32
+ request.body = @request_context.body
33
+ end
34
+ request
62
35
  end
63
36
  end
64
37
  end
@@ -46,7 +46,7 @@ class Reynard
46
46
 
47
47
  def build_object_without_media_type
48
48
  # Try to parse the response as JSON and give up otherwise.
49
- OpenStruct.new(MultiJson.load(@http_response.body))
49
+ Reynard::Model.new(MultiJson.load(@http_response.body))
50
50
  rescue StandardError
51
51
  @http_response.body
52
52
  end
@@ -15,7 +15,7 @@ class Reynard
15
15
  if @media_type.schema_name
16
16
  self.class.model_class(@media_type.schema_name, @schema.object_type)
17
17
  else
18
- OpenStruct
18
+ Reynard::Model
19
19
  end
20
20
  end
21
21
 
@@ -23,7 +23,7 @@ class Reynard
23
23
  if @schema.item_schema_name
24
24
  self.class.model_class(@schema.item_schema_name, 'object')
25
25
  else
26
- OpenStruct
26
+ Reynard::Model
27
27
  end
28
28
  end
29
29
 
@@ -3,6 +3,7 @@
3
3
  class Reynard
4
4
  # Value class for details about the request.
5
5
  RequestContext = Struct.new(
6
+ :logger,
6
7
  :base_url,
7
8
  :operation,
8
9
  :headers,
@@ -5,6 +5,8 @@ require 'rack'
5
5
  class Reynard
6
6
  # Wraps the YAML representation of an OpenAPI specification.
7
7
  class Specification
8
+ VERBS = %w[get put post delete options head patch trace].freeze
9
+
8
10
  def initialize(filename:)
9
11
  @filename = filename
10
12
  @data = read
@@ -32,7 +34,15 @@ class Reynard
32
34
  def build_grouped_params(operation_node, params)
33
35
  return {} unless params
34
36
 
35
- GroupedParameters.new(dig(*operation_node, 'parameters'), params).to_h
37
+ GroupedParameters.new(
38
+ [
39
+ # Parameters can be shared between methods on a path or be specific to an operation. The
40
+ # parameters on the operation level override those at the path level.
41
+ dig(*operation_node, 'parameters'),
42
+ dig(*operation_node[..-2], 'parameters')
43
+ ].compact.flatten,
44
+ params
45
+ ).to_h
36
46
  end
37
47
 
38
48
  # Returns a serialized body instance to serialize a request body and figure out the request
@@ -43,7 +53,7 @@ class Reynard
43
53
 
44
54
  def operation(operation_name)
45
55
  dig('paths').each do |path, operations|
46
- operations.each do |verb, operation|
56
+ operations.slice(*VERBS).each do |verb, operation|
47
57
  return Operation.new(node: ['paths', path, verb]) if operation_name == operation['operationId']
48
58
  end
49
59
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Reynard
4
- VERSION = '0.2.0'
4
+ VERSION = '0.4.1'
5
5
  end
data/lib/reynard.rb CHANGED
@@ -11,12 +11,13 @@ require 'uri'
11
11
  # OpenAPI specification.
12
12
  class Reynard
13
13
  extend Forwardable
14
- def_delegators :build_context, :base_url, :operation, :headers, :params
14
+ def_delegators :build_context, :logger, :base_url, :operation, :headers, :params
15
15
  def_delegators :@specification, :servers
16
16
 
17
17
  autoload :Context, 'reynard/context'
18
18
  autoload :GroupedParameters, 'reynard/grouped_parameters'
19
19
  autoload :Http, 'reynard/http'
20
+ autoload :Logger, 'reynard/logger'
20
21
  autoload :MediaType, 'reynard/media_type'
21
22
  autoload :Model, 'reynard/model'
22
23
  autoload :Models, 'reynard/models'
@@ -34,9 +35,9 @@ class Reynard
34
35
  @specification = Specification.new(filename: filename)
35
36
  end
36
37
 
37
- # Assign an object that follows Reynard's internal request interface to mock requests or use a
38
- # different HTTP client.
39
38
  class << self
39
+ # Assign an object that follows Reynard's internal request interface to mock requests or use a
40
+ # different HTTP client.
40
41
  attr_writer :http
41
42
  end
42
43
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reynard
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Manfred Stienstra
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-16 00:00:00.000000000 Z
11
+ date: 2022-04-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: multi_json
@@ -142,7 +142,7 @@ licenses:
142
142
  - MIT
143
143
  metadata:
144
144
  rubygems_mfa_required: 'true'
145
- post_install_message:
145
+ post_install_message:
146
146
  rdoc_options: []
147
147
  require_paths:
148
148
  - lib
@@ -158,7 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
158
158
  version: '0'
159
159
  requirements: []
160
160
  rubygems_version: 3.1.6
161
- signing_key:
161
+ signing_key:
162
162
  specification_version: 4
163
163
  summary: Minimal OpenAPI client.
164
164
  test_files: []