Created
July 9, 2011 17:56
-
-
Save thekid/1073799 to your computer and use it in GitHub Desktop.
XP Framework: Patch for issue #30
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/core/src/main/php/unittest/AssertionFailedError.class.php b/core/src/main/php/unittest/AssertionFailedError.class.php | |
index e4e706c..a6d9377 100644 | |
--- a/core/src/main/php/unittest/AssertionFailedError.class.php | |
+++ b/core/src/main/php/unittest/AssertionFailedError.class.php | |
@@ -7,7 +7,7 @@ | |
/** | |
* Indicates an assertion failed | |
* | |
- * @purpose Exception | |
+ * @test xp://net.xp_framework.unittest.tests.StringComparisonTest | |
*/ | |
class AssertionFailedError extends XPException { | |
public | |
@@ -29,18 +29,61 @@ | |
} | |
/** | |
+ * Format the difference between the expected and actual values | |
+ * | |
+ * @return string | |
+ */ | |
+ public function formatDifference() { | |
+ if (is_string($this->expect) && is_string($this->actual)) { | |
+ $la= strlen($this->actual); | |
+ $le= strlen($this->expect); | |
+ for ($i= 0, $l= min($le, $la); $i < $l; $i++) { // Search from beginning | |
+ if ($this->expect{$i} !== $this->actual{$i}) break; | |
+ } | |
+ for ($j= $le- 1, $k= $la- 1; $k >= $i && $j >= $i; $k--, $j--) { // Search from end | |
+ if ($this->expect{$j} !== $this->actual{$k}) break; | |
+ } | |
+ if ($j < $i && $k < $i) { | |
+ $expect= '"'.$this->expect.'"'; | |
+ $actual= '"'.$this->actual.'"'; | |
+ } else { | |
+ $expect= substr($this->expect, $i, $j+ 1- $i); | |
+ $actual= substr($this->actual, $i, $k+ 1- $i); | |
+ $c= $i <= $l && $i > 0; | |
+ $expect= $c ? '"...'.$expect : '"'.$expect; // Common beginning | |
+ $actual= $c ? '"...'.$actual : '"'.$actual; | |
+ $expect.= ($j < $le- 1) ? '..."' : '"'; // Common ending | |
+ $actual.= ($k < $la- 1) ? '..."' : '"'; | |
+ } | |
+ } else { | |
+ $ta= typeof($this->actual); | |
+ $te= typeof($this->expect); | |
+ if ($ta->equals($te)) { | |
+ $expect= xp::stringOf($this->expect); | |
+ $actual= xp::stringOf($this->actual); | |
+ } else { | |
+ if ($te instanceof XPClass) { | |
+ $expect= $this->expect->toString(); | |
+ } else { | |
+ $expect= NULL == $this->expect ? 'null' : $te->getName().'<'.xp::stringOf($this->expect).'>'; | |
+ } | |
+ if ($ta instanceof XPClass) { | |
+ $actual= $this->actual->toString(); | |
+ } else { | |
+ $actual= NULL == $this->actual ? 'null' : $ta->getName().'<'.xp::stringOf($this->actual).'>'; | |
+ } | |
+ } | |
+ } | |
+ return 'expected: '.$expect.' but was: '.$actual; | |
+ } | |
+ | |
+ /** | |
* Return compound message of this exception. | |
* | |
* @return string | |
*/ | |
public function compoundMessage() { | |
- return sprintf( | |
- "%s (%s) { expected: [%s:%s] but was: [%s:%s] }\n", | |
- $this->getClassName(), | |
- $this->message, | |
- xp::typeOf($this->expect), xp::stringOf($this->expect), | |
- xp::typeOf($this->actual), xp::stringOf($this->actual) | |
- ); | |
+ return $this->getClassName().' ('.$this->message.') { '.$this->formatDifference().' }'; | |
} | |
/** | |
diff --git a/core/src/resources/unittest/unittest.ini b/core/src/resources/unittest/unittest.ini | |
index be6b518..18e93cf 100644 | |
--- a/core/src/resources/unittest/unittest.ini | |
+++ b/core/src/resources/unittest/unittest.ini | |
@@ -29,3 +29,6 @@ class="net.xp_framework.unittest.tests.WebTestCaseTest" | |
[special] | |
class="net.xp_framework.unittest.tests.SpecialMethodsTest" | |
+ | |
+[comparison] | |
+class="net.xp_framework.unittest.tests.ComparisonTest" | |
diff --git a/core/src/test/php/net/xp_framework/unittest/tests/ComparisonTest.class.php b/core/src/test/php/net/xp_framework/unittest/tests/ComparisonTest.class.php | |
new file mode 100644 | |
index 0000000..4054b0d | |
--- /dev/null | |
+++ b/core/src/test/php/net/xp_framework/unittest/tests/ComparisonTest.class.php | |
@@ -0,0 +1,177 @@ | |
+<?php | |
+/* This class is part of the XP framework | |
+ * | |
+ * $Id$ | |
+ */ | |
+ | |
+ uses('unittest.TestCase'); | |
+ | |
+ /** | |
+ * TestCase | |
+ * | |
+ * @see xp://unittest.AssertionFailedError | |
+ */ | |
+ class ComparisonTest extends TestCase { | |
+ | |
+ /** | |
+ * Helper method | |
+ * | |
+ * @param var expected | |
+ * @param var actual | |
+ * @return string | |
+ */ | |
+ protected function compare($expected, $actual) { | |
+ return create(new AssertionFailedError('', $actual, $expected))->formatDifference(); | |
+ } | |
+ | |
+ /** | |
+ * Test strings | |
+ * | |
+ */ | |
+ #[@test] | |
+ public function stringWithCommonBeginning() { | |
+ $prefix= str_repeat('0123456789', 10); | |
+ | |
+ $this->assertEquals( | |
+ 'expected: "...3abc" but was: "...Hello Worlddef"', | |
+ $this->compare($prefix.'3abc', $prefix.'Hello Worlddef') | |
+ ); | |
+ } | |
+ | |
+ /** | |
+ * Test strings | |
+ * | |
+ */ | |
+ #[@test] | |
+ public function stringWithCommonEnding() { | |
+ $postfix= str_repeat('012345678', 10); | |
+ | |
+ $this->assertEquals( | |
+ 'expected: "3..." but was: "Hello World..."', | |
+ $this->compare('3'.$postfix, 'Hello World'.$postfix) | |
+ ); | |
+ } | |
+ | |
+ /** | |
+ * Test strings | |
+ * | |
+ */ | |
+ #[@test] | |
+ public function stringWithCommonBeginningAndEnding() { | |
+ $prefix= str_repeat('0123456789', 10); | |
+ $postfix= str_repeat('012345678', 10); | |
+ | |
+ $this->assertEquals( | |
+ 'expected: "...3..." but was: "...Hello World..."', | |
+ $this->compare($prefix.'3'.$postfix, $prefix.'Hello World'.$postfix) | |
+ ); | |
+ } | |
+ | |
+ /** | |
+ * Test two strings | |
+ * | |
+ */ | |
+ #[@test] | |
+ public function twoStrings() { | |
+ $this->assertEquals( | |
+ 'expected: "Hello" but was: "World"', | |
+ $this->compare('Hello', 'World') | |
+ ); | |
+ } | |
+ | |
+ /** | |
+ * Test two integers | |
+ * | |
+ */ | |
+ #[@test] | |
+ public function twoIntegers() { | |
+ $this->assertEquals( | |
+ 'expected: 3 but was: 1', | |
+ $this->compare(3, 1) | |
+ ); | |
+ } | |
+ | |
+ /** | |
+ * Test two doubles | |
+ * | |
+ */ | |
+ #[@test] | |
+ public function twoDoubles() { | |
+ $this->assertEquals( | |
+ 'expected: 3.1 but was: 1.1', | |
+ $this->compare(3.1, 1.1) | |
+ ); | |
+ } | |
+ | |
+ /** | |
+ * Test two bools | |
+ * | |
+ */ | |
+ #[@test] | |
+ public function twoBools() { | |
+ $this->assertEquals( | |
+ 'expected: true but was: false', | |
+ $this->compare(TRUE, FALSE) | |
+ ); | |
+ } | |
+ | |
+ /** | |
+ * Test two integer arrays | |
+ * | |
+ */ | |
+ #[@test] | |
+ public function twoArrays() { | |
+ $this->assertEquals( | |
+ "expected: [\n 0 => 1\n 1 => 2\n] but was: [\n 0 => 2\n 1 => 3\n]", | |
+ $this->compare(array(1, 2), array(2, 3)) | |
+ ); | |
+ } | |
+ | |
+ /** | |
+ * Test string vs null | |
+ * | |
+ */ | |
+ #[@test] | |
+ public function twoObjects() { | |
+ $this->assertEquals( | |
+ 'expected: unittest.TestCase<a> but was: unittest.TestCase<b>', | |
+ $this->compare(new TestCase('a'), new TestCase('b')) | |
+ ); | |
+ } | |
+ /** | |
+ * Test string vs int | |
+ * | |
+ */ | |
+ #[@test] | |
+ public function stringVsInt() { | |
+ $this->assertEquals( | |
+ 'expected: string<"3"> but was: int<3>', | |
+ $this->compare('3', 3) | |
+ ); | |
+ } | |
+ | |
+ /** | |
+ * Test string vs double | |
+ * | |
+ */ | |
+ #[@test] | |
+ public function stringVsDouble() { | |
+ $this->assertEquals( | |
+ 'expected: string<"3"> but was: double<3>', | |
+ $this->compare('3', 3.0) | |
+ ); | |
+ } | |
+ | |
+ /** | |
+ * Test string vs null | |
+ * | |
+ */ | |
+ #[@test] | |
+ public function stringVsNull() { | |
+ $this->assertEquals( | |
+ 'expected: string<"null"> but was: null', | |
+ $this->compare('null', NULL) | |
+ ); | |
+ } | |
+ } | |
+?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
What the
formatDifference()
method does: