/** * Proxy setting properties to real objects. * * @param string $name Property name. * @param mixed $value Property value. * * @throws \UnexpectedValueException If property unknown. * @return float */ public function __set($name, $value) { switch ($name) { case 'Diff_Timeout': $this->diff->setTimeout($value); break; case 'Diff_EditCost': $this->diff->setEditCost($value); break; case 'Match_Threshold': $this->match->setThreshold($value); break; case 'Match_Distance': $this->match->setDistance($value); break; case 'Match_MaxBits': $this->match->setMaxBits($value); break; case 'Patch_DeleteThreshold': $this->patch->setDeleteTreshold($value); break; case 'Patch_Margin': $this->patch->setMargin($value); break; default: throw new \UnexpectedValueException('Unknown property: ' . $name); } }
public function testDiffMainMemoryLeaks() { $text1 = file_get_contents(__DIR__ . '/fixtures/S_performance1.txt'); $text2 = file_get_contents(__DIR__ . '/fixtures/S_performance2.txt'); $n = 20; // Warm up $diff = new Diff(); $diff->setTimeout(0); $diff->main($text1, $text2); unset($diff); $timeStart = microtime(1); $memoryStart = memory_get_usage(); for ($i = 0; $i < $n; $i++) { $diff = new Diff(); $diff->setTimeout(0); $diff->main($text1, $text2); unset($diff); } $timeElapsed = microtime(1) - $timeStart; $memoryUsage = (memory_get_usage() - $memoryStart) / 1024 / 1024; $this->assertLessThan(0.001, $memoryUsage); echo 'Elapsed time: ' . round($timeElapsed, 3) . PHP_EOL; echo 'Memory usage: ' . round($memoryUsage, 10) . PHP_EOL; }
public function testMain() { // Perform a trivial diff. // Null case. $this->assertEquals(array(), $this->d->main("", "", false)->getChanges()); // Equality. $this->assertEquals(array(array(Diff::EQUAL, "abc")), $this->d->main("abc", "abc", false)->getChanges()); // Check '0' strings $this->assertEquals(array(array(Diff::EQUAL, "0"), array(Diff::INSERT, "X"), array(Diff::EQUAL, "12"), array(Diff::INSERT, "X"), array(Diff::EQUAL, "0"), array(Diff::INSERT, "X"), array(Diff::EQUAL, "34"), array(Diff::INSERT, "X"), array(Diff::EQUAL, "0")), $this->d->main("0120340", "0X12X0X34X0", false)->getChanges()); $this->assertEquals(array(array(Diff::EQUAL, "0"), array(Diff::DELETE, "X"), array(Diff::EQUAL, "12"), array(Diff::DELETE, "X"), array(Diff::EQUAL, "0"), array(Diff::DELETE, "X"), array(Diff::EQUAL, "34"), array(Diff::DELETE, "X"), array(Diff::EQUAL, "0")), $this->d->main("0X12X0X34X0", "0120340", false)->getChanges()); $this->assertEquals(array(array(Diff::DELETE, "Apple"), array(Diff::INSERT, "Banana"), array(Diff::EQUAL, "s are a"), array(Diff::INSERT, "lso"), array(Diff::EQUAL, " fruit.")), $this->d->main("Apples are a fruit.", "Bananas are also fruit.", false)->getChanges()); $this->assertEquals(array(array(Diff::DELETE, "a"), array(Diff::INSERT, Utils::unicodeChr(0x680)), array(Diff::EQUAL, "x"), array(Diff::DELETE, "\t"), array(Diff::INSERT, "")), $this->d->main("ax\t", Utils::unicodeChr(0x680) . "x", false)->getChanges()); // Overlaps. $this->assertEquals(array(array(Diff::DELETE, "1"), array(Diff::EQUAL, "a"), array(Diff::DELETE, "y"), array(Diff::EQUAL, "b"), array(Diff::DELETE, "2"), array(Diff::INSERT, "xab")), $this->d->main("1ayb2", "abxab", false)->getChanges()); $this->assertEquals(array(array(Diff::INSERT, "xaxcx"), array(Diff::EQUAL, "abc"), array(Diff::DELETE, "y")), $this->d->main("abcy", "xaxcxabc", false)->getChanges()); $this->assertEquals(array(array(Diff::DELETE, "ABCD"), array(Diff::EQUAL, "a"), array(Diff::DELETE, "="), array(Diff::INSERT, "-"), array(Diff::EQUAL, "bcd"), array(Diff::DELETE, "="), array(Diff::INSERT, "-"), array(Diff::EQUAL, "efghijklmnopqrs"), array(Diff::DELETE, "EFGHIJKLMNOefg")), $this->d->main("ABCDa=bcd=efghijklmnopqrsEFGHIJKLMNOefg", "a-bcd-efghijklmnopqrs", false)->getChanges()); // Large equality. $this->assertEquals(array(array(Diff::INSERT, " "), array(Diff::EQUAL, "a"), array(Diff::INSERT, "nd"), array(Diff::EQUAL, " [[Pennsylvania]]"), array(Diff::DELETE, " and [[New")), $this->d->main("a [[Pennsylvania]] and [[New", " and [[Pennsylvania]]", false)->getChanges()); // Timeout. // 100ms $this->d->setTimeout(0.1); $a = "`Twas brillig, and the slithy toves\nDid gyre and gimble in the wabe:\nAll mimsy were the borogoves,\nAnd the mome raths outgrabe.\n"; $b = "I am the very model of a modern major general,\nI've information vegetable, animal, and mineral,\nI know the kings of England, and I quote the fights historical,\nFrom Marathon to Waterloo, in order categorical.\n"; // Increase the text lengths by 1024 times to ensure a timeout. for ($i = 0; $i < 10; $i++) { $a .= $a; $b .= $b; } $startTime = microtime(1); $this->d->main($a, $b); $endTime = microtime(1); // Test that we took at least the timeout period. $this->assertGreaterThanOrEqual($this->d->getTimeout(), $endTime - $startTime); // Test that we didn't take forever (be forgiving). // Theoretically this test could fail very occasionally if the // OS task swaps or locks up for a second at the wrong moment. // TODO must be $this->d->getTimeout() * 2, but it need some optimization of linesToCharsMunge() $this->assertLessThan($this->d->getTimeout() * 15, $endTime - $startTime); $this->d->setTimeout(0); // Test the linemode speedup. // Must be long to pass the 100 char cutoff. // Simple line-mode. $a = str_repeat("1234567890\n", 13); $b = str_repeat("abcdefghij\n", 13); $this->assertEquals($this->d->main($a, $b, false)->getChanges(), $this->d->main($a, $b, true)->getChanges()); // Single line-mode. $a = str_repeat("1234567890", 13); $b = str_repeat("abcdefghij", 13); $this->assertEquals($this->d->main($a, $b, false)->getChanges(), $this->d->main($a, $b, true)->getChanges()); function rebuildtexts($diffs) { // Construct the two texts which made up the diff originally. $text1 = ""; $text2 = ""; foreach ($diffs as $change) { if ($change[0] != Diff::INSERT) { $text1 .= $change[1]; } if ($change[0] != Diff::DELETE) { $text2 .= $change[1]; } } return array($text1, $text2); } // Overlap line-mode. $a = str_repeat("1234567890\n", 13); $b = "abcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n"; $this->assertEquals(rebuildtexts($this->d->main($a, $b, false)->getChanges()), rebuildtexts($this->d->main($a, $b, true)->getChanges())); // Test null inputs. try { $this->d->main(null, null); $this->fail(); } catch (\InvalidArgumentException $e) { } }