From c42bef4e25469836a43e4ca0b4ff3018a3f94f45 Mon Sep 17 00:00:00 2001 From: Joshua Spence Date: Sat, 8 Mar 2014 18:23:14 -0800 Subject: [PATCH] Added some additional assertion methods. Summary: There are quite a few tests in Arcanist, libphutil and Phabricator that do something similar to `$this->assertEqual(false, ...)` or `$this->assertEqual(true, ...)`. This is unnecessarily verbose and it would be cleaner if we had `assertFalse` and `assertTrue` methods. Test Plan: I contemplated adding a unit test for the `getCallerInfo` method but wasn't sure if it was required / where it should live. Reviewers: epriestley, #blessed_reviewers Reviewed By: epriestley CC: Korvin, epriestley, aran Differential Revision: https://secure.phabricator.com/D8460 --- .../engine/phutil/ArcanistPhutilTestCase.php | 105 ++++++++++++++++-- 1 file changed, 94 insertions(+), 11 deletions(-) diff --git a/src/unit/engine/phutil/ArcanistPhutilTestCase.php b/src/unit/engine/phutil/ArcanistPhutilTestCase.php index 73234d77..419c9b4c 100644 --- a/src/unit/engine/phutil/ArcanistPhutilTestCase.php +++ b/src/unit/engine/phutil/ArcanistPhutilTestCase.php @@ -25,6 +25,65 @@ abstract class ArcanistPhutilTestCase { /* -( Making Test Assertions )--------------------------------------------- */ + /** + * Assert that a value is false. The test fails if it is not. + * + * @param wild The empirically derived value, generated by executing the + * test. + * @param string A human-readable description of what these values represent, + * and particularly of what a discrepancy means. + * + * @return void + * @task assert + */ + final protected function assertFalse($result, $message = null) { + if ($result === false) { + $this->assertions++; + return; + } + + $result = PhutilReadableSerializer::printableValue($result); + $caller = self::getCallerInfo(); + + $output = "Assertion failed at line {$caller['line']} in {$caller['file']}"; + + if ($message) { + $output .= ": {$message}"; + } + + $this->failTest($output); + throw new ArcanistPhutilTestTerminatedException($output); + } + + /** + * Assert that a value is true. The test fails if it is not. + * + * @param wild The empirically derived value, generated by executing the + * test. + * @param string A human-readable description of what these values represent, + * and particularly of what a discrepancy means. + * + * @return void + * @task assert + */ + final protected function assertTrue($result, $message = null) { + if ($result === true) { + $this->assertions++; + return; + } + + $result = PhutilReadableSerializer::printableValue($result); + $caller = self::getCallerInfo(); + + $output = "Assertion failed at line {$caller['line']} in {$caller['file']}"; + + if ($message) { + $output .= ": {$message}"; + } + + $this->failTest($output); + throw new ArcanistPhutilTestTerminatedException($output); + } /** * Assert that two values are equal. The test fails if they are not. @@ -51,18 +110,9 @@ abstract class ArcanistPhutilTestCase { $expect = PhutilReadableSerializer::printableValue($expect); $result = PhutilReadableSerializer::printableValue($result); + $caller = self::getCallerInfo(); - foreach (debug_backtrace() as $location) { - if (!preg_match('/^assert[A-Z]/', idx($location, 'function'))) { - break; - } - $where = $location; - } - - $line = idx($where, 'line'); - $file = basename(idx($where, 'file')); - - $output = "Assertion failed at line {$line} in {$file}"; + $output = "Assertion failed at line {$caller['line']} in {$caller['file']}"; if ($message) { $output .= ": {$message}"; @@ -582,4 +632,37 @@ abstract class ArcanistPhutilTestCase { return $this; } + /** + * Returns info about the caller function. + * + * @return map + */ + private static final function getCallerInfo() { + $callee = array(); + $caller = array(); + $seen = false; + + foreach (array_slice(debug_backtrace(), 1) as $location) { + $function = idx($location, 'function'); + + if (!$seen && preg_match('/^assert[A-Z]/', $function)) { + $seen = true; + $caller = $location; + } else if ($seen && !preg_match('/^assert[A-Z]/', $function)) { + $callee = $location; + break; + } + } + + return array( + 'file' => basename(idx($caller, 'file')), + 'line' => idx($caller, 'line'), + 'function' => idx($callee, 'function'), + 'class' => idx($callee, 'class'), + 'object' => idx($caller, 'object'), + 'type' => idx($callee, 'type'), + 'args' => idx($caller, 'args'), + ); + } + }