deas 0.37.0 → 0.37.1

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.
data/lib/deas/logging.rb CHANGED
@@ -41,7 +41,7 @@ module Deas
41
41
  log_error(env['sinatra.error'])
42
42
  env['deas.time_taken'] = RoundedTime.new(benchmark.real)
43
43
 
44
- [ status, headers, body ]
44
+ [status, headers, body]
45
45
  end
46
46
 
47
47
  def log(message)
@@ -81,11 +81,11 @@ module Deas
81
81
  status, headers, body = super(env)
82
82
  log " Redir: #{headers['Location']}" if headers.key?('Location')
83
83
  log "===== Completed in #{env['deas.time_taken']}ms (#{response_display(status)}) ====="
84
- [ status, headers, body ]
84
+ [status, headers, body]
85
85
  end
86
86
 
87
87
  def response_display(status)
88
- [ status, RESPONSE_STATUS_NAMES[status.to_i] ].compact.join(', ')
88
+ [status, RESPONSE_STATUS_NAMES[status.to_i]].compact.join(', ')
89
89
  end
90
90
 
91
91
  end
@@ -101,16 +101,18 @@ module Deas
101
101
  line_attrs = {
102
102
  'method' => request.request_method,
103
103
  'path' => request.path,
104
- 'handler' => env['deas.handler_class'].name,
105
104
  'params' => env['deas.params'],
106
105
  'time' => env['deas.time_taken'],
107
106
  'status' => status
108
107
  }
108
+ if env['deas.handler_class']
109
+ line_attrs['handler'] = env['deas.handler_class'].name
110
+ end
109
111
  if headers.key?('Location')
110
112
  line_attrs['redir'] = headers['Location']
111
113
  end
112
114
  log SummaryLine.new(line_attrs)
113
- [ status, headers, body ]
115
+ [status, headers, body]
114
116
  end
115
117
 
116
118
  end
@@ -27,24 +27,19 @@ module Deas
27
27
  error_body = Body.new(error)
28
28
 
29
29
  headers['Content-Length'] = error_body.size.to_s
30
- headers['Content-Type'] = error_body.mime_type.to_s
30
+ headers['Content-Type'] = error_body.mime_type.to_s
31
31
  body = [error_body.content]
32
32
  end
33
- [ status, headers, body ]
33
+ [status, headers, body]
34
34
  end
35
35
 
36
36
  class Body
37
- attr_reader :content
38
- def initialize(e)
39
- @content ||= "#{e.class}: #{e.message}\n#{(e.backtrace || []).join("\n")}"
40
- end
37
+ attr_reader :content, :size, :mime_type
41
38
 
42
- def size
43
- @size ||= Rack::Utils.bytesize(self.content)
44
- end
45
-
46
- def mime_type
47
- @mime_type ||= "text/plain"
39
+ def initialize(e)
40
+ @content = "#{e.class}: #{e.message}\n#{e.backtrace.join("\n")}"
41
+ @size = Rack::Utils.bytesize(@content)
42
+ @mime_type = "text/plain"
48
43
  end
49
44
  end
50
45
 
data/lib/deas/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Deas
2
- VERSION = "0.37.0"
2
+ VERSION = "0.37.1"
3
3
  end
@@ -10,7 +10,7 @@ class FakeSinatraCall
10
10
 
11
11
  def initialize(settings = nil)
12
12
  @request = FakeRequest.new('GET','/something', {}, OpenStruct.new)
13
- @response = FakeResponse.new
13
+ @response = FakeResponse.new(Factory.integer, {}, [Factory.text])
14
14
  @session = @request.session
15
15
  @params = @request.params
16
16
  @logger = Deas::NullLogger.new
@@ -26,6 +26,10 @@ class FakeSinatraCall
26
26
  }.merge(settings || {}))
27
27
  end
28
28
 
29
+ def call(env)
30
+ [@response.status, @response.headers, [@response.body]]
31
+ end
32
+
29
33
  def halt(*args)
30
34
  throw :halt, args
31
35
  end
@@ -6,7 +6,7 @@ class DeasTestServer
6
6
  root TEST_SUPPORT_ROOT
7
7
 
8
8
  logger TEST_LOGGER
9
- verbose_logging true
9
+ verbose_logging Factory.boolean
10
10
 
11
11
  set :a_setting, 'something'
12
12
 
@@ -5,41 +5,277 @@ module Deas::Logging
5
5
 
6
6
  class UnitTests < Assert::Context
7
7
  desc "Deas::Logging"
8
- setup do
9
- @app = Factory.sinatra_call
10
- end
11
8
  subject{ Deas::Logging }
12
9
 
13
10
  should have_imeths :middleware
14
11
 
12
+ should "return a middleware class given a verbose flag" do
13
+ assert_equal Deas::VerboseLogging, subject.middleware(true)
14
+ assert_equal Deas::SummaryLogging, subject.middleware(false)
15
+ end
16
+
17
+ end
18
+
19
+ class CallSetupTests < UnitTests
20
+ setup do
21
+ @logger = SpyLogger.new
22
+ @app = Factory.sinatra_call({
23
+ :deas_server_data => Factory.server_data(:logger => @logger)
24
+ })
25
+
26
+ @app_call_env = nil
27
+ @resp_status = Factory.integer
28
+ @resp_headers = { 'Location' => Factory.path }
29
+ @app_response = [@resp_status, @resp_headers, [Factory.text]]
30
+ Assert.stub(@app, :call) do |env|
31
+ # dup so we can see what keys were added before supering
32
+ @app_call_env = env.dup
33
+ @app_response
34
+ end
35
+
36
+ @env = {
37
+ 'REQUEST_METHOD' => Factory.string(3).upcase,
38
+ 'PATH_INFO' => Factory.path,
39
+ 'rack.run_once' => true
40
+ }
41
+ end
42
+ subject{ @middleware_class }
43
+
44
+ end
45
+
46
+ class BaseLoggingTests < CallSetupTests
47
+ desc "Deas::BaseLogging"
48
+ setup do
49
+ @middleware_class = Deas::BaseLogging
50
+ end
51
+
15
52
  end
16
53
 
17
- class VerboseLoggingTests < UnitTests
54
+ class BaseLoggingInitTests < BaseLoggingTests
55
+ desc "when init"
56
+ setup do
57
+ @benchmark = Benchmark.measure{}
58
+ Assert.stub(Benchmark, :measure) do |&block|
59
+ block.call
60
+ @benchmark
61
+ end
62
+
63
+ @middleware = @middleware_class.new(@app)
64
+ end
65
+ subject{ @middleware }
66
+
67
+ should have_imeths :call, :call!
68
+
69
+ should "call the app and return its response when called" do
70
+ response = subject.call(@env)
71
+ assert_not_nil @app_call_env
72
+ assert_equal @app_response, response
73
+ end
74
+
75
+ should "set the rack.logger env key before its app is called" do
76
+ subject.call(@env)
77
+ assert_equal @logger, @env['rack.logger']
78
+ assert_same @env['rack.logger'], @app_call_env['rack.logger']
79
+ end
80
+
81
+ should "benchmark calling its app and set the deas.time_taken env key" do
82
+ assert_nil @env['deas.time_taken']
83
+ subject.call(@env)
84
+ exp = Deas::RoundedTime.new(@benchmark.real)
85
+ assert_equal exp, @env['deas.time_taken']
86
+ end
87
+
88
+ should "log a sinatra.error env key if it exists" do
89
+ @env.delete('sinatra.error')
90
+ subject.call(@env)
91
+ assert_empty @logger.info_logged
92
+
93
+ @env['sinatra.error'] = Factory.exception(Sinatra::NotFound)
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")}"
100
+ assert_includes exp, @logger.info_logged
101
+ end
102
+
103
+ end
104
+
105
+ class VerboseLoggingTests < CallSetupTests
18
106
  desc "Deas::VerboseLogging"
19
107
  setup do
108
+ @middleware_class = Deas::VerboseLogging
109
+ end
110
+
111
+ should "be a base logging middleware" do
112
+ assert subject < Deas::BaseLogging
113
+ end
114
+
115
+ should "know its response status names" do
116
+ exp = {
117
+ 200 => 'OK',
118
+ 302 => 'FOUND',
119
+ 400 => 'BAD REQUEST',
120
+ 401 => 'UNAUTHORIZED',
121
+ 403 => 'FORBIDDEN',
122
+ 404 => 'NOT FOUND',
123
+ 408 => 'TIMEOUT',
124
+ 500 => 'ERROR'
125
+ }
126
+ assert_equal exp, @middleware_class::RESPONSE_STATUS_NAMES
127
+ end
128
+
129
+ end
130
+
131
+ class VerboseLoggingInitTests < VerboseLoggingTests
132
+ desc "when init"
133
+ setup do
134
+ @resp_status = @middleware_class::RESPONSE_STATUS_NAMES.keys.choice
135
+ @app_response[0] = @resp_status
136
+
20
137
  @middleware = Deas::VerboseLogging.new(@app)
21
138
  end
22
139
  subject{ @middleware }
23
140
 
24
- should have_imeths :call, :call!
141
+ should have_imeths :call!
142
+
143
+ should "call the app and return its response when called" do
144
+ response = subject.call(@env)
145
+ assert_not_nil @app_call_env
146
+ assert_equal @app_response, response
147
+ end
148
+
149
+ should "set the deas.logging env key before calling its app" do
150
+ assert_nil @env['deas.logging']
151
+ subject.call(@env)
152
+ assert_instance_of Proc, @env['deas.logging']
153
+
154
+ message = Factory.text
155
+ @env['deas.logging'].call(message)
156
+ assert_includes "[Deas] #{message}", @logger.info_logged
157
+
158
+ assert_same @env['deas.logging'], @app_call_env['deas.logging']
159
+ end
25
160
 
26
- should "be a kind of Deas::BaseLogging middleware" do
27
- assert_kind_of Deas::BaseLogging, subject
161
+ should "log the request when called" do
162
+ assert_empty @logger.info_logged
163
+ subject.call(@env)
164
+ status = "#{@resp_status}, " \
165
+ "#{@middleware_class::RESPONSE_STATUS_NAMES[@resp_status]}"
166
+ exp = [
167
+ "[Deas] ===== Received request =====",
168
+ "[Deas] Method: #{@env['REQUEST_METHOD'].inspect}",
169
+ "[Deas] Path: #{@env['PATH_INFO'].inspect}",
170
+ "[Deas] Redir: #{@resp_headers['Location']}",
171
+ "[Deas] ===== Completed in #{@env['deas.time_taken']}ms (#{status}) ====="
172
+ ]
173
+ assert_equal exp, @logger.info_logged
174
+ end
175
+
176
+ should "not log a redir line if it doesn't have a Location header" do
177
+ @resp_headers.delete('Location')
178
+ subject.call(@env)
179
+
180
+ exp = "[Deas] Redir: #{@resp_headers['Location']}"
181
+ assert_not_includes exp, @logger.info_logged
182
+ end
183
+
184
+ should "not log a status name for unknown statuses" do
185
+ @resp_status = Factory.integer
186
+ @app_response[0] = @resp_status
187
+ subject.call(@env)
188
+
189
+ exp = "[Deas] ===== Completed in #{@env['deas.time_taken']}ms (#{@resp_status}) ====="
190
+ assert_includes exp, @logger.info_logged
28
191
  end
29
192
 
30
193
  end
31
194
 
32
- class SummaryLoggingTests < UnitTests
195
+ class SummaryLoggingTests < CallSetupTests
33
196
  desc "Deas::SummaryLogging"
34
197
  setup do
198
+ @middleware_class = Deas::SummaryLogging
199
+ end
200
+
201
+ should "be a base logging middleware" do
202
+ assert subject < Deas::BaseLogging
203
+ end
204
+
205
+ end
206
+
207
+ class SummaryLoggingInitTests < SummaryLoggingTests
208
+ desc "when init"
209
+ setup do
210
+ @params = { Factory.string => Factory.string }
211
+ @handler_class = TestHandler
212
+ @env.merge!({
213
+ 'deas.params' => @params,
214
+ 'deas.handler_class' => @handler_class
215
+ })
216
+
35
217
  @middleware = Deas::SummaryLogging.new(@app)
36
218
  end
37
219
  subject{ @middleware }
38
220
 
39
- should have_imeths :call, :call!
221
+ should "call the app and return its response when called" do
222
+ response = subject.call(@env)
223
+ assert_not_nil @app_call_env
224
+ assert_equal @app_response, response
225
+ end
40
226
 
41
- should "be a kind of Deas::BaseLogging middleware" do
42
- assert_kind_of Deas::BaseLogging, subject
227
+ should "set the deas.logging env key before calling its app" do
228
+ assert_nil @env['deas.logging']
229
+ subject.call(@env)
230
+ assert_instance_of Proc, @env['deas.logging']
231
+ assert_nil @env['deas.logging'].call(Factory.text)
232
+ assert_same @env['deas.logging'], @app_call_env['deas.logging']
233
+ end
234
+
235
+ should "log the request when called" do
236
+ assert_empty @logger.info_logged
237
+ subject.call(@env)
238
+
239
+ summary_line = Deas::SummaryLine.new({
240
+ 'method' => @env['REQUEST_METHOD'],
241
+ 'path' => @env['PATH_INFO'],
242
+ 'params' => @env['deas.params'],
243
+ 'time' => @env['deas.time_taken'],
244
+ 'status' => @resp_status,
245
+ 'handler' => @handler_class.name,
246
+ 'redir' => @resp_headers['Location']
247
+ })
248
+ assert_includes "[Deas] #{summary_line}", @logger.info_logged
249
+ end
250
+
251
+ should "not log a handler when it doesn't have a handler class" do
252
+ @env.delete('deas.handler_class')
253
+ subject.call(@env)
254
+
255
+ summary_line = Deas::SummaryLine.new({
256
+ 'method' => @env['REQUEST_METHOD'],
257
+ 'path' => @env['PATH_INFO'],
258
+ 'params' => @env['deas.params'],
259
+ 'time' => @env['deas.time_taken'],
260
+ 'status' => @resp_status,
261
+ 'redir' => @resp_headers['Location']
262
+ })
263
+ assert_includes "[Deas] #{summary_line}", @logger.info_logged
264
+ end
265
+
266
+ should "not log a redir if it doesn't have a Location header" do
267
+ @resp_headers.delete('Location')
268
+ subject.call(@env)
269
+
270
+ summary_line = Deas::SummaryLine.new({
271
+ 'method' => @env['REQUEST_METHOD'],
272
+ 'path' => @env['PATH_INFO'],
273
+ 'params' => @env['deas.params'],
274
+ 'time' => @env['deas.time_taken'],
275
+ 'status' => @resp_status,
276
+ 'handler' => @handler_class.name,
277
+ })
278
+ assert_includes "[Deas] #{summary_line}", @logger.info_logged
43
279
  end
44
280
 
45
281
  end
@@ -88,4 +324,16 @@ module Deas::Logging
88
324
 
89
325
  end
90
326
 
327
+ TestHandler = Class.new
328
+
329
+ class SpyLogger
330
+ attr_reader :info_logged
331
+
332
+ def initialize
333
+ @info_logged = []
334
+ end
335
+
336
+ def info(message); @info_logged << message; end
337
+ end
338
+
91
339
  end
@@ -8,27 +8,60 @@ class Deas::ShowExceptions
8
8
  class UnitTests < Assert::Context
9
9
  desc "Deas::ShowExceptions"
10
10
  setup do
11
- exception = Sinatra::NotFound.new
12
- @app = proc do |env|
13
- env['sinatra.error'] = exception
14
- [ 404, {}, [] ]
15
- end
16
- @exception = exception
17
- @show_exceptions = Deas::ShowExceptions.new(@app)
11
+ @middleware_class = Deas::ShowExceptions
18
12
  end
19
- subject{ @show_exceptions }
13
+ subject{ @middleware_class }
14
+
15
+ end
16
+
17
+ class InitTests < UnitTests
18
+ desc "when init"
19
+ setup do
20
+ @app = Factory.sinatra_call
21
+ @env = { 'sinatra.error' => Factory.exception }
22
+ @middleware = @middleware_class.new(@app)
23
+ end
24
+ subject{ @middleware }
20
25
 
21
26
  should have_imeths :call, :call!
22
27
 
23
- should "return a body that contains details about the exception" do
24
- status, headers, body = subject.call({})
25
- expected_body = "#{@exception.class}: #{@exception.message}\n" \
26
- "#{(@exception.backtrace || []).join("\n")}"
27
- expected_body_size = Rack::Utils.bytesize(expected_body).to_s
28
+ should "return a response for the exception when called" do
29
+ status, headers, body = subject.call(@env)
30
+ error_body = Body.new(@env['sinatra.error'])
31
+
32
+ assert_equal @app.response.status, status
33
+ assert_equal error_body.size.to_s, headers['Content-Length']
34
+ assert_equal error_body.mime_type, headers['Content-Type']
35
+ assert_equal [error_body.content], body
36
+ end
37
+
38
+ should "return the apps response if there isn't an exception" do
39
+ @env.delete('sinatra.error')
40
+ status, headers, body = subject.call(@env)
41
+
42
+ assert_equal @app.response.status, status
43
+ assert_equal @app.response.headers, headers
44
+ assert_equal [@app.response.body], body
45
+ end
46
+
47
+ end
48
+
49
+ class BodyTests < UnitTests
50
+ desc "Body"
51
+ setup do
52
+ @exception = Factory.exception
53
+ @body = Body.new(@exception)
54
+ end
55
+ subject{ @body }
56
+
57
+ should have_readers :content, :size, :mime_type
28
58
 
29
- assert_equal expected_body_size, headers['Content-Length']
30
- assert_equal "text/plain", headers['Content-Type']
31
- assert_equal [expected_body], body
59
+ should "know its attributes" do
60
+ exp_content = "#{@exception.class}: #{@exception.message}\n" \
61
+ "#{@exception.backtrace.join("\n")}"
62
+ assert_equal exp_content, subject.content
63
+ assert_equal Rack::Utils.bytesize(exp_content), subject.size
64
+ assert_equal "text/plain", subject.mime_type
32
65
  end
33
66
 
34
67
  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: 139
4
+ hash: 137
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 37
9
- - 0
10
- version: 0.37.0
9
+ - 1
10
+ version: 0.37.1
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-09-14 00:00:00 Z
19
+ date: 2015-10-07 00:00:00 Z
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  requirement: &id001 !ruby/object:Gem::Requirement
@@ -206,7 +206,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
206
206
  requirements: []
207
207
 
208
208
  rubyforge_project:
209
- rubygems_version: 1.8.29
209
+ rubygems_version: 1.8.25
210
210
  signing_key:
211
211
  specification_version: 3
212
212
  summary: Handler-based web framework powered by Sinatra