deas 0.42.0 → 0.43.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.
- 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
|
|