qeweney 0.14 → 0.15

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: 3f515f9637f0d993c9dfbea4d425695f76915871ad0c62e090cbb31a4a57b4a7
4
- data.tar.gz: 80a6bf6da6a0d2b85771deff0cb24ad9bcf389e4af37042a6fd62c215617a657
3
+ metadata.gz: a776c09a368fd3b348a685f43dcffb40320e6d181529427f7659e56815994735
4
+ data.tar.gz: 9ba936914a124c9a21923c147cf5d90b76cb6ea4dde46cbeeb558d99909a9d86
5
5
  SHA512:
6
- metadata.gz: d08170e772a3fad93d49a06bc8ee6c656e5057e5368d3dfba6687d1f838dff50e7cfb8895315480f3f85ea519d8ee0ae20a3a480ee26293bd86bfec2c4912918
7
- data.tar.gz: a1918424e95a70891eb4f8fb1b163cdf62167bb3847c16192be9f8dffd95c77513cca4f0e6d4a759275b14bc7891d770585b3625b4601177195ade7a731f6814
6
+ metadata.gz: 9f49f57a3c037646789565e1adb8c5ba129b1ed7e3f7b2ddbc3ec6a11c150d9e946728fcb2912af84c69070c1cefab00be707aed104b5eda2a7a9845cc14c5b8
7
+ data.tar.gz: 214702b726cb0c4c18fd380f3d4d985955002bad65a7e80ac0072da78d2014eea8a0c604256deefaab9c5adbb77fec0c155397df9dbcd868b2410f13a884e89a
@@ -0,0 +1 @@
1
+ github: ciconia
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## 0.15 2022-01-08
2
+
3
+ - Add `TestAdapter` class for testing requests and responses
4
+ - Add `RoutingMethods#reject` method
5
+
1
6
  ## 0.14 2021-08-10
2
7
 
3
8
  - Fix Request#on with paths containing slashes
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- qeweney (0.14)
4
+ qeweney (0.15)
5
5
  escape_utils (~> 1.2.1)
6
6
 
7
7
  GEM
@@ -21,7 +21,7 @@ GEM
21
21
  ruby-progressbar (1.11.0)
22
22
 
23
23
  PLATFORMS
24
- ruby
24
+ x86_64-linux
25
25
 
26
26
  DEPENDENCIES
27
27
  benchmark-ips (~> 2.8.3)
@@ -31,4 +31,4 @@ DEPENDENCIES
31
31
  rake (~> 12.3.3)
32
32
 
33
33
  BUNDLED WITH
34
- 2.1.4
34
+ 2.3.3
@@ -104,7 +104,7 @@ OptimizedRubyApp = ->(r) do
104
104
  else
105
105
  return r.respond('Hello')
106
106
  end
107
- elsif method == 'post'
107
+ elsif method == 'post'
108
108
  # puts 'Someone said Hello'
109
109
  return r.redirect('/')
110
110
  end
data/lib/qeweney/rack.rb CHANGED
@@ -74,15 +74,15 @@ module Qeweney
74
74
  def initialize(request)
75
75
  @request = request
76
76
  end
77
-
77
+
78
78
  def gets; end
79
-
79
+
80
80
  def read(length = nil, outbuf = nil); end
81
-
81
+
82
82
  def each(&block)
83
83
  @request.each_chunk(&block)
84
84
  end
85
-
85
+
86
86
  def rewind; end
87
87
  end
88
88
 
@@ -110,7 +110,7 @@ module Qeweney
110
110
  'rack.multipart.buffer_size' => nil,
111
111
  'rack.multipar.tempfile_factory' => nil
112
112
  }
113
-
113
+
114
114
  HTTP_HEADER_RE = /^HTTP_(.+)$/.freeze
115
115
 
116
116
  def self.rack_env_value_from_request(request, key)
@@ -15,13 +15,12 @@ module Qeweney
15
15
  extend RequestInfoClassMethods
16
16
 
17
17
  attr_reader :headers, :adapter
18
- attr_accessor :__next__
19
-
18
+
20
19
  def initialize(headers, adapter)
21
20
  @headers = headers
22
21
  @adapter = adapter
23
22
  end
24
-
23
+
25
24
  def buffer_body_chunk(chunk)
26
25
  @buffered_body_chunks ||= []
27
26
  @buffered_body_chunks << chunk
@@ -38,7 +37,7 @@ module Qeweney
38
37
 
39
38
  @adapter.get_body_chunk(self, buffered_only)
40
39
  end
41
-
40
+
42
41
  def each_chunk
43
42
  if @buffered_body_chunks
44
43
  while (chunk = @buffered_body_chunks.shift)
@@ -68,29 +67,29 @@ module Qeweney
68
67
  def complete?
69
68
  @adapter.complete?(self)
70
69
  end
71
-
70
+
72
71
  def respond(body, headers = {})
73
72
  @adapter.respond(self, body, headers)
74
73
  @headers_sent = true
75
74
  end
76
-
75
+
77
76
  def send_headers(headers = {}, empty_response = false)
78
77
  return if @headers_sent
79
-
78
+
80
79
  @headers_sent = true
81
80
  @adapter.send_headers(self, headers, empty_response: empty_response)
82
81
  end
83
-
82
+
84
83
  def send_chunk(body, done: false)
85
84
  send_headers({}) unless @headers_sent
86
-
85
+
87
86
  @adapter.send_chunk(self, body, done: done)
88
87
  end
89
88
  alias_method :<<, :send_chunk
90
-
89
+
91
90
  def finish
92
91
  send_headers({}) unless @headers_sent
93
-
92
+
94
93
  @adapter.finish(self)
95
94
  end
96
95
 
@@ -25,39 +25,39 @@ module Qeweney
25
25
  def protocol
26
26
  @protocol ||= @adapter.protocol
27
27
  end
28
-
28
+
29
29
  def method
30
30
  @method ||= @headers[':method'].downcase
31
31
  end
32
-
32
+
33
33
  def scheme
34
34
  @scheme ||= @headers[':scheme']
35
35
  end
36
-
36
+
37
37
  def uri
38
38
  @uri ||= URI.parse(@headers[':path'] || '')
39
39
  end
40
-
40
+
41
41
  def full_uri
42
42
  @full_uri = "#{scheme}://#{host}#{uri}"
43
43
  end
44
-
44
+
45
45
  def path
46
46
  @path ||= uri.path
47
47
  end
48
-
48
+
49
49
  def query_string
50
50
  @query_string ||= uri.query
51
51
  end
52
-
52
+
53
53
  def query
54
54
  return @query if @query
55
-
55
+
56
56
  @query = (q = uri.query) ? parse_query(q) : {}
57
57
  end
58
-
58
+
59
59
  QUERY_KV_REGEXP = /([^=]+)(?:=(.*))?/
60
-
60
+
61
61
  def parse_query(query)
62
62
  query.split('&').each_with_object({}) do |kv, h|
63
63
  k, v = kv.match(QUERY_KV_REGEXP)[1..2]
@@ -89,13 +89,13 @@ module Qeweney
89
89
 
90
90
  COOKIE_RE = /^([^=]+)=(.*)$/.freeze
91
91
  SEMICOLON = ';'
92
-
92
+
93
93
  def parse_cookies(cookies)
94
94
  return {} unless cookies
95
95
 
96
96
  cookies.split(SEMICOLON).each_with_object({}) do |c, h|
97
97
  raise BadRequestError, 'Invalid cookie format' unless c.strip =~ COOKIE_RE
98
-
98
+
99
99
  key, value = Regexp.last_match[1..2]
100
100
  h[key] = EscapeUtils.unescape_uri(value)
101
101
  end
@@ -151,7 +151,7 @@ module Qeweney
151
151
  break if header.empty?
152
152
 
153
153
  next unless header =~ /^([^\:]+)\:\s?(.+)$/
154
-
154
+
155
155
  headers[Regexp.last_match(1).downcase] = Regexp.last_match(2)
156
156
  end
157
157
  # remove trailing \r\n
@@ -169,13 +169,13 @@ module Qeweney
169
169
  body.force_encoding(Encoding::UTF_8) unless body.encoding == Encoding::UTF_8
170
170
  body.split('&').each_with_object({}) do |i, m|
171
171
  raise 'Invalid parameter format' unless i =~ PARAMETER_RE
172
-
172
+
173
173
  k = Regexp.last_match(1)
174
174
  raise 'Invalid parameter size' if k.size > MAX_PARAMETER_NAME_SIZE
175
-
175
+
176
176
  v = Regexp.last_match(2)
177
177
  raise 'Invalid parameter size' if v.size > MAX_PARAMETER_VALUE_SIZE
178
-
178
+
179
179
  m[EscapeUtils.unescape_uri(k)] = EscapeUtils.unescape_uri(v)
180
180
  end
181
181
  end
@@ -14,7 +14,7 @@ module Qeweney
14
14
  def file_stat_to_etag(stat)
15
15
  "#{stat.mtime.to_i.to_s(36)}#{stat.size.to_s(36)}"
16
16
  end
17
-
17
+
18
18
  def file_stat_to_last_modified(stat)
19
19
  stat.mtime.httpdate
20
20
  end
@@ -114,7 +114,7 @@ module Qeweney
114
114
  if (modified_since = headers['if-modified-since'])
115
115
  return true if modified_since == last_modified
116
116
  end
117
-
117
+
118
118
  false
119
119
  end
120
120
 
@@ -10,7 +10,7 @@ module Qeweney
10
10
  (@path_parts ||= path.split('/'))[@path_parts_idx ||= 1]
11
11
  res = catch(:stop) { yield self }
12
12
  return if res == :found
13
-
13
+
14
14
  respond(nil, ':status' => 404)
15
15
  end
16
16
 
@@ -39,11 +39,11 @@ module Qeweney
39
39
 
40
40
  def on(route, &block)
41
41
  return route_found(&block) unless route
42
-
42
+
43
43
  route_parts = route.split('/')
44
44
  route_length = route_parts.size
45
45
  return unless @path_parts[@path_parts_idx, route_length] == route_parts
46
-
46
+
47
47
  enter_route(route_length)
48
48
  route_found(&block)
49
49
  leave_route(route_length)
@@ -72,22 +72,22 @@ module Qeweney
72
72
 
73
73
  route_found(&block)
74
74
  end
75
-
75
+
76
76
  def on_get(route = nil, &block)
77
77
  return unless method == 'get'
78
-
78
+
79
79
  on(route, &block)
80
80
  end
81
-
81
+
82
82
  def on_post(route = nil, &block)
83
83
  return unless method == 'post'
84
-
84
+
85
85
  on(route, &block)
86
86
  end
87
87
 
88
88
  def on_options(route = nil, &block)
89
89
  return unless method == 'options'
90
-
90
+
91
91
  on(route, &block)
92
92
  end
93
93
 
@@ -124,6 +124,11 @@ module Qeweney
124
124
  on_upgrade('websocket', &block)
125
125
  end
126
126
 
127
+ def reject(body, status)
128
+ respond(body, ':status' => status)
129
+ throw :stop, :found
130
+ end
131
+
127
132
  def stop_routing
128
133
  throw :stop, :found
129
134
  end
@@ -5,7 +5,7 @@ module Qeweney
5
5
  module Status
6
6
  # translated from https://golang.org/pkg/net/http/#pkg-constants
7
7
  # https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
8
-
8
+
9
9
  CONTINUE = 100 # RFC 7231, 6.2.1
10
10
  SWITCHING_PROTOCOLS = 101 # RFC 7231, 6.2.2
11
11
  PROCESSING = 102 # RFC 2518, 10.1
@@ -0,0 +1,26 @@
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']
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,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Qeweney
4
- VERSION = '0.14'
4
+ VERSION = '0.15'
5
5
  end
data/lib/qeweney.rb CHANGED
@@ -5,4 +5,3 @@ end
5
5
 
6
6
  require_relative 'qeweney/request.rb'
7
7
  require_relative 'qeweney/status.rb'
8
-
data/test/helper.rb CHANGED
@@ -8,7 +8,6 @@ require 'fileutils'
8
8
  require_relative './coverage' if ENV['COVERAGE']
9
9
 
10
10
  require 'minitest/autorun'
11
- require 'minitest/reporters'
12
11
 
13
12
  module Qeweney
14
13
  class MockAdapter
@@ -35,7 +34,3 @@ module Qeweney
35
34
  end
36
35
  end
37
36
  end
38
-
39
- Minitest::Reporters.use! [
40
- Minitest::Reporters::SpecReporter.new
41
- ]
@@ -73,7 +73,7 @@ class StaticFileResponeTest < MiniTest::Test
73
73
 
74
74
  deflate = Zlib::Deflate.new
75
75
  deflated_content = deflate.deflate(@content, Zlib::FINISH)
76
-
76
+
77
77
  assert_equal [
78
78
  [:respond, r, deflated_content, {
79
79
  'etag' => @etag,
@@ -94,7 +94,7 @@ class StaticFileResponeTest < MiniTest::Test
94
94
  z.flush
95
95
  z.close
96
96
  gzipped_content = buf.string
97
-
97
+
98
98
  assert_equal [
99
99
  [:respond, r, gzipped_content, {
100
100
  'etag' => @etag,
@@ -127,7 +127,7 @@ class UpgradeTest < MiniTest::Test
127
127
  }]
128
128
  ], r.response_calls
129
129
 
130
-
130
+
131
131
  r = Qeweney.mock
132
132
  r.upgrade('df', { 'foo' => 'bar' })
133
133
 
@@ -148,7 +148,7 @@ class UpgradeTest < MiniTest::Test
148
148
  'sec-websocket-version' => '23',
149
149
  'sec-websocket-key' => 'abcdefghij'
150
150
  )
151
-
151
+
152
152
  assert_equal 'websocket', r.upgrade_protocol
153
153
 
154
154
  r.upgrade_to_websocket('foo' => 'baz')
data/test/test_routing.rb CHANGED
@@ -81,7 +81,7 @@ class RoutingTest < MiniTest::Test
81
81
  default_relative_path = r.route_relative_path
82
82
  r.on_root { r.respond(File.join('ROOT', r.route_relative_path)) }
83
83
  r.on('foo') { r.respond(File.join('FOO', r.route_relative_path)) }
84
- r.on('bar') {
84
+ r.on('bar') {
85
85
  r.on('baz') { r.respond(File.join('BAR/BAZ', r.route_relative_path)) }
86
86
  r.default { r.respond(File.join('BAR', r.route_relative_path)) }
87
87
  }
@@ -0,0 +1,15 @@
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
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.14'
4
+ version: '0.15'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sharon Rosner
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-08-10 00:00:00.000000000 Z
11
+ date: 2022-01-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: escape_utils
@@ -80,13 +80,14 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: 2.8.3
83
- description:
83
+ description:
84
84
  email: sharon@noteflakes.com
85
85
  executables: []
86
86
  extensions: []
87
87
  extra_rdoc_files:
88
88
  - README.md
89
89
  files:
90
+ - ".github/FUNDING.yml"
90
91
  - ".github/workflows/test.yml"
91
92
  - ".gitignore"
92
93
  - CHANGELOG.md
@@ -105,6 +106,7 @@ files:
105
106
  - lib/qeweney/response.rb
106
107
  - lib/qeweney/routing.rb
107
108
  - lib/qeweney/status.rb
109
+ - lib/qeweney/test_adapter.rb
108
110
  - lib/qeweney/version.rb
109
111
  - qeweney.gemspec
110
112
  - test/helper.rb
@@ -112,12 +114,13 @@ files:
112
114
  - test/test_request_info.rb
113
115
  - test/test_response.rb
114
116
  - test/test_routing.rb
117
+ - test/test_test_adapter.rb
115
118
  homepage: http://github.com/digital-fabric/qeweney
116
119
  licenses:
117
120
  - MIT
118
121
  metadata:
119
122
  source_code_uri: https://github.com/digital-fabric/qeweney
120
- post_install_message:
123
+ post_install_message:
121
124
  rdoc_options:
122
125
  - "--title"
123
126
  - Qeweney
@@ -136,8 +139,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
136
139
  - !ruby/object:Gem::Version
137
140
  version: '0'
138
141
  requirements: []
139
- rubygems_version: 3.1.6
140
- signing_key:
142
+ rubygems_version: 3.3.3
143
+ signing_key:
141
144
  specification_version: 4
142
145
  summary: Qeweney - cross library HTTP request / response API
143
146
  test_files: []