nyny 3.1.0 → 3.2.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: ae38227835876ef5e85282b236b5349049e15116
4
- data.tar.gz: 70836d65922b92ac174fee44b9c0c1dc8a2525b9
3
+ metadata.gz: 123f620e3c40a87a0f54fd78cd8f8112941d0220
4
+ data.tar.gz: 89ff15d4d6635afe7fdb7626f5981ecd756359b6
5
5
  SHA512:
6
- metadata.gz: 99cfbc9eabad3173837d1acba68236b4eb7ba01dee114691d12a8266bb6c4970acea3a586c7be8b1699f08938abaea8f5ef1e25931b47dc78b6d2c10a6d5907b
7
- data.tar.gz: 5443fdcb5d69b8771f35153ca8c7bbec47eb71f6db4221fd831f2f733da4b62576f99ac723491f9778d7e2fa0659a472ff21d378bbb9fd46054948067127fe8b
6
+ metadata.gz: 6ef900b1533aca5c0b1422ab7a621ebac15a0eb5a9f2e1b49c0a04da5464d4b656b9b1e328cf2da566983b1a9e4c242ad51069f5669e6a66c088fe611e31d9a6
7
+ data.tar.gz: 82fdbc3b1dc437bb94b3e51142d5082077b4ed25c0a7ccd6d87489d832c1cda8debf9224ad1539b5be14acb0e7d6e23df5c002346a216e5115f858d62c87e687
data/CHANGELOG CHANGED
@@ -1,3 +1,7 @@
1
+ 3.2.0
2
+ - Use Rails' Journey router as router to conquer the world and shorten
3
+ the codebase
4
+
1
5
  3.1.0
2
6
  - use latest Tilt (2.0.0)
3
7
  - get rid of silly Rack::Response hacks, write to body properly
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # New York, New York.
2
- (very) small Sinatra clone.
2
+ (ridiculously) small and powerful micro web framework.
3
3
 
4
4
  [![Build Status](https://api.travis-ci.org/alisnic/nyny.png)](https://travis-ci.org/alisnic/nyny)
5
5
  [![Coverage Status](https://coveralls.io/repos/alisnic/nyny/badge.png)](https://coveralls.io/r/alisnic/nyny)
@@ -42,9 +42,9 @@ Open the browser at [http://localhost:9292](http://localhost:9292)
42
42
  - [Environment](#environment)
43
43
  - [Running](#running)
44
44
  - [Defining routes](#defining-routes)
45
+ - [Request scope](#request-scope)
45
46
  - [Namespaces](#namespaces)
46
47
  - [Templates](#templates)
47
- - [Request scope](#request-scope)
48
48
  - [Filters](#filters)
49
49
  - [Middleware](#middleware)
50
50
  - [Helpers](#helpers)
@@ -52,31 +52,17 @@ Open the browser at [http://localhost:9292](http://localhost:9292)
52
52
  - [FAQ](#f-a-q)
53
53
  - [Contributing](#contributing)
54
54
 
55
- # Motivation
56
- My efforts to write __NYNY__ started when I wanted to understand how __Sinatra__
57
- works, and stumbled upon the [base.rb][0]. The majority of the classes that
58
- are used by Sinatra are in one single file, which makes it nearly impossible
59
- for a new person to grasp.
60
-
61
- I wanted to understand how sinatra works, but the code was pretty challenging.
62
- So I decided I should re-implement the basic things Sinatra has.
63
- Thus, __NYNY__ was born.
64
-
65
55
  # Philosophy
66
- NYNY should have only the bare minimum to write basic web servers comfortably,
67
- everything else should be in a extension. It is also
68
- trivial to use NYNY to build large and complex apps, by writing multiple sub
69
- apps and using Rack to mount them, or by using those sub apps in the "main" app
70
- as middleware.
71
-
72
- # Why use NYNY instead of Sinatra
73
- - It's very small (~300 LOC), which is just a little overhead on top of Rack.
74
- - Sinatra is a drop-in replacement for NYNY. Anytime you feel that you need more,
75
- you can just change your app to inherit from `Sinatra::Base`, your code will
76
- still work, and you will be able to use any of the Sinatra features.
77
- - It's __~2 times faster__ than Sinatra (see [Performance][performance] for details)
56
+ NYNY is unassuming, it has all the core stuff to get running, but nothing else.
57
+ Your app is the framework. However, it's trivial to extend NYNY via its
58
+ [extension interface](#extensions).
59
+
60
+ # Why use NYNY instead of any other small web framework
61
+ - It's __very__ small (<300 LOC), which is just a little overhead on top of Rack.
78
62
  - You want to dig into the source code and change to your needs (NYNY's source code is more welcoming)
79
63
  - Each NYNY app is a Rack middleware, so it can be used inside of Sinatra, Rails, or any other Rack-based app.
64
+ - __It uses Journey for routing (Rails' router)__, which makes its routing logic
65
+ a lot more powerful and reliable that in most micro web frameworks.
80
66
 
81
67
  # Usage
82
68
 
@@ -97,6 +83,7 @@ To get the directory in which your app is running use `NYNY.root`
97
83
  #/some/folder/server.rb
98
84
  require 'nyny'
99
85
  puts NYNY.root #=> /some/folder/
86
+ puts NYNY.root.join("foo") #=> /some/folder/foo
100
87
  ```
101
88
 
102
89
  To get NYNY's environment, use `NYNY.env`
@@ -142,13 +129,14 @@ App.run!
142
129
 
143
130
  `run!` takes the port number as optional argument (the default port is 9292).
144
131
  Also the `run!` method will include 2 default middlewares to make the
145
- development easier: Rack::CommonLogger and Rack::ShowExceptions.
132
+ development easier: Rack::CommonLogger and BetterErrors::Middleware (only in dev).
146
133
  This will show all requests in the log, and will provide useful details
147
134
  in the case a error occurs during a request.
148
135
 
149
136
  ## Defining routes
150
137
 
151
- NYNY supports the following verbs for defining a route: delete, get, head,
138
+ NYNY uses [Journey][journey] for routing, that means that NYNY has all the
139
+ awesomeness the Rails' router has. NYNY supports the following verbs for defining a route: delete, get, head,
152
140
  options, patch, post, put and trace.
153
141
 
154
142
  ```ruby
@@ -158,24 +146,25 @@ class App < NYNY::App
158
146
  end
159
147
  end
160
148
  ```
149
+ You can use any construct or convention [supported in Rails][bound-params]
150
+ for the path string.
161
151
 
162
- NYNY also suports basic URL patterns:
152
+ Each route definition call optionally accepts constraints:
163
153
 
164
154
  ```ruby
165
155
  class App < NYNY::App
166
- get '/greet/:first_name/:last_name' do
167
- # the last expression in the block is _always_ considered the response body.
168
- "Hello #{params[:first_name]} #{params[:last_name]}!"
156
+ get '/', :constraints => {:format => :html} do
157
+ 'html'
169
158
  end
170
159
  end
171
160
  ```
161
+ You can use [the same constraints][constraints] you use in Rails.
172
162
 
173
- you can also tell NYNY to match a regex for a path:
174
-
163
+ Besides the constraints, you can specify defaults:
175
164
  ```ruby
176
165
  class App < NYNY::App
177
- get /html/ do
178
- 'Your URL contains html!'
166
+ get '/', :defaults => {:format => 'html'} do
167
+ 'html'
179
168
  end
180
169
  end
181
170
  ```
@@ -183,6 +172,30 @@ end
183
172
  Each block that is passed to a route definition is evaluated in the context of
184
173
  a request scope. See below what methods are available there.
185
174
 
175
+ ## Request scope
176
+ As was said above, when you pass a block to a route definition,
177
+ that block is evaluated in the context of a [RequestScope][2].
178
+ This means that several methods/objects available inside that block:
179
+
180
+ - `request` - A `Rack::Request` object which encapsulates the request
181
+ to that route. (see [Rack::Request documentation][3] for more info)
182
+ - `response` - A `Rack::Response` object which encapsulates the response.
183
+ Additionally, NYNY's response exposes 2 more methods in addition to Rack's ones.
184
+ (see [primitives.rb][primitivesrb])
185
+ - `params` - a hash which contains both POST body params and GET querystring params.
186
+ - `headers` - a hash with the response headers
187
+ (ex: `headers['Content-Type'] = 'text/html'`)
188
+ - `status` - allows you to set the status of the response (ex: `status 403`)
189
+ - `redirect_to` - sets the response to redirect
190
+ (ex: `redirect_to 'http://google.com'`)
191
+ - `cookies` - a hash which allows you to access/modify/remove cookies
192
+ (ex: `cookies[:foo] = 'bar'` or `cookies.delete[:foo]`)
193
+ - `session` - a hash which allows you to access/modify/remove session variables
194
+ (ex: `session[:foo] = 'bar'`)
195
+ - `halt` - allows you to instantly return a response, interrupting current
196
+ handler execution (see [halt][halt-definition])
197
+
198
+
186
199
  ## Namespaces
187
200
  You can define namespaces for routes in NYNY. Each namespace is an isolated
188
201
  app, which means that you can use the same api that you use in your top app there:
@@ -254,29 +267,6 @@ end
254
267
  ```
255
268
  NYNY uses [Tilt][tilt] for templating, so the list of supported engines is pretty complete.
256
269
 
257
- ## Request scope
258
- As was said above, when you pass a block to a route definition,
259
- that block is evaluated in the context of a [RequestScope][2].
260
- This means that several methods/objects available inside that block:
261
-
262
- - `request` - A `Rack::Request` object which encapsulates the request
263
- to that route. (see [Rack::Request documentation][3] for more info)
264
- - `response` - A `Rack::Response` object which encapsulates the response.
265
- Additionally, NYNY's response exposes 2 more methods in addition to Rack's ones.
266
- (see [primitives.rb][primitivesrb])
267
- - `params` - a hash which contains both POST body params and GET querystring params.
268
- - `headers` - a hash with the response headers
269
- (ex: `headers['Content-Type'] = 'text/html'`)
270
- - `status` - allows you to set the status of the response (ex: `status 403`)
271
- - `redirect_to` - sets the response to redirect
272
- (ex: `redirect_to 'http://google.com'`)
273
- - `cookies` - a hash which allows you to access/modify/remove cookies
274
- (ex: `cookies[:foo] = 'bar'` or `cookies.delete[:foo]`)
275
- - `session` - a hash which allows you to access/modify/remove session variables
276
- (ex: `session[:foo] = 'bar'`)
277
- - `halt` - allows you to instantly return a response, interrupting current
278
- handler execution (see [halt][halt-definition])
279
-
280
270
  ## Filters
281
271
 
282
272
  Unlike Sinatra, NYNY supports only "generic" before and after filters.
@@ -422,3 +412,6 @@ TBD.
422
412
  [halt-definition]: https://github.com/alisnic/nyny/blob/master/lib/nyny/request_scope.rb#L36
423
413
  [primitivesrb]: https://github.com/alisnic/nyny/blob/master/lib/nyny/primitives.rb
424
414
  [tilt]: https://github.com/rtomayko/tilt
415
+ [journey]: https://github.com/rails/journey
416
+ [constraints]: http://guides.rubyonrails.org/routing.html#request-based-constraints
417
+ [bound-params]: http://guides.rubyonrails.org/routing.html#bound-parameters
@@ -1,12 +1,7 @@
1
- require 'uri'
2
1
  require 'rack'
3
2
 
4
3
  require 'nyny/version'
5
- require 'nyny/primitives'
6
- require 'nyny/request_scope'
7
- require 'nyny/route'
8
4
  require 'nyny/app'
9
- require 'nyny/router'
10
5
  require 'nyny/core-ext/runner'
11
6
  require 'nyny/core-ext/templates'
12
7
 
@@ -19,8 +14,14 @@ module NYNY
19
14
  end
20
15
  end
21
16
 
17
+ class PathString < String
18
+ def join other
19
+ File.join(self, other)
20
+ end
21
+ end
22
+
22
23
  def self.root
23
- Dir.pwd
24
+ @root ||= PathString.new(Dir.pwd)
24
25
  end
25
26
 
26
27
  def self.env
@@ -1,3 +1,7 @@
1
+ require 'nyny/primitives'
2
+ require 'nyny/request_scope'
3
+ require 'nyny/router'
4
+
1
5
  module NYNY
2
6
  class App
3
7
  HTTP_VERBS = [:delete, :get, :head, :options, :patch, :post, :put, :trace]
@@ -19,19 +23,20 @@ module NYNY
19
23
  end
20
24
 
21
25
  inheritable :builder, Rack::Builder.new
22
- inheritable :routes, []
26
+ inheritable :route_defs, []
23
27
  inheritable :before_hooks, []
24
28
  inheritable :after_hooks, []
25
29
  inheritable :scope_class, Class.new(RequestScope)
26
30
 
27
31
  def initialize app=nil
28
32
  self.class.builder.run Router.new({
29
- :routes => self.class.routes,
30
- :fallback => (app || lambda {|env| Response.new [], 404 }),
31
- :before_hooks => self.class.before_hooks,
32
- :after_hooks => self.class.after_hooks,
33
- :scope_class => self.class.scope_class
33
+ :scope_class => self.class.scope_class,
34
+ :route_defs => self.class.route_defs,
35
+ :before_hooks => self.class.before_hooks,
36
+ :after_hooks => self.class.after_hooks,
37
+ :fallback => app
34
38
  })
39
+
35
40
  @app = self.class.builder.to_app
36
41
  end
37
42
 
@@ -42,11 +47,17 @@ module NYNY
42
47
  #class methods
43
48
  class << self
44
49
  HTTP_VERBS.each do |method|
45
- define_method method do |str, &blk|
46
- routes << Route.new(method, str, &blk)
50
+ define_method method do |path, options={}, &block|
51
+ options[:constraints] ||= {}
52
+ options[:constraints].merge!(:request_method => method.to_s.upcase)
53
+ define_route path, options, &block
47
54
  end
48
55
  end
49
56
 
57
+ def define_route path, options, &block
58
+ self.route_defs << [path, options, Proc.new(&block)]
59
+ end
60
+
50
61
  def register *extensions
51
62
  extensions.each do |ext|
52
63
  extend ext
@@ -11,7 +11,7 @@ module NYNY
11
11
 
12
12
  def initialize request
13
13
  @request = request
14
- @response = Response.new
14
+ @response = Response.new [], 200, {'Content-Type' => 'text/html'}
15
15
  end
16
16
 
17
17
  def cookies
@@ -1,46 +1,64 @@
1
+ require 'journey'
2
+
1
3
  module NYNY
2
4
  class Router
3
- attr_reader :fallback, :routes, :before_hooks, :after_hooks, :scope_class
5
+ attr_reader :scope_class, :journey, :before_hooks, :after_hooks, :fallback
4
6
  def initialize options
5
- @fallback = options[:fallback]
6
- @routes = options[:routes]
7
- @before_hooks = options[:before_hooks]
8
- @after_hooks = options[:after_hooks]
9
- @scope_class = options[:scope_class]
7
+ @scope_class = options[:scope_class]
8
+ @before_hooks = options[:before_hooks]
9
+ @after_hooks = options[:after_hooks]
10
+ @fallback = options[:fallback]
11
+
12
+ prepare_for_journey(options[:route_defs])
10
13
  end
11
14
 
12
15
  def call env
13
- env['PATH_INFO'] = '/' if env['PATH_INFO'].empty?
14
- route = routes.find {|route| route.match? env }
16
+ response = journey.call(env)
15
17
 
16
- if route
17
- process route, env
18
+ if response[0] == 404 and fallback
19
+ fallback.call(env)
18
20
  else
19
- fallback.call env
21
+ response
20
22
  end
21
23
  end
22
24
 
23
- def process route, env
24
- request = Request.new(env)
25
- request.params.merge! route.url_params(env)
26
- request.params.default_proc = lambda do |h, k|
27
- h.fetch(k.to_s, nil) || h.fetch(k.to_sym, nil)
28
- end
25
+ private
29
26
 
30
- eval_response scope_class.new(request), route.handler
31
- end
27
+ def prepare_for_journey route_defs
28
+ @journey = Journey::Router.new(Journey::Routes.new, {
29
+ :parameters_key => 'nyny.params'
30
+ })
32
31
 
33
- def eval_response scope, handler
34
- response = catch (:halt) do
35
- before_hooks.each {|h| scope.instance_eval &h }
36
- scope.apply_to &handler
37
- end
32
+ route_defs.each do |path, options, handler|
33
+ pat = Journey::Path::Pattern.new(path)
34
+ constraints = options.fetch(:constraints, {})
35
+ defaults = options.fetch(:defaults, {})
38
36
 
39
- catch (:halt) do
40
- after_hooks.each {|h| scope.instance_eval &h }
37
+ @journey.routes.add_route compile(handler), pat, constraints, defaults
41
38
  end
39
+ end
42
40
 
43
- response
41
+ def compile handler
42
+ Proc.new do |env|
43
+ request = Request.new(env)
44
+ request.params.merge! env["nyny.params"]
45
+ request.params.default_proc = lambda do |h, k|
46
+ h.fetch(k.to_s, nil) || h.fetch(k.to_sym, nil)
47
+ end
48
+
49
+ scope = scope_class.new(request)
50
+
51
+ response = catch (:halt) do
52
+ before_hooks.each {|h| scope.instance_eval &h }
53
+ scope.apply_to &handler
54
+ end
55
+
56
+ catch (:halt) do
57
+ after_hooks.each {|h| scope.instance_eval &h }
58
+ end
59
+
60
+ response
61
+ end
44
62
  end
45
63
  end
46
- end
64
+ end
@@ -1,3 +1,3 @@
1
1
  module NYNY
2
- VERSION = "3.1.0"
2
+ VERSION = "3.2.0"
3
3
  end
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
24
24
  spec.add_dependency "rack-contrib", "~> 1.1.0"
25
25
  spec.add_dependency "tilt", "~> 2.0.0"
26
26
  spec.add_dependency "better_errors", "~> 1.1.0"
27
+ spec.add_dependency "journey", "~> 1.0.4"
27
28
  spec.add_development_dependency "bundler", "~> 1.3"
28
29
  spec.add_development_dependency "rake"
29
30
  spec.add_development_dependency "rspec"
@@ -1,11 +1,15 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe NYNY do
4
- it '.root points to pwd' do
4
+ its 'root points to pwd' do
5
5
  NYNY.root.should == Dir.pwd
6
6
  end
7
7
 
8
8
  it 'has the correct env' do
9
9
  NYNY.env.should be_test
10
10
  end
11
+
12
+ its 'root can join a path' do
13
+ NYNY.root.join("foo").should == File.join(Dir.pwd, "foo")
14
+ end
11
15
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nyny
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0
4
+ version: 3.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrei Lisnic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-23 00:00:00.000000000 Z
11
+ date: 2014-01-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: 1.1.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: journey
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 1.0.4
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 1.0.4
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: bundler
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -122,7 +136,6 @@ files:
122
136
  - CHANGELOG
123
137
  - Gemfile
124
138
  - LICENSE.txt
125
- - Performance.md
126
139
  - README.md
127
140
  - Rakefile
128
141
  - lib/nyny.rb
@@ -131,7 +144,6 @@ files:
131
144
  - lib/nyny/core-ext/templates.rb
132
145
  - lib/nyny/primitives.rb
133
146
  - lib/nyny/request_scope.rb
134
- - lib/nyny/route.rb
135
147
  - lib/nyny/router.rb
136
148
  - lib/nyny/version.rb
137
149
  - nyny.gemspec
@@ -140,7 +152,6 @@ files:
140
152
  - spec/nyny_spec.rb
141
153
  - spec/primitives_spec.rb
142
154
  - spec/request_scope_spec.rb
143
- - spec/router_spec.rb
144
155
  - spec/runner_spec.rb
145
156
  - spec/spec_helper.rb
146
157
  - spec/templates_spec.rb
@@ -178,7 +189,6 @@ test_files:
178
189
  - spec/nyny_spec.rb
179
190
  - spec/primitives_spec.rb
180
191
  - spec/request_scope_spec.rb
181
- - spec/router_spec.rb
182
192
  - spec/runner_spec.rb
183
193
  - spec/spec_helper.rb
184
194
  - spec/templates_spec.rb
@@ -1,45 +0,0 @@
1
-
2
- Note: this bench may be a bit obsolete, I removed the profiling
3
- script due to the fact that NYNY's and Sintara's deps are
4
- incompatible. For a more complete list of of microframework
5
- benchmarks, see [https://github.com/luislavena/bench-micro]()
6
- ```
7
- Comparing NYNY 3.0.0 with Sinatra 1.4.4
8
-
9
- Test: hello world
10
- user system total real
11
- nyny: 0.110000 0.000000 0.110000 ( 0.108916)
12
- sinatra: 0.260000 0.010000 0.270000 ( 0.273225)
13
- NYNY is 2.51x faster than Sinatra in this test
14
-
15
- Test: filters
16
- user system total real
17
- nyny: 0.120000 0.000000 0.120000 ( 0.118976)
18
- sinatra: 0.250000 0.010000 0.260000 ( 0.264279)
19
- NYNY is 2.22x faster than Sinatra in this test
20
-
21
- Test: helpers
22
- user system total real
23
- nyny: 0.100000 0.000000 0.100000 ( 0.105290)
24
- sinatra: 0.240000 0.000000 0.240000 ( 0.249585)
25
- NYNY is 2.37x faster than Sinatra in this test
26
-
27
- Test: Url patterns
28
- user system total real
29
- nyny: 0.120000 0.000000 0.120000 ( 0.113535)
30
- sinatra: 0.260000 0.020000 0.280000 ( 0.277098)
31
- NYNY is 2.44x faster than Sinatra in this test
32
-
33
- Test: A lot o Plain routes
34
- user system total real
35
- nyny: 0.120000 0.000000 0.120000 ( 0.113001)
36
- sinatra: 0.250000 0.000000 0.250000 ( 0.262890)
37
- NYNY is 2.33x faster than Sinatra in this test
38
-
39
- Test: A lot of Pattern routes
40
- user system total real
41
- nyny: 0.130000 0.000000 0.130000 ( 0.133590)
42
- sinatra: 0.270000 0.010000 0.280000 ( 0.284605)
43
- NYNY is 2.13x faster than Sinatra in this test
44
-
45
- ```
@@ -1,40 +0,0 @@
1
- module NYNY
2
- class Route
3
- NAME_PATTERN = /:(\S+)/
4
-
5
- attr_reader :pattern, :handler, :method
6
- def initialize method, signature, &block
7
- @pattern = pattern_for signature
8
- @handler = Proc.new(&block)
9
- @method = method.to_s.upcase
10
- end
11
-
12
- def pattern_for signature
13
- return signature if signature.is_a? Regexp
14
- build_regex(signature.start_with?('/') ? signature : "/#{signature}")
15
- end
16
-
17
- def build_regex signature
18
- return %r(^#{signature}$) unless signature.include?(':')
19
-
20
- groups = signature.split('/').map do |part|
21
- next part if part.empty?
22
- next part unless part.start_with? ':'
23
- name = NAME_PATTERN.match(part)[1]
24
- %Q{(?<#{name}>\\S+)}
25
- end.select {|s| !s.empty? }.join('\/')
26
-
27
- %r(^\/#{groups}$)
28
- end
29
-
30
- def match? env
31
- return false unless method == env['REQUEST_METHOD']
32
- not pattern.match(env['PATH_INFO']).nil?
33
- end
34
-
35
- def url_params env
36
- data = pattern.match(env['PATH_INFO'])
37
- Hash[data.names.map {|n| [n.to_sym, URI.unescape(data[n])]}]
38
- end
39
- end
40
- end
@@ -1,29 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Router do
4
- let (:app) do
5
- mock_app do
6
- get '/' do
7
- halt 200, {}, "Bar"
8
- "Foo"
9
- end
10
-
11
- post '/' do
12
- params[:not_exist].to_s
13
- end
14
-
15
- after do
16
- response.rewrite "Zaz"
17
- end
18
- end
19
- end
20
-
21
- it "should eval after blocks even if the request was halted" do
22
- response = app.get('/')
23
- response.body.should == "Zaz"
24
- end
25
-
26
- it "should not raise SystemStackError if any absent param is accessed" do
27
- expect { response = app.post('/') }.not_to raise_error
28
- end
29
- end