deas 0.43.3 → 0.43.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -28,7 +28,7 @@ module Deas
28
28
 
29
29
  # ignore captures when setting params
30
30
  # remove duplicate forward slashes
31
- set_anchor(set_extra(set_named(set_splat(@path, s), h), h), a).gsub(/\/\/+/, '/')
31
+ set_anchor(set_extra(set_named(set_splat(@path, s), h).gsub(/\/\/+/, '/'), h), a)
32
32
  end
33
33
 
34
34
  private
@@ -1,3 +1,3 @@
1
1
  module Deas
2
- VERSION = "0.43.3"
2
+ VERSION = "0.43.4"
3
3
  end
@@ -73,6 +73,7 @@ module Deas
73
73
  def headers(*args); @deas_runner.headers(*args); end
74
74
  def body(*args); @deas_runner.body(*args); end
75
75
  def content_type(*args); @deas_runner.content_type(*args); end
76
+ def set_cookie(*args); @deas_runner.set_cookie(*args); end
76
77
  def halt(*args); @deas_runner.halt(*args); end
77
78
  def redirect(*args); @deas_runner.redirect(*args); end
78
79
  def send_file(*args); @deas_runner.send_file(*args); end
@@ -41,8 +41,8 @@ module Factory
41
41
  Deas::RequestData.new({
42
42
  :request => args[:request] || Factory.request,
43
43
  :response => args[:response] || Factory.response,
44
- :params => args[:params] || { Factory.string => Factory.string },
45
- :route_path => args[:route_path] || Factory.string
44
+ :route_path => args[:route_path] || Factory.string,
45
+ :params => args[:params] || { Factory.string => Factory.string }
46
46
  })
47
47
  end
48
48
 
@@ -22,9 +22,7 @@ class FakeSinatraCall
22
22
  @status = 200
23
23
  @headers = {}
24
24
 
25
- @settings = OpenStruct.new({
26
- :deas_server_data => Factory.server_data
27
- }.merge(settings || {}))
25
+ @settings = OpenStruct.new(settings || {})
28
26
  end
29
27
 
30
28
  def call(env)
@@ -69,6 +69,40 @@ class DeasDevServer
69
69
 
70
70
  end
71
71
 
72
+ class RemoveTrailingSlashesServer
73
+ include Deas::Server
74
+
75
+ root TEST_SUPPORT_ROOT
76
+ logger TEST_LOGGER
77
+ verbose_logging true
78
+ show_exceptions true
79
+
80
+ router do
81
+ remove_trailing_slashes
82
+
83
+ get '/show', 'ShowHandler'
84
+ end
85
+
86
+ end
87
+
88
+ class AllowTrailingSlashesServer
89
+ include Deas::Server
90
+
91
+ root TEST_SUPPORT_ROOT
92
+ logger TEST_LOGGER
93
+ verbose_logging true
94
+ show_exceptions true
95
+
96
+ router do
97
+ allow_trailing_slashes
98
+
99
+ get '/show', 'ShowHandler'
100
+ get '/show-text/', 'ShowTextHandler'
101
+
102
+ end
103
+
104
+ end
105
+
72
106
  class ShowHandler
73
107
  include Deas::ViewHandler
74
108
 
@@ -152,7 +152,7 @@ module Deas
152
152
 
153
153
  assert_equal 404, last_response.status
154
154
  assert_equal "text/plain", last_response.headers['Content-Type']
155
- assert_match "Deas::NotFound: /not_defined", last_response.body
155
+ assert_match "Deas::NotFound: GET /not_defined", last_response.body
156
156
  end
157
157
 
158
158
  should "return a text/plain body when an exception occurs" do
@@ -165,4 +165,45 @@ module Deas
165
165
 
166
166
  end
167
167
 
168
+ class RemoveTrailingSlashesTests < RackTestsContext
169
+ desc "a Deas server rack app with a router that requires no trailing slashes"
170
+ setup do
171
+ @app = RemoveTrailingSlashesServer.new
172
+ end
173
+
174
+ should "redirect any paths that end in a slash" do
175
+ get '/show/'
176
+
177
+ assert_equal 302, last_response.status
178
+ assert_equal '/show', last_response.headers['Location']
179
+ end
180
+
181
+ end
182
+
183
+ class AllowTrailingSlashesTests < RackTestsContext
184
+ desc "a Deas server rack app with a router that allows trailing slashes"
185
+ setup do
186
+ @app = AllowTrailingSlashesServer.new
187
+ end
188
+
189
+ should "serve any found paths regardless of whether they end with a slash" do
190
+ get '/show'
191
+ assert_equal 200, last_response.status
192
+ assert_equal 'text/html;charset=utf-8', last_response.headers['Content-Type']
193
+
194
+ get '/show/'
195
+ assert_equal 200, last_response.status
196
+ assert_equal 'text/html;charset=utf-8', last_response.headers['Content-Type']
197
+
198
+ get '/show-text'
199
+ assert_equal 200, last_response.status
200
+ assert_equal 'text/plain', last_response.headers['Content-Type']
201
+
202
+ get '/show-text/'
203
+ assert_equal 200, last_response.status
204
+ assert_equal 'text/plain', last_response.headers['Content-Type']
205
+ end
206
+
207
+ end
208
+
168
209
  end
@@ -12,21 +12,21 @@ class Deas::ErrorHandler
12
12
  @server_data = Factory.server_data(:error_procs => @error_proc_spies)
13
13
  @request = Factory.string
14
14
  @response = Factory.string
15
+ @route_path = Factory.string
15
16
  @handler_class = Factory.string
16
17
  @handler = Factory.string
17
18
  @params = Factory.string
18
19
  @splat = Factory.string
19
- @route_path = Factory.string
20
20
 
21
21
  @context_hash = {
22
22
  :server_data => @server_data,
23
23
  :request => @request,
24
24
  :response => @response,
25
+ :route_path => @route_path,
25
26
  :handler_class => @handler_class,
26
27
  :handler => @handler,
27
28
  :params => @params,
28
- :splat => @splat,
29
- :route_path => @route_path
29
+ :splat => @splat
30
30
  }
31
31
 
32
32
  @error_handler_class = Deas::ErrorHandler
@@ -117,18 +117,18 @@ class Deas::ErrorHandler
117
117
  subject{ @context }
118
118
 
119
119
  should have_readers :server_data
120
- should have_readers :request, :response, :handler_class, :handler
121
- should have_readers :params, :splat, :route_path
120
+ should have_readers :request, :response
121
+ should have_readers :route_path, :handler_class, :handler, :params, :splat
122
122
 
123
123
  should "know its attributes" do
124
124
  assert_equal @context_hash[:server_data], subject.server_data
125
125
  assert_equal @context_hash[:request], subject.request
126
126
  assert_equal @context_hash[:response], subject.response
127
+ assert_equal @context_hash[:route_path], subject.route_path
127
128
  assert_equal @context_hash[:handler_class], subject.handler_class
128
129
  assert_equal @context_hash[:handler], subject.handler
129
130
  assert_equal @context_hash[:params], subject.params
130
131
  assert_equal @context_hash[:splat], subject.splat
131
- assert_equal @context_hash[:route_path], subject.route_path
132
132
  end
133
133
 
134
134
  should "know if it equals another context" do
@@ -139,11 +139,11 @@ class Deas::ErrorHandler
139
139
  :server_data => Factory.server_data,
140
140
  :request => Factory.string,
141
141
  :response => Factory.string,
142
+ :route_path => Factory.string,
142
143
  :handler_class => Factory.string,
143
144
  :handler => Factory.string,
144
145
  :params => Factory.string,
145
146
  :splat => Factory.string,
146
- :route_path => Factory.string
147
147
  })
148
148
  assert_not_equal exp, subject
149
149
  end
@@ -62,8 +62,8 @@ class Deas::HandlerProxy
62
62
  :router => @server_data.router,
63
63
  :template_source => @server_data.template_source,
64
64
  :request => @request_data.request,
65
- :params => @request_data.params,
66
- :route_path => @request_data.route_path
65
+ :route_path => @request_data.route_path,
66
+ :params => @request_data.params
67
67
  }
68
68
  assert_equal exp_args, @runner_spy.args
69
69
 
@@ -71,6 +71,9 @@ class Deas::HandlerProxy
71
71
  end
72
72
 
73
73
  should "add data to the request env to make it available to Rack" do
74
+ exp = @runner_spy.route_path
75
+ assert_equal exp, @request_data.request.env['deas.route_path']
76
+
74
77
  exp = subject.handler_class
75
78
  assert_equal exp, @request_data.request.env['deas.handler_class']
76
79
 
@@ -82,17 +85,14 @@ class Deas::HandlerProxy
82
85
 
83
86
  exp = @runner_spy.splat
84
87
  assert_equal exp, @request_data.request.env['deas.splat']
85
-
86
- exp = @runner_spy.route_path
87
- assert_equal exp, @request_data.request.env['deas.route_path']
88
88
  end
89
89
 
90
90
  should "log the handler class name and the params" do
91
91
  exp_msgs = [
92
+ " Route: #{@runner_spy.route_path.inspect}",
92
93
  " Handler: #{subject.handler_class.name}",
93
94
  " Params: #{@runner_spy.params.inspect}",
94
- " Splat: #{@runner_spy.splat.inspect}",
95
- " Route: #{@runner_spy.route_path.inspect}"
95
+ " Splat: #{@runner_spy.splat.inspect}"
96
96
  ]
97
97
  assert_equal exp_msgs, @request_data.request.logging_msgs
98
98
  end
@@ -7,11 +7,11 @@ module Deas::Logging
7
7
  desc "Deas::Logging"
8
8
  subject{ Deas::Logging }
9
9
 
10
- should have_imeths :middleware_args
10
+ should have_imeths :middleware_type
11
11
 
12
12
  should "return middleware args given a verbose flag" do
13
- assert_equal [Deas::VerboseLogging], subject.middleware_args(true)
14
- assert_equal [Deas::SummaryLogging], subject.middleware_args(false)
13
+ assert_equal Deas::VerboseLogging, subject.middleware_type(true)
14
+ assert_equal Deas::SummaryLogging, subject.middleware_type(false)
15
15
  end
16
16
 
17
17
  end
@@ -19,9 +19,7 @@ module Deas::Logging
19
19
  class CallSetupTests < UnitTests
20
20
  setup do
21
21
  @logger = SpyLogger.new
22
- @app = Factory.sinatra_call({
23
- :deas_server_data => Factory.server_data(:logger => @logger)
24
- })
22
+ @app = Factory.sinatra_call
25
23
 
26
24
  @app_call_env = nil
27
25
  @resp_status = Factory.integer
@@ -60,7 +58,7 @@ module Deas::Logging
60
58
  @benchmark
61
59
  end
62
60
 
63
- @middleware = @middleware_class.new(@app)
61
+ @middleware = @middleware_class.new(@app, @logger)
64
62
  end
65
63
  subject{ @middleware }
66
64
 
@@ -131,7 +129,7 @@ module Deas::Logging
131
129
  @resp_status = @middleware_class::RESPONSE_STATUS_NAMES.keys.sample
132
130
  @app_response[0] = @resp_status
133
131
 
134
- @middleware = Deas::VerboseLogging.new(@app)
132
+ @middleware = Deas::VerboseLogging.new(@app, @logger)
135
133
  end
136
134
  subject{ @middleware }
137
135
 
@@ -213,7 +211,7 @@ module Deas::Logging
213
211
  'deas.handler_class' => @handler_class
214
212
  })
215
213
 
216
- @middleware = Deas::SummaryLogging.new(@app)
214
+ @middleware = Deas::SummaryLogging.new(@app, @logger)
217
215
  end
218
216
  subject{ @middleware }
219
217
 
@@ -8,25 +8,25 @@ class Deas::RequestData
8
8
  setup do
9
9
  @request = Factory.string
10
10
  @response = Factory.string
11
- @params = Factory.string
12
11
  @route_path = Factory.string
12
+ @params = Factory.string
13
13
 
14
14
  @request_data = Deas::RequestData.new({
15
15
  :request => @request,
16
16
  :response => @response,
17
- :params => @params,
18
- :route_path => @route_path
17
+ :route_path => @route_path,
18
+ :params => @params
19
19
  })
20
20
  end
21
21
  subject{ @request_data }
22
22
 
23
- should have_readers :request, :response, :params, :route_path
23
+ should have_readers :request, :response, :route_path, :params
24
24
 
25
25
  should "know its attributes" do
26
26
  assert_equal @request, subject.request
27
27
  assert_equal @response, subject.response
28
- assert_equal @params, subject.params
29
28
  assert_equal @route_path, subject.route_path
29
+ assert_equal @params, subject.params
30
30
  end
31
31
 
32
32
  should "default its attributes when they aren't provided" do
@@ -34,16 +34,16 @@ class Deas::RequestData
34
34
 
35
35
  assert_nil request_data.request
36
36
  assert_nil request_data.response
37
- assert_nil request_data.params
38
37
  assert_nil request_data.route_path
38
+ assert_nil request_data.params
39
39
  end
40
40
 
41
41
  should "know if it is equal to another request data" do
42
42
  request_data = Deas::RequestData.new({
43
43
  :request => @request,
44
44
  :response => @response,
45
- :params => @params,
46
- :route_path => @route_path
45
+ :route_path => @route_path,
46
+ :params => @params
47
47
  })
48
48
  assert_equal request_data, subject
49
49
 
@@ -19,6 +19,12 @@ class Deas::Router
19
19
  assert_equal 'default', subject::DEFAULT_REQUEST_TYPE_NAME
20
20
  end
21
21
 
22
+ should "know its trailing slashes constants" do
23
+ assert_equal 'remove', subject::REMOVE_TRAILING_SLASHES
24
+ assert_equal 'allow', subject::ALLOW_TRAILING_SLASHES
25
+ assert_equal '/', subject::SLASH
26
+ end
27
+
22
28
  end
23
29
 
24
30
  class InitTests < UnitTests
@@ -32,9 +38,13 @@ class Deas::Router
32
38
  subject{ @router }
33
39
 
34
40
  should have_readers :request_types, :urls, :routes, :definitions
35
- should have_readers :escape_query_value_proc
41
+ should have_readers :trailing_slashes, :escape_query_value_proc
36
42
 
37
- should have_imeths :view_handler_ns, :escape_query_value
43
+ should have_imeths :view_handler_ns
44
+ should have_imeths :allow_trailing_slashes, :allow_trailing_slashes_set?
45
+ should have_imeths :remove_trailing_slashes, :remove_trailing_slashes_set?
46
+ should have_imeths :trailing_slashes_set?
47
+ should have_imeths :escape_query_value
38
48
  should have_imeths :base_url, :set_base_url, :prepend_base_url
39
49
  should have_imeths :url, :url_for
40
50
  should have_imeths :default_request_type_name, :add_request_type
@@ -42,10 +52,12 @@ class Deas::Router
42
52
  should have_imeths :get, :post, :put, :patch, :delete
43
53
  should have_imeths :route, :redirect, :not_found
44
54
  should have_imeths :apply_definitions!, :validate!
55
+ should have_imeths :validate_trailing_slashes!
45
56
 
46
57
  should "default its attrs" do
47
58
  router = @router_class.new
48
59
  assert_nil router.view_handler_ns
60
+ assert_nil router.trailing_slashes
49
61
  assert_nil router.base_url
50
62
  assert_empty router.request_types
51
63
  assert_empty router.urls
@@ -74,6 +86,26 @@ class Deas::Router
74
86
  assert_equal exp, subject.view_handler_ns
75
87
  end
76
88
 
89
+ should "config trailing slash handling" do
90
+ assert_false subject.allow_trailing_slashes_set?
91
+ assert_false subject.remove_trailing_slashes_set?
92
+ assert_false subject.trailing_slashes_set?
93
+
94
+ subject.allow_trailing_slashes
95
+
96
+ assert_equal subject.class::ALLOW_TRAILING_SLASHES, subject.trailing_slashes
97
+ assert_true subject.allow_trailing_slashes_set?
98
+ assert_false subject.remove_trailing_slashes_set?
99
+ assert_true subject.trailing_slashes_set?
100
+
101
+ subject.remove_trailing_slashes
102
+
103
+ assert_equal subject.class::REMOVE_TRAILING_SLASHES, subject.trailing_slashes
104
+ assert_false subject.allow_trailing_slashes_set?
105
+ assert_true subject.remove_trailing_slashes_set?
106
+ assert_true subject.trailing_slashes_set?
107
+ end
108
+
77
109
  should "allow configuring a custom escape query value proc" do
78
110
  escape_proc = proc{ Factory.string }
79
111
  subject.escape_query_value(&escape_proc)
@@ -158,21 +190,91 @@ class Deas::Router
158
190
  assert_equal path1, nf.path
159
191
  end
160
192
 
193
+ should "validate trailing slashes" do
194
+ router = @router_class.new
195
+ router.get('/something', 'EmptyViewHandler')
196
+ router.get('/something/', 'EmptyViewHandler')
197
+ router.apply_definitions!
198
+
199
+ assert_nothing_raised do
200
+ router.validate_trailing_slashes!
201
+ end
202
+
203
+ router.allow_trailing_slashes
204
+ assert_nothing_raised do
205
+ router.validate_trailing_slashes!
206
+ end
207
+
208
+ router.remove_trailing_slashes
209
+ err = assert_raises(TrailingSlashesError) do
210
+ router.validate_trailing_slashes!
211
+ end
212
+ exp = "all route paths must *not* end with a \"/\", but these do:\n/something/"
213
+ assert_includes exp, err.message
214
+
215
+ router = @router_class.new
216
+ router.get('/something/', 'EmptyViewHandler')
217
+ router.get('/something-else/', 'EmptyViewHandler')
218
+ router.apply_definitions!
219
+
220
+ assert_nothing_raised do
221
+ router.validate_trailing_slashes!
222
+ end
223
+
224
+ router.allow_trailing_slashes
225
+ assert_nothing_raised do
226
+ router.validate_trailing_slashes!
227
+ end
228
+
229
+ router.remove_trailing_slashes
230
+ err = assert_raises(TrailingSlashesError) do
231
+ router.validate_trailing_slashes!
232
+ end
233
+ exp = "all route paths must *not* end with a \"/\", but these do:\n"\
234
+ "/something/\n/something-else/"
235
+ assert_includes exp, err.message
236
+
237
+ router = @router_class.new
238
+ router.get('/something', 'EmptyViewHandler')
239
+ router.get('/something-else', 'EmptyViewHandler')
240
+ router.apply_definitions!
241
+
242
+ assert_nothing_raised do
243
+ router.validate_trailing_slashes!
244
+ end
245
+
246
+ router.allow_trailing_slashes
247
+ assert_nothing_raised do
248
+ router.validate_trailing_slashes!
249
+ end
250
+
251
+ router.remove_trailing_slashes
252
+ assert_nothing_raised do
253
+ router.validate_trailing_slashes!
254
+ end
255
+ end
256
+
161
257
  should "apply definitions and validate each route when validating" do
162
258
  subject.get('/something', 'EmptyViewHandler')
163
259
  subject.apply_definitions!
260
+ subject.validate_trailing_slashes!
164
261
  route = subject.routes.last
165
262
  proxy = route.handler_proxies[subject.default_request_type_name]
166
263
 
167
264
  apply_def_called = false
168
265
  Assert.stub(subject, :apply_definitions!){ apply_def_called = true }
169
266
 
267
+ val_trailing_called = false
268
+ Assert.stub(subject, :validate_trailing_slashes!){ val_trailing_called = true }
269
+
170
270
  assert_false apply_def_called
271
+ assert_false val_trailing_called
171
272
  assert_nil proxy.handler_class
172
273
 
173
274
  subject.validate!
174
275
 
175
276
  assert_true apply_def_called
277
+ assert_true val_trailing_called
176
278
  assert_equal EmptyViewHandler, proxy.handler_class
177
279
  end
178
280