From af0aa5756654fc0d68824132970e72f463e3252c Mon Sep 17 00:00:00 2001 From: rd2 Date: Wed, 23 Aug 2023 10:58:07 -0300 Subject: [PATCH 1/3] Re-introduces msg & tag methods; +new trim method --- lib/oslg/oslog.rb | 192 ++++++++++++++++++++++++---------------- lib/oslg/version.rb | 2 +- spec/oslg_tests_spec.rb | 6 +- 3 files changed, 120 insertions(+), 80 deletions(-) diff --git a/lib/oslg/oslog.rb b/lib/oslg/oslog.rb index 04083cb..c4981cf 100644 --- a/lib/oslg/oslog.rb +++ b/lib/oslg/oslog.rb @@ -29,14 +29,35 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. module OSlg - DEBUG = 1 # e.g. for debugging e.g. "argument String? expecting Integer" - INFO = 2 # e.g. informative e.g. "success! no errors, no warnings" - WARN = 3 # e.g. warnings e.g. "partial success, see non-fatal warnings" - ERROR = 4 # e.g. erros e.g. "partial success, see non-fatal errors" - FATAL = 5 # e.g. failures e.g. "stopping! encountered fatal errors" + DEBUG = 1 # e.g. for debugging e.g. "argument String? expecting Integer" + INFO = 2 # e.g. informative e.g. "success! no errors, no warnings" + WARN = 3 # e.g. warnings e.g. "partial success, see non-fatal warnings" + ERROR = 4 # e.g. erros e.g. "partial success, see non-fatal errors" + FATAL = 5 # e.g. failures e.g. "stopping! encountered fatal errors" # each log is a Hash with keys :level (Integer) and :message (String) - @@logs = [] + @@logs = [] + + # preset strings matching log levels + @@tag = [ + "", # (empty string) + "DEBUG", # DEBUG + "INFO", # INFO + "WARNING", # WARNING + "ERROR", # ERROR + "FATAL" # FATAL + ].freeze + + # preset strings matching log status + @@msg = [ + "", # (empty string) + "Debugging ...", # DEBUG + "Success! No errors, no warnings", # INFO + "Partial success, raised non-fatal warnings", # WARNING + "Partial success, encountered non-fatal errors", # ERROR + "Failure, triggered fatal errors" # FATAL + ].freeze + @@level = INFO # initial log level @@status = 0 # initial status @@ -51,7 +72,7 @@ def logs ## # Returns current log level. # - # @return [Integer] DEBUG, INFO, WARN, ERROR or FATAL + # @return [DEBUG, INFO, WARN, ERROR, FATAL] log level def level @@level end @@ -59,7 +80,7 @@ def level ## # Returns current log status. # - # @return [Integer] DEBUG, INFO, WARN, ERROR or FATAL + # @return [0, DEBUG, INFO, WARN, ERROR, FATAL] log status def status @@status end @@ -67,7 +88,7 @@ def status ## # Returns whether current status is DEBUG. # - # @return [Bool] true if DEBUG + # @return [Bool] whether current log status is DEBUG def debug? @@status == DEBUG end @@ -75,7 +96,7 @@ def debug? ## # Returns whether current status is INFO. # - # @return [Bool] true if INFO + # @return [Bool] whether current log status is INFO def info? @@status == INFO end @@ -83,7 +104,7 @@ def info? ## # Returns whether current status is WARN. # - # @return [Bool] true if WARN + # @return [Bool] whether current log status is WARN def warn? @@status == WARN end @@ -91,7 +112,7 @@ def warn? ## # Returns whether current status is ERROR. # - # @return [Bool] true if ERROR + # @return [Bool] whether current log status is ERROR def error? @@status == ERROR end @@ -99,17 +120,68 @@ def error? ## # Returns whether current status is FATAL. # - # @return [Bool] true if FATAL + # @return [Bool] whether current log status is FATAL def fatal? @@status == FATAL end + ## + # Returns preset OSlg string that matches log level. + # + # @param lvl [#to_i] 0, DEBUG, INFO, WARN, ERROR or FATAL + # + # @return [String] preset OSlg tag (see @@tag) + def tag(lvl) + return "" unless lvl.respond_to?(:to_i) + + lvl = lvl.to_i + return "" if lvl < DEBUG + return "" if lvl > FATAL + + @@tag[lvl] + + end + + ## + # Returns preset OSlg message that matches log status. + # + # @param stat [Integer] 0, DEBUG, INFO, WARN, ERROR or FATAL + # + # @return [String] preset OSlg message (see @@msg) + def msg(stat) + return "" unless stat.respond_to?(:to_i) + + stat = stat.to_i + return "" if stat < DEBUG + return "" if stat > FATAL + + @@msg[stat] + end + + ## + # Converts object to String and trims if necessary. + # + # @param txt [#to_s] a stringable object + # @param length [#to_i] maximum return string length + # + # @return [String] a trimmed message string (empty unless stringable) + def trim(txt = "", length = 60) + length = 60 unless length.respond_to?(:to_i) + length = length.to_i + return "" unless txt.respond_to?(:to_s) + + txt = txt.to_s.strip + txt = txt[0...length] + " ..." if txt.length > length + + txt + end + ## # Resets level, if lvl (input) is within accepted range. # # @param lvl [#to_i] DEBUG, INFO, WARN, ERROR or FATAL # - # @return [Integer] updated/current level + # @return [DEBUG, INFO, WARN, ERROR, FATAL] updated/current level def reset(lvl = DEBUG) return @@level unless lvl.respond_to?(:to_i) @@ -129,13 +201,13 @@ def reset(lvl = DEBUG) # @example A user warning # log(WARN, "Surface area < 100cm2") # - # @return [Integer] updated/current status + # @return [DEBUG, INFO, WARN, ERROR, FATAL] updated/current status def log(lvl = DEBUG, message = "") return @@status unless lvl.respond_to?(:to_i) return @@status unless message.respond_to?(:to_s) lvl = lvl.to_i - message = message.to_s.strip + message = trim(message) return @@status if lvl < DEBUG return @@status if lvl > FATAL return @@status if lvl < @@level @@ -152,7 +224,7 @@ def log(lvl = DEBUG, message = "") # @param id [#to_s] 'invalid object' identifier # @param mth [#to_s] calling method identifier # @param ord [#to_i] calling method argument order number of obj (optional) - # @param lvl [#to_i] DEBUG, INFO, WARN, ERROR or FATAL + # @param lvl [#to_i] DEBUG, INFO, WARN, ERROR or FATAL (optional) # @param res what to return (optional) # # @example An invalid argument, logging a FATAL error, returning FALSE @@ -166,23 +238,18 @@ def invalid(id = "", mth = "", ord = 0, lvl = DEBUG, res = nil) return res unless ord.respond_to?(:to_i) return res unless lvl.respond_to?(:to_i) - id = id.to_s.strip - mth = mth.to_s.strip ord = ord.to_i lvl = lvl.to_i - - id = id[0...60] + " ..." if id.length > 60 + id = trim(id) + mth = trim(mth) return res if id.empty? - - mth = mth[0...60] + " ..." if mth.length > 60 return res if mth.empty? + return res if lvl < DEBUG + return res if lvl > FATAL msg = "Invalid '#{id}' " msg += "arg ##{ord} " if ord > 0 msg += "(#{mth})" - return res if lvl < DEBUG - return res if lvl > FATAL - log(lvl, msg) res @@ -197,7 +264,7 @@ def invalid(id = "", mth = "", ord = 0, lvl = DEBUG, res = nil) # @param obj the object to validate # @param cl [Class] target class # @param mth [#to_s] calling method identifier (optional) - # @param lvl [#to_i] DEBUG, INFO, WARN, ERROR or FATAL + # @param lvl [#to_i] DEBUG, INFO, WARN, ERROR or FATAL (optional) # @param res what to return (optional) # # @example A mismatched argument instance/class @@ -207,26 +274,20 @@ def invalid(id = "", mth = "", ord = 0, lvl = DEBUG, res = nil) # @return [nil] if user hasn't provided an object to return def mismatch(id = "", obj = nil, cl = nil, mth = "", lvl = DEBUG, res = nil) return res unless id.respond_to?(:to_s) + return res unless mth.respond_to?(:to_s) return res unless cl.is_a?(Class) return res if obj.is_a?(cl) - return res unless mth.respond_to?(:to_s) return res unless lvl.respond_to?(:to_i) - id = id.to_s.strip - mth = mth.to_s.strip lvl = lvl.to_i - - id = id[0...60] + " ..." if id.length > 60 + id = trim(id) + mth = trim(mth) return res if id.empty? - - mth = mth[0...60] + " ..." if mth.length > 60 return res if mth.empty? - - msg = "'#{id}' #{obj.class}? expecting #{cl} (#{mth})" return res if lvl < DEBUG return res if lvl > FATAL - log(lvl, msg) + log(lvl, "'#{id}' #{obj.class}? expecting #{cl} (#{mth})") res end @@ -239,7 +300,7 @@ def mismatch(id = "", obj = nil, cl = nil, mth = "", lvl = DEBUG, res = nil) # @param hsh [Hash] hash to validate # @param key missing key # @param mth [#to_s] calling method identifier - # @param lvl [#to_i] DEBUG, INFO, WARN, ERROR or FATAL + # @param lvl [#to_i] DEBUG, INFO, WARN, ERROR or FATAL (optional) # @param res what to return (optional) # # @example A missing Hash key @@ -254,21 +315,15 @@ def hashkey(id = "", hsh = {}, key = "", mth = "", lvl = DEBUG, res = nil) return res unless mth.respond_to?(:to_s) return res unless lvl.respond_to?(:to_i) - id = id.to_s.strip - mth = mth.to_s.strip lvl = lvl.to_i - - id = id[0...60] + " ..." if id.length > 60 + id = trim(id) + mth = trim(mth) return res if id.empty? - - mth = mth[0...60] + " ..." if mth.length > 60 return res if mth.empty? - - msg = "Missing '#{key}' key in '#{id}' Hash (#{mth})" return res if lvl < DEBUG return res if lvl > FATAL - log(lvl, msg) + log(lvl, "Missing '#{key}' key in '#{id}' Hash (#{mth})") res end @@ -278,7 +333,7 @@ def hashkey(id = "", hsh = {}, key = "", mth = "", lvl = DEBUG, res = nil) # # @param id [#to_s] empty object identifier # @param mth [#to_s] calling method identifier - # @param lvl [#to_i] DEBUG, INFO, WARN, ERROR or FATAL + # @param lvl [#to_i] DEBUG, INFO, WARN, ERROR or FATAL (optional) # @param res what to return (optional) # # @example An uninitialized variable, logging an ERROR, returning FALSE @@ -291,21 +346,15 @@ def empty(id = "", mth = "", lvl = DEBUG, res = nil) return res unless mth.respond_to?(:to_s) return res unless lvl.respond_to?(:to_i) - id = id.to_s.strip - mth = mth.to_s.strip lvl = lvl.to_i - - id = id[0...60] + " ..." if id.length > 60 + id = trim(id) + mth = trim(mth) return res if id.empty? - - mth = mth[0...60] + " ..." if mth.length > 60 return res if mth.empty? - - msg = "Empty '#{id}' (#{mth})" return res if lvl < DEBUG return res if lvl > FATAL - log(lvl, msg) + log(lvl, "Empty '#{id}' (#{mth})") res end @@ -315,7 +364,7 @@ def empty(id = "", mth = "", lvl = DEBUG, res = nil) # # @param id [#to_s] zero object identifier # @param mth [#to_s] calling method identifier - # @param lvl [#to_i] DEBUG, INFO, WARN, ERROR or FATAL + # @param lvl [#to_i] DEBUG, INFO, WARN, ERROR or FATAL (optional) # @param res what to return (optional) # # @example A near-zero variable @@ -328,22 +377,16 @@ def zero(id = "", mth = "", lvl = DEBUG, res = nil) return res unless mth.respond_to?(:to_s) return res unless lvl.respond_to?(:to_i) - id = id.to_s.strip - mth = mth.to_s.strip ord = ord.to_i lvl = lvl.to_i - - id = id[0...60] + " ..." if id.length > 60 + id = trim(id) + mth = trim(mth) return res if id.empty? - - mth = mth[0...60] + " ..." if mth.length > 60 return res if mth.empty? - - msg = "Zero '#{id}' (#{mth})" return res if lvl < DEBUG return res if lvl > FATAL - log(lvl, msg) + log(lvl, "Zero '#{id}' (#{mth})") res end @@ -366,22 +409,15 @@ def negative(id = "", mth = "", lvl = DEBUG, res = nil) return res unless mth.respond_to?(:to_s) return res unless lvl.respond_to?(:to_i) - id = id.to_s.strip - mth = mth.to_s.strip - ord = ord.to_i lvl = lvl.to_i - - id = id[0...60] + " ..." if id.length > 60 + id = trim(id) + mth = trim(mth) return res if id.empty? - - mth = mth[0...60] + " ..." if mth.length > 60 return res if mth.empty? - - msg = "Negative '#{id}' (#{mth})" return res if lvl < DEBUG return res if lvl > FATAL - log(lvl, msg) + log(lvl, "Negative '#{id}' (#{mth})") res end @@ -389,7 +425,7 @@ def negative(id = "", mth = "", lvl = DEBUG, res = nil) ## # Resets log status and entries. # - # @return [Integer] current level + # @return [Integer] current log level def clean! @@status = 0 @@logs = [] diff --git a/lib/oslg/version.rb b/lib/oslg/version.rb index 82bf87f..31ae157 100644 --- a/lib/oslg/version.rb +++ b/lib/oslg/version.rb @@ -29,5 +29,5 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. module OSlg - VERSION = "0.2.8".freeze # OSlg version + VERSION = "0.2.9".freeze # OSlg version end diff --git a/spec/oslg_tests_spec.rb b/spec/oslg_tests_spec.rb index a929caa..f2563ca 100644 --- a/spec/oslg_tests_spec.rb +++ b/spec/oslg_tests_spec.rb @@ -7,6 +7,9 @@ let(:mod2) { Module.new { extend OSlg } } it "can log within class instances" do + expect(cls1.tag(cls1::DEBUG)).to eq("DEBUG") + expect(cls1.msg(cls1::DEBUG)).to eq("Debugging ...") + expect(cls1.clean!).to eq(cls1::INFO) expect(cls1.log(cls1::INFO, "Logging within cls1")).to eq(cls1::INFO) @@ -86,7 +89,8 @@ expect(cls2.mismatch("x", "String", Array, array).nil?).to be(true) expect(cls2.logs.size).to eq(1) expect(cls2.logs.first.key?(:message)) - str = "'x' String? expecting Array ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12," + str = "'x' String? expecting Array ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ..." + expect(cls2.logs.first[:message].length).to eq(60 + 4) expect(cls2.logs.first[:message].include?(str)).to be(true) expect(cls2.clean!).to eq(cls2::DEBUG) From 8c372ea827be954e59415f0dba54657793f0c0c5 Mon Sep 17 00:00:00 2001 From: rd2 Date: Wed, 23 Aug 2023 11:58:59 -0300 Subject: [PATCH 2/3] Removes message length for log method --- lib/oslg/oslog.rb | 2 +- spec/oslg_tests_spec.rb | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/lib/oslg/oslog.rb b/lib/oslg/oslog.rb index c4981cf..3edbdf4 100644 --- a/lib/oslg/oslog.rb +++ b/lib/oslg/oslog.rb @@ -207,7 +207,7 @@ def log(lvl = DEBUG, message = "") return @@status unless message.respond_to?(:to_s) lvl = lvl.to_i - message = trim(message) + message = message.to_s return @@status if lvl < DEBUG return @@status if lvl > FATAL return @@status if lvl < @@level diff --git a/spec/oslg_tests_spec.rb b/spec/oslg_tests_spec.rb index f2563ca..f30cbde 100644 --- a/spec/oslg_tests_spec.rb +++ b/spec/oslg_tests_spec.rb @@ -86,12 +86,19 @@ expect(cls2.logs.empty?).to be(true) array = (1..60).to_a + l1 = 3 * 9 # "1, " + "2, " + "3, " ...+ "9, " + l2 = 4 * (59 - 9) # "10, " + "11, " + 12, ...+ "59, " + l3 = 2 # "60" + l4 = 2 # "[]" + expect(array.to_s.size).to eq(l1 + l2 + l3 + l4) expect(cls2.mismatch("x", "String", Array, array).nil?).to be(true) expect(cls2.logs.size).to eq(1) expect(cls2.logs.first.key?(:message)) - str = "'x' String? expecting Array ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ..." - expect(cls2.logs.first[:message].length).to eq(60 + 4) - expect(cls2.logs.first[:message].include?(str)).to be(true) + str1 = "'x' String? expecting Array " # 28 chars + str2 = "([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, ...)" + expect(str1.size + str2.size).to eq(28 + 60 + "(".length + " ...)".length) + expect(cls2.logs.first[:message].length).to eq(str1.size + str2.size) + expect(cls2.logs.first[:message]).to eq(str1 + str2) expect(cls2.clean!).to eq(cls2::DEBUG) expect(cls2.hashkey("x", {bar: 0}, "k", "foo")).to be(nil) From 3705f3bc38a5ac43ef86079da6e1f731a984c200 Mon Sep 17 00:00:00 2001 From: rd2 Date: Wed, 23 Aug 2023 12:20:20 -0300 Subject: [PATCH 3/3] Adds safeguard for trim method --- lib/oslg/oslog.rb | 2 +- spec/oslg_tests_spec.rb | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/oslg/oslog.rb b/lib/oslg/oslog.rb index 3edbdf4..ce49766 100644 --- a/lib/oslg/oslog.rb +++ b/lib/oslg/oslog.rb @@ -167,7 +167,7 @@ def msg(stat) # @return [String] a trimmed message string (empty unless stringable) def trim(txt = "", length = 60) length = 60 unless length.respond_to?(:to_i) - length = length.to_i + length = length.to_i if length.respond_to?(:to_i) return "" unless txt.respond_to?(:to_s) txt = txt.to_s.strip diff --git a/spec/oslg_tests_spec.rb b/spec/oslg_tests_spec.rb index f30cbde..a78bd02 100644 --- a/spec/oslg_tests_spec.rb +++ b/spec/oslg_tests_spec.rb @@ -7,6 +7,7 @@ let(:mod2) { Module.new { extend OSlg } } it "can log within class instances" do + expect(cls1.trim(nil).length).to eq(0) expect(cls1.tag(cls1::DEBUG)).to eq("DEBUG") expect(cls1.msg(cls1::DEBUG)).to eq("Debugging ...")