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

Inherits:
Object
  • Object
show all
Defined in:
lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-expectations-3.12.2/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 `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 `expect` block. To ensure that all `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 collapse

UNDEFINED =
Module.new.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(matcher_name, receiver = nil, message = nil, &block) ⇒ ChangeDetails

Returns a new instance of ChangeDetails.



357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
# File 'lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-expectations-3.12.2/lib/rspec/matchers/built_in/change.rb', line 357

def initialize(matcher_name, receiver=nil, message=nil, &block)
  if receiver && !message
    raise(
      ArgumentError,
      "`change` requires either an object and message " \
      "(`change(obj, :msg)`) or a block (`change { }`). " \
      "You passed an object but no message."
    )
  end

  @matcher_name = matcher_name
  @receiver = receiver
  @message = message
  @value_proc = block
  # TODO: temporary measure to mute warning of access to an initialized
  # instance variable when a deprecated implicit block expectation
  # syntax is used. This may be removed once `fail` is used, and the
  # matcher never issues this warning.
  @actual_after = UNDEFINED
end

Instance Attribute Details

#actual_afterObject (readonly)

Returns the value of attribute actual_after.



353
354
355
# File 'lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-expectations-3.12.2/lib/rspec/matchers/built_in/change.rb', line 353

def actual_after
  @actual_after
end

Instance Method Details

#actual_deltaObject



418
419
420
# File 'lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-expectations-3.12.2/lib/rspec/matchers/built_in/change.rb', line 418

def actual_delta
  @actual_after - @actual_before
end

#changed?Boolean

Returns:

  • (Boolean)


402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
# File 'lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-expectations-3.12.2/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

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

Yields:

  • (@actual_before)


389
390
391
392
393
394
395
396
397
398
399
400
# File 'lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-expectations-3.12.2/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_representationObject



378
379
380
381
382
383
384
385
386
387
# File 'lib/rubypitaya/app-template/vendor/bundle/ruby/3.1.0/gems/rspec-expectations-3.12.2/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