nrser 0.0.13 → 0.0.14
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
- data/lib/nrser/collection.rb +61 -0
- data/lib/nrser/logger.rb +458 -0
- data/lib/nrser/version.rb +1 -1
- data/lib/nrser.rb +1 -0
- data/nrser.gemspec +2 -0
- data/spec/nrser/collection/each_spec.rb +33 -0
- data/spec/nrser/collection/map_spec.rb +37 -0
- data/spec/nrser/logger/dest_spec.rb +14 -0
- data/spec/nrser/logger/die_spec.rb +41 -0
- data/spec/nrser/logger/install_spec.rb +98 -0
- data/spec/nrser/logger/level_int_spec.rb +22 -0
- data/spec/nrser/logger/level_name_spec.rb +23 -0
- data/spec/nrser/logger/level_sym_spec.rb +22 -0
- data/spec/nrser/logger/send_log_spec.rb +63 -0
- data/spec/nrser/logger/use_spec.rb +16 -0
- data/spec/spec_helper.rb +24 -0
- metadata +53 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cf2ecc0e4643be7c0c21b0e724cfeb4f5103747b
|
4
|
+
data.tar.gz: a476408cd07adb066c09802bf1e5fbc895e0edec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 40f0ba9542f641d70420844363c3ed87aa2774a4da49ee77b504421a84f5b350164195d2a46de253fb52d1ee75b4dc8e71604fbe132e58c5da391a2288812af9
|
7
|
+
data.tar.gz: 1a86fd85091edc7c449471134e1c05700e0b9c4228431e6bf52099b2110218c5e4189ad37af1d42835ed6e37fbf50f78aed0f21e660e3334d2bd1e4274e0905a
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module NRSER
|
2
|
+
# include this module in any custom classes to have them treated as
|
3
|
+
# collections instead of individual objects by the methods in this file
|
4
|
+
module Collection
|
5
|
+
|
6
|
+
# [Array<Class>] stdlib classes that are considered collections.
|
7
|
+
STDLIB = [
|
8
|
+
Array,
|
9
|
+
Hash,
|
10
|
+
Set,
|
11
|
+
]
|
12
|
+
end
|
13
|
+
|
14
|
+
class << self
|
15
|
+
|
16
|
+
# test if an object is considered a collection.
|
17
|
+
#
|
18
|
+
# @param obj [Object] object to test
|
19
|
+
# @return [Boolean] true if `obj` is a collection.
|
20
|
+
#
|
21
|
+
def collection? obj
|
22
|
+
Collection::STDLIB.any? {|cls| obj.is_a? cls} || obj.is_a?(Collection)
|
23
|
+
end
|
24
|
+
|
25
|
+
# yield on each element of a collection or on the object itself if it's
|
26
|
+
# not a collection. avoids having to normalize to an array to iterate over
|
27
|
+
# something that may be an object OR a collection of objects.
|
28
|
+
#
|
29
|
+
# @param obj [Object] target object.
|
30
|
+
#
|
31
|
+
# @yield each element of a collection or the target object itself.
|
32
|
+
#
|
33
|
+
# @return [Object] obj param.
|
34
|
+
#
|
35
|
+
def each obj, &block
|
36
|
+
if collection? obj
|
37
|
+
obj.each &block
|
38
|
+
else
|
39
|
+
block.call obj
|
40
|
+
obj
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# if `obj` is a collection, calls `#map` with the block. otherwise,
|
45
|
+
# applies block to the object and returns the result.
|
46
|
+
#
|
47
|
+
# @param obj [Object] target object.
|
48
|
+
#
|
49
|
+
# @yield each element of a collection or the target object itself.
|
50
|
+
#
|
51
|
+
# @return [Object] the result of mapping or applying the block.
|
52
|
+
#
|
53
|
+
def map obj, &block
|
54
|
+
if collection? obj
|
55
|
+
obj.map &block
|
56
|
+
else
|
57
|
+
block.call obj
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/nrser/logger.rb
ADDED
@@ -0,0 +1,458 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'yaml'
|
3
|
+
require 'pp'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
require 'nrser'
|
7
|
+
require 'nrser/refinements'
|
8
|
+
|
9
|
+
using NRSER
|
10
|
+
|
11
|
+
module NRSER
|
12
|
+
|
13
|
+
# @todo doc class
|
14
|
+
class Logger
|
15
|
+
# constants
|
16
|
+
# =========
|
17
|
+
|
18
|
+
# symbols for the level names
|
19
|
+
LEVEL_SYMS = [
|
20
|
+
:debug,
|
21
|
+
:info,
|
22
|
+
:warn,
|
23
|
+
:error,
|
24
|
+
:fatal,
|
25
|
+
:unknown,
|
26
|
+
]
|
27
|
+
|
28
|
+
LOGGING_METHODS = LEVEL_SYMS - [:unknown] + [:die]
|
29
|
+
|
30
|
+
SEVERITY_COLORS = {
|
31
|
+
'DEBUG' => :bright_black,
|
32
|
+
'WARN' => :yellow,
|
33
|
+
'INFO' => :green,
|
34
|
+
'ERROR' => :red,
|
35
|
+
'FATAL' => :on_red,
|
36
|
+
}
|
37
|
+
|
38
|
+
# class variables
|
39
|
+
# ===============
|
40
|
+
|
41
|
+
# [Pastel, false] if pastel is present, this will be an instance of
|
42
|
+
# `Pastel` otherwise, it will be false
|
43
|
+
@@pastel = begin
|
44
|
+
require 'pastel'
|
45
|
+
Pastel.new
|
46
|
+
rescue LoadError => e
|
47
|
+
false
|
48
|
+
end
|
49
|
+
|
50
|
+
# [Hash<IO, ::Logger>] map of IO instances (files, STDOUT, STDERR, etc.)
|
51
|
+
# to Ruby stdlib `Logger` instances that handle the actual writing to
|
52
|
+
# that destination.
|
53
|
+
@ruby_loggers = {}
|
54
|
+
|
55
|
+
# class functions
|
56
|
+
# ==============
|
57
|
+
|
58
|
+
# @api util
|
59
|
+
# *pure*
|
60
|
+
#
|
61
|
+
# format a debug message with optional key / values to print
|
62
|
+
#
|
63
|
+
# @param name [String] logger name.
|
64
|
+
# @param level [String, Symbol, Fixnum] the level in string, symbol or
|
65
|
+
# integer form.
|
66
|
+
# @param msg [String] message to print.
|
67
|
+
# @param dump [Hash] optional hash of keys and vaues to dump.
|
68
|
+
def self.format name, level, msg, dump = {}
|
69
|
+
data = {
|
70
|
+
'logger' => name,
|
71
|
+
'time' => Time.now,
|
72
|
+
}
|
73
|
+
|
74
|
+
data['msg'] = msg unless msg.empty?
|
75
|
+
data['values'] = dump_value(dump) unless dump.empty?
|
76
|
+
|
77
|
+
YAML.dump level_name(level) => data
|
78
|
+
end
|
79
|
+
# prev:
|
80
|
+
# def self.format msg, dump = {}
|
81
|
+
# unless dump.empty?
|
82
|
+
# msg += "\n" + dump.map {|k, v| " #{ k }: #{ v.inspect }" }.join("\n")
|
83
|
+
# end
|
84
|
+
# msg
|
85
|
+
# end
|
86
|
+
|
87
|
+
def self.dump_value value
|
88
|
+
case value
|
89
|
+
when String, Fixnum, Float, TrueClass, FalseClass
|
90
|
+
value
|
91
|
+
when Array
|
92
|
+
value.map {|v| dump_value v}
|
93
|
+
when Hash
|
94
|
+
Hash[value.map {|k, v| [k.to_s, dump_value(v)]}]
|
95
|
+
else
|
96
|
+
value.pretty_inspect
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# @api util
|
101
|
+
#
|
102
|
+
#
|
103
|
+
def self.check_level level
|
104
|
+
case level
|
105
|
+
when Fixnum
|
106
|
+
unless level >= 0 && level < LEVEL_SYMS.length
|
107
|
+
raise ArgumentError.new "invalid integer level: #{ level.inspect }"
|
108
|
+
end
|
109
|
+
when Symbol
|
110
|
+
unless LEVEL_SYMS.include? level
|
111
|
+
raise ArgumentError.new "invalid level symbol: #{ level.inspect }"
|
112
|
+
end
|
113
|
+
when String
|
114
|
+
unless LEVEL_SYMS.map {|_| _.to_s.upcase}.include? level
|
115
|
+
raise ArgumentError.new "invalid level name: #{ level.inspect }"
|
116
|
+
end
|
117
|
+
else
|
118
|
+
raise TypeError.new binding.erb <<-END
|
119
|
+
level must be Fixnum, Symbol or String, not <%= level.inspect %>
|
120
|
+
END
|
121
|
+
end
|
122
|
+
end # #check_level
|
123
|
+
|
124
|
+
# @api util
|
125
|
+
# *pure*
|
126
|
+
#
|
127
|
+
# get the integer value of a level (like ::Logger::DEBUG, etc.).
|
128
|
+
#
|
129
|
+
# @param level [Fixnum, Symbol, String] the integer level, method symbol,
|
130
|
+
# or string name (all caps).
|
131
|
+
#
|
132
|
+
# @return [Fixnum] level integer (between 0 and 5 inclusive).
|
133
|
+
#
|
134
|
+
def self.level_int level
|
135
|
+
check_level level
|
136
|
+
case level
|
137
|
+
when Fixnum
|
138
|
+
level
|
139
|
+
when Symbol
|
140
|
+
LEVEL_SYMS.each_with_index {|sym, index|
|
141
|
+
return index if level == sym
|
142
|
+
}
|
143
|
+
when String
|
144
|
+
LEVEL_SYMS.each_with_index {|sym, index|
|
145
|
+
return index if level == sym.to_s.upcase
|
146
|
+
}
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
# @api util
|
151
|
+
# *pure*
|
152
|
+
#
|
153
|
+
# get the string "name" of a level ('DEBUG', 'INFO', etc.).
|
154
|
+
#
|
155
|
+
# @param level [Fixnum, Symbol, String] the integer level, method symbol,
|
156
|
+
# or string name (all caps).
|
157
|
+
#
|
158
|
+
# @return ['DEBUG', 'INFO', 'WARN', 'ERROR', 'FATAL', 'UNKNOWN']
|
159
|
+
#
|
160
|
+
def self.level_name level
|
161
|
+
check_level level
|
162
|
+
case level
|
163
|
+
when Fixnum
|
164
|
+
LEVEL_SYMS[level].to_s.upcase
|
165
|
+
when Symbol
|
166
|
+
level.to_s.upcase
|
167
|
+
when String
|
168
|
+
level
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
# @api util
|
173
|
+
# *pure*
|
174
|
+
#
|
175
|
+
# get the symbol for a level as used in method sigs.
|
176
|
+
#
|
177
|
+
# @param level [Fixnum, Symbol, String] the integer level, method symbol,
|
178
|
+
# or string name (all caps).
|
179
|
+
#
|
180
|
+
# @return [:debug, :info, :warn, :error, :fatal, :unknown]
|
181
|
+
#
|
182
|
+
def self.level_sym level
|
183
|
+
check_level level
|
184
|
+
case level
|
185
|
+
when Fixnum
|
186
|
+
LEVEL_SYMS[level]
|
187
|
+
when Symbol
|
188
|
+
level
|
189
|
+
when String
|
190
|
+
level.downcase.to_sym
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
# @api util
|
195
|
+
# *pure*
|
196
|
+
#
|
197
|
+
# creates methods closed around a `NRSER::Logger` instance to be attached
|
198
|
+
# to objects to access the logger and do logging and 'installs' them on
|
199
|
+
# the target.
|
200
|
+
#
|
201
|
+
# @param target [Object] object to install methods on.
|
202
|
+
#
|
203
|
+
# @param logger [NRSER::Logger] the logger to bind the methods to.
|
204
|
+
#
|
205
|
+
# @return nil
|
206
|
+
#
|
207
|
+
def self.install_methods! target, logger
|
208
|
+
methods = {
|
209
|
+
logger: {
|
210
|
+
private: false,
|
211
|
+
body: ->() { logger },
|
212
|
+
},
|
213
|
+
}
|
214
|
+
|
215
|
+
LOGGING_METHODS.each do |sym|
|
216
|
+
methods[sym] = {
|
217
|
+
private: true,
|
218
|
+
body: ->(*args, &block) { logger.send sym, *args, &block },
|
219
|
+
}
|
220
|
+
end
|
221
|
+
|
222
|
+
if target.is_a? Class
|
223
|
+
methods.each do |sym, stuff|
|
224
|
+
target.define_singleton_method sym, &stuff[:body]
|
225
|
+
target.send :define_method, sym, &stuff[:body]
|
226
|
+
target.send :private, sym if stuff[:private]
|
227
|
+
end
|
228
|
+
|
229
|
+
elsif target.is_a? Module
|
230
|
+
methods.each do |sym, stuff|
|
231
|
+
target.define_singleton_method sym, &stuff[:body]
|
232
|
+
target.private_class_method sym if stuff[:private]
|
233
|
+
end
|
234
|
+
|
235
|
+
else
|
236
|
+
methods.each do |sym, stuff|
|
237
|
+
target.send :define_method, sym, &stuff[:body]
|
238
|
+
target.send :private, sym if stuff[:private]
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
nil
|
243
|
+
end
|
244
|
+
|
245
|
+
|
246
|
+
# creates a new `NRSER::Logger` and 'installs' a logger on target, adding
|
247
|
+
# singleton (class) and instance methods as appropriate
|
248
|
+
#
|
249
|
+
# @param target [Object] the object to install a new logger on, which can
|
250
|
+
# be a Module, a Class, or just any plain-old instance that you want
|
251
|
+
# to have it's own logger client.
|
252
|
+
#
|
253
|
+
# @param options [Hash] options used when creating the `NRSER::Logger`.
|
254
|
+
# @see NRSER::Logger#initialize
|
255
|
+
#
|
256
|
+
# @return [NRSER::Logger] the new `NRSER::Logger` instance.
|
257
|
+
#
|
258
|
+
def self.install target, options = {}
|
259
|
+
options[:on] ||= false
|
260
|
+
options[:name] ||= if target.respond_to?(:name) && !target.name.nil?
|
261
|
+
target.name
|
262
|
+
else
|
263
|
+
target.to_s
|
264
|
+
end
|
265
|
+
|
266
|
+
logger = self.new options
|
267
|
+
install_methods! target, logger
|
268
|
+
|
269
|
+
logger
|
270
|
+
end # .install
|
271
|
+
|
272
|
+
|
273
|
+
# singleton (class) and instance methods as appropriate
|
274
|
+
#
|
275
|
+
#
|
276
|
+
# @param source [Object] source instance with a logger installed to use
|
277
|
+
# for the target.
|
278
|
+
#
|
279
|
+
# @param target [Object] the object to use the source's logger.
|
280
|
+
#
|
281
|
+
# @return [NRSER::Logger] the new `NRSER::Logger` instance.
|
282
|
+
#
|
283
|
+
def self.use source, target
|
284
|
+
install_methods! target, source.logger
|
285
|
+
end # .use
|
286
|
+
|
287
|
+
attr_reader :name, :dest, :level, :ruby_logger
|
288
|
+
|
289
|
+
def initialize options = {}
|
290
|
+
options = {
|
291
|
+
dest: $stderr,
|
292
|
+
level: :info,
|
293
|
+
say_hi: true,
|
294
|
+
on: true,
|
295
|
+
}.merge options
|
296
|
+
|
297
|
+
@name = options[:name]
|
298
|
+
@on = options[:on]
|
299
|
+
@level = self.class.level_int options[:level]
|
300
|
+
self.dest = options[:dest]
|
301
|
+
|
302
|
+
if @on && options[:say_hi]
|
303
|
+
info <<-END.squish
|
304
|
+
started to logging to #{ @dest } at level
|
305
|
+
#{ self.class.level_name @level }...
|
306
|
+
END
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
def on?
|
311
|
+
@on
|
312
|
+
end
|
313
|
+
|
314
|
+
def off?
|
315
|
+
!on?
|
316
|
+
end
|
317
|
+
|
318
|
+
def on &block
|
319
|
+
if block
|
320
|
+
prev = @on
|
321
|
+
@on = true
|
322
|
+
block.call
|
323
|
+
@on = prev
|
324
|
+
else
|
325
|
+
@on = true
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
def off &block
|
330
|
+
if block
|
331
|
+
prev = @on
|
332
|
+
@on = false
|
333
|
+
block.call
|
334
|
+
@on = prev
|
335
|
+
else
|
336
|
+
@on = false
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
def level= level
|
341
|
+
@level = self.class.level_int(level)
|
342
|
+
@ruby_loggers.each do |dest, ruby_logger|
|
343
|
+
ruby_logger.level = @level
|
344
|
+
end
|
345
|
+
@level
|
346
|
+
end
|
347
|
+
|
348
|
+
def with_level level, &block
|
349
|
+
prev_level = self.level
|
350
|
+
self.level = level
|
351
|
+
block.call
|
352
|
+
self.level = prev_level
|
353
|
+
end
|
354
|
+
|
355
|
+
def dest= dest
|
356
|
+
@ruby_loggers = {}
|
357
|
+
NRSER.each dest do |dest|
|
358
|
+
@ruby_loggers[dest] = ::Logger.new(dest).tap do |ruby_logger|
|
359
|
+
ruby_logger.level = @level
|
360
|
+
ruby_logger.formatter = proc do |severity, datetime, progname, msg|
|
361
|
+
# just pass through
|
362
|
+
msg
|
363
|
+
end
|
364
|
+
end
|
365
|
+
end
|
366
|
+
@dest = dest
|
367
|
+
end
|
368
|
+
|
369
|
+
# logging api
|
370
|
+
# ===========
|
371
|
+
|
372
|
+
# @api logging
|
373
|
+
def debug *args, &block
|
374
|
+
send_log :debug, args, block
|
375
|
+
end
|
376
|
+
|
377
|
+
# @api logging
|
378
|
+
def info *args, &block
|
379
|
+
send_log :info, args, block
|
380
|
+
end
|
381
|
+
|
382
|
+
# @api logging
|
383
|
+
def warn *args, &block
|
384
|
+
send_log :warn, args, block
|
385
|
+
end
|
386
|
+
|
387
|
+
# @api logging
|
388
|
+
def error *args, &block
|
389
|
+
send_log :error, args, block
|
390
|
+
end
|
391
|
+
|
392
|
+
# @api logging
|
393
|
+
def fatal *args, &block
|
394
|
+
send_log :fatal, args, block
|
395
|
+
end
|
396
|
+
|
397
|
+
# @api logging
|
398
|
+
def die *args, &block
|
399
|
+
if @on
|
400
|
+
send_log :fatal, args, block
|
401
|
+
abort
|
402
|
+
else
|
403
|
+
abort self.class.format(
|
404
|
+
@name,
|
405
|
+
:fatal,
|
406
|
+
*extract_msg_and_dump(args, block)
|
407
|
+
)
|
408
|
+
end
|
409
|
+
end
|
410
|
+
|
411
|
+
private
|
412
|
+
def extract_msg_and_dump args, block
|
413
|
+
msg = ''
|
414
|
+
dump = {}
|
415
|
+
case args.length
|
416
|
+
when 0
|
417
|
+
# if there is no block, just no-op
|
418
|
+
# @todo is this the right way to go?
|
419
|
+
if block
|
420
|
+
result = block.call
|
421
|
+
result = [result] unless result.is_a? Array
|
422
|
+
|
423
|
+
return extract_msg_and_dump result, nil
|
424
|
+
end
|
425
|
+
when 1
|
426
|
+
case args[0]
|
427
|
+
when Hash
|
428
|
+
dump = args[0]
|
429
|
+
when String
|
430
|
+
msg = args[0]
|
431
|
+
else
|
432
|
+
msg = args[0].to_s
|
433
|
+
end
|
434
|
+
when 2
|
435
|
+
msg, dump = args
|
436
|
+
else
|
437
|
+
raise "must provide one or two arguments, not #{ args.length }"
|
438
|
+
end
|
439
|
+
|
440
|
+
[msg, dump]
|
441
|
+
end
|
442
|
+
|
443
|
+
def send_log level_sym, args, block
|
444
|
+
return unless @on && @level <= self.class.level_int(level_sym)
|
445
|
+
|
446
|
+
msg, dump = extract_msg_and_dump args, block
|
447
|
+
|
448
|
+
@ruby_loggers.each do |dest, ruby_logger|
|
449
|
+
ruby_logger.send(level_sym, @name) do
|
450
|
+
self.class.format(@name, level_sym, msg, dump)
|
451
|
+
end
|
452
|
+
end
|
453
|
+
end
|
454
|
+
|
455
|
+
# end private
|
456
|
+
|
457
|
+
end # Logger
|
458
|
+
end # NRSER
|
data/lib/nrser/version.rb
CHANGED
data/lib/nrser.rb
CHANGED
data/nrser.gemspec
CHANGED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "NRSER.each" do
|
4
|
+
it "iterates enumerables" do
|
5
|
+
[
|
6
|
+
[1, 2, 3],
|
7
|
+
Set.new([1, 2, 3]),
|
8
|
+
{a: 1, b: 2, c: 3},
|
9
|
+
].each do |enumerable|
|
10
|
+
count = 0
|
11
|
+
NRSER.each enumerable do |element|
|
12
|
+
count += 1
|
13
|
+
end
|
14
|
+
expect(count).to eq enumerable.count
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
[
|
19
|
+
"abc",
|
20
|
+
1,
|
21
|
+
Pathname.new('.').expand_path,
|
22
|
+
File.open('/dev/null'),
|
23
|
+
].each do |obj|
|
24
|
+
it "iterates a single #{ obj.class }" do
|
25
|
+
count = 0
|
26
|
+
NRSER.each obj do |element|
|
27
|
+
expect(element).to eq obj
|
28
|
+
count += 1
|
29
|
+
end
|
30
|
+
expect(count).to eq 1
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "NRSER.map" do
|
4
|
+
it "maps enumerables" do
|
5
|
+
[
|
6
|
+
[1, 2, 3],
|
7
|
+
Set.new([1, 2, 3]),
|
8
|
+
{a: 1, b: 2, c: 3},
|
9
|
+
].each do |enumerable|
|
10
|
+
count = 0
|
11
|
+
result = NRSER.map enumerable do |element|
|
12
|
+
count += 1
|
13
|
+
:x
|
14
|
+
end
|
15
|
+
expect(count).to eq enumerable.count
|
16
|
+
expect(result).to eq enumerable.map {|_| :x}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
[
|
21
|
+
"abc",
|
22
|
+
1,
|
23
|
+
Pathname.new('.').expand_path,
|
24
|
+
File.open('/dev/null'),
|
25
|
+
].map do |obj|
|
26
|
+
it "iterates a single #{ obj.class }" do
|
27
|
+
count = 0
|
28
|
+
result = NRSER.map obj do |element|
|
29
|
+
expect(element).to eq obj
|
30
|
+
count += 1
|
31
|
+
:x
|
32
|
+
end
|
33
|
+
expect(count).to eq 1
|
34
|
+
expect(result).to eq :x
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'NRSER::Logger.dest=' do
|
4
|
+
it "writes to multiple destinations" do
|
5
|
+
files = [Tempfile.new('f1'), Tempfile.new('f2')]
|
6
|
+
logger = NRSER::Logger.new dest: files, say_hi: false
|
7
|
+
logger.info "hey!"
|
8
|
+
files.each do |file|
|
9
|
+
file.rewind
|
10
|
+
data = YAML.load file.read
|
11
|
+
expect(data['INFO']['msg']).to eq "hey!"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
using NRSER
|
4
|
+
|
5
|
+
describe 'NRSER::Logger#die' do
|
6
|
+
it "prints the log message when logger is off" do
|
7
|
+
src = <<-END.dedent
|
8
|
+
require 'nrser/logger'
|
9
|
+
|
10
|
+
NRSER::Logger.install self
|
11
|
+
|
12
|
+
die "die!", cause: "just 'cause"
|
13
|
+
END
|
14
|
+
|
15
|
+
err = Cmds.err("bundle exec ruby"){ src }
|
16
|
+
data = YAML.load(err)['FATAL']
|
17
|
+
|
18
|
+
expect(data['msg']).to eq 'die!'
|
19
|
+
expect(data['values']).to eq({'cause' => "just 'cause"})
|
20
|
+
end
|
21
|
+
|
22
|
+
it(
|
23
|
+
"prints only to the log when it's on and the log writes to " +
|
24
|
+
"$stderr"
|
25
|
+
) do
|
26
|
+
src = <<-END
|
27
|
+
require 'nrser/logger'
|
28
|
+
|
29
|
+
NRSER::Logger.install self, on: true, say_hi: false
|
30
|
+
|
31
|
+
die "die!", cause: "just 'cause"
|
32
|
+
END
|
33
|
+
|
34
|
+
err = Cmds.err("bundle exec ruby"){ src }
|
35
|
+
|
36
|
+
data = YAML.load(err)['FATAL']
|
37
|
+
|
38
|
+
expect(data['msg']).to eq 'die!'
|
39
|
+
expect(data['values']).to eq({'cause' => "just 'cause"})
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'NRSER::Logger.install' do
|
4
|
+
it "installs on the global instance" do
|
5
|
+
NRSER::Logger.install MAIN
|
6
|
+
|
7
|
+
expect(logger).to be_a NRSER::Logger
|
8
|
+
expect(logger.name).to eq 'main'
|
9
|
+
|
10
|
+
expect_to_not_log { info "hey" }
|
11
|
+
|
12
|
+
logger.on
|
13
|
+
|
14
|
+
expect_to_log { info "hey" }
|
15
|
+
expect_to_not_log { debug "hey" }
|
16
|
+
end
|
17
|
+
|
18
|
+
it "is accesible in modules" do
|
19
|
+
|
20
|
+
mod = Module.new do
|
21
|
+
def self.log
|
22
|
+
info "hey"
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.logger_name
|
26
|
+
logger.name
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
expect_to_log { mod.log }
|
31
|
+
expect(mod.logger_name).to eq 'main'
|
32
|
+
end
|
33
|
+
|
34
|
+
it "is accessible in classes" do
|
35
|
+
|
36
|
+
cls = Class.new do
|
37
|
+
def self.log
|
38
|
+
info "hey"
|
39
|
+
end
|
40
|
+
|
41
|
+
def log
|
42
|
+
info "hey"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
expect_to_log { cls.log }
|
47
|
+
|
48
|
+
c = cls.new
|
49
|
+
expect_to_log { c.log }
|
50
|
+
end
|
51
|
+
|
52
|
+
it "installs in modules" do
|
53
|
+
mod = Module.new do
|
54
|
+
NRSER::Logger.install self
|
55
|
+
end
|
56
|
+
|
57
|
+
expect(mod.logger).to_not be MAIN.logger
|
58
|
+
expect(mod.logger.name).to match /\#\<Module/
|
59
|
+
|
60
|
+
expect_to_not_log { mod.send :info, "hey" }
|
61
|
+
|
62
|
+
mod.logger.on
|
63
|
+
|
64
|
+
expect_to_log { mod.send :info, "hey" }
|
65
|
+
end
|
66
|
+
|
67
|
+
it "installs in classes" do
|
68
|
+
cls = Class.new do
|
69
|
+
NRSER::Logger.install self
|
70
|
+
end
|
71
|
+
|
72
|
+
expect(cls.logger).to_not be MAIN.logger
|
73
|
+
expect(cls.logger.name).to match /\#\<Class/
|
74
|
+
|
75
|
+
c = cls.new
|
76
|
+
|
77
|
+
expect(c.logger).to be cls.logger
|
78
|
+
expect(c.logger.name).to match /\#\<Class/
|
79
|
+
|
80
|
+
expect_to_not_log { cls.send :info, "hey" }
|
81
|
+
expect_to_not_log { c.send :info, "hey" }
|
82
|
+
|
83
|
+
cls.logger.on
|
84
|
+
|
85
|
+
expect_to_log { cls.send :info, "hey" }
|
86
|
+
expect_to_log { c.send :info, "hey" }
|
87
|
+
|
88
|
+
expect_to_not_log { cls.send :debug, "hey" }
|
89
|
+
|
90
|
+
# @todo hmmm... this switches the log level for the entire class, not
|
91
|
+
# the instance...
|
92
|
+
c.logger.level = :debug
|
93
|
+
|
94
|
+
expect_to_log { cls.send :debug, "hey" }
|
95
|
+
expect_to_log { c.send :debug, "hey" }
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe 'NRSER::Logger.level_int' do
|
6
|
+
it "translates level ints, names and symbols" do
|
7
|
+
LOG_LEVELS.each do |int, (sym, name)|
|
8
|
+
expect( NRSER::Logger.level_int int ).to eq int
|
9
|
+
expect( NRSER::Logger.level_int sym ).to eq int
|
10
|
+
expect( NRSER::Logger.level_int name ).to eq int
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
it "pukes on bad a args" do
|
15
|
+
BAD_LOG_LEVELS.each do |arg|
|
16
|
+
expect {
|
17
|
+
NRSER::Logger.level_int arg
|
18
|
+
}.to raise_error ArgumentError
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe 'NRSER::Logger.level_name' do
|
6
|
+
|
7
|
+
it "translates level names, integers and symbols" do
|
8
|
+
LOG_LEVELS.each do |int, (sym, name)|
|
9
|
+
expect( NRSER::Logger.level_name name ).to eq name
|
10
|
+
expect( NRSER::Logger.level_name sym ).to eq name
|
11
|
+
expect( NRSER::Logger.level_name int ).to eq name
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
it "pukes on bad a args" do
|
16
|
+
BAD_LOG_LEVELS.each do |arg|
|
17
|
+
expect {
|
18
|
+
NRSER::Logger.level_name arg
|
19
|
+
}.to raise_error ArgumentError
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe 'NRSER::Logger.level_sym' do
|
6
|
+
it "translates level syms, names and symbols" do
|
7
|
+
LOG_LEVELS.each do |int, (sym, name)|
|
8
|
+
expect( NRSER::Logger.level_sym sym ).to eq sym
|
9
|
+
expect( NRSER::Logger.level_sym int ).to eq sym
|
10
|
+
expect( NRSER::Logger.level_sym name ).to eq sym
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
it "pukes on bad a args" do
|
15
|
+
BAD_LOG_LEVELS.each do |arg|
|
16
|
+
expect {
|
17
|
+
NRSER::Logger.level_sym arg
|
18
|
+
}.to raise_error ArgumentError
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
NRSER::Logger.install MAIN, on: true, say_hi: false
|
4
|
+
|
5
|
+
describe 'NRSER::Logger.send_log' do
|
6
|
+
it "works with blocks that yield msg strings" do
|
7
|
+
expect_to_log {
|
8
|
+
info {
|
9
|
+
"hey!"
|
10
|
+
}
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
it "works with blocks that yield values hashes" do
|
15
|
+
expect_to_log {
|
16
|
+
info {
|
17
|
+
{x: 'ex', y: 'why?'}
|
18
|
+
}
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
it "works with blocks that yield msg and values" do
|
23
|
+
expect_to_log {
|
24
|
+
info {
|
25
|
+
["hey!", {x: 'ex', y: 'why'}]
|
26
|
+
}
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
it "doesn't evaluate blocks unless they're going to be logged" do
|
31
|
+
evaled = false
|
32
|
+
|
33
|
+
expect_to_log {
|
34
|
+
info {
|
35
|
+
evaled = true
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
expect(evaled).to be true
|
40
|
+
|
41
|
+
evaled = false
|
42
|
+
|
43
|
+
logger.off {
|
44
|
+
expect_to_not_log {
|
45
|
+
info {
|
46
|
+
evaled = true
|
47
|
+
}
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
51
|
+
expect(evaled).to be false
|
52
|
+
|
53
|
+
logger.with_level :fatal do
|
54
|
+
expect_to_not_log {
|
55
|
+
info {
|
56
|
+
evaled = true
|
57
|
+
}
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
expect(evaled).to be false
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'NRSER::Logger.use' do
|
4
|
+
it "points to the source logger" do
|
5
|
+
module Source
|
6
|
+
NRSER::Logger.install self, on: true, say_hi: false
|
7
|
+
|
8
|
+
module Target
|
9
|
+
NRSER::Logger.use Source, self
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
expect_to_log { Source::Target.send :info, "here" }
|
14
|
+
expect(Source::Target.logger).to be Source.logger
|
15
|
+
end
|
16
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,2 +1,26 @@
|
|
1
|
+
require 'cmds'
|
2
|
+
|
1
3
|
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
2
4
|
require 'nrser'
|
5
|
+
require 'nrser/logger'
|
6
|
+
|
7
|
+
MAIN = self
|
8
|
+
|
9
|
+
LOG_LEVELS = {
|
10
|
+
Logger::DEBUG => [:debug, 'DEBUG'],
|
11
|
+
Logger::INFO => [:info, 'INFO'],
|
12
|
+
Logger::WARN => [:warn, 'WARN'],
|
13
|
+
Logger::ERROR => [:error, 'ERROR'],
|
14
|
+
Logger::FATAL => [:fatal, 'FATAL'],
|
15
|
+
Logger::UNKNOWN => [:unknown, 'UNKNOWN'],
|
16
|
+
}
|
17
|
+
|
18
|
+
BAD_LOG_LEVELS = [:blah, -1, 6, "BLAH"]
|
19
|
+
|
20
|
+
def expect_to_log &block
|
21
|
+
expect(&block).to output.to_stderr_from_any_process
|
22
|
+
end
|
23
|
+
|
24
|
+
def expect_to_not_log &block
|
25
|
+
expect(&block).to_not output.to_stderr_from_any_process
|
26
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nrser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.14
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- nrser
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-01-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,6 +52,34 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: yard
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: cmds
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
55
83
|
description:
|
56
84
|
email:
|
57
85
|
- neil@neilsouza.com
|
@@ -67,13 +95,25 @@ files:
|
|
67
95
|
- README.md
|
68
96
|
- Rakefile
|
69
97
|
- lib/nrser.rb
|
98
|
+
- lib/nrser/collection.rb
|
99
|
+
- lib/nrser/logger.rb
|
70
100
|
- lib/nrser/refinements.rb
|
71
101
|
- lib/nrser/version.rb
|
72
102
|
- nrser.gemspec
|
103
|
+
- spec/nrser/collection/each_spec.rb
|
104
|
+
- spec/nrser/collection/map_spec.rb
|
73
105
|
- spec/nrser/common_prefix_spec.rb
|
74
106
|
- spec/nrser/dedent_spec.rb
|
75
107
|
- spec/nrser/format_exception_spec.rb
|
76
108
|
- spec/nrser/indent_spec.rb
|
109
|
+
- spec/nrser/logger/dest_spec.rb
|
110
|
+
- spec/nrser/logger/die_spec.rb
|
111
|
+
- spec/nrser/logger/install_spec.rb
|
112
|
+
- spec/nrser/logger/level_int_spec.rb
|
113
|
+
- spec/nrser/logger/level_name_spec.rb
|
114
|
+
- spec/nrser/logger/level_sym_spec.rb
|
115
|
+
- spec/nrser/logger/send_log_spec.rb
|
116
|
+
- spec/nrser/logger/use_spec.rb
|
77
117
|
- spec/nrser/refinements/erb_spec.rb
|
78
118
|
- spec/nrser/refinements/format_exception_spec.rb
|
79
119
|
- spec/nrser/refinements/indent_spec.rb
|
@@ -108,10 +148,20 @@ signing_key:
|
|
108
148
|
specification_version: 4
|
109
149
|
summary: basic ruby utils i use in a lot of stuff.
|
110
150
|
test_files:
|
151
|
+
- spec/nrser/collection/each_spec.rb
|
152
|
+
- spec/nrser/collection/map_spec.rb
|
111
153
|
- spec/nrser/common_prefix_spec.rb
|
112
154
|
- spec/nrser/dedent_spec.rb
|
113
155
|
- spec/nrser/format_exception_spec.rb
|
114
156
|
- spec/nrser/indent_spec.rb
|
157
|
+
- spec/nrser/logger/dest_spec.rb
|
158
|
+
- spec/nrser/logger/die_spec.rb
|
159
|
+
- spec/nrser/logger/install_spec.rb
|
160
|
+
- spec/nrser/logger/level_int_spec.rb
|
161
|
+
- spec/nrser/logger/level_name_spec.rb
|
162
|
+
- spec/nrser/logger/level_sym_spec.rb
|
163
|
+
- spec/nrser/logger/send_log_spec.rb
|
164
|
+
- spec/nrser/logger/use_spec.rb
|
115
165
|
- spec/nrser/refinements/erb_spec.rb
|
116
166
|
- spec/nrser/refinements/format_exception_spec.rb
|
117
167
|
- spec/nrser/refinements/indent_spec.rb
|
@@ -120,3 +170,4 @@ test_files:
|
|
120
170
|
- spec/nrser/truncate_spec.rb
|
121
171
|
- spec/nrser_spec.rb
|
122
172
|
- spec/spec_helper.rb
|
173
|
+
has_rdoc:
|