daikon-cqrs /
data-structure
| 1 | <?php declare(strict_types=1); |
||
| 2 | /** |
||
| 3 | * This file is part of the daikon-cqrs/data-structure project. |
||
| 4 | * |
||
| 5 | * For the full copyright and license information, please view the LICENSE |
||
| 6 | * file that was distributed with this source code. |
||
| 7 | */ |
||
| 8 | |||
| 9 | namespace Daikon\Tests\DataStructure; |
||
| 10 | |||
| 11 | use Daikon\Interop\InvalidArgumentException; |
||
| 12 | use Daikon\Tests\DataStructure\Fixture\PlainMap; |
||
| 13 | use DateTime; |
||
| 14 | use PHPUnit\Framework\TestCase; |
||
| 15 | use stdClass; |
||
| 16 | |||
| 17 | final class MapTest extends TestCase |
||
| 18 | { |
||
| 19 | 1 | public function testConstructWithoutParams(): void |
|
| 20 | { |
||
| 21 | 1 | $this->assertInstanceOf(PlainMap::class, new PlainMap); |
|
| 22 | 1 | } |
|
| 23 | |||
| 24 | 1 | public function testConstructWithParams(): void |
|
| 25 | { |
||
| 26 | 1 | $map = new PlainMap(['k' => 'v']); |
|
| 27 | 1 | $this->assertCount(1, $map); |
|
| 28 | 1 | } |
|
| 29 | |||
| 30 | 1 | public function testConstructWithObjects(): void |
|
| 31 | { |
||
| 32 | 1 | $this->expectException(InvalidArgumentException::class); |
|
| 33 | 1 | $this->expectExceptionCode(32); |
|
| 34 | 1 | $this->expectExceptionMessage( |
|
| 35 | "Invalid value type given to 'Daikon\Tests\DataStructure\Fixture\PlainMap', ". |
||
| 36 | 1 | "expected scalar or array but was given 'DateTime'." |
|
| 37 | ); |
||
| 38 | 1 | new PlainMap(['a1337' => new DateTime]); |
|
| 39 | } |
||
| 40 | |||
| 41 | 1 | public function testConstructWithIntegerKey(): void |
|
| 42 | { |
||
| 43 | 1 | $this->expectException(InvalidArgumentException::class); |
|
| 44 | 1 | $this->expectExceptionCode(16); |
|
| 45 | 1 | $this->expectExceptionMessage('Key must be a valid string.'); |
|
| 46 | 1 | new PlainMap([0 => 'v0']); |
|
| 47 | } |
||
| 48 | |||
| 49 | 1 | public function testKeys(): void |
|
| 50 | { |
||
| 51 | 1 | $map = new PlainMap(['k0' => 'v0', 'k1' => 1]); |
|
| 52 | 1 | $this->assertSame(['k0', 'k1'], $map->keys()); |
|
| 53 | 1 | } |
|
| 54 | |||
| 55 | 1 | public function testEmpty(): void |
|
| 56 | { |
||
| 57 | 1 | $map = new PlainMap(['k0' => 'v0', 'k1' => 1]); |
|
| 58 | 1 | $empty = $map->empty(); |
|
| 59 | 1 | $this->assertNotSame($map, $empty); |
|
| 60 | 1 | $this->assertCount(0, $empty); |
|
| 61 | 1 | $this->assertTrue($empty->isEmpty()); |
|
| 62 | 1 | } |
|
| 63 | |||
| 64 | 1 | public function testHas(): void |
|
| 65 | { |
||
| 66 | 1 | $map = new PlainMap(['k0' => 'v0', 'k1' => 'v1']); |
|
| 67 | 1 | $this->assertTrue($map->has('k0')); |
|
| 68 | 1 | $this->assertTrue($map->has('k1')); |
|
| 69 | 1 | $this->assertFalse($map->has('K0')); |
|
| 70 | 1 | $this->assertFalse($map->has('K1')); |
|
| 71 | 1 | } |
|
| 72 | |||
| 73 | 1 | public function testGet(): void |
|
| 74 | { |
||
| 75 | 1 | $map = new PlainMap(['k0' => 'v0', 'k1' => 1]); |
|
| 76 | 1 | $this->assertSame('v0', $map->get('k0')); |
|
| 77 | 1 | $this->assertSame(1, $map->get('k1')); |
|
| 78 | 1 | } |
|
| 79 | |||
| 80 | 1 | public function testGetWithDefault(): void |
|
| 81 | { |
||
| 82 | 1 | $map = new PlainMap(['k0' => 'v0', 'k1' => 'v1']); |
|
| 83 | 1 | $this->assertSame('y', $map->get('x', 'y')); |
|
| 84 | 1 | } |
|
| 85 | |||
| 86 | 1 | public function testGetWithNullDefault(): void |
|
| 87 | { |
||
| 88 | 1 | $map = new PlainMap(['k0' => 'v0']); |
|
| 89 | 1 | $this->assertNull($map->get('x', null)); |
|
| 90 | 1 | } |
|
| 91 | |||
| 92 | 1 | public function testGetWithInvalidDefault(): void |
|
| 93 | { |
||
| 94 | 1 | $map = new PlainMap(['k0' => 'v0']); |
|
| 95 | 1 | $this->expectException(InvalidArgumentException::class); |
|
| 96 | 1 | $this->expectExceptionCode(32); |
|
| 97 | 1 | $this->expectExceptionMessage( |
|
| 98 | "Invalid value type given to 'Daikon\Tests\DataStructure\Fixture\PlainMap', ". |
||
| 99 | 1 | "expected scalar or array but was given 'stdClass'." |
|
| 100 | ); |
||
| 101 | 1 | $map->get('x', new stdClass); |
|
| 102 | } |
||
| 103 | |||
| 104 | 1 | public function testGetWithNoDefault(): void |
|
| 105 | { |
||
| 106 | 1 | $map = new PlainMap(['k0' => 'v0']); |
|
| 107 | 1 | $this->expectException(InvalidArgumentException::class); |
|
| 108 | 1 | $this->expectExceptionCode(217); |
|
| 109 | 1 | $this->expectExceptionMessage("Key 'x' not found and no default provided."); |
|
| 110 | 1 | $map->x; |
|
|
0 ignored issues
–
show
Bug
Best Practice
introduced
by
Loading history...
|
|||
| 111 | } |
||
| 112 | |||
| 113 | 1 | public function testGetThrowsForInternalProperties(): void |
|
| 114 | { |
||
| 115 | 1 | $map = new PlainMap(['k0' => 'v1']); |
|
| 116 | 1 | $this->expectException(InvalidArgumentException::class); |
|
| 117 | 1 | $this->expectExceptionCode(217); |
|
| 118 | 1 | $map->validTypes; |
|
|
0 ignored issues
–
show
The property
validTypes does not exist on Daikon\Tests\DataStructure\Fixture\PlainMap. Since you implemented __get, consider adding a @property annotation.
Loading history...
|
|||
| 119 | } |
||
| 120 | |||
| 121 | 1 | public function testWith(): void |
|
| 122 | { |
||
| 123 | 1 | $map = new PlainMap(['k0' => 'v0']); |
|
| 124 | 1 | $unwrappedMap = $map->with('k1', 'v1')->unwrap(); |
|
| 125 | 1 | $this->assertSame('v0', $unwrappedMap['k0']); |
|
| 126 | 1 | $this->assertSame('v1', $unwrappedMap['k1']); |
|
| 127 | 1 | $this->assertCount(2, $unwrappedMap); |
|
| 128 | 1 | } |
|
| 129 | |||
| 130 | 1 | public function testWithFailsOnUnacceptableType(): void |
|
| 131 | { |
||
| 132 | 1 | $map = new PlainMap(['k0' => 'v0']); |
|
| 133 | 1 | $this->expectException(InvalidArgumentException::class); |
|
| 134 | 1 | $this->expectExceptionCode(32); |
|
| 135 | 1 | $this->expectExceptionMessage( |
|
| 136 | "Invalid value type given to 'Daikon\Tests\DataStructure\Fixture\PlainMap', ". |
||
| 137 | 1 | "expected scalar or array but was given 'stdClass'." |
|
| 138 | ); |
||
| 139 | 1 | $map->with('k1', new stdClass); |
|
| 140 | } |
||
| 141 | |||
| 142 | 1 | public function testWithout(): void |
|
| 143 | { |
||
| 144 | 1 | $map = new PlainMap(['k0' => 'v0', 'k1' => 'v1', 'k2' => 'v2']); |
|
| 145 | 1 | $unwrappedMap = $map->unwrap(); |
|
| 146 | 1 | $prunedMap = $map->without('k1')->unwrap(); |
|
| 147 | 1 | $this->assertSame($unwrappedMap['k0'], $prunedMap['k0']); |
|
| 148 | 1 | $this->assertCount(2, $prunedMap); |
|
| 149 | 1 | $this->assertSame('v0', $prunedMap['k0']); |
|
| 150 | 1 | $this->assertSame('v2', $prunedMap['k2']); |
|
| 151 | 1 | $this->assertArrayNotHasKey('k1', $prunedMap); |
|
| 152 | 1 | } |
|
| 153 | |||
| 154 | 1 | public function testWithoutWithNotExistentKey(): void |
|
| 155 | { |
||
| 156 | 1 | $map = new PlainMap(['k0' => 'v0', 'k1' => 'v1']); |
|
| 157 | 1 | $this->expectException(InvalidArgumentException::class); |
|
| 158 | 1 | $this->expectExceptionCode(217); |
|
| 159 | 1 | $this->expectExceptionMessage("Key 'k2' not found."); |
|
| 160 | 1 | $map->without('k2'); |
|
| 161 | } |
||
| 162 | |||
| 163 | 1 | public function testFirst(): void |
|
| 164 | { |
||
| 165 | 1 | $map = new PlainMap(['k0' => 'v0', 'k1' => 'v1']); |
|
| 166 | 1 | $unwrappedMap = $map->unwrap(); |
|
| 167 | 1 | $this->assertSame('v0', $unwrappedMap['k0']); |
|
| 168 | 1 | $this->assertSame($unwrappedMap['k0'], $map->first()); |
|
| 169 | 1 | } |
|
| 170 | |||
| 171 | 1 | public function testLast(): void |
|
| 172 | { |
||
| 173 | 1 | $map = new PlainMap(['k0' => 'v0', 'k1' => 'v1']); |
|
| 174 | 1 | $unwrappedMap = $map->unwrap(); |
|
| 175 | 1 | $this->assertSame('v1', $unwrappedMap['k1']); |
|
| 176 | 1 | $this->assertSame($unwrappedMap['k1'], $map->last()); |
|
| 177 | 1 | } |
|
| 178 | |||
| 179 | 1 | public function testIsEmpty(): void |
|
| 180 | { |
||
| 181 | 1 | $map = new PlainMap(['k0' => 'v1']); |
|
| 182 | 1 | $this->assertFalse($map->isEmpty()); |
|
| 183 | 1 | $map = new PlainMap; |
|
| 184 | 1 | $this->assertTrue($map->isEmpty()); |
|
| 185 | 1 | } |
|
| 186 | |||
| 187 | 1 | public function testEquals(): void |
|
| 188 | { |
||
| 189 | 1 | $map0 = new PlainMap(['k0' => 'v0', 'k1' => 'v1']); |
|
| 190 | 1 | $map1 = new PlainMap(['k0' => 'v0', 'k1' => 'v1']); |
|
| 191 | 1 | $map2 = new PlainMap(['k2' => 'v2']); |
|
| 192 | 1 | $this->assertTrue($map0->equals($map1)); |
|
| 193 | 1 | $this->assertFalse($map1->equals($map2)); |
|
| 194 | 1 | $this->assertFalse($map0->equals($map2)); |
|
| 195 | 1 | } |
|
| 196 | |||
| 197 | 1 | public function testCount(): void |
|
| 198 | { |
||
| 199 | 1 | $map = new PlainMap(['k0' => 'v0', 'k1' => 'v1']); |
|
| 200 | 1 | $this->assertCount(2, $map); |
|
| 201 | 1 | } |
|
| 202 | |||
| 203 | 1 | public function testunwrap(): void |
|
| 204 | { |
||
| 205 | 1 | $state = ['k0' => 'v0', 'k1' => 'v1']; |
|
| 206 | 1 | $map = new PlainMap($state); |
|
| 207 | 1 | $this->assertSame($state, $map->unwrap()); |
|
| 208 | 1 | } |
|
| 209 | |||
| 210 | 1 | public function testGetIterator(): void |
|
| 211 | { |
||
| 212 | 1 | $state = ['k0' => 'v0', 'k1' => 'v1']; |
|
| 213 | 1 | $map = new PlainMap($state); |
|
| 214 | 1 | foreach ($map as $key => $value) { |
|
| 215 | 1 | $this->assertSame($state[$key], $value); |
|
| 216 | } |
||
| 217 | 1 | } |
|
| 218 | |||
| 219 | 1 | public function testClone(): void |
|
| 220 | { |
||
| 221 | 1 | $t0 = [new stdClass]; |
|
| 222 | 1 | $map = new PlainMap(['k0' => 'v0', 'k1' => 'v1', 'k2' => $t0]); |
|
| 223 | 1 | $clonedMap = clone $map; |
|
| 224 | 1 | $this->assertNotSame($map->getIterator(), $clonedMap->getIterator()); |
|
| 225 | 1 | $this->assertEquals($map->getIterator(), $clonedMap->getIterator()); |
|
| 226 | 1 | $this->assertSame('v1', $map->get('k1')); |
|
| 227 | //@todo handle deep clone objects in array? |
||
| 228 | // $this->assertNotSame($t0, $clonedMap->get('k2')); |
||
| 229 | 1 | $this->assertEquals($t0, $clonedMap->get('k2')); |
|
| 230 | 1 | } |
|
| 231 | } |
||
| 232 |