Skip to content

Commit 3f02fb2

Browse files
authored
Merge pull request #21 from Katalam/prod-of
Add product of expectation
2 parents 7facc0a + 4f164e7 commit 3f02fb2

File tree

4 files changed

+124
-0
lines changed

4 files changed

+124
-0
lines changed

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,3 +108,16 @@ $$\sum\limits_n^k x * 2$$
108108
expect(2)->toBeSummationOf(fn (int $x) => $x * 2, from: 0, to: 1);
109109
expect(3)->not->toBeSummationOf(fn (int $x) => $x * 2, from: 0, to: 1);
110110
```
111+
112+
#### `toBeProdOf()`
113+
```php
114+
expect(6)->toBeProdOf([1, 2, 3]);
115+
expect(4)->not->toBeProdOf([2, 3]);
116+
```
117+
118+
#### `toBeProductOf()`
119+
$$\prod\limits_n^k x * 2$$
120+
```php
121+
expect(3715891200)->toBeProductOf(fn (int $x) => $x * 2, from: 1, to: 10);
122+
expect(1)->not->toBeProductOf(fn (int $x) => $x * 2, from: 1, to: 10);
123+
```

src/Expectation.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,4 +196,41 @@ public function toBeSummationOf(callable $step, int $from, int $to): PestExpecta
196196

197197
return expect($this->value === $sum)->toBeTrue("$this->value doesn't equal $sum");
198198
}
199+
200+
/**
201+
* @param array<int|float> $numbers
202+
* @return PestExpectation<TValue>
203+
*/
204+
public function toBeProdOf(array $numbers): PestExpectation
205+
{
206+
if ($numbers === []) {
207+
return expect($this->value === 0)->toBeTrue("$this->value doesn't equal 0");
208+
}
209+
210+
$prod = 1;
211+
212+
foreach ($numbers as $number) {
213+
expect($number)->toBeNumeric();
214+
215+
$prod *= $number;
216+
}
217+
218+
return expect($this->value === $prod)->toBeTrue("$this->value doesn't equal $prod");
219+
}
220+
221+
/**
222+
* @return PestExpectation<TValue>
223+
*/
224+
public function toBeProductOf(callable $step, int $from, int $to): PestExpectation
225+
{
226+
$product = 1;
227+
228+
foreach (range($from, $to) as $i) {
229+
$stepProd = $step($i);
230+
expect($stepProd)->toBeNumeric();
231+
$product *= $stepProd;
232+
}
233+
234+
return expect($this->value === $product)->toBeTrue("$this->value !== $product");
235+
}
199236
}

tests/toBeProdOf.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
use PHPUnit\Framework\ExpectationFailedException;
4+
5+
it('passes', function (int $prod, array $numbers): void {
6+
expect($prod)->toBeProdOf($numbers);
7+
})->with([
8+
[0, []],
9+
[0, [-1, 0, 1]],
10+
[36, [3, '3', 4]],
11+
[1024, [4, 4, 4, 4, 4]],
12+
[1680, [-4, -30, 14]],
13+
[15625, [5, 5, 5, 5, 5, 5]],
14+
[186624, [6, 6, 6, 6, 6, 6, 4]],
15+
[823543, [7, 7, 7, 7, 7, 7, 7, 1]],
16+
[134217728, [8, 8, 8, 8, 8, 8, 8, 8, 8]],
17+
[2711943423, [9, 9, 9, 9, 9, 9, 9, 9, 9, 7]],
18+
[100000000000, [10, 10, 10, 10, 10, 10, '10', 10, 10, 10, 10]],
19+
]);
20+
21+
it('passes not', function (array $numbers): void {
22+
expect(1)->not->toBeProdOf($numbers);
23+
})->with([
24+
[[2, 3]],
25+
[[1, 2, 3]],
26+
[[1, 2, 3, 4]],
27+
[[1, 2, 3, 4, 5]],
28+
]);
29+
30+
it('fails if not number on the list', function (): void {
31+
expect(0)->toBeProdOf([2, 1, 3, 'not number', 78, 99]);
32+
})->throws(ExpectationFailedException::class);
33+
34+
test('failures', function (): void {
35+
expect(1)->toBeProdOf([1, 2]);
36+
})->throws(ExpectationFailedException::class);
37+
38+
test('failures not', function (): void {
39+
expect(2)->not->toBeProdOf([2]);
40+
})->throws(ExpectationFailedException::class);

tests/toBeProductOf.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
use PHPUnit\Framework\ExpectationFailedException;
4+
5+
it('passes', function (int $prod, int $from, int $to, callable $step): void {
6+
expect($prod)->toBeProductOf($step, $from, $to);
7+
})->with([
8+
[0, -1, 0, fn (int $i): int => $i * 2],
9+
[0, 0, 0, fn (int $i): int => $i * 2],
10+
[3715891200, 1, 10, fn (int $i): int => $i * 2],
11+
[3715891200, 10, 1, fn (int $i): int => $i * 2],
12+
[362880, 2, 10, function (int $i): int {
13+
return $i - 1;
14+
}],
15+
]);
16+
17+
it('passes not', function (callable $step, int $from, int $to): void {
18+
expect(1)->not->toBeProductOf($step, $from, $to);
19+
})->with([
20+
[fn (int $i): int => $i * 2, 1, 10],
21+
[fn (int $i): int => $i * 2, 2, 20],
22+
]);
23+
24+
it('fails if step does not return a number', function (): void {
25+
expect(0)->toBeProductOf(fn (): string => 'not number', 0, 0);
26+
})->throws(ExpectationFailedException::class);
27+
28+
test('failures', function (): void {
29+
expect(1)->toBeProductOf(fn (int $i): int => $i * 2, 0, 1);
30+
})->throws(ExpectationFailedException::class);
31+
32+
test('failures not', function (): void {
33+
expect(2)->not->toBeProductOf(fn (int $i): int => $i * 2, 1, 1);
34+
})->throws(ExpectationFailedException::class);

0 commit comments

Comments
 (0)