deas 0.37.1 → 0.38.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -18,4 +18,6 @@ module Deas
18
18
 
19
19
  HandlerProxyNotFound = Class.new(Error)
20
20
 
21
+ NotFound = Class.new(Error)
22
+
21
23
  end
data/lib/deas/logging.rb CHANGED
@@ -38,7 +38,7 @@ module Deas
38
38
  benchmark = Benchmark.measure do
39
39
  status, headers, body = @app.call(env)
40
40
  end
41
- log_error(env['sinatra.error'])
41
+ log_error(env['deas.error'])
42
42
  env['deas.time_taken'] = RoundedTime.new(benchmark.real)
43
43
 
44
44
  [status, headers, body]
@@ -49,9 +49,9 @@ module Deas
49
49
  end
50
50
 
51
51
  def log_error(exception)
52
- return if !exception || exception.kind_of?(Sinatra::NotFound)
52
+ return if !exception
53
53
  log "#{exception.class}: #{exception.message}\n" \
54
- "#{exception.backtrace.join("\n")}"
54
+ "#{(exception.backtrace || []).join("\n")}"
55
55
  end
56
56
 
57
57
  end
@@ -0,0 +1,42 @@
1
+ require 'deas/handler_proxy'
2
+ require 'deas/url'
3
+ require 'deas/view_handler'
4
+
5
+ module Deas
6
+
7
+ class RespondWithProxy < HandlerProxy
8
+
9
+ attr_reader :handler_class_name, :handler_class
10
+
11
+ def initialize(halt_args)
12
+ @handler_class = Class.new do
13
+ include Deas::ViewHandler
14
+
15
+ def self.halt_args; @halt_args; end
16
+ def self.halt_args=(value)
17
+ @halt_args = value
18
+ end
19
+
20
+ def self.name; 'Deas::RespondWithHandler'; end
21
+
22
+ attr_reader :halt_args
23
+
24
+ def init!
25
+ @halt_args = self.class.halt_args
26
+ end
27
+
28
+ def run!
29
+ halt *self.halt_args
30
+ end
31
+
32
+ end
33
+
34
+ @handler_class.halt_args = halt_args
35
+ @handler_class_name = @handler_class.name
36
+ end
37
+
38
+ def validate!; end
39
+
40
+ end
41
+
42
+ end
data/lib/deas/router.rb CHANGED
@@ -8,12 +8,12 @@ module Deas
8
8
 
9
9
  DEFAULT_REQUEST_TYPE_NAME = 'default'
10
10
 
11
- attr_reader :request_types, :urls, :routes
11
+ attr_reader :request_types, :urls, :routes, :definitions
12
12
  attr_reader :escape_query_value_proc
13
13
 
14
14
  def initialize(&block)
15
15
  @request_types = []
16
- @urls, @routes = {}, []
16
+ @urls, @routes, @definitions = {}, [], []
17
17
  default_request_type_name(DEFAULT_REQUEST_TYPE_NAME)
18
18
  escape_query_value{ |v| Rack::Utils.escape(v) }
19
19
  self.instance_eval(&block) if !block.nil?
@@ -77,42 +77,90 @@ module Deas
77
77
  def delete(path, *args); self.route(:delete, path, *args); end
78
78
 
79
79
  def route(http_method, from_path, *args)
80
+ self.definitions.push([:route, [http_method, from_path, *args], nil])
81
+ true
82
+ end
83
+
84
+ def redirect(from_path, to_path = nil, &block)
85
+ self.definitions.push([:redirect, [from_path, to_path], block])
86
+ true
87
+ end
88
+
89
+ def not_found(from_path, body = nil)
90
+ respond_with_args = [404, {}, body || 'Not Found']
91
+ self.definitions.push([:respond_with, [from_path, respond_with_args], nil])
92
+ end
93
+
94
+ def apply_definitions!
95
+ self.definitions.each do |(type, args, block)|
96
+ self.send("apply_#{type}", *args, &block)
97
+ end
98
+ self.definitions.clear
99
+ true
100
+ end
101
+
102
+ def validate!
103
+ self.apply_definitions!
104
+ self.routes.each(&:validate!)
105
+ true
106
+ end
107
+
108
+ private
109
+
110
+ def apply_route(http_method, from_path, *args)
80
111
  handler_names = args.last.kind_of?(::Hash) ? args.pop : {}
81
112
  default_handler_name = args.last
82
113
  if !handler_names.key?(self.default_request_type_name) && default_handler_name
83
114
  handler_names[self.default_request_type_name] = default_handler_name
84
115
  end
85
116
 
117
+ from_url = self.urls[from_path]
118
+ if from_path.kind_of?(::Symbol) && from_url.nil?
119
+ raise ArgumentError, "no url named `#{from_path.inspect}`"
120
+ end
121
+ from_url_path = from_url.path if from_url
122
+
86
123
  require 'deas/route_proxy'
87
124
  proxies = handler_names.inject({}) do |proxies, (req_type_name, handler_name)|
88
125
  proxies[req_type_name] = Deas::RouteProxy.new(handler_name, self.view_handler_ns)
89
126
  proxies
90
127
  end
91
128
 
92
- from_url = self.urls[from_path]
93
- from_url_path = from_url.path if from_url
94
-
95
129
  add_route(http_method, prepend_base_url(from_url_path || from_path), proxies)
96
130
  end
97
131
 
98
- def redirect(from_path, to_path = nil, &block)
132
+ def apply_redirect(from_path, to_path = nil, &block)
99
133
  to_url = self.urls[to_path]
100
134
  if to_path.kind_of?(::Symbol) && to_url.nil?
101
135
  raise ArgumentError, "no url named `#{to_path.inspect}`"
102
136
  end
137
+ from_url = self.urls[from_path]
138
+ if from_path.kind_of?(::Symbol) && from_url.nil?
139
+ raise ArgumentError, "no url named `#{from_path.inspect}`"
140
+ end
141
+ from_url_path = from_url.path if from_url
103
142
 
104
143
  require 'deas/redirect_proxy'
105
144
  proxy = Deas::RedirectProxy.new(self, to_url || to_path, &block)
106
145
  proxies = { self.default_request_type_name => proxy }
107
146
 
147
+ add_route(:get, prepend_base_url(from_url_path || from_path), proxies)
148
+ end
149
+
150
+ def apply_respond_with(from_path, respond_with_args)
108
151
  from_url = self.urls[from_path]
152
+ if from_path.kind_of?(::Symbol) && from_url.nil?
153
+ raise ArgumentError, "no url named `#{from_path.inspect}`"
154
+ end
109
155
  from_url_path = from_url.path if from_url
110
156
 
157
+ require 'deas/respond_with_proxy'
158
+ proxy = Deas::RespondWithProxy.new(respond_with_args)
159
+ proxies = { self.default_request_type_name => proxy }
160
+
111
161
  add_route(:get, prepend_base_url(from_url_path || from_path), proxies)
112
162
  end
113
163
 
114
- private
115
-
116
164
  def add_url(name, path, options)
117
165
  options[:escape_query_value] ||= self.escape_query_value_proc
118
166
  self.urls[name] = Deas::Url.new(name, path, {
data/lib/deas/server.rb CHANGED
@@ -224,8 +224,8 @@ module Deas
224
224
  self.init_procs.each{ |p| p.call }
225
225
  raise Deas::ServerRootError if self.root.nil?
226
226
 
227
- # validate the routes
228
- self.routes.each(&:validate!)
227
+ # validate the router
228
+ self.router.validate!
229
229
 
230
230
  # append the show exceptions and logging middlewares last. This ensures
231
231
  # that the logging and exception showing happens just before the app gets
@@ -23,7 +23,7 @@ module Deas
23
23
  # The real Rack call interface.
24
24
  def call!(env)
25
25
  status, headers, body = @app.call(env)
26
- if error = env['sinatra.error']
26
+ if error = env['deas.error']
27
27
  error_body = Body.new(error)
28
28
 
29
29
  headers['Content-Length'] = error_body.size.to_s
@@ -37,7 +37,7 @@ module Deas
37
37
  attr_reader :content, :size, :mime_type
38
38
 
39
39
  def initialize(e)
40
- @content = "#{e.class}: #{e.message}\n#{e.backtrace.join("\n")}"
40
+ @content = "#{e.class}: #{e.message}\n#{(e.backtrace || []).join("\n")}"
41
41
  @size = Rack::Utils.bytesize(@content)
42
42
  @mime_type = "text/plain"
43
43
  end
@@ -1,5 +1,6 @@
1
1
  require 'sinatra/base'
2
2
  require 'deas/error_handler'
3
+ require 'deas/exceptions'
3
4
  require 'deas/server_data'
4
5
 
5
6
  module Deas
@@ -55,28 +56,40 @@ module Deas
55
56
  end
56
57
 
57
58
  # error handling
59
+
58
60
  not_found do
59
61
  # `self` is the sinatra call in this context
60
- env['sinatra.error'] ||= Sinatra::NotFound.new
61
- ErrorHandler.run(env['sinatra.error'], {
62
- :server_data => server_data,
63
- :request => self.request,
64
- :response => self.response,
65
- :handler_class => self.request.env['deas.handler_class'],
66
- :handler => self.request.env['deas.handler'],
67
- :params => self.request.env['deas.params'],
68
- })
62
+ if env['sinatra.error']
63
+ env['deas.error'] = if env['sinatra.error'].instance_of?(::Sinatra::NotFound)
64
+ Deas::NotFound.new(env['PATH_INFO']).tap do |e|
65
+ e.set_backtrace(env['sinatra.error'].backtrace)
66
+ end
67
+ else
68
+ env['sinatra.error']
69
+ end
70
+ ErrorHandler.run(env['deas.error'], {
71
+ :server_data => server_data,
72
+ :request => self.request,
73
+ :response => self.response,
74
+ :handler_class => self.request.env['deas.handler_class'],
75
+ :handler => self.request.env['deas.handler'],
76
+ :params => self.request.env['deas.params'],
77
+ })
78
+ end
69
79
  end
70
80
  error do
71
81
  # `self` is the sinatra call in this context
72
- ErrorHandler.run(env['sinatra.error'], {
73
- :server_data => server_data,
74
- :request => self.request,
75
- :response => self.response,
76
- :handler_class => self.request.env['deas.handler_class'],
77
- :handler => self.request.env['deas.handler'],
78
- :params => self.request.env['deas.params'],
79
- })
82
+ if env['sinatra.error']
83
+ env['deas.error'] = env['sinatra.error']
84
+ ErrorHandler.run(env['deas.error'], {
85
+ :server_data => server_data,
86
+ :request => self.request,
87
+ :response => self.response,
88
+ :handler_class => self.request.env['deas.handler_class'],
89
+ :handler => self.request.env['deas.handler'],
90
+ :params => self.request.env['deas.params'],
91
+ })
92
+ end
80
93
  end
81
94
 
82
95
  end
data/lib/deas/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Deas
2
- VERSION = "0.37.1"
2
+ VERSION = "0.38.0"
3
3
  end
@@ -13,6 +13,7 @@ module Factory
13
13
  message ||= Factory.text
14
14
  exception = nil
15
15
  begin; raise(klass, message); rescue klass => exception; end
16
+ exception.set_backtrace(nil) if Factory.boolean
16
17
  exception
17
18
  end
18
19
 
@@ -12,7 +12,7 @@ class DeasTestServer
12
12
 
13
13
  error do |exception, context|
14
14
  case exception
15
- when Sinatra::NotFound
15
+ when Deas::NotFound
16
16
  [404, "Couldn't be found"]
17
17
  when Exception
18
18
  [500, "Oops, something went wrong"]
@@ -155,7 +155,7 @@ module Deas
155
155
 
156
156
  assert_equal 404, last_response.status
157
157
  assert_equal "text/plain", last_response.headers['Content-Type']
158
- assert_match "Sinatra::NotFound: Sinatra::NotFound", last_response.body
158
+ assert_match "Deas::NotFound: /not_defined", last_response.body
159
159
  end
160
160
 
161
161
  should "return a text/plain body when an exception occurs" do
@@ -41,6 +41,11 @@ module Deas
41
41
  assert_kind_of Deas::Error, Deas::HandlerProxyNotFound.new
42
42
  end
43
43
 
44
+ should "provide a generic not found exception" do
45
+ assert Deas::NotFound
46
+ assert_kind_of Deas::Error, Deas::NotFound.new
47
+ end
48
+
44
49
  end
45
50
 
46
51
  end
@@ -85,18 +85,15 @@ module Deas::Logging
85
85
  assert_equal exp, @env['deas.time_taken']
86
86
  end
87
87
 
88
- should "log a sinatra.error env key if it exists" do
89
- @env.delete('sinatra.error')
88
+ should "log a deas.error env key if it exists" do
89
+ @env.delete('deas.error')
90
90
  subject.call(@env)
91
91
  assert_empty @logger.info_logged
92
92
 
93
- @env['sinatra.error'] = Factory.exception(Sinatra::NotFound)
93
+ @env['deas.error'] = error = Factory.exception
94
94
  subject.call(@env)
95
- assert_empty @logger.info_logged
96
-
97
- @env['sinatra.error'] = error = Factory.exception
98
- subject.call(@env)
99
- exp = "[Deas] #{error.class}: #{error.message}\n#{error.backtrace.join("\n")}"
95
+ exp = "[Deas] #{error.class}: #{error.message}\n" \
96
+ "#{(error.backtrace || []).join("\n")}"
100
97
  assert_includes exp, @logger.info_logged
101
98
  end
102
99
 
@@ -0,0 +1,87 @@
1
+ require 'assert'
2
+ require 'deas/respond_with_proxy'
3
+
4
+ require 'deas/handler_proxy'
5
+ require 'deas/test_helpers'
6
+ require 'deas/url'
7
+ require 'deas/view_handler'
8
+
9
+ class Deas::RespondWithProxy
10
+
11
+ class UnitTests < Assert::Context
12
+ desc "Deas::RespondWithProxy"
13
+ setup do
14
+ @status = Factory.integer
15
+ @headers = { Factory.string => Factory.string }
16
+ @body = Factory.string
17
+ @proxy = Deas::RespondWithProxy.new([@status, @headers, @body])
18
+ end
19
+ subject{ @proxy }
20
+
21
+ should "be a HandlerProxy" do
22
+ assert_kind_of Deas::HandlerProxy, subject
23
+ end
24
+
25
+ end
26
+
27
+ class HandlerClassTests < UnitTests
28
+ include Deas::TestHelpers
29
+
30
+ desc "handler class"
31
+ setup do
32
+ @handler_class = @proxy.handler_class
33
+ end
34
+ subject{ @handler_class }
35
+
36
+ should have_accessor :halt_args
37
+ should have_imeth :name
38
+
39
+ should "be a view handler" do
40
+ subject.included_modules.tap do |modules|
41
+ assert_includes Deas::ViewHandler, modules
42
+ end
43
+ end
44
+
45
+ should "store the args to halt with" do
46
+ assert_equal [@status, @headers, @body], subject.halt_args
47
+ end
48
+
49
+ should "know its name" do
50
+ assert_equal 'Deas::RespondWithHandler', subject.name
51
+ end
52
+
53
+ end
54
+
55
+ class HandlerTests < HandlerClassTests
56
+ desc "handler instance"
57
+ setup do
58
+ @handler = test_handler(@handler_class)
59
+ end
60
+ subject{ @handler }
61
+
62
+ should have_reader :halt_args
63
+
64
+ should "know its halt args" do
65
+ assert_equal [@status, @headers, @body], subject.halt_args
66
+ end
67
+
68
+ end
69
+
70
+ class RunTests < HandlerClassTests
71
+ desc "when run"
72
+ setup do
73
+ @runner = test_runner(@handler_class)
74
+ @handler = @runner.handler
75
+ @response = @runner.run
76
+ end
77
+ subject{ @response }
78
+
79
+ should "halt and respond with the halt args" do
80
+ assert_equal @status, subject.status
81
+ assert_equal @headers, subject.headers
82
+ assert_equal @body, subject.body
83
+ end
84
+
85
+ end
86
+
87
+ end
@@ -31,7 +31,7 @@ class Deas::Router
31
31
  end
32
32
  subject{ @router }
33
33
 
34
- should have_readers :request_types, :urls, :routes
34
+ should have_readers :request_types, :urls, :routes, :definitions
35
35
  should have_readers :escape_query_value_proc
36
36
 
37
37
  should have_imeths :view_handler_ns, :escape_query_value
@@ -40,7 +40,8 @@ class Deas::Router
40
40
  should have_imeths :default_request_type_name, :add_request_type
41
41
  should have_imeths :request_type_name
42
42
  should have_imeths :get, :post, :put, :patch, :delete
43
- should have_imeths :route, :redirect
43
+ should have_imeths :route, :redirect, :not_found
44
+ should have_imeths :apply_definitions!, :validate!
44
45
 
45
46
  should "default its settings" do
46
47
  router = @router_class.new
@@ -49,6 +50,7 @@ class Deas::Router
49
50
  assert_empty router.request_types
50
51
  assert_empty router.urls
51
52
  assert_empty router.routes
53
+ assert_empty router.definitions
52
54
 
53
55
  exp = @router_class::DEFAULT_REQUEST_TYPE_NAME
54
56
  assert_equal exp, router.default_request_type_name
@@ -58,6 +60,15 @@ class Deas::Router
58
60
  assert_equal exp, router.escape_query_value_proc.call(value)
59
61
  end
60
62
 
63
+ should "instance eval any given block" do
64
+ ns = Factory.string
65
+ router = Deas::Router.new do
66
+ view_handler_ns ns
67
+ end
68
+
69
+ assert_equal ns, router.view_handler_ns
70
+ end
71
+
61
72
  should "set a view handler namespace" do
62
73
  subject.view_handler_ns(exp = Factory.string)
63
74
  assert_equal exp, subject.view_handler_ns
@@ -71,6 +82,100 @@ class Deas::Router
71
82
  assert_raises(ArgumentError){ subject.escape_query_value }
72
83
  end
73
84
 
85
+ should "add get, post, put, patch and delete route definitions" do
86
+ path = Factory.path
87
+ args = [Factory.string]
88
+
89
+ [:get, :post, :put, :patch, :delete].each do |meth|
90
+ subject.send(meth, path, *args)
91
+ d = DefinitionSpy.new(*subject.definitions.last)
92
+ assert_equal :route, d.type
93
+ assert_equal [meth, path, *args], d.args
94
+ assert_equal nil, d.block
95
+ end
96
+ end
97
+
98
+ should "add redirect definitions" do
99
+ from_path = Factory.path
100
+ to_path = Factory.path
101
+ block = proc{}
102
+
103
+ subject.redirect(from_path, to_path, &block)
104
+ d = DefinitionSpy.new(*subject.definitions.last)
105
+ assert_equal :redirect, d.type
106
+ assert_equal [from_path, to_path], d.args
107
+ assert_equal block, d.block
108
+
109
+ subject.redirect(from_path, to_path)
110
+ d = DefinitionSpy.new(*subject.definitions.last)
111
+ assert_equal :redirect, d.type
112
+ assert_equal [from_path, to_path], d.args
113
+ assert_equal nil, d.block
114
+
115
+ subject.redirect(from_path)
116
+ d = DefinitionSpy.new(*subject.definitions.last)
117
+ assert_equal :redirect, d.type
118
+ assert_equal [from_path, nil], d.args
119
+ assert_equal nil, d.block
120
+ end
121
+
122
+ should "add not found definitions" do
123
+ from_path = Factory.path
124
+ body = Factory.string
125
+
126
+ subject.not_found(from_path, body)
127
+
128
+ args = [404, {}, body]
129
+ d = DefinitionSpy.new(*subject.definitions.last)
130
+ assert_equal :respond_with, d.type
131
+ assert_equal [from_path, args], d.args
132
+ assert_equal nil, d.block
133
+ end
134
+
135
+ should "add a route for every definition when applying defintions" do
136
+ subject.set_base_url(nil)
137
+
138
+ path1 = Factory.path
139
+ path2 = Factory.path
140
+ subject.get(path1)
141
+ subject.redirect(path1, path2)
142
+ subject.not_found(path1)
143
+
144
+ assert_not_empty subject.definitions
145
+ assert_empty subject.routes
146
+
147
+ subject.apply_definitions!
148
+ assert_equal 3, subject.routes.size
149
+ assert_empty subject.definitions
150
+
151
+ get = subject.routes[0]
152
+ assert_equal path1, get.path
153
+
154
+ redir = subject.routes[1]
155
+ assert_equal path1, redir.path
156
+
157
+ nf = subject.routes[2]
158
+ assert_equal path1, nf.path
159
+ end
160
+
161
+ should "apply definitions and validate each route when validating" do
162
+ subject.get('/something', 'EmptyViewHandler')
163
+ subject.apply_definitions!
164
+ route = subject.routes.last
165
+ proxy = route.handler_proxies[subject.default_request_type_name]
166
+
167
+ apply_def_called = false
168
+ Assert.stub(subject, :apply_definitions!){ apply_def_called = true }
169
+
170
+ assert_false apply_def_called
171
+ assert_nil proxy.handler_class
172
+
173
+ subject.validate!
174
+
175
+ assert_true apply_def_called
176
+ assert_equal EmptyViewHandler, proxy.handler_class
177
+ end
178
+
74
179
  should "set a base url" do
75
180
  subject.base_url(exp = Factory.url)
76
181
  assert_equal exp, subject.base_url
@@ -97,7 +202,8 @@ class Deas::Router
97
202
  url = Factory.url
98
203
  subject.base_url url
99
204
  path = Factory.path
100
- route = subject.get(path, Object)
205
+ subject.get(path); subject.apply_definitions!
206
+ route = subject.routes.last
101
207
 
102
208
  exp_path = subject.prepend_base_url(path)
103
209
  assert_equal exp_path, route.path
@@ -108,7 +214,8 @@ class Deas::Router
108
214
  subject.base_url url
109
215
  path1 = Factory.path
110
216
  path2 = Factory.path
111
- redirect = subject.redirect(path1, path2)
217
+ subject.redirect(path1, path2); subject.apply_definitions!
218
+ redirect = subject.routes.last
112
219
 
113
220
  exp = subject.prepend_base_url(path1)
114
221
  assert_equal exp, redirect.path
@@ -119,6 +226,17 @@ class Deas::Router
119
226
  assert_equal exp, handler.redirect_path
120
227
  end
121
228
 
229
+ should "prepend the base url when adding not founds" do
230
+ url = Factory.url
231
+ subject.base_url url
232
+ path = Factory.path
233
+ subject.not_found(path); subject.apply_definitions!
234
+ route = subject.routes.last
235
+
236
+ exp_path = subject.prepend_base_url(path)
237
+ assert_equal exp_path, route.path
238
+ end
239
+
122
240
  should "set a default request type name" do
123
241
  subject.default_request_type_name(exp = Factory.string)
124
242
  assert_equal exp, subject.default_request_type_name
@@ -150,28 +268,6 @@ class Deas::Router
150
268
  assert_equal exp, subject.request_type_name(Factory.string)
151
269
  end
152
270
 
153
- should "add get, post, put, patch and delete routes" do
154
- Assert.stub(subject, :route){ |*args| RouteSpy.new(*args) }
155
- path = Factory.path
156
- args = [Factory.string]
157
-
158
- [:get, :post, :put, :patch, :delete].each do |meth|
159
- route = subject.send(meth, path, *args)
160
- assert_equal meth, route.method
161
- assert_equal path, route.path
162
- assert_equal args, route.args
163
- end
164
- end
165
-
166
- should "instance eval any given block" do
167
- ns = Factory.string
168
- router = Deas::Router.new do
169
- view_handler_ns ns
170
- end
171
-
172
- assert_equal ns, router.view_handler_ns
173
- end
174
-
175
271
  end
176
272
 
177
273
  class RouteTests < InitTests
@@ -186,7 +282,7 @@ class Deas::Router
186
282
  should "add a Route with the given method and path" do
187
283
  assert_empty subject.routes
188
284
 
189
- subject.route(@method, @path1)
285
+ subject.route(@method, @path1); subject.apply_definitions!
190
286
  assert_not_empty subject.routes
191
287
 
192
288
  route = subject.routes.last
@@ -201,7 +297,7 @@ class Deas::Router
201
297
  end
202
298
 
203
299
  should "proxy any handler class given for the default request type" do
204
- subject.route(@method, @path1, @handler_class_name1)
300
+ subject.route(@method, @path1, @handler_class_name1); subject.apply_definitions!
205
301
  route = subject.routes.last
206
302
  proxy = route.handler_proxies[subject.default_request_type_name]
207
303
  assert_kind_of Deas::RouteProxy, proxy
@@ -209,7 +305,7 @@ class Deas::Router
209
305
 
210
306
  subject.route(@method, @path1, @handler_class_name1, {
211
307
  subject.default_request_type_name => @handler_class_name2
212
- })
308
+ }); subject.apply_definitions!
213
309
  route = subject.routes.last
214
310
  proxy = route.handler_proxies[subject.default_request_type_name]
215
311
  assert_kind_of Deas::RouteProxy, proxy
@@ -221,7 +317,7 @@ class Deas::Router
221
317
  subject.route(@method, @path1, {
222
318
  '1' => @handler_class_name1,
223
319
  '2' => @handler_class_name2,
224
- })
320
+ }); subject.apply_definitions!
225
321
  route = subject.routes.last
226
322
 
227
323
  proxy = route.handler_proxies['1']
@@ -234,7 +330,7 @@ class Deas::Router
234
330
  end
235
331
 
236
332
  should "add redirect routes" do
237
- subject.redirect(@path1, @path2)
333
+ subject.redirect(@path1, @path2); subject.apply_definitions!
238
334
 
239
335
  route = subject.routes.last
240
336
  assert_instance_of Deas::Route, route
@@ -250,6 +346,30 @@ class Deas::Router
250
346
  assert_equal exp, handler.redirect_path
251
347
  end
252
348
 
349
+ should "add not found routes" do
350
+ subject.not_found(@path1); subject.apply_definitions!
351
+
352
+ route = subject.routes.last
353
+ assert_instance_of Deas::Route, route
354
+ assert_equal :get, route.method
355
+ assert_equal subject.prepend_base_url(@path1), route.path
356
+
357
+ proxy = route.handler_proxies[subject.default_request_type_name]
358
+ assert_kind_of Deas::RespondWithProxy, proxy
359
+ assert_equal 'Deas::RespondWithHandler', proxy.handler_class_name
360
+
361
+ handler = test_handler(proxy.handler_class)
362
+ assert_equal [404, {}, 'Not Found'], handler.halt_args
363
+
364
+ body = Factory.string
365
+ subject.not_found(@path1, body); subject.apply_definitions!
366
+
367
+ route = subject.routes.last
368
+ proxy = route.handler_proxies[subject.default_request_type_name]
369
+ handler = test_handler(proxy.handler_class)
370
+ assert_equal [404, {}, body], handler.halt_args
371
+ end
372
+
253
373
  end
254
374
 
255
375
  class NamedUrlTests < InitTests
@@ -300,14 +420,37 @@ class Deas::Router
300
420
  end
301
421
  end
302
422
 
303
- should "complain if redirecting to a named url that hasn't been defined" do
423
+ should "complain if routing a named url that hasn't been defined" do
424
+ assert_raises ArgumentError do
425
+ subject.route(:get, :not_defined_url, 'GetInfo')
426
+ subject.apply_definitions!
427
+ end
428
+ end
429
+
430
+ should "route using a url name instead of a path" do
431
+ subject.route(:get, :get_info, 'GetInfo'); subject.apply_definitions!
432
+
433
+ url = subject.urls[:get_info]
434
+ route = subject.routes.last
435
+
436
+ exp = subject.prepend_base_url(url.path)
437
+ assert_equal exp, route.path
438
+ end
439
+
440
+ should "complain if redirecting to/from a named url that hasn't been defined" do
304
441
  assert_raises ArgumentError do
305
442
  subject.redirect('/somewhere', :not_defined_url)
443
+ subject.apply_definitions!
444
+ end
445
+ assert_raises ArgumentError do
446
+ subject.redirect(:not_defined_url, '/somewhere')
447
+ subject.apply_definitions!
306
448
  end
307
449
  end
308
450
 
309
451
  should "redirect using a url name instead of a path" do
310
- subject.redirect(:get_info, '/somewhere')
452
+ subject.redirect(:get_info, '/somewhere'); subject.apply_definitions!
453
+
311
454
  url = subject.urls[:get_info]
312
455
  route = subject.routes.last
313
456
 
@@ -315,8 +458,16 @@ class Deas::Router
315
458
  assert_equal exp, route.path
316
459
  end
317
460
 
318
- should "route using a url name instead of a path" do
319
- subject.route(:get, :get_info, 'GetInfo')
461
+ should "complain if adding a not found with a named url that hasn't been defined" do
462
+ assert_raises ArgumentError do
463
+ subject.not_found(:not_defined_url)
464
+ subject.apply_definitions!
465
+ end
466
+ end
467
+
468
+ should "add a not found using a url name instead of a path" do
469
+ subject.not_found(:get_info); subject.apply_definitions!
470
+
320
471
  url = subject.urls[:get_info]
321
472
  route = subject.routes.last
322
473
 
@@ -390,9 +541,5 @@ class Deas::Router
390
541
 
391
542
  end
392
543
 
393
- class RouteSpy < Struct.new(:method, :path, :args)
394
- def initialize(method, path, *args)
395
- super(method, path, args)
396
- end
397
- end
544
+ DefinitionSpy = Struct.new(:type, :args, :block)
398
545
  end
@@ -207,8 +207,9 @@ module Deas::Server
207
207
  @initialized = false
208
208
  @other_initialized = false
209
209
  @router = Deas::Router.new
210
- @route = @router.get('/something', 'EmptyViewHandler')
211
- @proxy = @route.handler_proxies[@router.default_request_type_name]
210
+
211
+ @router_validate_called = false
212
+ Assert.stub(@router, :validate!){ @router_validate_called = true }
212
213
 
213
214
  @configuration = Configuration.new.tap do |c|
214
215
  c.env = 'staging'
@@ -236,11 +237,11 @@ module Deas::Server
236
237
  assert_equal true, @other_initialized
237
238
  end
238
239
 
239
- should "call validate! on all routes" do
240
- assert_nil @proxy.handler_class
240
+ should "call validate! on the router" do
241
+ assert_false @router_validate_called
241
242
 
242
243
  subject.validate!
243
- assert_equal EmptyViewHandler, @proxy.handler_class
244
+ assert_true @router_validate_called
244
245
  end
245
246
 
246
247
  should "add the Logging and ShowExceptions middleware to the end" do
@@ -18,7 +18,7 @@ class Deas::ShowExceptions
18
18
  desc "when init"
19
19
  setup do
20
20
  @app = Factory.sinatra_call
21
- @env = { 'sinatra.error' => Factory.exception }
21
+ @env = { 'deas.error' => Factory.exception }
22
22
  @middleware = @middleware_class.new(@app)
23
23
  end
24
24
  subject{ @middleware }
@@ -27,7 +27,7 @@ class Deas::ShowExceptions
27
27
 
28
28
  should "return a response for the exception when called" do
29
29
  status, headers, body = subject.call(@env)
30
- error_body = Body.new(@env['sinatra.error'])
30
+ error_body = Body.new(@env['deas.error'])
31
31
 
32
32
  assert_equal @app.response.status, status
33
33
  assert_equal error_body.size.to_s, headers['Content-Length']
@@ -36,7 +36,7 @@ class Deas::ShowExceptions
36
36
  end
37
37
 
38
38
  should "return the apps response if there isn't an exception" do
39
- @env.delete('sinatra.error')
39
+ @env.delete('deas.error')
40
40
  status, headers, body = subject.call(@env)
41
41
 
42
42
  assert_equal @app.response.status, status
@@ -58,7 +58,7 @@ class Deas::ShowExceptions
58
58
 
59
59
  should "know its attributes" do
60
60
  exp_content = "#{@exception.class}: #{@exception.message}\n" \
61
- "#{@exception.backtrace.join("\n")}"
61
+ "#{(@exception.backtrace || []).join("\n")}"
62
62
  assert_equal exp_content, subject.content
63
63
  assert_equal Rack::Utils.bytesize(exp_content), subject.size
64
64
  assert_equal "text/plain", subject.mime_type
@@ -16,8 +16,8 @@ module Deas::SinatraApp
16
16
  desc "Deas::SinatraApp"
17
17
  setup do
18
18
  @router = Deas::Router.new
19
- @route = @router.get('/something', 'EmptyViewHandler')
20
- @proxy = @route.handler_proxies[@router.default_request_type_name]
19
+ @router.get('/something', 'EmptyViewHandler')
20
+ @router.validate!
21
21
 
22
22
  @configuration = Deas::Server::Configuration.new.tap do |c|
23
23
  c.env = 'staging'
@@ -74,10 +74,10 @@ module Deas::SinatraApp
74
74
  end
75
75
 
76
76
  should "define Sinatra routes for every route in the configuration" do
77
- get_routes = subject.routes[@route.method.to_s.upcase] || []
78
- sinatra_route = get_routes.detect{ |route| route[0].match(@route.path) }
77
+ router_route = @router.routes.last
78
+ sinatra_routes = subject.routes[router_route.method.to_s.upcase] || []
79
79
 
80
- assert_not_nil sinatra_route
80
+ assert_not_nil sinatra_routes.detect{ |r| r[0].match(router_route.path) }
81
81
  end
82
82
 
83
83
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: deas
3
3
  version: !ruby/object:Gem::Version
4
- hash: 137
4
+ hash: 135
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 37
9
- - 1
10
- version: 0.37.1
8
+ - 38
9
+ - 0
10
+ version: 0.38.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Kelly Redding
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2015-10-07 00:00:00 Z
19
+ date: 2015-10-21 00:00:00 Z
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  requirement: &id001 !ruby/object:Gem::Requirement
@@ -126,6 +126,7 @@ files:
126
126
  - lib/deas/logging.rb
127
127
  - lib/deas/rack_request_fix.rb
128
128
  - lib/deas/redirect_proxy.rb
129
+ - lib/deas/respond_with_proxy.rb
129
130
  - lib/deas/route.rb
130
131
  - lib/deas/route_proxy.rb
131
132
  - lib/deas/router.rb
@@ -161,6 +162,7 @@ files:
161
162
  - test/unit/handler_proxy_tests.rb
162
163
  - test/unit/logging_tests.rb
163
164
  - test/unit/redirect_proxy_tests.rb
165
+ - test/unit/respond_with_proxy_tests.rb
164
166
  - test/unit/route_proxy_tests.rb
165
167
  - test/unit/route_tests.rb
166
168
  - test/unit/router_tests.rb
@@ -206,7 +208,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
206
208
  requirements: []
207
209
 
208
210
  rubyforge_project:
209
- rubygems_version: 1.8.25
211
+ rubygems_version: 1.8.29
210
212
  signing_key:
211
213
  specification_version: 3
212
214
  summary: Handler-based web framework powered by Sinatra
@@ -229,6 +231,7 @@ test_files:
229
231
  - test/unit/handler_proxy_tests.rb
230
232
  - test/unit/logging_tests.rb
231
233
  - test/unit/redirect_proxy_tests.rb
234
+ - test/unit/respond_with_proxy_tests.rb
232
235
  - test/unit/route_proxy_tests.rb
233
236
  - test/unit/route_tests.rb
234
237
  - test/unit/router_tests.rb