hanami-router 2.0.0.alpha3 → 2.0.0.alpha4

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: fab23d35a0e2c1e71ec08a112f95f35a2c21eed5fb3ab45f231a2a7fc500cc31
4
- data.tar.gz: 85c7e6ab36e321fb04235f088f3f479f542e98cf00e5ae7d642bb323bb42d969
3
+ metadata.gz: a855344a3dcd5d256259802c803eae8c7e41aeaeda1f108855d668458ec6c32d
4
+ data.tar.gz: 79f333141e1453d4bd4c4f4e09fd41e54bb2cab94d3889268a6a765ec9d52a16
5
5
  SHA512:
6
- metadata.gz: 2ce90e7659b29b0571742eb972442ea27a4d51d1ea5500f9d25f943fe7e6a5e9b04598a1289a4c50f107289ea7162708a78e4825564b4ef056ee30a5765a63d6
7
- data.tar.gz: b953c5d251e8cfb6f698bb6cea77df0dec2ff194bf51fe091d7fb4464ffad135c0760d328f9e50ae49f6cd48c45171b6ef4c55dc42f64c924cfd6d631cde5250
6
+ metadata.gz: 1dc165c33814c2869852526395de10368b14918b09af6d4dbac56e2610f6ae8dcd8e78eb1034e0b858a48e30d80470976af692e1a235cb58a54561c1dc7393b7
7
+ data.tar.gz: a73e23f4d0875143660610be0b8e349be143dcdbed62a258070d0b1973ee876c57b68ae8df90f1fc786bf9e689ec40a16ced52053dbd16f893efe4b62fa70e85
@@ -1,6 +1,12 @@
1
1
  # Hanami::Router
2
2
  Rack compatible HTTP router for Ruby
3
3
 
4
+ ## v2.0.0.alpha4 - 2021-01-16
5
+ ### Added
6
+ - [Luca Guidi] Official support for MRI 3.0
7
+ - [Luca Guidi] Introduced `Hanami::Middleware::BodyParser::Parser` as superclass for body parsers
8
+ - [Paweł Świątkowski] Added `not_found:` option to `Hanami::Router#initialize` to customize HTTP 404 status
9
+
4
10
  ## v2.0.0.alpha3 - 2020-05-20
5
11
  ### Fixed
6
12
  - [Luca Guidi] `Hanami::Router#initialize` do not yield block if not given
data/LICENSE.md CHANGED
@@ -1,4 +1,4 @@
1
- Copyright © 2014-2017 Luca Guidi
1
+ Copyright © 2014-2021 Luca Guidi
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -5,9 +5,8 @@ Rack compatible, lightweight and fast HTTP Router for Ruby and [Hanami](http://h
5
5
  ## Status
6
6
 
7
7
  [![Gem Version](https://badge.fury.io/rb/hanami-router.svg)](https://badge.fury.io/rb/hanami-router)
8
- [![Build Status](https://ci.hanamirb.org/api/badges/hanami/router/status.svg)](https://ci.hanamirb.org/hanami/router)
9
- [![CircleCI](https://circleci.com/gh/hanami/router/tree/master.svg?style=svg)](https://circleci.com/gh/hanami/router/tree/master)
10
- [![Test Coverage](https://codecov.io/gh/hanami/router/branch/master/graph/badge.svg)](https://codecov.io/gh/hanami/router)
8
+ [![CI](https://github.com/hanami/router/workflows/ci/badge.svg?branch=unstable)](https://github.com/hanami/router/actions?query=workflow%3Aci+branch%3Aunstable)
9
+ [![Test Coverage](https://codecov.io/gh/hanami/router/branch/unstable/graph/badge.svg)](https://codecov.io/gh/hanami/router)
11
10
  [![Depfu](https://badges.depfu.com/badges/5f6b8e8fa3b0d082539f0b0f84d55960/overview.svg)](https://depfu.com/github/hanami/router?project=Bundler)
12
11
  [![Inline Docs](http://inch-ci.org/github/hanami/router.svg)](http://inch-ci.org/github/hanami/router)
13
12
 
@@ -22,7 +21,7 @@ Rack compatible, lightweight and fast HTTP Router for Ruby and [Hanami](http://h
22
21
 
23
22
  ## Rubies
24
23
 
25
- __Hanami::Router__ supports Ruby (MRI) 2.5+
24
+ __Hanami::Router__ supports Ruby (MRI) 2.6+
26
25
 
27
26
 
28
27
  ## Installation
@@ -225,6 +224,13 @@ router = Hanami::Router.new
225
224
  router.call(Rack::MockRequest.env_for("/unknown")).status # => 404
226
225
  ```
227
226
 
227
+ ### Explicit Not Found:
228
+
229
+ ```ruby
230
+ router = Hanami::Router.new(not_found: ->(_) { [499, {}, []]})
231
+ router.call(Rack::MockRequest.env_for("/unknown")).status # => 499
232
+ ```
233
+
228
234
  ### Body Parsers
229
235
 
230
236
  Rack ignores request bodies unless they come from a form submission.
@@ -355,6 +361,6 @@ __Hanami::Router__ uses [Semantic Versioning 2.0.0](http://semver.org)
355
361
 
356
362
  ## Copyright
357
363
 
358
- Copyright © 2014-2020 Luca Guidi – Released under MIT License
364
+ Copyright © 2014-2021 Luca Guidi – Released under MIT License
359
365
 
360
366
  This project was formerly known as Lotus (`lotus-router`).
@@ -14,11 +14,11 @@ Gem::Specification.new do |spec|
14
14
  spec.homepage = "http://hanamirb.org"
15
15
  spec.license = "MIT"
16
16
 
17
- spec.files = `git ls-files -- lib/* CHANGELOG.md LICENSE.md README.md hanami-router.gemspec`.split($INPUT_RECORD_SEPARATOR)
17
+ spec.files = `git ls-files -- lib/* CHANGELOG.md LICENSE.md README.md hanami-router.gemspec`.split($/)
18
18
  spec.executables = []
19
19
  spec.test_files = spec.files.grep(%r{^(test)/})
20
20
  spec.require_paths = ["lib"]
21
- spec.required_ruby_version = ">= 2.5.0"
21
+ spec.required_ruby_version = ">= 2.6.0"
22
22
 
23
23
  spec.add_dependency "rack", "~> 2.0"
24
24
  spec.add_dependency "mustermann", "~> 1.0"
@@ -28,4 +28,7 @@ Gem::Specification.new do |spec|
28
28
  spec.add_development_dependency "rake", "~> 13"
29
29
  spec.add_development_dependency "rack-test", "~> 1.0"
30
30
  spec.add_development_dependency "rspec", "~> 3.8"
31
+
32
+ spec.add_development_dependency "rubocop", "0.91"
33
+ spec.add_development_dependency "rubocop-performance", "1.8.1"
31
34
  end
@@ -2,13 +2,15 @@
2
2
 
3
3
  require "hanami/router/params"
4
4
  require "hanami/middleware/error"
5
- require_relative "body_parser/class_interface"
6
5
 
7
6
  module Hanami
8
7
  module Middleware
9
8
  # @since 1.3.0
10
9
  # @api private
11
10
  class BodyParser
11
+ require_relative "body_parser/class_interface"
12
+ require_relative "body_parser/parser"
13
+
12
14
  # @since 1.3.0
13
15
  # @api private
14
16
  CONTENT_TYPE = "CONTENT_TYPE"
@@ -72,7 +74,7 @@ module Hanami
72
74
  if body.is_a?(::Hash)
73
75
  Router::Params.deep_symbolize(body)
74
76
  else
75
- { FALLBACK_KEY => body }
77
+ {FALLBACK_KEY => body}
76
78
  end
77
79
  end
78
80
 
@@ -11,7 +11,7 @@ module Hanami
11
11
  module ClassInterface
12
12
  # @api private
13
13
  # @since 1.3.0
14
- def for(parser) # rubocop:disable Metrics/MethodLength
14
+ def for(parser)
15
15
  parser =
16
16
  case parser
17
17
  when String, Symbol
@@ -1,14 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "json"
4
- require_relative "errors"
4
+ require_relative "parser"
5
5
 
6
6
  module Hanami
7
7
  module Middleware
8
8
  class BodyParser
9
9
  # @since 1.3.0
10
10
  # @api private
11
- class JsonParser
11
+ class JsonParser < Parser
12
12
  # @since 1.3.0
13
13
  # @api private
14
14
  def mime_types
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hanami
4
+ module Middleware
5
+ class BodyParser
6
+ # Body parser abstract class
7
+ #
8
+ # @since 2.0.0
9
+ class Parser
10
+ # Declare supported MIME types
11
+ #
12
+ # @return [Array<String>] supported MIME types
13
+ #
14
+ # @abstract
15
+ # @since 2.0.0
16
+ #
17
+ # @example
18
+ # require "hanami/middleware/body_parser"
19
+ #
20
+ # class XMLParser < Hanami::Middleware::BodyParser::Parser
21
+ # def mime_types
22
+ # ["application/xml", "text/xml"]
23
+ # end
24
+ # end
25
+ def mime_types
26
+ raise NotImplementedError
27
+ end
28
+
29
+ # Parse raw HTTP request body
30
+ #
31
+ # @param body [String] HTTP request body
32
+ #
33
+ # @return [Hash] the result of the parsing
34
+ #
35
+ # @raise [Hanami::Middleware::BodyParser::BodyParsingError] the error
36
+ # that must be raised if the parsing cannot be accomplished
37
+ #
38
+ # @abstract
39
+ # @since 2.0.0
40
+ #
41
+ # @example
42
+ # require "hanami/middleware/body_parser"
43
+ #
44
+ # class XMLParser < Hanami::Middleware::BodyParser::Parser
45
+ # def parse(body)
46
+ # # XML parsing
47
+ # # ...
48
+ # rescue => exception
49
+ # raise Hanami::Middleware::BodyParser::BodyParsingError.new(exception.message)
50
+ # end
51
+ # end
52
+ def parse(body)
53
+ raise NotImplementedError
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -6,7 +6,7 @@ module Hanami
6
6
  # Rack compatible, lightweight and fast HTTP Router.
7
7
  #
8
8
  # @since 0.1.0
9
- class Router # rubocop:disable Metrics/ClassLength
9
+ class Router
10
10
  require "hanami/router/version"
11
11
  require "hanami/router/error"
12
12
  require "hanami/router/segment"
@@ -48,6 +48,7 @@ module Hanami
48
48
  # is deployed
49
49
  # @param resolver [#call(path, to)] a resolver for route entpoints
50
50
  # @param block_context [Hanami::Router::Block::Context)
51
+ # @param not_found [#call(env)] default handler when route is not matched
51
52
  # @param blk [Proc] the route definitions
52
53
  #
53
54
  # @since 0.1.0
@@ -60,12 +61,13 @@ module Hanami
60
61
  # Hanami::Router.new do
61
62
  # get "/", to: ->(*) { [200, {}, ["OK"]] }
62
63
  # end
63
- def initialize(base_url: DEFAULT_BASE_URL, prefix: DEFAULT_PREFIX, resolver: DEFAULT_RESOLVER, block_context: nil, &blk)
64
+ def initialize(base_url: DEFAULT_BASE_URL, prefix: DEFAULT_PREFIX, resolver: DEFAULT_RESOLVER, not_found: NOT_FOUND, block_context: nil, &blk) # rubocop:disable Layout/LineLength
64
65
  # TODO: verify if Prefix can handle both name and path prefix
65
66
  @path_prefix = Prefix.new(prefix)
66
67
  @name_prefix = Prefix.new("")
67
68
  @url_helpers = UrlHelpers.new(base_url)
68
69
  @resolver = resolver
70
+ @not_found = not_found
69
71
  @block_context = block_context
70
72
  @fixed = {}
71
73
  @variable = {}
@@ -86,7 +88,7 @@ module Hanami
86
88
 
87
89
  unless endpoint
88
90
  return not_allowed(env) ||
89
- not_found
91
+ not_found(env)
90
92
  end
91
93
 
92
94
  endpoint.call(
@@ -631,13 +633,14 @@ module Hanami
631
633
  # @since 2.0.0
632
634
  # @api private
633
635
  def not_allowed(env)
634
- (_not_allowed_fixed(env) || _not_allowed_variable(env)) and return [405, { "Content-Length" => "11" }, ["Not Allowed"]]
636
+ (_not_allowed_fixed(env) ||
637
+ _not_allowed_variable(env)) and return [405, {"Content-Length" => "11"}, ["Not Allowed"]]
635
638
  end
636
639
 
637
640
  # @since 2.0.0
638
641
  # @api private
639
- def not_found
640
- [404, { "Content-Length" => "9" }, ["Not Found"]]
642
+ def not_found(env)
643
+ @not_found.call(env)
641
644
  end
642
645
 
643
646
  protected
@@ -655,7 +658,7 @@ module Hanami
655
658
  #
656
659
  # @see Hanami::Router#recognize
657
660
  # @see http://www.rubydoc.info/github/rack/rack/Rack%2FMockRequest.env_for
658
- def env_for(env, params = {}, options = {}) # rubocop:disable Metrics/MethodLength
661
+ def env_for(env, params = {}, options = {})
659
662
  require "rack/mock"
660
663
 
661
664
  case env
@@ -695,6 +698,12 @@ module Hanami
695
698
  # @api private
696
699
  PARAMS = "router.params"
697
700
 
701
+ # Default response when no route was matched
702
+ #
703
+ # @api private
704
+ # @since 2.0.0
705
+ NOT_FOUND = ->(*) { [404, {"Content-Length" => "9"}, ["Not Found"]] }.freeze
706
+
698
707
  # @since 2.0.0
699
708
  # @api private
700
709
  def lookup(env)
@@ -789,7 +798,7 @@ module Hanami
789
798
  end
790
799
 
791
800
  destination = prefixed_path(to)
792
- Redirect.new(destination, ->(*) { [code, { "Location" => destination }, [body]] })
801
+ Redirect.new(destination, ->(*) { [code, {"Location" => destination}, [body]] })
793
802
  end
794
803
 
795
804
  # @since 2.0.0
@@ -36,8 +36,7 @@ module Hanami
36
36
  # @api private
37
37
  # @since 2.0.0
38
38
  #
39
- # rubocop:disable Metrics/MethodLength
40
- def get(segment)
39
+ def get(segment) # rubocop:disable Metrics/PerceivedComplexity
41
40
  return unless @variable || @fixed
42
41
 
43
42
  found = nil
@@ -55,7 +54,6 @@ module Hanami
55
54
 
56
55
  [found, captured&.named_captures]
57
56
  end
58
- # rubocop:enable Metrics/MethodLength
59
57
 
60
58
  # @api private
61
59
  # @since 2.0.0
@@ -15,7 +15,7 @@ module Hanami
15
15
  #
16
16
  # @api private
17
17
  # @since 2.0.0
18
- def self.deep_symbolize(params) # rubocop:disable Metrics/MethodLength
18
+ def self.deep_symbolize(params)
19
19
  params.each_with_object({}) do |(key, value), output|
20
20
  output[key.to_sym] =
21
21
  case value
@@ -25,7 +25,7 @@ module Hanami
25
25
  # @api private
26
26
  def relative_join(path, separator = DEFAULT_SEPARATOR)
27
27
  _join(path.to_s)
28
- .gsub(DEFAULT_SEPARATOR_REGEXP, separator)[1..-1]
28
+ .gsub(DEFAULT_SEPARATOR_REGEXP, separator)[1..]
29
29
  end
30
30
 
31
31
  # @since 2.0.0
@@ -52,7 +52,7 @@ module Hanami
52
52
 
53
53
  # @since 2.0.0
54
54
  # @api private
55
- DOUBLE_DEFAULT_SEPARATOR_REGEXP = /[\/]{2,}/.freeze
55
+ DOUBLE_DEFAULT_SEPARATOR_REGEXP = /\/{2,}/.freeze
56
56
 
57
57
  # @since 2.0.0
58
58
  # @api private
@@ -27,7 +27,7 @@ module Hanami
27
27
  # @see Hanami::Router::RecognizedRoute#routable?
28
28
  # @see Hanami::Router::NotRoutableEndpointError
29
29
  def call(env)
30
- if routable? # rubocop:disable Style/GuardClause
30
+ if routable?
31
31
  @endpoint.call(env)
32
32
  else
33
33
  raise NotRoutableEndpointError.new(@env)
@@ -4,6 +4,6 @@ module Hanami
4
4
  class Router
5
5
  # @since 0.1.0
6
6
  # @api public
7
- VERSION = "2.0.0.alpha3"
7
+ VERSION = "2.0.0.alpha4"
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hanami-router
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.alpha3
4
+ version: 2.0.0.alpha4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luca Guidi
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-20 00:00:00.000000000 Z
11
+ date: 2021-01-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -114,6 +114,34 @@ dependencies:
114
114
  - - "~>"
115
115
  - !ruby/object:Gem::Version
116
116
  version: '3.8'
117
+ - !ruby/object:Gem::Dependency
118
+ name: rubocop
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - '='
122
+ - !ruby/object:Gem::Version
123
+ version: '0.91'
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - '='
129
+ - !ruby/object:Gem::Version
130
+ version: '0.91'
131
+ - !ruby/object:Gem::Dependency
132
+ name: rubocop-performance
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - '='
136
+ - !ruby/object:Gem::Version
137
+ version: 1.8.1
138
+ type: :development
139
+ prerelease: false
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - '='
143
+ - !ruby/object:Gem::Version
144
+ version: 1.8.1
117
145
  description: Rack compatible HTTP router for Ruby
118
146
  email:
119
147
  - me@lucaguidi.com
@@ -129,6 +157,7 @@ files:
129
157
  - lib/hanami/middleware/body_parser/class_interface.rb
130
158
  - lib/hanami/middleware/body_parser/errors.rb
131
159
  - lib/hanami/middleware/body_parser/json_parser.rb
160
+ - lib/hanami/middleware/body_parser/parser.rb
132
161
  - lib/hanami/middleware/error.rb
133
162
  - lib/hanami/router.rb
134
163
  - lib/hanami/router/block.rb
@@ -146,7 +175,7 @@ homepage: http://hanamirb.org
146
175
  licenses:
147
176
  - MIT
148
177
  metadata: {}
149
- post_install_message:
178
+ post_install_message:
150
179
  rdoc_options: []
151
180
  require_paths:
152
181
  - lib
@@ -154,15 +183,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
154
183
  requirements:
155
184
  - - ">="
156
185
  - !ruby/object:Gem::Version
157
- version: 2.5.0
186
+ version: 2.6.0
158
187
  required_rubygems_version: !ruby/object:Gem::Requirement
159
188
  requirements:
160
189
  - - ">"
161
190
  - !ruby/object:Gem::Version
162
191
  version: 1.3.1
163
192
  requirements: []
164
- rubygems_version: 3.1.3
165
- signing_key:
193
+ rubygems_version: 3.2.4
194
+ signing_key:
166
195
  specification_version: 4
167
196
  summary: Rack compatible HTTP router for Ruby and Hanami
168
197
  test_files: []