http_router 0.5.4 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|