qeweney 0.7.3 → 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8410ab97bb9ce59f14cd87659fa5eeb77595f2a4a1fad873392e403d0b27a80a
4
- data.tar.gz: 5b8404bf25b0b23cb72f0e3e919245d7f41361b692601f0e1bf5b208bc0215ed
3
+ metadata.gz: 5df52e7e0b995f2e515f13dd405b8113f82c9ff56029fc7124e6c72bb1782354
4
+ data.tar.gz: 64f53dd7900143576734f6d05942dd8bea23dcec3f3f913f48f384ea6c1928a8
5
5
  SHA512:
6
- metadata.gz: 5ec5cb26a660c15cd465c04597c8135857f18b5cf8f706582243e3406f9163038c515d4d7a13678777ad71ab4c6fe26b11b35df8d27673316cf423f844c0529d
7
- data.tar.gz: 85d6961f2eb42cf6d7299318e24dbf0ac697a89051667be99fc485b1359c0a0365eabeb69bbe2744d70bbefe9bcbce0226a1cf37196480defc7a6845572963e8
6
+ metadata.gz: 5d932768bd895b3dcbcc72ebad4ef37cb5ed5a02db856af446bc24face24d515715515a12a4617d0f070ef579aa6cbdf95dd17e9dc3d83fceb322c9b595c47df
7
+ data.tar.gz: cc0c52ffe47b2ae0244660e02c66929f48a97093f30de028b0364c45285d6b667011e74aa14d8be847cb5f16f221630f16ee8751af940273f986a8668033d2be
data/CHANGELOG.md CHANGED
@@ -1,3 +1,25 @@
1
+ ## 0.8.2 2021-03-17
2
+
3
+ - Fix form parsing when charset is specified
4
+
5
+ ## 0.8.1 2021-03-10
6
+
7
+ - Add `Request#transfer_counts`, `Request#total_transfer`
8
+ - Fix `Request#rx_incr`
9
+
10
+ ## 0.8 2021-03-10
11
+
12
+ - Pass request as first argument to all adapter methods
13
+
14
+ ## 0.7.5 2021-03-08
15
+
16
+ - Set content-type header in `#serve_file`
17
+
18
+ ## 0.7.4 2021-03-07
19
+
20
+ - Add `Request#cookies`
21
+ - Add `Request#full_uri`
22
+
1
23
  ## 0.7.3 2021-03-05
2
24
 
3
25
  - Fix `parse_urlencoded_form_data`
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- qeweney (0.7.3)
4
+ qeweney (0.8.2)
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
@@ -37,6 +37,10 @@ module Qeweney
37
37
  @uri ||= URI.parse(@headers[':path'] || '')
38
38
  end
39
39
 
40
+ def full_uri
41
+ @full_uri = "#{scheme}://#{host}#{uri}"
42
+ end
43
+
40
44
  def path
41
45
  @path ||= uri.path
42
46
  end
@@ -74,15 +78,33 @@ module Qeweney
74
78
 
75
79
  encoding.split(',').map { |i| i.strip }
76
80
  end
81
+
82
+ def cookies
83
+ @cookies ||= parse_cookies(headers['cookie'])
84
+ end
85
+
86
+ COOKIE_RE = /^([^=]+)=(.*)$/.freeze
87
+ SEMICOLON = ';'
88
+
89
+ def parse_cookies(cookies)
90
+ return {} unless cookies
91
+
92
+ cookies.split(SEMICOLON).each_with_object({}) do |c, h|
93
+ raise BadRequestError, 'Invalid cookie format' unless c.strip =~ COOKIE_RE
94
+
95
+ key, value = Regexp.last_match[1..2]
96
+ h[key] = EscapeUtils.unescape_uri(value)
97
+ end
98
+ end
77
99
  end
78
100
 
79
101
  module RequestInfoClassMethods
80
102
  def parse_form_data(body, headers)
81
103
  case (content_type = headers['content-type'])
82
- when /multipart\/form\-data; boundary=([^\s]+)/
104
+ when /^multipart\/form\-data; boundary=([^\s]+)/
83
105
  boundary = "--#{Regexp.last_match(1)}"
84
106
  parse_multipart_form_data(body, boundary)
85
- when 'application/x-www-form-urlencoded'
107
+ when /^application\/x-www-form-urlencoded/
86
108
  parse_urlencoded_form_data(body)
87
109
  else
88
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Qeweney
4
- VERSION = '0.7.3'
4
+ VERSION = '0.8.2'
5
5
  end
@@ -20,4 +20,30 @@ class RequestInfoTest < MiniTest::Test
20
20
  r = Qeweney.mock('host' => 'my.example.com')
21
21
  assert_equal 'my.example.com', r.host
22
22
  end
23
+
24
+ def test_full_uri
25
+ r = Qeweney.mock(
26
+ ':scheme' => 'https',
27
+ 'host' => 'foo.bar',
28
+ ':path' => '/hey?a=b&c=d'
29
+ )
30
+
31
+ assert_equal 'https://foo.bar/hey?a=b&c=d', r.full_uri
32
+ end
33
+
34
+ def test_cookies
35
+ r = Qeweney.mock
36
+
37
+ assert_equal({}, r.cookies)
38
+
39
+ r = Qeweney.mock(
40
+ 'cookie' => 'uaid=a%2Fb; lastLocus=settings; signin_ref=/'
41
+ )
42
+
43
+ assert_equal({
44
+ 'uaid' => 'a/b',
45
+ 'lastLocus' => 'settings',
46
+ 'signin_ref' => '/'
47
+ }, r.cookies)
48
+ end
23
49
  end
@@ -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
@@ -19,27 +19,27 @@ class RoutingTest < MiniTest::Test
19
19
  def test_app1
20
20
  r = Qeweney.mock(':path' => '/foo')
21
21
  App1.(r)
22
- assert_equal [[:respond, nil, { ':status' => 404 }]], r.response_calls
22
+ assert_equal [[:respond, r, nil, { ':status' => 404 }]], r.response_calls
23
23
 
24
24
  r = Qeweney.mock(':path' => '/')
25
25
  App1.(r)
26
- assert_equal [[:respond, nil, { ':status' => 302, 'Location' => '/hello' }]], r.response_calls
26
+ assert_equal [[:respond, r, nil, { ':status' => 302, 'Location' => '/hello' }]], r.response_calls
27
27
 
28
28
  r = Qeweney.mock(':path' => '/hello', ':method' => 'foo')
29
29
  App1.(r)
30
- assert_equal [[:respond, nil, { ':status' => 404 }]], r.response_calls
30
+ assert_equal [[:respond, r, nil, { ':status' => 404 }]], r.response_calls
31
31
 
32
32
  r = Qeweney.mock(':path' => '/hello', ':method' => 'get')
33
33
  App1.(r)
34
- assert_equal [[:respond, 'Hello', {}]], r.response_calls
34
+ assert_equal [[:respond, r, 'Hello', {}]], r.response_calls
35
35
 
36
36
  r = Qeweney.mock(':path' => '/hello', ':method' => 'post')
37
37
  App1.(r)
38
- assert_equal [[:respond, nil, { ':status' => 302, 'Location' => '/' }]], r.response_calls
38
+ assert_equal [[:respond, r, nil, { ':status' => 302, 'Location' => '/' }]], r.response_calls
39
39
 
40
40
  r = Qeweney.mock(':path' => '/hello/world', ':method' => 'get')
41
41
  App1.(r)
42
- assert_equal [[:respond, 'Hello world', {}]], r.response_calls
42
+ assert_equal [[:respond, r, 'Hello world', {}]], r.response_calls
43
43
  end
44
44
 
45
45
  def test_on_root
@@ -58,19 +58,19 @@ class RoutingTest < MiniTest::Test
58
58
 
59
59
  r = Qeweney.mock(':path' => '/')
60
60
  app.(r)
61
- assert_equal [[:respond, 'root', {}]], r.response_calls
61
+ assert_equal [[:respond, r, 'root', {}]], r.response_calls
62
62
 
63
63
  r = Qeweney.mock(':path' => '/foo')
64
64
  app.(r)
65
- assert_equal [[:respond, 'foo root', {}]], r.response_calls
65
+ assert_equal [[:respond, r, 'foo root', {}]], r.response_calls
66
66
 
67
67
  r = Qeweney.mock(':path' => '/foo/bar')
68
68
  app.(r)
69
- assert_equal [[:respond, 'bar root', {}]], r.response_calls
69
+ assert_equal [[:respond, r, 'bar root', {}]], r.response_calls
70
70
 
71
71
  r = Qeweney.mock(':path' => '/foo/bar/baz')
72
72
  app.(r)
73
- assert_equal [[:respond, 'baz root', {}]], r.response_calls
73
+ assert_equal [[:respond, r, 'baz root', {}]], r.response_calls
74
74
  end
75
75
 
76
76
  def test_relative_path
@@ -90,27 +90,27 @@ class RoutingTest < MiniTest::Test
90
90
  r = Qeweney.mock(':path' => '/')
91
91
  app.(r)
92
92
  assert_equal '/', default_relative_path
93
- assert_equal [[:respond, 'ROOT/', {}]], r.response_calls
93
+ assert_equal [[:respond, r, 'ROOT/', {}]], r.response_calls
94
94
 
95
95
 
96
96
  r = Qeweney.mock(':path' => '/foo/bar/baz')
97
97
  app.(r)
98
98
  assert_equal '/foo/bar/baz', default_relative_path
99
- assert_equal [[:respond, 'FOO/bar/baz', {}]], r.response_calls
99
+ assert_equal [[:respond, r, 'FOO/bar/baz', {}]], r.response_calls
100
100
 
101
101
  r = Qeweney.mock(':path' => '/bar/a/b/c')
102
102
  app.(r)
103
103
  assert_equal '/bar/a/b/c', default_relative_path
104
- assert_equal [[:respond, 'BAR/a/b/c', {}]], r.response_calls
104
+ assert_equal [[:respond, r, 'BAR/a/b/c', {}]], r.response_calls
105
105
 
106
106
  r = Qeweney.mock(':path' => '/bar/baz/b/c')
107
107
  app.(r)
108
108
  assert_equal '/bar/baz/b/c', default_relative_path
109
- assert_equal [[:respond, 'BAR/BAZ/b/c', {}]], r.response_calls
109
+ assert_equal [[:respond, r, 'BAR/BAZ/b/c', {}]], r.response_calls
110
110
 
111
111
  r = Qeweney.mock(':path' => '/baz/d/e/f')
112
112
  app.(r)
113
113
  assert_equal '/baz/d/e/f', default_relative_path
114
- assert_equal [[:respond, '/d/e/f', {}]], r.response_calls
114
+ assert_equal [[:respond, r, '/d/e/f', {}]], r.response_calls
115
115
  end
116
116
  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.3
4
+ version: 0.8.2
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-05 00:00:00.000000000 Z
11
+ date: 2021-03-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: escape_utils