phpspec / prophecy

Highly opinionated mocking framework for PHP 5.3+
MIT License
8.53k stars 241 forks source link

Fixes comparison of identical closures #456

Closed larowlan closed 4 years ago

larowlan commented 4 years ago

https://github.com/phpspec/prophecy/pull/446 changed the way exact value token works with closures.

Before that change, comparisons of two identical closures passed. After it, they don't.

I feel that if the closure is identical, it should be treated as an exact.

In the meantime, we'll use IdenticalValueToken, but wanted to send this in case someone else hits it.

This was picked up with Drupal core's test-suite on the higher end of our upstream dependencies (phpunit 7.5.18, phpspec/prophecy 1.10.0)

https://www.drupal.org/node/3060/qa shows the fails coming on php 7.3 from the new 1.10.0 version.

The code in question that is failing in Drupal core:


/**
   * @covers ::prepareCallback
   *
   * @dataProvider providerPrepareCallback
   *
   * @param string|callable $unprepared_callback
   * @param callable $prepared_callback
   */
  public function testPrepareCallback($unprepared_callback, callable $prepared_callback) {
    $this->decoratedFormState->prepareCallback($unprepared_callback)
      ->willReturn($prepared_callback)
      ->shouldBeCalled();

    $this->assertSame($prepared_callback, $this->formStateDecoratorBase->prepareCallback($unprepared_callback));
  }

  /**
   * Provides data to self::testPrepareCallback().
   */
  public function providerPrepareCallback() {
    $function = 'sleep';
    $shorthand_form_method = '::submit()';
    $closure = function () {};
    $static_method_string = __METHOD__;
    $static_method_array = [__CLASS__, __FUNCTION__];
    $object_method_array = [$this, __FUNCTION__];

    return [
      // A shorthand form method is generally expanded to become a method on an
      // object.
      [$shorthand_form_method, $object_method_array],
      // Functions, closures, and static method calls generally remain the same.
      [$function, $function],
      [$closure, $closure],
      [$static_method_string, $static_method_string],
      [$static_method_array, $static_method_array],
    ];
  }

The test case [$closure, $closure] is the one failing.

larowlan commented 4 years ago

Closing as this is probably not the right approach, but hopefully if someone else hits this issue, they know to use Argument:is($closure) instead