sinatra 0.9.1.1 → 0.9.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sinatra might be problematic. Click here for more details.

@@ -115,6 +115,22 @@ module Sinatra
115
115
  halt data
116
116
  end
117
117
 
118
+ # The :views_directory, :options, :haml, and :sass options are deprecated.
119
+ def render(engine, template, options={}, locals={}, &bk)
120
+ if options.key?(:views_directory)
121
+ sinatra_warn "The :views_directory option is deprecated; use :views instead."
122
+ options[:views] = options.delete(:views_directory)
123
+ end
124
+ [:options, engine.to_sym].each do |key|
125
+ if options.key?(key)
126
+ sinatra_warn "Passing :#{key} => {} to #{engine} is deprecated; " +
127
+ "merge options directly into hash instead."
128
+ options.merge! options.delete(key)
129
+ end
130
+ end
131
+ super(engine, template, options, locals, &bk)
132
+ end
133
+
118
134
  # Throwing halt with a Symbol and the to_result convention are
119
135
  # deprecated. Override the invoke method to detect those types of return
120
136
  # values.
@@ -6,26 +6,14 @@ module Sinatra
6
6
  # we assume that the first file that requires 'sinatra' is the
7
7
  # app_file. all other path related options are calculated based
8
8
  # on this path by default.
9
- set :app_file, lambda {
10
- ignore = [
11
- /lib\/sinatra.*\.rb$/, # all sinatra code
12
- /\(.*\)/, # generated code
13
- /custom_require\.rb$/ # rubygems require hacks
14
- ]
15
- path =
16
- caller.map{ |line| line.split(/:\d/, 2).first }.find do |file|
17
- next if ignore.any? { |pattern| file =~ pattern }
18
- file
19
- end
20
- path || $0
21
- }.call
9
+ set :app_file, caller_files.first || $0
22
10
 
23
11
  set :run, Proc.new { $0 == app_file }
24
12
 
25
13
  if run? && ARGV.any?
26
14
  require 'optparse'
27
15
  OptionParser.new { |op|
28
- op.on('-x') { set :mutex, true }
16
+ op.on('-x') { set :lock, true }
29
17
  op.on('-e env') { |val| set :environment, val.to_sym }
30
18
  op.on('-s server') { |val| set :server, val }
31
19
  op.on('-p port') { |val| set :port, val.to_i }
@@ -0,0 +1,303 @@
1
+ require 'rack/showexceptions'
2
+
3
+ module Sinatra
4
+ class ShowExceptions < Rack::ShowExceptions
5
+ def initialize(app)
6
+ @app = app
7
+ @template = ERB.new(TEMPLATE)
8
+ end
9
+
10
+ def frame_class(frame)
11
+ if frame.filename =~ /lib\/sinatra.*\.rb/
12
+ "framework"
13
+ elsif (defined?(Gem) && frame.filename.include?(Gem.dir)) ||
14
+ frame.filename =~ /\/bin\/(\w+)$/
15
+ "system"
16
+ else
17
+ "app"
18
+ end
19
+ end
20
+
21
+ TEMPLATE = <<HTML
22
+ <!DOCTYPE html>
23
+ <html>
24
+ <head>
25
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
26
+ <title><%=h exception.class %> at <%=h path %></title>
27
+
28
+ <script type="text/javascript">
29
+ //<!--
30
+ function toggle(id) {
31
+ var pre = document.getElementById("pre-" + id);
32
+ var post = document.getElementById("post-" + id);
33
+ var context = document.getElementById("context-" + id);
34
+
35
+ if (pre.style.display == 'block') {
36
+ pre.style.display = 'none';
37
+ post.style.display = 'none';
38
+ context.style.background = "none";
39
+ } else {
40
+ pre.style.display = 'block';
41
+ post.style.display = 'block';
42
+ context.style.background = "#fffed9";
43
+ }
44
+ }
45
+
46
+ function toggleBacktrace(){
47
+ var bt = document.getElementById("backtrace");
48
+ var toggler = document.getElementById("expando");
49
+
50
+ if (bt.className == 'condensed') {
51
+ bt.className = 'expanded';
52
+ toggler.innerHTML = "(condense)";
53
+ } else {
54
+ bt.className = 'condensed';
55
+ toggler.innerHTML = "(expand)";
56
+ }
57
+ }
58
+ //-->
59
+ </script>
60
+
61
+ <style type="text/css" media="screen">
62
+ * {margin: 0; padding: 0; border: 0; outline: 0;}
63
+ div.clear {clear: both;}
64
+ body {background: #EEEEEE; margin: 0; padding: 0;
65
+ font-family: 'Lucida Grande', 'Lucida Sans Unicode',
66
+ 'Garuda';}
67
+ code {font-family: 'Lucida Console', monospace;
68
+ font-size: 12px;}
69
+ li {height: 18px;}
70
+ ul {list-style: none; margin: 0; padding: 0;}
71
+ ol:hover {cursor: pointer;}
72
+ ol li {white-space: pre;}
73
+ #explanation {font-size: 12px; color: #666666;
74
+ margin: 20px 0 0 100px;}
75
+ /* WRAP */
76
+ #wrap {width: 860px; background: #FFFFFF; margin: 0 auto;
77
+ padding: 30px 50px 20px 50px;
78
+ border-left: 1px solid #DDDDDD;
79
+ border-right: 1px solid #DDDDDD;}
80
+ /* HEADER */
81
+ #header {margin: 0 auto 25px auto;}
82
+ #header img {float: left;}
83
+ #header #summary {float: left; margin: 12px 0 0 20px; width:520px;
84
+ font-family: 'Lucida Grande', 'Lucida Sans Unicode';}
85
+ h1 {margin: 0; font-size: 36px; color: #981919;}
86
+ h2 {margin: 0; font-size: 22px; color: #333333;}
87
+ #header ul {margin: 0; font-size: 12px; color: #666666;}
88
+ #header ul li strong{color: #444444;}
89
+ #header ul li {display: inline; padding: 0 10px;}
90
+ #header ul li.first {padding-left: 0;}
91
+ #header ul li.last {border: 0; padding-right: 0;}
92
+ /* BODY */
93
+ #backtrace,
94
+ #get,
95
+ #post,
96
+ #cookies,
97
+ #rack {width: 860px; margin: 0 auto 10px auto;}
98
+ p#nav {float: right; font-size: 14px;}
99
+ /* BACKTRACE */
100
+ a#expando {float: left; padding-left: 5px; color: #666666;
101
+ font-size: 14px; text-decoration: none; cursor: pointer;}
102
+ a#expando:hover {text-decoration: underline;}
103
+ h3 {float: left; width: 100px; margin-bottom: 10px;
104
+ color: #981919; font-size: 14px; font-weight: bold;}
105
+ #nav a {color: #666666; text-decoration: none; padding: 0 5px;}
106
+ #backtrace li.frame-info {background: #f7f7f7; padding-left: 10px;
107
+ font-size: 12px; color: #333333;}
108
+ #backtrace ul {list-style-position: outside; border: 1px solid #E9E9E9;
109
+ border-bottom: 0;}
110
+ #backtrace ol {width: 808px; margin-left: 50px;
111
+ font: 10px 'Lucida Console', monospace; color: #666666;}
112
+ #backtrace ol li {border: 0; border-left: 1px solid #E9E9E9;
113
+ padding: 2px 0;}
114
+ #backtrace ol code {font-size: 10px; color: #555555; padding-left: 5px;}
115
+ #backtrace-ul li {border-bottom: 1px solid #E9E9E9; height: auto;
116
+ padding: 3px 0;}
117
+ #backtrace-ul .code {padding: 6px 0 4px 0;}
118
+ #backtrace.condensed .system,
119
+ #backtrace.condensed .framework {display:none;}
120
+ /* REQUEST DATA */
121
+ p.no-data {padding-top: 2px; font-size: 12px; color: #666666;}
122
+ table.req {width: 760px; text-align: left; font-size: 12px;
123
+ color: #666666; padding: 0; border-spacing: 0;
124
+ border: 1px solid #EEEEEE; border-bottom: 0;
125
+ border-left: 0;}
126
+ table.req tr th {padding: 2px 10px; font-weight: bold;
127
+ background: #F7F7F7; border-bottom: 1px solid #EEEEEE;
128
+ border-left: 1px solid #EEEEEE;}
129
+ table.req tr td {padding: 2px 20px 2px 10px;
130
+ border-bottom: 1px solid #EEEEEE;
131
+ border-left: 1px solid #EEEEEE;}
132
+ /* HIDE PRE/POST CODE AT START */
133
+ .pre-context,
134
+ .post-context {display: none;}
135
+ </style>
136
+ </head>
137
+ <body>
138
+ <div id="wrap">
139
+ <div id="header">
140
+ <img src="/__sinatra__/500.png" alt="application error" />
141
+ <div id="summary">
142
+ <h1><strong><%=h exception.class %></strong> at <strong><%=h path %>
143
+ </strong></h1>
144
+ <h2><%=h exception.message %></h2>
145
+ <ul>
146
+ <li class="first"><strong>file:</strong> <code>
147
+ <%=h frames.first.filename.split("/").last %></code></li>
148
+ <li><strong>location:</strong> <code><%=h frames.first.function %>
149
+ </code></li>
150
+ <li class="last"><strong>line:
151
+ </strong> <%=h frames.first.lineno %></li>
152
+ </ul>
153
+ </div>
154
+ <div class="clear"></div>
155
+ </div>
156
+
157
+ <div id="backtrace" class='condensed'>
158
+ <h3>BACKTRACE</h3>
159
+ <p><a href="#" id="expando"
160
+ onclick="toggleBacktrace(); return false">(expand)</a></p>
161
+ <p id="nav"><strong>JUMP TO:</strong>
162
+ <a href="#get-info">GET</a>
163
+ <a href="#post-info">POST</a>
164
+ <a href="#cookie-info">COOKIES</a>
165
+ <a href="#env-info">ENV</a>
166
+ </p>
167
+ <div class="clear"></div>
168
+
169
+ <ul id="backtrace-ul">
170
+
171
+ <% id = 1 %>
172
+ <% frames.each do |frame| %>
173
+ <% if frame.context_line && frame.context_line != "#" %>
174
+
175
+ <li class="frame-info <%= frame_class(frame) %>">
176
+ <code><%=h frame.filename %></code> in
177
+ <code><strong><%=h frame.function %></strong></code>
178
+ </li>
179
+
180
+ <li class="code <%= frame_class(frame) %>">
181
+ <% if frame.pre_context %>
182
+ <ol start="<%=h frame.pre_context_lineno + 1 %>"
183
+ class="pre-context" id="pre-<%= id %>"
184
+ onclick="toggle(<%= id %>);">
185
+ <% frame.pre_context.each do |line| %>
186
+ <li class="pre-context-line"><code><%=h line %></code></li>
187
+ <% end %>
188
+ </ol>
189
+ <% end %>
190
+
191
+ <ol start="<%= frame.lineno %>" class="context" id="<%= id %>"
192
+ onclick="toggle(<%= id %>);">
193
+ <li class="context-line" id="context-<%= id %>"><code><%=
194
+ h frame.context_line %></code></li>
195
+ </ol>
196
+
197
+ <% if frame.post_context %>
198
+ <ol start="<%=h frame.lineno + 1 %>" class="post-context"
199
+ id="post-<%= id %>" onclick="toggle(<%= id %>);">
200
+ <% frame.post_context.each do |line| %>
201
+ <li class="post-context-line"><code><%=h line %></code></li>
202
+ <% end %>
203
+ </ol>
204
+ <% end %>
205
+ <div class="clear"></div>
206
+ </li>
207
+
208
+ <% end %>
209
+
210
+ <% id += 1 %>
211
+ <% end %>
212
+
213
+ </ul>
214
+ </div> <!-- /BACKTRACE -->
215
+
216
+ <div id="get">
217
+ <h3 id="get-info">GET</h3>
218
+ <% unless req.GET.empty? %>
219
+ <table class="req">
220
+ <tr>
221
+ <th>Variable</th>
222
+ <th>Value</th>
223
+ </tr>
224
+ <% req.GET.sort_by { |k, v| k.to_s }.each { |key, val| %>
225
+ <tr>
226
+ <td><%=h key %></td>
227
+ <td class="code"><div><%=h val.inspect %></div></td>
228
+ </tr>
229
+ <% } %>
230
+ </table>
231
+ <% else %>
232
+ <p class="no-data">No GET data.</p>
233
+ <% end %>
234
+ <div class="clear"></div>
235
+ </div> <!-- /GET -->
236
+
237
+ <div id="post">
238
+ <h3 id="post-info">POST</h3>
239
+ <% unless req.POST.empty? %>
240
+ <table class="req">
241
+ <tr>
242
+ <th>Variable</th>
243
+ <th>Value</th>
244
+ </tr>
245
+ <% req.POST.sort_by { |k, v| k.to_s }.each { |key, val| %>
246
+ <tr>
247
+ <td><%=h key %></td>
248
+ <td class="code"><div><%=h val.inspect %></div></td>
249
+ </tr>
250
+ <% } %>
251
+ </table>
252
+ <% else %>
253
+ <p class="no-data">No POST data.</p>
254
+ <% end %>
255
+ <div class="clear"></div>
256
+ </div> <!-- /POST -->
257
+
258
+ <div id="cookies">
259
+ <h3 id="cookie-info">COOKIES</h3>
260
+ <% unless req.cookies.empty? %>
261
+ <table class="req">
262
+ <tr>
263
+ <th>Variable</th>
264
+ <th>Value</th>
265
+ </tr>
266
+ <% req.cookies.each { |key, val| %>
267
+ <tr>
268
+ <td><%=h key %></td>
269
+ <td class="code"><div><%=h val.inspect %></div></td>
270
+ </tr>
271
+ <% } %>
272
+ </table>
273
+ <% else %>
274
+ <p class="no-data">No cookie data.</p>
275
+ <% end %>
276
+ <div class="clear"></div>
277
+ </div> <!-- /COOKIES -->
278
+
279
+ <div id="rack">
280
+ <h3 id="env-info">Rack ENV</h3>
281
+ <table class="req">
282
+ <tr>
283
+ <th>Variable</th>
284
+ <th>Value</th>
285
+ </tr>
286
+ <% env.sort_by { |k, v| k.to_s }.each { |key, val| %>
287
+ <tr>
288
+ <td><%=h key %></td>
289
+ <td class="code"><div><%=h val %></div></td>
290
+ </tr>
291
+ <% } %>
292
+ </table>
293
+ <div class="clear"></div>
294
+ </div> <!-- /RACK ENV -->
295
+
296
+ <p id="explanation">You're seeing this error because you use you have
297
+ enabled the <code>show_exceptions</code> option.</p>
298
+ </div> <!-- /WRAP -->
299
+ </body>
300
+ </html>
301
+ HTML
302
+ end
303
+ end
@@ -1,5 +1,7 @@
1
1
  require 'sinatra/base'
2
2
 
3
+ warn 'Sinatra::Test is deprecated; use Rack::Test instead.'
4
+
3
5
  module Sinatra
4
6
  module Test
5
7
  include Rack::Utils
@@ -3,8 +3,8 @@ Gem::Specification.new do |s|
3
3
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
4
4
 
5
5
  s.name = 'sinatra'
6
- s.version = '0.9.1.1'
7
- s.date = '2009-03-09'
6
+ s.version = '0.9.2'
7
+ s.date = '2009-05-18'
8
8
 
9
9
  s.description = "Classy web-development dressed in a DSL"
10
10
  s.summary = "Classy web-development dressed in a DSL"
@@ -60,6 +60,7 @@ Gem::Specification.new do |s|
60
60
  lib/sinatra/images/404.png
61
61
  lib/sinatra/images/500.png
62
62
  lib/sinatra/main.rb
63
+ lib/sinatra/showexceptions.rb
63
64
  lib/sinatra/test.rb
64
65
  lib/sinatra/test/bacon.rb
65
66
  lib/sinatra/test/rspec.rb
@@ -68,6 +69,7 @@ Gem::Specification.new do |s|
68
69
  sinatra.gemspec
69
70
  test/base_test.rb
70
71
  test/builder_test.rb
72
+ test/contest.rb
71
73
  test/data/reload_app_file.rb
72
74
  test/erb_test.rb
73
75
  test/extensions_test.rb
@@ -78,10 +80,11 @@ Gem::Specification.new do |s|
78
80
  test/mapped_error_test.rb
79
81
  test/middleware_test.rb
80
82
  test/options_test.rb
81
- test/reload_test.rb
83
+ test/render_backtrace_test.rb
82
84
  test/request_test.rb
83
85
  test/response_test.rb
84
86
  test/result_test.rb
87
+ test/route_added_hook_test.rb
85
88
  test/routing_test.rb
86
89
  test/sass_test.rb
87
90
  test/server_test.rb
@@ -89,6 +92,10 @@ Gem::Specification.new do |s|
89
92
  test/static_test.rb
90
93
  test/templates_test.rb
91
94
  test/test_test.rb
95
+ test/views/error.builder
96
+ test/views/error.erb
97
+ test/views/error.haml
98
+ test/views/error.sass
92
99
  test/views/hello.builder
93
100
  test/views/hello.erb
94
101
  test/views/hello.haml
@@ -104,7 +111,9 @@ Gem::Specification.new do |s|
104
111
  s.test_files = s.files.select {|path| path =~ /^test\/.*_test.rb/}
105
112
 
106
113
  s.extra_rdoc_files = %w[README.rdoc LICENSE]
107
- s.add_dependency 'rack', '>= 0.9.1', '< 1.0'
114
+ s.add_dependency 'rack', '>= 0.9.1'
115
+ s.add_development_dependency 'shotgun', '>= 0.2', '< 1.0'
116
+ s.add_development_dependency 'rack-test', '>= 0.3.0'
108
117
 
109
118
  s.has_rdoc = true
110
119
  s.homepage = "http://sinatra.rubyforge.org"
@@ -1,130 +1,160 @@
1
1
  require File.dirname(__FILE__) + '/helper'
2
2
 
3
- describe 'Sinatra::Base subclasses' do
3
+ class BaseTest < Test::Unit::TestCase
4
+ def test_default
5
+ assert true
6
+ end
4
7
 
5
- class TestApp < Sinatra::Base
6
- get '/' do
7
- 'Hello World'
8
+ describe 'Sinatra::Base subclasses' do
9
+ class TestApp < Sinatra::Base
10
+ get '/' do
11
+ 'Hello World'
12
+ end
8
13
  end
9
- end
10
14
 
11
- it 'include Rack::Utils' do
12
- assert TestApp.included_modules.include?(Rack::Utils)
13
- end
15
+ it 'include Rack::Utils' do
16
+ assert TestApp.included_modules.include?(Rack::Utils)
17
+ end
14
18
 
15
- it 'processes requests with #call' do
16
- assert TestApp.respond_to?(:call)
19
+ it 'processes requests with #call' do
20
+ assert TestApp.respond_to?(:call)
17
21
 
18
- request = Rack::MockRequest.new(TestApp)
19
- response = request.get('/')
20
- assert response.ok?
21
- assert_equal 'Hello World', response.body
22
- end
22
+ request = Rack::MockRequest.new(TestApp)
23
+ response = request.get('/')
24
+ assert response.ok?
25
+ assert_equal 'Hello World', response.body
26
+ end
23
27
 
24
- class TestApp < Sinatra::Base
25
- get '/state' do
26
- body = "Foo: #{@foo}"
27
- @foo = 'discard'
28
- body
28
+ class TestApp < Sinatra::Base
29
+ get '/state' do
30
+ @foo ||= "new"
31
+ body = "Foo: #{@foo}"
32
+ @foo = 'discard'
33
+ body
34
+ end
29
35
  end
30
- end
31
36
 
32
- it 'does not maintain state between requests' do
33
- request = Rack::MockRequest.new(TestApp)
34
- 2.times do
35
- response = request.get('/state')
36
- assert response.ok?
37
- assert_equal 'Foo: ', response.body
37
+ it 'does not maintain state between requests' do
38
+ request = Rack::MockRequest.new(TestApp)
39
+ 2.times do
40
+ response = request.get('/state')
41
+ assert response.ok?
42
+ assert_equal 'Foo: new', response.body
43
+ end
44
+ end
45
+
46
+ it "passes the subclass to configure blocks" do
47
+ ref = nil
48
+ TestApp.configure { |app| ref = app }
49
+ assert_equal TestApp, ref
50
+ end
51
+
52
+ it "allows the configure block arg to be omitted and does not change context" do
53
+ context = nil
54
+ TestApp.configure { context = self }
55
+ assert_equal self, context
38
56
  end
39
57
  end
40
- end
41
58
 
42
- describe "Sinatra::Base as Rack middleware" do
59
+ describe "Sinatra::Base as Rack middleware" do
60
+ app = lambda { |env|
61
+ headers = {'X-Downstream' => 'true'}
62
+ headers['X-Route-Missing'] = env['sinatra.route-missing'] || ''
63
+ [210, headers, ['Hello from downstream']] }
43
64
 
44
- app = lambda { |env|
45
- [210, {'X-Downstream' => 'true'}, ['Hello from downstream']] }
65
+ class TestMiddleware < Sinatra::Base
66
+ end
46
67
 
47
- class TestMiddleware < Sinatra::Base
48
- end
68
+ it 'creates a middleware that responds to #call with .new' do
69
+ middleware = TestMiddleware.new(app)
70
+ assert middleware.respond_to?(:call)
71
+ end
49
72
 
50
- it 'creates a middleware that responds to #call with .new' do
51
- middleware = TestMiddleware.new(app)
52
- assert middleware.respond_to?(:call)
53
- end
73
+ it 'exposes the downstream app' do
74
+ middleware = TestMiddleware.new(app)
75
+ assert_same app, middleware.app
76
+ end
77
+
78
+ class TestMiddleware < Sinatra::Base
79
+ def route_missing
80
+ env['sinatra.route-missing'] = '1'
81
+ super
82
+ end
83
+
84
+ get '/' do
85
+ 'Hello from middleware'
86
+ end
87
+ end
54
88
 
55
- it 'exposes the downstream app' do
56
89
  middleware = TestMiddleware.new(app)
57
- assert_same app, middleware.app
58
- end
90
+ request = Rack::MockRequest.new(middleware)
59
91
 
60
- class TestMiddleware < Sinatra::Base
61
- get '/' do
62
- 'Hello from middleware'
92
+ it 'intercepts requests' do
93
+ response = request.get('/')
94
+ assert response.ok?
95
+ assert_equal 'Hello from middleware', response.body
63
96
  end
64
- end
65
97
 
66
- middleware = TestMiddleware.new(app)
67
- request = Rack::MockRequest.new(middleware)
98
+ it 'automatically forwards requests downstream when no matching route found' do
99
+ response = request.get('/missing')
100
+ assert_equal 210, response.status
101
+ assert_equal 'Hello from downstream', response.body
102
+ end
68
103
 
69
- it 'intercepts requests' do
70
- response = request.get('/')
71
- assert response.ok?
72
- assert_equal 'Hello from middleware', response.body
73
- end
104
+ it 'calls #route_missing before forwarding downstream' do
105
+ response = request.get('/missing')
106
+ assert_equal '1', response['X-Route-Missing']
107
+ end
74
108
 
75
- it 'automatically forwards requests downstream when no matching route found' do
76
- response = request.get('/missing')
77
- assert_equal 210, response.status
78
- assert_equal 'Hello from downstream', response.body
79
- end
109
+ class TestMiddleware < Sinatra::Base
110
+ get '/low-level-forward' do
111
+ app.call(env)
112
+ end
113
+ end
80
114
 
81
- class TestMiddleware < Sinatra::Base
82
- get '/low-level-forward' do
83
- app.call(env)
115
+ it 'can call the downstream app directly and return result' do
116
+ response = request.get('/low-level-forward')
117
+ assert_equal 210, response.status
118
+ assert_equal 'true', response['X-Downstream']
119
+ assert_equal 'Hello from downstream', response.body
84
120
  end
85
- end
86
121
 
87
- it 'can call the downstream app directly and return result' do
88
- response = request.get('/low-level-forward')
89
- assert_equal 210, response.status
90
- assert_equal 'true', response['X-Downstream']
91
- assert_equal 'Hello from downstream', response.body
92
- end
122
+ class TestMiddleware < Sinatra::Base
123
+ get '/explicit-forward' do
124
+ response['X-Middleware'] = 'true'
125
+ res = forward
126
+ assert_nil res
127
+ assert_equal 210, response.status
128
+ assert_equal 'true', response['X-Downstream']
129
+ assert_equal ['Hello from downstream'], response.body
130
+ 'Hello after explicit forward'
131
+ end
132
+ end
93
133
 
94
- class TestMiddleware < Sinatra::Base
95
- get '/explicit-forward' do
96
- response['X-Middleware'] = 'true'
97
- res = forward
98
- assert_nil res
134
+ it 'forwards the request downstream and integrates the response into the current context' do
135
+ response = request.get('/explicit-forward')
99
136
  assert_equal 210, response.status
100
137
  assert_equal 'true', response['X-Downstream']
101
- assert_equal ['Hello from downstream'], response.body
102
- 'Hello after explicit forward'
138
+ assert_equal 'Hello after explicit forward', response.body
139
+ assert_equal '28', response['Content-Length']
103
140
  end
104
- end
105
141
 
106
- it 'forwards the request downstream and integrates the response into the current context' do
107
- response = request.get('/explicit-forward')
108
- assert_equal 210, response.status
109
- assert_equal 'true', response['X-Downstream']
110
- assert_equal 'Hello after explicit forward', response.body
111
- assert_equal '28', response['Content-Length']
112
- end
142
+ app_content_length = lambda {|env|
143
+ [200, {'Content-Length' => '16'}, 'From downstream!']}
113
144
 
114
- app_content_length = lambda {|env|
115
- [200, {'Content-Length' => '16'}, 'From downstream!']}
116
- class TestMiddlewareContentLength < Sinatra::Base
117
- get '/forward' do
118
- res = forward
119
- 'From after explicit forward!'
145
+ class TestMiddlewareContentLength < Sinatra::Base
146
+ get '/forward' do
147
+ res = forward
148
+ 'From after explicit forward!'
149
+ end
120
150
  end
121
- end
122
151
 
123
- middleware_content_length = TestMiddlewareContentLength.new(app_content_length)
124
- request_content_length = Rack::MockRequest.new(middleware_content_length)
152
+ middleware_content_length = TestMiddlewareContentLength.new(app_content_length)
153
+ request_content_length = Rack::MockRequest.new(middleware_content_length)
125
154
 
126
- it "sets content length for last response" do
127
- response = request_content_length.get('/forward')
128
- assert_equal '28', response['Content-Length']
155
+ it "sets content length for last response" do
156
+ response = request_content_length.get('/forward')
157
+ assert_equal '28', response['Content-Length']
158
+ end
129
159
  end
130
160
  end