/** * Assert that two values are equal. The test fails if they are not. * * NOTE: This method uses PHP's strict equality test operator ("===") to * compare values. This means values and types must be equal, key order must * be identical in arrays, and objects must be referentially identical. * * @param wild The theoretically expected value, generated by careful * reasoning about the properties of the system. * @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 */ protected final function assertEqual($expect, $result, $message = null) { if ($expect === $result) { $this->assertions++; return; } $expect = PhutilReadableSerializer::printableValue($expect); $result = PhutilReadableSerializer::printableValue($result); $where = debug_backtrace(); $where = array_shift($where); $line = idx($where, 'line'); $file = basename(idx($where, 'file')); $output = "Assertion failed at line {$line} in {$file}"; if ($message) { $output .= ": {$message}"; } $output .= "\n"; if (strpos($expect, "\n") === false && strpos($result, "\n") === false) { $output .= "Expected: {$expect}\n"; $output .= "Actual: {$result}"; } else { $output .= "Expected vs Actual Output Diff\n"; $output .= ArcanistDiffUtils::renderDifferences($expect, $result, $lines = 0xffff); } $this->failTest($output); throw new ArcanistPhutilTestTerminatedException($output); }
public function testPrintableValue() { $tests = array(array(null, 'null'), array(true, 'true'), array(false, 'false'), array(0, '0'), array(0.0, '0.0'), array(0.1, '0.1'), array('test', 'test')); foreach ($tests as $test) { list($value, $expect) = $test; $this->assertEqual($expect, PhutilReadableSerializer::printableValue($value)); } }
public function parse($json) { $jsonlint_root = phutil_get_library_root('phutil') . '/../externals/jsonlint'; require_once $jsonlint_root . '/src/Seld/JsonLint/JsonParser.php'; require_once $jsonlint_root . '/src/Seld/JsonLint/Lexer.php'; require_once $jsonlint_root . '/src/Seld/JsonLint/ParsingException.php'; require_once $jsonlint_root . '/src/Seld/JsonLint/Undefined.php'; $parser = new JsonLintJsonParser(); try { $output = $parser->parse($json, $this->getFlags()); } catch (JsonLintParsingException $ex) { $details = $ex->getDetails(); $message = preg_replace("/^Parse error .*\\^\n/s", '', $ex->getMessage()); throw new PhutilJSONParserException($message, idx(idx($details, 'loc', array()), 'last_line'), idx(idx($details, 'loc', array()), 'last_column'), idx($details, 'token'), idx($details, 'expected')); } if (!is_array($output)) { throw new PhutilJSONParserException(pht('%s is not a valid JSON object.', PhutilReadableSerializer::printShort($json))); } return $output; }
public static function handleErrors($event, $value, $metadata) { if (self::$discardMode) { return; } switch ($event) { case PhutilErrorHandler::EXCEPTION: // $value is of type Exception self::$errors[] = array('details' => $value->getMessage(), 'event' => $event, 'file' => $value->getFile(), 'line' => $value->getLine(), 'str' => $value->getMessage(), 'trace' => $metadata['trace']); break; case PhutilErrorHandler::ERROR: // $value is a simple string self::$errors[] = array('details' => $value, 'event' => $event, 'file' => $metadata['file'], 'line' => $metadata['line'], 'str' => $value, 'trace' => $metadata['trace']); break; case PhutilErrorHandler::PHLOG: // $value can be anything self::$errors[] = array('details' => PhutilReadableSerializer::printShallow($value, 3), 'event' => $event, 'file' => $metadata['file'], 'line' => $metadata['line'], 'str' => PhutilReadableSerializer::printShort($value), 'trace' => $metadata['trace']); break; default: error_log('Unknown event : ' . $event); break; } }
/** * All different types of error messages come here before they are * dispatched to the listener; this method also prints them to the PHP error * log. * * @param const Event type constant. * @param wild Event value. * @param dict Event metadata. * @return void * @task internal */ public static function dispatchErrorMessage($event, $value, $metadata) { $timestamp = strftime('%Y-%m-%d %H:%M:%S'); switch ($event) { case PhutilErrorHandler::ERROR: $default_message = sprintf('[%s] ERROR %d: %s at [%s:%d]', $timestamp, $metadata['error_code'], $value, $metadata['file'], $metadata['line']); $metadata['default_message'] = $default_message; error_log($default_message); self::outputStacktrace($metadata['trace']); break; case PhutilErrorHandler::EXCEPTION: $messages = array(); $current = $value; do { $messages[] = '(' . get_class($current) . ') ' . $current->getMessage(); } while ($current = self::getPreviousException($current)); $messages = implode(' {>} ', $messages); if (strlen($messages) > 4096) { $messages = substr($messages, 0, 4096) . '...'; } $default_message = sprintf('[%s] EXCEPTION: %s at [%s:%d]', $timestamp, $messages, self::getRootException($value)->getFile(), self::getRootException($value)->getLine()); $metadata['default_message'] = $default_message; error_log($default_message); self::outputStacktrace(self::getRootException($value)->getTrace()); break; case PhutilErrorHandler::PHLOG: $default_message = sprintf('[%s] PHLOG: %s at [%s:%d]', $timestamp, PhutilReadableSerializer::printShort($value), $metadata['file'], $metadata['line']); $metadata['default_message'] = $default_message; error_log($default_message); break; case PhutilErrorHandler::DEPRECATED: $default_message = sprintf('[%s] DEPRECATED: %s is deprecated; %s', $timestamp, $value, $metadata['why']); $metadata['default_message'] = $default_message; error_log($default_message); break; default: error_log('Unknown event ' . $event); break; } if (self::$errorListener) { static $handling_error; if ($handling_error) { error_log("Error handler was reentered, some errors were not passed to the " . "listener."); return; } $handling_error = true; call_user_func(self::$errorListener, $event, $value, $metadata); $handling_error = false; } }
public function renderForDisplay(PhabricatorUser $viewer) { $data = PhutilReadableSerializer::printableValue($this->data); return phutil_tag('pre', array(), $data); }
/** * All different types of error messages come here before they are * dispatched to the listener; this method also prints them to the PHP error * log. * * @param const Event type constant. * @param wild Event value. * @param dict Event metadata. * @return void * @task internal */ public static function dispatchErrorMessage($event, $value, $metadata) { $timestamp = strftime("%F %T"); switch ($event) { case PhutilErrorHandler::ERROR: if (error_reporting() === 0) { // Respect the use of "@" to silence warnings: if this error was // emitted from a context where "@" was in effect, the // value returned by error_reporting() will be 0. This is the // recommended way to check for this, see set_error_handler() docs // on php.net. break; } $default_message = sprintf('[%s] ERROR %d: %s at [%s:%d]', $timestamp, $metadata['error_code'], $value, $metadata['file'], $metadata['line']); $metadata['default_message'] = $default_message; error_log($default_message); self::outputStacktrace($metadata['trace']); break; case PhutilErrorHandler::EXCEPTION: $default_message = sprintf('[%s] EXCEPTION: %s at [%s:%d]', $timestamp, '(' . get_class($value) . ') ' . $value->getMessage(), $value->getFile(), $value->getLine()); $metadata['default_message'] = $default_message; error_log($default_message); self::outputStacktrace($value->getTrace()); break; case PhutilErrorHandler::PHLOG: $default_message = sprintf('[%s] PHLOG: %s at [%s:%d]', $timestamp, PhutilReadableSerializer::printShort($value), $metadata['file'], $metadata['line']); $metadata['default_message'] = $default_message; error_log($default_message); break; case PhutilErrorHandler::DEPRECATED: $default_message = sprintf('[%s] DEPRECATED: %s is deprecated; %s', $timestamp, $value, $metadata['why']); $metadata['default_message'] = $default_message; error_log($default_message); break; default: error_log('Unknown event ' . $event); break; } if (self::$errorListener) { static $handling_error; if ($handling_error) { error_log("Error handler was reentered, some errors were not passed to the " . "listener."); return; } $handling_error = true; call_user_func(self::$errorListener, $event, $value, $metadata); $handling_error = false; } }
/** * Fail an assertion which checks that some result is equal to a specific * value, like 'true' or 'false'. This prints a readable error message and * fails the current test. * * This method throws and does not return. * * @param string Human readable description of the expected value. * @param string The actual value. * @param string|null Optional assertion message. * @return void * @task internal */ private function failAssertionWithExpectedValue($expect_description, $actual_result, $message) { $caller = self::getCallerInfo(); $file = $caller['file']; $line = $caller['line']; if ($message !== null) { $description = pht("Assertion failed, expected '%s' (at %s:%d): %s", $expect_description, $file, $line, $message); } else { $description = pht("Assertion failed, expected '%s' (at %s:%d).", $expect_description, $file, $line); } $actual_result = PhutilReadableSerializer::printableValue($actual_result); $header = pht('ACTUAL VALUE'); $output = $description . "\n\n" . $header . "\n" . $actual_result; $this->failTest($output); throw new PhutilTestTerminatedException($output); }