123456789_123456789_123456789_123456789_123456789_

Class: RSpec::Rails::Matchers::ActionCable::HaveBroadcastedTo Private

Do not use. This class is for internal use only.

Overview

rubocop: disable Metrics/ClassLength

Constant Summary

::RSpec::Matchers::BuiltIn::BaseMatcher - Inherited

UNDEFINED

Class Method Summary

::RSpec::Matchers::BuiltIn::BaseMatcher - Inherited

.matcher_name, .new,
.underscore

Borrowed from ActiveSupport.

Instance Attribute Summary

::RSpec::Matchers::BuiltIn::BaseMatcher - Inherited

#actual,
#diffable?

::RSpec::Rails::Matchers are not diffable by default.

#expected, #expects_call_stack_jump?, #matcher_name, #matcher_name=, #rescued_exception,
#supports_block_expectations?

Most matchers are value matchers (i.e. meant to work with ‘expect(value)`) rather than block matchers (i.e. meant to work with `expect { }`), so this defaults to false.

#supports_value_expectations?

::RSpec::Matchers::BuiltIn::BaseMatcher::StringEncodingFormatting - Included

Instance Method Summary

::RSpec::Matchers::BuiltIn::BaseMatcher - Inherited

#actual_formatted,
#description

Generates a description using EnglishPhrasing.

#expected_formatted,
#match_unless_raises

Used to wrap a block of code that will indicate failure by raising one of the named exceptions.

#matches?

Indicates if the match is successful.

#assert_ivars,
#present_ivars

:nocov:

::RSpec::Matchers::BuiltIn::BaseMatcher::DefaultFailureMessages - Included

#failure_message

Provides a good generic failure message.

#failure_message_when_negated

Provides a good generic negative failure message.

::RSpec::Matchers::BuiltIn::BaseMatcher::StringEncodingFormatting - Included

#format_encoding

Formats a String’s encoding as a human readable string.

::RSpec::Matchers::BuiltIn::BaseMatcher::HashFormatting - Included

#improve_hash_formatting

‘{ :a => 5, :b => 2 }.inspect` produces:

::RSpec::Matchers::Composable - Included

#&
#===

Delegates to ‘#matches?`.

#and

Creates a compound ‘and` expectation.

#description_of

Returns the description of the given object in a way that is aware of composed matchers.

#or

Creates a compound ‘or` expectation.

#values_match?

This provides a generic way to fuzzy-match an expected value against an actual value.

#|
#should_enumerate?

We should enumerate arrays as long as they are not recursive.

#surface_descriptions_in

Transforms the given data structure (typically a hash or array) into a new data structure that, when ‘#inspect` is called on it, will provide descriptions of any contained matchers rather than the normal #inspect output.

#unreadable_io?,
#with_matchers_cloned

Historically, a single matcher instance was only checked against a single value.

Instance Attribute Details

#supports_block_expectations?Boolean (readonly)

[ GitHub ]

  
# File 'rspec-rails/lib/rspec/rails/matchers/action_cable/have_broadcasted_to.rb', line 77

def supports_block_expectations?
  true
end

Instance Method Details

#at_least(count)

[ GitHub ]

  
# File 'rspec-rails/lib/rspec/rails/matchers/action_cable/have_broadcasted_to.rb', line 28

def at_least(count)
  set_expected_number(:at_least, count)
  self
end

#at_most(count)

[ GitHub ]

  
# File 'rspec-rails/lib/rspec/rails/matchers/action_cable/have_broadcasted_to.rb', line 33

def at_most(count)
  set_expected_number(:at_most, count)
  self
end

#base_message (private)

[ GitHub ]

  
# File 'rspec-rails/lib/rspec/rails/matchers/action_cable/have_broadcasted_to.rb', line 143

def base_message
  "#{message_expectation_modifier} #{@expected_number} messages to #{stream}".tap do |msg|
    msg << " with #{data_description(@data)}" unless @data.nil?
    msg << ", but broadcast #{@matching_msgs_count}"
  end
end

#check(messages) (private)

[ GitHub ]

  
# File 'rspec-rails/lib/rspec/rails/matchers/action_cable/have_broadcasted_to.rb', line 110

def check(messages)
  @matching_msgs, @unmatching_msgs = messages.partition do |msg|
    decoded = ActiveSupport::JSON.decode(msg)
    decoded = decoded.with_indifferent_access if decoded.is_a?(Hash)

    if @data.nil? || values_match?(@data, decoded)
      @block.call(decoded)
      true
    else
      false
    end
  end

  @matching_msgs_count = @matching_msgs.size

  case @expectation_type
  when :exactly then @expected_number == @matching_msgs_count
  when :at_most then @expected_number >= @matching_msgs_count
  when :at_least then @expected_number <= @matching_msgs_count
  end
end

#check_channel_presence (private)

Raises:

  • (ArgumentError)
[ GitHub ]

  
# File 'rspec-rails/lib/rspec/rails/matchers/action_cable/have_broadcasted_to.rb', line 162

def check_channel_presence
  return if @channel.present? && @channel.respond_to?(:channel_name)

  error_msg = "Broadcasting channel can't be inferred. Please, specify it with `from_channel`"
  raise ArgumentError, error_msg
end

#data_description(data) (private)

[ GitHub ]

  
# File 'rspec-rails/lib/rspec/rails/matchers/action_cable/have_broadcasted_to.rb', line 150

def data_description(data)
  if data.is_a?(RSpec::Matchers::Composable)
    data.description
  else
    data
  end
end

#exactly(count)

[ GitHub ]

  
# File 'rspec-rails/lib/rspec/rails/matchers/action_cable/have_broadcasted_to.rb', line 23

def exactly(count)
  set_expected_number(:exactly, count)
  self
end

#failure_message

[ GitHub ]

  
# File 'rspec-rails/lib/rspec/rails/matchers/action_cable/have_broadcasted_to.rb', line 54

def failure_message
  "expected to broadcast #{base_message}".tap do |msg|
    if @unmatching_msgs.any?
      msg << "\nBroadcasted messages to #{stream}:"
      @unmatching_msgs.each do |data|
        msg << "\n   #{data}"
      end
    end
  end
end

#failure_message_when_negated

[ GitHub ]

  
# File 'rspec-rails/lib/rspec/rails/matchers/action_cable/have_broadcasted_to.rb', line 65

def failure_message_when_negated
  "expected not to broadcast #{base_message}"
end

#from_channel(channel)

[ GitHub ]

  
# File 'rspec-rails/lib/rspec/rails/matchers/action_cable/have_broadcasted_to.rb', line 91

def from_channel(channel)
  @channel = channel
  self
end

#matches?(proc) ⇒ Boolean

Raises:

  • (ArgumentError)
[ GitHub ]

  
# File 'rspec-rails/lib/rspec/rails/matchers/action_cable/have_broadcasted_to.rb', line 81

def matches?(proc)
  raise ArgumentError, "have_broadcasted_to and broadcast_to only support block expectations" unless Proc === proc

  original_sent_messages_count = pubsub_adapter.broadcasts(stream).size
  proc.call
  in_block_messages = pubsub_adapter.broadcasts(stream).drop(original_sent_messages_count)

  check(in_block_messages)
end

#message_expectation_modifier

[ GitHub ]

  
# File 'rspec-rails/lib/rspec/rails/matchers/action_cable/have_broadcasted_to.rb', line 69

def message_expectation_modifier
  case @expectation_type
  when :exactly then "exactly"
  when :at_most then "at most"
  when :at_least then "at least"
  end
end

#once

[ GitHub ]

  
# File 'rspec-rails/lib/rspec/rails/matchers/action_cable/have_broadcasted_to.rb', line 42

def once
  exactly(:once)
end

#pubsub_adapter (private)

[ GitHub ]

  
# File 'rspec-rails/lib/rspec/rails/matchers/action_cable/have_broadcasted_to.rb', line 158

def pubsub_adapter
  ::ActionCable.server.pubsub
end

#set_expected_number(relativity, count) (private)

[ GitHub ]

  
# File 'rspec-rails/lib/rspec/rails/matchers/action_cable/have_broadcasted_to.rb', line 132

def set_expected_number(relativity, count)
  @expectation_type = relativity
  @expected_number =
    case count
    when :once then 1
    when :twice then 2
    when :thrice then 3
    else Integer(count)
    end
end

#stream (private)

[ GitHub ]

  
# File 'rspec-rails/lib/rspec/rails/matchers/action_cable/have_broadcasted_to.rb', line 98

def stream
  @stream ||= case @target
              when String
                @target
              when Symbol
                @target.to_s
              else
                check_channel_presence
                @channel.broadcasting_for(@target)
              end
end

#thrice

[ GitHub ]

  
# File 'rspec-rails/lib/rspec/rails/matchers/action_cable/have_broadcasted_to.rb', line 50

def thrice
  exactly(:thrice)
end

#times

[ GitHub ]

  
# File 'rspec-rails/lib/rspec/rails/matchers/action_cable/have_broadcasted_to.rb', line 38

def times
  self
end

#twice

[ GitHub ]

  
# File 'rspec-rails/lib/rspec/rails/matchers/action_cable/have_broadcasted_to.rb', line 46

def twice
  exactly(:twice)
end

#with(data = nil, &block)

[ GitHub ]

  
# File 'rspec-rails/lib/rspec/rails/matchers/action_cable/have_broadcasted_to.rb', line 16

def with(data = nil, &block)
  @data = data
  @data = @data.with_indifferent_access if @data.is_a?(Hash)
  @block = block if block
  self
end