| 34 | | null !== $this->plan and $this->output->echoln(sprintf("1..%d", $this->plan)); |
|---|
| | 32 | $d = debug_backtrace(); |
|---|
| | 33 | self::$all_results[] = array( |
|---|
| | 34 | 'file' => isset($d[0]) ? $d[0]['file'] : '', |
|---|
| | 35 | 'tests' => array(), |
|---|
| | 36 | 'stats' => array('plan' => $plan, 'total' => 0, 'failed' => array(), 'passed' => array(), 'skipped' => array()), |
|---|
| | 37 | ); |
|---|
| | 38 | $this->results = &self::$all_results[count(self::$all_results) - 1]; |
|---|
| | 39 | |
|---|
| | 40 | null !== $plan and $this->output->echoln(sprintf("1..%d", $plan)); |
|---|
| | 41 | } |
|---|
| | 42 | |
|---|
| | 43 | static public function reset() |
|---|
| | 44 | { |
|---|
| | 45 | self::$all_results = array(); |
|---|
| | 46 | } |
|---|
| | 47 | |
|---|
| | 48 | static public function to_array() |
|---|
| | 49 | { |
|---|
| | 50 | return self::$all_results; |
|---|
| | 51 | } |
|---|
| | 52 | |
|---|
| | 53 | static public function to_xml($results = null) |
|---|
| | 54 | { |
|---|
| | 55 | if (is_null($results)) |
|---|
| | 56 | { |
|---|
| | 57 | $results = self::$all_results; |
|---|
| | 58 | } |
|---|
| | 59 | |
|---|
| | 60 | $dom = new DOMDocument('1.0', 'UTF-8'); |
|---|
| | 61 | $dom->formatOutput = true; |
|---|
| | 62 | $dom->appendChild($testsuites = $dom->createElement('testsuites')); |
|---|
| | 63 | |
|---|
| | 64 | $errors = 0; |
|---|
| | 65 | $failures = 0; |
|---|
| | 66 | $errors = 0; |
|---|
| | 67 | $skipped = 0; |
|---|
| | 68 | $assertions = 0; |
|---|
| | 69 | |
|---|
| | 70 | foreach ($results as $result) |
|---|
| | 71 | { |
|---|
| | 72 | $testsuites->appendChild($testsuite = $dom->createElement('testsuite')); |
|---|
| | 73 | $testsuite->setAttribute('name', basename($result['file'], '.php')); |
|---|
| | 74 | $testsuite->setAttribute('file', $result['file']); |
|---|
| | 75 | $testsuite->setAttribute('failures', count($result['stats']['failed'])); |
|---|
| | 76 | $testsuite->setAttribute('errors', 0); |
|---|
| | 77 | $testsuite->setAttribute('skipped', count($result['stats']['skipped'])); |
|---|
| | 78 | $testsuite->setAttribute('tests', $result['stats']['plan']); |
|---|
| | 79 | $testsuite->setAttribute('assertions', $result['stats']['plan']); |
|---|
| | 80 | |
|---|
| | 81 | $failures += count($result['stats']['failed']); |
|---|
| | 82 | $skipped += count($result['stats']['skipped']); |
|---|
| | 83 | $assertions += $result['stats']['plan']; |
|---|
| | 84 | |
|---|
| | 85 | foreach ($result['tests'] as $test) |
|---|
| | 86 | { |
|---|
| | 87 | $testsuite->appendChild($testcase = $dom->createElement('testcase')); |
|---|
| | 88 | $testcase->setAttribute('name', $test['message']); |
|---|
| | 89 | $testcase->setAttribute('file', $test['file']); |
|---|
| | 90 | $testcase->setAttribute('line', $test['line']); |
|---|
| | 91 | $testcase->setAttribute('assertions', 1); |
|---|
| | 92 | if (!$test['status']) |
|---|
| | 93 | { |
|---|
| | 94 | $testcase->appendChild($failure = $dom->createElement('failure')); |
|---|
| | 95 | $failure->setAttribute('type', 'lime'); |
|---|
| | 96 | if ($test['error']) |
|---|
| | 97 | { |
|---|
| | 98 | $failure->appendChild($dom->createTextNode($test['error'])); |
|---|
| | 99 | } |
|---|
| | 100 | } |
|---|
| | 101 | } |
|---|
| | 102 | } |
|---|
| | 103 | |
|---|
| | 104 | $testsuites->setAttribute('failures', $failures); |
|---|
| | 105 | $testsuites->setAttribute('errors', $errors); |
|---|
| | 106 | $testsuites->setAttribute('tests', $assertions); |
|---|
| | 107 | $testsuites->setAttribute('assertions', $assertions); |
|---|
| | 108 | $testsuites->setAttribute('skipped', $skipped); |
|---|
| | 109 | |
|---|
| | 110 | return $dom->saveXml(); |
|---|
| 39 | | $total = $this->passed + $this->failed + $this->skipped; |
|---|
| 40 | | |
|---|
| 41 | | null === $this->plan and $this->plan = $total and $this->output->echoln(sprintf("1..%d", $this->plan)); |
|---|
| 42 | | |
|---|
| 43 | | if ($total > $this->plan) |
|---|
| 44 | | { |
|---|
| 45 | | $this->output->red_bar(sprintf(" Looks like you planned %d tests but ran %d extra.", $this->plan, $total - $this->plan)); |
|---|
| 46 | | } |
|---|
| 47 | | elseif ($total < $this->plan) |
|---|
| 48 | | { |
|---|
| 49 | | $this->output->red_bar(sprintf(" Looks like you planned %d tests but only ran %d.", $this->plan, $total)); |
|---|
| 50 | | } |
|---|
| 51 | | |
|---|
| 52 | | if ($this->failed) |
|---|
| 53 | | { |
|---|
| 54 | | $this->output->red_bar(sprintf(" Looks like you failed %d tests of %d.", $this->failed, $this->passed + $this->failed)); |
|---|
| 55 | | } |
|---|
| 56 | | else if ($total == $this->plan) |
|---|
| | 115 | $plan = $this->results['stats']['plan']; |
|---|
| | 116 | $passed = count($this->results['stats']['passed']); |
|---|
| | 117 | $failed = count($this->results['stats']['failed']); |
|---|
| | 118 | $total = $this->results['stats']['total']; |
|---|
| | 119 | is_null($plan) and $plan = $total and $this->output->echoln(sprintf("1..%d", $plan)); |
|---|
| | 120 | |
|---|
| | 121 | if ($total > $plan) |
|---|
| | 122 | { |
|---|
| | 123 | $this->output->red_bar(sprintf(" Looks like you planned %d tests but ran %d extra.", $plan, $total - $plan)); |
|---|
| | 124 | } |
|---|
| | 125 | elseif ($total < $plan) |
|---|
| | 126 | { |
|---|
| | 127 | $this->output->red_bar(sprintf(" Looks like you planned %d tests but only ran %d.", $plan, $total)); |
|---|
| | 128 | } |
|---|
| | 129 | |
|---|
| | 130 | if ($failed) |
|---|
| | 131 | { |
|---|
| | 132 | $this->output->red_bar(sprintf(" Looks like you failed %d tests of %d.", $failed, $passed + $failed)); |
|---|
| | 133 | } |
|---|
| | 134 | else if ($total == $plan) |
|---|
| 80 | | ++$this->failed; |
|---|
| 81 | | } |
|---|
| 82 | | $this->output->echoln(sprintf("%s %d%s", $result ? 'ok' : 'not ok', ++$this->test_nb, $message = $message ? sprintf('%s %s', 0 === strpos($message, '#') ? '' : ' -', $message) : '')); |
|---|
| | 160 | $this->results['stats']['failed'][] = $this->test_nb; |
|---|
| | 161 | } |
|---|
| | 162 | $this->results['tests'][$this->test_nb]['message'] = $message; |
|---|
| | 163 | $this->results['tests'][$this->test_nb]['status'] = $result; |
|---|
| | 164 | $this->output->echoln(sprintf("%s %d%s", $result ? 'ok' : 'not ok', $this->test_nb, $message = $message ? sprintf('%s %s', 0 === strpos($message, '#') ? '' : ' -', $message) : '')); |
|---|
| 205 | | $this->output->diag(sprintf(" %s", str_replace("\n", '', var_export($exp1, true))), sprintf(" %s", $op), sprintf(" %s", str_replace("\n", '', var_export($exp2, true)))); |
|---|
| | 278 | $this->set_last_test_errors(array(sprintf(" %s", str_replace("\n", '', var_export($exp1, true))), sprintf(" %s", $op), sprintf(" %s", str_replace("\n", '', var_export($exp2, true))))); |
|---|
| | 487 | } |
|---|
| | 488 | |
|---|
| | 489 | protected function update_stats() |
|---|
| | 490 | { |
|---|
| | 491 | ++$this->test_nb; |
|---|
| | 492 | ++$this->results['stats']['total']; |
|---|
| | 493 | |
|---|
| | 494 | $this->results['tests'][$this->test_nb]['file'] = 'n/a'; |
|---|
| | 495 | $this->results['tests'][$this->test_nb]['line'] = '0'; |
|---|
| | 496 | $test_file = self::$all_results[count(self::$all_results) - 1]['file']; |
|---|
| | 497 | foreach (debug_backtrace() as $trace) |
|---|
| | 498 | { |
|---|
| | 499 | if (isset($trace['file']) && $test_file == $trace['file']) |
|---|
| | 500 | { |
|---|
| | 501 | $this->results['tests'][$this->test_nb]['file'] = $trace['file']; |
|---|
| | 502 | $this->results['tests'][$this->test_nb]['line'] = $trace['line']; |
|---|
| | 503 | |
|---|
| | 504 | break; |
|---|
| | 505 | } |
|---|
| | 506 | } |
|---|
| | 507 | } |
|---|
| | 508 | |
|---|
| | 509 | protected function set_last_test_errors(array $errors) |
|---|
| | 510 | { |
|---|
| | 511 | $this->output->diag($errors); |
|---|
| | 512 | |
|---|
| | 513 | $this->results['tests'][$this->test_nb]['error'] = implode("\n", $errors); |
|---|
| 623 | | $delta = $this->stats[$file]['plan'] - $this->stats[$file]['nb_tests']; |
|---|
| 624 | | if ($delta > 0) |
|---|
| 625 | | { |
|---|
| 626 | | $this->output->echoln(sprintf('%s%s%s', substr($relative_file, -min(67, strlen($relative_file))), str_repeat('.', 70 - min(67, strlen($relative_file))), $this->output->comment(sprintf('# Looks like you planned %d tests but only ran %d.', $this->stats[$file]['plan'], $this->stats[$file]['nb_tests'])))); |
|---|
| 627 | | $this->stats[$file]['status'] = 'dubious'; |
|---|
| 628 | | $this->stats[$file]['status_code'] = 255; |
|---|
| 629 | | $this->stats['_nb_tests'] += $delta; |
|---|
| 630 | | for ($i = 1; $i <= $delta; $i++) |
|---|
| 631 | | { |
|---|
| 632 | | $this->stats[$file]['failed'][] = $this->stats[$file]['nb_tests'] + $i; |
|---|
| 633 | | } |
|---|
| 634 | | } |
|---|
| 635 | | else if ($delta < 0) |
|---|
| 636 | | { |
|---|
| 637 | | $this->output->echoln(sprintf('%s%s%s', substr($relative_file, -min(67, strlen($relative_file))), str_repeat('.', 70 - min(67, strlen($relative_file))), $this->output->comment(sprintf('# Looks like you planned %s test but ran %s extra.', $this->stats[$file]['plan'], $this->stats[$file]['nb_tests'] - $this->stats[$file]['plan'])))); |
|---|
| 638 | | $this->stats[$file]['status'] = 'dubious'; |
|---|
| 639 | | $this->stats[$file]['status_code'] = 255; |
|---|
| 640 | | for ($i = 1; $i <= -$delta; $i++) |
|---|
| 641 | | { |
|---|
| 642 | | $this->stats[$file]['failed'][] = $this->stats[$file]['plan'] + $i; |
|---|
| 643 | | } |
|---|
| | 758 | $this->stats['total'] += $file_stats['total']; |
|---|
| | 759 | |
|---|
| | 760 | if (!$file_stats['plan']) |
|---|
| | 761 | { |
|---|
| | 762 | $file_stats['plan'] = $file_stats['total']; |
|---|
| | 763 | } |
|---|
| | 764 | |
|---|
| | 765 | $delta = $file_stats['plan'] - $file_stats['total']; |
|---|
| | 766 | if (0 != $delta) |
|---|
| | 767 | { |
|---|
| | 768 | $stats['status'] = 'dubious'; |
|---|
| | 769 | $stats['status_code'] = 255; |
|---|
| 647 | | $this->stats[$file]['status_code'] = 0; |
|---|
| 648 | | $this->stats[$file]['status'] = $this->stats[$file]['failed'] ? 'not ok' : 'ok'; |
|---|
| 649 | | } |
|---|
| 650 | | } |
|---|
| 651 | | |
|---|
| 652 | | $this->output->echoln(sprintf('%s%s%s', substr($relative_file, -min(67, strlen($relative_file))), str_repeat('.', 70 - min(67, strlen($relative_file))), $this->stats[$file]['status'])); |
|---|
| 653 | | if (($nb = count($this->stats[$file]['failed'])) || $return > 0) |
|---|
| 654 | | { |
|---|
| 655 | | if ($nb) |
|---|
| 656 | | { |
|---|
| 657 | | $this->output->echoln(sprintf(" Failed tests: %s", implode(', ', $this->stats[$file]['failed']))); |
|---|
| 658 | | } |
|---|
| 659 | | $this->stats['_failed_files'][] = $file; |
|---|
| 660 | | $this->stats['_failed_tests'] += $nb; |
|---|
| 661 | | } |
|---|
| 662 | | |
|---|
| 663 | | if ('dubious' == $this->stats[$file]['status']) |
|---|
| 664 | | { |
|---|
| 665 | | $this->output->echoln(sprintf(' Test returned status %s', $this->stats[$file]['status_code'])); |
|---|
| 666 | | } |
|---|
| 667 | | } |
|---|
| 668 | | |
|---|
| 669 | | if (count($this->stats['_failed_files'])) |
|---|
| | 773 | $stats['status'] = $file_stats['failed'] ? 'not ok' : 'ok'; |
|---|
| | 774 | $stats['status_code'] = 0; |
|---|
| | 775 | } |
|---|
| | 776 | } |
|---|
| | 777 | |
|---|
| | 778 | $this->output->echoln(sprintf('%s%s%s', substr($relative_file, -min(67, strlen($relative_file))), str_repeat('.', 70 - min(67, strlen($relative_file))), $stats['status'])); |
|---|
| | 779 | |
|---|
| | 780 | if (0 != $stats['status_code']) |
|---|
| | 781 | { |
|---|
| | 782 | $this->output->echoln(sprintf(' Test returned status %s', $stats['status_code'])); |
|---|
| | 783 | } |
|---|
| | 784 | |
|---|
| | 785 | if ('ok' != $stats['status']) |
|---|
| | 786 | { |
|---|
| | 787 | $this->stats['failed_files'][] = $file; |
|---|
| | 788 | } |
|---|
| | 789 | |
|---|
| | 790 | if ($delta > 0) |
|---|
| | 791 | { |
|---|
| | 792 | $this->output->echoln(sprintf(' Looks like you planned %d tests but only ran %d.', $file_stats['plan'], $file_stats['total'])); |
|---|
| | 793 | |
|---|
| | 794 | $this->stats['failed_tests'] += $delta; |
|---|
| | 795 | $this->stats['total'] += $delta; |
|---|
| | 796 | } |
|---|
| | 797 | else if ($delta < 0) |
|---|
| | 798 | { |
|---|
| | 799 | $this->output->echoln(sprintf(' Looks like you planned %s test but ran %s extra.', $file_stats['plan'], $file_stats['total'] - $file_stats['plan'])); |
|---|
| | 800 | } |
|---|
| | 801 | |
|---|
| | 802 | if (false !== $file_stats && $file_stats['failed']) |
|---|
| | 803 | { |
|---|
| | 804 | $this->stats['failed_tests'] += count($file_stats['failed']); |
|---|
| | 805 | |
|---|
| | 806 | $this->output->echoln(sprintf(" Failed tests: %s", implode(', ', $file_stats['failed']))); |
|---|
| | 807 | } |
|---|
| | 808 | } |
|---|
| | 809 | |
|---|
| | 810 | if (count($this->stats['failed_files'])) |
|---|
| 679 | | $this->output->echoln(sprintf($format, substr($relative_file, -min(30, strlen($relative_file))), $file_stat['status_code'], count($file_stat['failed']) + count($file_stat['passed']), count($file_stat['failed']), implode(' ', $file_stat['failed']))); |
|---|
| | 822 | |
|---|
| | 823 | if (isset($stat['output'][0])) |
|---|
| | 824 | { |
|---|
| | 825 | $this->output->echoln(sprintf($format, substr($relative_file, -min(30, strlen($relative_file))), $stat['status_code'], count($stat['output'][0]['stats']['failed']) + count($stat['output'][0]['stats']['passed']), count($stat['output'][0]['stats']['failed']), implode(' ', $stat['output'][0]['stats']['failed']))); |
|---|
| | 826 | } |
|---|
| | 827 | else |
|---|
| | 828 | { |
|---|
| | 829 | $this->output->echoln(sprintf($format, substr($relative_file, -min(30, strlen($relative_file))), $stat['status_code'], '', '', '')); |
|---|
| | 830 | } |
|---|
| 702 | | return isset($this->stats['_failed_files']) ? $this->stats['_failed_files'] : array(); |
|---|
| 703 | | } |
|---|
| 704 | | |
|---|
| 705 | | private function process_test_output($lines) |
|---|
| 706 | | { |
|---|
| 707 | | foreach (explode("\n", $lines) as $text) |
|---|
| 708 | | { |
|---|
| 709 | | if (false !== strpos($text, 'not ok ')) |
|---|
| 710 | | { |
|---|
| 711 | | ++$this->current_test; |
|---|
| 712 | | $test_number = (int) substr($text, 7); |
|---|
| 713 | | $this->stats[$this->current_file]['failed'][] = $test_number; |
|---|
| 714 | | |
|---|
| 715 | | ++$this->stats[$this->current_file]['nb_tests']; |
|---|
| 716 | | ++$this->stats['_nb_tests']; |
|---|
| 717 | | } |
|---|
| 718 | | else if (false !== strpos($text, 'ok ')) |
|---|
| 719 | | { |
|---|
| 720 | | ++$this->stats[$this->current_file]['nb_tests']; |
|---|
| 721 | | ++$this->stats['_nb_tests']; |
|---|
| 722 | | } |
|---|
| 723 | | else if (preg_match('/^1\.\.(\d+)/', $text, $match)) |
|---|
| 724 | | { |
|---|
| 725 | | $this->stats[$this->current_file]['plan'] = $match[1]; |
|---|
| 726 | | } |
|---|
| 727 | | } |
|---|
| 728 | | |
|---|
| 729 | | return; |
|---|
| | 853 | return isset($this->stats['failed_files']) ? $this->stats['failed_files'] : array(); |
|---|