sinatra-sinatra 0.9.1.2 → 0.9.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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.
@@ -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
@@ -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.2'
7
- s.date = '2009-03-24'
6
+ s.version = '0.9.1.3'
7
+ s.date = '2009-04-25'
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,9 +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
83
+ test/render_backtrace_test.rb
81
84
  test/request_test.rb
82
85
  test/response_test.rb
83
86
  test/result_test.rb
87
+ test/route_added_hook_test.rb
84
88
  test/routing_test.rb
85
89
  test/sass_test.rb
86
90
  test/server_test.rb
@@ -88,6 +92,10 @@ Gem::Specification.new do |s|
88
92
  test/static_test.rb
89
93
  test/templates_test.rb
90
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
91
99
  test/views/hello.builder
92
100
  test/views/hello.erb
93
101
  test/views/hello.haml
@@ -103,7 +111,7 @@ Gem::Specification.new do |s|
103
111
  s.test_files = s.files.select {|path| path =~ /^test\/.*_test.rb/}
104
112
 
105
113
  s.extra_rdoc_files = %w[README.rdoc LICENSE]
106
- s.add_dependency 'rack', '>= 0.9.1', '< 1.0'
114
+ s.add_dependency 'rack', '>= 0.9.1'
107
115
  s.add_development_dependency 'shotgun', '>= 0.2', '< 1.0'
108
116
 
109
117
  s.has_rdoc = true
@@ -1,139 +1,155 @@
1
1
  require File.dirname(__FILE__) + '/helper'
2
2
 
3
- describe 'Sinatra::Base subclasses' do
3
+ class BaseTest < Test::Unit::TestCase
4
+ describe 'Sinatra::Base subclasses' do
5
+ class TestApp < Sinatra::Base
6
+ get '/' do
7
+ 'Hello World'
8
+ end
9
+ end
4
10
 
5
- class TestApp < Sinatra::Base
6
- get '/' do
7
- 'Hello World'
11
+ it 'include Rack::Utils' do
12
+ assert TestApp.included_modules.include?(Rack::Utils)
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 'processes requests with #call' do
16
+ assert TestApp.respond_to?(:call)
14
17
 
15
- it 'processes requests with #call' do
16
- assert TestApp.respond_to?(:call)
18
+ request = Rack::MockRequest.new(TestApp)
19
+ response = request.get('/')
20
+ assert response.ok?
21
+ assert_equal 'Hello World', response.body
22
+ end
17
23
 
18
- request = Rack::MockRequest.new(TestApp)
19
- response = request.get('/')
20
- assert response.ok?
21
- assert_equal 'Hello World', response.body
22
- end
24
+ class TestApp < Sinatra::Base
25
+ get '/state' do
26
+ body = "Foo: #{@foo}"
27
+ @foo = 'discard'
28
+ body
29
+ end
30
+ end
23
31
 
24
- class TestApp < Sinatra::Base
25
- get '/state' do
26
- body = "Foo: #{@foo}"
27
- @foo = 'discard'
28
- body
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
38
+ end
29
39
  end
30
- end
31
40
 
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
41
+ it "passes the subclass to configure blocks" do
42
+ ref = nil
43
+ TestApp.configure { |app| ref = app }
44
+ assert_equal TestApp, ref
45
+ end
46
+
47
+ it "allows the configure block arg to be omitted and does not change context" do
48
+ context = nil
49
+ TestApp.configure { context = self }
50
+ assert_equal self, context
38
51
  end
39
52
  end
40
- end
41
53
 
42
- describe "Sinatra::Base as Rack middleware" do
54
+ describe "Sinatra::Base as Rack middleware" do
55
+ app = lambda { |env|
56
+ headers = {'X-Downstream' => 'true'}
57
+ headers['X-Route-Missing'] = env['sinatra.route-missing'] || ''
58
+ [210, headers, ['Hello from downstream']] }
43
59
 
44
- app = lambda { |env|
45
- [210, {'X-Downstream' => 'true', 'X-Bypass-Test' => '1' || ''}, ['Hello from downstream']] }
60
+ class TestMiddleware < Sinatra::Base
61
+ end
46
62
 
47
- class TestMiddleware < Sinatra::Base
48
- end
63
+ it 'creates a middleware that responds to #call with .new' do
64
+ middleware = TestMiddleware.new(app)
65
+ assert middleware.respond_to?(:call)
66
+ end
49
67
 
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
68
+ it 'exposes the downstream app' do
69
+ middleware = TestMiddleware.new(app)
70
+ assert_same app, middleware.app
71
+ end
54
72
 
55
- it 'exposes the downstream app' do
56
- middleware = TestMiddleware.new(app)
57
- assert_same app, middleware.app
58
- end
73
+ class TestMiddleware < Sinatra::Base
74
+ def route_missing
75
+ env['sinatra.route-missing'] = '1'
76
+ super
77
+ end
59
78
 
60
- class TestMiddleware < Sinatra::Base
61
- def bypassed
62
- env['X-Bypass-Test'] = '1'
79
+ get '/' do
80
+ 'Hello from middleware'
81
+ end
63
82
  end
64
83
 
65
- get '/' do
66
- 'Hello from middleware'
67
- end
68
- end
84
+ middleware = TestMiddleware.new(app)
85
+ request = Rack::MockRequest.new(middleware)
69
86
 
70
- middleware = TestMiddleware.new(app)
71
- request = Rack::MockRequest.new(middleware)
87
+ it 'intercepts requests' do
88
+ response = request.get('/')
89
+ assert response.ok?
90
+ assert_equal 'Hello from middleware', response.body
91
+ end
72
92
 
73
- it 'intercepts requests' do
74
- response = request.get('/')
75
- assert response.ok?
76
- assert_equal 'Hello from middleware', response.body
77
- end
93
+ it 'automatically forwards requests downstream when no matching route found' do
94
+ response = request.get('/missing')
95
+ assert_equal 210, response.status
96
+ assert_equal 'Hello from downstream', response.body
97
+ end
78
98
 
79
- it 'automatically forwards requests downstream when no matching route found' do
80
- response = request.get('/missing')
81
- assert_equal 210, response.status
82
- assert_equal 'Hello from downstream', response.body
83
- end
99
+ it 'calls #route_missing before forwarding downstream' do
100
+ response = request.get('/missing')
101
+ assert_equal '1', response['X-Route-Missing']
102
+ end
84
103
 
85
- it 'calls #bypassed before forwarding downstream' do
86
- response = request.get('/missing')
87
- assert_equal '1', response['X-Bypass-Test']
88
- end
104
+ class TestMiddleware < Sinatra::Base
105
+ get '/low-level-forward' do
106
+ app.call(env)
107
+ end
108
+ end
89
109
 
90
- class TestMiddleware < Sinatra::Base
91
- get '/low-level-forward' do
92
- app.call(env)
110
+ it 'can call the downstream app directly and return result' do
111
+ response = request.get('/low-level-forward')
112
+ assert_equal 210, response.status
113
+ assert_equal 'true', response['X-Downstream']
114
+ assert_equal 'Hello from downstream', response.body
93
115
  end
94
- end
95
116
 
96
- it 'can call the downstream app directly and return result' do
97
- response = request.get('/low-level-forward')
98
- assert_equal 210, response.status
99
- assert_equal 'true', response['X-Downstream']
100
- assert_equal 'Hello from downstream', response.body
101
- end
117
+ class TestMiddleware < Sinatra::Base
118
+ get '/explicit-forward' do
119
+ response['X-Middleware'] = 'true'
120
+ res = forward
121
+ assert_nil res
122
+ assert_equal 210, response.status
123
+ assert_equal 'true', response['X-Downstream']
124
+ assert_equal ['Hello from downstream'], response.body
125
+ 'Hello after explicit forward'
126
+ end
127
+ end
102
128
 
103
- class TestMiddleware < Sinatra::Base
104
- get '/explicit-forward' do
105
- response['X-Middleware'] = 'true'
106
- res = forward
107
- assert_nil res
129
+ it 'forwards the request downstream and integrates the response into the current context' do
130
+ response = request.get('/explicit-forward')
108
131
  assert_equal 210, response.status
109
132
  assert_equal 'true', response['X-Downstream']
110
- assert_equal ['Hello from downstream'], response.body
111
- 'Hello after explicit forward'
133
+ assert_equal 'Hello after explicit forward', response.body
134
+ assert_equal '28', response['Content-Length']
112
135
  end
113
- end
114
136
 
115
- it 'forwards the request downstream and integrates the response into the current context' do
116
- response = request.get('/explicit-forward')
117
- assert_equal 210, response.status
118
- assert_equal 'true', response['X-Downstream']
119
- assert_equal 'Hello after explicit forward', response.body
120
- assert_equal '28', response['Content-Length']
121
- end
137
+ app_content_length = lambda {|env|
138
+ [200, {'Content-Length' => '16'}, 'From downstream!']}
122
139
 
123
- app_content_length = lambda {|env|
124
- [200, {'Content-Length' => '16'}, 'From downstream!']}
125
- class TestMiddlewareContentLength < Sinatra::Base
126
- get '/forward' do
127
- res = forward
128
- 'From after explicit forward!'
140
+ class TestMiddlewareContentLength < Sinatra::Base
141
+ get '/forward' do
142
+ res = forward
143
+ 'From after explicit forward!'
144
+ end
129
145
  end
130
- end
131
146
 
132
- middleware_content_length = TestMiddlewareContentLength.new(app_content_length)
133
- request_content_length = Rack::MockRequest.new(middleware_content_length)
147
+ middleware_content_length = TestMiddlewareContentLength.new(app_content_length)
148
+ request_content_length = Rack::MockRequest.new(middleware_content_length)
134
149
 
135
- it "sets content length for last response" do
136
- response = request_content_length.get('/forward')
137
- assert_equal '28', response['Content-Length']
150
+ it "sets content length for last response" do
151
+ response = request_content_length.get('/forward')
152
+ assert_equal '28', response['Content-Length']
153
+ end
138
154
  end
139
155
  end