Class: Amigo::SpecHelpers::EventPublishedMatcher

Inherits:
Object
  • Object
show all
Defined in:
lib/amigo/spec_helpers.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(eventname, expected_payload = []) ⇒ EventPublishedMatcher

Returns a new instance of EventPublishedMatcher.



47
48
49
50
51
52
# File 'lib/amigo/spec_helpers.rb', line 47

def initialize(eventname, expected_payload=[])
  @expected_events = [[eventname, expected_payload]]
  @recorded_events = []
  @missing         = []
  @matched         = []
end

Instance Attribute Details

#recorded_eventsObject (readonly)

Returns the value of attribute recorded_events.



45
46
47
# File 'lib/amigo/spec_helpers.rb', line 45

def recorded_events
  @recorded_events
end

Instance Method Details

#add_matched(topic, payload, event) ⇒ Object



144
145
146
# File 'lib/amigo/spec_helpers.rb', line 144

def add_matched(topic, payload, event)
  @matched << [topic, payload, event]
end

#add_missing(event, payload) ⇒ Object



148
149
150
# File 'lib/amigo/spec_helpers.rb', line 148

def add_missing(event, payload)
  @missing << [event, payload]
end

#and(another_eventname, *expected_payload) ⇒ Object



54
55
56
57
# File 'lib/amigo/spec_helpers.rb', line 54

def and(another_eventname, *expected_payload)
  @expected_events << [another_eventname, expected_payload]
  return self
end

#does_not_match?(given_proc) ⇒ Boolean

rubocop:disable Naming/PredicatePrefix

Returns:

  • (Boolean)


97
98
99
# File 'lib/amigo/spec_helpers.rb', line 97

def does_not_match?(given_proc)
  !matches?(given_proc, true)
end

#event_names_match?(expected, actual) ⇒ Boolean

Returns:

  • (Boolean)


132
133
134
135
136
137
# File 'lib/amigo/spec_helpers.rb', line 132

def event_names_match?(expected, actual)
  return true if expected.nil?
  return expected.matches?(actual) if expected.respond_to?(:matches?)
  return expected.match?(actual) if expected.respond_to?(:match?)
  return expected == actual
end

#failure_messageObject



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/amigo/spec_helpers.rb', line 152

def failure_message
  return "Error while publishing: %p" % [@error] if @error

  messages = []

  @missing.each do |event, payload|
    message = "expected a '%s' event to be fired" % [event]
    message << (" with a payload of %p" % [payload]) unless payload.nil?
    message << " but none was."

    messages << message
  end

  if @recorded_events.empty?
    messages << "No events were sent."
  else
    parts = @recorded_events.map(&:inspect)
    messages << ("The following events were recorded: %s" % [parts.join(", ")])
  end

  return messages.join("\n")
end

#failure_message_when_negatedObject



175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/amigo/spec_helpers.rb', line 175

def failure_message_when_negated
  messages = []
  @matched.each do |topic, payload, event|
    message = "expected a '#{topic || event.name}' event not to be fired"
    message << " with a payload of #{payload.inspect}" if payload
    message << " but one was"
    event.payload.any? && message << ": #{event.payload.inspect}"
    message << "."
    messages << message
  end

  return messages.join("\n")
end

#match_expected_events(negative_expectation) ⇒ Object



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/amigo/spec_helpers.rb', line 106

def match_expected_events(negative_expectation)
  @expected_events.each do |expected_event, expected_payload|
    if expected_event.nil? && !negative_expectation
      RSpec::Expectations.configuration.false_positives_handler.call(
        "Using the `publish` matcher without providing a specific " \
        "event name risks false positives, since `publish` " \
        "will match any event. Instead, provide the name " \
        "of the event you are matching against."\
        "This message can be suppressed by setting: " \
        "`RSpec::Expectations.configuration.on_potential_false" \
        "_positives = :nothing`",
      )
    end
    match = @recorded_events.find do |recorded|
      self.event_names_match?(expected_event, recorded.name) &&
        self.payloads_match?(expected_payload, recorded.payload)
    end

    if match
      self.add_matched(expected_event, expected_payload, match)
    else
      self.add_missing(expected_event, expected_payload)
    end
  end
end

#matches?(given_proc, negative_expectation = false) ⇒ Boolean

Returns:

  • (Boolean)


75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/amigo/spec_helpers.rb', line 75

def matches?(given_proc, negative_expectation=false)
  unless given_proc.respond_to?(:call)
    warn "publish matcher used with non-proc object #{given_proc.inspect}"
    return false
  end

  unless Amigo.synchronous_mode
    warn "publish matcher used without synchronous_mode (use :async test metadata)"
    return false
  end

  state = {on_error: self.method(:on_publish_error), subscribers: [self.method(:record_event)]}
  Amigo::SpecHelpers.snapshot_async_state(state) do
    given_proc.call
  end

  self.match_expected_events(negative_expectation)

  return @error.nil? && @missing.empty?
end

#on_publish_error(err) ⇒ Object

rubocop:enable Naming/PredicatePrefix



102
103
104
# File 'lib/amigo/spec_helpers.rb', line 102

def on_publish_error(err)
  @error = err
end

#payloads_match?(expected, actual) ⇒ Boolean

Returns:

  • (Boolean)


139
140
141
142
# File 'lib/amigo/spec_helpers.rb', line 139

def payloads_match?(expected, actual)
  return expected.matches?(actual) if expected.respond_to?(:matches?)
  return expected.nil? || expected.empty? || expected == actual
end

#record_event(event) ⇒ Object



66
67
68
69
# File 'lib/amigo/spec_helpers.rb', line 66

def record_event(event)
  Amigo.log nil, :debug, "recording_event", event: event
  @recorded_events << event
end

#supports_block_expectations?Boolean

Returns:

  • (Boolean)


71
72
73
# File 'lib/amigo/spec_helpers.rb', line 71

def supports_block_expectations?
  true
end

#with_payload(expected_payload) ⇒ Object

Raises:

  • (ArgumentError)


59
60
61
62
63
64
# File 'lib/amigo/spec_helpers.rb', line 59

def with_payload(expected_payload)
  raise ArgumentError, "expected payload must be an array or matcher" unless
    expected_payload.is_a?(Array) || expected_payload.respond_to?(:matches?)
  @expected_events.last[1] = expected_payload
  return self
end