loggability 0.7.0 → 0.8.0.pre.65
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 +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
|
+
|