deas 0.37.1 → 0.38.0

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.
@@ -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