184 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			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);
 | 
						|
  }
 | 
						|
}
 |