nur-sery/nur_tests/mapper/base/MapperTest.php

184 lines
5.6 KiB
PHP

<?php
namespace nur\mapper\base;
use nur\b\ValueException;
use nur\mapper\base\impl\IdentMapToMapper;
use nur\mapper\base\impl\IdentReturnMapper;
use nur\mapper\base\impl\SofEofMapper;
use nur\t\TestCase;
class MapperTest extends TestCase {
const NUMBERS = [1, 2, 3, 4];
const DOUBLE = [2, 4, 6, 8];
const FIRST = [1, 2];
const LAST = [3, 4];
const LAST_DOUBLE = [6, 8];
const ASSOC = [1, "a" => "b", 2, "c" => "d"];
const STRINGS = ["a", "bb", "ccc", "dddd"];
const SPLIT = ["b", "b", "c", "cc", "dd", "dd"];
const SPLIT2 = ["<a>", "<bb>", "b", "-", "b", "<ccc>", "c", "-", "cc", "<dddd>", "dd", "-", "dd"];
function testReturn() {
$mapper = new IdentReturnMapper(self::NUMBERS);
self::assertSame(self::NUMBERS, iterator_to_array($mapper));
$mapper = new IdentReturnMapper(self::ASSOC);
self::assertSame(self::ASSOC, iterator_to_array($mapper));
$mapper = new class(self::NUMBERS) extends Mapper {
function mapper($item) {
return $item * 2;
}
};
self::assertSame(self::DOUBLE, iterator_to_array($mapper));
}
function testFilter() {
$mapper = new class(self::NUMBERS) extends Mapper {
function mapper($item) {
return $item <= 2 ? $item : null;
}
};
self::assertSame(self::FIRST, iterator_to_array($mapper));
$mapper = new class(self::NUMBERS) extends Mapper {
function mapper($item) {
return $item > 2 ? $item : null;
}
};
self::assertSame(self::LAST, iterator_to_array($mapper));
}
static function split($value): ?array {
$length = strlen($value);
if ($length < 2) return null;
$middle = intdiv($length, 2);
$first = substr($value, 0, $middle);
$last = substr($value, $middle);
return [$first, $last];
}
function testMapTo() {
$mapper = new IdentMapToMapper(self::NUMBERS);
self::assertSame(self::NUMBERS, iterator_to_array($mapper));
$mapper = new IdentMapToMapper(self::ASSOC);
self::assertSame(self::ASSOC, iterator_to_array($mapper));
$mapper = new class(self::NUMBERS) extends Mapper {
function mapper($item) {
$this->mapToValue($item * 2);
}
};
self::assertSame(self::DOUBLE, iterator_to_array($mapper));
$mapper = new class(self::NUMBERS) extends Mapper {
function mapper($item) {
// possible d'utiliser return (la valeur est ignorée)
return $item > 2 ? $this->mapToValue($item * 2) : $this->mapToNone();
}
};
self::assertSame(self::LAST_DOUBLE, iterator_to_array($mapper));
$mapper = new class(self::STRINGS) extends Mapper {
function mapper($item) {
return $this->mapTo(MapperTest::split($item));
}
};
self::assertSame(self::SPLIT, iterator_to_array($mapper));
$mapper = new class(self::STRINGS) extends Mapper {
function splitemup($value) {
$parts = MapperTest::split($value);
if ($parts !== null) {
yield $parts[0];
yield "-";
yield $parts[1];
}
}
function mapper($item) {
$this->mapToValue("<$item>");
$this->mapTo($this->splitemup($item));
}
};
self::assertSame(self::SPLIT2, iterator_to_array($mapper));
}
function testSofEof() {
self::assertSame(["a", "b"], iterator_to_array(new SofEofMapper(["a", "b"])));
self::assertSame(["<", "a", "b"], iterator_to_array(new class(["a", "b"]) extends SofEofMapper {
const MAP_SOF = true;
}));
self::assertSame(["a", "b", ">"], iterator_to_array(new class(["a", "b"]) extends SofEofMapper {
const MAP_EOF = true;
}));
self::assertSame(["<", "a", "b", ">"], iterator_to_array(new class(["a", "b"]) extends SofEofMapper {
const MAP_SOF = true;
const MAP_EOF = true;
}));
}
function testClose() {
$mapper1 = new class extends Mapper {
public $complete = false;
public function getIterator(): iterable {
yield from parent::getIterator();
$this->complete = true;
}
public $closed = false;
protected function teardown(): void {
parent::teardown();
$this->closed = true;
}
public function mapper($item) {
return $item;
}
};
$mapper2 = new class extends Mapper {
public $complete = false;
public function getIterator(): iterable {
yield from parent::getIterator();
$this->complete = true;
}
public $closed = false;
protected function teardown(): void {
parent::teardown();
$this->closed = true;
}
public function mapper($item) {
return $item;
}
};
$consumer = new class extends Consumer {
public $throw = true;
public function cook($item) {
if ($this->throw && $item >= 5) throw new ValueException("cinq");
return $item + 1;
}
};
$mapper1->complete = $mapper1->closed = false;
$mapper2->complete = $mapper2->closed = false;
$consumer->throw = true;
self::assertException(ValueException::class, [$consumer, "consume"], [1, 2, 3, 5, 6, 7], $mapper1, $mapper2);
self::assertFalse($mapper1->complete);
self::assertTrue($mapper1->closed);
self::assertFalse($mapper2->complete);
self::assertTrue($mapper2->closed);
$mapper1->complete = $mapper1->closed = false;
$mapper2->complete = $mapper2->closed = false;
$consumer->throw = false;
self::assertNotException([$consumer, "consume"], [1, 2, 3, 5, 6, 7], $mapper1, $mapper2);
self::assertTrue($mapper1->complete);
self::assertTrue($mapper1->closed);
self::assertTrue($mapper2->complete);
self::assertTrue($mapper2->closed);
}
}