Skip to content

Commit f0332ec

Browse files
authored
Add more tests (#13)
1 parent 7e0a6ba commit f0332ec

File tree

8 files changed

+277
-32
lines changed

8 files changed

+277
-32
lines changed

Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ COMPOSER=$(PHP) $(shell which composer)
2828

2929
# Infection
3030
INFECTION=./.tools/infection.phar
31-
INFECTION_URL="https://github.com/infection/infection/releases/download/0.24.0/infection.phar"
32-
MIN_MSI=57
31+
INFECTION_URL="https://github.com/infection/infection/releases/download/0.25.3/infection.phar"
32+
MIN_MSI=68
3333
MIN_COVERED_MSI=97
34-
INFECTION_ARGS=--min-msi=$(MIN_MSI) --min-covered-msi=$(MIN_COVERED_MSI) --threads=$(JOBS) --log-verbosity=none --no-interaction --no-progress
34+
INFECTION_ARGS=--min-msi=$(MIN_MSI) --min-covered-msi=$(MIN_COVERED_MSI) --threads=$(JOBS) --log-verbosity=none --no-interaction --no-progress --show-mutations
3535

3636
all: test
3737

src/CommandLineBuilder.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,9 @@
4545

4646
/**
4747
* @internal
48+
* @final
4849
*/
49-
final class CommandLineBuilder
50+
class CommandLineBuilder
5051
{
5152
/**
5253
* @var string[]|null

src/PhpSpecAdapter.php

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
use Infection\TestFramework\PhpSpec\CommandLine\ArgumentsAndOptionsBuilder;
4242
use Infection\TestFramework\PhpSpec\Config\Builder\InitialConfigBuilder;
4343
use Infection\TestFramework\PhpSpec\Config\Builder\MutationConfigBuilder;
44-
use InvalidArgumentException;
4544
use const PHP_EOL;
4645
use function preg_match;
4746
use function sprintf;
@@ -62,22 +61,24 @@ final class PhpSpecAdapter implements TestFrameworkAdapter
6261
private MutationConfigBuilder $mutationConfigBuilder;
6362
private VersionParser $versionParser;
6463
private CommandLineBuilder $commandLineBuilder;
65-
private ?string $cachedVersion = null;
64+
private ?string $version;
6665

6766
public function __construct(
6867
string $testFrameworkExecutable,
6968
InitialConfigBuilder $initialConfigBuilder,
7069
MutationConfigBuilder $mutationConfigBuilder,
7170
ArgumentsAndOptionsBuilder $argumentsAndOptionsBuilder,
7271
VersionParser $versionParser,
73-
CommandLineBuilder $commandLineBuilder
72+
CommandLineBuilder $commandLineBuilder,
73+
?string $version = null
7474
) {
7575
$this->testFrameworkExecutable = $testFrameworkExecutable;
7676
$this->initialConfigBuilder = $initialConfigBuilder;
7777
$this->mutationConfigBuilder = $mutationConfigBuilder;
7878
$this->argumentsAndOptionsBuilder = $argumentsAndOptionsBuilder;
7979
$this->versionParser = $versionParser;
8080
$this->commandLineBuilder = $commandLineBuilder;
81+
$this->version = $version;
8182
}
8283

8384
public function hasJUnitReport(): bool
@@ -153,28 +154,7 @@ public function getMutantCommandLine(
153154

154155
public function getVersion(): string
155156
{
156-
if ($this->cachedVersion !== null) {
157-
return $this->cachedVersion;
158-
}
159-
160-
$testFrameworkVersionExecutable = $this->commandLineBuilder->build(
161-
$this->testFrameworkExecutable,
162-
[],
163-
['--version']
164-
);
165-
166-
$process = new Process($testFrameworkVersionExecutable);
167-
$process->mustRun();
168-
169-
try {
170-
$version = $this->versionParser->parse($process->getOutput());
171-
} catch (InvalidArgumentException $e) {
172-
$version = 'unknown';
173-
}
174-
175-
$this->cachedVersion = $version;
176-
177-
return $this->cachedVersion;
157+
return $this->version ?? $this->version = $this->retrieveVersion();
178158
}
179159

180160
public function getInitialTestsFailRecommendations(string $commandLine): string
@@ -218,4 +198,18 @@ private function getCommandLine(
218198

219199
return $this->commandLineBuilder->build($this->testFrameworkExecutable, $phpExtraArgs, $frameworkArgs);
220200
}
201+
202+
private function retrieveVersion(): string
203+
{
204+
$testFrameworkVersionExecutable = $this->commandLineBuilder->build(
205+
$this->testFrameworkExecutable,
206+
[],
207+
['--version']
208+
);
209+
210+
$process = new Process($testFrameworkVersionExecutable);
211+
$process->mustRun();
212+
213+
return $this->versionParser->parse($process->getOutput());
214+
}
221215
}

tests/phpunit/FinderExceptionTest.php renamed to tests/phpunit/Adapter/FinderExceptionTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333

3434
declare(strict_types=1);
3535

36-
namespace Infection\Tests\TestFramework\PhpSpec;
36+
namespace Infection\Tests\TestFramework\PhpSpec\Adapter;
3737

3838
use Infection\TestFramework\PhpSpec\FinderException;
3939
use PHPUnit\Framework\TestCase;

tests/phpunit/Adapter/PhpSpecAdapterFactoryTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,14 @@ public function test_it_creates_phpspec_adapter(): void
5959

6060
$this->assertInstanceOf(PhpSpecAdapter::class, $adapter);
6161
}
62+
63+
public function test_it_returns_right_adapter_name(): void
64+
{
65+
$this->assertSame('phpspec', PhpSpecAdapterFactory::getAdapterName());
66+
}
67+
68+
public function test_it_returns_right_executable_name(): void
69+
{
70+
$this->assertSame('phpspec', PhpSpecAdapterFactory::getExecutableName());
71+
}
6272
}

tests/phpunit/Adapter/PhpSpecAdapterTest.php

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,15 @@
3535

3636
namespace Infection\Tests\TestFramework\PhpSpec\Adapter;
3737

38+
use Infection\AbstractTestFramework\Coverage\TestLocation;
3839
use Infection\TestFramework\PhpSpec\CommandLine\ArgumentsAndOptionsBuilder;
3940
use Infection\TestFramework\PhpSpec\CommandLineBuilder;
4041
use Infection\TestFramework\PhpSpec\Config\Builder\InitialConfigBuilder;
4142
use Infection\TestFramework\PhpSpec\Config\Builder\MutationConfigBuilder;
4243
use Infection\TestFramework\PhpSpec\PhpSpecAdapter;
4344
use Infection\TestFramework\PhpSpec\VersionParser;
4445
use PHPUnit\Framework\TestCase;
46+
use function sprintf;
4547

4648
final class PhpSpecAdapterTest extends TestCase
4749
{
@@ -122,6 +124,134 @@ public function test_it_catches_fatal_errors_from_start(): void
122124
$this->assertFalse($adapter->testsPass($output));
123125
}
124126

127+
public function test_has_junit_report_returns_false(): void
128+
{
129+
$adapter = $this->getAdapter();
130+
131+
$this->assertFalse($adapter->hasJUnitReport(), 'PhpSpec does not have JUnit Report');
132+
}
133+
134+
public function test_it_returns_initial_tests_fail_recommendations(): void
135+
{
136+
$adapter = $this->getAdapter();
137+
138+
$commandLine = 'cli';
139+
140+
$this->assertSame(
141+
sprintf('Check the executed command to identify the problem: %s', $commandLine),
142+
$adapter->getInitialTestsFailRecommendations($commandLine)
143+
);
144+
}
145+
146+
public function test_it_provides_initial_test_run_command_line(): void
147+
{
148+
$initialConfigBuilder = $this->createMock(InitialConfigBuilder::class);
149+
$initialConfigBuilder->expects($this->once())
150+
->method('build')
151+
->with('7.2.0')
152+
->willReturn('/tmp/phpspecConfiguration.initial.infection.yml');
153+
154+
$commandLineBuilder = $this->createMock(CommandLineBuilder::class);
155+
156+
$commandLineBuilder->expects($this->once())
157+
->method('build')
158+
->with(
159+
'/path/to/phpspec',
160+
['-d', 'memory_limit=-1'],
161+
[
162+
'run',
163+
'--config',
164+
'/tmp/phpspecConfiguration.initial.infection.yml',
165+
'--no-ansi',
166+
'--format=tap',
167+
'--stop-on-failure',
168+
'--ansi',
169+
]
170+
)
171+
->willReturn(['/path/to/phpspec', '--dummy-argument']);
172+
173+
$adapter = new PhpSpecAdapter(
174+
'/path/to/phpspec',
175+
$initialConfigBuilder,
176+
$this->createMock(MutationConfigBuilder::class),
177+
new ArgumentsAndOptionsBuilder(),
178+
new VersionParser(),
179+
$commandLineBuilder,
180+
'7.2.0'
181+
);
182+
183+
$initialTestRunCommandLine = $adapter->getInitialTestRunCommandLine('--ansi', ['-d', 'memory_limit=-1'], true);
184+
185+
$this->assertSame(
186+
[
187+
'/path/to/phpspec',
188+
'--dummy-argument',
189+
],
190+
$initialTestRunCommandLine
191+
);
192+
}
193+
194+
public function test_it_provides_mutant_test_run_command_line(): void
195+
{
196+
$coverageTests = [new TestLocation('test', 'path', 1.2)];
197+
$mutatedFilePath = '/tmp/mutated_file_path.php';
198+
$mutationHash = 'hash';
199+
$mutationOriginalFilePath = '/src/Class.php';
200+
201+
$expectedMutationConfigFile = '/path/file';
202+
203+
$mutationConfigBuilder = $this->createMock(MutationConfigBuilder::class);
204+
205+
$mutationConfigBuilder->expects($this->once())
206+
->method('build')
207+
->with($coverageTests, $mutatedFilePath, $mutationHash, $mutationOriginalFilePath)
208+
->willReturn($expectedMutationConfigFile);
209+
210+
$commandLineBuilder = $this->createMock(CommandLineBuilder::class);
211+
212+
$commandLineBuilder->expects($this->once())
213+
->method('build')
214+
->with(
215+
'/path/to/phpspec',
216+
[],
217+
[
218+
'run',
219+
'--config',
220+
$expectedMutationConfigFile,
221+
'--no-ansi',
222+
'--format=tap',
223+
'--stop-on-failure',
224+
]
225+
)
226+
->willReturn(['/path/to/phpspec', '--dummy-argument']);
227+
228+
$adapter = new PhpSpecAdapter(
229+
'/path/to/phpspec',
230+
$this->createMock(InitialConfigBuilder::class),
231+
$mutationConfigBuilder,
232+
new ArgumentsAndOptionsBuilder(),
233+
new VersionParser(),
234+
$commandLineBuilder,
235+
'7.2.0'
236+
);
237+
238+
$initialTestRunCommandLine = $adapter->getMutantCommandLine(
239+
[new TestLocation('test', 'path', 1.2)],
240+
$mutatedFilePath,
241+
$mutationHash,
242+
$mutationOriginalFilePath,
243+
''
244+
);
245+
246+
$this->assertSame(
247+
[
248+
'/path/to/phpspec',
249+
'--dummy-argument',
250+
],
251+
$initialTestRunCommandLine
252+
);
253+
}
254+
125255
private function getAdapter(): PhpSpecAdapter
126256
{
127257
return new PhpSpecAdapter(
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<?php
2+
/**
3+
* This code is licensed under the BSD 3-Clause License.
4+
*
5+
* Copyright (c) 2017, Maks Rafalko
6+
* All rights reserved.
7+
*
8+
* Redistribution and use in source and binary forms, with or without
9+
* modification, are permitted provided that the following conditions are met:
10+
*
11+
* * Redistributions of source code must retain the above copyright notice, this
12+
* list of conditions and the following disclaimer.
13+
*
14+
* * Redistributions in binary form must reproduce the above copyright notice,
15+
* this list of conditions and the following disclaimer in the documentation
16+
* and/or other materials provided with the distribution.
17+
*
18+
* * Neither the name of the copyright holder nor the names of its
19+
* contributors may be used to endorse or promote products derived from
20+
* this software without specific prior written permission.
21+
*
22+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32+
*/
33+
34+
declare(strict_types=1);
35+
36+
namespace Infection\Tests\TestFramework\PhpSpec\Adapter;
37+
38+
use Infection\TestFramework\PhpSpec\VersionParser;
39+
use InvalidArgumentException;
40+
use PHPUnit\Framework\TestCase;
41+
42+
final class VersionParserTest extends TestCase
43+
{
44+
private VersionParser $versionParser;
45+
46+
protected function setUp(): void
47+
{
48+
$this->versionParser = new VersionParser();
49+
}
50+
51+
/**
52+
* @dataProvider versionProvider
53+
*/
54+
public function test_it_parses_version_from_string(string $content, string $expectedVersion): void
55+
{
56+
$result = $this->versionParser->parse($content);
57+
58+
$this->assertSame($expectedVersion, $result);
59+
}
60+
61+
public function test_it_throws_exception_when_content_has_no_version_substring(): void
62+
{
63+
try {
64+
$this->versionParser->parse('abc');
65+
66+
$this->fail();
67+
} catch (InvalidArgumentException $exception) {
68+
$this->assertSame(
69+
'Parameter does not contain a valid SemVer (sub)string.',
70+
$exception->getMessage()
71+
);
72+
}
73+
}
74+
75+
/**
76+
* @return iterable<string, array<array-key, string>>
77+
*/
78+
public function versionProvider(): iterable
79+
{
80+
yield 'nominal stable' => ['7.0.2', '7.0.2'];
81+
82+
yield 'nominal development' => ['0.2.8', '0.2.8'];
83+
84+
yield 'stable variant' => ['v7.0.2', '7.0.2'];
85+
86+
yield 'development variant' => ['v0.2.8', '0.2.8'];
87+
88+
yield 'patch' => ['7.0.2-patch', '7.0.2-patch'];
89+
90+
yield 'versioned patch' => ['7.0.2-patch.0', '7.0.2-patch.0'];
91+
92+
yield 'RC' => ['7.0.2-rc', '7.0.2-rc'];
93+
94+
yield 'uppercase RC' => ['7.0.2-RC', '7.0.2-RC'];
95+
96+
yield 'versioned RC' => ['7.0.2-rc.0', '7.0.2-rc.0'];
97+
98+
yield 'with spaces' => [' 7.0.2 ', '7.0.2'];
99+
100+
yield 'nonsense suffix 0' => ['7.0.2foo', '7.0.2'];
101+
102+
yield 'nonsense suffix 1' => ['7.0.2-foo', '7.0.2-foo'];
103+
104+
yield 'Hoa' => ['3.17.05.02', '3.17.05'];
105+
106+
yield 'phpspec stable' => ['phpspec 7.1.0', '7.1.0'];
107+
108+
yield 'phpspec RC' => ['phpspec version 5.0.0-rc1', '5.0.0-rc1'];
109+
}
110+
}

0 commit comments

Comments
 (0)