loggability 0.7.0 → 0.8.0.pre.65
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/Manifest.txt +5 -1
- data/README.rdoc +30 -0
- data/Rakefile +5 -3
- data/lib/loggability/logclient.rb +48 -0
- data/lib/loggability/logger.rb +26 -4
- data/lib/loggability/loghost.rb +40 -0
- data/lib/loggability/override.rb +171 -0
- data/lib/loggability.rb +49 -77
- data/spec/helpers.rb +116 -0
- data/spec/loggability/formatter/color_spec.rb +3 -6
- data/spec/loggability/formatter/html_spec.rb +3 -6
- data/spec/loggability/formatter_spec.rb +8 -11
- data/spec/loggability/logger_spec.rb +88 -32
- data/spec/loggability/override_spec.rb +134 -0
- data/spec/loggability_spec.rb +162 -57
- data.tar.gz.sig +2 -2
- metadata +23 -5
- metadata.gz.sig +3 -3
- data/spec/lib/helpers.rb +0 -40
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 080af7dac1d884020028cd90faa021b2162279ed
|
4
|
+
data.tar.gz: 5030296da798cc5802812a0b1a7fcee1223161b7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eed60ff758345f3996dd7ad517bbb4de4ea4d52ff8a4520eeaa380e01e1244df5cddf71784b76a5cf6dfc529a74a2a9c411823317b8cea28743f44020a6c4338
|
7
|
+
data.tar.gz: c65f9e7137429f584aad8cba285b437793df9461c977b36ab34c44e595b7306f9ef457c2db1347c080742c01add876c313476c66b58da6ede67916696b714072
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/Manifest.txt
CHANGED
@@ -9,11 +9,15 @@ lib/loggability/formatter.rb
|
|
9
9
|
lib/loggability/formatter/color.rb
|
10
10
|
lib/loggability/formatter/default.rb
|
11
11
|
lib/loggability/formatter/html.rb
|
12
|
+
lib/loggability/logclient.rb
|
12
13
|
lib/loggability/logger.rb
|
14
|
+
lib/loggability/loghost.rb
|
15
|
+
lib/loggability/override.rb
|
13
16
|
lib/loggability/spechelpers.rb
|
14
|
-
spec/
|
17
|
+
spec/helpers.rb
|
15
18
|
spec/loggability/formatter/color_spec.rb
|
16
19
|
spec/loggability/formatter/html_spec.rb
|
17
20
|
spec/loggability/formatter_spec.rb
|
18
21
|
spec/loggability/logger_spec.rb
|
22
|
+
spec/loggability/override_spec.rb
|
19
23
|
spec/loggability_spec.rb
|
data/README.rdoc
CHANGED
@@ -206,6 +206,36 @@ methods on Loggability::Logger:
|
|
206
206
|
Loggability.output_to( "/tmp/my_project_log.html" )
|
207
207
|
|
208
208
|
|
209
|
+
=== Temporarily Overriding Logging Behavior
|
210
|
+
|
211
|
+
Sometimes you want to log one particular chunk of code at a different
|
212
|
+
level, or to a different destination, and then restore everything back
|
213
|
+
to the way it was afterwards.
|
214
|
+
|
215
|
+
Loggability has a few ways of doing that:
|
216
|
+
|
217
|
+
# Log only fatal errors...
|
218
|
+
Loggability.with_level( :fatal ) do
|
219
|
+
...
|
220
|
+
end
|
221
|
+
|
222
|
+
# Log everything to an array for the block
|
223
|
+
logs = []
|
224
|
+
Loggability.outputting_to( logs ) do
|
225
|
+
...
|
226
|
+
end
|
227
|
+
|
228
|
+
# Log using the HTML formatter
|
229
|
+
Loggability.formatted_with( :html ) do
|
230
|
+
...
|
231
|
+
end
|
232
|
+
|
233
|
+
# Or chain them together:
|
234
|
+
Loggability.with_level( :debug ).outputting_to( $stderr ).formatted_with( :color ) do
|
235
|
+
Client.connect!
|
236
|
+
end
|
237
|
+
|
238
|
+
|
209
239
|
== Contributing
|
210
240
|
|
211
241
|
You can check out the current development source with
|
data/Rakefile
CHANGED
@@ -11,6 +11,7 @@ end
|
|
11
11
|
Hoe.plugin :mercurial
|
12
12
|
Hoe.plugin :signing
|
13
13
|
Hoe.plugin :deveiate
|
14
|
+
Hoe.plugin :bundler
|
14
15
|
|
15
16
|
Hoe.plugins.delete :rubyforge
|
16
17
|
|
@@ -22,11 +23,12 @@ hoespec = Hoe.spec 'loggability' do
|
|
22
23
|
self.developer 'Michael Granger', 'ged@FaerieMUD.org'
|
23
24
|
|
24
25
|
self.dependency 'hoe-deveiate', '~> 0.3', :developer
|
26
|
+
self.dependency 'hoe-bundler', '~> 1.2', :developer
|
25
27
|
self.dependency 'simplecov', '~> 0.7', :developer
|
26
28
|
self.dependency 'configurability', '~> 2.0', :developer
|
27
29
|
|
28
|
-
self.
|
29
|
-
self.require_ruby_version( '>=1.
|
30
|
+
self.license "Ruby"
|
31
|
+
self.require_ruby_version( '>=1.9.3' )
|
30
32
|
self.hg_sign_tags = true if self.respond_to?( :hg_sign_tags= )
|
31
33
|
self.check_history_on_release = true if self.respond_to?( :check_history_on_release= )
|
32
34
|
|
@@ -36,7 +38,7 @@ end
|
|
36
38
|
ENV['VERSION'] ||= hoespec.spec.version.to_s
|
37
39
|
|
38
40
|
# Ensure the specs pass before checking in
|
39
|
-
task 'hg:precheckin' => [ :check_history, :check_manifest, :spec ]
|
41
|
+
task 'hg:precheckin' => [ :check_history, 'bundler:gemfile', :check_manifest, :spec ]
|
40
42
|
|
41
43
|
|
42
44
|
desc "Build a coverage report"
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
#encoding: utf-8
|
3
|
+
|
4
|
+
require 'loggability' unless defined?( Loggability )
|
5
|
+
|
6
|
+
# Methods to install for objects which call +log_to+.
|
7
|
+
module Loggability::LogClient
|
8
|
+
|
9
|
+
##
|
10
|
+
# The key of the log host this client targets
|
11
|
+
attr_accessor :log_host_key
|
12
|
+
|
13
|
+
### Return the Loggability::Logger object associated with the log host the
|
14
|
+
### client is logging to.
|
15
|
+
### :TODO: Use delegation for efficiency.
|
16
|
+
def log
|
17
|
+
@__log ||= Loggability[ self ].proxy_for( self )
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
### Inheritance hook -- set the log host key of subclasses to the same
|
22
|
+
### thing as the extended class.
|
23
|
+
def inherited( subclass )
|
24
|
+
super
|
25
|
+
Loggability.log.debug "Setting up subclass %p of %p to log to %p" %
|
26
|
+
[ subclass, self, self.log_host_key ]
|
27
|
+
subclass.log_host_key = self.log_host_key
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
# Stuff that gets added to instances of Classes that are log hosts.
|
32
|
+
module InstanceMethods
|
33
|
+
|
34
|
+
### Fetch the key of the log host the instance of this client targets
|
35
|
+
def log_host_key
|
36
|
+
return self.class.log_host_key
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
### Delegate to the class's logger.
|
41
|
+
def log
|
42
|
+
@__log ||= Loggability[ self.class ].proxy_for( self )
|
43
|
+
end
|
44
|
+
|
45
|
+
end # module InstanceMethods
|
46
|
+
|
47
|
+
end # module Loggability::LogClient
|
48
|
+
|
data/lib/loggability/logger.rb
CHANGED
@@ -163,7 +163,7 @@ class Loggability::Logger < ::Logger
|
|
163
163
|
dev = if self.logdev.respond_to?( :dev )
|
164
164
|
self.logdev.dev.class
|
165
165
|
else
|
166
|
-
self.logdev
|
166
|
+
self.logdev
|
167
167
|
end
|
168
168
|
|
169
169
|
return "#<%p:%#x severity: %s, formatter: %s, outputting to: %p>" % [
|
@@ -185,6 +185,25 @@ class Loggability::Logger < ::Logger
|
|
185
185
|
end
|
186
186
|
|
187
187
|
|
188
|
+
### Return a Hash that contains its settings suitable for restoration via
|
189
|
+
### #restore_settings later.
|
190
|
+
def settings
|
191
|
+
return {
|
192
|
+
level: self.level,
|
193
|
+
logdev: self.logdev,
|
194
|
+
formatter: self.formatter,
|
195
|
+
}
|
196
|
+
end
|
197
|
+
|
198
|
+
|
199
|
+
### Restore the level, logdev, and formatter from the given +settings+.
|
200
|
+
def restore_settings( settings )
|
201
|
+
self.level = settings[:level] if settings[ :level ]
|
202
|
+
self.output_to( settings[:logdev] ) if settings[ :logdev ]
|
203
|
+
self.format_with( settings[:formatter] ) if settings[ :formatter ]
|
204
|
+
end
|
205
|
+
|
206
|
+
|
188
207
|
#
|
189
208
|
# :section: Severity Level
|
190
209
|
#
|
@@ -196,8 +215,8 @@ class Loggability::Logger < ::Logger
|
|
196
215
|
end
|
197
216
|
|
198
217
|
|
199
|
-
### Set the logger level to +newlevel+, which can be a numeric level (e.g.,
|
200
|
-
### or a symbolic level (e.g., :debug, :info, etc.)
|
218
|
+
### Set the logger level to +newlevel+, which can be a numeric level (e.g.,
|
219
|
+
### Logger::DEBUG, etc.), or a symbolic level (e.g., :debug, :info, etc.)
|
201
220
|
def level=( newlevel )
|
202
221
|
newlevel = LOG_LEVELS[ newlevel.to_sym ] if
|
203
222
|
newlevel.respond_to?( :to_sym ) && LOG_LEVELS.key?( newlevel.to_sym )
|
@@ -218,7 +237,10 @@ class Loggability::Logger < ::Logger
|
|
218
237
|
### logging to IO objects and files (given a filename in a String), this method can also
|
219
238
|
### set up logging to any object that responds to #<<.
|
220
239
|
def output_to( target, *args )
|
221
|
-
if target.
|
240
|
+
if target.is_a?( Logger::LogDevice ) ||
|
241
|
+
target.is_a?( Loggability::Logger::AppendingLogDevice )
|
242
|
+
self.logdev = target
|
243
|
+
elsif target.respond_to?( :write ) || target.is_a?( String )
|
222
244
|
opts = { :shift_age => args.shift || 0, :shift_size => args.shift || 1048576 }
|
223
245
|
self.logdev = Logger::LogDevice.new( target, opts )
|
224
246
|
elsif target.respond_to?( :<< )
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
#encoding: utf-8
|
3
|
+
|
4
|
+
require 'loggability' unless defined?( Loggability )
|
5
|
+
|
6
|
+
# Extension for 'log hosts'. A <b>log host</b> is an object that hosts a Loggability::Logger
|
7
|
+
# object, and is typically the top of some kind of hierarchy, like a namespace
|
8
|
+
# module for a project:
|
9
|
+
#
|
10
|
+
# module MyProject
|
11
|
+
#
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# This module isn't mean to be used directly -- it's installed via the Loggability#log_as
|
15
|
+
# declaration, which also does some other initialization that you'll likely want.
|
16
|
+
#
|
17
|
+
#
|
18
|
+
module Loggability::LogHost
|
19
|
+
|
20
|
+
# The logger that will be used when the logging subsystem is reset
|
21
|
+
attr_accessor :default_logger
|
22
|
+
|
23
|
+
# The logger that's currently in effect
|
24
|
+
attr_reader :logger
|
25
|
+
alias_method :log, :logger
|
26
|
+
|
27
|
+
# The key associated with the logger for this host
|
28
|
+
attr_accessor :log_host_key
|
29
|
+
|
30
|
+
|
31
|
+
### Set the logger associated with the LogHost to +newlogger+. If +newlogger+ isn't a
|
32
|
+
### Loggability::Logger, it will be converted to one.
|
33
|
+
def logger=( newlogger )
|
34
|
+
@logger = Loggability::Logger( newlogger )
|
35
|
+
end
|
36
|
+
alias_method :log=, :logger=
|
37
|
+
|
38
|
+
end # module Loggability::LogHost
|
39
|
+
|
40
|
+
|
@@ -0,0 +1,171 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
#encoding: utf-8
|
3
|
+
|
4
|
+
require 'monitor'
|
5
|
+
require 'loggability' unless defined?( Loggability )
|
6
|
+
|
7
|
+
|
8
|
+
# A class which encapsulates the logic and data of temporarily overriding one or
|
9
|
+
# more aspects of logging for the execution of one or more blocks of code.
|
10
|
+
#
|
11
|
+
# It's not meant to be used directly, but via one of the override aggregate methods
|
12
|
+
# on Loggability:
|
13
|
+
#
|
14
|
+
# * Loggability.with_level
|
15
|
+
# * Loggability.outputting_to
|
16
|
+
# * Loggability.formatted_with
|
17
|
+
#
|
18
|
+
class Loggability::Override
|
19
|
+
include MonitorMixin
|
20
|
+
|
21
|
+
|
22
|
+
### Return an Override with its logging level set to +newlevel+.
|
23
|
+
def self::with_level( new_level )
|
24
|
+
return self.new( level: new_level )
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
### Return an Override with its logging output set to +new_destination+.
|
29
|
+
def self::outputting_to( new_destination )
|
30
|
+
return self.new( logdev: new_destination )
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
### Return an Override with its logging formatter set to +formatter+.
|
35
|
+
def self::formatted_with( new_formatter )
|
36
|
+
return self.new( formatter: new_formatter )
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
### Create a new Override with the specified +settings+ that will be applied
|
41
|
+
### during a call to #call, and then reverted when #call returns. Valid +settings+
|
42
|
+
### are:
|
43
|
+
###
|
44
|
+
### [:level]
|
45
|
+
### Set the level of all Loggers to the value.
|
46
|
+
### [:logdev]
|
47
|
+
### Set the destination log device of all Loggers to the value.
|
48
|
+
### [:formatter]
|
49
|
+
### Set the formatter for all Loggers to the value (a Loggability::Formatter).
|
50
|
+
###
|
51
|
+
def initialize( settings={} )
|
52
|
+
super()
|
53
|
+
|
54
|
+
@settings = settings
|
55
|
+
@overridden_settings = {}
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
### Copy constructor -- make copies of the internal data structures
|
60
|
+
### when duplicated.
|
61
|
+
def initialize_copy( original )
|
62
|
+
@settings = original.settings.dup
|
63
|
+
@overridden_settings = {}
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
######
|
68
|
+
public
|
69
|
+
######
|
70
|
+
|
71
|
+
# The Override's settings Hash (the settings that will be applied during
|
72
|
+
# an overridden #call).
|
73
|
+
attr_reader :settings
|
74
|
+
|
75
|
+
# The original settings preserved by the Override during a call to #call,
|
76
|
+
# keyed by the logger they belong to.
|
77
|
+
attr_reader :overridden_settings
|
78
|
+
|
79
|
+
|
80
|
+
### Call the provided block with configured overrides applied, and then restore
|
81
|
+
### the previous settings before control is returned.
|
82
|
+
def call
|
83
|
+
self.apply_overrides
|
84
|
+
yield
|
85
|
+
ensure
|
86
|
+
self.restore_overridden_settings
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
#
|
91
|
+
# Mutator Methods
|
92
|
+
#
|
93
|
+
|
94
|
+
### Return a clone of the receiving Override with its logging level
|
95
|
+
### set to +newlevel+.
|
96
|
+
def with_level( new_level )
|
97
|
+
return self.clone_with( level: new_level )
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
### Return a clone of the receiving Override with its logging output
|
102
|
+
### set to +new_destination+.
|
103
|
+
def outputting_to( new_destination )
|
104
|
+
return self.clone_with( logdev: new_destination )
|
105
|
+
end
|
106
|
+
|
107
|
+
|
108
|
+
### Return a clone of the receiving Override with its logging formatter
|
109
|
+
### set to +formatter+.
|
110
|
+
def formatted_with( new_formatter )
|
111
|
+
return self.clone_with( formatter: new_formatter )
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
### Return the object as a human-readable string suitable for debugging.
|
116
|
+
def inspect
|
117
|
+
return "#<%p:%#016x formatter: %s, level: %s, output: %s>" % [
|
118
|
+
self.class,
|
119
|
+
self.object_id * 2,
|
120
|
+
self.settings[:formatter] || '-',
|
121
|
+
self.settings[:level] || '-',
|
122
|
+
self.settings[:logdev] ? self.settings[:logdev].class : '-',
|
123
|
+
]
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
#########
|
128
|
+
protected
|
129
|
+
#########
|
130
|
+
|
131
|
+
### Return a clone that has been modified with the specified +new_settings+.
|
132
|
+
def clone_with( new_settings )
|
133
|
+
newobj = self.dup
|
134
|
+
newobj.settings.merge!( new_settings )
|
135
|
+
|
136
|
+
return newobj
|
137
|
+
end
|
138
|
+
|
139
|
+
|
140
|
+
### Apply any configured overrides to all loggers.
|
141
|
+
def apply_overrides
|
142
|
+
self.synchronize do
|
143
|
+
raise LocalJumpError, "can't be called re-entrantly" unless
|
144
|
+
@overridden_settings.empty?
|
145
|
+
@overridden_settings = self.gather_current_settings
|
146
|
+
end
|
147
|
+
|
148
|
+
Loggability.log_hosts.each do |key, host|
|
149
|
+
host.logger.restore_settings( self.settings )
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
### Return a Hash of Loggers with the settings they currently have.
|
155
|
+
def gather_current_settings
|
156
|
+
return Loggability.log_hosts.values.each_with_object( {} ) do |host, hash|
|
157
|
+
hash[ host ] = host.logger.settings
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
|
162
|
+
### Restore the last settings saved by #apply_overrides to their corresponding
|
163
|
+
### loggers.
|
164
|
+
def restore_overridden_settings
|
165
|
+
@overridden_settings.each do |host, settings|
|
166
|
+
host.logger.restore_settings( settings )
|
167
|
+
end
|
168
|
+
@overridden_settings.clear
|
169
|
+
end
|
170
|
+
|
171
|
+
end # class Loggability::Override
|
data/lib/loggability.rb
CHANGED
@@ -9,10 +9,10 @@ require 'date'
|
|
9
9
|
module Loggability
|
10
10
|
|
11
11
|
# Package version constant
|
12
|
-
VERSION = '0.
|
12
|
+
VERSION = '0.8.0'
|
13
13
|
|
14
14
|
# VCS revision
|
15
|
-
REVISION = %q$Revision:
|
15
|
+
REVISION = %q$Revision: 44b025b728e6 $
|
16
16
|
|
17
17
|
# The key for the global logger (Loggability's own logger)
|
18
18
|
GLOBAL_KEY = :__global__
|
@@ -53,6 +53,12 @@ module Loggability
|
|
53
53
|
@log_hosts = {}
|
54
54
|
|
55
55
|
|
56
|
+
# Automatically log the log host and log client mixins when they're referenced
|
57
|
+
autoload :LogHost, 'loggability/loghost'
|
58
|
+
autoload :LogClient, 'loggability/logclient'
|
59
|
+
autoload :Override, 'loggability/override'
|
60
|
+
|
61
|
+
|
56
62
|
### Return the library's version string
|
57
63
|
def self::version_string( include_buildnum=false )
|
58
64
|
vstring = "%s %s" % [ self.name, VERSION ]
|
@@ -145,6 +151,21 @@ module Loggability
|
|
145
151
|
end
|
146
152
|
|
147
153
|
|
154
|
+
### Aggregate method: set the log level on all loggers to +level+ for the duration
|
155
|
+
### of the +block+, restoring the original levels afterward. If no block is given, returns a
|
156
|
+
### Loggability::Override object that set the log level to +level+ while its +#call+
|
157
|
+
### method is being called.
|
158
|
+
def self::with_level( level, &block )
|
159
|
+
override = Loggability::Override.with_level( level )
|
160
|
+
|
161
|
+
if block
|
162
|
+
return override.call( &block )
|
163
|
+
else
|
164
|
+
return override
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
|
148
169
|
##
|
149
170
|
# :method: output_to
|
150
171
|
# :call-seq:
|
@@ -161,6 +182,21 @@ module Loggability
|
|
161
182
|
end
|
162
183
|
|
163
184
|
|
185
|
+
### Aggregate method: set all loggers to log to +destination+ for the duration of the
|
186
|
+
### +block+, restoring the original destination afterward. If no block is given, returns a
|
187
|
+
### Loggability::Override object that will log to +destination+ whenever its +#call+ method is
|
188
|
+
### called.
|
189
|
+
def self::outputting_to( newdevice, &block )
|
190
|
+
override = Loggability::Override.outputting_to( newdevice )
|
191
|
+
|
192
|
+
if block
|
193
|
+
return override.call( &block )
|
194
|
+
else
|
195
|
+
return override
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
|
164
200
|
##
|
165
201
|
# :method: format_with
|
166
202
|
# :call-seq:
|
@@ -179,83 +215,19 @@ module Loggability
|
|
179
215
|
end
|
180
216
|
|
181
217
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
# end
|
189
|
-
#
|
190
|
-
# This module isn't mean to be used directly -- it's installed via the Loggability#log_as
|
191
|
-
# declaration, which also does some other initialization that you'll likely want.
|
192
|
-
#
|
193
|
-
#
|
194
|
-
module LogHost
|
195
|
-
|
196
|
-
# The logger that will be used when the logging subsystem is reset
|
197
|
-
attr_accessor :default_logger
|
198
|
-
|
199
|
-
# The logger that's currently in effect
|
200
|
-
attr_reader :logger
|
201
|
-
alias_method :log, :logger
|
202
|
-
|
203
|
-
# The key associated with the logger for this host
|
204
|
-
attr_accessor :log_host_key
|
218
|
+
### Aggregate method: set all loggers to log with the given +formatter+ for the duration
|
219
|
+
### of the +block+, restoring the original formatters afterward. If no block is given,
|
220
|
+
### returns a Loggability::Override object that will override all formatters whenever its
|
221
|
+
### +#call+ method is called.
|
222
|
+
def self::formatted_with( formatter, &block )
|
223
|
+
override = Loggability::Override.formatted_with( formatter )
|
205
224
|
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
@logger = Loggability::Logger( newlogger )
|
211
|
-
end
|
212
|
-
alias_method :log=, :logger=
|
213
|
-
|
214
|
-
end # module LogHost
|
215
|
-
|
216
|
-
|
217
|
-
# Methods to install for objects which call +log_to+.
|
218
|
-
module LogClient
|
219
|
-
|
220
|
-
##
|
221
|
-
# The key of the log host this client targets
|
222
|
-
attr_accessor :log_host_key
|
223
|
-
|
224
|
-
### Return the Loggability::Logger object associated with the log host the
|
225
|
-
### client is logging to.
|
226
|
-
### :TODO: Use delegation for efficiency.
|
227
|
-
def log
|
228
|
-
@__log ||= Loggability[ self ].proxy_for( self )
|
229
|
-
end
|
230
|
-
|
231
|
-
|
232
|
-
### Inheritance hook -- set the log host key of subclasses to the same
|
233
|
-
### thing as the extended class.
|
234
|
-
def inherited( subclass )
|
235
|
-
super
|
236
|
-
Loggability.log.debug "Setting up subclass %p of %p to log to %p" %
|
237
|
-
[ subclass, self, self.log_host_key ]
|
238
|
-
subclass.log_host_key = self.log_host_key
|
225
|
+
if block
|
226
|
+
return override.call( &block )
|
227
|
+
else
|
228
|
+
return override
|
239
229
|
end
|
240
|
-
|
241
|
-
|
242
|
-
# Stuff that gets added to instances of Classes that are log hosts.
|
243
|
-
module InstanceMethods
|
244
|
-
|
245
|
-
### Fetch the key of the log host the instance of this client targets
|
246
|
-
def log_host_key
|
247
|
-
return self.class.log_host_key
|
248
|
-
end
|
249
|
-
|
250
|
-
|
251
|
-
### Delegate to the class's logger.
|
252
|
-
def log
|
253
|
-
@__log ||= Loggability[ self.class ].proxy_for( self )
|
254
|
-
end
|
255
|
-
|
256
|
-
end # module InstanceMethods
|
257
|
-
|
258
|
-
end # module LogClient
|
230
|
+
end
|
259
231
|
|
260
232
|
|
261
233
|
#
|
data/spec/helpers.rb
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# vim: set nosta noet ts=4 sw=4:
|
3
|
+
# encoding: utf-8
|
4
|
+
|
5
|
+
BEGIN {
|
6
|
+
require 'pathname'
|
7
|
+
basedir = Pathname.new( __FILE__ ).dirname.parent
|
8
|
+
|
9
|
+
libdir = basedir + "lib"
|
10
|
+
|
11
|
+
$LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
|
12
|
+
}
|
13
|
+
|
14
|
+
# SimpleCov test coverage reporting; enable this using the :coverage rake task
|
15
|
+
if ENV['COVERAGE']
|
16
|
+
$stderr.puts "\n\n>>> Enabling coverage report.\n\n"
|
17
|
+
require 'simplecov'
|
18
|
+
SimpleCov.start do
|
19
|
+
add_filter 'spec'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
begin
|
24
|
+
require 'configurability'
|
25
|
+
rescue LoadError
|
26
|
+
end
|
27
|
+
|
28
|
+
require 'loggability'
|
29
|
+
require 'loggability/spechelpers'
|
30
|
+
|
31
|
+
|
32
|
+
# Helpers specific to Loggability specs
|
33
|
+
module SpecHelpers
|
34
|
+
|
35
|
+
### An object identity matcher for collections.
|
36
|
+
class AllBeMatcher
|
37
|
+
|
38
|
+
def initialize( expected )
|
39
|
+
@expected = expected
|
40
|
+
end
|
41
|
+
|
42
|
+
def matches?( collection )
|
43
|
+
@collection = collection
|
44
|
+
return collection.all? {|obj| obj.equal?(@expected) }
|
45
|
+
end
|
46
|
+
|
47
|
+
def description
|
48
|
+
"to all be %p" % [ @expected ]
|
49
|
+
end
|
50
|
+
|
51
|
+
def failure_message
|
52
|
+
"but they were: %p" % [ @collection ]
|
53
|
+
end
|
54
|
+
|
55
|
+
end # class AllBeMatcher
|
56
|
+
|
57
|
+
|
58
|
+
### An object kind matcher for collections
|
59
|
+
class AllBeAMatcher
|
60
|
+
|
61
|
+
def initialize( expected_class )
|
62
|
+
@expected_class = expected_class
|
63
|
+
end
|
64
|
+
|
65
|
+
def matches?( collection )
|
66
|
+
@collection = collection
|
67
|
+
return collection.all? {|obj| obj.is_a?(@expected_class) }
|
68
|
+
end
|
69
|
+
|
70
|
+
def description
|
71
|
+
"to all be a %p" % [ @expected_class ]
|
72
|
+
end
|
73
|
+
|
74
|
+
def failure_message
|
75
|
+
unmatched = @collection.find {|obj| !obj.is_a?(@expected_class) }
|
76
|
+
"but (at least) one was not. It was a %p (%s)" % [
|
77
|
+
unmatched.class,
|
78
|
+
unmatched.class.ancestors.map(&:inspect).join(' < '),
|
79
|
+
]
|
80
|
+
end
|
81
|
+
|
82
|
+
end # class AllBeAMatcher
|
83
|
+
|
84
|
+
|
85
|
+
###############
|
86
|
+
module_function
|
87
|
+
###############
|
88
|
+
|
89
|
+
### Return true if the actual value includes the specified +objects+.
|
90
|
+
def all_be( expected_object )
|
91
|
+
AllBeMatcher.new( expected_object )
|
92
|
+
end
|
93
|
+
|
94
|
+
### Returns +true+ if every object in the collection inherits from the +expected_class+.
|
95
|
+
def all_be_a( expected_class )
|
96
|
+
AllBeAMatcher.new( expected_class )
|
97
|
+
end
|
98
|
+
|
99
|
+
end # module SpecHelpers
|
100
|
+
|
101
|
+
|
102
|
+
### Mock with RSpec
|
103
|
+
RSpec.configure do |c|
|
104
|
+
c.treat_symbols_as_metadata_keys_with_true_values = true
|
105
|
+
c.run_all_when_everything_filtered = true
|
106
|
+
c.filter_run :focus
|
107
|
+
c.order = 'random'
|
108
|
+
c.mock_with( :rspec ) do |mock|
|
109
|
+
mock.syntax = :expect
|
110
|
+
end
|
111
|
+
|
112
|
+
c.include( SpecHelpers )
|
113
|
+
c.include( Loggability::SpecHelpers )
|
114
|
+
c.filter_run_excluding( :configurability ) unless defined?( Configurability )
|
115
|
+
end
|
116
|
+
|