devcenter 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (128) hide show
  1. data/CONTRIBUTING.md +14 -0
  2. data/Gemfile +0 -4
  3. data/devcenter.gemspec +2 -1
  4. data/lib/devcenter.rb +0 -1
  5. data/lib/devcenter/previewer/web_app.rb +3 -2
  6. data/lib/devcenter/version.rb +1 -1
  7. metadata +19 -124
  8. data/vendor/sinatra/.gitignore +0 -6
  9. data/vendor/sinatra/.travis.yml +0 -16
  10. data/vendor/sinatra/.yardopts +0 -4
  11. data/vendor/sinatra/AUTHORS +0 -61
  12. data/vendor/sinatra/Gemfile +0 -91
  13. data/vendor/sinatra/LICENSE +0 -22
  14. data/vendor/sinatra/README.de.rdoc +0 -2116
  15. data/vendor/sinatra/README.es.rdoc +0 -2106
  16. data/vendor/sinatra/README.fr.rdoc +0 -2133
  17. data/vendor/sinatra/README.hu.rdoc +0 -608
  18. data/vendor/sinatra/README.jp.rdoc +0 -1056
  19. data/vendor/sinatra/README.ko.rdoc +0 -1932
  20. data/vendor/sinatra/README.pt-br.rdoc +0 -778
  21. data/vendor/sinatra/README.pt-pt.rdoc +0 -647
  22. data/vendor/sinatra/README.rdoc +0 -2049
  23. data/vendor/sinatra/README.ru.rdoc +0 -2033
  24. data/vendor/sinatra/README.zh.rdoc +0 -1816
  25. data/vendor/sinatra/Rakefile +0 -182
  26. data/vendor/sinatra/examples/chat.rb +0 -61
  27. data/vendor/sinatra/examples/simple.rb +0 -3
  28. data/vendor/sinatra/examples/stream.ru +0 -26
  29. data/vendor/sinatra/lib/sinatra.rb +0 -5
  30. data/vendor/sinatra/lib/sinatra/base.rb +0 -1820
  31. data/vendor/sinatra/lib/sinatra/images/404.png +0 -0
  32. data/vendor/sinatra/lib/sinatra/images/500.png +0 -0
  33. data/vendor/sinatra/lib/sinatra/main.rb +0 -30
  34. data/vendor/sinatra/lib/sinatra/showexceptions.rb +0 -345
  35. data/vendor/sinatra/lib/sinatra/version.rb +0 -3
  36. data/vendor/sinatra/sinatra.gemspec +0 -18
  37. data/vendor/sinatra/test/base_test.rb +0 -172
  38. data/vendor/sinatra/test/builder_test.rb +0 -91
  39. data/vendor/sinatra/test/coffee_test.rb +0 -90
  40. data/vendor/sinatra/test/compile_test.rb +0 -139
  41. data/vendor/sinatra/test/contest.rb +0 -98
  42. data/vendor/sinatra/test/creole_test.rb +0 -65
  43. data/vendor/sinatra/test/delegator_test.rb +0 -160
  44. data/vendor/sinatra/test/encoding_test.rb +0 -20
  45. data/vendor/sinatra/test/erb_test.rb +0 -98
  46. data/vendor/sinatra/test/extensions_test.rb +0 -98
  47. data/vendor/sinatra/test/filter_test.rb +0 -437
  48. data/vendor/sinatra/test/haml_test.rb +0 -91
  49. data/vendor/sinatra/test/helper.rb +0 -123
  50. data/vendor/sinatra/test/helpers_test.rb +0 -1768
  51. data/vendor/sinatra/test/integration/app.rb +0 -62
  52. data/vendor/sinatra/test/integration_helper.rb +0 -222
  53. data/vendor/sinatra/test/integration_test.rb +0 -87
  54. data/vendor/sinatra/test/less_test.rb +0 -69
  55. data/vendor/sinatra/test/liquid_test.rb +0 -59
  56. data/vendor/sinatra/test/mapped_error_test.rb +0 -305
  57. data/vendor/sinatra/test/markaby_test.rb +0 -80
  58. data/vendor/sinatra/test/markdown_test.rb +0 -82
  59. data/vendor/sinatra/test/middleware_test.rb +0 -68
  60. data/vendor/sinatra/test/nokogiri_test.rb +0 -67
  61. data/vendor/sinatra/test/public/favicon.ico +0 -0
  62. data/vendor/sinatra/test/rabl_test.rb +0 -89
  63. data/vendor/sinatra/test/rack_test.rb +0 -45
  64. data/vendor/sinatra/test/radius_test.rb +0 -59
  65. data/vendor/sinatra/test/rdoc_test.rb +0 -66
  66. data/vendor/sinatra/test/readme_test.rb +0 -120
  67. data/vendor/sinatra/test/request_test.rb +0 -45
  68. data/vendor/sinatra/test/response_test.rb +0 -64
  69. data/vendor/sinatra/test/result_test.rb +0 -76
  70. data/vendor/sinatra/test/route_added_hook_test.rb +0 -59
  71. data/vendor/sinatra/test/routing_test.rb +0 -1175
  72. data/vendor/sinatra/test/sass_test.rb +0 -116
  73. data/vendor/sinatra/test/scss_test.rb +0 -89
  74. data/vendor/sinatra/test/server_test.rb +0 -48
  75. data/vendor/sinatra/test/settings_test.rb +0 -561
  76. data/vendor/sinatra/test/sinatra_test.rb +0 -12
  77. data/vendor/sinatra/test/slim_test.rb +0 -84
  78. data/vendor/sinatra/test/static_test.rb +0 -219
  79. data/vendor/sinatra/test/streaming_test.rb +0 -149
  80. data/vendor/sinatra/test/templates_test.rb +0 -333
  81. data/vendor/sinatra/test/textile_test.rb +0 -65
  82. data/vendor/sinatra/test/views/a/in_a.str +0 -1
  83. data/vendor/sinatra/test/views/ascii.erb +0 -2
  84. data/vendor/sinatra/test/views/b/in_b.str +0 -1
  85. data/vendor/sinatra/test/views/calc.html.erb +0 -1
  86. data/vendor/sinatra/test/views/error.builder +0 -3
  87. data/vendor/sinatra/test/views/error.erb +0 -3
  88. data/vendor/sinatra/test/views/error.haml +0 -3
  89. data/vendor/sinatra/test/views/error.sass +0 -2
  90. data/vendor/sinatra/test/views/explicitly_nested.str +0 -1
  91. data/vendor/sinatra/test/views/foo/hello.test +0 -1
  92. data/vendor/sinatra/test/views/hello.builder +0 -1
  93. data/vendor/sinatra/test/views/hello.coffee +0 -1
  94. data/vendor/sinatra/test/views/hello.creole +0 -1
  95. data/vendor/sinatra/test/views/hello.erb +0 -1
  96. data/vendor/sinatra/test/views/hello.haml +0 -1
  97. data/vendor/sinatra/test/views/hello.less +0 -5
  98. data/vendor/sinatra/test/views/hello.liquid +0 -1
  99. data/vendor/sinatra/test/views/hello.mab +0 -1
  100. data/vendor/sinatra/test/views/hello.md +0 -1
  101. data/vendor/sinatra/test/views/hello.nokogiri +0 -1
  102. data/vendor/sinatra/test/views/hello.rabl +0 -2
  103. data/vendor/sinatra/test/views/hello.radius +0 -1
  104. data/vendor/sinatra/test/views/hello.rdoc +0 -1
  105. data/vendor/sinatra/test/views/hello.sass +0 -2
  106. data/vendor/sinatra/test/views/hello.scss +0 -3
  107. data/vendor/sinatra/test/views/hello.slim +0 -1
  108. data/vendor/sinatra/test/views/hello.str +0 -1
  109. data/vendor/sinatra/test/views/hello.test +0 -1
  110. data/vendor/sinatra/test/views/hello.textile +0 -1
  111. data/vendor/sinatra/test/views/hello.wlang +0 -1
  112. data/vendor/sinatra/test/views/hello.yajl +0 -1
  113. data/vendor/sinatra/test/views/layout2.builder +0 -3
  114. data/vendor/sinatra/test/views/layout2.erb +0 -2
  115. data/vendor/sinatra/test/views/layout2.haml +0 -2
  116. data/vendor/sinatra/test/views/layout2.liquid +0 -2
  117. data/vendor/sinatra/test/views/layout2.mab +0 -2
  118. data/vendor/sinatra/test/views/layout2.nokogiri +0 -3
  119. data/vendor/sinatra/test/views/layout2.rabl +0 -3
  120. data/vendor/sinatra/test/views/layout2.radius +0 -2
  121. data/vendor/sinatra/test/views/layout2.slim +0 -3
  122. data/vendor/sinatra/test/views/layout2.str +0 -2
  123. data/vendor/sinatra/test/views/layout2.test +0 -1
  124. data/vendor/sinatra/test/views/layout2.wlang +0 -2
  125. data/vendor/sinatra/test/views/nested.str +0 -1
  126. data/vendor/sinatra/test/views/utf8.erb +0 -2
  127. data/vendor/sinatra/test/wlang_test.rb +0 -70
  128. data/vendor/sinatra/test/yajl_test.rb +0 -86
@@ -1,45 +0,0 @@
1
- require File.expand_path('../helper', __FILE__)
2
- require 'stringio'
3
-
4
- class RequestTest < Test::Unit::TestCase
5
- it 'responds to #user_agent' do
6
- request = Sinatra::Request.new({'HTTP_USER_AGENT' => 'Test'})
7
- assert request.respond_to?(:user_agent)
8
- assert_equal 'Test', request.user_agent
9
- end
10
-
11
- it 'parses POST params when Content-Type is form-dataish' do
12
- request = Sinatra::Request.new(
13
- 'REQUEST_METHOD' => 'PUT',
14
- 'CONTENT_TYPE' => 'application/x-www-form-urlencoded',
15
- 'rack.input' => StringIO.new('foo=bar')
16
- )
17
- assert_equal 'bar', request.params['foo']
18
- end
19
-
20
- it 'is secure when the url scheme is https' do
21
- request = Sinatra::Request.new('rack.url_scheme' => 'https')
22
- assert request.secure?
23
- end
24
-
25
- it 'is not secure when the url scheme is http' do
26
- request = Sinatra::Request.new('rack.url_scheme' => 'http')
27
- assert !request.secure?
28
- end
29
-
30
- it 'respects X-Forwarded-Proto header for proxied SSL' do
31
- request = Sinatra::Request.new('HTTP_X_FORWARDED_PROTO' => 'https')
32
- assert request.secure?
33
- end
34
-
35
- it 'is possible to marshal params' do
36
- request = Sinatra::Request.new(
37
- 'REQUEST_METHOD' => 'PUT',
38
- 'CONTENT_TYPE' => 'application/x-www-form-urlencoded',
39
- 'rack.input' => StringIO.new('foo=bar')
40
- )
41
- params = Sinatra::Base.new!.send(:indifferent_hash).replace(request.params)
42
- dumped = Marshal.dump(request.params)
43
- assert_equal 'bar', Marshal.load(dumped)['foo']
44
- end
45
- end
@@ -1,64 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require File.expand_path('../helper', __FILE__)
4
-
5
- class ResponseTest < Test::Unit::TestCase
6
- setup { @response = Sinatra::Response.new }
7
-
8
- def assert_same_body(a, b)
9
- enum = Enumerable.const_get(:Enumerator)
10
- assert_equal enum.new(a).to_a, enum.new(b).to_a
11
- end
12
-
13
- it "initializes with 200, text/html, and empty body" do
14
- assert_equal 200, @response.status
15
- assert_equal 'text/html', @response['Content-Type']
16
- assert_equal [], @response.body
17
- end
18
-
19
- it 'uses case insensitive headers' do
20
- @response['content-type'] = 'application/foo'
21
- assert_equal 'application/foo', @response['Content-Type']
22
- assert_equal 'application/foo', @response['CONTENT-TYPE']
23
- end
24
-
25
- it 'writes to body' do
26
- @response.body = 'Hello'
27
- @response.write ' World'
28
- assert_equal 'Hello World', @response.body.join
29
- end
30
-
31
- [204, 304].each do |status_code|
32
- it "removes the Content-Type header and body when response status is #{status_code}" do
33
- @response.status = status_code
34
- @response.body = ['Hello World']
35
- assert_equal [status_code, {}, []], @response.finish
36
- end
37
- end
38
-
39
- it 'Calculates the Content-Length using the bytesize of the body' do
40
- @response.body = ['Hello', 'World!', '✈']
41
- status, headers, body = @response.finish
42
- assert_equal '14', headers['Content-Length']
43
- assert_same_body @response.body, body
44
- end
45
-
46
- it 'does not call #to_ary or #inject on the body' do
47
- object = Object.new
48
- def object.inject(*) fail 'called' end
49
- def object.to_ary(*) fail 'called' end
50
- def object.each(*) end
51
- @response.body = object
52
- assert @response.finish
53
- end
54
-
55
- it 'does not nest a Sinatra::Response' do
56
- @response.body = Sinatra::Response.new ["foo"]
57
- assert_same_body @response.body, ["foo"]
58
- end
59
-
60
- it 'does not nest a Rack::Response' do
61
- @response.body = Rack::Response.new ["foo"]
62
- assert_same_body @response.body, ["foo"]
63
- end
64
- end
@@ -1,76 +0,0 @@
1
- require File.expand_path('../helper', __FILE__)
2
-
3
- class ResultTest < Test::Unit::TestCase
4
- it "sets response.body when result is a String" do
5
- mock_app { get('/') { 'Hello World' } }
6
-
7
- get '/'
8
- assert ok?
9
- assert_equal 'Hello World', body
10
- end
11
-
12
- it "sets response.body when result is an Array of Strings" do
13
- mock_app { get('/') { ['Hello', 'World'] } }
14
-
15
- get '/'
16
- assert ok?
17
- assert_equal 'HelloWorld', body
18
- end
19
-
20
- it "sets response.body when result responds to #each" do
21
- mock_app do
22
- get('/') do
23
- res = lambda { 'Hello World' }
24
- def res.each ; yield call ; end
25
- return res
26
- end
27
- end
28
-
29
- get '/'
30
- assert ok?
31
- assert_equal 'Hello World', body
32
- end
33
-
34
- it "sets response.body to [] when result is nil" do
35
- mock_app { get( '/') { nil } }
36
-
37
- get '/'
38
- assert ok?
39
- assert_equal '', body
40
- end
41
-
42
- it "sets status, headers, and body when result is a Rack response tuple" do
43
- mock_app {
44
- get('/') { [203, {'Content-Type' => 'foo/bar'}, 'Hello World'] }
45
- }
46
-
47
- get '/'
48
- assert_equal 203, status
49
- assert_equal 'foo/bar', response['Content-Type']
50
- assert_equal 'Hello World', body
51
- end
52
-
53
- it "sets status and body when result is a two-tuple" do
54
- mock_app { get('/') { [409, 'formula of'] } }
55
-
56
- get '/'
57
- assert_equal 409, status
58
- assert_equal 'formula of', body
59
- end
60
-
61
- it "raises a ArgumentError when result is a non two or three tuple Array" do
62
- mock_app {
63
- get('/') { [409, 'formula of', 'something else', 'even more'] }
64
- }
65
-
66
- assert_raise(ArgumentError) { get '/' }
67
- end
68
-
69
- it "sets status when result is a Fixnum status code" do
70
- mock_app { get('/') { 205 } }
71
-
72
- get '/'
73
- assert_equal 205, status
74
- assert_equal '', body
75
- end
76
- end
@@ -1,59 +0,0 @@
1
- require File.expand_path('../helper', __FILE__)
2
-
3
- module RouteAddedTest
4
- @routes, @procs = [], []
5
- def self.routes ; @routes ; end
6
- def self.procs ; @procs ; end
7
- def self.route_added(verb, path, proc)
8
- @routes << [verb, path]
9
- @procs << proc
10
- end
11
- end
12
-
13
- class RouteAddedHookTest < Test::Unit::TestCase
14
- setup do
15
- RouteAddedTest.routes.clear
16
- RouteAddedTest.procs.clear
17
- end
18
-
19
- it "should be notified of an added route" do
20
- mock_app(Class.new(Sinatra::Base)) do
21
- register RouteAddedTest
22
- get('/') {}
23
- end
24
-
25
- assert_equal [["GET", "/"], ["HEAD", "/"]],
26
- RouteAddedTest.routes
27
- end
28
-
29
- it "should include hooks from superclass" do
30
- a = Class.new(Class.new(Sinatra::Base))
31
- b = Class.new(a)
32
-
33
- a.register RouteAddedTest
34
- b.class_eval { post("/sub_app_route") {} }
35
-
36
- assert_equal [["POST", "/sub_app_route"]],
37
- RouteAddedTest.routes
38
- end
39
-
40
- it "should only run once per extension" do
41
- mock_app(Class.new(Sinatra::Base)) do
42
- register RouteAddedTest
43
- register RouteAddedTest
44
- get('/') {}
45
- end
46
-
47
- assert_equal [["GET", "/"], ["HEAD", "/"]],
48
- RouteAddedTest.routes
49
- end
50
-
51
- it "should pass route blocks as an argument" do
52
- mock_app(Class.new(Sinatra::Base)) do
53
- register RouteAddedTest
54
- get('/') {}
55
- end
56
-
57
- assert_kind_of Proc, RouteAddedTest.procs.first
58
- end
59
- end
@@ -1,1175 +0,0 @@
1
- # I like coding: UTF-8
2
- require File.expand_path('../helper', __FILE__)
3
-
4
- # Helper method for easy route pattern matching testing
5
- def route_def(pattern)
6
- mock_app { get(pattern) { } }
7
- end
8
-
9
- class RegexpLookAlike
10
- class MatchData
11
- def captures
12
- ["this", "is", "a", "test"]
13
- end
14
- end
15
-
16
- def match(string)
17
- ::RegexpLookAlike::MatchData.new if string == "/this/is/a/test/"
18
- end
19
-
20
- def keys
21
- ["one", "two", "three", "four"]
22
- end
23
- end
24
-
25
- class RoutingTest < Test::Unit::TestCase
26
- %w[get put post delete options patch].each do |verb|
27
- it "defines #{verb.upcase} request handlers with #{verb}" do
28
- mock_app {
29
- send verb, '/hello' do
30
- 'Hello World'
31
- end
32
- }
33
-
34
- request = Rack::MockRequest.new(@app)
35
- response = request.request(verb.upcase, '/hello', {})
36
- assert response.ok?
37
- assert_equal 'Hello World', response.body
38
- end
39
- end
40
-
41
- it "defines HEAD request handlers with HEAD" do
42
- mock_app {
43
- head '/hello' do
44
- response['X-Hello'] = 'World!'
45
- 'remove me'
46
- end
47
- }
48
-
49
- request = Rack::MockRequest.new(@app)
50
- response = request.request('HEAD', '/hello', {})
51
- assert response.ok?
52
- assert_equal 'World!', response['X-Hello']
53
- assert_equal '', response.body
54
- end
55
-
56
- it "404s when no route satisfies the request" do
57
- mock_app {
58
- get('/foo') { }
59
- }
60
- get '/bar'
61
- assert_equal 404, status
62
- end
63
-
64
- it "404s and sets X-Cascade header when no route satisfies the request" do
65
- mock_app {
66
- get('/foo') { }
67
- }
68
- get '/bar'
69
- assert_equal 404, status
70
- assert_equal 'pass', response.headers['X-Cascade']
71
- end
72
-
73
- it "allows using unicode" do
74
- mock_app do
75
- get('/föö') { }
76
- end
77
- get '/f%C3%B6%C3%B6'
78
- assert_equal 200, status
79
- end
80
-
81
- it "it handles encoded slashes correctly" do
82
- mock_app { get("/:a") { |a| a } }
83
- get '/foo%2Fbar'
84
- assert_equal 200, status
85
- assert_body "foo/bar"
86
- end
87
-
88
- it "overrides the content-type in error handlers" do
89
- mock_app {
90
- before { content_type 'text/plain' }
91
- error Sinatra::NotFound do
92
- content_type "text/html"
93
- "<h1>Not Found</h1>"
94
- end
95
- }
96
-
97
- get '/foo'
98
- assert_equal 404, status
99
- assert_equal 'text/html;charset=utf-8', response["Content-Type"]
100
- assert_equal "<h1>Not Found</h1>", response.body
101
- end
102
-
103
- it 'matches empty PATH_INFO to "/" if no route is defined for ""' do
104
- mock_app do
105
- get '/' do
106
- 'worked'
107
- end
108
- end
109
-
110
- get '/', {}, "PATH_INFO" => ""
111
- assert ok?
112
- assert_equal 'worked', body
113
- end
114
-
115
- it 'matches empty PATH_INFO to "" if a route is defined for ""' do
116
- mock_app do
117
- disable :protection
118
-
119
- get '/' do
120
- 'did not work'
121
- end
122
-
123
- get '' do
124
- 'worked'
125
- end
126
- end
127
-
128
- get '/', {}, "PATH_INFO" => ""
129
- assert ok?
130
- assert_equal 'worked', body
131
- end
132
-
133
- it 'takes multiple definitions of a route' do
134
- mock_app {
135
- user_agent(/Foo/)
136
- get '/foo' do
137
- 'foo'
138
- end
139
-
140
- get '/foo' do
141
- 'not foo'
142
- end
143
- }
144
-
145
- get '/foo', {}, 'HTTP_USER_AGENT' => 'Foo'
146
- assert ok?
147
- assert_equal 'foo', body
148
-
149
- get '/foo'
150
- assert ok?
151
- assert_equal 'not foo', body
152
- end
153
-
154
- it "exposes params with indifferent hash" do
155
- mock_app {
156
- get '/:foo' do
157
- assert_equal 'bar', params['foo']
158
- assert_equal 'bar', params[:foo]
159
- 'well, alright'
160
- end
161
- }
162
- get '/bar'
163
- assert_equal 'well, alright', body
164
- end
165
-
166
- it "merges named params and query string params in params" do
167
- mock_app {
168
- get '/:foo' do
169
- assert_equal 'bar', params['foo']
170
- assert_equal 'biz', params['baz']
171
- end
172
- }
173
- get '/bar?baz=biz'
174
- assert ok?
175
- end
176
-
177
- it "supports named params like /hello/:person" do
178
- mock_app {
179
- get '/hello/:person' do
180
- "Hello #{params['person']}"
181
- end
182
- }
183
- get '/hello/Frank'
184
- assert_equal 'Hello Frank', body
185
- end
186
-
187
- it "supports optional named params like /?:foo?/?:bar?" do
188
- mock_app {
189
- get '/?:foo?/?:bar?' do
190
- "foo=#{params[:foo]};bar=#{params[:bar]}"
191
- end
192
- }
193
-
194
- get '/hello/world'
195
- assert ok?
196
- assert_equal "foo=hello;bar=world", body
197
-
198
- get '/hello'
199
- assert ok?
200
- assert_equal "foo=hello;bar=", body
201
-
202
- get '/'
203
- assert ok?
204
- assert_equal "foo=;bar=", body
205
- end
206
-
207
- it "supports named captures like %r{/hello/(?<person>[^/?#]+)} on Ruby >= 1.9" do
208
- next if RUBY_VERSION < '1.9'
209
- mock_app {
210
- get Regexp.new('/hello/(?<person>[^/?#]+)') do
211
- "Hello #{params['person']}"
212
- end
213
- }
214
- get '/hello/Frank'
215
- assert_equal 'Hello Frank', body
216
- end
217
-
218
- it "supports optional named captures like %r{/page(?<format>.[^/?#]+)?} on Ruby >= 1.9" do
219
- next if RUBY_VERSION < '1.9'
220
- mock_app {
221
- get Regexp.new('/page(?<format>.[^/?#]+)?') do
222
- "format=#{params[:format]}"
223
- end
224
- }
225
-
226
- get '/page.html'
227
- assert ok?
228
- assert_equal "format=.html", body
229
-
230
- get '/page.xml'
231
- assert ok?
232
- assert_equal "format=.xml", body
233
-
234
- get '/page'
235
- assert ok?
236
- assert_equal "format=", body
237
- end
238
-
239
- it 'does not concatinate params with the same name' do
240
- mock_app { get('/:foo') { params[:foo] } }
241
- get '/a?foo=b'
242
- assert_body 'a'
243
- end
244
-
245
- it "supports single splat params like /*" do
246
- mock_app {
247
- get '/*' do
248
- assert params['splat'].kind_of?(Array)
249
- params['splat'].join "\n"
250
- end
251
- }
252
-
253
- get '/foo'
254
- assert_equal "foo", body
255
-
256
- get '/foo/bar/baz'
257
- assert_equal "foo/bar/baz", body
258
- end
259
-
260
- it "supports mixing multiple splat params like /*/foo/*/*" do
261
- mock_app {
262
- get '/*/foo/*/*' do
263
- assert params['splat'].kind_of?(Array)
264
- params['splat'].join "\n"
265
- end
266
- }
267
-
268
- get '/bar/foo/bling/baz/boom'
269
- assert_equal "bar\nbling\nbaz/boom", body
270
-
271
- get '/bar/foo/baz'
272
- assert not_found?
273
- end
274
-
275
- it "supports mixing named and splat params like /:foo/*" do
276
- mock_app {
277
- get '/:foo/*' do
278
- assert_equal 'foo', params['foo']
279
- assert_equal ['bar/baz'], params['splat']
280
- end
281
- }
282
-
283
- get '/foo/bar/baz'
284
- assert ok?
285
- end
286
-
287
- it "matches a dot ('.') as part of a named param" do
288
- mock_app {
289
- get '/:foo/:bar' do
290
- params[:foo]
291
- end
292
- }
293
-
294
- get '/user@example.com/name'
295
- assert_equal 200, response.status
296
- assert_equal 'user@example.com', body
297
- end
298
-
299
- it "matches a literal dot ('.') outside of named params" do
300
- mock_app {
301
- get '/:file.:ext' do
302
- assert_equal 'pony', params[:file]
303
- assert_equal 'jpg', params[:ext]
304
- 'right on'
305
- end
306
- }
307
-
308
- get '/pony.jpg'
309
- assert_equal 200, response.status
310
- assert_equal 'right on', body
311
- end
312
-
313
- it "literally matches dot in paths" do
314
- route_def '/test.bar'
315
-
316
- get '/test.bar'
317
- assert ok?
318
- get 'test0bar'
319
- assert not_found?
320
- end
321
-
322
- it "literally matches dollar sign in paths" do
323
- route_def '/test$/'
324
-
325
- get '/test$/'
326
- assert ok?
327
- end
328
-
329
- it "literally matches plus sign in paths" do
330
- route_def '/te+st/'
331
-
332
- get '/te%2Bst/'
333
- assert ok?
334
- get '/teeeeeeest/'
335
- assert not_found?
336
- end
337
-
338
- it "converts plus sign into space as the value of a named param" do
339
- mock_app {
340
- get '/:test' do
341
- params["test"]
342
- end
343
- }
344
- get '/bob+ross'
345
- assert ok?
346
- assert_equal 'bob ross', body
347
- end
348
-
349
- it "literally matches parens in paths" do
350
- route_def '/test(bar)/'
351
-
352
- get '/test(bar)/'
353
- assert ok?
354
- end
355
-
356
- it "supports basic nested params" do
357
- mock_app {
358
- get '/hi' do
359
- params["person"]["name"]
360
- end
361
- }
362
-
363
- get "/hi?person[name]=John+Doe"
364
- assert ok?
365
- assert_equal "John Doe", body
366
- end
367
-
368
- it "exposes nested params with indifferent hash" do
369
- mock_app {
370
- get '/testme' do
371
- assert_equal 'baz', params['bar']['foo']
372
- assert_equal 'baz', params['bar'][:foo]
373
- 'well, alright'
374
- end
375
- }
376
- get '/testme?bar[foo]=baz'
377
- assert_equal 'well, alright', body
378
- end
379
-
380
- it "exposes params nested within arrays with indifferent hash" do
381
- mock_app {
382
- get '/testme' do
383
- assert_equal 'baz', params['bar'][0]['foo']
384
- assert_equal 'baz', params['bar'][0][:foo]
385
- 'well, alright'
386
- end
387
- }
388
- get '/testme?bar[][foo]=baz'
389
- assert_equal 'well, alright', body
390
- end
391
-
392
- it "supports arrays within params" do
393
- mock_app {
394
- get '/foo' do
395
- assert_equal ['A', 'B'], params['bar']
396
- 'looks good'
397
- end
398
- }
399
- get '/foo?bar[]=A&bar[]=B'
400
- assert ok?
401
- assert_equal 'looks good', body
402
- end
403
-
404
- it "supports deeply nested params" do
405
- expected_params = {
406
- "emacs" => {
407
- "map" => { "goto-line" => "M-g g" },
408
- "version" => "22.3.1"
409
- },
410
- "browser" => {
411
- "firefox" => {"engine" => {"name"=>"spidermonkey", "version"=>"1.7.0"}},
412
- "chrome" => {"engine" => {"name"=>"V8", "version"=>"1.0"}}
413
- },
414
- "paste" => {"name"=>"hello world", "syntax"=>"ruby"}
415
- }
416
- mock_app {
417
- get '/foo' do
418
- assert_equal expected_params, params
419
- 'looks good'
420
- end
421
- }
422
- get '/foo', expected_params
423
- assert ok?
424
- assert_equal 'looks good', body
425
- end
426
-
427
- it "preserves non-nested params" do
428
- mock_app {
429
- get '/foo' do
430
- assert_equal "2", params["article_id"]
431
- assert_equal "awesome", params['comment']['body']
432
- assert_nil params['comment[body]']
433
- 'looks good'
434
- end
435
- }
436
-
437
- get '/foo?article_id=2&comment[body]=awesome'
438
- assert ok?
439
- assert_equal 'looks good', body
440
- end
441
-
442
- it "matches paths that include spaces encoded with %20" do
443
- mock_app {
444
- get '/path with spaces' do
445
- 'looks good'
446
- end
447
- }
448
-
449
- get '/path%20with%20spaces'
450
- assert ok?
451
- assert_equal 'looks good', body
452
- end
453
-
454
- it "matches paths that include spaces encoded with +" do
455
- mock_app {
456
- get '/path with spaces' do
457
- 'looks good'
458
- end
459
- }
460
-
461
- get '/path+with+spaces'
462
- assert ok?
463
- assert_equal 'looks good', body
464
- end
465
-
466
- it "matches paths that include ampersands" do
467
- mock_app {
468
- get '/:name' do
469
- 'looks good'
470
- end
471
- }
472
-
473
- get '/foo&bar'
474
- assert ok?
475
- assert_equal 'looks good', body
476
- end
477
-
478
- it "URL decodes named parameters and splats" do
479
- mock_app {
480
- get '/:foo/*' do
481
- assert_equal 'hello world', params['foo']
482
- assert_equal ['how are you'], params['splat']
483
- nil
484
- end
485
- }
486
-
487
- get '/hello%20world/how%20are%20you'
488
- assert ok?
489
- end
490
-
491
- it 'supports regular expressions' do
492
- mock_app {
493
- get(/^\/foo...\/bar$/) do
494
- 'Hello World'
495
- end
496
- }
497
-
498
- get '/foooom/bar'
499
- assert ok?
500
- assert_equal 'Hello World', body
501
- end
502
-
503
- it 'makes regular expression captures available in params[:captures]' do
504
- mock_app {
505
- get(/^\/fo(.*)\/ba(.*)/) do
506
- assert_equal ['orooomma', 'f'], params[:captures]
507
- 'right on'
508
- end
509
- }
510
-
511
- get '/foorooomma/baf'
512
- assert ok?
513
- assert_equal 'right on', body
514
- end
515
-
516
- it 'supports regular expression look-alike routes' do
517
- mock_app {
518
- get(RegexpLookAlike.new) do
519
- assert_equal 'this', params[:one]
520
- assert_equal 'is', params[:two]
521
- assert_equal 'a', params[:three]
522
- assert_equal 'test', params[:four]
523
- 'right on'
524
- end
525
- }
526
-
527
- get '/this/is/a/test/'
528
- assert ok?
529
- assert_equal 'right on', body
530
- end
531
-
532
- it 'raises a TypeError when pattern is not a String or Regexp' do
533
- assert_raise(TypeError) {
534
- mock_app { get(42){} }
535
- }
536
- end
537
-
538
- it "returns response immediately on halt" do
539
- mock_app {
540
- get '/' do
541
- halt 'Hello World'
542
- 'Boo-hoo World'
543
- end
544
- }
545
-
546
- get '/'
547
- assert ok?
548
- assert_equal 'Hello World', body
549
- end
550
-
551
- it "halts with a response tuple" do
552
- mock_app {
553
- get '/' do
554
- halt 295, {'Content-Type' => 'text/plain'}, 'Hello World'
555
- end
556
- }
557
-
558
- get '/'
559
- assert_equal 295, status
560
- assert_equal 'text/plain', response['Content-Type']
561
- assert_equal 'Hello World', body
562
- end
563
-
564
- it "halts with an array of strings" do
565
- mock_app {
566
- get '/' do
567
- halt %w[Hello World How Are You]
568
- end
569
- }
570
-
571
- get '/'
572
- assert_equal 'HelloWorldHowAreYou', body
573
- end
574
-
575
- it 'sets response.status with halt' do
576
- status_was = nil
577
- mock_app do
578
- after { status_was = status }
579
- get('/') { halt 500, 'error' }
580
- end
581
- get '/'
582
- assert_status 500
583
- assert_equal 500, status_was
584
- end
585
-
586
- it "transitions to the next matching route on pass" do
587
- mock_app {
588
- get '/:foo' do
589
- pass
590
- 'Hello Foo'
591
- end
592
-
593
- get '/*' do
594
- assert !params.include?('foo')
595
- 'Hello World'
596
- end
597
- }
598
-
599
- get '/bar'
600
- assert ok?
601
- assert_equal 'Hello World', body
602
- end
603
-
604
- it "transitions to 404 when passed and no subsequent route matches" do
605
- mock_app {
606
- get '/:foo' do
607
- pass
608
- 'Hello Foo'
609
- end
610
- }
611
-
612
- get '/bar'
613
- assert not_found?
614
- end
615
-
616
- it "transitions to 404 and sets X-Cascade header when passed and no subsequent route matches" do
617
- mock_app {
618
- get '/:foo' do
619
- pass
620
- 'Hello Foo'
621
- end
622
-
623
- get '/bar' do
624
- 'Hello Bar'
625
- end
626
- }
627
-
628
- get '/foo'
629
- assert not_found?
630
- assert_equal 'pass', response.headers['X-Cascade']
631
- end
632
-
633
- it "uses optional block passed to pass as route block if no other route is found" do
634
- mock_app {
635
- get "/" do
636
- pass do
637
- "this"
638
- end
639
- "not this"
640
- end
641
- }
642
-
643
- get "/"
644
- assert ok?
645
- assert "this", body
646
- end
647
-
648
- it "passes when matching condition returns false" do
649
- mock_app {
650
- condition { params[:foo] == 'bar' }
651
- get '/:foo' do
652
- 'Hello World'
653
- end
654
- }
655
-
656
- get '/bar'
657
- assert ok?
658
- assert_equal 'Hello World', body
659
-
660
- get '/foo'
661
- assert not_found?
662
- end
663
-
664
- it "does not pass when matching condition returns nil" do
665
- mock_app {
666
- condition { nil }
667
- get '/:foo' do
668
- 'Hello World'
669
- end
670
- }
671
-
672
- get '/bar'
673
- assert ok?
674
- assert_equal 'Hello World', body
675
- end
676
-
677
- it "passes to next route when condition calls pass explicitly" do
678
- mock_app {
679
- condition { pass unless params[:foo] == 'bar' }
680
- get '/:foo' do
681
- 'Hello World'
682
- end
683
- }
684
-
685
- get '/bar'
686
- assert ok?
687
- assert_equal 'Hello World', body
688
-
689
- get '/foo'
690
- assert not_found?
691
- end
692
-
693
- it "passes to the next route when host_name does not match" do
694
- mock_app {
695
- host_name 'example.com'
696
- get '/foo' do
697
- 'Hello World'
698
- end
699
- }
700
- get '/foo'
701
- assert not_found?
702
-
703
- get '/foo', {}, { 'HTTP_HOST' => 'example.com' }
704
- assert_equal 200, status
705
- assert_equal 'Hello World', body
706
- end
707
-
708
- it "passes to the next route when user_agent does not match" do
709
- mock_app {
710
- user_agent(/Foo/)
711
- get '/foo' do
712
- 'Hello World'
713
- end
714
- }
715
- get '/foo'
716
- assert not_found?
717
-
718
- get '/foo', {}, { 'HTTP_USER_AGENT' => 'Foo Bar' }
719
- assert_equal 200, status
720
- assert_equal 'Hello World', body
721
- end
722
-
723
- it "treats missing user agent like an empty string" do
724
- mock_app do
725
- user_agent(/.*/)
726
- get '/' do
727
- "Hello World"
728
- end
729
- end
730
- get '/'
731
- assert_equal 200, status
732
- assert_equal 'Hello World', body
733
- end
734
-
735
- it "makes captures in user agent pattern available in params[:agent]" do
736
- mock_app {
737
- user_agent(/Foo (.*)/)
738
- get '/foo' do
739
- 'Hello ' + params[:agent].first
740
- end
741
- }
742
- get '/foo', {}, { 'HTTP_USER_AGENT' => 'Foo Bar' }
743
- assert_equal 200, status
744
- assert_equal 'Hello Bar', body
745
- end
746
-
747
- it "filters by accept header" do
748
- mock_app {
749
- get '/', :provides => :xml do
750
- env['HTTP_ACCEPT']
751
- end
752
- get '/foo', :provides => :html do
753
- env['HTTP_ACCEPT']
754
- end
755
- }
756
-
757
- get '/', {}, { 'HTTP_ACCEPT' => 'application/xml' }
758
- assert ok?
759
- assert_equal 'application/xml', body
760
- assert_equal 'application/xml;charset=utf-8', response.headers['Content-Type']
761
-
762
- get '/', {}, { :accept => 'text/html' }
763
- assert !ok?
764
-
765
- get '/foo', {}, { 'HTTP_ACCEPT' => 'text/html;q=0.9' }
766
- assert ok?
767
- assert_equal 'text/html;q=0.9', body
768
-
769
- get '/foo', {}, { 'HTTP_ACCEPT' => '' }
770
- assert !ok?
771
- end
772
-
773
- it "filters by current Content-Type" do
774
- mock_app do
775
- before('/txt') { content_type :txt }
776
- get('*', :provides => :txt) { 'txt' }
777
-
778
- before('/html') { content_type :html }
779
- get('*', :provides => :html) { 'html' }
780
- end
781
-
782
- get '/', {}, { 'HTTP_ACCEPT' => '*' }
783
- assert ok?
784
- assert_equal 'text/plain;charset=utf-8', response.headers['Content-Type']
785
- assert_body 'txt'
786
-
787
- get '/txt', {}, { 'HTTP_ACCEPT' => 'text/plain' }
788
- assert ok?
789
- assert_equal 'text/plain;charset=utf-8', response.headers['Content-Type']
790
- assert_body 'txt'
791
-
792
- get '/', {}, { 'HTTP_ACCEPT' => 'text/html' }
793
- assert ok?
794
- assert_equal 'text/html;charset=utf-8', response.headers['Content-Type']
795
- assert_body 'html'
796
- end
797
-
798
- it "allows multiple mime types for accept header" do
799
- types = ['image/jpeg', 'image/pjpeg']
800
-
801
- mock_app {
802
- get '/', :provides => types do
803
- env['HTTP_ACCEPT']
804
- end
805
- }
806
-
807
- types.each do |type|
808
- get '/', {}, { 'HTTP_ACCEPT' => type }
809
- assert ok?
810
- assert_equal type, body
811
- assert_equal type, response.headers['Content-Type']
812
- end
813
- end
814
-
815
- it 'degrades gracefully when optional accept header is not provided' do
816
- mock_app {
817
- get '/', :provides => :xml do
818
- env['HTTP_ACCEPT']
819
- end
820
- get '/' do
821
- 'default'
822
- end
823
- }
824
- get '/'
825
- assert ok?
826
- assert_equal 'default', body
827
- end
828
-
829
- it 'respects user agent prefferences for the content type' do
830
- mock_app { get('/', :provides => [:png, :html]) { content_type }}
831
- get '/', {}, { 'HTTP_ACCEPT' => 'image/png;q=0.5,text/html;q=0.8' }
832
- assert_body 'text/html;charset=utf-8'
833
- get '/', {}, { 'HTTP_ACCEPT' => 'image/png;q=0.8,text/html;q=0.5' }
834
- assert_body 'image/png'
835
- end
836
-
837
- it 'accepts generic types' do
838
- mock_app do
839
- get('/', :provides => :xml) { content_type }
840
- get('/') { 'no match' }
841
- end
842
- get '/'
843
- assert_body 'no match'
844
- get '/', {}, { 'HTTP_ACCEPT' => 'foo/*' }
845
- assert_body 'no match'
846
- get '/', {}, { 'HTTP_ACCEPT' => 'application/*' }
847
- assert_body 'application/xml;charset=utf-8'
848
- get '/', {}, { 'HTTP_ACCEPT' => '*/*' }
849
- assert_body 'application/xml;charset=utf-8'
850
- end
851
-
852
- it 'prefers concrete over partly generic types' do
853
- mock_app { get('/', :provides => [:png, :html]) { content_type }}
854
- get '/', {}, { 'HTTP_ACCEPT' => 'image/*, text/html' }
855
- assert_body 'text/html;charset=utf-8'
856
- get '/', {}, { 'HTTP_ACCEPT' => 'image/png, text/*' }
857
- assert_body 'image/png'
858
- end
859
-
860
- it 'prefers concrete over fully generic types' do
861
- mock_app { get('/', :provides => [:png, :html]) { content_type }}
862
- get '/', {}, { 'HTTP_ACCEPT' => '*/*, text/html' }
863
- assert_body 'text/html;charset=utf-8'
864
- get '/', {}, { 'HTTP_ACCEPT' => 'image/png, */*' }
865
- assert_body 'image/png'
866
- end
867
-
868
- it 'prefers partly generic over fully generic types' do
869
- mock_app { get('/', :provides => [:png, :html]) { content_type }}
870
- get '/', {}, { 'HTTP_ACCEPT' => '*/*, text/*' }
871
- assert_body 'text/html;charset=utf-8'
872
- get '/', {}, { 'HTTP_ACCEPT' => 'image/*, */*' }
873
- assert_body 'image/png'
874
- end
875
-
876
- it 'respects quality with generic types' do
877
- mock_app { get('/', :provides => [:png, :html]) { content_type }}
878
- get '/', {}, { 'HTTP_ACCEPT' => 'image/*;q=1, text/html;q=0' }
879
- assert_body 'image/png'
880
- get '/', {}, { 'HTTP_ACCEPT' => 'image/png;q=0.5, text/*;q=0.7' }
881
- assert_body 'text/html;charset=utf-8'
882
- end
883
-
884
- it 'accepts both text/javascript and application/javascript for js' do
885
- mock_app { get('/', :provides => :js) { content_type }}
886
- get '/', {}, { 'HTTP_ACCEPT' => 'application/javascript' }
887
- assert_body 'application/javascript;charset=utf-8'
888
- get '/', {}, { 'HTTP_ACCEPT' => 'text/javascript' }
889
- assert_body 'text/javascript;charset=utf-8'
890
- end
891
-
892
- it 'accepts both text/xml and application/xml for xml' do
893
- mock_app { get('/', :provides => :xml) { content_type }}
894
- get '/', {}, { 'HTTP_ACCEPT' => 'application/xml' }
895
- assert_body 'application/xml;charset=utf-8'
896
- get '/', {}, { 'HTTP_ACCEPT' => 'text/xml' }
897
- assert_body 'text/xml;charset=utf-8'
898
- end
899
-
900
- it 'passes a single url param as block parameters when one param is specified' do
901
- mock_app {
902
- get '/:foo' do |foo|
903
- assert_equal 'bar', foo
904
- end
905
- }
906
-
907
- get '/bar'
908
- assert ok?
909
- end
910
-
911
- it 'passes multiple params as block parameters when many are specified' do
912
- mock_app {
913
- get '/:foo/:bar/:baz' do |foo, bar, baz|
914
- assert_equal 'abc', foo
915
- assert_equal 'def', bar
916
- assert_equal 'ghi', baz
917
- end
918
- }
919
-
920
- get '/abc/def/ghi'
921
- assert ok?
922
- end
923
-
924
- it 'passes regular expression captures as block parameters' do
925
- mock_app {
926
- get(/^\/fo(.*)\/ba(.*)/) do |foo, bar|
927
- assert_equal 'orooomma', foo
928
- assert_equal 'f', bar
929
- 'looks good'
930
- end
931
- }
932
-
933
- get '/foorooomma/baf'
934
- assert ok?
935
- assert_equal 'looks good', body
936
- end
937
-
938
- it "supports mixing multiple splat params like /*/foo/*/* as block parameters" do
939
- mock_app {
940
- get '/*/foo/*/*' do |foo, bar, baz|
941
- assert_equal 'bar', foo
942
- assert_equal 'bling', bar
943
- assert_equal 'baz/boom', baz
944
- 'looks good'
945
- end
946
- }
947
-
948
- get '/bar/foo/bling/baz/boom'
949
- assert ok?
950
- assert_equal 'looks good', body
951
- end
952
-
953
- it 'raises an ArgumentError with block arity > 1 and too many values' do
954
- mock_app do
955
- get '/:foo/:bar/:baz' do |foo, bar|
956
- 'quux'
957
- end
958
- end
959
-
960
- assert_raise(ArgumentError) { get '/a/b/c' }
961
- end
962
-
963
- it 'raises an ArgumentError with block param arity > 1 and too few values' do
964
- mock_app {
965
- get '/:foo/:bar' do |foo, bar, baz|
966
- 'quux'
967
- end
968
- }
969
-
970
- assert_raise(ArgumentError) { get '/a/b' }
971
- end
972
-
973
- it 'succeeds if no block parameters are specified' do
974
- mock_app {
975
- get '/:foo/:bar' do
976
- 'quux'
977
- end
978
- }
979
-
980
- get '/a/b'
981
- assert ok?
982
- assert_equal 'quux', body
983
- end
984
-
985
- it 'passes all params with block param arity -1 (splat args)' do
986
- mock_app {
987
- get '/:foo/:bar' do |*args|
988
- args.join
989
- end
990
- }
991
-
992
- get '/a/b'
993
- assert ok?
994
- assert_equal 'ab', body
995
- end
996
-
997
- it 'allows custom route-conditions to be set via route options' do
998
- protector = Module.new {
999
- def protect(*args)
1000
- condition {
1001
- unless authorize(params["user"], params["password"])
1002
- halt 403, "go away"
1003
- end
1004
- }
1005
- end
1006
- }
1007
-
1008
- mock_app {
1009
- register protector
1010
-
1011
- helpers do
1012
- def authorize(username, password)
1013
- username == "foo" && password == "bar"
1014
- end
1015
- end
1016
-
1017
- get "/", :protect => true do
1018
- "hey"
1019
- end
1020
- }
1021
-
1022
- get "/"
1023
- assert forbidden?
1024
- assert_equal "go away", body
1025
-
1026
- get "/", :user => "foo", :password => "bar"
1027
- assert ok?
1028
- assert_equal "hey", body
1029
- end
1030
-
1031
- # NOTE Block params behaves differently under 1.8 and 1.9. Under 1.8, block
1032
- # param arity is lax: declaring a mismatched number of block params results
1033
- # in a warning. Under 1.9, block param arity is strict: mismatched block
1034
- # arity raises an ArgumentError.
1035
-
1036
- if RUBY_VERSION >= '1.9'
1037
-
1038
- it 'raises an ArgumentError with block param arity 1 and no values' do
1039
- mock_app {
1040
- get '/foo' do |foo|
1041
- 'quux'
1042
- end
1043
- }
1044
-
1045
- assert_raise(ArgumentError) { get '/foo' }
1046
- end
1047
-
1048
- it 'raises an ArgumentError with block param arity 1 and too many values' do
1049
- mock_app {
1050
- get '/:foo/:bar/:baz' do |foo|
1051
- 'quux'
1052
- end
1053
- }
1054
-
1055
- assert_raise(ArgumentError) { get '/a/b/c' }
1056
- end
1057
-
1058
- else
1059
-
1060
- it 'does not raise an ArgumentError with block param arity 1 and no values' do
1061
- mock_app {
1062
- get '/foo' do |foo|
1063
- 'quux'
1064
- end
1065
- }
1066
-
1067
- silence_warnings { get '/foo' }
1068
- assert ok?
1069
- assert_equal 'quux', body
1070
- end
1071
-
1072
- it 'does not raise an ArgumentError with block param arity 1 and too many values' do
1073
- mock_app {
1074
- get '/:foo/:bar/:baz' do |foo|
1075
- 'quux'
1076
- end
1077
- }
1078
-
1079
- silence_warnings { get '/a/b/c' }
1080
- assert ok?
1081
- assert_equal 'quux', body
1082
- end
1083
-
1084
- end
1085
-
1086
- it "matches routes defined in superclasses" do
1087
- base = Class.new(Sinatra::Base)
1088
- base.get('/foo') { 'foo in baseclass' }
1089
-
1090
- mock_app(base) {
1091
- get('/bar') { 'bar in subclass' }
1092
- }
1093
-
1094
- get '/foo'
1095
- assert ok?
1096
- assert_equal 'foo in baseclass', body
1097
-
1098
- get '/bar'
1099
- assert ok?
1100
- assert_equal 'bar in subclass', body
1101
- end
1102
-
1103
- it "matches routes in subclasses before superclasses" do
1104
- base = Class.new(Sinatra::Base)
1105
- base.get('/foo') { 'foo in baseclass' }
1106
- base.get('/bar') { 'bar in baseclass' }
1107
-
1108
- mock_app(base) {
1109
- get('/foo') { 'foo in subclass' }
1110
- }
1111
-
1112
- get '/foo'
1113
- assert ok?
1114
- assert_equal 'foo in subclass', body
1115
-
1116
- get '/bar'
1117
- assert ok?
1118
- assert_equal 'bar in baseclass', body
1119
- end
1120
-
1121
- it "adds hostname condition when it is in options" do
1122
- mock_app {
1123
- get '/foo', :host => 'host' do
1124
- 'foo'
1125
- end
1126
- }
1127
-
1128
- get '/foo'
1129
- assert not_found?
1130
- end
1131
-
1132
- it 'allows using call to fire another request internally' do
1133
- mock_app do
1134
- get '/foo' do
1135
- status, headers, body = call env.merge("PATH_INFO" => '/bar')
1136
- [status, headers, body.each.map(&:upcase)]
1137
- end
1138
-
1139
- get '/bar' do
1140
- "bar"
1141
- end
1142
- end
1143
-
1144
- get '/foo'
1145
- assert ok?
1146
- assert_body "BAR"
1147
- end
1148
-
1149
- it 'plays well with other routing middleware' do
1150
- middleware = Sinatra.new
1151
- inner_app = Sinatra.new { get('/foo') { 'hello' } }
1152
- builder = Rack::Builder.new do
1153
- use middleware
1154
- map('/test') { run inner_app }
1155
- end
1156
-
1157
- @app = builder.to_app
1158
- get '/test/foo'
1159
- assert ok?
1160
- assert_body 'hello'
1161
- end
1162
-
1163
- it 'returns the route signature' do
1164
- signature = list = nil
1165
-
1166
- mock_app do
1167
- signature = post('/') { }
1168
- list = routes['POST']
1169
- end
1170
-
1171
- assert_equal Array, signature.class
1172
- assert_equal 4, signature.length
1173
- assert list.include?(signature)
1174
- end
1175
- end