http_router 0.5.4 → 0.6.0
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.
- data/lib/http_router.rb +58 -210
- data/lib/http_router/node.rb +124 -226
- data/lib/http_router/node/arbitrary.rb +16 -0
- data/lib/http_router/node/free_regex.rb +19 -0
- data/lib/http_router/node/glob.rb +16 -0
- data/lib/http_router/node/glob_regex.rb +9 -0
- data/lib/http_router/node/regex.rb +26 -0
- data/lib/http_router/node/request.rb +44 -0
- data/lib/http_router/node/spanning_regex.rb +16 -0
- data/lib/http_router/node/variable.rb +11 -0
- data/lib/http_router/optional_compiler.rb +8 -15
- data/lib/http_router/path.rb +36 -49
- data/lib/http_router/regex_route.rb +20 -0
- data/lib/http_router/request.rb +26 -0
- data/lib/http_router/response.rb +13 -0
- data/lib/http_router/route.rb +121 -299
- data/lib/http_router/version.rb +1 -1
- data/test/helper.rb +11 -9
- data/test/rack/test_urlmap.rb +9 -9
- data/test/test_arbitrary.rb +18 -10
- data/test/test_misc.rb +28 -28
- data/test/test_mounting.rb +81 -81
- data/test/test_request.rb +6 -0
- data/test/test_trailing_slash.rb +0 -4
- data/test/test_variable.rb +1 -9
- metadata +16 -16
- data/lib/http_router/glob.rb +0 -20
- data/lib/http_router/interface/sinatra.rb +0 -149
- data/lib/http_router/parts.rb +0 -24
- data/lib/http_router/rack.rb +0 -18
- data/lib/http_router/rack/builder.rb +0 -60
- data/lib/http_router/rack/url_map.rb +0 -10
- data/lib/http_router/root.rb +0 -36
- data/lib/http_router/static.rb +0 -5
- data/lib/http_router/variable.rb +0 -30
- data/test/sinatra/recognize_spec.rb +0 -168
- data/test/sinatra/test_recognize.rb +0 -150
data/lib/http_router/glob.rb
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
class HttpRouter
|
2
|
-
class Glob < Variable
|
3
|
-
def matches?(parts)
|
4
|
-
return if @matches_with.nil? or parts.empty? or !match.begin(0)
|
5
|
-
@matches_with.match(parts.first)
|
6
|
-
end
|
7
|
-
|
8
|
-
def consume(match, parts)
|
9
|
-
if @matches_with
|
10
|
-
params = [parts.shift]
|
11
|
-
params << parts.shift while matches?(parts)
|
12
|
-
params
|
13
|
-
else
|
14
|
-
params = parts.dup
|
15
|
-
parts.clear
|
16
|
-
params
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
@@ -1,149 +0,0 @@
|
|
1
|
-
require 'http_router'
|
2
|
-
|
3
|
-
class HttpRouter
|
4
|
-
module Interface
|
5
|
-
class Sinatra
|
6
|
-
|
7
|
-
def initialize
|
8
|
-
::Sinatra.send(:include, Extension)
|
9
|
-
end
|
10
|
-
|
11
|
-
module Extension
|
12
|
-
|
13
|
-
def self.registered(app)
|
14
|
-
app.send(:include, Extension)
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.included(base)
|
18
|
-
base.extend ClassMethods
|
19
|
-
end
|
20
|
-
|
21
|
-
def generate(name, *params)
|
22
|
-
self.class.generate(name, *params)
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
def route!(base=self.class, pass_block=nil)
|
27
|
-
if base.router and match = base.router.recognize(@request)
|
28
|
-
if match.first.respond_to?(:path)
|
29
|
-
@block_params = match.first.param_values
|
30
|
-
(@params ||= {}).merge!(match.first.params)
|
31
|
-
pass_block = catch(:pass) do
|
32
|
-
route_eval(&match.first.path.route.dest)
|
33
|
-
end
|
34
|
-
elsif match.is_a?(Array)
|
35
|
-
route_eval {
|
36
|
-
match[1].each{|k,v| response[k] = v}
|
37
|
-
status match[0]
|
38
|
-
}
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
# Run routes defined in superclass.
|
43
|
-
if base.superclass.respond_to?(:router)
|
44
|
-
route! base.superclass, pass_block
|
45
|
-
return
|
46
|
-
end
|
47
|
-
|
48
|
-
route_eval(&pass_block) if pass_block
|
49
|
-
|
50
|
-
route_missing
|
51
|
-
end
|
52
|
-
|
53
|
-
module ClassMethods
|
54
|
-
|
55
|
-
def new(*args, &bk)
|
56
|
-
configure! unless @_configured
|
57
|
-
super(*args, &bk)
|
58
|
-
end
|
59
|
-
|
60
|
-
def route(verb, path, options={}, &block)
|
61
|
-
name = options.delete(:name)
|
62
|
-
|
63
|
-
define_method "#{verb} #{path}", &block
|
64
|
-
unbound_method = instance_method("#{verb} #{path}")
|
65
|
-
block = block.arity.zero? ?
|
66
|
-
proc { unbound_method.bind(self).call } :
|
67
|
-
proc { unbound_method.bind(self).call(*@block_params) }
|
68
|
-
|
69
|
-
invoke_hook(:route_added, verb, path, block)
|
70
|
-
|
71
|
-
route = router.add(path)
|
72
|
-
|
73
|
-
route.matching(options[:matching]) if options.key?(:matching)
|
74
|
-
|
75
|
-
route.request_method(verb)
|
76
|
-
route.host(options[:host]) if options.key?(:host)
|
77
|
-
|
78
|
-
route.name(name) if name
|
79
|
-
route.to(block)
|
80
|
-
route
|
81
|
-
end
|
82
|
-
|
83
|
-
def router
|
84
|
-
@router ||= HttpRouter.new
|
85
|
-
block_given? ? yield(@router) : @router
|
86
|
-
end
|
87
|
-
|
88
|
-
def generate(name, *params)
|
89
|
-
router.url(name, *params)
|
90
|
-
end
|
91
|
-
|
92
|
-
def reset!
|
93
|
-
router.reset!
|
94
|
-
super
|
95
|
-
end
|
96
|
-
|
97
|
-
def configure!
|
98
|
-
configure :development do
|
99
|
-
error 404 do
|
100
|
-
content_type 'text/html'
|
101
|
-
|
102
|
-
(<<-HTML).gsub(/^ {17}/, '')
|
103
|
-
<!DOCTYPE html>
|
104
|
-
<html>
|
105
|
-
<head>
|
106
|
-
<style type="text/css">
|
107
|
-
body { text-align:center;font-family:helvetica,arial;font-size:22px;
|
108
|
-
color:#888;margin:20px}
|
109
|
-
#c {margin:0 auto;width:500px;text-align:left}
|
110
|
-
</style>
|
111
|
-
</head>
|
112
|
-
<body>
|
113
|
-
<h2>Sinatra doesn't know this ditty.</h2>
|
114
|
-
<div id="c">
|
115
|
-
Try this:
|
116
|
-
<pre>#{request.request_method.downcase} '#{request.path_info}' do\n "Hello World"\nend</pre>
|
117
|
-
</div>
|
118
|
-
</body>
|
119
|
-
</html>
|
120
|
-
HTML
|
121
|
-
end
|
122
|
-
error 405 do
|
123
|
-
content_type 'text/html'
|
124
|
-
|
125
|
-
(<<-HTML).gsub(/^ {17}/, '')
|
126
|
-
<!DOCTYPE html>
|
127
|
-
<html>
|
128
|
-
<head>
|
129
|
-
<style type="text/css">
|
130
|
-
body { text-align:center;font-family:helvetica,arial;font-size:22px;
|
131
|
-
color:#888;margin:20px}
|
132
|
-
#c {margin:0 auto;width:500px;text-align:left}
|
133
|
-
</style>
|
134
|
-
</head>
|
135
|
-
<body>
|
136
|
-
<h2>Sinatra sorta knows this ditty, but the request method is not allowed.</h2>
|
137
|
-
</body>
|
138
|
-
</html>
|
139
|
-
HTML
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
@_configured = true
|
144
|
-
end
|
145
|
-
end # ClassMethods
|
146
|
-
end # Extension
|
147
|
-
end # Sinatra
|
148
|
-
end # Interface
|
149
|
-
end # HttpRouter
|
data/lib/http_router/parts.rb
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
class HttpRouter
|
2
|
-
class Parts < Array
|
3
|
-
SLASH = '/'.freeze
|
4
|
-
SLASH_RX = Regexp.new(SLASH)
|
5
|
-
|
6
|
-
def initialize(path)
|
7
|
-
super((path[0] == ?/ ? path[1, path.size] : path).split(SLASH_RX))
|
8
|
-
end
|
9
|
-
|
10
|
-
def whole_path
|
11
|
-
@whole_path ||= join(SLASH)
|
12
|
-
end
|
13
|
-
|
14
|
-
def shift
|
15
|
-
@whole_path = nil
|
16
|
-
super
|
17
|
-
end
|
18
|
-
|
19
|
-
def replace(ary)
|
20
|
-
@whole_path = nil
|
21
|
-
super
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
data/lib/http_router/rack.rb
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
class HttpRouter
|
2
|
-
module Rack
|
3
|
-
autoload :URLMap, 'http_router/rack/url_map'
|
4
|
-
autoload :Builder, 'http_router/rack/buidler'
|
5
|
-
|
6
|
-
# Monkey-patches Rack::Builder to use HttpRouter.
|
7
|
-
# See examples/rack_mapper.rb
|
8
|
-
def self.override_rack_builder!
|
9
|
-
::Rack.class_eval("OriginalBuilder = Builder; HttpRouterBuilder = HttpRouter::Rack::Builder; remove_const :Builder; Builder = HttpRouterBuilder")
|
10
|
-
end
|
11
|
-
|
12
|
-
# Monkey-patches Rack::URLMap to use HttpRouter.
|
13
|
-
# See examples/rack_mapper.rb
|
14
|
-
def self.override_rack_urlmap!
|
15
|
-
::Rack.class_eval("OriginalURLMap = URLMap; HttpRouterURLMap = HttpRouter::Rack::URLMap; remove_const :URLMap; URLMap = HttpRouterURLMap")
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
@@ -1,60 +0,0 @@
|
|
1
|
-
# Replacement for {Rack::Builder} which using HttpRouter to map requests instead of a simple Hash.
|
2
|
-
# As well, add convenience methods for the request methods.
|
3
|
-
class HttpRouter::Rack::Builder < ::Rack::Builder
|
4
|
-
def initialize(&block)
|
5
|
-
super
|
6
|
-
end
|
7
|
-
|
8
|
-
def router
|
9
|
-
@router ||= HttpRouter.new
|
10
|
-
end
|
11
|
-
|
12
|
-
# Maps a path to a block.
|
13
|
-
# @param path [String] Path to map to.
|
14
|
-
# @param options [Hash] Options for added path.
|
15
|
-
# @see HttpRouter#add
|
16
|
-
def map(path, options = nil, &block)
|
17
|
-
router.add(path).with_options(options).to(&block)
|
18
|
-
@ins << router unless @ins.last == router
|
19
|
-
end
|
20
|
-
|
21
|
-
# Maps a path with request methods `HEAD` and `GET` to a block.
|
22
|
-
# @param path [String] Path to map to.
|
23
|
-
# @param options [Hash] Options for added path.
|
24
|
-
# @see HttpRouter#add
|
25
|
-
def get(path, options = nil, &block)
|
26
|
-
router.get(path).with_options(options).to(&block)
|
27
|
-
end
|
28
|
-
|
29
|
-
# Maps a path with request methods `POST` to a block.
|
30
|
-
# @param path [String] Path to map to.
|
31
|
-
# @param options [Hash] Options for added path.
|
32
|
-
# @see HttpRouter#add
|
33
|
-
def post(path, options = nil, &block)
|
34
|
-
router.post(path).with_options(options).to(&block)
|
35
|
-
end
|
36
|
-
|
37
|
-
# Maps a path with request methods `PUT` to a block.
|
38
|
-
# @param path [String] Path to map to.
|
39
|
-
# @param options [Hash] Options for added path.
|
40
|
-
# @see HttpRouter#add
|
41
|
-
def put(path, options = nil, &block)
|
42
|
-
router.put(path).with_options(options).to(&block)
|
43
|
-
end
|
44
|
-
|
45
|
-
# Maps a path with request methods `DELETE` to a block.
|
46
|
-
# @param path [String] Path to map to.
|
47
|
-
# @param options [Hash] Options for added path.
|
48
|
-
# @see HttpRouter#add
|
49
|
-
def delete(path, options = nil, &block)
|
50
|
-
router.delete(path).with_options(options).to(&block)
|
51
|
-
end
|
52
|
-
|
53
|
-
# Maps a path with request methods `HEAD` to a block.
|
54
|
-
# @param path [String] Path to map to.
|
55
|
-
# @param options [Hash] Options for added path.
|
56
|
-
# @see HttpRouter#add
|
57
|
-
def head(path, options = nil, &block)
|
58
|
-
router.head(path).with_options(options).to(&block)
|
59
|
-
end
|
60
|
-
end
|
@@ -1,10 +0,0 @@
|
|
1
|
-
class HttpRouter::Rack::URLMap < ::Rack::URLMap
|
2
|
-
def initialize(map = {})
|
3
|
-
@router = HttpRouter.new
|
4
|
-
map.each { |path, app| (path =~ /^(https?):\/\/(.*?)(\/.*)/ ? @router.add($3).host($2).scheme($1) : @router.add(path)).partial.to(app) }
|
5
|
-
end
|
6
|
-
|
7
|
-
def call(env)
|
8
|
-
@router.call(env)
|
9
|
-
end
|
10
|
-
end
|
data/lib/http_router/root.rb
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
class HttpRouter
|
2
|
-
class Root < Node
|
3
|
-
class AlternativeRequestMethods < Array
|
4
|
-
attr_accessor :request_method_found
|
5
|
-
end
|
6
|
-
|
7
|
-
def add_path(path)
|
8
|
-
node = path.parts.inject(self) { |node, part| node.add(part) }
|
9
|
-
node
|
10
|
-
end
|
11
|
-
|
12
|
-
def recognize(request)
|
13
|
-
call(request, :nocall)
|
14
|
-
end
|
15
|
-
|
16
|
-
def call(request, action = :call)
|
17
|
-
request = ::Rack::Request.new(request) if request.is_a?(Hash)
|
18
|
-
catch(:response) { find_on_parts(request, get_parts(request), action) } || construct_unmatched(request)
|
19
|
-
end
|
20
|
-
|
21
|
-
def construct_unmatched(request)
|
22
|
-
alternate_methods = (router.request_methods_specified - [request.request_method]).select do |alternate_method|
|
23
|
-
test_request = ::Rack::Request.new(request.env.dup)
|
24
|
-
test_request.env['REQUEST_METHOD'] = alternate_method
|
25
|
-
catch(:response) { find_on_parts(test_request, get_parts(request), :nocall) }
|
26
|
-
end
|
27
|
-
alternate_methods.empty? ? nil : ::Rack::Response.new("Method not found", 405, {"Allow" => alternate_methods.join(", ")}).finish
|
28
|
-
end
|
29
|
-
|
30
|
-
def get_parts(request)
|
31
|
-
parts = router.split(request.path_info)
|
32
|
-
parts << '' if request.path_info.size > 1 && request.path_info[-1] == ?/
|
33
|
-
parts
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
data/lib/http_router/static.rb
DELETED
data/lib/http_router/variable.rb
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
class HttpRouter
|
2
|
-
class Variable
|
3
|
-
attr_reader :name, :matches_with
|
4
|
-
attr_accessor :priority
|
5
|
-
|
6
|
-
def initialize(router, name, matches_with = nil, priority = 0)
|
7
|
-
@router, @name, @matches_with, @priority = router, name, matches_with, priority
|
8
|
-
end
|
9
|
-
|
10
|
-
def matches?(parts)
|
11
|
-
@matches_with.nil? or (@matches_with and match = @matches_with.match(parts.whole_path) and match.begin(0) == 0) ? match : nil
|
12
|
-
end
|
13
|
-
|
14
|
-
def consume(match, parts)
|
15
|
-
if @matches_with
|
16
|
-
parts.replace(router.split(parts.whole_path[match.end(0), parts.whole_path.size]))
|
17
|
-
match[0]
|
18
|
-
else
|
19
|
-
parts.shift
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def ===(part)
|
24
|
-
@matches_with.nil?
|
25
|
-
end
|
26
|
-
|
27
|
-
protected
|
28
|
-
attr_reader :router
|
29
|
-
end
|
30
|
-
end
|
@@ -1,168 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require "sinatra"
|
3
|
-
require "http_router/interface/sinatra"
|
4
|
-
|
5
|
-
describe "HttpRouter (for Sinatra) route recognition" do
|
6
|
-
before(:each) do
|
7
|
-
@app = Sinatra.new { register HttpRouter::Interface::Sinatra::Extension }
|
8
|
-
@app.extend(CallWithMockRequestMixin)
|
9
|
-
@app.reset!
|
10
|
-
end
|
11
|
-
|
12
|
-
describe "basic functionality" do
|
13
|
-
it "should map not found" do
|
14
|
-
response = @app.call_with_mock_request('/bar')
|
15
|
-
response.status.should == 404
|
16
|
-
end
|
17
|
-
|
18
|
-
it "should map index" do
|
19
|
-
@app.get("/") { "index" }
|
20
|
-
response = @app.call_with_mock_request('/')
|
21
|
-
response.status.should == 200
|
22
|
-
response.body.should == "index"
|
23
|
-
end
|
24
|
-
|
25
|
-
it "should ignore trailing delimiters" do
|
26
|
-
@app.get("/foo") { "foo" }
|
27
|
-
response = @app.call_with_mock_request('/foo')
|
28
|
-
response.status.should == 200
|
29
|
-
response.body.should == "foo"
|
30
|
-
response = @app.call_with_mock_request('/foo/')
|
31
|
-
response.status.should == 200
|
32
|
-
response.body.should == "foo"
|
33
|
-
end
|
34
|
-
|
35
|
-
it "should ignore trailing delimiters in a more advanced route" do
|
36
|
-
@app.get("/foo") { "foo" }
|
37
|
-
@app.get("/foo/bar") { "bar" }
|
38
|
-
response = @app.call_with_mock_request('/foo')
|
39
|
-
response.status.should == 200
|
40
|
-
response.body.should == "foo"
|
41
|
-
response = @app.call_with_mock_request('/foo/bar')
|
42
|
-
response.status.should == 200
|
43
|
-
response.body.should == "bar"
|
44
|
-
response = @app.call_with_mock_request('/foo/')
|
45
|
-
response.status.should == 200
|
46
|
-
response.body.should == "foo"
|
47
|
-
response = @app.call_with_mock_request('/foo/bar/')
|
48
|
-
response.status.should == 200
|
49
|
-
response.body.should == "bar"
|
50
|
-
end
|
51
|
-
|
52
|
-
it "should ignore trailing delimiters with an optional param" do
|
53
|
-
@app.get("/foo/(:bar)") { params[:bar] }
|
54
|
-
@app.get("/bar(/:foo)") { params[:foo] }
|
55
|
-
response = @app.call_with_mock_request('/foo/bar')
|
56
|
-
response.status.should == 200
|
57
|
-
response.body.should == "bar"
|
58
|
-
response = @app.call_with_mock_request('/bar/foo')
|
59
|
-
response.status.should == 200
|
60
|
-
response.body.should == "foo"
|
61
|
-
response = @app.call_with_mock_request('/bar')
|
62
|
-
response.status.should == 200
|
63
|
-
response.body.should == ""
|
64
|
-
response = @app.call_with_mock_request('/bar/')
|
65
|
-
response.status.should == 200
|
66
|
-
response.body.should == ""
|
67
|
-
end
|
68
|
-
|
69
|
-
it "should use sinatra optionals trailing delimiters" do
|
70
|
-
@app.get("/foo/?") { "foo" }
|
71
|
-
response = @app.call_with_mock_request('/foo')
|
72
|
-
response.status.should == 200
|
73
|
-
response.body.should == "foo"
|
74
|
-
response = @app.call_with_mock_request('/foo/')
|
75
|
-
response.status.should == 200
|
76
|
-
response.body.should == "foo"
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
describe "mapping functionality" do
|
81
|
-
|
82
|
-
it "should map a basic route" do
|
83
|
-
@app.get('/hi', :name => :hi) { generate(:hi) }
|
84
|
-
response = @app.call_with_mock_request('/hi')
|
85
|
-
response.status.should == 200
|
86
|
-
response.body.should == "/hi"
|
87
|
-
end
|
88
|
-
|
89
|
-
it "should map a basic route ignoring trailing delimiters" do
|
90
|
-
@app.get('/hi', :name => :hi) { generate(:hi) }
|
91
|
-
response = @app.call_with_mock_request('/hi/')
|
92
|
-
response.status.should == 200
|
93
|
-
response.body.should == "/hi"
|
94
|
-
end
|
95
|
-
|
96
|
-
it "should map a basic route with params" do
|
97
|
-
@app.get('/hi/:id', :name => :hi) { generate(:hi, :id => 18) }
|
98
|
-
response = @app.call_with_mock_request('/hi/1')
|
99
|
-
response.status.should == 200
|
100
|
-
response.body.should == "/hi/18"
|
101
|
-
end
|
102
|
-
|
103
|
-
it "should map route with params" do
|
104
|
-
@app.get('/hi-:id', :name => :hi) { generate(:hi, :id => 18) }
|
105
|
-
response = @app.call_with_mock_request('/hi-1')
|
106
|
-
response.status.should == 200
|
107
|
-
response.body.should == "/hi-18"
|
108
|
-
end
|
109
|
-
|
110
|
-
it "should map route with complex params" do
|
111
|
-
@app.get('/hi/:foo/:bar/:baz(.:format)') { "/#{params[:foo]}/#{params[:bar]}/#{params[:baz]}/#{params[:format]}" }
|
112
|
-
response = @app.call_with_mock_request('/hi/foo/bar/baz')
|
113
|
-
response.status.should == 200
|
114
|
-
response.body.should == "/foo/bar/baz/"
|
115
|
-
response = @app.call_with_mock_request('/hi/foo/bar-bax/baz')
|
116
|
-
response.status.should == 200
|
117
|
-
response.body.should == "/foo/bar-bax/baz/"
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
describe "matching by regexp" do
|
122
|
-
before :each do
|
123
|
-
@app.get('/numbers/:digits', :matching => { :digits => /\d+/ }) { params[:digits] }
|
124
|
-
end
|
125
|
-
|
126
|
-
describe "when regexp is matched" do
|
127
|
-
before :each do
|
128
|
-
@response = @app.call_with_mock_request('/numbers/2010')
|
129
|
-
end
|
130
|
-
|
131
|
-
it "should map successfully" do
|
132
|
-
@response.status.should == 200
|
133
|
-
@response.body.should == "2010"
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
describe "when regexp is not matched" do
|
138
|
-
before :each do
|
139
|
-
@response = @app.call_with_mock_request('/numbers/boobs')
|
140
|
-
end
|
141
|
-
|
142
|
-
it "should not map" do
|
143
|
-
@response.status.should == 404
|
144
|
-
end
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
describe "not found" do
|
149
|
-
|
150
|
-
it "should correctly generate a not found page without images" do
|
151
|
-
response = @app.call_with_mock_request('/bar')
|
152
|
-
response.status.should == 404
|
153
|
-
response.body.should_not match(/__sinatra__/)
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
describe "method not allowed" do
|
158
|
-
|
159
|
-
it "should correctly generate a not found page without images and return a 405" do
|
160
|
-
@app.post('/bar') { 'found' }
|
161
|
-
@app.put('/bar') { 'found' }
|
162
|
-
response = @app.call_with_mock_request('/bar')
|
163
|
-
response.status.should == 405
|
164
|
-
response.headers['Allow'].should == 'POST, PUT'
|
165
|
-
response.body.should_not match(/__sinatra__/)
|
166
|
-
end
|
167
|
-
end
|
168
|
-
end
|