From 5e5eb069dceef1c584a4c9fa570b0dfe61abcf55 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Tue, 27 Jan 2015 16:56:39 +0100 Subject: [PATCH] Don't use a regex to parse installer tests to allow for longer tests --- tests/Composer/Test/InstallerTest.php | 143 ++++++++++++++++---------- 1 file changed, 90 insertions(+), 53 deletions(-) diff --git a/tests/Composer/Test/InstallerTest.php b/tests/Composer/Test/InstallerTest.php index 9bf2c01a7..2c77f9bc3 100644 --- a/tests/Composer/Test/InstallerTest.php +++ b/tests/Composer/Test/InstallerTest.php @@ -241,10 +241,10 @@ class InstallerTest extends TestCase } $installationManager = $composer->getInstallationManager(); - $this->assertSame($expect, implode("\n", $installationManager->getTrace())); + $this->assertSame(rtrim($expect), implode("\n", $installationManager->getTrace())); if ($expectOutput) { - $this->assertEquals($expectOutput, $output); + $this->assertEquals(rtrim($expectOutput), rtrim($output)); } } @@ -258,21 +258,7 @@ class InstallerTest extends TestCase continue; } - $test = file_get_contents($file->getRealpath()); - - $content = '(?:.(?!--[A-Z]))+'; - $pattern = '{^ - --TEST--\s*(?P.*?)\s* - (?:--CONDITION--\s*(?P'.$content.'))?\s* - --COMPOSER--\s*(?P'.$content.')\s* - (?:--LOCK--\s*(?P'.$content.'))?\s* - (?:--INSTALLED--\s*(?P'.$content.'))?\s* - --RUN--\s*(?P.*?)\s* - (?:--EXPECT-LOCK--\s*(?P'.$content.'))?\s* - (?:--EXPECT-OUTPUT--\s*(?P'.$content.'))?\s* - (?:--EXPECT-EXIT-CODE--\s*(?P\d+))?\s* - --EXPECT--\s*(?P.*?)\s* - $}xs'; + $testData = $this->readTestFile($file, $fixturesDir); $installed = array(); $installedDev = array(); @@ -280,48 +266,44 @@ class InstallerTest extends TestCase $expectLock = array(); $expectExitCode = 0; - if (preg_match($pattern, $test, $match)) { - try { - $message = $match['test']; - $condition = !empty($match['condition']) ? $match['condition'] : null; - $composer = JsonFile::parseJson($match['composer']); + try { + $message = $testData['TEST']; + $condition = !empty($testData['CONDITION']) ? $testData['CONDITION'] : null; + $composer = JsonFile::parseJson($testData['COMPOSER']); - if (isset($composer['repositories'])) { - foreach ($composer['repositories'] as &$repo) { - if ($repo['type'] !== 'composer') { - continue; - } - - // Change paths like file://foobar to file:///path/to/fixtures - if (preg_match('{^file://[^/]}', $repo['url'])) { - $repo['url'] = 'file://' . strtr($fixturesDir, '\\', '/') . '/' . substr($repo['url'], 7); - } - - unset($repo); + if (isset($composer['repositories'])) { + foreach ($composer['repositories'] as &$repo) { + if ($repo['type'] !== 'composer') { + continue; } - } - if (!empty($match['lock'])) { - $lock = JsonFile::parseJson($match['lock']); - if (!isset($lock['hash'])) { - $lock['hash'] = md5(json_encode($composer)); + // Change paths like file://foobar to file:///path/to/fixtures + if (preg_match('{^file://[^/]}', $repo['url'])) { + $repo['url'] = 'file://' . strtr($fixturesDir, '\\', '/') . '/' . substr($repo['url'], 7); } + + unset($repo); } - if (!empty($match['installed'])) { - $installed = JsonFile::parseJson($match['installed']); - } - $run = $match['run']; - if (!empty($match['expectLock'])) { - $expectLock = JsonFile::parseJson($match['expectLock']); - } - $expectOutput = $match['expectOutput']; - $expect = $match['expect']; - $expectExitCode = (int) $match['expectExitCode']; - } catch (\Exception $e) { - die(sprintf('Test "%s" is not valid: '.$e->getMessage(), str_replace($fixturesDir.'/', '', $file))); } - } else { - die(sprintf('Test "%s" is not valid, did not match the expected format.', str_replace($fixturesDir.'/', '', $file))); + + if (!empty($testData['LOCK'])) { + $lock = JsonFile::parseJson($testData['LOCK']); + if (!isset($lock['hash'])) { + $lock['hash'] = md5(json_encode($composer)); + } + } + if (!empty($testData['INSTALLED'])) { + $installed = JsonFile::parseJson($testData['INSTALLED']); + } + $run = $testData['RUN']; + if (!empty($testData['EXPECT-LOCK'])) { + $expectLock = JsonFile::parseJson($testData['EXPECT-LOCK']); + } + $expectOutput = isset($testData['EXPECT-OUTPUT']) ? $testData['EXPECT-OUTPUT'] : null; + $expect = $testData['EXPECT']; + $expectExitCode = isset($testData['EXPECT-EXIT-CODE']) ? (int) $testData['EXPECT-EXIT-CODE'] : 0; + } catch (\Exception $e) { + die(sprintf('Test "%s" is not valid: '.$e->getMessage(), str_replace($fixturesDir.'/', '', $file))); } $tests[basename($file)] = array(str_replace($fixturesDir.'/', '', $file), $message, $condition, $composer, $lock, $installed, $run, $expectLock, $expectOutput, $expect, $expectExitCode); @@ -329,4 +311,59 @@ class InstallerTest extends TestCase return $tests; } + + protected function readTestFile(\SplFileInfo $file, $fixturesDir) + { + $tokens = preg_split('#(?:^|\n*)--([A-Z-]+)--\n#', file_get_contents($file->getRealPath()), null, PREG_SPLIT_DELIM_CAPTURE); + + $sectionInfo = array( + 'TEST' => true, + 'CONDITION' => false, + 'COMPOSER' => true, + 'LOCK' => false, + 'INSTALLED' => false, + 'RUN' => true, + 'EXPECT-LOCK' => false, + 'EXPECT-OUTPUT' => false, + 'EXPECT-EXIT-CODE' => false, + 'EXPECT' => true, + ); + + $section = null; + foreach ($tokens as $i => $token) + { + if (null === $section && empty($token)) { + continue; // skip leading blank + } + + if (null === $section) { + if (!isset($sectionInfo[$token])) { + throw new \RuntimeException(sprintf( + 'The test file "%s" must not contain a section named "%s".', + str_replace($fixturesDir.'/', '', $file), + $token + )); + } + $section = $token; + continue; + } + + $sectionData = $token; + + $data[$section] = $sectionData; + $section = $sectionData = null; + } + + foreach ($sectionInfo as $section => $required) { + if ($required && !isset($data[$section])) { + throw new \RuntimeException(sprintf( + 'The test file "%s" must have a section named "%s".', + str_replace($fixturesDir.'/', '', $file), + $section + )); + } + } + + return $data; + } }