deas 0.42.0 → 0.43.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/deas.gemspec +1 -1
- data/lib/deas/error_handler.rb +17 -12
- data/lib/deas/handler_proxy.rb +18 -18
- data/lib/deas/logging.rb +4 -3
- data/lib/deas/request_data.rb +33 -0
- data/lib/deas/route.rb +5 -7
- data/lib/deas/router.rb +15 -5
- data/lib/deas/runner.rb +49 -6
- data/lib/deas/server.rb +41 -115
- data/lib/deas/server_data.rb +12 -1
- data/lib/deas/sinatra_app.rb +69 -43
- data/lib/deas/test_runner.rb +3 -2
- data/lib/deas/url.rb +11 -7
- data/lib/deas/version.rb +1 -1
- data/lib/deas/view_handler.rb +0 -2
- data/test/support/factory.rb +16 -0
- data/test/support/fake_request.rb +1 -0
- data/test/support/fake_response.rb +12 -0
- data/test/support/fake_sinatra_call.rb +1 -11
- data/test/support/routes.rb +8 -7
- data/test/system/deas_tests.rb +3 -11
- data/test/unit/error_handler_tests.rb +19 -5
- data/test/unit/handler_proxy_tests.rb +28 -33
- data/test/unit/logging_tests.rb +12 -5
- data/test/unit/request_data_tests.rb +57 -0
- data/test/unit/route_tests.rb +15 -15
- data/test/unit/router_tests.rb +38 -24
- data/test/unit/runner_tests.rb +66 -12
- data/test/unit/server_data_tests.rb +14 -1
- data/test/unit/server_tests.rb +41 -106
- data/test/unit/sinatra_app_tests.rb +38 -24
- data/test/unit/test_runner_tests.rb +7 -4
- data/test/unit/url_tests.rb +13 -2
- data/test/unit/view_handler_tests.rb +1 -7
- metadata +8 -3
data/lib/deas/server_data.rb
CHANGED
@@ -9,7 +9,7 @@ module Deas
|
|
9
9
|
|
10
10
|
attr_reader :error_procs, :template_source, :logger, :router
|
11
11
|
|
12
|
-
def initialize(args
|
12
|
+
def initialize(args)
|
13
13
|
args ||= {}
|
14
14
|
@error_procs = args[:error_procs] || []
|
15
15
|
@template_source = args[:template_source]
|
@@ -17,6 +17,17 @@ module Deas
|
|
17
17
|
@router = args[:router]
|
18
18
|
end
|
19
19
|
|
20
|
+
def ==(other_server_data)
|
21
|
+
if other_server_data.kind_of?(ServerData)
|
22
|
+
self.error_procs == other_server_data.error_procs &&
|
23
|
+
self.template_source == other_server_data.template_source &&
|
24
|
+
self.logger == other_server_data.logger &&
|
25
|
+
self.router == other_server_data.router
|
26
|
+
else
|
27
|
+
super
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
20
31
|
end
|
21
32
|
|
22
33
|
end
|
data/lib/deas/sinatra_app.rb
CHANGED
@@ -1,12 +1,27 @@
|
|
1
1
|
require 'sinatra/base'
|
2
2
|
require 'deas/error_handler'
|
3
3
|
require 'deas/exceptions'
|
4
|
+
require 'deas/request_data'
|
4
5
|
require 'deas/server_data'
|
5
6
|
|
6
7
|
module Deas
|
7
8
|
|
8
9
|
module SinatraApp
|
9
10
|
|
11
|
+
DEFAULT_ERROR_RESPONSE_STATUS = 500.freeze
|
12
|
+
|
13
|
+
# these are standard error classes that we rescue, handle and don't reraise
|
14
|
+
# in the rack app, this keeps the app from shutting down unexpectedly;
|
15
|
+
# `LoadError`, `NotImplementedError` and `Timeout::Error` are common non
|
16
|
+
# `StandardError` exceptions that should be treated like a `StandardError`
|
17
|
+
# so we don't want one of these to shutdown the app
|
18
|
+
STANDARD_ERROR_CLASSES = [
|
19
|
+
StandardError,
|
20
|
+
LoadError,
|
21
|
+
NotImplementedError,
|
22
|
+
Timeout::Error
|
23
|
+
].freeze
|
24
|
+
|
10
25
|
def self.new(server_config)
|
11
26
|
# This is generic server initialization stuff. Eventually do this in the
|
12
27
|
# server's initialization logic more like Sanford does.
|
@@ -19,17 +34,11 @@ module Deas
|
|
19
34
|
})
|
20
35
|
|
21
36
|
Sinatra.new do
|
22
|
-
#
|
23
|
-
|
24
|
-
|
25
|
-
set :
|
26
|
-
set :
|
27
|
-
set :default_encoding, server_config.default_encoding
|
28
|
-
set :dump_errors, server_config.dump_errors
|
29
|
-
set :method_override, server_config.method_override
|
30
|
-
set :reload_templates, server_config.reload_templates
|
31
|
-
set :sessions, server_config.sessions
|
32
|
-
set :static, server_config.static_files
|
37
|
+
# unifying settings - these are used by Deas so extensions can have a
|
38
|
+
# common way to identify these low-level settings. Deas does not use
|
39
|
+
# them directly
|
40
|
+
set :environment, server_config.env
|
41
|
+
set :root, server_config.root
|
33
42
|
|
34
43
|
# TODO: sucks to have to do this but b/c of Rack there is no better way
|
35
44
|
# to make the server data available to middleware. We should remove this
|
@@ -38,32 +47,61 @@ module Deas
|
|
38
47
|
# Not sure right now, just jotting down notes.
|
39
48
|
set :deas_server_data, server_data
|
40
49
|
|
50
|
+
# static settings - Deas doesn't care about these anymore so just
|
51
|
+
# use some intelligent defaults
|
52
|
+
set :views, server_config.root
|
53
|
+
set :public_folder, server_config.root
|
54
|
+
set :default_encoding, 'utf-8'
|
55
|
+
set :method_override, false
|
56
|
+
set :reload_templates, false
|
57
|
+
set :static, false
|
58
|
+
set :sessions, false
|
59
|
+
|
60
|
+
# Turn this off b/c Deas won't auto provide it. We may add an extension
|
61
|
+
# gem or something??
|
62
|
+
disable :protection
|
63
|
+
|
41
64
|
# raise_errors and show_exceptions prevent Deas error handlers from being
|
42
65
|
# called and Deas' logging doesn't finish. They should always be false.
|
43
66
|
set :raise_errors, false
|
44
67
|
set :show_exceptions, false
|
45
68
|
|
46
|
-
# turn off logging b/c Deas handles its own logging logic
|
69
|
+
# turn off logging, dump_errors b/c Deas handles its own logging logic
|
70
|
+
set :dump_errors, false
|
47
71
|
set :logging, false
|
48
72
|
|
49
|
-
# TODO: rework with `server_config.default_encoding` once we move off of using Sinatra
|
50
|
-
# TODO: could maybe move into a deas-json mixin once off of Sinatra
|
51
|
-
# Add charset to json content type responses - by default only added to these:
|
52
|
-
# ["application/javascript", "application/xml", "application/xhtml+xml", /^text\//]
|
53
|
-
settings.add_charset << "application/json"
|
54
|
-
|
55
|
-
server_config.settings.each{ |set_args| set *set_args }
|
56
73
|
server_config.middlewares.each{ |use_args| use *use_args }
|
57
74
|
|
58
75
|
# routes
|
59
76
|
server_config.routes.each do |route|
|
60
|
-
|
61
|
-
|
62
|
-
|
77
|
+
send(route.method, route.path) do
|
78
|
+
begin
|
79
|
+
route.run(
|
80
|
+
server_data,
|
81
|
+
RequestData.new({
|
82
|
+
:request => request,
|
83
|
+
:response => response,
|
84
|
+
:params => params,
|
85
|
+
:route_path => route.path
|
86
|
+
})
|
87
|
+
)
|
88
|
+
rescue *STANDARD_ERROR_CLASSES => err
|
89
|
+
request.env['deas.error'] = err
|
90
|
+
response.status = DEFAULT_ERROR_RESPONSE_STATUS
|
91
|
+
ErrorHandler.run(request.env['deas.error'], {
|
92
|
+
:server_data => server_data,
|
93
|
+
:request => request,
|
94
|
+
:response => response,
|
95
|
+
:handler_class => request.env['deas.handler_class'],
|
96
|
+
:handler => request.env['deas.handler'],
|
97
|
+
:params => request.env['deas.params'],
|
98
|
+
:splat => request.env['deas.splat'],
|
99
|
+
:route_path => request.env['deas.route_path']
|
100
|
+
})
|
101
|
+
end
|
102
|
+
end
|
63
103
|
end
|
64
104
|
|
65
|
-
# error handling
|
66
|
-
|
67
105
|
not_found do
|
68
106
|
# `self` is the sinatra call in this context
|
69
107
|
if env['sinatra.error']
|
@@ -76,25 +114,13 @@ module Deas
|
|
76
114
|
end
|
77
115
|
ErrorHandler.run(env['deas.error'], {
|
78
116
|
:server_data => server_data,
|
79
|
-
:request =>
|
80
|
-
:response =>
|
81
|
-
:handler_class =>
|
82
|
-
:handler =>
|
83
|
-
:params =>
|
84
|
-
|
85
|
-
|
86
|
-
end
|
87
|
-
error do
|
88
|
-
# `self` is the sinatra call in this context
|
89
|
-
if env['sinatra.error']
|
90
|
-
env['deas.error'] = env['sinatra.error']
|
91
|
-
ErrorHandler.run(env['deas.error'], {
|
92
|
-
:server_data => server_data,
|
93
|
-
:request => self.request,
|
94
|
-
:response => self.response,
|
95
|
-
:handler_class => self.request.env['deas.handler_class'],
|
96
|
-
:handler => self.request.env['deas.handler'],
|
97
|
-
:params => self.request.env['deas.params'],
|
117
|
+
:request => request,
|
118
|
+
:response => response,
|
119
|
+
:handler_class => request.env['deas.handler_class'],
|
120
|
+
:handler => request.env['deas.handler'],
|
121
|
+
:params => request.env['deas.params'],
|
122
|
+
:splat => request.env['deas.splat'],
|
123
|
+
:route_path => request.env['deas.route_path']
|
98
124
|
})
|
99
125
|
end
|
100
126
|
end
|
data/lib/deas/test_runner.rb
CHANGED
@@ -27,15 +27,16 @@ module Deas
|
|
27
27
|
:router => a.delete(:router),
|
28
28
|
:template_source => a.delete(:template_source),
|
29
29
|
:request => a.delete(:request),
|
30
|
-
:session => a.delete(:session),
|
31
30
|
:params => NormalizedParams.new(a.delete(:params) || {}).value,
|
32
|
-
:
|
31
|
+
:route_path => a.delete(:route_path)
|
33
32
|
})
|
33
|
+
@splat = a.delete(:splat)
|
34
34
|
a.each{|key, value| self.handler.send("#{key}=", value) }
|
35
35
|
|
36
36
|
catch(:halt){ self.handler.deas_init }
|
37
37
|
end
|
38
38
|
|
39
|
+
def splat; @splat; end
|
39
40
|
def halted?; @halted; end
|
40
41
|
|
41
42
|
def run
|
data/lib/deas/url.rb
CHANGED
@@ -38,16 +38,20 @@ module Deas
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def set_named(path, params)
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
41
|
+
# Process longer param names first. This ensures that shorter names that
|
42
|
+
# compose longer names won't be set as a part of the longer name.
|
43
|
+
params.keys.sort{ |a, b| b.to_s.size <=> a.to_s.size }.inject(path) do |p, name|
|
44
|
+
if p.include?(":#{name}")
|
45
|
+
if (v = params[name].to_s).empty?
|
46
|
+
raise EmptyNamedValueError , "an empty value, " \
|
47
|
+
"`#{params[name].inspect}`, " \
|
48
|
+
"was given for the " \
|
49
|
+
"`#{name.inspect}` url param"
|
46
50
|
end
|
47
51
|
params.delete(name)
|
48
|
-
|
52
|
+
p.gsub(":#{name}", v)
|
49
53
|
else
|
50
|
-
|
54
|
+
p
|
51
55
|
end
|
52
56
|
end
|
53
57
|
end
|
data/lib/deas/version.rb
CHANGED
data/lib/deas/view_handler.rb
CHANGED
@@ -65,7 +65,6 @@ module Deas
|
|
65
65
|
|
66
66
|
# request
|
67
67
|
def request; @deas_runner.request; end
|
68
|
-
def session; @deas_runner.session; end
|
69
68
|
def params; @deas_runner.params; end
|
70
69
|
def splat; @deas_runner.splat; end
|
71
70
|
|
@@ -131,7 +130,6 @@ module Deas
|
|
131
130
|
def test_runner(handler_class, args = nil)
|
132
131
|
args ||= {}
|
133
132
|
args[:request] ||= Rack::Request.new({})
|
134
|
-
args[:session] ||= args[:request].session
|
135
133
|
TestRunner.new(handler_class, args)
|
136
134
|
end
|
137
135
|
|
data/test/support/factory.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
require 'assert/factory'
|
2
2
|
require 'deas/logger'
|
3
|
+
require 'deas/request_data'
|
3
4
|
require 'deas/router'
|
4
5
|
require 'deas/server_data'
|
5
6
|
require 'deas/template_source'
|
6
7
|
require 'test/support/fake_request'
|
8
|
+
require 'test/support/fake_response'
|
7
9
|
require 'test/support/fake_sinatra_call'
|
8
10
|
|
9
11
|
module Factory
|
@@ -30,6 +32,20 @@ module Factory
|
|
30
32
|
FakeRequest.new(args)
|
31
33
|
end
|
32
34
|
|
35
|
+
def self.response(args = nil)
|
36
|
+
FakeResponse.new(args)
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.request_data(args = nil)
|
40
|
+
args ||= {}
|
41
|
+
Deas::RequestData.new({
|
42
|
+
:request => args[:request] || Factory.request,
|
43
|
+
:response => args[:response] || Factory.response,
|
44
|
+
:params => args[:params] || { Factory.string => Factory.string },
|
45
|
+
:route_path => args[:route_path] || Factory.string
|
46
|
+
})
|
47
|
+
end
|
48
|
+
|
33
49
|
def self.sinatra_call(settings = nil)
|
34
50
|
FakeSinatraCall.new(settings)
|
35
51
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'test/support/fake_request'
|
2
|
+
require 'test/support/fake_response'
|
2
3
|
|
3
4
|
class FakeSinatraCall
|
4
5
|
|
@@ -68,14 +69,3 @@ class FakeSinatraCall
|
|
68
69
|
SendFileArgs = Struct.new(:file_path, :options, :block_call_result)
|
69
70
|
|
70
71
|
end
|
71
|
-
|
72
|
-
class FakeResponse < Struct.new(:status, :headers, :body)
|
73
|
-
def initialize(args = nil)
|
74
|
-
args ||= {}
|
75
|
-
super(*[
|
76
|
-
args[:status] || Factory.integer,
|
77
|
-
args[:headers] || {},
|
78
|
-
args[:body] || [Factory.text]
|
79
|
-
])
|
80
|
-
end
|
81
|
-
end
|
data/test/support/routes.rb
CHANGED
@@ -8,13 +8,11 @@ class DeasTestServer
|
|
8
8
|
logger TEST_LOGGER
|
9
9
|
verbose_logging Factory.boolean
|
10
10
|
|
11
|
-
set :a_setting, 'something'
|
12
|
-
|
13
11
|
error do |exception, context|
|
14
12
|
case exception
|
15
13
|
when Deas::NotFound
|
16
14
|
[404, "Couldn't be found"]
|
17
|
-
when
|
15
|
+
when *Deas::SinatraApp::STANDARD_ERROR_CLASSES
|
18
16
|
[500, "Oops, something went wrong"]
|
19
17
|
end
|
20
18
|
end
|
@@ -46,6 +44,10 @@ class DeasTestServer
|
|
46
44
|
redirect('/:prefix/redirect'){ "/#{params['prefix']}/somewhere" }
|
47
45
|
end
|
48
46
|
|
47
|
+
use Rack::Session::Cookie, :key => 'my.session',
|
48
|
+
:expire_after => Factory.integer,
|
49
|
+
:secret => Factory.string
|
50
|
+
|
49
51
|
end
|
50
52
|
|
51
53
|
class DeasDevServer
|
@@ -153,7 +155,7 @@ class ErrorHandler
|
|
153
155
|
include Deas::ViewHandler
|
154
156
|
|
155
157
|
def run!
|
156
|
-
raise '
|
158
|
+
raise Deas::SinatraApp::STANDARD_ERROR_CLASSES.sample, 'sinatra app standard error'
|
157
159
|
end
|
158
160
|
|
159
161
|
end
|
@@ -171,7 +173,7 @@ class SetSessionHandler
|
|
171
173
|
include Deas::ViewHandler
|
172
174
|
|
173
175
|
def run!
|
174
|
-
session[:secret] = 'session_secret'
|
176
|
+
request.session[:secret] = 'session_secret'
|
175
177
|
redirect '/session'
|
176
178
|
end
|
177
179
|
|
@@ -181,7 +183,7 @@ class UseSessionHandler
|
|
181
183
|
include Deas::ViewHandler
|
182
184
|
|
183
185
|
def run!
|
184
|
-
body session[:secret]
|
186
|
+
body request.session[:secret]
|
185
187
|
end
|
186
188
|
|
187
189
|
end
|
@@ -194,7 +196,6 @@ class HandlerTestsHandler
|
|
194
196
|
set_data('logger_class_name'){ logger.class.name }
|
195
197
|
set_data('request_method'){ request.request_method.to_s }
|
196
198
|
set_data('params_a_param'){ params['a-param'] }
|
197
|
-
set_data('session_inspect'){ session.inspect }
|
198
199
|
end
|
199
200
|
|
200
201
|
def set_data(a, &block)
|
data/test/system/deas_tests.rb
CHANGED
@@ -111,14 +111,7 @@ module Deas
|
|
111
111
|
end
|
112
112
|
|
113
113
|
class SessionTests < RackTests
|
114
|
-
desc "
|
115
|
-
setup do
|
116
|
-
@orig_sessions = @app.settings.sessions
|
117
|
-
@app.set :sessions, true
|
118
|
-
end
|
119
|
-
teardown do
|
120
|
-
@app.set :sessions, @orig_sessions
|
121
|
-
end
|
114
|
+
desc "using sessions"
|
122
115
|
|
123
116
|
should "return a 200 response and the session value" do
|
124
117
|
post '/session'
|
@@ -141,8 +134,7 @@ module Deas
|
|
141
134
|
exp = {
|
142
135
|
'logger_class_name' => 'Logger',
|
143
136
|
'request_method' => 'GET',
|
144
|
-
'params_a_param' => 'something'
|
145
|
-
'session_inspect' => '{}'
|
137
|
+
'params_a_param' => 'something'
|
146
138
|
}
|
147
139
|
assert_equal exp.inspect, @data_inspect
|
148
140
|
end
|
@@ -168,7 +160,7 @@ module Deas
|
|
168
160
|
|
169
161
|
assert_equal 500, last_response.status
|
170
162
|
assert_equal "text/plain", last_response.headers['Content-Type']
|
171
|
-
assert_match "
|
163
|
+
assert_match "sinatra app standard error", last_response.body
|
172
164
|
end
|
173
165
|
|
174
166
|
end
|
@@ -12,9 +12,11 @@ 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
|
-
@handler_class =
|
15
|
+
@handler_class = Deas::ErrorHandler
|
16
16
|
@handler = Factory.string
|
17
17
|
@params = Factory.string
|
18
|
+
@splat = Factory.string
|
19
|
+
@route_path = Factory.string
|
18
20
|
|
19
21
|
@context_hash = {
|
20
22
|
:server_data => @server_data,
|
@@ -23,9 +25,9 @@ class Deas::ErrorHandler
|
|
23
25
|
:handler_class => @handler_class,
|
24
26
|
:handler => @handler,
|
25
27
|
:params => @params,
|
28
|
+
:splat => @splat,
|
29
|
+
:route_path => @route_path
|
26
30
|
}
|
27
|
-
|
28
|
-
@handler_class = Deas::ErrorHandler
|
29
31
|
end
|
30
32
|
subject{ @handler_class }
|
31
33
|
|
@@ -113,7 +115,8 @@ class Deas::ErrorHandler
|
|
113
115
|
subject{ @context }
|
114
116
|
|
115
117
|
should have_readers :server_data
|
116
|
-
should have_readers :request, :response, :handler_class, :handler
|
118
|
+
should have_readers :request, :response, :handler_class, :handler
|
119
|
+
should have_readers :params, :splat, :route_path
|
117
120
|
|
118
121
|
should "know its attributes" do
|
119
122
|
assert_equal @context_hash[:server_data], subject.server_data
|
@@ -122,13 +125,24 @@ class Deas::ErrorHandler
|
|
122
125
|
assert_equal @context_hash[:handler_class], subject.handler_class
|
123
126
|
assert_equal @context_hash[:handler], subject.handler
|
124
127
|
assert_equal @context_hash[:params], subject.params
|
128
|
+
assert_equal @context_hash[:splat], subject.splat
|
129
|
+
assert_equal @context_hash[:route_path], subject.route_path
|
125
130
|
end
|
126
131
|
|
127
132
|
should "know if it equals another context" do
|
128
133
|
exp = Context.new(@context_hash)
|
129
134
|
assert_equal exp, subject
|
130
135
|
|
131
|
-
exp = Context.new({
|
136
|
+
exp = Context.new({
|
137
|
+
:server_data => Factory.server_data,
|
138
|
+
:request => Factory.string,
|
139
|
+
:response => Factory.string,
|
140
|
+
:handler_class => Factory.string,
|
141
|
+
:handler => Factory.string,
|
142
|
+
:params => Factory.string,
|
143
|
+
:splat => Factory.string,
|
144
|
+
:route_path => Factory.string
|
145
|
+
})
|
132
146
|
assert_not_equal exp, subject
|
133
147
|
end
|
134
148
|
|