Advertisement
Guest User

ImmutableTest.php

a guest
Sep 23rd, 2017
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 3.03 KB | None | 0 0
  1. <?php declare(strict_types=1);
  2.  
  3. namespace tests\unit;
  4.  
  5. use BadMethodCallException;
  6.  
  7. class Immutable extends \stdClass
  8. {
  9.     private $a;
  10.     private $b;
  11.     private $c;
  12.  
  13.     protected $set = false;
  14.  
  15.     /**
  16.      * Returns an instance clone that is now immutable, further calls to with<Name> wiill return clones
  17.      *
  18.      * @throws BadMethodCallException if already set
  19.      * @return Immutable
  20.      */
  21.     public function set(): Immutable
  22.     {
  23.         if ($this->set) {
  24.             throw new BadMethodCallException("Instance is already set!");
  25.         }
  26.         $new = clone $this;
  27.         $new->set = true;
  28.         return $new;
  29.     }
  30.  
  31.     public function isHard(): bool
  32.     {
  33.         return $this->set;
  34.     }
  35.  
  36.     public function withA(string $value): Immutable
  37.     {
  38.         $new = $this->set ? clone $this : $this;
  39.         $new->a = $value;
  40.         return $new;
  41.     }
  42.  
  43.     public function withB(string $value): Immutable
  44.     {
  45.         $new = $this->set ? clone $this : $this;
  46.         $new->b = $value;
  47.         return $new;
  48.     }
  49.  
  50.     public function withC(string $value): Immutable
  51.     {
  52.         $new = $this->set ? clone $this : $this;
  53.         $new->c = $value;
  54.         return $new;
  55.     }
  56.  
  57.     public function __toString()
  58.     {
  59.         return "{$this->a} : {$this->b} : {$this->c}";
  60.     }
  61. }
  62.  
  63. class ImmutableTest extends \PHPUnit\Framework\TestCase
  64. {
  65.     public function testWith()
  66.     {
  67.         $i = (new Immutable)->withA('a')->withB('b');
  68.         $this->assertEquals('a : b : ', "$i");
  69.  
  70.         $i2 = $i->withC('c');
  71.         $this->assertSame($i2, $i);
  72.         $this->assertEquals('a : b : c', "$i");
  73.         $this->assertEquals('a : b : c', "$i2");
  74.  
  75.         $i3 = $i2->set();
  76.         $this->assertNotSame($i3, $i2);
  77.         $this->assertEquals('a : b : c', "$i3");
  78.  
  79.         $i4 = $i3->withA('GG');
  80.         $this->assertNotSame($i4, $i3);
  81.         $this->assertEquals('GG : b : c', "$i4");
  82.     }
  83.  
  84.     public function testUndefined()
  85.     {
  86.         $this->expectException(BadMethodCallException::class);
  87.         $this->expectExceptionMessage("Instance is already set");
  88.         $c = (new Immutable)->set()->withA('a')->set();
  89.     }
  90.  
  91.     public function testThatDemonstrateUseCase()
  92.     {
  93.         // Semi builder pattern, but without needless instance generation
  94.         $blank = (new Immutable)
  95.             ->withA('Alpacca') // update $blank
  96.             ->withC('Whool') // update $blank
  97.             ->set() // $blank is from now on immutable
  98.         ;
  99.  
  100.         $one = $blank->withB('Cool');
  101.         $two = $blank->withB('Warm');
  102.  
  103.         $this->assertTrue($blank->isHard());
  104.         $this->assertTrue($one->isHard());
  105.         $this->assertTrue($two->isHard());
  106.  
  107.         $this->assertNotSame($blank, $one);
  108.         $this->assertNotSame($blank, $two);
  109.         $this->assertNotSame($one, $two);
  110.  
  111.         $this->assertEquals("Alpacca :  : Whool", $blank);
  112.         $this->assertEquals("Alpacca : Cool : Whool", $one);
  113.         $this->assertEquals("Alpacca : Warm : Whool", $two);
  114.     }
  115. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement