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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f7cccd729e2db47b7cbf560dcd58615a97a97d4305c7edde20be1771d1a44571
4
- data.tar.gz: d386ad5b4713412f22e4d02248717f27fa8a7ccd2ec289abc132b9931b299d9a
3
+ metadata.gz: 83fd3aeea3a2ab2fff17ca871189e60098168523583b801423a6d2ecd21d5a9f
4
+ data.tar.gz: 53dcc37653949d20a6324d5e24df1f5b827a56ce134dd69c168369242917f825
5
5
  SHA512:
6
- metadata.gz: 1d12923a83b5d33a2e5503e1c164cfcec5b6de862d2e049b784cf8a6b8055e442b5c67f2892013ca3eaad90cf03f62176b076680b05f6a510535ca85a087746c
7
- data.tar.gz: 7fd3a28276cbf48044c32d5f11e3a0b2b665df4ba2405c7ead715f5641fa727a4c3c6bfb2b45856c1034613fa97c9e2e0c768e67ecd43a71d6e6a35923cad4a8
6
+ metadata.gz: 3cee5ee51f356cddcff578d2cd2e582ea0f293ce2d898e43022fe9ab83d0e812423473f047701306796f70ac53833818b125f7308a438c6a05d18a00465e9e93
7
+ data.tar.gz: 6de0f052bc1077e665d5c5bd3f6fc8de59442e5944ddc68c3b9ceca873cfdd2e6ed47880bb5e0a89dbb36cbfc802936f3f15c121e82e59922515f000bd5d7b31
@@ -8,7 +8,7 @@ jobs:
8
8
  fail-fast: false
9
9
  matrix:
10
10
  os: [ubuntu-latest]
11
- ruby: ['3.0', 3.1, 3.2]
11
+ ruby: [3.2, 3.3, 3.4]
12
12
 
13
13
  name: >-
14
14
  ${{matrix.os}}, ${{matrix.ruby}}
data/.gitignore CHANGED
@@ -45,7 +45,7 @@ build-iPhoneSimulator/
45
45
 
46
46
  # for a library or gem, you might want to ignore these files since the code is
47
47
  # intended to run in multiple environments; otherwise, check them in:
48
- # Gemfile.lock
48
+ Gemfile.lock
49
49
  # .ruby-version
50
50
  # .ruby-gemset
51
51
 
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ## 0.22 2025-08-28
2
+
3
+ - Improve form data parsing.
4
+ - Add `Qeweney::BadRequestError` exception class.
5
+
6
+ ## 0.20 2025-01-09
7
+
8
+ - Improve `Qeweney::MockAdapter`.
9
+
1
10
  ## 0.18 2022-02-16
2
11
 
3
12
  - Implement `Request#rewrite!` (#2)
data/TODO.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## Immediate
2
+
3
+ - [ ] Tests for `#parse_form_data`!
4
+
1
5
  ## Serve files / arbitrary content
2
6
 
3
7
  - `#serve_file(path, opts)`
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Qeweney
4
+ class BadRequestError < StandardError
5
+ end
6
+ end
@@ -35,4 +35,4 @@ module Qeweney
35
35
  end
36
36
  end
37
37
  end
38
- end
38
+ end
@@ -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
@@ -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
@@ -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 = /^(.+)=(.*)$/.freeze
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Qeweney
4
- VERSION = '0.20'
4
+ VERSION = '0.22'
5
5
  end
data/lib/qeweney.rb CHANGED
@@ -3,5 +3,6 @@
3
3
  module Qeweney
4
4
  end
5
5
 
6
- require_relative 'qeweney/request.rb'
7
- require_relative 'qeweney/status.rb'
6
+ require_relative 'qeweney/errors'
7
+ require_relative 'qeweney/request'
8
+ require_relative 'qeweney/status'
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
- "source_code_uri" => "https://github.com/digital-fabric/qeweney"
13
+ 'source_code_uri' => 'https://github.com/digital-fabric/qeweney'
14
14
  }
15
- s.rdoc_options = ["--title", "Qeweney", "--main", "README.md"]
16
- s.extra_rdoc_files = ["README.md"]
17
- s.require_paths = ["lib"]
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', '~>1.3.0'
20
+ s.add_runtime_dependency 'escape_utils', '1.3.0'
21
21
 
22
- s.add_development_dependency 'rake', '~>12.3.3'
23
- s.add_development_dependency 'minitest', '~>5.11.3'
24
- s.add_development_dependency 'minitest-reporters', '~>1.4.2'
25
- s.add_development_dependency 'benchmark-ips', '~>2.8.3'
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
- module Qeweney
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
@@ -2,46 +2,46 @@
2
2
 
3
3
  require_relative 'helper'
4
4
 
5
- class RequestInfoTest < MiniTest::Test
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'
@@ -2,27 +2,27 @@
2
2
 
3
3
  require_relative 'helper'
4
4
 
5
- class RedirectTest < MiniTest::Test
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.response_calls
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.response_calls
21
+ ], r.adapter.calls
22
22
  end
23
23
  end
24
24
 
25
- class StaticFileResponeTest < MiniTest::Test
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.response_calls
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.response_calls
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.response_calls
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.response_calls
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.response_calls
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.response_calls
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.response_calls
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.response_calls
113
+ ], r.adapter.calls
114
114
  end
115
115
  end
116
116
 
117
- class UpgradeTest < MiniTest::Test
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.response_calls
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.response_calls
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.response_calls
166
+ ], r.adapter.calls
167
167
  end
168
168
  end
169
169
 
170
- class ServeRackTest < MiniTest::Test
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.response_calls
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 < MiniTest::Test
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.response_calls
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.response_calls
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.response_calls
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.response_calls
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.response_calls
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.response_calls
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.response_calls
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.response_calls
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.response_calls
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.response_calls
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.response_calls
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.response_calls
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.response_calls
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.response_calls
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.response_calls
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.response_calls
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.20'
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: 2024-12-16 00:00:00.000000000 Z
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: rake
27
+ name: benchmark-ips
29
28
  requirement: !ruby/object:Gem::Requirement
30
29
  requirements:
31
- - - "~>"
30
+ - - '='
32
31
  - !ruby/object:Gem::Version
33
- version: 12.3.3
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: 12.3.3
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.11.3
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.11.3
53
+ version: 5.25.4
55
54
  - !ruby/object:Gem::Dependency
56
- name: minitest-reporters
55
+ name: rake
57
56
  requirement: !ruby/object:Gem::Requirement
58
57
  requirements:
59
- - - "~>"
58
+ - - '='
60
59
  - !ruby/object:Gem::Version
61
- version: 1.4.2
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: 1.4.2
67
+ version: 13.2.1
69
68
  - !ruby/object:Gem::Dependency
70
- name: benchmark-ips
69
+ name: listen
71
70
  requirement: !ruby/object:Gem::Requirement
72
71
  requirements:
73
- - - "~>"
72
+ - - '='
74
73
  - !ruby/object:Gem::Version
75
- version: 2.8.3
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: 2.8.3
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.5.16
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
@@ -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
@@ -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