|
10 | 10 | use GrumPHP\Collection\ProcessArgumentsCollection; |
11 | 11 | use GrumPHP\Formatter\ProcessFormatterInterface; |
12 | 12 | use GrumPHP\Process\ProcessBuilder; |
| 13 | +use GrumPHP\Runner\TaskResultInterface; |
13 | 14 | use GrumPHP\Task\Config\TaskConfigInterface; |
| 15 | +use GrumPHP\Task\Context\ContextInterface; |
| 16 | +use Symfony\Component\Process\Process; |
14 | 17 | use PHPUnit\Framework\TestCase; |
15 | 18 | use Symfony\Component\Yaml\Yaml; |
16 | 19 | use Wunderio\GrumPHP\Task\PhpUnitDrupalModules\PhpUnitDrupalModulesTask; |
@@ -130,6 +133,118 @@ public function testBuildsProcessArgumentsWithOnlyModules(): void { |
130 | 133 | $this->assertInstanceOf(ProcessArgumentsCollection::class, $actual); |
131 | 134 | } |
132 | 135 |
|
| 136 | + /** |
| 137 | + * Ensure run() skips when there are no modules with tests. |
| 138 | + * |
| 139 | + * @covers \Wunderio\GrumPHP\Task\PhpUnitDrupalModules\PhpUnitDrupalModulesTask::run |
| 140 | + */ |
| 141 | + public function testRunSkipsWhenNoModulesWithTests(): void { |
| 142 | + $processBuilder = $this->createMock(ProcessBuilder::class); |
| 143 | + $formatter = $this->createMock(ProcessFormatterInterface::class); |
| 144 | + |
| 145 | + /** @var \PHPUnit\Framework\MockObject\MockObject|PhpUnitDrupalModulesTask $task */ |
| 146 | + $task = $this->getMockBuilder(PhpUnitDrupalModulesTask::class) |
| 147 | + ->setConstructorArgs([$processBuilder, $formatter]) |
| 148 | + ->onlyMethods(['getConfig', 'getPathsOrResult', 'collectModulesFromPaths', 'splitModulesByTests']) |
| 149 | + ->getMock(); |
| 150 | + |
| 151 | + $config = []; |
| 152 | + foreach ($this->getConfigurations() as $name => $option) { |
| 153 | + $config[$name] = $option['defaults']; |
| 154 | + } |
| 155 | + |
| 156 | + $taskConfig = $this->createMock(TaskConfigInterface::class); |
| 157 | + $task->method('getConfig')->willReturn($taskConfig); |
| 158 | + $taskConfig->method('getOptions')->willReturn($config); |
| 159 | + |
| 160 | + $context = $this->createMock(ContextInterface::class); |
| 161 | + |
| 162 | + $paths = new \ArrayObject(['web/modules/custom/foo/src/Foo.php']); |
| 163 | + $task->method('getPathsOrResult')->willReturn($paths); |
| 164 | + $task->method('collectModulesFromPaths')->willReturn([ |
| 165 | + 'web/modules/custom/foo' => 'web/modules/custom/foo', |
| 166 | + ]); |
| 167 | + |
| 168 | + // No modules with tests, one without. |
| 169 | + $task->method('splitModulesByTests')->willReturn([[], ['web/modules/custom/foo']]); |
| 170 | + |
| 171 | + $result = $task->run($context); |
| 172 | + $this->assertInstanceOf(TaskResultInterface::class, $result); |
| 173 | + $this->assertFalse($result->isPassed()); |
| 174 | + } |
| 175 | + |
| 176 | + /** |
| 177 | + * Ensure run() executes phpunit once per module and stops on first failure. |
| 178 | + * |
| 179 | + * @covers \Wunderio\GrumPHP\Task\PhpUnitDrupalModules\PhpUnitDrupalModulesTask::run |
| 180 | + */ |
| 181 | + public function testRunExecutesPhpunitPerModuleAndStopsOnFailure(): void { |
| 182 | + $processBuilder = $this->createMock(ProcessBuilder::class); |
| 183 | + $formatter = $this->createMock(ProcessFormatterInterface::class); |
| 184 | + |
| 185 | + /** @var \PHPUnit\Framework\MockObject\MockObject|PhpUnitDrupalModulesTask $task */ |
| 186 | + $task = $this->getMockBuilder(PhpUnitDrupalModulesTask::class) |
| 187 | + ->setConstructorArgs([$processBuilder, $formatter]) |
| 188 | + ->onlyMethods([ |
| 189 | + 'getConfig', |
| 190 | + 'getPathsOrResult', |
| 191 | + 'collectModulesFromPaths', |
| 192 | + 'splitModulesByTests', |
| 193 | + 'buildArguments', |
| 194 | + 'getTaskResult', |
| 195 | + ]) |
| 196 | + ->getMock(); |
| 197 | + |
| 198 | + $config = []; |
| 199 | + foreach ($this->getConfigurations() as $name => $option) { |
| 200 | + $config[$name] = $option['defaults']; |
| 201 | + } |
| 202 | + |
| 203 | + $taskConfig = $this->createMock(TaskConfigInterface::class); |
| 204 | + $task->method('getConfig')->willReturn($taskConfig); |
| 205 | + $taskConfig->method('getOptions')->willReturn($config); |
| 206 | + |
| 207 | + $context = $this->createMock(ContextInterface::class); |
| 208 | + |
| 209 | + $paths = new \ArrayObject([ |
| 210 | + 'web/modules/custom/foo/src/Foo.php', |
| 211 | + 'web/modules/custom/bar/src/Bar.php', |
| 212 | + ]); |
| 213 | + $task->method('getPathsOrResult')->willReturn($paths); |
| 214 | + $task->method('collectModulesFromPaths')->willReturn([ |
| 215 | + 'web/modules/custom/foo' => 'web/modules/custom/foo', |
| 216 | + 'web/modules/custom/bar' => 'web/modules/custom/bar', |
| 217 | + ]); |
| 218 | + |
| 219 | + $modulesWithTests = ['web/modules/custom/foo', 'web/modules/custom/bar']; |
| 220 | + $modulesWithoutTests = []; |
| 221 | + $task->method('splitModulesByTests')->willReturn([$modulesWithTests, $modulesWithoutTests]); |
| 222 | + |
| 223 | + // Expect buildArguments to be called once per module with a single-element |
| 224 | + // array. |
| 225 | + $task->expects($this->exactly(2)) |
| 226 | + ->method('buildArguments') |
| 227 | + ->withConsecutive( |
| 228 | + [['web/modules/custom/foo']], |
| 229 | + [['web/modules/custom/bar']] |
| 230 | + ) |
| 231 | + ->willReturn($this->createMock(ProcessArgumentsCollection::class)); |
| 232 | + |
| 233 | + $processBuilder->method('buildProcess') |
| 234 | + ->willReturn($this->createMock(Process::class)); |
| 235 | + |
| 236 | + // Simulate first module passing, second failing. |
| 237 | + $passingResult = $this->createConfiguredMock(TaskResultInterface::class, ['isPassed' => TRUE]); |
| 238 | + $failingResult = $this->createConfiguredMock(TaskResultInterface::class, ['isPassed' => FALSE]); |
| 239 | + |
| 240 | + $task->expects($this->exactly(2)) |
| 241 | + ->method('getTaskResult') |
| 242 | + ->willReturnOnConsecutiveCalls($passingResult, $failingResult); |
| 243 | + |
| 244 | + $result = $task->run($context); |
| 245 | + $this->assertSame($failingResult, $result); |
| 246 | + } |
| 247 | + |
133 | 248 | /** |
134 | 249 | * Gets task configurations. |
135 | 250 | * |
|
0 commit comments