qeweney 0.20 → 0.22
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 +4 -4
- data/.github/workflows/test.yml +1 -1
- data/.gitignore +1 -1
- data/CHANGELOG.md +9 -0
- data/TODO.md +4 -0
- data/lib/qeweney/errors.rb +6 -0
- data/lib/qeweney/mime_types.rb +1 -1
- data/lib/qeweney/mock_adapter.rb +55 -0
- data/lib/qeweney/request.rb +2 -2
- data/lib/qeweney/request_info.rb +9 -6
- data/lib/qeweney/version.rb +1 -1
- data/lib/qeweney.rb +3 -2
- data/qeweney.gemspec +9 -9
- data/test/helper.rb +2 -29
- data/test/run_loop.rb +39 -0
- data/test/test_mock_adapter.rb +49 -0
- data/test/test_request_info.rb +13 -13
- data/test/test_response.rb +32 -32
- data/test/test_routing.rb +33 -33
- metadata +28 -31
- data/Gemfile.lock +0 -35
- data/lib/qeweney/test_adapter.rb +0 -26
- data/test/test_test_adapter.rb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 83fd3aeea3a2ab2fff17ca871189e60098168523583b801423a6d2ecd21d5a9f
|
4
|
+
data.tar.gz: 53dcc37653949d20a6324d5e24df1f5b827a56ce134dd69c168369242917f825
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3cee5ee51f356cddcff578d2cd2e582ea0f293ce2d898e43022fe9ab83d0e812423473f047701306796f70ac53833818b125f7308a438c6a05d18a00465e9e93
|
7
|
+
data.tar.gz: 6de0f052bc1077e665d5c5bd3f6fc8de59442e5944ddc68c3b9ceca873cfdd2e6ed47880bb5e0a89dbb36cbfc802936f3f15c121e82e59922515f000bd5d7b31
|
data/.github/workflows/test.yml
CHANGED
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
data/TODO.md
CHANGED
data/lib/qeweney/mime_types.rb
CHANGED
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'qeweney'
|
4
|
+
|
5
|
+
module Qeweney
|
6
|
+
class MockAdapter
|
7
|
+
attr_reader :body, :headers, :calls
|
8
|
+
|
9
|
+
def get_body_chunk(_req, _buffered_only)
|
10
|
+
@request_body_chunks.shift
|
11
|
+
end
|
12
|
+
|
13
|
+
def get_body(_req)
|
14
|
+
body = @request_body_chunks.join('')
|
15
|
+
@request_body_chunks.clear
|
16
|
+
body
|
17
|
+
end
|
18
|
+
|
19
|
+
def complete?(_req)
|
20
|
+
@request_body_chunks.empty?
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize(request_body)
|
24
|
+
case request_body
|
25
|
+
when Array
|
26
|
+
@request_body_chunks = request_body
|
27
|
+
when nil
|
28
|
+
@request_body_chunks = []
|
29
|
+
else
|
30
|
+
@request_body_chunks = [request_body]
|
31
|
+
end
|
32
|
+
@calls = []
|
33
|
+
end
|
34
|
+
|
35
|
+
def respond(req, body, headers)
|
36
|
+
@calls << [:respond, req, body, headers]
|
37
|
+
@body = body
|
38
|
+
@headers = headers
|
39
|
+
end
|
40
|
+
|
41
|
+
def status
|
42
|
+
headers[':status'] || Qeweney::Status::OK
|
43
|
+
end
|
44
|
+
|
45
|
+
def method_missing(sym, *args)
|
46
|
+
calls << [sym, *args]
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.mock(headers = {}, request_body = nil)
|
50
|
+
headers[':method'] ||= ''
|
51
|
+
headers[':path'] ||= ''
|
52
|
+
Request.new(headers, new(request_body))
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/lib/qeweney/request.rb
CHANGED
@@ -45,7 +45,7 @@ module Qeweney
|
|
45
45
|
end
|
46
46
|
@buffered_body_chunks = nil
|
47
47
|
end
|
48
|
-
while (chunk = @adapter.get_body_chunk(self))
|
48
|
+
while (chunk = @adapter.get_body_chunk(self, false))
|
49
49
|
yield chunk
|
50
50
|
end
|
51
51
|
end
|
@@ -115,4 +115,4 @@ module Qeweney
|
|
115
115
|
(headers[':rx'] || 0) + (headers[':tx'] || 0)
|
116
116
|
end
|
117
117
|
end
|
118
|
-
end
|
118
|
+
end
|
data/lib/qeweney/request_info.rb
CHANGED
@@ -3,6 +3,8 @@
|
|
3
3
|
require 'uri'
|
4
4
|
require 'escape_utils'
|
5
5
|
|
6
|
+
require_relative './errors'
|
7
|
+
|
6
8
|
module Qeweney
|
7
9
|
module RequestInfoMethods
|
8
10
|
def host
|
@@ -126,12 +128,13 @@ module Qeweney
|
|
126
128
|
when /^application\/x-www-form-urlencoded/
|
127
129
|
parse_urlencoded_form_data(body)
|
128
130
|
else
|
129
|
-
raise "Unsupported form data content type: #{content_type}"
|
131
|
+
raise BadRequestError, "Unsupported form data content type: #{content_type}"
|
130
132
|
end
|
131
133
|
end
|
132
134
|
|
133
135
|
def parse_multipart_form_data(body, boundary)
|
134
136
|
parts = body.split(boundary)
|
137
|
+
raise BadRequestError, 'Invalid form data' if parts.size < 2
|
135
138
|
parts.each_with_object({}) do |p, h|
|
136
139
|
next if p.empty? || p == "--\r\n"
|
137
140
|
|
@@ -174,7 +177,7 @@ module Qeweney
|
|
174
177
|
[part, headers]
|
175
178
|
end
|
176
179
|
|
177
|
-
PARAMETER_RE = /^(
|
180
|
+
PARAMETER_RE = /^([^=]+)(?:=(.*))?$/.freeze
|
178
181
|
MAX_PARAMETER_NAME_SIZE = 256
|
179
182
|
MAX_PARAMETER_VALUE_SIZE = 2**20 # 1MB
|
180
183
|
|
@@ -183,15 +186,15 @@ module Qeweney
|
|
183
186
|
|
184
187
|
body.force_encoding(Encoding::UTF_8) unless body.encoding == Encoding::UTF_8
|
185
188
|
body.split('&').each_with_object({}) do |i, m|
|
186
|
-
raise 'Invalid parameter format' unless i =~ PARAMETER_RE
|
189
|
+
raise BadRequestError, 'Invalid parameter format' unless i =~ PARAMETER_RE
|
187
190
|
|
188
191
|
k = Regexp.last_match(1)
|
189
|
-
raise 'Invalid parameter size' if k.size > MAX_PARAMETER_NAME_SIZE
|
192
|
+
raise BadRequestError, 'Invalid parameter size' if k.size > MAX_PARAMETER_NAME_SIZE
|
190
193
|
|
191
194
|
v = Regexp.last_match(2)
|
192
|
-
raise 'Invalid parameter size' if v.size > MAX_PARAMETER_VALUE_SIZE
|
195
|
+
raise BadRequestError, 'Invalid parameter size' if v && v.size > MAX_PARAMETER_VALUE_SIZE
|
193
196
|
|
194
|
-
m[EscapeUtils.unescape_uri(k)] = EscapeUtils.unescape_uri(v)
|
197
|
+
m[EscapeUtils.unescape_uri(k)] = v ? EscapeUtils.unescape_uri(v) : true
|
195
198
|
end
|
196
199
|
end
|
197
200
|
end
|
data/lib/qeweney/version.rb
CHANGED
data/lib/qeweney.rb
CHANGED
data/qeweney.gemspec
CHANGED
@@ -10,17 +10,17 @@ Gem::Specification.new do |s|
|
|
10
10
|
s.files = `git ls-files`.split
|
11
11
|
s.homepage = 'https://github.com/digital-fabric/qeweney'
|
12
12
|
s.metadata = {
|
13
|
-
|
13
|
+
'source_code_uri' => 'https://github.com/digital-fabric/qeweney'
|
14
14
|
}
|
15
|
-
s.rdoc_options = [
|
16
|
-
s.extra_rdoc_files = [
|
17
|
-
s.require_paths = [
|
15
|
+
s.rdoc_options = ['--title', 'Qeweney', '--main', 'README.md']
|
16
|
+
s.extra_rdoc_files = ['README.md']
|
17
|
+
s.require_paths = ['lib']
|
18
18
|
s.required_ruby_version = '>= 2.6'
|
19
19
|
|
20
|
-
s.add_runtime_dependency 'escape_utils',
|
20
|
+
s.add_runtime_dependency 'escape_utils', '1.3.0'
|
21
21
|
|
22
|
-
s.add_development_dependency '
|
23
|
-
s.add_development_dependency 'minitest',
|
24
|
-
s.add_development_dependency '
|
25
|
-
s.add_development_dependency '
|
22
|
+
s.add_development_dependency 'benchmark-ips', '2.14.0'
|
23
|
+
s.add_development_dependency 'minitest', '5.25.4'
|
24
|
+
s.add_development_dependency 'rake', '13.2.1'
|
25
|
+
s.add_development_dependency 'listen', '3.9.0'
|
26
26
|
end
|
data/test/helper.rb
CHANGED
@@ -2,35 +2,8 @@
|
|
2
2
|
|
3
3
|
require 'bundler/setup'
|
4
4
|
require 'qeweney'
|
5
|
-
|
5
|
+
require 'qeweney/mock_adapter'
|
6
6
|
require 'fileutils'
|
7
|
-
|
8
|
-
require_relative './coverage' if ENV['COVERAGE']
|
9
|
-
|
10
7
|
require 'minitest/autorun'
|
11
8
|
|
12
|
-
|
13
|
-
class MockAdapter
|
14
|
-
attr_reader :calls
|
15
|
-
|
16
|
-
def initialize
|
17
|
-
@calls = []
|
18
|
-
end
|
19
|
-
|
20
|
-
def method_missing(sym, *args)
|
21
|
-
calls << [sym, *args]
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def self.mock(headers = {})
|
26
|
-
headers[':method'] ||= ''
|
27
|
-
headers[':path'] ||= ''
|
28
|
-
Request.new(headers, MockAdapter.new)
|
29
|
-
end
|
30
|
-
|
31
|
-
class Request
|
32
|
-
def response_calls
|
33
|
-
adapter.calls
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
9
|
+
require_relative './coverage' if ENV['COVERAGE']
|
data/test/run_loop.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'bundler/setup'
|
5
|
+
|
6
|
+
require 'listen'
|
7
|
+
|
8
|
+
def run_all_tests
|
9
|
+
puts
|
10
|
+
system('bundle exec ruby test/run.rb')
|
11
|
+
end
|
12
|
+
|
13
|
+
def run_test(fn)
|
14
|
+
system("bundle exec ruby #{fn}")
|
15
|
+
end
|
16
|
+
|
17
|
+
listener = Listen.to('lib', 'test') do |modified, added, removed|
|
18
|
+
puts '*' * 40
|
19
|
+
|
20
|
+
fns = []
|
21
|
+
|
22
|
+
modified.each { fns << it }
|
23
|
+
added.each { fns << it }
|
24
|
+
removed.each { fns << it }
|
25
|
+
|
26
|
+
fns = fns.uniq
|
27
|
+
puts "modified: #{fns.inspect}"
|
28
|
+
puts '*' * 40
|
29
|
+
|
30
|
+
if fns.size == 1 && fns.first =~ /test_/
|
31
|
+
run_test(fns.first)
|
32
|
+
else
|
33
|
+
run_all_tests
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
run_all_tests
|
38
|
+
listener.start
|
39
|
+
sleep
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'helper'
|
4
|
+
|
5
|
+
class MockAdapterTest < Minitest::Test
|
6
|
+
def test_mock_adapter
|
7
|
+
adapter = Qeweney::MockAdapter.new(nil)
|
8
|
+
req = Qeweney::Request.new({ ':path' => '/foo' }, adapter)
|
9
|
+
req.respond('bar', 'Content-Type' => 'baz')
|
10
|
+
|
11
|
+
assert_equal 'bar', adapter.body
|
12
|
+
assert_equal({'Content-Type' => 'baz'}, adapter.headers)
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_mock_adapter_with_body
|
16
|
+
adapter = Qeweney::MockAdapter.new('barbaz')
|
17
|
+
req = Qeweney::Request.new({ ':path' => '/foo' }, adapter)
|
18
|
+
assert_equal false, req.complete?
|
19
|
+
|
20
|
+
body = req.read
|
21
|
+
assert_equal 'barbaz', body
|
22
|
+
assert_equal true, req.complete?
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_mock_adapter_with_chunked_body
|
26
|
+
adapter = Qeweney::MockAdapter.new(['bar', 'baz'])
|
27
|
+
req = Qeweney::Request.new({ ':path' => '/foo' }, adapter)
|
28
|
+
assert_equal false, req.complete?
|
29
|
+
|
30
|
+
chunk = req.next_chunk
|
31
|
+
assert_equal 'bar', chunk
|
32
|
+
assert_equal false, req.complete?
|
33
|
+
|
34
|
+
chunk = req.next_chunk
|
35
|
+
assert_equal 'baz', chunk
|
36
|
+
assert_equal true, req.complete?
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_mock_adapter_each_chunk
|
40
|
+
chunks = []
|
41
|
+
adapter = Qeweney::MockAdapter.new(['bar', 'baz'])
|
42
|
+
req = Qeweney::Request.new({ ':path' => '/foo' }, adapter)
|
43
|
+
assert_equal false, req.complete?
|
44
|
+
|
45
|
+
req.each_chunk { chunks << _1 }
|
46
|
+
assert_equal ['bar', 'baz'], chunks
|
47
|
+
assert_equal true, req.complete?
|
48
|
+
end
|
49
|
+
end
|
data/test/test_request_info.rb
CHANGED
@@ -2,46 +2,46 @@
|
|
2
2
|
|
3
3
|
require_relative 'helper'
|
4
4
|
|
5
|
-
class RequestInfoTest <
|
5
|
+
class RequestInfoTest < Minitest::Test
|
6
6
|
def test_uri
|
7
|
-
r = Qeweney.mock(':path' => '/test/path')
|
7
|
+
r = Qeweney::MockAdapter.mock(':path' => '/test/path')
|
8
8
|
assert_equal '/test/path', r.path
|
9
9
|
assert_equal({}, r.query)
|
10
10
|
|
11
|
-
r = Qeweney.mock(':path' => '/test/path?a=1&b=2&c=3%2f4')
|
11
|
+
r = Qeweney::MockAdapter.mock(':path' => '/test/path?a=1&b=2&c=3%2f4')
|
12
12
|
assert_equal '/test/path', r.path
|
13
13
|
assert_equal({ a: '1', b: '2', c: '3/4' }, r.query)
|
14
14
|
end
|
15
15
|
|
16
16
|
def test_query
|
17
|
-
r = Qeweney.mock(':path' => '/GponForm/diag_Form?images/')
|
17
|
+
r = Qeweney::MockAdapter.mock(':path' => '/GponForm/diag_Form?images/')
|
18
18
|
assert_equal '/GponForm/diag_Form', r.path
|
19
19
|
assert_equal({:'images/' => true}, r.query)
|
20
20
|
|
21
|
-
r = Qeweney.mock(':path' => '/?a=1&b=2')
|
21
|
+
r = Qeweney::MockAdapter.mock(':path' => '/?a=1&b=2')
|
22
22
|
assert_equal '/', r.path
|
23
23
|
assert_equal({a: '1', b: '2'}, r.query)
|
24
24
|
|
25
|
-
r = Qeweney.mock(':path' => '/?l=a&t=&x=42')
|
25
|
+
r = Qeweney::MockAdapter.mock(':path' => '/?l=a&t=&x=42')
|
26
26
|
assert_equal({l: 'a', t: '', x: '42'}, r.query)
|
27
27
|
end
|
28
28
|
|
29
29
|
def test_host
|
30
|
-
r = Qeweney.mock(':path' => '/')
|
30
|
+
r = Qeweney::MockAdapter.mock(':path' => '/')
|
31
31
|
assert_nil r.host
|
32
32
|
assert_nil r.authority
|
33
33
|
|
34
|
-
r = Qeweney.mock('host' => 'my.example.com')
|
34
|
+
r = Qeweney::MockAdapter.mock('host' => 'my.example.com')
|
35
35
|
assert_equal 'my.example.com', r.host
|
36
36
|
assert_equal 'my.example.com', r.authority
|
37
37
|
|
38
|
-
r = Qeweney.mock(':authority' => 'my.foo.com')
|
38
|
+
r = Qeweney::MockAdapter.mock(':authority' => 'my.foo.com')
|
39
39
|
assert_equal 'my.foo.com', r.host
|
40
40
|
assert_equal 'my.foo.com', r.authority
|
41
41
|
end
|
42
42
|
|
43
43
|
def test_full_uri
|
44
|
-
r = Qeweney.mock(
|
44
|
+
r = Qeweney::MockAdapter.mock(
|
45
45
|
':scheme' => 'https',
|
46
46
|
'host' => 'foo.bar',
|
47
47
|
':path' => '/hey?a=b&c=d'
|
@@ -51,11 +51,11 @@ class RequestInfoTest < MiniTest::Test
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def test_cookies
|
54
|
-
r = Qeweney.mock
|
54
|
+
r = Qeweney::MockAdapter.mock
|
55
55
|
|
56
56
|
assert_equal({}, r.cookies)
|
57
57
|
|
58
|
-
r = Qeweney.mock(
|
58
|
+
r = Qeweney::MockAdapter.mock(
|
59
59
|
'cookie' => 'uaid=a%2Fb; lastLocus=settings; signin_ref=/'
|
60
60
|
)
|
61
61
|
|
@@ -67,7 +67,7 @@ class RequestInfoTest < MiniTest::Test
|
|
67
67
|
end
|
68
68
|
|
69
69
|
def test_rewrite!
|
70
|
-
r = Qeweney.mock(
|
70
|
+
r = Qeweney::MockAdapter.mock(
|
71
71
|
':scheme' => 'https',
|
72
72
|
'host' => 'foo.bar',
|
73
73
|
':path' => '/hey/ho?a=b&c=d'
|
data/test/test_response.rb
CHANGED
@@ -2,27 +2,27 @@
|
|
2
2
|
|
3
3
|
require_relative 'helper'
|
4
4
|
|
5
|
-
class RedirectTest <
|
5
|
+
class RedirectTest < Minitest::Test
|
6
6
|
def test_redirect
|
7
|
-
r = Qeweney.mock
|
7
|
+
r = Qeweney::MockAdapter.mock
|
8
8
|
r.redirect('/foo')
|
9
9
|
|
10
10
|
assert_equal [
|
11
11
|
[:respond, r, nil, {":status"=>302, "Location"=>"/foo"}]
|
12
|
-
], r.
|
12
|
+
], r.adapter.calls
|
13
13
|
end
|
14
14
|
|
15
15
|
def test_redirect_wirth_status
|
16
|
-
r = Qeweney.mock
|
16
|
+
r = Qeweney::MockAdapter.mock
|
17
17
|
r.redirect('/bar', Qeweney::Status::MOVED_PERMANENTLY)
|
18
18
|
|
19
19
|
assert_equal [
|
20
20
|
[:respond, r, nil, {":status"=>301, "Location"=>"/bar"}]
|
21
|
-
], r.
|
21
|
+
], r.adapter.calls
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
class StaticFileResponeTest <
|
25
|
+
class StaticFileResponeTest < Minitest::Test
|
26
26
|
def setup
|
27
27
|
@path = File.join(__dir__, 'helper.rb')
|
28
28
|
@stat = File.stat(@path)
|
@@ -33,42 +33,42 @@ class StaticFileResponeTest < MiniTest::Test
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def test_serve_file
|
36
|
-
r = Qeweney.mock
|
36
|
+
r = Qeweney::MockAdapter.mock
|
37
37
|
r.serve_file('helper.rb', base_path: __dir__)
|
38
38
|
|
39
39
|
assert_equal [
|
40
40
|
[:respond, r, @content, { 'etag' => @etag, 'last-modified' => @last_modified }]
|
41
|
-
], r.
|
41
|
+
], r.adapter.calls
|
42
42
|
end
|
43
43
|
|
44
44
|
def test_serve_file_with_cache_headers
|
45
|
-
r = Qeweney.mock('if-none-match' => @etag)
|
45
|
+
r = Qeweney::MockAdapter.mock('if-none-match' => @etag)
|
46
46
|
r.serve_file('helper.rb', base_path: __dir__)
|
47
47
|
assert_equal [
|
48
48
|
[:respond, r, nil, { 'etag' => @etag, ':status' => Qeweney::Status::NOT_MODIFIED }]
|
49
|
-
], r.
|
49
|
+
], r.adapter.calls
|
50
50
|
|
51
|
-
r = Qeweney.mock('if-modified-since' => @last_modified)
|
51
|
+
r = Qeweney::MockAdapter.mock('if-modified-since' => @last_modified)
|
52
52
|
r.serve_file('helper.rb', base_path: __dir__)
|
53
53
|
assert_equal [
|
54
54
|
[:respond, r, nil, { 'etag' => @etag, ':status' => Qeweney::Status::NOT_MODIFIED }]
|
55
|
-
], r.
|
55
|
+
], r.adapter.calls
|
56
56
|
|
57
|
-
r = Qeweney.mock('if-none-match' => 'foobar')
|
57
|
+
r = Qeweney::MockAdapter.mock('if-none-match' => 'foobar')
|
58
58
|
r.serve_file('helper.rb', base_path: __dir__)
|
59
59
|
assert_equal [
|
60
60
|
[:respond, r, @content, { 'etag' => @etag, 'last-modified' => @last_modified }]
|
61
|
-
], r.
|
61
|
+
], r.adapter.calls
|
62
62
|
|
63
|
-
r = Qeweney.mock('if-modified-since' => Time.now.httpdate)
|
63
|
+
r = Qeweney::MockAdapter.mock('if-modified-since' => Time.now.httpdate)
|
64
64
|
r.serve_file('helper.rb', base_path: __dir__)
|
65
65
|
assert_equal [
|
66
66
|
[:respond, r, @content, { 'etag' => @etag, 'last-modified' => @last_modified }]
|
67
|
-
], r.
|
67
|
+
], r.adapter.calls
|
68
68
|
end
|
69
69
|
|
70
70
|
def test_serve_file_deflate
|
71
|
-
r = Qeweney.mock('accept-encoding' => 'deflate')
|
71
|
+
r = Qeweney::MockAdapter.mock('accept-encoding' => 'deflate')
|
72
72
|
r.serve_file('helper.rb', base_path: __dir__)
|
73
73
|
|
74
74
|
deflate = Zlib::Deflate.new
|
@@ -81,11 +81,11 @@ class StaticFileResponeTest < MiniTest::Test
|
|
81
81
|
'vary' => 'Accept-Encoding',
|
82
82
|
'content-encoding' => 'deflate'
|
83
83
|
}]
|
84
|
-
], r.
|
84
|
+
], r.adapter.calls
|
85
85
|
end
|
86
86
|
|
87
87
|
def test_serve_file_gzip
|
88
|
-
r = Qeweney.mock('accept-encoding' => 'gzip')
|
88
|
+
r = Qeweney::MockAdapter.mock('accept-encoding' => 'gzip')
|
89
89
|
r.serve_file('helper.rb', base_path: __dir__)
|
90
90
|
|
91
91
|
buf = StringIO.new
|
@@ -102,21 +102,21 @@ class StaticFileResponeTest < MiniTest::Test
|
|
102
102
|
'vary' => 'Accept-Encoding',
|
103
103
|
'content-encoding' => 'gzip'
|
104
104
|
}]
|
105
|
-
], r.
|
105
|
+
], r.adapter.calls
|
106
106
|
end
|
107
107
|
|
108
108
|
def test_serve_file_non_existent
|
109
|
-
r = Qeweney.mock
|
109
|
+
r = Qeweney::MockAdapter.mock
|
110
110
|
r.serve_file('foo.rb', base_path: __dir__)
|
111
111
|
assert_equal [
|
112
112
|
[:respond, r, nil, { ':status' => Qeweney::Status::NOT_FOUND }]
|
113
|
-
], r.
|
113
|
+
], r.adapter.calls
|
114
114
|
end
|
115
115
|
end
|
116
116
|
|
117
|
-
class UpgradeTest <
|
117
|
+
class UpgradeTest < Minitest::Test
|
118
118
|
def test_upgrade
|
119
|
-
r = Qeweney.mock
|
119
|
+
r = Qeweney::MockAdapter.mock
|
120
120
|
r.upgrade('df')
|
121
121
|
|
122
122
|
assert_equal [
|
@@ -125,10 +125,10 @@ class UpgradeTest < MiniTest::Test
|
|
125
125
|
'Upgrade' => 'df',
|
126
126
|
'Connection' => 'upgrade'
|
127
127
|
}]
|
128
|
-
], r.
|
128
|
+
], r.adapter.calls
|
129
129
|
|
130
130
|
|
131
|
-
r = Qeweney.mock
|
131
|
+
r = Qeweney::MockAdapter.mock
|
132
132
|
r.upgrade('df', { 'foo' => 'bar' })
|
133
133
|
|
134
134
|
assert_equal [
|
@@ -138,11 +138,11 @@ class UpgradeTest < MiniTest::Test
|
|
138
138
|
'Connection' => 'upgrade',
|
139
139
|
'foo' => 'bar'
|
140
140
|
}]
|
141
|
-
], r.
|
141
|
+
], r.adapter.calls
|
142
142
|
end
|
143
143
|
|
144
144
|
def test_websocket_upgrade
|
145
|
-
r = Qeweney.mock(
|
145
|
+
r = Qeweney::MockAdapter.mock(
|
146
146
|
'connection' => 'upgrade',
|
147
147
|
'upgrade' => 'websocket',
|
148
148
|
'sec-websocket-version' => '23',
|
@@ -163,13 +163,13 @@ class UpgradeTest < MiniTest::Test
|
|
163
163
|
'Sec-WebSocket-Accept' => accept
|
164
164
|
}],
|
165
165
|
[:websocket_connection, r]
|
166
|
-
], r.
|
166
|
+
], r.adapter.calls
|
167
167
|
end
|
168
168
|
end
|
169
169
|
|
170
|
-
class ServeRackTest <
|
170
|
+
class ServeRackTest < Minitest::Test
|
171
171
|
def test_serve_rack
|
172
|
-
r = Qeweney.mock(
|
172
|
+
r = Qeweney::MockAdapter.mock(
|
173
173
|
':method' => 'get',
|
174
174
|
':path' => '/foo/bar?a=1&b=2%2F3',
|
175
175
|
'accept' => 'blah'
|
@@ -180,6 +180,6 @@ class ServeRackTest < MiniTest::Test
|
|
180
180
|
|
181
181
|
assert_equal [
|
182
182
|
[:respond, r, 'GET /foo/bar', {':status' => 404, 'Foo' => 'Bar' }]
|
183
|
-
], r.
|
183
|
+
], r.adapter.calls
|
184
184
|
end
|
185
185
|
end
|
data/test/test_routing.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require_relative 'helper'
|
4
4
|
|
5
|
-
class RoutingTest <
|
5
|
+
class RoutingTest < Minitest::Test
|
6
6
|
App1 = ->(r) do
|
7
7
|
r.route do
|
8
8
|
r.on_root { r.redirect '/hello' }
|
@@ -18,29 +18,29 @@ class RoutingTest < MiniTest::Test
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def test_app1
|
21
|
-
r = Qeweney.mock(':path' => '/foo')
|
21
|
+
r = Qeweney::MockAdapter.mock(':path' => '/foo')
|
22
22
|
App1.(r)
|
23
|
-
assert_equal [[:respond, r, nil, { ':status' => 404 }]], r.
|
23
|
+
assert_equal [[:respond, r, nil, { ':status' => 404 }]], r.adapter.calls
|
24
24
|
|
25
|
-
r = Qeweney.mock(':path' => '/')
|
25
|
+
r = Qeweney::MockAdapter.mock(':path' => '/')
|
26
26
|
App1.(r)
|
27
|
-
assert_equal [[:respond, r, nil, { ':status' => 302, 'Location' => '/hello' }]], r.
|
27
|
+
assert_equal [[:respond, r, nil, { ':status' => 302, 'Location' => '/hello' }]], r.adapter.calls
|
28
28
|
|
29
|
-
r = Qeweney.mock(':path' => '/hello', ':method' => 'foo')
|
29
|
+
r = Qeweney::MockAdapter.mock(':path' => '/hello', ':method' => 'foo')
|
30
30
|
App1.(r)
|
31
|
-
assert_equal [[:respond, r, nil, { ':status' => 404 }]], r.
|
31
|
+
assert_equal [[:respond, r, nil, { ':status' => 404 }]], r.adapter.calls
|
32
32
|
|
33
|
-
r = Qeweney.mock(':path' => '/hello', ':method' => 'get')
|
33
|
+
r = Qeweney::MockAdapter.mock(':path' => '/hello', ':method' => 'get')
|
34
34
|
App1.(r)
|
35
|
-
assert_equal [[:respond, r, 'Hello', {}]], r.
|
35
|
+
assert_equal [[:respond, r, 'Hello', {}]], r.adapter.calls
|
36
36
|
|
37
|
-
r = Qeweney.mock(':path' => '/hello', ':method' => 'post')
|
37
|
+
r = Qeweney::MockAdapter.mock(':path' => '/hello', ':method' => 'post')
|
38
38
|
App1.(r)
|
39
|
-
assert_equal [[:respond, r, nil, { ':status' => 302, 'Location' => '/' }]], r.
|
39
|
+
assert_equal [[:respond, r, nil, { ':status' => 302, 'Location' => '/' }]], r.adapter.calls
|
40
40
|
|
41
|
-
r = Qeweney.mock(':path' => '/hello/world', ':method' => 'get')
|
41
|
+
r = Qeweney::MockAdapter.mock(':path' => '/hello/world', ':method' => 'get')
|
42
42
|
App1.(r)
|
43
|
-
assert_equal [[:respond, r, 'Hello world', {}]], r.
|
43
|
+
assert_equal [[:respond, r, 'Hello world', {}]], r.adapter.calls
|
44
44
|
end
|
45
45
|
|
46
46
|
def test_on_root
|
@@ -57,21 +57,21 @@ class RoutingTest < MiniTest::Test
|
|
57
57
|
}
|
58
58
|
end
|
59
59
|
|
60
|
-
r = Qeweney.mock(':path' => '/')
|
60
|
+
r = Qeweney::MockAdapter.mock(':path' => '/')
|
61
61
|
app.(r)
|
62
|
-
assert_equal [[:respond, r, 'root', {}]], r.
|
62
|
+
assert_equal [[:respond, r, 'root', {}]], r.adapter.calls
|
63
63
|
|
64
|
-
r = Qeweney.mock(':path' => '/foo')
|
64
|
+
r = Qeweney::MockAdapter.mock(':path' => '/foo')
|
65
65
|
app.(r)
|
66
|
-
assert_equal [[:respond, r, 'foo root', {}]], r.
|
66
|
+
assert_equal [[:respond, r, 'foo root', {}]], r.adapter.calls
|
67
67
|
|
68
|
-
r = Qeweney.mock(':path' => '/foo/bar')
|
68
|
+
r = Qeweney::MockAdapter.mock(':path' => '/foo/bar')
|
69
69
|
app.(r)
|
70
|
-
assert_equal [[:respond, r, 'bar root', {}]], r.
|
70
|
+
assert_equal [[:respond, r, 'bar root', {}]], r.adapter.calls
|
71
71
|
|
72
|
-
r = Qeweney.mock(':path' => '/foo/bar/baz')
|
72
|
+
r = Qeweney::MockAdapter.mock(':path' => '/foo/bar/baz')
|
73
73
|
app.(r)
|
74
|
-
assert_equal [[:respond, r, 'baz root', {}]], r.
|
74
|
+
assert_equal [[:respond, r, 'baz root', {}]], r.adapter.calls
|
75
75
|
end
|
76
76
|
|
77
77
|
def test_relative_path
|
@@ -88,31 +88,31 @@ class RoutingTest < MiniTest::Test
|
|
88
88
|
r.on('baz') { r.respond(r.route_relative_path) }
|
89
89
|
end
|
90
90
|
|
91
|
-
r = Qeweney.mock(':path' => '/')
|
91
|
+
r = Qeweney::MockAdapter.mock(':path' => '/')
|
92
92
|
app.(r)
|
93
93
|
assert_equal '/', default_relative_path
|
94
|
-
assert_equal [[:respond, r, 'ROOT/', {}]], r.
|
94
|
+
assert_equal [[:respond, r, 'ROOT/', {}]], r.adapter.calls
|
95
95
|
|
96
96
|
|
97
|
-
r = Qeweney.mock(':path' => '/foo/bar/baz')
|
97
|
+
r = Qeweney::MockAdapter.mock(':path' => '/foo/bar/baz')
|
98
98
|
app.(r)
|
99
99
|
assert_equal '/foo/bar/baz', default_relative_path
|
100
|
-
assert_equal [[:respond, r, 'FOO/bar/baz', {}]], r.
|
100
|
+
assert_equal [[:respond, r, 'FOO/bar/baz', {}]], r.adapter.calls
|
101
101
|
|
102
|
-
r = Qeweney.mock(':path' => '/bar/a/b/c')
|
102
|
+
r = Qeweney::MockAdapter.mock(':path' => '/bar/a/b/c')
|
103
103
|
app.(r)
|
104
104
|
assert_equal '/bar/a/b/c', default_relative_path
|
105
|
-
assert_equal [[:respond, r, 'BAR/a/b/c', {}]], r.
|
105
|
+
assert_equal [[:respond, r, 'BAR/a/b/c', {}]], r.adapter.calls
|
106
106
|
|
107
|
-
r = Qeweney.mock(':path' => '/bar/baz/b/c')
|
107
|
+
r = Qeweney::MockAdapter.mock(':path' => '/bar/baz/b/c')
|
108
108
|
app.(r)
|
109
109
|
assert_equal '/bar/baz/b/c', default_relative_path
|
110
|
-
assert_equal [[:respond, r, 'BAR/BAZ/b/c', {}]], r.
|
110
|
+
assert_equal [[:respond, r, 'BAR/BAZ/b/c', {}]], r.adapter.calls
|
111
111
|
|
112
|
-
r = Qeweney.mock(':path' => '/baz/d/e/f')
|
112
|
+
r = Qeweney::MockAdapter.mock(':path' => '/baz/d/e/f')
|
113
113
|
app.(r)
|
114
114
|
assert_equal '/baz/d/e/f', default_relative_path
|
115
|
-
assert_equal [[:respond, r, '/d/e/f', {}]], r.
|
115
|
+
assert_equal [[:respond, r, '/d/e/f', {}]], r.adapter.calls
|
116
116
|
end
|
117
117
|
|
118
118
|
def test_well_known
|
@@ -121,9 +121,9 @@ class RoutingTest < MiniTest::Test
|
|
121
121
|
r.default { r.respond('not found') }
|
122
122
|
end
|
123
123
|
|
124
|
-
r = Qeweney.mock(':path' => '/.well-known/acme-challenge/foo')
|
124
|
+
r = Qeweney::MockAdapter.mock(':path' => '/.well-known/acme-challenge/foo')
|
125
125
|
app.(r)
|
126
|
-
assert_equal [[:respond, r, '/foo', {}]], r.
|
126
|
+
assert_equal [[:respond, r, '/foo', {}]], r.adapter.calls
|
127
127
|
end
|
128
128
|
end
|
129
129
|
|
metadata
CHANGED
@@ -1,86 +1,84 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: qeweney
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.22'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sharon Rosner
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: escape_utils
|
15
14
|
requirement: !ruby/object:Gem::Requirement
|
16
15
|
requirements:
|
17
|
-
- -
|
16
|
+
- - '='
|
18
17
|
- !ruby/object:Gem::Version
|
19
18
|
version: 1.3.0
|
20
19
|
type: :runtime
|
21
20
|
prerelease: false
|
22
21
|
version_requirements: !ruby/object:Gem::Requirement
|
23
22
|
requirements:
|
24
|
-
- -
|
23
|
+
- - '='
|
25
24
|
- !ruby/object:Gem::Version
|
26
25
|
version: 1.3.0
|
27
26
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
27
|
+
name: benchmark-ips
|
29
28
|
requirement: !ruby/object:Gem::Requirement
|
30
29
|
requirements:
|
31
|
-
- -
|
30
|
+
- - '='
|
32
31
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
32
|
+
version: 2.14.0
|
34
33
|
type: :development
|
35
34
|
prerelease: false
|
36
35
|
version_requirements: !ruby/object:Gem::Requirement
|
37
36
|
requirements:
|
38
|
-
- -
|
37
|
+
- - '='
|
39
38
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
39
|
+
version: 2.14.0
|
41
40
|
- !ruby/object:Gem::Dependency
|
42
41
|
name: minitest
|
43
42
|
requirement: !ruby/object:Gem::Requirement
|
44
43
|
requirements:
|
45
|
-
- -
|
44
|
+
- - '='
|
46
45
|
- !ruby/object:Gem::Version
|
47
|
-
version: 5.
|
46
|
+
version: 5.25.4
|
48
47
|
type: :development
|
49
48
|
prerelease: false
|
50
49
|
version_requirements: !ruby/object:Gem::Requirement
|
51
50
|
requirements:
|
52
|
-
- -
|
51
|
+
- - '='
|
53
52
|
- !ruby/object:Gem::Version
|
54
|
-
version: 5.
|
53
|
+
version: 5.25.4
|
55
54
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
55
|
+
name: rake
|
57
56
|
requirement: !ruby/object:Gem::Requirement
|
58
57
|
requirements:
|
59
|
-
- -
|
58
|
+
- - '='
|
60
59
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
60
|
+
version: 13.2.1
|
62
61
|
type: :development
|
63
62
|
prerelease: false
|
64
63
|
version_requirements: !ruby/object:Gem::Requirement
|
65
64
|
requirements:
|
66
|
-
- -
|
65
|
+
- - '='
|
67
66
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
67
|
+
version: 13.2.1
|
69
68
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
69
|
+
name: listen
|
71
70
|
requirement: !ruby/object:Gem::Requirement
|
72
71
|
requirements:
|
73
|
-
- -
|
72
|
+
- - '='
|
74
73
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
74
|
+
version: 3.9.0
|
76
75
|
type: :development
|
77
76
|
prerelease: false
|
78
77
|
version_requirements: !ruby/object:Gem::Requirement
|
79
78
|
requirements:
|
80
|
-
- -
|
79
|
+
- - '='
|
81
80
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
83
|
-
description:
|
81
|
+
version: 3.9.0
|
84
82
|
email: sharon@noteflakes.com
|
85
83
|
executables: []
|
86
84
|
extensions: []
|
@@ -92,35 +90,35 @@ files:
|
|
92
90
|
- ".gitignore"
|
93
91
|
- CHANGELOG.md
|
94
92
|
- Gemfile
|
95
|
-
- Gemfile.lock
|
96
93
|
- LICENSE
|
97
94
|
- README.md
|
98
95
|
- Rakefile
|
99
96
|
- TODO.md
|
100
97
|
- examples/routing_benchmark.rb
|
101
98
|
- lib/qeweney.rb
|
99
|
+
- lib/qeweney/errors.rb
|
102
100
|
- lib/qeweney/mime_types.rb
|
101
|
+
- lib/qeweney/mock_adapter.rb
|
103
102
|
- lib/qeweney/rack.rb
|
104
103
|
- lib/qeweney/request.rb
|
105
104
|
- lib/qeweney/request_info.rb
|
106
105
|
- lib/qeweney/response.rb
|
107
106
|
- lib/qeweney/routing.rb
|
108
107
|
- lib/qeweney/status.rb
|
109
|
-
- lib/qeweney/test_adapter.rb
|
110
108
|
- lib/qeweney/version.rb
|
111
109
|
- qeweney.gemspec
|
112
110
|
- test/helper.rb
|
113
111
|
- test/run.rb
|
112
|
+
- test/run_loop.rb
|
113
|
+
- test/test_mock_adapter.rb
|
114
114
|
- test/test_request_info.rb
|
115
115
|
- test/test_response.rb
|
116
116
|
- test/test_routing.rb
|
117
|
-
- test/test_test_adapter.rb
|
118
117
|
homepage: https://github.com/digital-fabric/qeweney
|
119
118
|
licenses:
|
120
119
|
- MIT
|
121
120
|
metadata:
|
122
121
|
source_code_uri: https://github.com/digital-fabric/qeweney
|
123
|
-
post_install_message:
|
124
122
|
rdoc_options:
|
125
123
|
- "--title"
|
126
124
|
- Qeweney
|
@@ -139,8 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
139
137
|
- !ruby/object:Gem::Version
|
140
138
|
version: '0'
|
141
139
|
requirements: []
|
142
|
-
rubygems_version: 3.
|
143
|
-
signing_key:
|
140
|
+
rubygems_version: 3.6.9
|
144
141
|
specification_version: 4
|
145
142
|
summary: Qeweney - cross library HTTP request / response API
|
146
143
|
test_files: []
|
data/Gemfile.lock
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
qeweney (0.19)
|
5
|
-
escape_utils (~> 1.3.0)
|
6
|
-
|
7
|
-
GEM
|
8
|
-
remote: https://rubygems.org/
|
9
|
-
specs:
|
10
|
-
ansi (1.5.0)
|
11
|
-
benchmark-ips (2.8.4)
|
12
|
-
builder (3.3.0)
|
13
|
-
escape_utils (1.3.0)
|
14
|
-
minitest (5.11.3)
|
15
|
-
minitest-reporters (1.4.3)
|
16
|
-
ansi
|
17
|
-
builder
|
18
|
-
minitest (>= 5.0)
|
19
|
-
ruby-progressbar
|
20
|
-
rake (12.3.3)
|
21
|
-
ruby-progressbar (1.13.0)
|
22
|
-
|
23
|
-
PLATFORMS
|
24
|
-
ruby
|
25
|
-
x86_64-linux
|
26
|
-
|
27
|
-
DEPENDENCIES
|
28
|
-
benchmark-ips (~> 2.8.3)
|
29
|
-
minitest (~> 5.11.3)
|
30
|
-
minitest-reporters (~> 1.4.2)
|
31
|
-
qeweney!
|
32
|
-
rake (~> 12.3.3)
|
33
|
-
|
34
|
-
BUNDLED WITH
|
35
|
-
2.5.22
|
data/lib/qeweney/test_adapter.rb
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Qeweney
|
4
|
-
class TestAdapter
|
5
|
-
attr_reader :body, :headers
|
6
|
-
|
7
|
-
def get_body_chunk
|
8
|
-
nil
|
9
|
-
end
|
10
|
-
|
11
|
-
def respond(req, body, headers)
|
12
|
-
@body = body
|
13
|
-
@headers = headers
|
14
|
-
end
|
15
|
-
|
16
|
-
def status
|
17
|
-
headers[':status'] || Qeweney::Status::OK
|
18
|
-
end
|
19
|
-
|
20
|
-
def self.mock(headers = {})
|
21
|
-
headers[':method'] ||= ''
|
22
|
-
headers[':path'] ||= ''
|
23
|
-
Request.new(headers, new)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
data/test/test_test_adapter.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'helper'
|
4
|
-
require 'qeweney/test_adapter'
|
5
|
-
|
6
|
-
class TestAdapterTest < MiniTest::Test
|
7
|
-
def test_test_adapter
|
8
|
-
adapter = Qeweney::TestAdapter.new
|
9
|
-
req = Qeweney::Request.new({ ':path' => '/foo' }, adapter)
|
10
|
-
req.respond('bar', 'Content-Type' => 'baz')
|
11
|
-
|
12
|
-
assert_equal 'bar', adapter.body
|
13
|
-
assert_equal({'Content-Type' => 'baz'}, adapter.headers)
|
14
|
-
end
|
15
|
-
end
|