qeweney 0.7.4 → 0.8.3

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: a7beaa70b4d37af5b9bb46aa06bcd78e6d9353eada5715e28d22bc8b5fac61a4
4
- data.tar.gz: 030c6f1fb05fde6ae12c2bb61844c98b9e821b4f7e21f1e7d51fa934814bc3b1
3
+ metadata.gz: 7581e52b302cdddc3c72e952e1fb10987294008b835dc4397be43eeb02432e21
4
+ data.tar.gz: db9891b0910cbd82a579fc0fe5e57d7b0fcdec2a0913a772ef1292fbbf6944cb
5
5
  SHA512:
6
- metadata.gz: 82b3104f93f3ac826f2c4319fb4c9c324efbb490983af4b8035f402fcb04c13f8f8f28dd2443764dcff26e9d7e33f0eb071c3ec0005acefd4fe27cbd13d314e4
7
- data.tar.gz: 9629ed95b4b7397fc8c15ef1b10b8948d31fc047e913c5aab9b7450eaa4ff31cbf7dde4b027870757eb02c0d72e00d8f766c57871aca9fc6948a75ed90adb769
6
+ metadata.gz: 1bd790e2a419bd5463846436c517c8f4552a8347099d6d0ea86ee9c5a5759bf343a0ddda6022f5f6173688f892685669d9d832a073bfbef808f5b105c7d97ede
7
+ data.tar.gz: c89e11cb104b50cbc30f0db451aef81d829767992d4cba18568f1fee243962b63464ff186731709754e8bd919923aabe13e4080a8f470d81d1501ca13481fa1a
data/CHANGELOG.md CHANGED
@@ -1,3 +1,25 @@
1
+ ## 0.8.3 2021-03-22
2
+
3
+ - Streamline routing behaviour in sub routes (an explicit default sub route is
4
+ now required if no sub route matches).
5
+
6
+ ## 0.8.2 2021-03-17
7
+
8
+ - Fix form parsing when charset is specified
9
+
10
+ ## 0.8.1 2021-03-10
11
+
12
+ - Add `Request#transfer_counts`, `Request#total_transfer`
13
+ - Fix `Request#rx_incr`
14
+
15
+ ## 0.8 2021-03-10
16
+
17
+ - Pass request as first argument to all adapter methods
18
+
19
+ ## 0.7.5 2021-03-08
20
+
21
+ - Set content-type header in `#serve_file`
22
+
1
23
  ## 0.7.4 2021-03-07
2
24
 
3
25
  - Add `Request#cookies`
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- qeweney (0.7.4)
4
+ qeweney (0.8.3)
5
5
  escape_utils (~> 1.2.1)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -1,11 +1,71 @@
1
1
  # Qeweney
2
2
 
3
- ## Cross-library feature rich HTTP request / response API
3
+ ## Cross-library HTTP request / response API for servers
4
4
 
5
- Qeweney provides a uniform API for dealing with HTTP requests and responses.
5
+ Qeweney provides a uniform API for dealing with HTTP requests and responses on
6
+ the server side. Qeweney defines a uniform adapter interface that allows
7
+ handling incoming HTTP requests and sending HTTP responses over any protocol or
8
+ transport, be it HTTP/1, HTTP/2 or a Rack interface.
9
+
10
+ Qeweney is primarily designed to work with
11
+ [Tipi](https://github.com/digital-fabric/tipi), but can also be used directly
12
+ inside Rack apps, or to drive Rack apps.
6
13
 
7
14
  ## Features
8
15
 
9
- - Works with different web server APIs, notably Tipi, Digital Fabric, and Rack
10
- - Transport-agnostic
11
- - High-performance routing API inspired by Roda
16
+ - Works with different web server APIs, notably Tipi, Digital Fabric, and Rack.
17
+ - Transport-agnostic.
18
+ - High-performance routing API inspired by Roda.
19
+ - Rich API for extracting data from HTTP requests: form parsing, cookies, file
20
+ uploads, etc.
21
+ - Rich API for constructing HTTP responses: streaming responses, HTTP upgrades,
22
+ static file serving, delate and gzip encoding, caching etc.
23
+ - Suitable for both blocking and non-blocking concurrency models.
24
+ - Allows working with request before request body is read and parsed.
25
+
26
+ ## Overview
27
+
28
+ In Qeweney, the main class developers will interact with is `Qeweney::Request`,
29
+ which encapsulates an HTTP request (from the server's point of view), and offers
30
+ an API for extracting request information and responding to that request.
31
+
32
+ A request is always associated with an _adapter_, an object that implements the
33
+ Qeweney adapter interface, and that allows reading request bodies (for uploads
34
+ and form submissions) and sending responses.
35
+
36
+ ## The Qeweney Adapter Interface
37
+
38
+ ```ruby
39
+ class AdapterInterface
40
+ # Reads a chunk from the request body
41
+ # @req [Qeweney::Request] request for which the chunk is to be read
42
+ def get_body_chunk(req)
43
+ end
44
+
45
+ # Send a non-streaming response
46
+ # @req [Qeweney::Request] request for which the response is sent
47
+ # @body [String, nil] response body
48
+ # @headers [Hash] response headers
49
+ def respond(req, body, headers)
50
+ end
51
+
52
+ # Send only headers
53
+ # @req [Qeweney::Request] request for which the response is sent
54
+ # @headers [Hash] response headers
55
+ # @empty_response [boolean] whether response is empty
56
+ def send_headers(req, headers, empty_response: nil)
57
+ end
58
+
59
+ # Send a body chunk (this implies chunked transfer encoding)
60
+ # @req [Qeweney::Request] request for which the response is sent
61
+ # @body [String, nil] chunk
62
+ # @done [boolean] whether response is finished
63
+ def send_chunk(req, body, done: false)
64
+ end
65
+
66
+ # Finishes response
67
+ # @req [Qeweney::Request] request for which the response is sent
68
+ def finish(req)
69
+ end
70
+ end
71
+ ```
@@ -7,7 +7,7 @@ module Qeweney
7
7
  'html' => 'text/html',
8
8
  'css' => 'text/css',
9
9
  'js' => 'application/javascript',
10
- 'txt' => 'text/plain'
10
+ 'txt' => 'text/plain',
11
11
 
12
12
  'gif' => 'image/gif',
13
13
  'jpg' => 'image/jpeg',
@@ -19,7 +19,7 @@ module Qeweney
19
19
  'json' => 'application/json',
20
20
  }.freeze
21
21
 
22
- def [](ref)
22
+ def self.[](ref)
23
23
  case ref
24
24
  when Symbol
25
25
  TYPES[ref.to_s]
data/lib/qeweney/rack.rb CHANGED
@@ -32,20 +32,20 @@ module Qeweney
32
32
  headers
33
33
  end
34
34
 
35
- def respond(body, headers)
35
+ def respond(req, body, headers)
36
36
  @response_body << body
37
37
  @response_headers = headers
38
38
  end
39
39
 
40
- def send_headers(headers, empty_response: nil)
40
+ def send_headers(req, headers, empty_response: nil)
41
41
  @response_headers = headers
42
42
  end
43
43
 
44
- def send_chunk(body, done: false)
44
+ def send_chunk(req, body, done: false)
45
45
  @response_body << body
46
46
  end
47
47
 
48
- def finish
48
+ def finish(req)
49
49
  end
50
50
 
51
51
  def rack_response
@@ -34,7 +34,7 @@ module Qeweney
34
34
  return chunk
35
35
  end
36
36
 
37
- @message_complete ? nil : @adapter.get_body_chunk
37
+ @message_complete ? nil : @adapter.get_body_chunk(self)
38
38
  end
39
39
 
40
40
  def each_chunk
@@ -44,7 +44,7 @@ module Qeweney
44
44
  end
45
45
  @buffered_body_chunks = nil
46
46
  end
47
- while !@message_complete && (chunk = @adapter.get_body_chunk)
47
+ while !@message_complete && (chunk = @adapter.get_body_chunk(self))
48
48
  yield chunk
49
49
  end
50
50
  end
@@ -59,7 +59,7 @@ module Qeweney
59
59
  end
60
60
 
61
61
  def consume
62
- @adapter.consume_request
62
+ @adapter.consume_request(self)
63
63
  end
64
64
 
65
65
  def keep_alive?
@@ -68,7 +68,7 @@ module Qeweney
68
68
 
69
69
  def read
70
70
  buf = @buffered_body_chunks ? @buffered_body_chunks.join : nil
71
- while (chunk = @adapter.get_body_chunk)
71
+ while (chunk = @adapter.get_body_chunk(self))
72
72
  (buf ||= +'') << chunk
73
73
  end
74
74
  @buffered_body_chunks = nil
@@ -77,7 +77,7 @@ module Qeweney
77
77
  alias_method :body, :read
78
78
 
79
79
  def respond(body, headers = {})
80
- @adapter.respond(body, headers)
80
+ @adapter.respond(self, body, headers)
81
81
  @headers_sent = true
82
82
  end
83
83
 
@@ -85,24 +85,40 @@ module Qeweney
85
85
  return if @headers_sent
86
86
 
87
87
  @headers_sent = true
88
- @adapter.send_headers(headers, empty_response: empty_response)
88
+ @adapter.send_headers(self, headers, empty_response: empty_response)
89
89
  end
90
90
 
91
91
  def send_chunk(body, done: false)
92
92
  send_headers({}) unless @headers_sent
93
93
 
94
- @adapter.send_chunk(body, done: done)
94
+ @adapter.send_chunk(self, body, done: done)
95
95
  end
96
96
  alias_method :<<, :send_chunk
97
97
 
98
98
  def finish
99
99
  send_headers({}) unless @headers_sent
100
100
 
101
- @adapter.finish
101
+ @adapter.finish(self)
102
102
  end
103
103
 
104
104
  def headers_sent?
105
105
  @headers_sent
106
106
  end
107
+
108
+ def rx_incr(count)
109
+ headers[':rx'] ? headers[':rx'] += count : headers[':rx'] = count
110
+ end
111
+
112
+ def tx_incr(count)
113
+ headers[':tx'] ? headers[':tx'] += count : headers[':tx'] = count
114
+ end
115
+
116
+ def transfer_counts
117
+ [headers[':rx'], headers[':tx']]
118
+ end
119
+
120
+ def total_transfer
121
+ (headers[':rx'] || 0) + (headers[':tx'] || 0)
122
+ end
107
123
  end
108
124
  end
@@ -87,6 +87,8 @@ module Qeweney
87
87
  SEMICOLON = ';'
88
88
 
89
89
  def parse_cookies(cookies)
90
+ return {} unless cookies
91
+
90
92
  cookies.split(SEMICOLON).each_with_object({}) do |c, h|
91
93
  raise BadRequestError, 'Invalid cookie format' unless c.strip =~ COOKIE_RE
92
94
 
@@ -99,10 +101,10 @@ module Qeweney
99
101
  module RequestInfoClassMethods
100
102
  def parse_form_data(body, headers)
101
103
  case (content_type = headers['content-type'])
102
- when /multipart\/form\-data; boundary=([^\s]+)/
104
+ when /^multipart\/form\-data; boundary=([^\s]+)/
103
105
  boundary = "--#{Regexp.last_match(1)}"
104
106
  parse_multipart_form_data(body, boundary)
105
- when 'application/x-www-form-urlencoded'
107
+ when /^application\/x-www-form-urlencoded/
106
108
  parse_urlencoded_form_data(body)
107
109
  else
108
110
  raise "Unsupported form data content type: #{content_type}"
@@ -6,6 +6,7 @@ require 'stringio'
6
6
  require 'digest/sha1'
7
7
 
8
8
  require_relative 'status'
9
+ require_relative 'mime_types'
9
10
 
10
11
  module Qeweney
11
12
  module StaticFileCaching
@@ -59,7 +60,7 @@ module Qeweney
59
60
  redirect(secure_uri, status)
60
61
  end
61
62
 
62
- def serve_file(path, opts)
63
+ def serve_file(path, opts = {})
63
64
  full_path = file_full_path(path, opts)
64
65
  stat = File.stat(full_path)
65
66
  etag = StaticFileCaching.file_stat_to_etag(stat)
@@ -72,17 +73,25 @@ module Qeweney
72
73
  })
73
74
  end
74
75
 
76
+ mime_type = Qeweney::MimeTypes[File.extname(path)]
77
+ (opts[:headers] ||= {})['Content-Type'] ||= mime_type if mime_type
78
+
75
79
  respond_with_static_file(full_path, etag, last_modified, opts)
76
80
  rescue Errno::ENOENT => e
77
81
  respond(nil, ':status' => Status::NOT_FOUND)
78
82
  end
79
83
 
80
84
  def respond_with_static_file(path, etag, last_modified, opts)
85
+ cache_headers = {
86
+ 'etag' => etag,
87
+ 'last-modified' => last_modified,
88
+ }
81
89
  File.open(path, 'r') do |f|
82
- opts = opts.merge(headers: {
83
- 'etag' => etag,
84
- 'last-modified' => last_modified,
85
- })
90
+ if opts[:headers]
91
+ opts[:headers].merge!(cache_headers)
92
+ else
93
+ opts[:headers] = cache_headers
94
+ end
86
95
 
87
96
  # accept_encoding should return encodings in client's order of preference
88
97
  accept_encoding.each do |encoding|
@@ -150,6 +159,7 @@ module Qeweney
150
159
 
151
160
  # TODO: send separate chunks for multi-part body
152
161
  # TODO: add support for streaming body
162
+ # TODO: add support for websocket
153
163
  end
154
164
  end
155
165
  end
@@ -16,7 +16,7 @@ module Qeweney
16
16
 
17
17
  def route_found(&block)
18
18
  catch(:stop, &block)
19
- throw :stop, headers_sent? ? :found : nil
19
+ throw :stop, :found
20
20
  end
21
21
 
22
22
  @@regexp_cache = {}
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Qeweney
4
- VERSION = '0.7.4'
4
+ VERSION = '0.8.3'
5
5
  end
@@ -32,6 +32,10 @@ class RequestInfoTest < MiniTest::Test
32
32
  end
33
33
 
34
34
  def test_cookies
35
+ r = Qeweney.mock
36
+
37
+ assert_equal({}, r.cookies)
38
+
35
39
  r = Qeweney.mock(
36
40
  'cookie' => 'uaid=a%2Fb; lastLocus=settings; signin_ref=/'
37
41
  )
@@ -8,7 +8,7 @@ class RedirectTest < MiniTest::Test
8
8
  r.redirect('/foo')
9
9
 
10
10
  assert_equal [
11
- [:respond, nil, {":status"=>302, "Location"=>"/foo"}]
11
+ [:respond, r, nil, {":status"=>302, "Location"=>"/foo"}]
12
12
  ], r.response_calls
13
13
  end
14
14
 
@@ -17,7 +17,7 @@ class RedirectTest < MiniTest::Test
17
17
  r.redirect('/bar', Qeweney::Status::MOVED_PERMANENTLY)
18
18
 
19
19
  assert_equal [
20
- [:respond, nil, {":status"=>301, "Location"=>"/bar"}]
20
+ [:respond, r, nil, {":status"=>301, "Location"=>"/bar"}]
21
21
  ], r.response_calls
22
22
  end
23
23
  end
@@ -37,7 +37,7 @@ class StaticFileResponeTest < MiniTest::Test
37
37
  r.serve_file('helper.rb', base_path: __dir__)
38
38
 
39
39
  assert_equal [
40
- [:respond, @content, { 'etag' => @etag, 'last-modified' => @last_modified }]
40
+ [:respond, r, @content, { 'etag' => @etag, 'last-modified' => @last_modified }]
41
41
  ], r.response_calls
42
42
  end
43
43
 
@@ -45,25 +45,25 @@ class StaticFileResponeTest < MiniTest::Test
45
45
  r = Qeweney.mock('if-none-match' => @etag)
46
46
  r.serve_file('helper.rb', base_path: __dir__)
47
47
  assert_equal [
48
- [:respond, nil, { 'etag' => @etag, ':status' => Qeweney::Status::NOT_MODIFIED }]
48
+ [:respond, r, nil, { 'etag' => @etag, ':status' => Qeweney::Status::NOT_MODIFIED }]
49
49
  ], r.response_calls
50
50
 
51
51
  r = Qeweney.mock('if-modified-since' => @last_modified)
52
52
  r.serve_file('helper.rb', base_path: __dir__)
53
53
  assert_equal [
54
- [:respond, nil, { 'etag' => @etag, ':status' => Qeweney::Status::NOT_MODIFIED }]
54
+ [:respond, r, nil, { 'etag' => @etag, ':status' => Qeweney::Status::NOT_MODIFIED }]
55
55
  ], r.response_calls
56
56
 
57
57
  r = Qeweney.mock('if-none-match' => 'foobar')
58
58
  r.serve_file('helper.rb', base_path: __dir__)
59
59
  assert_equal [
60
- [:respond, @content, { 'etag' => @etag, 'last-modified' => @last_modified }]
60
+ [:respond, r, @content, { 'etag' => @etag, 'last-modified' => @last_modified }]
61
61
  ], r.response_calls
62
62
 
63
63
  r = Qeweney.mock('if-modified-since' => Time.now.httpdate)
64
64
  r.serve_file('helper.rb', base_path: __dir__)
65
65
  assert_equal [
66
- [:respond, @content, { 'etag' => @etag, 'last-modified' => @last_modified }]
66
+ [:respond, r, @content, { 'etag' => @etag, 'last-modified' => @last_modified }]
67
67
  ], r.response_calls
68
68
  end
69
69
 
@@ -75,7 +75,7 @@ class StaticFileResponeTest < MiniTest::Test
75
75
  deflated_content = deflate.deflate(@content, Zlib::FINISH)
76
76
 
77
77
  assert_equal [
78
- [:respond, deflated_content, {
78
+ [:respond, r, deflated_content, {
79
79
  'etag' => @etag,
80
80
  'last-modified' => @last_modified,
81
81
  'vary' => 'Accept-Encoding',
@@ -96,7 +96,7 @@ class StaticFileResponeTest < MiniTest::Test
96
96
  gzipped_content = buf.string
97
97
 
98
98
  assert_equal [
99
- [:respond, gzipped_content, {
99
+ [:respond, r, gzipped_content, {
100
100
  'etag' => @etag,
101
101
  'last-modified' => @last_modified,
102
102
  'vary' => 'Accept-Encoding',
@@ -109,7 +109,7 @@ class StaticFileResponeTest < MiniTest::Test
109
109
  r = Qeweney.mock
110
110
  r.serve_file('foo.rb', base_path: __dir__)
111
111
  assert_equal [
112
- [:respond, nil, { ':status' => Qeweney::Status::NOT_FOUND }]
112
+ [:respond, r, nil, { ':status' => Qeweney::Status::NOT_FOUND }]
113
113
  ], r.response_calls
114
114
  end
115
115
  end
@@ -120,7 +120,7 @@ class UpgradeTest < MiniTest::Test
120
120
  r.upgrade('df')
121
121
 
122
122
  assert_equal [
123
- [:respond, nil, {
123
+ [:respond, r, nil, {
124
124
  ':status' => 101,
125
125
  'Upgrade' => 'df',
126
126
  'Connection' => 'upgrade'
@@ -132,7 +132,7 @@ class UpgradeTest < MiniTest::Test
132
132
  r.upgrade('df', { 'foo' => 'bar' })
133
133
 
134
134
  assert_equal [
135
- [:respond, nil, {
135
+ [:respond, r, nil, {
136
136
  ':status' => 101,
137
137
  'Upgrade' => 'df',
138
138
  'Connection' => 'upgrade',
@@ -155,7 +155,7 @@ class UpgradeTest < MiniTest::Test
155
155
  accept = Digest::SHA1.base64digest('abcdefghij258EAFA5-E914-47DA-95CA-C5AB0DC85B11')
156
156
 
157
157
  assert_equal [
158
- [:respond, nil, {
158
+ [:respond, r, nil, {
159
159
  ':status' => 101,
160
160
  'Upgrade' => 'websocket',
161
161
  'Connection' => 'upgrade',
@@ -179,7 +179,7 @@ class ServeRackTest < MiniTest::Test
179
179
  })
180
180
 
181
181
  assert_equal [
182
- [:respond, "get /foo/bar", {':status' => 404, 'Foo' => 'Bar' }]
182
+ [:respond, r, 'get /foo/bar', {':status' => 404, 'Foo' => 'Bar' }]
183
183
  ], r.response_calls
184
184
  end
185
185
  end
data/test/test_routing.rb CHANGED
@@ -12,6 +12,7 @@ class RoutingTest < MiniTest::Test
12
12
  r.on_post do
13
13
  r.redirect '/'
14
14
  end
15
+ r.default { r.respond nil, ':status' => 404 }
15
16
  end
16
17
  end
17
18
  end
@@ -19,27 +20,27 @@ class RoutingTest < MiniTest::Test
19
20
  def test_app1
20
21
  r = Qeweney.mock(':path' => '/foo')
21
22
  App1.(r)
22
- assert_equal [[:respond, nil, { ':status' => 404 }]], r.response_calls
23
+ assert_equal [[:respond, r, nil, { ':status' => 404 }]], r.response_calls
23
24
 
24
25
  r = Qeweney.mock(':path' => '/')
25
26
  App1.(r)
26
- assert_equal [[:respond, nil, { ':status' => 302, 'Location' => '/hello' }]], r.response_calls
27
+ assert_equal [[:respond, r, nil, { ':status' => 302, 'Location' => '/hello' }]], r.response_calls
27
28
 
28
29
  r = Qeweney.mock(':path' => '/hello', ':method' => 'foo')
29
30
  App1.(r)
30
- assert_equal [[:respond, nil, { ':status' => 404 }]], r.response_calls
31
+ assert_equal [[:respond, r, nil, { ':status' => 404 }]], r.response_calls
31
32
 
32
33
  r = Qeweney.mock(':path' => '/hello', ':method' => 'get')
33
34
  App1.(r)
34
- assert_equal [[:respond, 'Hello', {}]], r.response_calls
35
+ assert_equal [[:respond, r, 'Hello', {}]], r.response_calls
35
36
 
36
37
  r = Qeweney.mock(':path' => '/hello', ':method' => 'post')
37
38
  App1.(r)
38
- assert_equal [[:respond, nil, { ':status' => 302, 'Location' => '/' }]], r.response_calls
39
+ assert_equal [[:respond, r, nil, { ':status' => 302, 'Location' => '/' }]], r.response_calls
39
40
 
40
41
  r = Qeweney.mock(':path' => '/hello/world', ':method' => 'get')
41
42
  App1.(r)
42
- assert_equal [[:respond, 'Hello world', {}]], r.response_calls
43
+ assert_equal [[:respond, r, 'Hello world', {}]], r.response_calls
43
44
  end
44
45
 
45
46
  def test_on_root
@@ -58,19 +59,19 @@ class RoutingTest < MiniTest::Test
58
59
 
59
60
  r = Qeweney.mock(':path' => '/')
60
61
  app.(r)
61
- assert_equal [[:respond, 'root', {}]], r.response_calls
62
+ assert_equal [[:respond, r, 'root', {}]], r.response_calls
62
63
 
63
64
  r = Qeweney.mock(':path' => '/foo')
64
65
  app.(r)
65
- assert_equal [[:respond, 'foo root', {}]], r.response_calls
66
+ assert_equal [[:respond, r, 'foo root', {}]], r.response_calls
66
67
 
67
68
  r = Qeweney.mock(':path' => '/foo/bar')
68
69
  app.(r)
69
- assert_equal [[:respond, 'bar root', {}]], r.response_calls
70
+ assert_equal [[:respond, r, 'bar root', {}]], r.response_calls
70
71
 
71
72
  r = Qeweney.mock(':path' => '/foo/bar/baz')
72
73
  app.(r)
73
- assert_equal [[:respond, 'baz root', {}]], r.response_calls
74
+ assert_equal [[:respond, r, 'baz root', {}]], r.response_calls
74
75
  end
75
76
 
76
77
  def test_relative_path
@@ -90,27 +91,27 @@ class RoutingTest < MiniTest::Test
90
91
  r = Qeweney.mock(':path' => '/')
91
92
  app.(r)
92
93
  assert_equal '/', default_relative_path
93
- assert_equal [[:respond, 'ROOT/', {}]], r.response_calls
94
+ assert_equal [[:respond, r, 'ROOT/', {}]], r.response_calls
94
95
 
95
96
 
96
97
  r = Qeweney.mock(':path' => '/foo/bar/baz')
97
98
  app.(r)
98
99
  assert_equal '/foo/bar/baz', default_relative_path
99
- assert_equal [[:respond, 'FOO/bar/baz', {}]], r.response_calls
100
+ assert_equal [[:respond, r, 'FOO/bar/baz', {}]], r.response_calls
100
101
 
101
102
  r = Qeweney.mock(':path' => '/bar/a/b/c')
102
103
  app.(r)
103
104
  assert_equal '/bar/a/b/c', default_relative_path
104
- assert_equal [[:respond, 'BAR/a/b/c', {}]], r.response_calls
105
+ assert_equal [[:respond, r, 'BAR/a/b/c', {}]], r.response_calls
105
106
 
106
107
  r = Qeweney.mock(':path' => '/bar/baz/b/c')
107
108
  app.(r)
108
109
  assert_equal '/bar/baz/b/c', default_relative_path
109
- assert_equal [[:respond, 'BAR/BAZ/b/c', {}]], r.response_calls
110
+ assert_equal [[:respond, r, 'BAR/BAZ/b/c', {}]], r.response_calls
110
111
 
111
112
  r = Qeweney.mock(':path' => '/baz/d/e/f')
112
113
  app.(r)
113
114
  assert_equal '/baz/d/e/f', default_relative_path
114
- assert_equal [[:respond, '/d/e/f', {}]], r.response_calls
115
+ assert_equal [[:respond, r, '/d/e/f', {}]], r.response_calls
115
116
  end
116
117
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qeweney
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.4
4
+ version: 0.8.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sharon Rosner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-07 00:00:00.000000000 Z
11
+ date: 2021-03-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: escape_utils
@@ -136,7 +136,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
136
136
  - !ruby/object:Gem::Version
137
137
  version: '0'
138
138
  requirements: []
139
- rubygems_version: 3.0.8
139
+ rubygems_version: 3.1.4
140
140
  signing_key:
141
141
  specification_version: 4
142
142
  summary: Qeweney - cross library HTTP request / response API