Class: RailsSemanticLogging::RSpec::HaveLoggedMessageMatcher
- Inherits:
-
Object
- Object
- RailsSemanticLogging::RSpec::HaveLoggedMessageMatcher
- Defined in:
- lib/rails_semantic_logging/rspec/matchers.rb
Overview
Block matcher that finds a specific log event by message and exposes both the raw SemanticLogger::Log and an optionally formatted version to a user block, so the test can make arbitrary assertions on the event.
Complementary to ‘log_semantic`:
-
‘log_semantic` is declarative (“was anything matching these criteria logged?”) and returns a boolean.
-
‘have_logged_message` is imperative — it finds the event, hands it over to the test, and lets the test assert whatever it needs.
Usage:
expect { logger.info("hello", key: "val") }.to ("hello")
expect { do_work }.to (/import/, :warn)
expect { service.call }
.to ("Completed").with_formatted_event { |event, formatted|
expect(event.payload).to include(order_id: order.id)
expect(formatted.dig("http", "status_code")).to eq(200)
}
The optional ‘with_formatted_event` block receives `(event, formatted)` where `formatted` is the JSON output of the chosen formatter parsed back with indifferent access. By default the gem’s Datadog formatter is used; pass any ‘SemanticLogger::Formatters::Base` subclass to override:
.with_formatted_event(SemanticLogger::Formatters::Json) { |event, formatted| ... }
Constant Summary collapse
- DEFAULT_FORMATTER =
::RailsSemanticLogging::Formatters::Datadog
Instance Attribute Summary collapse
-
#event_block ⇒ Object
readonly
Returns the value of attribute event_block.
Instance Method Summary collapse
- #failure_message ⇒ Object
- #failure_message_when_negated ⇒ Object
-
#initialize(expected, expected_level = nil) ⇒ HaveLoggedMessageMatcher
constructor
A new instance of HaveLoggedMessageMatcher.
- #matches?(block) ⇒ Boolean
- #supports_block_expectations? ⇒ Boolean
-
#with_formatted_event(formatter_class = nil, &block) ⇒ Object
Attach a block that receives the matched ‘(log_event, formatted)` pair.
Constructor Details
#initialize(expected, expected_level = nil) ⇒ HaveLoggedMessageMatcher
Returns a new instance of HaveLoggedMessageMatcher.
147 148 149 150 151 |
# File 'lib/rails_semantic_logging/rspec/matchers.rb', line 147 def initialize(expected, expected_level = nil) @expected_message = expected @expected_level = expected_level @formatter_class = DEFAULT_FORMATTER end |
Instance Attribute Details
#event_block ⇒ Object (readonly)
Returns the value of attribute event_block.
143 144 145 |
# File 'lib/rails_semantic_logging/rspec/matchers.rb', line 143 def event_block @event_block end |
Instance Method Details
#failure_message ⇒ Object
189 190 191 192 193 194 195 196 |
# File 'lib/rails_semantic_logging/rspec/matchers.rb', line 189 def return @error. if @error if @log_event && @expected_level && @log_event.level != @expected_level return "expected log level #{@expected_level.inspect}, got #{@log_event.level.inspect}" end "expected block to log a message matching #{@expected_message.inspect}" end |
#failure_message_when_negated ⇒ Object
198 199 200 |
# File 'lib/rails_semantic_logging/rspec/matchers.rb', line 198 def "expected block NOT to log a message matching #{@expected_message.inspect}, but a matching event was emitted" end |
#matches?(block) ⇒ Boolean
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/rails_semantic_logging/rspec/matchers.rb', line 153 def matches?(block) # Capture the live appender BEFORE we attach our test appender. The # Datadog formatter reads `logger.host` on the appender it receives, so # the formatter call later on needs a real one (any subscriber will do). @live_appender = ::SemanticLogger.appenders.first @log_event = capture_first_matching_event(block) return false unless @log_event return false if @expected_level && @log_event.level != @expected_level @event_block&.call(@log_event, formatted) true rescue ::RSpec::Expectations::ExpectationNotMetError => e @error = e false end |
#supports_block_expectations? ⇒ Boolean
169 170 171 |
# File 'lib/rails_semantic_logging/rspec/matchers.rb', line 169 def supports_block_expectations? true end |
#with_formatted_event(formatter_class = nil, &block) ⇒ Object
Attach a block that receives the matched ‘(log_event, formatted)` pair. `formatted` is the JSON output of the configured formatter, parsed back with `HashWithIndifferentAccess` so callers can navigate the structure with either string or symbol keys.
177 178 179 180 181 182 183 184 185 186 187 |
# File 'lib/rails_semantic_logging/rspec/matchers.rb', line 177 def with_formatted_event(formatter_class = nil, &block) raise ArgumentError, 'block is required' unless block if formatter_class && !(formatter_class < ::SemanticLogger::Formatters::Base) raise ArgumentError, "formatter must inherit from SemanticLogger::Formatters::Base, got #{formatter_class.inspect}" end @formatter_class = formatter_class if formatter_class @event_block = block self end |