diff --git a/lib/console/filter.rb b/lib/console/filter.rb index a14908f..a109972 100644 --- a/lib/console/filter.rb +++ b/lib/console/filter.rb @@ -40,6 +40,10 @@ def self.[] **levels const_set(:MINIMUM_LEVEL, minimum_level) const_set(:MAXIMUM_LEVEL, maximum_level) + # The default log level for instances of this filter class. + # Set to MINIMUM_LEVEL to allow all messages by default. + const_set(:DEFAULT_LEVEL, minimum_level) + levels.each do |name, level| const_set(name.to_s.upcase, level) @@ -206,6 +210,10 @@ def clear(subject) # Log a message with the given severity. # + # If the severity is not defined in this filter's LEVELS (e.g., when chaining + # filters with different severity levels), the message is passed through to the + # output without filtering. This allows custom filters to be composed together. + # # @parameter subject [Object] The subject of the log message. # @parameter arguments [Array] The arguments to log. # @parameter options [Hash] Additional options to pass to the output. @@ -215,7 +223,8 @@ def call(subject, *arguments, **options, &block) severity = options[:severity] || UNKNOWN level = self.class::LEVELS[severity] - if self.enabled?(subject, level) + # If the severity is unknown (level is nil), pass through to output without filtering: + if level.nil? || self.enabled?(subject, level) @output.call(subject, *arguments, **options, &block) end diff --git a/test/console/filter.rb b/test/console/filter.rb index f2bc566..82227d0 100644 --- a/test/console/filter.rb +++ b/test/console/filter.rb @@ -114,4 +114,44 @@ def before expect(result).to be_nil end end + + with "custom filter class" do + let(:custom_filter) {Console::Filter[noise: 0, stuff: 1, broken: 2]} + let(:custom_logger) {custom_filter.new(output)} + + it "can create a custom filter class" do + expect(custom_logger).to be_a(Console::Filter) + end + + it "has DEFAULT_LEVEL constant defined" do + expect(custom_filter::DEFAULT_LEVEL).to be_a(Integer) + end + + it "can log messages" do + custom_logger.broken(MySubject, "It's so janky") + expect(output).to be(:include?, "It's so janky") + end + + it "respects log levels" do + custom_logger.level = custom_filter::BROKEN + + custom_logger.noise(MySubject, "This is noise") + expect(output).to be(:empty?) + + custom_logger.broken(MySubject, "This is broken") + expect(output).to be(:include?, "This is broken") + end + + with "chained with another logger" do + let(:inner_logger) {Console::Logger.new(output)} + let(:chained_logger) {custom_filter.new(inner_logger, name: "Chained")} + + it "can log through chained loggers with different severities" do + # The custom logger has 'broken' severity which doesn't exist in the inner logger + # But it should pass through anyway + chained_logger.broken(MySubject, "It's so janky") + expect(output).to be(:include?, "It's so janky") + end + end + end end