123456789_123456789_123456789_123456789_123456789_

Class: RSpec::Matchers::BuiltIn::ChangeDetails Private

Do not use. This class is for internal use only.
Relationships & Source Files
Inherits: Object
Defined in: rspec-expectations/lib/rspec/matchers/built_in/change.rb

Overview

Encapsulates the details of the before/after values.

Note that this class exposes the #actual_after value, to allow the matchers above to derive failure messages, etc from the value on demand as needed, but it intentionally does not expose the actual_before value. Some usages of the RSpec::Matchers#change matcher mutate a specific object returned by the value proc, which means that failure message snippets, etc, which are derived from the before value may not be accurate if they are lazily computed as needed. We must pre-compute them before applying the change in the RSpec::Matchers#expect block. To ensure that all RSpec::Matchers#change matchers do that properly, we do not expose the actual_before value. Instead, matchers must pass a block to #perform_change, which yields the actual_before value before applying the change.

Constant Summary

Class Method Summary

Instance Attribute Summary

Instance Method Summary

Instance Attribute Details

#actual_after (readonly)

[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/change.rb', line 353

attr_reader :actual_after

#changed?Boolean (readonly)

[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/change.rb', line 402

def changed?
  # Consider it changed if either:
  #
  # - The before/after values are unequal
  # - The before/after values have different hash values
  #
  # The latter case specifically handles the case when the value proc
  # returns the exact same object, but it has been mutated.
  #
  # Note that it is not sufficient to only check the hashes; it is
  # possible for two values to be unequal (and of different classes)
  # but to return the same hash value. Also, some objects may change
  # their hash after being compared with `==`/`!=`.
  @actual_before != @actual_after || @before_hash != @actual_hash
end

Instance Method Details

#actual_delta

[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/change.rb', line 418

def actual_delta
  @actual_after - @actual_before
end

#evaluate_value_proc (private)

[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/change.rb', line 424

def evaluate_value_proc
  @value_proc ? @value_proc.call : @receiver.__send__(@message)
end

#extract_value_block_snippet (private)

:nocov:

[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/change.rb', line 444

def extract_value_block_snippet
  return nil unless @value_proc
  Expectations::BlockSnippetExtractor.try_extracting_single_line_body_of(@value_proc, @matcher_name)
end

#message_notation(receiver, message) (private)

[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/change.rb', line 428

def message_notation(receiver, message)
  case receiver
  when Module
    "#{receiver}.#{message}"
  else
    "#{Support.class_of(receiver)}##{message}"
  end
end

#perform_change(event_proc) {|@actual_before| ... }

Yields:

  • (@actual_before)
[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/change.rb', line 389

def perform_change(event_proc)
  @actual_before = evaluate_value_proc
  @before_hash = @actual_before.hash
  yield @actual_before if block_given?

  return false unless Proc === event_proc
  event_proc.call

  @actual_after = evaluate_value_proc
  @actual_hash = @actual_after.hash
  true
end

#value_representation

[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/change.rb', line 378

def value_representation
  @value_representation ||=
    if @message
      "`#{message_notation(@receiver, @message)}`"
    elsif (value_block_snippet = extract_value_block_snippet)
      "`#{value_block_snippet}`"
    else
      'result'
    end
end