hanami-router 0.6.2 → 0.7.0

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
  SHA1:
3
- metadata.gz: 2a2586983782aac1daa6b998207f6b1711ce0b30
4
- data.tar.gz: 56be6fbaa73b846cd3d531da9747edbbf938cb6f
3
+ metadata.gz: 393f316c6e21157b2ac3d3d7a9544c9311e55c41
4
+ data.tar.gz: 887ed0b0c22b13bf105a621b2cfb9f8ce7542ea7
5
5
  SHA512:
6
- metadata.gz: d4b100f203d78a140e62830b309f1bf6edca12cd825dfbfde86e6b89645baf7ed61898d06ec38bcf55b15eccb0fc38d3bc63ae9ffa151e6bb9a4dc3232d95650
7
- data.tar.gz: 807b558c107acf679aef63e26b7b17bf4d7d726e6ae198beb954e9d380ba1ebc3578ea95ce9c589111591ca81f8a4ffcd3050301a4c0c0bcbcc506604d1a8a06
6
+ metadata.gz: 4fc20e2fe87c4fd3f2a7c088d26836dca184f7dfa4918930793442f7fabecd99de3eaec56c16d2e0fe85cca6f5b90b21607efaa297b27868dad5a0701e0de649
7
+ data.tar.gz: 722378463a90b9ea3ebcd5151a630a776655ce37d1025389b5dda41f4bd76e7345506a44188ad10c6ec8d2af8f35a741419665afc0704ce782d8596db3d0d5ac
data/CHANGELOG.md CHANGED
@@ -1,6 +1,21 @@
1
1
  # Hanami::Router
2
2
  Rack compatible HTTP router for Ruby
3
3
 
4
+ ## v0.7.0 - 2016-07-22
5
+ ### Added
6
+ - [Sean Collins] Introduced `Hanami::Router#root`. Example: `root to: 'home#index'`, equivalent to `get '/', to: 'home#index', as: :root`.
7
+ - [Nicola Racco] Allow to mount Rack applications at a specific host. Example: `mount Blog, host: 'blog'`, which will be hit for `GET http://blog.example.com`
8
+ - [Luca Guidi] Support `multi_json` gem as backend for JSON body parser. If `multi_json` is present in the gem bundle, it will be used, otherwise it will fallback to Ruby's `JSON`.
9
+ - [Luca Guidi] Introduced `Hanami::Routing::RecognizedRoute#path` in order to allow a better introspection
10
+
11
+ ### Fixed
12
+ - [Andrew De Ponte] Make routes inspection to work when non-Hanami apps are mounted
13
+ - [Andrew De Ponte] Ensure to set the right `SCRIPT_NAME` in Rack env for mounted Hanami apps
14
+ - [Luca Guidi] Fix `NoMethodError` when `Hanami::Router#recognize` is invoked with a Rack env or a route name or a path that can't be recognized
15
+
16
+ ### Changed
17
+ – [Luca Guidi] Drop support for Ruby 2.0 and 2.1. Official support for JRuby 9.0.5.0+
18
+
4
19
  ## v0.6.2 - 2016-02-05
5
20
  ### Fixed
6
21
  - [Anton Davydov] Fix double leading slash for Capybara's `current_path`
data/README.md CHANGED
@@ -68,7 +68,8 @@ For the standalone usage, it supports neat features:
68
68
 
69
69
  ```ruby
70
70
  Hanami::Router.new do
71
- get '/', to: ->(env) { [200, {}, ['Hi!']] }
71
+ root to: ->(env) { [200, {}, ['Hello']] }
72
+ get '/lambda', to: ->(env) { [200, {}, ['World']] }
72
73
  get '/dashboard', to: Dashboard::Index
73
74
  get '/rack-app', to: RackApp.new
74
75
  get '/flowers', to: 'flowers#index'
@@ -167,6 +168,15 @@ router.trace '/hanami', to: endpoint
167
168
 
168
169
 
169
170
 
171
+ ### Root:
172
+
173
+ ```ruby
174
+ router = Hanami::Router.new
175
+ router.root to: ->(env) { [200, {}, ['Hello from Hanami!']] }
176
+ ```
177
+
178
+
179
+
170
180
  ### Redirect:
171
181
 
172
182
  ```ruby
@@ -608,6 +618,10 @@ If the json can't be parsed an exception is raised:
608
618
  Hanami::Routing::Parsing::BodyParsingError
609
619
  ```
610
620
 
621
+ ##### `multi_json`
622
+
623
+ If you want to use a different JSON backend, include `multi_json` in your `Gemfile`.
624
+
611
625
  #### Custom Parsers
612
626
 
613
627
  ```ruby
@@ -17,13 +17,14 @@ Gem::Specification.new do |spec|
17
17
  spec.executables = []
18
18
  spec.test_files = spec.files.grep(%r{^(test)/})
19
19
  spec.require_paths = ['lib']
20
- spec.required_ruby_version = '>= 2.0.0'
20
+ spec.required_ruby_version = '>= 2.2.0'
21
21
 
22
+ spec.add_dependency 'rack', '~> 1.6'
22
23
  spec.add_dependency 'http_router', '~> 0.11'
23
- spec.add_dependency 'hanami-utils', '~> 0.7'
24
+ spec.add_dependency 'hanami-utils', '~> 0.8'
24
25
 
25
26
  spec.add_development_dependency 'bundler', '~> 1.5'
26
27
  spec.add_development_dependency 'minitest', '~> 5'
27
- spec.add_development_dependency 'rake', '~> 10'
28
+ spec.add_development_dependency 'rake', '~> 11'
28
29
  spec.add_development_dependency 'rack-test', '~> 0.6'
29
30
  end
data/lib/hanami/router.rb CHANGED
@@ -91,6 +91,14 @@ module Hanami
91
91
  end
92
92
  end
93
93
 
94
+ # Defines root path
95
+ #
96
+ # @since 0.7.0
97
+ # @api private
98
+ #
99
+ # @see Hanami::Router#root
100
+ ROOT_PATH = '/'.freeze
101
+
94
102
  # Returns the given block as it is.
95
103
  #
96
104
  # When Hanami::Router is used as a standalone gem and the routes are defined
@@ -491,6 +499,36 @@ module Hanami
491
499
  @router.trace(path, options, &blk)
492
500
  end
493
501
 
502
+ # Defines a root route (a GET route for '/')
503
+ #
504
+ # @param options [Hash] the options to customize the route
505
+ # @option options [String,Proc,Class,Object#call] :to the endpoint
506
+ #
507
+ # @param blk [Proc] the anonymous proc to be used as endpoint for the route
508
+ #
509
+ # @return [Hanami::Routing::Route] this may vary according to the :route
510
+ # option passed to the constructor
511
+ #
512
+ # @since 0.7.0
513
+ #
514
+ # @example Fixed matching string
515
+ # require 'hanami/router'
516
+ #
517
+ # router = Hanami::Router.new
518
+ # router.root to: ->(env) { [200, {}, ['Hello from Hanami!']] }
519
+ #
520
+ # @example Included names as `root` (for path and url helpers)
521
+ # require 'hanami/router'
522
+ #
523
+ # router = Hanami::Router.new(scheme: 'https', host: 'hanamirb.org')
524
+ # router.root to: ->(env) { [200, {}, ['Hello from Hanami!']] }
525
+ #
526
+ # router.path(:root) # => "/"
527
+ # router.url(:root) # => "https://hanamirb.org/"
528
+ def root(options = {}, &blk)
529
+ @router.get(ROOT_PATH, options.merge(as: :root), &blk)
530
+ end
531
+
494
532
  # Defines a route that accepts a OPTIONS request for the given path.
495
533
  #
496
534
  # @param path [String] the relative URL to be matched
@@ -1,6 +1,6 @@
1
1
  module Hanami
2
2
  class Router
3
3
  # @since 0.1.0
4
- VERSION = '0.6.2'.freeze
4
+ VERSION = '0.7.0'.freeze
5
5
  end
6
6
  end
@@ -14,6 +14,10 @@ module Hanami
14
14
  # @api private
15
15
  NAMING_PATTERN = '%{controller}::%{action}'.freeze
16
16
 
17
+ # @since 0.7.0
18
+ # @api private
19
+ DEFAULT_RESPONSE = [404, {'X-Cascade' => 'pass'}, 'Not Found'].freeze
20
+
17
21
  # Default separator for controller and action.
18
22
  # A different separator can be passed to #initialize with the `:separator` option.
19
23
  #
@@ -48,7 +52,7 @@ module Hanami
48
52
  # will be ignored.
49
53
  # See the examples below.
50
54
  #
51
- # @option options [String] :action_separator the sepatator between controller and
55
+ # @option options [String] :action_separator the separator between controller and
52
56
  # action name. (defaults to `ACTION_SEPARATOR`)
53
57
  #
54
58
  # @return [Hanami::Routing::EndpointResolver] self
@@ -178,7 +182,7 @@ module Hanami
178
182
  protected
179
183
  def default
180
184
  @endpoint_class.new(
181
- ->(env) { [404, {'X-Cascade' => 'pass'}, 'Not Found'] }
185
+ ->(env) { DEFAULT_RESPONSE }
182
186
  )
183
187
  end
184
188
 
@@ -1,3 +1,4 @@
1
+ require 'uri'
1
2
  require 'http_router'
2
3
  require 'hanami/utils/io'
3
4
  require 'hanami/routing/endpoint_resolver'
@@ -37,6 +38,24 @@ module Hanami
37
38
  # @api private
38
39
  SCRIPT_NAME = 'SCRIPT_NAME'.freeze
39
40
 
41
+ # Path info - rack environment variable
42
+ #
43
+ # @since 0.7.0
44
+ # @api private
45
+ PATH_INFO = 'PATH_INFO'.freeze
46
+
47
+ # Default PATH_INFO for Rack requests
48
+ #
49
+ # @since 0.7.0
50
+ # @api private
51
+ DEFAULT_PATH_INFO = '/'.freeze
52
+
53
+ # URL separator
54
+ #
55
+ # @since 0.7.0
56
+ # @api private
57
+ URL_SEPARATOR = '/'.freeze
58
+
40
59
  # @since 0.5.0
41
60
  # @api private
42
61
  attr_reader :namespace
@@ -48,6 +67,8 @@ module Hanami
48
67
  # @since 0.1.0
49
68
  # @api private
50
69
  def initialize(options = {}, &blk)
70
+ @compiled = false
71
+ @uri_parser = URI::Parser.new
51
72
  super(options, &nil)
52
73
 
53
74
  @namespace = options[:namespace] if options[:namespace]
@@ -122,7 +143,7 @@ module Hanami
122
143
  # @since 0.1.1
123
144
  # @api private
124
145
  def mount(app, options)
125
- add("#{ options.fetch(:at) }*").to(
146
+ add("#{ options.fetch(:at) }*", host: options[:host]).to(
126
147
  @resolver.resolve(to: app)
127
148
  )
128
149
  end
@@ -158,10 +179,15 @@ module Hanami
158
179
  end
159
180
 
160
181
  # @api private
161
- # @since 0.5.0
162
- def rewrite_path_info(env, request)
163
- super
164
- env[SCRIPT_NAME] = @prefix.join(env[SCRIPT_NAME])
182
+ def rewrite_partial_path_info(env, request)
183
+ if request.path.empty?
184
+ env[SCRIPT_NAME] += env[PATH_INFO]
185
+ env[PATH_INFO] = DEFAULT_PATH_INFO
186
+ else
187
+ path_info_before = env[PATH_INFO].dup
188
+ env[PATH_INFO] = "/#{@uri_parser.escape(request.path.join(URL_SEPARATOR))}"
189
+ env[SCRIPT_NAME] += path_info_before[0, path_info_before.bytesize - env[PATH_INFO].bytesize]
190
+ end
165
191
  end
166
192
 
167
193
  private
@@ -1,4 +1,4 @@
1
- require 'json'
1
+ require 'hanami/utils/json'
2
2
 
3
3
  module Hanami
4
4
  module Routing
@@ -18,8 +18,8 @@ module Hanami
18
18
  #
19
19
  # @since 0.2.0
20
20
  def parse(body)
21
- JSON.parse(body)
22
- rescue JSON::ParserError => e
21
+ Hanami::Utils::Json.load(body)
22
+ rescue Hanami::Utils::Json::ParserError => e
23
23
  raise BodyParsingError.new(e.message)
24
24
  end
25
25
  end
@@ -12,6 +12,10 @@ module Hanami
12
12
  # @api private
13
13
  REQUEST_METHOD = 'REQUEST_METHOD'.freeze
14
14
 
15
+ # @since 0.7.0
16
+ # @api private
17
+ PATH_INFO = 'PATH_INFO'.freeze
18
+
15
19
  # @since 0.5.0
16
20
  # @api private
17
21
  NAMESPACE = '%s::'.freeze
@@ -39,7 +43,9 @@ module Hanami
39
43
  # @since 0.5.0
40
44
  # @api private
41
45
  def initialize(response, env, router)
42
- @env = env
46
+ @env = env
47
+ @endpoint = nil
48
+ @params = {}
43
49
 
44
50
  unless response.nil?
45
51
  @endpoint = response.route.dest
@@ -81,6 +87,16 @@ module Hanami
81
87
  @env[REQUEST_METHOD]
82
88
  end
83
89
 
90
+ # Relative URL (path)
91
+ #
92
+ # @return [String]
93
+ #
94
+ # @since 0.7.0
95
+ # @api public
96
+ def path
97
+ @env[PATH_INFO]
98
+ end
99
+
84
100
  # Action name
85
101
  #
86
102
  # @return [String]
@@ -99,6 +115,7 @@ module Hanami
99
115
  #
100
116
  # puts router.recognize('/books/23').action # => "books#show"
101
117
  def action
118
+ return unless routable?
102
119
  namespace = NAMESPACE % @namespace
103
120
 
104
121
  if destination.match(namespace)
@@ -129,7 +146,7 @@ module Hanami
129
146
  # puts router.recognize('/').routable? # => true
130
147
  # puts router.recognize('/foo').routable? # => false
131
148
  def routable?
132
- !!@endpoint
149
+ !@endpoint.nil?
133
150
  end
134
151
 
135
152
  private
@@ -142,10 +159,12 @@ module Hanami
142
159
  @destination ||= begin
143
160
  case k = @endpoint.__getobj__
144
161
  when Class
145
- k
162
+ k.name
163
+ when Proc
164
+ @endpoint.inspect
146
165
  else
147
- k.class
148
- end.name
166
+ k.class.name
167
+ end
149
168
  end
150
169
  end
151
170
  end
@@ -16,6 +16,13 @@ module Hanami
16
16
  # router = Hanami::Router.new
17
17
  # router.get('/', to: endpoint) # => #<Hanami::Routing::Route:0x007f83083ba028 ...>
18
18
  class Route < HttpRouter::Route
19
+ # @since 0.7.0
20
+ # @api private
21
+ def initialize(*)
22
+ super
23
+ @name = nil
24
+ end
25
+
19
26
  # Asks the given resolver to return an endpoint that will be associated
20
27
  # with the other options.
21
28
  #
@@ -45,12 +52,12 @@ module Hanami
45
52
  end
46
53
 
47
54
  # Introspect the given route to understand if there is a wrapped
48
- # Hanami::Router
55
+ # router that has an inspector
49
56
  #
50
57
  # @since 0.2.0
51
58
  # @api private
52
59
  def nested_router
53
- dest.routes if dest.respond_to?(:routes)
60
+ dest.routes if dest.respond_to?(:routes) && dest.routes.respond_to?(:inspector)
54
61
  end
55
62
 
56
63
  private
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hanami-router
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.2
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luca Guidi
@@ -10,8 +10,22 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2016-02-05 00:00:00.000000000 Z
13
+ date: 2016-07-22 00:00:00.000000000 Z
14
14
  dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rack
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - "~>"
20
+ - !ruby/object:Gem::Version
21
+ version: '1.6'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - "~>"
27
+ - !ruby/object:Gem::Version
28
+ version: '1.6'
15
29
  - !ruby/object:Gem::Dependency
16
30
  name: http_router
17
31
  requirement: !ruby/object:Gem::Requirement
@@ -32,14 +46,14 @@ dependencies:
32
46
  requirements:
33
47
  - - "~>"
34
48
  - !ruby/object:Gem::Version
35
- version: '0.7'
49
+ version: '0.8'
36
50
  type: :runtime
37
51
  prerelease: false
38
52
  version_requirements: !ruby/object:Gem::Requirement
39
53
  requirements:
40
54
  - - "~>"
41
55
  - !ruby/object:Gem::Version
42
- version: '0.7'
56
+ version: '0.8'
43
57
  - !ruby/object:Gem::Dependency
44
58
  name: bundler
45
59
  requirement: !ruby/object:Gem::Requirement
@@ -74,14 +88,14 @@ dependencies:
74
88
  requirements:
75
89
  - - "~>"
76
90
  - !ruby/object:Gem::Version
77
- version: '10'
91
+ version: '11'
78
92
  type: :development
79
93
  prerelease: false
80
94
  version_requirements: !ruby/object:Gem::Requirement
81
95
  requirements:
82
96
  - - "~>"
83
97
  - !ruby/object:Gem::Version
84
- version: '10'
98
+ version: '11'
85
99
  - !ruby/object:Gem::Dependency
86
100
  name: rack-test
87
101
  requirement: !ruby/object:Gem::Requirement
@@ -142,7 +156,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
142
156
  requirements:
143
157
  - - ">="
144
158
  - !ruby/object:Gem::Version
145
- version: 2.0.0
159
+ version: 2.2.0
146
160
  required_rubygems_version: !ruby/object:Gem::Requirement
147
161
  requirements:
148
162
  - - ">="
@@ -150,9 +164,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
150
164
  version: '0'
151
165
  requirements: []
152
166
  rubyforge_project:
153
- rubygems_version: 2.5.1
167
+ rubygems_version: 2.6.4
154
168
  signing_key:
155
169
  specification_version: 4
156
170
  summary: Rack compatible HTTP router for Ruby and Hanami
157
171
  test_files: []
158
- has_rdoc: