|
10 | 10 | namespace PHPUnit\Framework; |
11 | 11 |
|
12 | 12 | use PHPUnit\Framework\Attributes\CoversClass; |
13 | | -use PHPUnit\Framework\Attributes\DataProvider; |
| 13 | +use PHPUnit\Framework\Attributes\Small; |
| 14 | +use PHPUnit\Metadata\Metadata; |
14 | 15 |
|
15 | 16 | #[CoversClass(ExecutionOrderDependency::class)] |
| 17 | +#[Small] |
16 | 18 | class ExecutionOrderDependencyTest extends TestCase |
17 | 19 | { |
18 | | - public static function createFromParametersProvider(): array |
| 20 | + public function testCanBeInvalid(): void |
19 | 21 | { |
20 | | - return [ |
21 | | - // Dependency on specific class::method target |
22 | | - ['Class1', 'test1', 'Class1::test1', false], |
23 | | - ['Class2', 'test2', 'Class2::test2', false], |
24 | | - ['Class3::method3', null, 'Class3::method3', false], |
| 22 | + $dependency = ExecutionOrderDependency::invalid(); |
| 23 | + |
| 24 | + $this->assertFalse($dependency->isValid()); |
| 25 | + $this->assertSame('', $dependency->getTarget()); |
| 26 | + $this->assertSame('', (string) $dependency); |
| 27 | + $this->assertSame('', $dependency->getTargetClassName()); |
| 28 | + $this->assertFalse($dependency->shallowClone()); |
| 29 | + $this->assertFalse($dependency->deepClone()); |
| 30 | + } |
| 31 | + |
| 32 | + public function testCanBeDependencyOnClass(): void |
| 33 | + { |
| 34 | + $metadata = Metadata::dependsOnClass('SomeClass', false, false); |
| 35 | + $dependency = ExecutionOrderDependency::forClass($metadata); |
| 36 | + |
| 37 | + $this->assertTrue($dependency->isValid()); |
| 38 | + $this->assertTrue($dependency->targetIsClass()); |
| 39 | + $this->assertSame('SomeClass::class', $dependency->getTarget()); |
| 40 | + $this->assertSame('SomeClass::class', (string) $dependency); |
| 41 | + $this->assertSame('SomeClass', $dependency->getTargetClassName()); |
| 42 | + $this->assertFalse($dependency->deepClone()); |
| 43 | + $this->assertFalse($dependency->shallowClone()); |
| 44 | + } |
| 45 | + |
| 46 | + public function testCanBeDependencyOnClassWithDeepClone(): void |
| 47 | + { |
| 48 | + $metadata = Metadata::dependsOnClass('SomeClass', true, false); |
| 49 | + $dependency = ExecutionOrderDependency::forClass($metadata); |
| 50 | + |
| 51 | + $this->assertTrue($dependency->deepClone()); |
| 52 | + $this->assertFalse($dependency->shallowClone()); |
| 53 | + } |
| 54 | + |
| 55 | + public function testCanBeDependencyOnClassWithShallowClone(): void |
| 56 | + { |
| 57 | + $metadata = Metadata::dependsOnClass('SomeClass', false, true); |
| 58 | + $dependency = ExecutionOrderDependency::forClass($metadata); |
| 59 | + |
| 60 | + $this->assertFalse($dependency->deepClone()); |
| 61 | + $this->assertTrue($dependency->shallowClone()); |
| 62 | + } |
| 63 | + |
| 64 | + public function testCanBeDependencyOnMethod(): void |
| 65 | + { |
| 66 | + $metadata = Metadata::dependsOnMethod('SomeClass', 'someMethod', false, false); |
| 67 | + $dependency = ExecutionOrderDependency::forMethod($metadata); |
| 68 | + |
| 69 | + $this->assertTrue($dependency->isValid()); |
| 70 | + $this->assertFalse($dependency->targetIsClass()); |
| 71 | + $this->assertSame('SomeClass::someMethod', $dependency->getTarget()); |
| 72 | + $this->assertSame('SomeClass::someMethod', (string) $dependency); |
| 73 | + $this->assertFalse($dependency->deepClone()); |
| 74 | + $this->assertFalse($dependency->shallowClone()); |
| 75 | + } |
| 76 | + |
| 77 | + public function testCanBeDependencyOnMethodWithDeepClone(): void |
| 78 | + { |
| 79 | + $metadata = Metadata::dependsOnMethod('SomeClass', 'someMethod', true, false); |
| 80 | + $dependency = ExecutionOrderDependency::forMethod($metadata); |
25 | 81 |
|
26 | | - // Dependency on whole class |
27 | | - ['Class4', null, 'Class4::class', true], |
28 | | - ['Class5', '', 'Class5::class', true], |
29 | | - ['Class6', 'class', 'Class6::class', true], |
30 | | - ['Class7::class', null, 'Class7::class', true], |
31 | | - ]; |
| 82 | + $this->assertTrue($dependency->deepClone()); |
| 83 | + $this->assertFalse($dependency->shallowClone()); |
32 | 84 | } |
33 | 85 |
|
34 | | - public static function createWithCloneOptionProvider(): array |
| 86 | + public function testCanBeDependencyOnMethodShallowClone(): void |
35 | 87 | { |
36 | | - return [ |
37 | | - 'no clone' => [false, false, false, false], |
38 | | - 'deep clone' => [true, false, false, true], |
39 | | - 'shallow clone' => [false, true, true, false], |
40 | | - ]; |
| 88 | + $metadata = Metadata::dependsOnMethod('SomeClass', 'someMethod', false, true); |
| 89 | + $dependency = ExecutionOrderDependency::forMethod($metadata); |
| 90 | + |
| 91 | + $this->assertFalse($dependency->deepClone()); |
| 92 | + $this->assertTrue($dependency->shallowClone()); |
41 | 93 | } |
42 | 94 |
|
43 | | - public function testCreateDependencyOnClassFromClassNameOnly(): void |
| 95 | + public function testConstructorParsesDoubleColonNotationForClass(): void |
44 | 96 | { |
45 | | - $dependency = new ExecutionOrderDependency('ClassDependency'); |
| 97 | + $dependency = new ExecutionOrderDependency('Class::class'); |
46 | 98 |
|
| 99 | + $this->assertSame('Class::class', $dependency->getTarget()); |
| 100 | + $this->assertSame('Class::class', (string) $dependency); |
47 | 101 | $this->assertTrue($dependency->targetIsClass()); |
48 | | - $this->assertSame('ClassDependency::class', $dependency->getTarget()); |
49 | | - $this->assertSame('ClassDependency', $dependency->getTargetClassName()); |
50 | 102 | } |
51 | 103 |
|
52 | | - #[DataProvider('createFromParametersProvider')] |
53 | | - public function testCreateDependencyFromParameters(string $className, ?string $methodName, string $expectedTarget, bool $expectedTargetIsClass): void |
| 104 | + public function testConstructorParsesDoubleColonNotationForMethod(): void |
54 | 105 | { |
55 | | - $dependency = new ExecutionOrderDependency($className, $methodName); |
| 106 | + $dependency = new ExecutionOrderDependency('Class::method'); |
56 | 107 |
|
57 | | - $this->assertSame( |
58 | | - $expectedTarget, |
59 | | - $dependency->getTarget(), |
60 | | - 'Incorrect dependency class::method target', |
61 | | - ); |
| 108 | + $this->assertSame('Class::method', $dependency->getTarget()); |
| 109 | + $this->assertSame('Class::method', (string) $dependency); |
| 110 | + $this->assertFalse($dependency->targetIsClass()); |
| 111 | + } |
62 | 112 |
|
63 | | - $this->assertSame( |
64 | | - $expectedTargetIsClass, |
65 | | - $dependency->targetIsClass(), |
66 | | - 'Incorrect targetIsClass', |
| 113 | + public function testInvalidDependenciesAreFiltered(): void |
| 114 | + { |
| 115 | + $valid = ExecutionOrderDependency::forMethod( |
| 116 | + Metadata::dependsOnMethod('ClassA', 'methodA', false, false), |
67 | 117 | ); |
| 118 | + |
| 119 | + $invalid = ExecutionOrderDependency::invalid(); |
| 120 | + |
| 121 | + $result = ExecutionOrderDependency::filterInvalid([$valid, $invalid]); |
| 122 | + |
| 123 | + $this->assertCount(1, $result); |
| 124 | + $this->assertSame($valid, $result[0]); |
68 | 125 | } |
69 | 126 |
|
70 | | - #[DataProvider('createWithCloneOptionProvider')] |
71 | | - public function testCreateDependencyWithCloneOption(bool $deepClone, bool $shallowClone, bool $expectedShallowClone, bool $expectedDeepClone): void |
| 127 | + public function testInvalidDependenciesAreFiltered2(): void |
72 | 128 | { |
73 | | - $dependency = new ExecutionOrderDependency('ClassName', 'methodName', $deepClone, $shallowClone); |
| 129 | + $result = ExecutionOrderDependency::filterInvalid([ |
| 130 | + ExecutionOrderDependency::invalid(), |
| 131 | + ExecutionOrderDependency::invalid(), |
| 132 | + ]); |
74 | 133 |
|
75 | | - $this->assertSame( |
76 | | - $expectedShallowClone, |
77 | | - $dependency->shallowClone(), |
78 | | - 'Incorrect shallowClone option', |
| 134 | + $this->assertSame([], $result); |
| 135 | + } |
| 136 | + |
| 137 | + public function testValidDependenciesAreNotFiltered(): void |
| 138 | + { |
| 139 | + $a = ExecutionOrderDependency::forMethod( |
| 140 | + Metadata::dependsOnMethod('ClassA', 'methodA', false, false), |
79 | 141 | ); |
80 | 142 |
|
81 | | - $this->assertSame( |
82 | | - $expectedDeepClone, |
83 | | - $dependency->deepClone(), |
84 | | - 'Incorrect clone option', |
| 143 | + $b = ExecutionOrderDependency::forMethod( |
| 144 | + Metadata::dependsOnMethod('ClassB', 'methodB', false, false), |
85 | 145 | ); |
| 146 | + |
| 147 | + $result = ExecutionOrderDependency::filterInvalid([$a, $b]); |
| 148 | + |
| 149 | + $this->assertCount(2, $result); |
| 150 | + $this->assertSame($a, $result[0]); |
| 151 | + $this->assertSame($b, $result[1]); |
86 | 152 | } |
87 | 153 |
|
88 | | - public function testMergeHandlesEmptyDependencyLists(): void |
| 154 | + public function testEmptyListsCanBeMerged(): void |
89 | 155 | { |
90 | | - $depOne = new ExecutionOrderDependency('classOne'); |
91 | | - $depTwo = new ExecutionOrderDependency('classTwo::methodTwo'); |
| 156 | + $a = ExecutionOrderDependency::forClass( |
| 157 | + Metadata::dependsOnClass('classOne', false, false), |
| 158 | + ); |
| 159 | + |
| 160 | + $b = ExecutionOrderDependency::forMethod( |
| 161 | + Metadata::dependsOnMethod('classTwo', 'methodTwo', false, false), |
| 162 | + ); |
92 | 163 |
|
93 | 164 | $this->assertSame( |
94 | | - [$depOne, $depTwo], |
| 165 | + [$a, $b], |
95 | 166 | ExecutionOrderDependency::mergeUnique( |
96 | 167 | [], |
97 | | - [$depOne, $depTwo], |
| 168 | + [$a, $b], |
98 | 169 | ), |
99 | 170 | 'Left side of merge could be empty', |
100 | 171 | ); |
101 | 172 |
|
102 | 173 | $this->assertSame( |
103 | | - [$depOne, $depTwo], |
| 174 | + [$a, $b], |
104 | 175 | ExecutionOrderDependency::mergeUnique( |
105 | | - [$depOne, $depTwo], |
| 176 | + [$a, $b], |
106 | 177 | [], |
107 | 178 | ), |
108 | 179 | 'Right side of merge could be empty', |
109 | 180 | ); |
110 | 181 | } |
111 | 182 |
|
112 | | - public function testEmptyClassOrCallable(): void |
| 183 | + public function testMergingDoesNotAddDuplicates(): void |
| 184 | + { |
| 185 | + $a = ExecutionOrderDependency::forMethod( |
| 186 | + Metadata::dependsOnMethod('ClassA', 'methodA', false, false), |
| 187 | + ); |
| 188 | + |
| 189 | + $b = ExecutionOrderDependency::forMethod( |
| 190 | + Metadata::dependsOnMethod('ClassB', 'methodB', false, false), |
| 191 | + ); |
| 192 | + |
| 193 | + $c = ExecutionOrderDependency::forMethod( |
| 194 | + Metadata::dependsOnMethod('ClassC', 'methodC', false, false), |
| 195 | + ); |
| 196 | + |
| 197 | + $duplicate = ExecutionOrderDependency::forMethod( |
| 198 | + Metadata::dependsOnMethod('ClassA', 'methodA', false, false), |
| 199 | + ); |
| 200 | + |
| 201 | + $result = ExecutionOrderDependency::mergeUnique([$a, $b], [$duplicate, $c]); |
| 202 | + |
| 203 | + $this->assertCount(3, $result); |
| 204 | + $this->assertSame('ClassA::methodA', $result[0]->getTarget()); |
| 205 | + $this->assertSame('ClassB::methodB', $result[1]->getTarget()); |
| 206 | + $this->assertSame('ClassC::methodC', $result[2]->getTarget()); |
| 207 | + } |
| 208 | + |
| 209 | + public function testDiffReturnsLeftWhenRightIsEmpty(): void |
113 | 210 | { |
114 | | - $empty = new ExecutionOrderDependency(''); |
115 | | - $this->assertFalse($empty->shallowClone()); |
116 | | - $this->assertFalse($empty->deepClone()); |
117 | | - $this->assertFalse($empty->targetIsClass()); |
118 | | - $this->assertSame('', $empty->getTargetClassName()); |
| 211 | + $a = ExecutionOrderDependency::forMethod( |
| 212 | + Metadata::dependsOnMethod('ClassA', 'methodA', false, false), |
| 213 | + ); |
| 214 | + |
| 215 | + $b = ExecutionOrderDependency::forMethod( |
| 216 | + Metadata::dependsOnMethod('ClassB', 'methodB', false, false), |
| 217 | + ); |
| 218 | + |
| 219 | + $result = ExecutionOrderDependency::diff([$a, $b], []); |
| 220 | + |
| 221 | + $this->assertSame([$a, $b], $result); |
| 222 | + } |
| 223 | + |
| 224 | + public function testDiffReturnsEmptyWhenLeftIsEmpty(): void |
| 225 | + { |
| 226 | + $dependency = ExecutionOrderDependency::forMethod( |
| 227 | + Metadata::dependsOnMethod('ClassA', 'methodA', false, false), |
| 228 | + ); |
| 229 | + |
| 230 | + $result = ExecutionOrderDependency::diff([], [$dependency]); |
| 231 | + |
| 232 | + $this->assertSame([], $result); |
| 233 | + } |
| 234 | + |
| 235 | + public function testDiffRemovesMatchingDependencies(): void |
| 236 | + { |
| 237 | + $a = ExecutionOrderDependency::forMethod( |
| 238 | + Metadata::dependsOnMethod('ClassA', 'methodA', false, false), |
| 239 | + ); |
| 240 | + |
| 241 | + $b = ExecutionOrderDependency::forMethod( |
| 242 | + Metadata::dependsOnMethod('ClassB', 'methodB', false, false), |
| 243 | + ); |
| 244 | + |
| 245 | + $c = ExecutionOrderDependency::forMethod( |
| 246 | + Metadata::dependsOnMethod('ClassC', 'methodC', false, false), |
| 247 | + ); |
| 248 | + |
| 249 | + $result = ExecutionOrderDependency::diff([$a, $b, $c], [$b]); |
| 250 | + |
| 251 | + $this->assertCount(2, $result); |
| 252 | + $this->assertSame($a, $result[0]); |
| 253 | + $this->assertSame($c, $result[1]); |
119 | 254 | } |
120 | 255 | } |
0 commit comments