You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
347 lines
8.2 KiB
347 lines
8.2 KiB
<?php |
|
|
|
namespace React\Promise; |
|
|
|
class FunctionReduceTest extends TestCase |
|
{ |
|
protected function plus() |
|
{ |
|
return function ($sum, $val) { |
|
return $sum + $val; |
|
}; |
|
} |
|
|
|
protected function append() |
|
{ |
|
return function ($sum, $val) { |
|
return $sum . $val; |
|
}; |
|
} |
|
|
|
/** @test */ |
|
public function shouldReduceValuesWithoutInitialValue() |
|
{ |
|
$mock = $this->createCallableMock(); |
|
$mock |
|
->expects($this->once()) |
|
->method('__invoke') |
|
->with($this->identicalTo(6)); |
|
|
|
reduce( |
|
[1, 2, 3], |
|
$this->plus() |
|
)->then($mock); |
|
} |
|
|
|
/** @test */ |
|
public function shouldReduceValuesWithInitialValue() |
|
{ |
|
$mock = $this->createCallableMock(); |
|
$mock |
|
->expects($this->once()) |
|
->method('__invoke') |
|
->with($this->identicalTo(7)); |
|
|
|
reduce( |
|
[1, 2, 3], |
|
$this->plus(), |
|
1 |
|
)->then($mock); |
|
} |
|
|
|
/** @test */ |
|
public function shouldReduceValuesWithInitialPromise() |
|
{ |
|
$mock = $this->createCallableMock(); |
|
$mock |
|
->expects($this->once()) |
|
->method('__invoke') |
|
->with($this->identicalTo(7)); |
|
|
|
reduce( |
|
[1, 2, 3], |
|
$this->plus(), |
|
resolve(1) |
|
)->then($mock); |
|
} |
|
|
|
/** @test */ |
|
public function shouldReducePromisedValuesWithoutInitialValue() |
|
{ |
|
$mock = $this->createCallableMock(); |
|
$mock |
|
->expects($this->once()) |
|
->method('__invoke') |
|
->with($this->identicalTo(6)); |
|
|
|
reduce( |
|
[resolve(1), resolve(2), resolve(3)], |
|
$this->plus() |
|
)->then($mock); |
|
} |
|
|
|
/** @test */ |
|
public function shouldReducePromisedValuesWithInitialValue() |
|
{ |
|
$mock = $this->createCallableMock(); |
|
$mock |
|
->expects($this->once()) |
|
->method('__invoke') |
|
->with($this->identicalTo(7)); |
|
|
|
reduce( |
|
[resolve(1), resolve(2), resolve(3)], |
|
$this->plus(), |
|
1 |
|
)->then($mock); |
|
} |
|
|
|
/** @test */ |
|
public function shouldReducePromisedValuesWithInitialPromise() |
|
{ |
|
$mock = $this->createCallableMock(); |
|
$mock |
|
->expects($this->once()) |
|
->method('__invoke') |
|
->with($this->identicalTo(7)); |
|
|
|
reduce( |
|
[resolve(1), resolve(2), resolve(3)], |
|
$this->plus(), |
|
resolve(1) |
|
)->then($mock); |
|
} |
|
|
|
/** @test */ |
|
public function shouldReduceEmptyInputWithInitialValue() |
|
{ |
|
$mock = $this->createCallableMock(); |
|
$mock |
|
->expects($this->once()) |
|
->method('__invoke') |
|
->with($this->identicalTo(1)); |
|
|
|
reduce( |
|
[], |
|
$this->plus(), |
|
1 |
|
)->then($mock); |
|
} |
|
|
|
/** @test */ |
|
public function shouldReduceEmptyInputWithInitialPromise() |
|
{ |
|
$mock = $this->createCallableMock(); |
|
$mock |
|
->expects($this->once()) |
|
->method('__invoke') |
|
->with($this->identicalTo(1)); |
|
|
|
reduce( |
|
[], |
|
$this->plus(), |
|
resolve(1) |
|
)->then($mock); |
|
} |
|
|
|
/** @test */ |
|
public function shouldRejectWhenInputContainsRejection() |
|
{ |
|
$mock = $this->createCallableMock(); |
|
$mock |
|
->expects($this->once()) |
|
->method('__invoke') |
|
->with($this->identicalTo(2)); |
|
|
|
reduce( |
|
[resolve(1), reject(2), resolve(3)], |
|
$this->plus(), |
|
resolve(1) |
|
)->then($this->expectCallableNever(), $mock); |
|
} |
|
|
|
/** @test */ |
|
public function shouldResolveWithNullWhenInputIsEmptyAndNoInitialValueOrPromiseProvided() |
|
{ |
|
// Note: this is different from when.js's behavior! |
|
// In when.reduce(), this rejects with a TypeError exception (following |
|
// JavaScript's [].reduce behavior. |
|
// We're following PHP's array_reduce behavior and resolve with NULL. |
|
$mock = $this->createCallableMock(); |
|
$mock |
|
->expects($this->once()) |
|
->method('__invoke') |
|
->with($this->identicalTo(null)); |
|
|
|
reduce( |
|
[], |
|
$this->plus() |
|
)->then($mock); |
|
} |
|
|
|
/** @test */ |
|
public function shouldAllowSparseArrayInputWithoutInitialValue() |
|
{ |
|
$mock = $this->createCallableMock(); |
|
$mock |
|
->expects($this->once()) |
|
->method('__invoke') |
|
->with($this->identicalTo(3)); |
|
|
|
reduce( |
|
[null, null, 1, null, 1, 1], |
|
$this->plus() |
|
)->then($mock); |
|
} |
|
|
|
/** @test */ |
|
public function shouldAllowSparseArrayInputWithInitialValue() |
|
{ |
|
$mock = $this->createCallableMock(); |
|
$mock |
|
->expects($this->once()) |
|
->method('__invoke') |
|
->with($this->identicalTo(4)); |
|
|
|
reduce( |
|
[null, null, 1, null, 1, 1], |
|
$this->plus(), |
|
1 |
|
)->then($mock); |
|
} |
|
|
|
/** @test */ |
|
public function shouldReduceInInputOrder() |
|
{ |
|
$mock = $this->createCallableMock(); |
|
$mock |
|
->expects($this->once()) |
|
->method('__invoke') |
|
->with($this->identicalTo('123')); |
|
|
|
reduce( |
|
[1, 2, 3], |
|
$this->append(), |
|
'' |
|
)->then($mock); |
|
} |
|
|
|
/** @test */ |
|
public function shouldAcceptAPromiseForAnArray() |
|
{ |
|
$mock = $this->createCallableMock(); |
|
$mock |
|
->expects($this->once()) |
|
->method('__invoke') |
|
->with($this->identicalTo('123')); |
|
|
|
reduce( |
|
resolve([1, 2, 3]), |
|
$this->append(), |
|
'' |
|
)->then($mock); |
|
} |
|
|
|
/** @test */ |
|
public function shouldResolveToInitialValueWhenInputPromiseDoesNotResolveToAnArray() |
|
{ |
|
$mock = $this->createCallableMock(); |
|
$mock |
|
->expects($this->once()) |
|
->method('__invoke') |
|
->with($this->identicalTo(1)); |
|
|
|
reduce( |
|
resolve(1), |
|
$this->plus(), |
|
1 |
|
)->then($mock); |
|
} |
|
|
|
/** @test */ |
|
public function shouldProvideCorrectBasisValue() |
|
{ |
|
$insertIntoArray = function ($arr, $val, $i) { |
|
$arr[$i] = $val; |
|
|
|
return $arr; |
|
}; |
|
|
|
$d1 = new Deferred(); |
|
$d2 = new Deferred(); |
|
$d3 = new Deferred(); |
|
|
|
$mock = $this->createCallableMock(); |
|
$mock |
|
->expects($this->once()) |
|
->method('__invoke') |
|
->with($this->identicalTo([1, 2, 3])); |
|
|
|
reduce( |
|
[$d1->promise(), $d2->promise(), $d3->promise()], |
|
$insertIntoArray, |
|
[] |
|
)->then($mock); |
|
|
|
$d3->resolve(3); |
|
$d1->resolve(1); |
|
$d2->resolve(2); |
|
} |
|
|
|
/** @test */ |
|
public function shouldRejectWhenInputPromiseRejects() |
|
{ |
|
$mock = $this->createCallableMock(); |
|
$mock |
|
->expects($this->once()) |
|
->method('__invoke') |
|
->with($this->identicalTo(null)); |
|
|
|
reduce( |
|
reject(), |
|
$this->plus(), |
|
1 |
|
)->then($this->expectCallableNever(), $mock); |
|
} |
|
|
|
/** @test */ |
|
public function shouldCancelInputPromise() |
|
{ |
|
$mock = $this |
|
->getMockBuilder('React\Promise\CancellablePromiseInterface') |
|
->getMock(); |
|
$mock |
|
->expects($this->once()) |
|
->method('cancel'); |
|
|
|
reduce( |
|
$mock, |
|
$this->plus(), |
|
1 |
|
)->cancel(); |
|
} |
|
|
|
/** @test */ |
|
public function shouldCancelInputArrayPromises() |
|
{ |
|
$mock1 = $this |
|
->getMockBuilder('React\Promise\CancellablePromiseInterface') |
|
->getMock(); |
|
$mock1 |
|
->expects($this->once()) |
|
->method('cancel'); |
|
|
|
$mock2 = $this |
|
->getMockBuilder('React\Promise\CancellablePromiseInterface') |
|
->getMock(); |
|
$mock2 |
|
->expects($this->once()) |
|
->method('cancel'); |
|
|
|
reduce( |
|
[$mock1, $mock2], |
|
$this->plus(), |
|
1 |
|
)->cancel(); |
|
} |
|
}
|
|
|