 1ac0f42a58
			
		
	
	1ac0f42a58
	
	
	
		
			
			Travis config update Removed HHVM script as Laravel no longer support HHVM after releasing 5.3
		
			
				
	
	
		
			300 lines
		
	
	
		
			9.8 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			300 lines
		
	
	
		
			9.8 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php declare(strict_types=1);
 | |
| /*
 | |
|  * This file is part of sebastian/diff.
 | |
|  *
 | |
|  * (c) Sebastian Bergmann <sebastian@phpunit.de>
 | |
|  *
 | |
|  * For the full copyright and license information, please view the LICENSE
 | |
|  * file that was distributed with this source code.
 | |
|  */
 | |
| 
 | |
| namespace SebastianBergmann\Diff\Output;
 | |
| 
 | |
| use PHPUnit\Framework\TestCase;
 | |
| use SebastianBergmann\Diff\Differ;
 | |
| use SebastianBergmann\Diff\Utils\FileUtils;
 | |
| use SebastianBergmann\Diff\Utils\UnifiedDiffAssertTrait;
 | |
| use Symfony\Component\Process\Process;
 | |
| 
 | |
| /**
 | |
|  * @covers SebastianBergmann\Diff\Output\StrictUnifiedDiffOutputBuilder
 | |
|  *
 | |
|  * @uses SebastianBergmann\Diff\Differ
 | |
|  * @uses SebastianBergmann\Diff\TimeEfficientLongestCommonSubsequenceCalculator
 | |
|  *
 | |
|  * @requires OS Linux
 | |
|  */
 | |
| final class StrictUnifiedDiffOutputBuilderIntegrationTest extends TestCase
 | |
| {
 | |
|     use UnifiedDiffAssertTrait;
 | |
| 
 | |
|     private $dir;
 | |
| 
 | |
|     private $fileFrom;
 | |
| 
 | |
|     private $fileTo;
 | |
| 
 | |
|     private $filePatch;
 | |
| 
 | |
|     protected function setUp(): void
 | |
|     {
 | |
|         $this->dir       = \realpath(__DIR__ . '/../../fixtures/out') . '/';
 | |
|         $this->fileFrom  = $this->dir . 'from.txt';
 | |
|         $this->fileTo    = $this->dir . 'to.txt';
 | |
|         $this->filePatch = $this->dir . 'diff.patch';
 | |
| 
 | |
|         if (!\is_dir($this->dir)) {
 | |
|             throw new \RuntimeException('Integration test working directory not found.');
 | |
|         }
 | |
| 
 | |
|         $this->cleanUpTempFiles();
 | |
|     }
 | |
| 
 | |
|     protected function tearDown(): void
 | |
|     {
 | |
|         $this->cleanUpTempFiles();
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Integration test
 | |
|      *
 | |
|      * - get a file pair
 | |
|      * - create a `diff` between the files
 | |
|      * - test applying the diff using `git apply`
 | |
|      * - test applying the diff using `patch`
 | |
|      *
 | |
|      * @param string $fileFrom
 | |
|      * @param string $fileTo
 | |
|      *
 | |
|      * @dataProvider provideFilePairs
 | |
|      */
 | |
|     public function testIntegrationUsingPHPFileInVendorGitApply(string $fileFrom, string $fileTo): void
 | |
|     {
 | |
|         $from = FileUtils::getFileContent($fileFrom);
 | |
|         $to   = FileUtils::getFileContent($fileTo);
 | |
| 
 | |
|         $diff = (new Differ(new StrictUnifiedDiffOutputBuilder(['fromFile' => 'Original', 'toFile' => 'New'])))->diff($from, $to);
 | |
| 
 | |
|         if ('' === $diff && $from === $to) {
 | |
|             // odd case: test after executing as it is more efficient than to read the files and check the contents every time
 | |
|             $this->addToAssertionCount(1);
 | |
| 
 | |
|             return;
 | |
|         }
 | |
| 
 | |
|         $this->doIntegrationTestGitApply($diff, $from, $to);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Integration test
 | |
|      *
 | |
|      * - get a file pair
 | |
|      * - create a `diff` between the files
 | |
|      * - test applying the diff using `git apply`
 | |
|      * - test applying the diff using `patch`
 | |
|      *
 | |
|      * @param string $fileFrom
 | |
|      * @param string $fileTo
 | |
|      *
 | |
|      * @dataProvider provideFilePairs
 | |
|      */
 | |
|     public function testIntegrationUsingPHPFileInVendorPatch(string $fileFrom, string $fileTo): void
 | |
|     {
 | |
|         $from = FileUtils::getFileContent($fileFrom);
 | |
|         $to   = FileUtils::getFileContent($fileTo);
 | |
| 
 | |
|         $diff = (new Differ(new StrictUnifiedDiffOutputBuilder(['fromFile' => 'Original', 'toFile' => 'New'])))->diff($from, $to);
 | |
| 
 | |
|         if ('' === $diff && $from === $to) {
 | |
|             // odd case: test after executing as it is more efficient than to read the files and check the contents every time
 | |
|             $this->addToAssertionCount(1);
 | |
| 
 | |
|             return;
 | |
|         }
 | |
| 
 | |
|         $this->doIntegrationTestPatch($diff, $from, $to);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * @param string $expected
 | |
|      * @param string $from
 | |
|      * @param string $to
 | |
|      *
 | |
|      * @dataProvider provideOutputBuildingCases
 | |
|      * @dataProvider provideSample
 | |
|      * @dataProvider provideBasicDiffGeneration
 | |
|      */
 | |
|     public function testIntegrationOfUnitTestCasesGitApply(string $expected, string $from, string $to): void
 | |
|     {
 | |
|         $this->doIntegrationTestGitApply($expected, $from, $to);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * @param string $expected
 | |
|      * @param string $from
 | |
|      * @param string $to
 | |
|      *
 | |
|      * @dataProvider provideOutputBuildingCases
 | |
|      * @dataProvider provideSample
 | |
|      * @dataProvider provideBasicDiffGeneration
 | |
|      */
 | |
|     public function testIntegrationOfUnitTestCasesPatch(string $expected, string $from, string $to): void
 | |
|     {
 | |
|         $this->doIntegrationTestPatch($expected, $from, $to);
 | |
|     }
 | |
| 
 | |
|     public function provideOutputBuildingCases(): array
 | |
|     {
 | |
|         return StrictUnifiedDiffOutputBuilderDataProvider::provideOutputBuildingCases();
 | |
|     }
 | |
| 
 | |
|     public function provideSample(): array
 | |
|     {
 | |
|         return StrictUnifiedDiffOutputBuilderDataProvider::provideSample();
 | |
|     }
 | |
| 
 | |
|     public function provideBasicDiffGeneration(): array
 | |
|     {
 | |
|         return StrictUnifiedDiffOutputBuilderDataProvider::provideBasicDiffGeneration();
 | |
|     }
 | |
| 
 | |
|     public function provideFilePairs(): array
 | |
|     {
 | |
|         $cases     = [];
 | |
|         $fromFile  = __FILE__;
 | |
|         $vendorDir = \realpath(__DIR__ . '/../../../vendor');
 | |
| 
 | |
|         $fileIterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($vendorDir, \RecursiveDirectoryIterator::SKIP_DOTS));
 | |
| 
 | |
|         /** @var \SplFileInfo $file */
 | |
|         foreach ($fileIterator as $file) {
 | |
|             if ('php' !== $file->getExtension()) {
 | |
|                 continue;
 | |
|             }
 | |
| 
 | |
|             $toFile                                                                                         = $file->getPathname();
 | |
|             $cases[\sprintf("Diff file:\n\"%s\"\nvs.\n\"%s\"\n", \realpath($fromFile), \realpath($toFile))] = [$fromFile, $toFile];
 | |
|             $fromFile                                                                                       = $toFile;
 | |
|         }
 | |
| 
 | |
|         return $cases;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Compare diff create by builder and against one create by `diff` command.
 | |
|      *
 | |
|      * @param string $diff
 | |
|      * @param string $from
 | |
|      * @param string $to
 | |
|      *
 | |
|      * @dataProvider provideBasicDiffGeneration
 | |
|      */
 | |
|     public function testIntegrationDiffOutputBuilderVersusDiffCommand(string $diff, string $from, string $to): void
 | |
|     {
 | |
|         $this->assertNotSame('', $diff);
 | |
|         $this->assertValidUnifiedDiffFormat($diff);
 | |
| 
 | |
|         $this->assertNotFalse(\file_put_contents($this->fileFrom, $from));
 | |
|         $this->assertNotFalse(\file_put_contents($this->fileTo, $to));
 | |
| 
 | |
|         $p = new Process(\sprintf('diff -u %s %s', \escapeshellarg($this->fileFrom), \escapeshellarg($this->fileTo)));
 | |
|         $p->run();
 | |
|         $this->assertSame(1, $p->getExitCode()); // note: Process assumes exit code 0 for `isSuccessful`, however `diff` uses the exit code `1` for success with diff
 | |
| 
 | |
|         $output = $p->getOutput();
 | |
| 
 | |
|         $diffLines    = \preg_split('/(.*\R)/', $diff, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
 | |
|         $diffLines[0] = \preg_replace('#^\-\-\- .*#', '--- /' . $this->fileFrom, $diffLines[0], 1);
 | |
|         $diffLines[1] = \preg_replace('#^\+\+\+ .*#', '+++ /' . $this->fileFrom, $diffLines[1], 1);
 | |
|         $diff         = \implode('', $diffLines);
 | |
| 
 | |
|         $outputLines    = \preg_split('/(.*\R)/', $output, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
 | |
|         $outputLines[0] = \preg_replace('#^\-\-\- .*#', '--- /' . $this->fileFrom, $outputLines[0], 1);
 | |
|         $outputLines[1] = \preg_replace('#^\+\+\+ .*#', '+++ /' . $this->fileFrom, $outputLines[1], 1);
 | |
|         $output         = \implode('', $outputLines);
 | |
| 
 | |
|         $this->assertSame($diff, $output);
 | |
|     }
 | |
| 
 | |
|     private function doIntegrationTestGitApply(string $diff, string $from, string $to): void
 | |
|     {
 | |
|         $this->assertNotSame('', $diff);
 | |
|         $this->assertValidUnifiedDiffFormat($diff);
 | |
| 
 | |
|         $diff = self::setDiffFileHeader($diff, $this->fileFrom);
 | |
| 
 | |
|         $this->assertNotFalse(\file_put_contents($this->fileFrom, $from));
 | |
|         $this->assertNotFalse(\file_put_contents($this->filePatch, $diff));
 | |
| 
 | |
|         $p = new Process(\sprintf(
 | |
|             'git --git-dir %s apply --check -v --unsafe-paths --ignore-whitespace %s',
 | |
|             \escapeshellarg($this->dir),
 | |
|             \escapeshellarg($this->filePatch)
 | |
|         ));
 | |
| 
 | |
|         $p->run();
 | |
| 
 | |
|         $this->assertProcessSuccessful($p);
 | |
|     }
 | |
| 
 | |
|     private function doIntegrationTestPatch(string $diff, string $from, string $to): void
 | |
|     {
 | |
|         $this->assertNotSame('', $diff);
 | |
|         $this->assertValidUnifiedDiffFormat($diff);
 | |
| 
 | |
|         $diff = self::setDiffFileHeader($diff, $this->fileFrom);
 | |
| 
 | |
|         $this->assertNotFalse(\file_put_contents($this->fileFrom, $from));
 | |
|         $this->assertNotFalse(\file_put_contents($this->filePatch, $diff));
 | |
| 
 | |
|         $command = \sprintf(
 | |
|             'patch -u --verbose --posix %s < %s',
 | |
|             \escapeshellarg($this->fileFrom),
 | |
|             \escapeshellarg($this->filePatch)
 | |
|         );
 | |
| 
 | |
|         $p = new Process($command);
 | |
|         $p->run();
 | |
| 
 | |
|         $this->assertProcessSuccessful($p);
 | |
| 
 | |
|         $this->assertStringEqualsFile(
 | |
|             $this->fileFrom,
 | |
|             $to,
 | |
|             \sprintf('Patch command "%s".', $command)
 | |
|         );
 | |
|     }
 | |
| 
 | |
|     private function assertProcessSuccessful(Process $p): void
 | |
|     {
 | |
|         $this->assertTrue(
 | |
|             $p->isSuccessful(),
 | |
|             \sprintf(
 | |
|                 "Command exec. was not successful:\n\"%s\"\nOutput:\n\"%s\"\nStdErr:\n\"%s\"\nExit code %d.\n",
 | |
|                 $p->getCommandLine(),
 | |
|                 $p->getOutput(),
 | |
|                 $p->getErrorOutput(),
 | |
|                 $p->getExitCode()
 | |
|             )
 | |
|         );
 | |
|     }
 | |
| 
 | |
|     private function cleanUpTempFiles(): void
 | |
|     {
 | |
|         @\unlink($this->fileFrom . '.orig');
 | |
|         @\unlink($this->fileFrom . '.rej');
 | |
|         @\unlink($this->fileFrom);
 | |
|         @\unlink($this->fileTo);
 | |
|         @\unlink($this->filePatch);
 | |
|     }
 | |
| 
 | |
|     private static function setDiffFileHeader(string $diff, string $file): string
 | |
|     {
 | |
|         $diffLines    = \preg_split('/(.*\R)/', $diff, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
 | |
|         $diffLines[0] = \preg_replace('#^\-\-\- .*#', '--- /' . $file, $diffLines[0], 1);
 | |
|         $diffLines[1] = \preg_replace('#^\+\+\+ .*#', '+++ /' . $file, $diffLines[1], 1);
 | |
| 
 | |
|         return \implode('', $diffLines);
 | |
|     }
 | |
| }
 |