Module: ActiveSupport::Testing::EventReporterAssertions

Included in:
ActiveSupport::TestCase
Defined in:
lib/active_support/testing/event_reporter_assertions.rb

Overview

Provides test helpers for asserting on ActiveSupport::EventReporter events.

Defined Under Namespace

Modules: EventCollector

Instance Method Summary collapse

Instance Method Details

#assert_event_reported(name, payload: nil, tags: {}, &block) ⇒ Object

Asserts that the block causes an event with the given name to be reported to Rails.event.

Passes if the evaluated code in the yielded block reports a matching event.

assert_event_reported("user.created") do
  Rails.event.notify("user.created", { id: 123 })
end

To test further details about the reported event, you can specify payload and tag matchers.

assert_event_reported("user.created",
  payload: { id: 123, name: "John Doe" },
  tags: { request_id: /[0-9]+/ }
) do
  Rails.event.tagged(request_id: "123") do
    Rails.event.notify("user.created", { id: 123, name: "John Doe" })
  end
end

The matchers support partial matching - only the specified keys need to match.

assert_event_reported("user.created", payload: { id: 123 }) do
  Rails.event.notify("user.created", { id: 123, name: "John Doe" })
end


142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/active_support/testing/event_reporter_assertions.rb', line 142

def assert_event_reported(name, payload: nil, tags: {}, &block)
  events = EventCollector.record(&block)

  if events.empty?
    flunk("Expected an event to be reported, but there were no events reported.")
  elsif (event = events.find { |event| event.matches?(name, payload, tags) })
    assert(true)
    event.event_data
  else
    message = "Expected an event to be reported matching:\n  " \
      "name: #{name.inspect}\n  " \
      "payload: #{payload.inspect}\n  " \
      "tags: #{tags.inspect}\n" \
      "but none of the #{events.size} reported events matched:\n  " \
      "#{events.map(&:inspect).join("\n  ")}"
    flunk(message)
  end
end

#assert_events_reported(expected_events, &block) ⇒ Object

Asserts that the provided events were reported, regardless of order.

assert_events_reported([
  { name: "user.created", payload: { id: 123 } },
  { name: "email.sent", payload: { to: "[email protected]" } }
]) do
  create_user_and_send_welcome_email
end

Supports the same payload and tag matching as assert_event_reported.

assert_events_reported([
  {
    name: "process.started",
    payload: { id: 123 },
    tags: { request_id: /[0-9]+/ }
  },
  { name: "process.completed" }
]) do
  Rails.event.tagged(request_id: "456") do
    start_and_complete_process(123)
  end
end


184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/active_support/testing/event_reporter_assertions.rb', line 184

def assert_events_reported(expected_events, &block)
  events = EventCollector.record(&block)

  if events.empty? && expected_events.size > 0
    flunk("Expected #{expected_events.size} events to be reported, but there were no events reported.")
  end

  events_copy = events.dup

  expected_events.each do |expected_event|
    name = expected_event[:name]
    payload = expected_event[:payload] || {}
    tags = expected_event[:tags] || {}

    matching_event_index = events_copy.find_index { |event| event.matches?(name, payload, tags) }

    if matching_event_index
      events_copy.delete_at(matching_event_index)
    else
      message = "Expected an event to be reported matching:\n  " \
        "name: #{name.inspect}\n  " \
        "payload: #{payload.inspect}\n  " \
        "tags: #{tags.inspect}\n" \
        "but none of the #{events.size} reported events matched:\n  " \
        "#{events.map(&:inspect).join("\n  ")}"
      flunk(message)
    end
  end

  assert(true)
end

#assert_no_event_reported(name = nil, payload: {}, tags: {}, &block) ⇒ Object

Asserts that the block does not cause an event to be reported to Rails.event.

If no name is provided, passes if evaluated code in the yielded block reports no events.

assert_no_event_reported do
  service_that_does_not_report_events.perform
end

If a name is provided, passes if evaluated code in the yielded block reports no events with that name.

assert_no_event_reported("user.created") do
  service_that_does_not_report_events.perform
end


101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/active_support/testing/event_reporter_assertions.rb', line 101

def assert_no_event_reported(name = nil, payload: {}, tags: {}, &block)
  events = EventCollector.record(&block)

  if name.nil?
    assert_predicate(events, :empty?)
  else
    matching_event = events.find { |event| event.matches?(name, payload, tags) }
    if matching_event
      message = "Expected no '#{name}' event to be reported, but found:\n  " \
        "#{matching_event.inspect}"
      flunk(message)
    end
    assert(true)
  end
end

#with_debug_event_reporting(&block) ⇒ Object

Allows debug events to be reported to Rails.event for the duration of a given block.

with_debug_event_reporting do
  service_that_reports_debug_events.perform
end


222
223
224
# File 'lib/active_support/testing/event_reporter_assertions.rb', line 222

def with_debug_event_reporting(&block)
  ActiveSupport.event_reporter.with_debug(&block)
end