deas 0.37.0 → 0.37.1

Sign up to get free protection for your applications and to get access to all the features.
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