require 'rubygems' require 'test/unit' require 'shoulda' require 'logger' require 'rr' require File.dirname(__FILE__) + '/../tagged_logger' class TestLogDevice attr_reader :last def write(msg); @last = msg; end def close; end; def to_s; @last || ""; end def inspect; to_s; end def clear; write(""); end end class TaggedLoggerTest < Test::Unit::TestCase include RR::Adapters::TestUnit context "@standard_logger with stub output @out1;" do setup do @out1 = TestLogDevice.new @standard_logger = Logger.new(@out1) @formatter = lambda {|severity, datetime, progname, msg| "#{msg}"} @standard_logger.formatter = @formatter end teardown do Kernel.class_eval do remove_method :logger end end should "be able to intialize with minimal effort" do TaggedLogger.init dont_allow(@out1).write assert Class.new.methods.include? "logger" assert_nothing_raised { Class.new.logger } end context "everything gets logged to @out1;" do setup do logger = @standard_logger TaggedLogger.rules do reset output_everything_to logger end end should " be possible to log by .logger.debug/info/warn/error/fatal()" do NewClass = Class.new obj = NewClass.new %w[debug info warn error fatal].each do |method| assert obj.logger.methods.include? method obj.logger.send(method.intern, method) assert_equal "#{obj.class}: #{method}\n", @out1.to_s end end context "class A and class B with logging;" do setup do module Foo def foo logger.info("foo") end end class A;include Foo; end class B;include Foo; end @a = A.new @b = B.new end should "be possible to replace tags for A, B classes with single tag TEST making rules for A and B obsolete" do TaggedLogger.rules do rename [A,B] => :TEST end @a.foo assert_equal "TEST: foo\n", @out1.to_s @out1.clear @b.foo assert_equal "TEST: foo\n", @out1.to_s end context "@logger2 with stub output @out2;" do setup do @out2 = TestLogDevice.new @logger2 = Logger.new(@out2) @logger2.formatter = @formatter end should "be possible to speialize logging for tag A by specifying another @logger2" do logger2 = @logger2 TaggedLogger.rules do output A => logger2 end @a.foo assert_equal "#{self.class}::A: foo\n", @out1.to_s assert_equal "#{self.class}::A: foo\n", @out2.to_s @out2.clear @b.foo assert_equal "#{self.class}::B: foo\n", @out1.to_s assert_equal "", @out2.to_s end should "be possible to speialize logging for tag A by providing block" do logger2 = @logger2 TaggedLogger.rules do output A do |level, tag, msg| logger2.send(level, msg) end end @a.foo assert_equal "#{self.class}::A: foo\n", @out1.to_s assert_equal "foo", @out2.to_s @out2.clear @b.foo assert_equal "#{self.class}::B: foo\n", @out1.to_s assert_equal "", @out2.to_s end should "be possible to replace tags for A, B classes with single tag TEST and specialize logging for it" do logger2 = @logger2 TaggedLogger.rules do rename [A, B] => :TEST output :TEST => logger2 end @a.foo assert_equal "TEST: foo\n", @out1.to_s assert_equal "TEST: foo\n", @out2.to_s @out1.clear @out2.clear @b.foo assert_equal "TEST: foo\n", @out1.to_s assert_equal "TEST: foo\n", @out2.to_s end should "use default tag equal to class name for class methods" do def A.bar logger.info "bar" end A.bar assert_equal "#{self.class}::A: bar\n", @out1.to_s end end end end end end