Test.php #1

  • //
  • guest/
  • perforce_software/
  • chronicle/
  • main/
  • tests/
  • phpunit/
  • P4Cms/
  • Diff/
  • Test.php
  • View
  • Commits
  • Open Download .zip Download (11 KB)
<?php
/**
 * Test diff
 *
 * @copyright   2011 Perforce Software. All rights reserved.
 * @license     Please see LICENSE.txt in top-level folder of this distribution.
 * @version     <release>/<patch>
 */
class P4Cms_Diff_Test extends TestCase
{
    /**
     * Test diff of assets where results have been manually inspected.
     */
    public function testCompareAssetOne()
    {
        $left   = file_get_contents(TEST_ASSETS_PATH . '/files/diff-left-1.txt');
        $right  = file_get_contents(TEST_ASSETS_PATH . '/files/diff-right-1.txt');
        
        $left   = str_replace("\r\n", "\n", $left);
        $right  = str_replace("\r\n", "\n", $right);
        
        $diff   = new P4Cms_Diff;
        $result = $diff->compare($left, $right);

        $this->assertTrue($result instanceof P4Cms_Diff_Result);

        // ensure we got the (previously manually inspected) expected result.
        $this->assertSame(
            unserialize(file_get_contents(TEST_ASSETS_PATH . '/files/diff-expected-1.txt')),
            $result->getRawResult(),
            "Unexpected diff result."
        );

        // exercise result.
        $this->assertTrue($result instanceof P4Cms_Diff_Result);
        $this->assertTrue($result->hasDiffs());
        $this->assertSame(4, $result->getDiffCount());
        $this->assertSame(9, count($result->getChunks()));
        $this->assertSame(4, count($result->getDiffChunks()));

        // exercise chunks.
        $chunks   = $result->getChunks();
        $expected = array(
            array('same',   6),
            array('change', 39),
            array('same',   26),
            array('change', 2),
            array('same',   214),
            array('insert', 4),
            array('same',   120),
            array('insert', 16),
            array('same',   46)
        );
        for ($i = 0; $i < count($chunks); $i++) {
            $chunk = $chunks[$i];
            $this->assertSame($expected[$i][0], $chunk->getChunkType());
            $this->assertSame($expected[$i][1], $chunk->getMaxValueCount());
            $this->assertTrue(
                call_user_func(array($chunk, 'is' . ucfirst($expected[$i][0])))
            );
        }

        // rebuild left-hand from chunks.
        $lines = array();
        foreach ($chunks as $chunk) {
            $lines = array_merge($lines, $chunk->getLeft());
        }
        $this->assertSame($left, implode("\n", $lines));

        // rebuild right-hand from chunks.
        $lines = array();
        foreach ($chunks as $chunk) {
            $lines = array_merge($lines, $chunk->getRight());
        }
        $this->assertSame($right, implode("\n", $lines));
    }

    /**
     * Try to compare models with fields.
     */
    public function testCompareModels()
    {
        $left = new P4Cms_Model(
            array(
                'one'   => "a",
                'two'   => "b",
                'three' => "foo bar\n"
                        .  "baz bof\r"
                        .  "zig zag\n"
            )
        );

        $right = new P4Cms_Model(
            array(
                'one'   => "b",
                'two'   => "b",
                'three' => "foo barnacle\r\n"
                        .  "baz bof\n"
                        .  "ziggery\n"
            )
        );

        $diff   = new P4Cms_Diff;
        $result = $diff->compareModels($left, $right);

        $this->assertTrue($result instanceof P4Cms_Diff_ResultCollection);
        $keys = array();
        foreach ($result as $field => $diffResult) {
            $keys[] = $field;
        }
        $this->assertEquals(array('one', 'two', 'three'), $keys, 'Expected fields in result.');
        $this->assertEquals(3, $result->getDiffCount(), 'Expected diff count.');
        $this->assertEquals(2, $result['three']->getDiffCount(), 'Expected diffs for three.');
        $rawResult = $result['three']->getRawResult();
        $this->assertEquals(1, count($rawResult[0]['i']), 'Expected raw result for three.');

        // make sure we can skip fields
        $options = new P4Cms_Diff_OptionsCollection;
        $options['two'] = new P4Cms_Diff_Options;
        $options['two']->setSkipped(true);
        $result = $diff->compareModels($left, $right, $options);

        $this->assertTrue($result instanceof P4Cms_Diff_ResultCollection);
        $this->assertEquals(3, $result->getDiffCount(), 'Expected diff count.');
        $keys = array();
        foreach ($result as $field => $diffResult) {
            $keys[] = $field;
        }
        $this->assertEquals(array('one', 'three'), $keys, 'Expected fields in result.');
        $this->assertEquals(2, $result['three']->getDiffCount(), 'Expected diffs for three.');
        $rawResult = $result['three']->getRawResult();
        $this->assertEquals(1, count($rawResult[0]['i']), 'Expected raw result for three.');
    }

    /**
     * Test that diff behaves as expected with identical inputs
     */
    public function testCompareIdentical()
    {
        $left  = file_get_contents(TEST_ASSETS_PATH . '/files/diff-left-1.txt');
        $right = $left;

        $diff   = new P4Cms_Diff;
        $result = $diff->compare($left, $right);

        $this->assertTrue($result instanceof P4Cms_Diff_Result);
        $this->assertFalse($result->hasDiffs());
        $this->assertSame(0, $result->getDiffCount());
        $this->assertSame(1, count($result->getChunks()));
        $this->assertSame(0, count($result->getDiffChunks()));
    }

    /**
     * Test whitespace detection.
     */
    public function testWhitespaceChanges()
    {
        $left   = "this is a string";
        $right  = "this is  a string";
        $diff   = new P4Cms_Diff;
        $result = $diff->compare($left, $right);
        $chunks = $result->getDiffChunks();

        $this->assertTrue($result->isWhitespaceChange());
        $this->assertTrue(current($chunks)->isWhitespaceChange());

        $left  .= "\nsecond line\nthird line";
        $right .= "\nsecond line\ndifferent third line";
        $diff   = new P4Cms_Diff;
        $result = $diff->compare($left, $right);
        $chunks = $result->getDiffChunks();
        
        $this->assertFalse($result->isWhitespaceChange());
        $this->assertTrue(current($chunks)->isWhitespaceChange());
        $this->assertFalse(end($chunks)->isWhitespaceChange());

        // try semantic flag.
        $left   = "this is a string";
        $right  = "this is astring";
        $diff   = new P4Cms_Diff;
        $result = $diff->compare($left, $right);
        $chunks = $result->getDiffChunks();
        $this->assertFalse($result->isWhitespaceChange());
        $this->assertTrue($result->isWhitespaceChange(false));
    }

    /**
     * Test split arguments option.
     */
    public function testSplitArgs()
    {
        $left  = "foo bar\nzig\nzag";
        $right = "foo baz\nzig\nzag";
        $diff  = new P4Cms_Diff;

        // default should be lines.
        $result = $diff->compare($left, $right);
        $chunks = $result->getChunks();
        $this->assertSame(2, count($chunks));

        // try with chars.
        $options = new P4Cms_Diff_Options;
        $options->setSplitArgs(P4Cms_Diff_Options::PATTERN_CHARS, PREG_SPLIT_NO_EMPTY);
        $result = $diff->compare($left, $right, $options);
        $chunks = $result->getChunks();
        $this->assertSame(3, count($chunks));
        $this->assertSame("foo ba", implode('', $chunks[0]->getLeft()));
        $this->assertSame("foo ba", implode('', $chunks[0]->getRight()));
        $this->assertSame("r", implode('', $chunks[1]->getLeft()));
        $this->assertSame("z", implode('', $chunks[1]->getRight()));
        $this->assertSame("\nzig\nzag", implode('', $chunks[2]->getLeft()));
        $this->assertSame("\nzig\nzag", implode('', $chunks[2]->getRight()));
    }

    /**
     * Test sub-diff feature of chunks
     */
    public function testSubDiff()
    {
        $left  = "foo bar\nzig\nzag";
        $right = "foo baz\nzig\nzag";
        $diff  = new P4Cms_Diff;

        // initial compare on line boundaries.
        $result = $diff->compare($left, $right);
        $chunks = $result->getChunks();
        $this->assertSame(2, count($chunks));

        // do a sub-diff on first line (defaults to char boundary)
        $subResult = $chunks[0]->getSubDiff(0);
        $subChunks = $subResult->getChunks();
        $this->assertTrue($subResult instanceof P4Cms_Diff_Result);
        $this->assertTrue(is_array($subChunks));
        $this->assertSame(2, count($subChunks));
        $this->assertSame('same', $subChunks[0]->getChunkType());
        $this->assertSame("foo ba", implode('', $subChunks[0]->getLeft()));
        $this->assertSame("foo ba", implode('', $subChunks[0]->getRight()));
        $this->assertSame('change', $subChunks[1]->getChunkType());
        $this->assertSame("r", implode('', $subChunks[1]->getLeft()));
        $this->assertSame("z", implode('', $subChunks[1]->getRight()));
    }

    /**
     * Test diffing of binaries.
     */
    public function testBinaryDiff()
    {
        // two different files.
        $left   = file_get_contents(TEST_ASSETS_PATH . '/files/test1.pdf');
        $right  = file_get_contents(TEST_ASSETS_PATH . '/files/test2.pdf');
        $diff   = new P4Cms_Diff;
        $result = $diff->compareBinaries($left, $right);
        $chunks = $result->getChunks();

        $this->assertTrue($result->hasDiffs());
        $this->assertSame(1, $result->getDiffCount());
        $this->assertSame(1, count($result->getChunks()));
        $this->assertSame($left, $chunks[0]->getLeft(0));
        $this->assertSame($right, $chunks[0]->getRight(0));

        // ensure calling indirectly works.
        $options = new P4Cms_Diff_Options;
        $options->setBinaryDiff(true);
        $result  = $diff->compare($left, $right, $options);
        $chunks  = $result->getChunks();

        $this->assertTrue($result->hasDiffs());
        $this->assertSame(1, $result->getDiffCount());
        $this->assertSame(1, count($result->getChunks()));
        $this->assertSame($left, $chunks[0]->getLeft(0));
        $this->assertSame($right, $chunks[0]->getRight(0));

        // two identical files.
        $left   = file_get_contents(TEST_ASSETS_PATH . '/images/content-type-icon.png');
        $right  = $left;
        $result = $diff->compare($left, $right, $options);
        $chunks = $result->getChunks();

        $this->assertFalse($result->hasDiffs());
        $this->assertSame(0, $result->getDiffCount());
        $this->assertSame(1, count($result->getChunks()));
        $this->assertSame($left, $chunks[0]->getLeft(0));
        $this->assertSame($right, $chunks[0]->getRight(0));

        // empty left (insertion)
        $left   = null;
        $result = $diff->compare($left, $right, $options);
        $chunks = $result->getChunks();
        $this->assertSame('insert', $chunks[0]->getChunkType());
        
        // empty right (deletion)
        $left   = $right;
        $right  = '';
        $result = $diff->compare($left, $right, $options);
        $chunks = $result->getChunks();
        $this->assertSame('delete', $chunks[0]->getChunkType());
    }
}
# Change User Description Committed
#1 16170 perforce_software Move Chronicle files to follow new path scheme for branching.
//guest/perforce_software/chronicle/tests/phpunit/P4Cms/Diff/Test.php
#1 8972 Matt Attaway Initial add of the Chronicle source code