logue 1.0.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.
data/README.md ADDED
@@ -0,0 +1,31 @@
1
+ logue
2
+ =====
3
+
4
+ A Ruby gem for generating logging and debugging output. Logging statements
5
+ include the file, line, class and method from which the logging method was
6
+ called.
7
+
8
+ ## EXAMPLES
9
+
10
+ ```
11
+ require 'logue/log'
12
+ require 'logue/loggable'
13
+
14
+ Logue::Log.level = Logue::Log::DEBUG
15
+
16
+ class MyClass
17
+ include Logue::Loggable
18
+
19
+ def mymethod foo
20
+ info "foo: #{foo}"
21
+ end
22
+ end
23
+
24
+ MyClass.new.mymethod "bar"
25
+ ```
26
+
27
+ Produces:
28
+
29
+ ```
30
+ [/tmp/foo.rb : 13] {MyClass#mymethod } foo: bar
31
+ ```
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ module Logue
5
+ class Format
6
+
7
+ def trim_left str, maxlen
8
+ str[0 ... maxlen.to_i.abs]
9
+ end
10
+
11
+ def trim_right str, maxlen
12
+ mxln = maxlen.abs
13
+
14
+ # magic number 3 for the ellipses ...
15
+
16
+ if str.length > mxln
17
+ path = str.split('/')
18
+ newstr = "..."
19
+ path.reverse.each do |element|
20
+ if newstr.length + element.length > mxln
21
+ while newstr.length < mxln
22
+ newstr.insert 0, " "
23
+ end
24
+ return newstr
25
+ else
26
+ if newstr.length > 3
27
+ newstr.insert 3, "/"
28
+ end
29
+ newstr.insert 3, element
30
+ end
31
+ end
32
+ newstr
33
+ else
34
+ str
35
+ end
36
+ end
37
+
38
+ def print_formatted file, line, func, msg, lvl, &blk
39
+ if trim
40
+ file = trim_right file, @file_width
41
+ line = trim_left line, @line_width
42
+ func = trim_left func, @function_width
43
+ end
44
+
45
+ hdr = sprintf @format, file, line, func
46
+ print hdr, msg, lvl, &blk
47
+ end
48
+ end
49
+ end
data/lib/logue/log.rb ADDED
@@ -0,0 +1,244 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+ #
4
+ # = log.rb
5
+ #
6
+ # Logging Module
7
+ #
8
+ # Author:: Jeff Pace <jpace@incava.org>
9
+ # Documentation:: Author
10
+ #
11
+
12
+ require 'logue/logger'
13
+ require 'logue/severity'
14
+ require 'rubygems'
15
+ require 'rainbow'
16
+
17
+ #
18
+ # == Log
19
+ #
20
+ # Very minimal logging output. If verbose is set, this displays the method and
21
+ # line number whence called. It can be a mixin to a class, which displays the
22
+ # class and method from where it called. If not in a class, it displays only the
23
+ # method.
24
+ #
25
+ # Remember: all kids love log.
26
+ #
27
+ # == Examples
28
+ #
29
+ # See the unit tests in log_test.rb
30
+ #
31
+ # == Usage
32
+ #
33
+ # The most general usage is simply to call:
34
+ #
35
+ # Log.log "some message"
36
+ #
37
+ # That will simply log the given message.
38
+ #
39
+ # class YourClass
40
+ # include Loggable
41
+ #
42
+ # def some_method(...)
43
+ # log "my message"
44
+ #
45
+ # That will log from the given class and method, showing the line number from
46
+ # which the logger was called.
47
+ #
48
+ # def another_method(...)
49
+ # stack "my message"
50
+ #
51
+ # That will produce a stack trace from the given location.
52
+ #
53
+
54
+ module Logue
55
+ class Log
56
+ $LOGGING_LEVEL = nil
57
+
58
+ DEFAULT_FILENAME_WIDTH = -25
59
+ DEFAULT_LINENUM_WIDTH = 4
60
+ DEFAULT_FUNCTION_WIDTH = -20
61
+
62
+ include Log::Severity
63
+
64
+ # by default, class methods delegate to a single app-wide log.
65
+
66
+ @@log = Logger.new
67
+
68
+ # Returns the logger of the log. A class method delegating to an instance
69
+ # method ... not so good. But temporary.
70
+ def self.logger
71
+ @@log
72
+ end
73
+
74
+ def self.method_missing meth, *args, &blk
75
+ validcolors = Sickill::Rainbow::TERM_COLORS
76
+ # only handling foregrounds, not backgrounds
77
+ if code = validcolors[meth]
78
+ add_color_method meth.to_s, code + 30
79
+ send meth, *args, &blk
80
+ else
81
+ super
82
+ end
83
+ end
84
+
85
+ def self.respond_to? meth
86
+ validcolors = Sickill::Rainbow::TERM_COLORS
87
+ validcolors.include?(meth) || super
88
+ end
89
+
90
+ def self.add_color_method color, code
91
+ instmeth = Array.new
92
+ instmeth << "def #{color} msg = \"\", lvl = Log::DEBUG, depth = 1, cname = nil, &blk"
93
+ instmeth << " log(\"\\e[#{code}m\#{msg\}\\e[0m\", lvl, depth + 1, cname, &blk)"
94
+ instmeth << "end"
95
+ instance_eval instmeth.join("\n")
96
+
97
+ clsmeth = Array.new
98
+ clsmeth << "def #{color} msg = \"\", lvl = Log::DEBUG, depth = 1, cname = nil, &blk"
99
+ clsmeth << " logger.#{color}(\"\\e[#{code}m\#{msg\}\\e[0m\", lvl, depth + 1, cname, &blk)"
100
+ clsmeth << "end"
101
+
102
+ class_eval clsmeth.join("\n")
103
+ end
104
+
105
+ def self.set_default_widths
106
+ logger.set_default_widths
107
+ end
108
+
109
+ def self.verbose
110
+ logger.verbose
111
+ end
112
+
113
+ def self.verbose= v
114
+ logger.verbose = v && v != 0 ? DEBUG : FATAL
115
+ end
116
+
117
+ def self.level= lvl
118
+ logger.level = lvl
119
+ end
120
+
121
+ def self.quiet
122
+ logger.quiet
123
+ end
124
+
125
+ def self.quiet= q
126
+ logger.quiet = q
127
+ end
128
+
129
+ def self.format
130
+ logger.format
131
+ end
132
+
133
+ def self.format= fmt
134
+ logger.format = fmt
135
+ end
136
+
137
+ # Assigns output to the given stream.
138
+ def self.output= io
139
+ logger.output = io
140
+ end
141
+
142
+ def self.output
143
+ logger.output
144
+ end
145
+
146
+ # sets whether to colorize the entire line, or just the message.
147
+ def self.colorize_line= col
148
+ logger.colorize_line = col
149
+ end
150
+
151
+ def self.colorize_line
152
+ logger.colorize_line
153
+ end
154
+
155
+ # Assigns output to a file with the given name. Returns the file; client
156
+ # is responsible for closing it.
157
+ def self.outfile= fname
158
+ logger.outfile = fname
159
+ end
160
+
161
+ def self.outfile
162
+ logger.outfile
163
+ end
164
+
165
+ # Creates a printf format for the given widths, for aligning output.
166
+ def self.set_widths file_width, line_width, func_width
167
+ logger.set_widths file_width, line_width, func_width
168
+ end
169
+
170
+ def self.ignore_file fname
171
+ logger.ignore_file fname
172
+ end
173
+
174
+ def self.ignore_method methname
175
+ logger.ignored_method methname
176
+ end
177
+
178
+ def self.ignore_class classname
179
+ logger.ignored_class classname
180
+ end
181
+
182
+ def self.log_file fname
183
+ logger.log_file fname
184
+ end
185
+
186
+ def self.log_method methname
187
+ logger.log_method methname
188
+ end
189
+
190
+ def self.log_class classname
191
+ logger.log_class classname
192
+ end
193
+
194
+ def self.debug msg = "", depth = 1, &blk
195
+ logger.log msg, DEBUG, depth + 1, &blk
196
+ end
197
+
198
+ def self.info msg = "", depth = 1, &blk
199
+ logger.log msg, INFO, depth + 1, &blk
200
+ end
201
+
202
+ def self.fatal msg = "", depth = 1, &blk
203
+ logger.log msg, FATAL, depth + 1, &blk
204
+ end
205
+
206
+ def self.log msg = "", lvl = DEBUG, depth = 1, cname = nil, &blk
207
+ logger.log msg, lvl, depth + 1, cname, &blk
208
+ end
209
+
210
+ def self.stack msg = "", lvl = DEBUG, depth = 1, cname = nil, &blk
211
+ logger.stack msg, lvl, depth + 1, cname, &blk
212
+ end
213
+
214
+ def self.warn msg = "", depth = 1, &blk
215
+ if verbose
216
+ logger.log msg, WARN, depth + 1, &blk
217
+ else
218
+ $stderr.puts "WARNING: " + msg
219
+ end
220
+ end
221
+
222
+ def self.error msg = "", depth = 1, &blk
223
+ if verbose
224
+ logger.log msg, ERROR, depth + 1, &blk
225
+ else
226
+ $stderr.puts "ERROR: " + msg
227
+ end
228
+ end
229
+
230
+ def self.write msg, depth = 1, cname = nil, &blk
231
+ if verbose
232
+ stack msg, Log::WARN, depth + 1, cname, &blk
233
+ elsif quiet
234
+ # nothing
235
+ else
236
+ $stderr.puts msg
237
+ end
238
+ end
239
+
240
+ def self.set_color lvl, color
241
+ logger.set_color lvl, color
242
+ end
243
+ end
244
+ end
@@ -0,0 +1,101 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+ #
4
+ # = log.rb
5
+ #
6
+ # Logging Module
7
+ #
8
+ # Author:: Jeff Pace <jpace@incava.org>
9
+ # Documentation:: Author
10
+ #
11
+
12
+ require 'logue/log'
13
+ require 'rubygems'
14
+ require 'rainbow'
15
+
16
+ #
17
+ # == Loggable
18
+ #
19
+ # Including this module in a class gives access to the logger methods.
20
+ #
21
+ # == Examples
22
+ #
23
+ # See the unit tests in log_test.rb
24
+ #
25
+ # == Usage
26
+ #
27
+ # class YourClass
28
+ # include Loggable
29
+ #
30
+ # def some_method(...)
31
+ # log "my message"
32
+ #
33
+ # That will log from the given class and method, showing the line number from
34
+ # which the logger was called.
35
+ #
36
+ # def another_method(...)
37
+ # stack "my message"
38
+ #
39
+ # That will produce a stack trace from the given location.
40
+ #
41
+
42
+ module Logue
43
+ module Loggable
44
+ # Logs the given message, including the class whence invoked.
45
+ def log msg = "", lvl = Log::DEBUG, depth = 1, &blk
46
+ Log.log msg, lvl, depth + 1, self.class.to_s, &blk
47
+ end
48
+
49
+ def debug msg = "", depth = 1, &blk
50
+ Log.log msg, Log::DEBUG, depth + 1, self.class.to_s, &blk
51
+ end
52
+
53
+ def info msg = "", depth = 1, &blk
54
+ Log.log msg, Log::INFO, depth + 1, self.class.to_s, &blk
55
+ end
56
+
57
+ def warn msg = "", depth = 1, &blk
58
+ Log.log msg, Log::WARN, depth + 1, self.class.to_s, &blk
59
+ end
60
+
61
+ def error msg = "", depth = 1, &blk
62
+ Log.log msg, Log::ERROR, depth + 1, self.class.to_s, &blk
63
+ end
64
+
65
+ def fatal msg = "", depth = 1, &blk
66
+ Log.log msg, Log::FATAL, depth + 1, self.class.to_s, &blk
67
+ end
68
+
69
+ def stack msg = "", lvl = Log::DEBUG, depth = 1, &blk
70
+ Log.stack msg, lvl, depth + 1, self.class.to_s, &blk
71
+ end
72
+
73
+ def write msg = "", depth = 1, &blk
74
+ Log.write msg, depth + 1, self.class.to_s, &blk
75
+ end
76
+
77
+ def method_missing meth, *args, &blk
78
+ validcolors = Sickill::Rainbow::TERM_COLORS
79
+ # only handling foregrounds, not backgrounds
80
+ if code = validcolors[meth]
81
+ add_color_method meth.to_s, code + 30
82
+ send meth, *args, &blk
83
+ else
84
+ super
85
+ end
86
+ end
87
+
88
+ def respond_to? meth
89
+ validcolors = Sickill::Rainbow::TERM_COLORS
90
+ validcolors.include?(meth) || super
91
+ end
92
+
93
+ def add_color_method color, code
94
+ meth = Array.new
95
+ meth << "def #{color}(msg = \"\", lvl = Log::DEBUG, depth = 1, cname = nil, &blk)"
96
+ meth << " Log.#{color} msg, lvl, depth + 1, self.class.to_s, &blk"
97
+ meth << "end"
98
+ self.class.module_eval meth.join("\n")
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,267 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+ #
4
+ # = logger.rb
5
+ #
6
+ # Logging Module
7
+ #
8
+ # Author:: Jeff Pace <jpace@incava.org>
9
+ # Documentation:: Author
10
+ #
11
+
12
+ require 'rubygems'
13
+ require 'rainbow'
14
+ require 'pathname'
15
+ require 'logue/severity'
16
+ require 'logue/format'
17
+
18
+ #
19
+ # == Logger
20
+ #
21
+ # This class logs messages. You probably don't want to use this directly; Log is
22
+ # the class containing the necessary class methods.
23
+ #
24
+ # == Examples
25
+ #
26
+ # See the unit tests in log_test.rb
27
+ #
28
+
29
+ module Logue
30
+ class Logger
31
+ $LOGGING_LEVEL = nil
32
+
33
+ attr_accessor :quiet
34
+ attr_accessor :output
35
+ attr_accessor :colorize_line
36
+ attr_accessor :level
37
+ attr_accessor :ignored_files
38
+ attr_accessor :ignored_methods
39
+ attr_accessor :ignored_classes
40
+ attr_accessor :trim
41
+
42
+ include Log::Severity
43
+
44
+ FRAME_RE = Regexp.new('(.*):(\d+)(?::in \`(.*)\')?')
45
+
46
+ def initialize
47
+ set_defaults
48
+ end
49
+
50
+ def verbose= v
51
+ @level = case v
52
+ when TrueClass
53
+ DEBUG
54
+ when FalseClass
55
+ FATAL
56
+ when Integer
57
+ v
58
+ end
59
+ end
60
+
61
+ def set_defaults
62
+ $LOGGING_LEVEL = @level = FATAL
63
+ @ignored_files = Hash.new
64
+ @ignored_methods = Hash.new
65
+ @ignored_classes = Hash.new
66
+ @width = 0
67
+ @output = $stdout
68
+ @colors = Array.new
69
+ @colorize_line = false
70
+ @quiet = false
71
+ @trim = true
72
+
73
+ set_default_widths
74
+ end
75
+
76
+ def set_default_widths
77
+ set_widths Log::DEFAULT_FILENAME_WIDTH, Log::DEFAULT_LINENUM_WIDTH, Log::DEFAULT_FUNCTION_WIDTH
78
+ end
79
+
80
+ def verbose
81
+ level <= DEBUG
82
+ end
83
+
84
+ # Assigns output to a file with the given name. Returns the file; client
85
+ # is responsible for closing it.
86
+ def outfile= f
87
+ @output = f.kind_of?(IO) ? f : File.new(f, "w")
88
+ end
89
+
90
+ # Creates a printf format for the given widths, for aligning output. To lead
91
+ # lines with zeros (e.g., "00317") the line_width argument must be a string,
92
+ # not an integer.
93
+ def set_widths file_width, line_width, func_width
94
+ @file_width = file_width
95
+ @line_width = line_width
96
+ @function_width = func_width
97
+
98
+ @format = "[%#{file_width}s:%#{line_width}d] {%#{func_width}s}"
99
+ end
100
+
101
+ def ignore_file fname
102
+ ignored_files[fname] = true
103
+ end
104
+
105
+ def ignore_method methname
106
+ ignored_methods[methname] = true
107
+ end
108
+
109
+ def ignore_class classname
110
+ ignored_classes[classname] = true
111
+ end
112
+
113
+ def log_file fname
114
+ ignored_files.delete fname
115
+ end
116
+
117
+ def log_method methname
118
+ ignored_methods.delete methname
119
+ end
120
+
121
+ def log_class classname
122
+ ignored_classes.delete classname
123
+ end
124
+
125
+ def debug msg = "", depth = 1, &blk
126
+ log msg, DEBUG, depth + 1, &blk
127
+ end
128
+
129
+ def info msg = "", depth = 1, &blk
130
+ log msg, INFO, depth + 1, &blk
131
+ end
132
+
133
+ def warn msg = "", depth = 1, &blk
134
+ log msg, WARN, depth + 1, &blk
135
+ end
136
+
137
+ def error msg = "", depth = 1, &blk
138
+ log msg, ERROR, depth + 1, &blk
139
+ end
140
+
141
+ def fatal msg = "", depth = 1, &blk
142
+ log msg, FATAL, depth + 1, &blk
143
+ end
144
+
145
+ # Logs the given message.
146
+ def log msg = "", lvl = DEBUG, depth = 1, cname = nil, &blk
147
+ if lvl >= level
148
+ frame = nil
149
+
150
+ stk = caller 0
151
+ stk.reverse.each_with_index do |frm, idx|
152
+ if frm.index(%r{logue/log.*:\d+:in\b})
153
+ break
154
+ else
155
+ frame = frm
156
+ end
157
+ end
158
+
159
+ print_stack_frame frame, cname, msg, lvl, &blk
160
+ end
161
+ end
162
+
163
+ # Shows the current stack.
164
+ def stack msg = "", lvl = DEBUG, depth = 1, cname = nil, &blk
165
+ if lvl >= level
166
+ stk = caller depth
167
+ for frame in stk
168
+ print_stack_frame frame, cname, msg, lvl, &blk
169
+ cname = nil
170
+ msg = ""
171
+ end
172
+ end
173
+ end
174
+
175
+ def print_stack_frame frame, cname, msg, lvl, &blk
176
+ md = FRAME_RE.match frame
177
+ file, line, func = md[1], md[2], (md[3] || "")
178
+ # file.sub!(/.*\//, "")
179
+
180
+ # Ruby 1.9 expands the file name, but 1.8 doesn't:
181
+ pn = Pathname.new(file).expand_path
182
+
183
+ file = pn.to_s
184
+
185
+ if cname
186
+ func = cname + "#" + func
187
+ end
188
+
189
+ if ignored_files[file] || (cname && ignored_classes[cname]) || ignored_methods[func]
190
+ # skip this one.
191
+ else
192
+ print_formatted(file, line, func, msg, lvl, &blk)
193
+ end
194
+ end
195
+
196
+ def print_formatted file, line, func, msg, lvl, &blk
197
+ if trim
198
+ fmt = Format.new
199
+ file = fmt.trim_right file, @file_width
200
+ line = fmt.trim_left line, @line_width
201
+ func = fmt.trim_left func, @function_width
202
+ end
203
+
204
+ hdr = sprintf @format, file, line, func
205
+ print hdr, msg, lvl, &blk
206
+ end
207
+
208
+ def print hdr, msg, lvl, &blk
209
+ if blk
210
+ x = blk.call
211
+ if x.kind_of? String
212
+ msg = x
213
+ else
214
+ return
215
+ end
216
+ end
217
+
218
+ msg = msg.to_s.chomp
219
+
220
+ if lvlcol = @colors[lvl]
221
+ if colorize_line
222
+ line = hdr + " " + msg
223
+ @output.puts line.color(lvlcol)
224
+ else
225
+ @output.puts hdr + " " + msg.color(lvlcol)
226
+ end
227
+ else
228
+ @output.puts hdr + " " + msg
229
+ end
230
+ end
231
+
232
+ def set_color lvl, color
233
+ @colors[lvl] = color
234
+ end
235
+
236
+ def method_missing meth, *args, &blk
237
+ validcolors = Sickill::Rainbow::TERM_COLORS
238
+ # only handling foregrounds, not backgrounds
239
+ if code = validcolors[meth]
240
+ add_color_method meth.to_s, code + 30
241
+ send meth, *args, &blk
242
+ else
243
+ super
244
+ end
245
+ end
246
+
247
+ def respond_to? meth
248
+ validcolors = Sickill::Rainbow::TERM_COLORS
249
+ validcolors.include?(meth) || super
250
+ end
251
+
252
+ def add_color_method color, code
253
+ instmeth = Array.new
254
+ instmeth << "def #{color}(msg = \"\", lvl = DEBUG, depth = 1, cname = nil, &blk)"
255
+ instmeth << " log(\"\\e[#{code}m\#{msg\}\\e[0m\", lvl, depth + 1, cname, &blk)"
256
+ instmeth << "end"
257
+ instance_eval instmeth.join("\n")
258
+
259
+ clsmeth = Array.new
260
+ clsmeth << "def #{color}(msg = \"\", lvl = DEBUG, depth = 1, cname = nil, &blk)"
261
+ clsmeth << " logger.#{color}(\"\\e[#{code}m\#{msg\}\\e[0m\", lvl, depth + 1, cname, &blk)"
262
+ clsmeth << "end"
263
+
264
+ class_eval clsmeth.join("\n")
265
+ end
266
+ end
267
+ end
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+ #
4
+ # = severity.rb
5
+ #
6
+ # Logging Module
7
+ #
8
+ # Author:: Jeff Pace <jpace@incava.org>
9
+ # Documentation:: Author
10
+ #
11
+
12
+ module Logue
13
+ class Log
14
+ module Severity
15
+ DEBUG = 0
16
+ INFO = 1
17
+ WARN = 2
18
+ ERROR = 3
19
+ FATAL = 4
20
+ end
21
+ end
22
+ end
data/lib/logue.rb ADDED
@@ -0,0 +1,17 @@
1
+ loguelibdir = File.dirname(__FILE__)
2
+
3
+ $:.unshift(loguelibdir) unless
4
+ $:.include?(loguelibdir) || $:.include?(File.expand_path(loguelibdir))
5
+
6
+ require 'pathname'
7
+
8
+ rbre = Regexp.new('\.rb$')
9
+
10
+ Pathname.glob(loguelibdir + '/logue/**/*.rb').each do |file|
11
+ fname = file.sub(Regexp.new('^' + loguelibdir + '/'), '').sub(rbre, '')
12
+ require fname
13
+ end
14
+
15
+ module Logue
16
+ VERSION = '1.0.0'
17
+ end
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ require 'pathname'
5
+ require 'test/unit'
6
+ require 'stringio'
7
+ require 'logue/format'
8
+ require 'logue/loggable'
9
+
10
+ module Logue
11
+ class FormatTestCase < Test::Unit::TestCase
12
+ include Logue::Loggable
13
+
14
+ def run_trim_left_test expected, length, str = "something"
15
+ trimmed = Format.new.trim_left(str, length)
16
+ assert_equal expected, trimmed
17
+ end
18
+
19
+ def test_trim_left_short_positive_number
20
+ run_trim_left_test "some", 4
21
+ end
22
+
23
+ def test_trim_left_long
24
+ run_trim_left_test "something", 10
25
+ end
26
+
27
+ def test_trim_left_short_negative_number
28
+ run_trim_left_test "some", -4
29
+ end
30
+
31
+ def run_trim_right_test expected, length, str = "something"
32
+ trimmed = Format.new.trim_right(str, length)
33
+ assert_equal expected, trimmed
34
+ end
35
+
36
+ def test_trim_right_short_positive_number
37
+ run_trim_right_test " ...", 5
38
+ end
39
+
40
+ def test_trim_right_long
41
+ run_trim_right_test "something", 10
42
+ end
43
+
44
+ def test_trim_right_short_negative_number
45
+ run_trim_right_test " ...", -5
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,97 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ require 'pathname'
5
+ require 'test/unit'
6
+ require 'stringio'
7
+ require 'logue'
8
+
9
+ include Logue
10
+
11
+ class LogAbyss
12
+ include Loggable
13
+
14
+ def squeal
15
+ log "hello from the abyss"
16
+ stack "turtles all the way down"
17
+ end
18
+ end
19
+
20
+ class LogDepths
21
+ include Loggable
22
+
23
+ def speak
24
+ log "hello from the depths"
25
+ la = LogAbyss.new
26
+ la.squeal
27
+ end
28
+ end
29
+
30
+ class LogInner
31
+ include Loggable
32
+
33
+ def screech
34
+ ldi = LogDepths.new
35
+ log "hello from the innerds"
36
+ ldi.speak
37
+ end
38
+ end
39
+
40
+ class LogStackTestCase < Test::Unit::TestCase
41
+ include Loggable
42
+
43
+ def test_stack
44
+ Log.set_widths(-15, 4, -40)
45
+
46
+ log = Proc.new {
47
+ li = LogInner.new
48
+ li.screech
49
+ }
50
+
51
+ expected_output = [
52
+ "[ ...: 35] {LogInner#screech } hello from the innerds",
53
+ "[ ...: 24] {LogDepths#speak } hello from the depths",
54
+ "[ ...: 15] {LogAbyss#squeal } hello from the abyss",
55
+ "[ ...: 16] {LogAbyss#squeal } turtles all the way down",
56
+ "[ ...: 26] {speak } ",
57
+ "[ ...: 36] {screech } ",
58
+ ]
59
+
60
+ run_test @verbose_setup, log, *expected_output
61
+ end
62
+
63
+ # the ctor is down here so the lines above are less likely to change.
64
+ def initialize test, name = nil
65
+ @nonverbose_setup = Proc.new {
66
+ Log.verbose = false
67
+ Log.output = StringIO.new
68
+ }
69
+
70
+ @verbose_setup = Proc.new {
71
+ Log.verbose = true
72
+ Log.output = StringIO.new
73
+ }
74
+
75
+ super test
76
+ end
77
+
78
+ def run_test setup, log, *expected
79
+ io = setup.call
80
+
81
+ log.call
82
+
83
+ assert_not_nil io
84
+ str = io.string
85
+ assert_not_nil str
86
+
87
+ lines = str.split "\n"
88
+
89
+ (0 ... expected.size).each do |idx|
90
+ if expected[idx]
91
+ assert_equal expected[idx], lines[idx], "index: #{idx}"
92
+ end
93
+ end
94
+
95
+ Log.output = io
96
+ end
97
+ end
@@ -0,0 +1,166 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ require 'pathname'
5
+ require 'test/unit'
6
+ require 'stringio'
7
+ require 'logue/loggable'
8
+ require 'logue/testlog/logtestee'
9
+
10
+ include Logue
11
+
12
+ class LogTestCase < Test::Unit::TestCase
13
+ include Loggable
14
+
15
+ def run_log_testee_test(methname, expected, &blk)
16
+ Log.verbose = true
17
+ io = StringIO.new
18
+ Log.output = io
19
+ Log.set_default_widths
20
+
21
+ blk.call if blk
22
+
23
+ lt = LogTestee.new
24
+ lt.send methname
25
+
26
+ str = io.string
27
+
28
+ lines = str.split "\n"
29
+
30
+ (0 ... expected.size).each do |idx|
31
+ if expected[idx]
32
+ assert_equal expected[idx], lines[idx], "index: #{idx}"
33
+ end
34
+ end
35
+
36
+ Log.set_default_widths
37
+ end
38
+
39
+ def run_format_test(expected, &blk)
40
+ Log.verbose = true
41
+ io = StringIO.new
42
+ Log.output = io
43
+ Log.set_default_widths
44
+
45
+ blk.call
46
+
47
+ lt = LogTestee.new
48
+ lt.format_test
49
+
50
+ assert_equal expected.join(''), io.string
51
+
52
+ Log.set_default_widths
53
+ end
54
+
55
+ def test_no_output
56
+ run_log_testee_test(:log_all, Array.new) do
57
+ Log.verbose = false
58
+ end
59
+ end
60
+
61
+ def msg lnum, methname, msg
62
+ sprintf("[ ...testlog/logtestee.rb: %2d] {%-20s} %s", 16 + lnum, methname[0 .. 19], msg)
63
+ end
64
+
65
+ def test_output_arg
66
+ methname = "log_all"
67
+
68
+ expected = Array.new
69
+ (1 .. 6).each do |lnum|
70
+ msg = "hello, world?"
71
+ if lnum == 4 || lnum == 5
72
+ msg = "EXPECTED OUTPUT TO STDERR: hello, world."
73
+ end
74
+ expected << sprintf("[ ...testlog/logtestee.rb: %2d] {%-20s} %s", 16 + lnum, methname[0 .. 19], msg)
75
+ end
76
+
77
+ run_log_testee_test(:log_all, expected)
78
+ end
79
+
80
+ def test_output_block_at_level
81
+ Log.level = Log::DEBUG
82
+
83
+ methname = "log_block"
84
+
85
+ msg = "block party"
86
+
87
+ expected = Array.new
88
+ expected << sprintf("[ ...testlog/logtestee.rb: %2d] {%-20s} %s", 26, methname[0 .. 19], msg)
89
+
90
+ run_log_testee_test(:log_block, expected)
91
+ end
92
+
93
+ def test_output_block_below_level
94
+ expected = Array.new
95
+
96
+ run_log_testee_test(:log_block, expected) do
97
+ Log.level = Log::INFO
98
+ end
99
+ end
100
+
101
+ def test_colors_foreground
102
+ methname = "log_foregrounds"
103
+ expected = Array.new
104
+ expected << sprintf("[ ...testlog/logtestee.rb: %2d] {%-20s} %s", 30, methname[0 .. 19], "\e[37mwhite wedding\e[0m")
105
+ expected << sprintf("[ ...testlog/logtestee.rb: %2d] {%-20s} %s", 31, methname[0 .. 19], "\e[34mblue iris\e[0m")
106
+
107
+ run_log_testee_test(:log_foregrounds, expected)
108
+ end
109
+
110
+ def xxxtest_colors_background
111
+ expected = Array.new
112
+ expected << "[ ...test/logue/log_test.rb: 109] {LogTestCase#test_col} \e[46mred\e[0m"
113
+
114
+ run_log_testee_test(:log_foregrounds, expected) do
115
+ end
116
+ end
117
+
118
+ def test_format_default
119
+ expected = Array.new
120
+ expected << "[ ...testlog/logtestee.rb: 10] {format_test } tamrof\n"
121
+
122
+ run_format_test expected do
123
+ Log.set_default_widths
124
+ end
125
+ end
126
+
127
+ def test_format_flush_filename_left
128
+ expected = Array.new
129
+ expected << "[ ...test/logue/testlog/logtestee.rb: 10] {format_test } tamrof\n"
130
+
131
+ run_format_test expected do
132
+ Log.set_widths(-35, Log::DEFAULT_LINENUM_WIDTH, Log::DEFAULT_FUNCTION_WIDTH)
133
+ end
134
+ end
135
+
136
+ def test_format_flush_linenum_left
137
+ expected = Array.new
138
+ expected << "[ ...testlog/logtestee.rb:10 ] {format_test } tamrof\n"
139
+
140
+ run_format_test expected do
141
+ Log.set_widths(Log::DEFAULT_FILENAME_WIDTH, -10, Log::DEFAULT_FUNCTION_WIDTH)
142
+ end
143
+ end
144
+
145
+ def test_format_flush_function_right
146
+ expected = Array.new
147
+ expected << "[ ...testlog/logtestee.rb: 10] { format_test} tamrof\n"
148
+
149
+ run_format_test expected do
150
+ Log.set_widths(Log::DEFAULT_FILENAME_WIDTH, Log::DEFAULT_LINENUM_WIDTH, 35)
151
+ end
152
+ end
153
+
154
+ def test_format_pad_linenum_zeros
155
+ expected = Array.new
156
+ expected << "[ ...testlog/logtestee.rb:00000010] {format_test } tamrof\n"
157
+
158
+ run_format_test expected do
159
+ Log.set_widths(Log::DEFAULT_FILENAME_WIDTH, "08", Log::DEFAULT_FUNCTION_WIDTH)
160
+ end
161
+ end
162
+
163
+ def test_respond_to_color
164
+ assert Log.respond_to? :blue
165
+ end
166
+ end
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ require 'pathname'
5
+ require 'test/unit'
6
+ require 'stringio'
7
+ require 'logue/log'
8
+ require 'logue/loggable'
9
+ require 'logue/testlog/lgbl_testee'
10
+
11
+ class LoggableTestCase < Test::Unit::TestCase
12
+ include Logue::Loggable
13
+
14
+ def test_instance_colors
15
+ Logue::Log.verbose = true
16
+ io = StringIO.new
17
+ Logue::Log.output = io
18
+
19
+ expected = Array.new
20
+ expected << "[...testlog/lgbl_testee.rb: 11] {LgblTestee#crystal } hello!\n"
21
+ expected << "[...testlog/lgbl_testee.rb: 12] {LgblTestee#crystal } azul ... \n"
22
+ expected << "[...testlog/lgbl_testee.rb: 13] {LgblTestee#crystal } rojo?\n"
23
+
24
+ te = LgblTestee.new
25
+ te.crystal
26
+
27
+ # puts io.string
28
+
29
+ assert_equal expected.join(''), io.string
30
+ end
31
+ end
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: logue
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jeff Pace
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-05-08 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rainbow
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 1.1.4
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 1.1.4
30
+ description: A module that adds logging/trace functionality.
31
+ email: jeugenepace@gmail.com
32
+ executables: []
33
+ extensions: []
34
+ extra_rdoc_files:
35
+ - README.md
36
+ files:
37
+ - lib/logue.rb
38
+ - lib/logue/format.rb
39
+ - lib/logue/log.rb
40
+ - lib/logue/loggable.rb
41
+ - lib/logue/logger.rb
42
+ - lib/logue/severity.rb
43
+ - test/logue/format_test.rb
44
+ - test/logue/testlog/log_stack_test.rb
45
+ - test/logue/testlog/log_test.rb
46
+ - test/logue/testlog/loggable_test.rb
47
+ - README.md
48
+ homepage: http://jeugenepace.github.com/logue
49
+ licenses: []
50
+ post_install_message:
51
+ rdoc_options: []
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ! '>='
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ requirements: []
67
+ rubyforge_project:
68
+ rubygems_version: 1.8.23
69
+ signing_key:
70
+ specification_version: 3
71
+ summary: A minimalist logging module.
72
+ test_files:
73
+ - test/logue/format_test.rb
74
+ - test/logue/testlog/log_stack_test.rb
75
+ - test/logue/testlog/log_test.rb
76
+ - test/logue/testlog/loggable_test.rb