LimeOutputTap.php 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. <?php
  2. /*
  3. * This file is part of the Lime framework.
  4. *
  5. * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
  6. * (c) Bernhard Schussek <bernhard.schussek@symfony-project.com>
  7. *
  8. * This source file is subject to the MIT license that is bundled
  9. * with this source code in the file LICENSE.
  10. */
  11. class LimeOutputTap implements LimeOutputInterface
  12. {
  13. protected
  14. $options = array(),
  15. $result = null,
  16. $expected = null,
  17. $passed = 0,
  18. $actual = 0,
  19. $warnings = 0,
  20. $errors = 0,
  21. $file = null,
  22. $printer = null;
  23. public function __construct(LimePrinter $printer, array $options = array())
  24. {
  25. $this->printer = $printer;
  26. $this->result = new LimeOutputResult();
  27. $this->options = array_merge(array(
  28. 'verbose' => false,
  29. 'base_dir' => null,
  30. ), $options);
  31. }
  32. public function supportsThreading()
  33. {
  34. return false;
  35. }
  36. private function stripBaseDir($path)
  37. {
  38. return is_null($this->options['base_dir']) ? $path : str_replace($this->options['base_dir'], '', $path);
  39. }
  40. public function focus($file)
  41. {
  42. if ($this->file !== $file)
  43. {
  44. $this->printer->printLine('# '.$this->stripBaseDir($file), LimePrinter::INFO);
  45. $this->file = $file;
  46. }
  47. }
  48. public function close()
  49. {
  50. }
  51. public function plan($amount)
  52. {
  53. $this->result->addPlan($amount);
  54. }
  55. public function pass($message, $file, $line)
  56. {
  57. $this->result->addPassed();
  58. if (empty($message))
  59. {
  60. $this->printer->printLine('ok '.$this->result->getNbActual(), LimePrinter::OK);
  61. }
  62. else
  63. {
  64. $this->printer->printText('ok '.$this->result->getNbActual(), LimePrinter::OK);
  65. $this->printer->printLine(' - '.$message);
  66. }
  67. }
  68. public function fail($message, $file, $line, $error = null)
  69. {
  70. $this->result->addFailure(array($message, $file, $line, $error));
  71. if (empty($message))
  72. {
  73. $this->printer->printLine('not ok '.$this->result->getNbActual(), LimePrinter::NOT_OK);
  74. }
  75. else
  76. {
  77. $this->printer->printText('not ok '.$this->result->getNbActual(), LimePrinter::NOT_OK);
  78. $this->printer->printLine(' - '.$message);
  79. }
  80. $this->printer->printLine(sprintf('# Failed test (%s at line %s)', $this->stripBaseDir($file), $line), LimePrinter::COMMENT);
  81. if (!is_null($error))
  82. {
  83. foreach (explode("\n", $error) as $line)
  84. {
  85. $this->printer->printLine('# '.$line, LimePrinter::COMMENT);
  86. }
  87. }
  88. }
  89. public function skip($message, $file, $line)
  90. {
  91. $this->result->addSkipped();
  92. if (empty($message))
  93. {
  94. $this->printer->printText('ok '.$this->result->getNbActual(), LimePrinter::SKIP);
  95. $this->printer->printText(' ');
  96. }
  97. else
  98. {
  99. $this->printer->printText('ok '.$this->result->getNbActual(), LimePrinter::SKIP);
  100. $this->printer->printText(' - '.$message.' ');
  101. }
  102. $this->printer->printLine('# SKIP', LimePrinter::SKIP);
  103. }
  104. public function todo($message, $file, $line)
  105. {
  106. $this->result->addTodo($message);
  107. if (empty($message))
  108. {
  109. $this->printer->printText('not ok '.$this->result->getNbActual(), LimePrinter::TODO);
  110. $this->printer->printText(' ');
  111. }
  112. else
  113. {
  114. $this->printer->printText('not ok '.$this->result->getNbActual(), LimePrinter::TODO);
  115. $this->printer->printText(' - '.$message.' ');
  116. }
  117. $this->printer->printLine('# TODO', LimePrinter::TODO);
  118. }
  119. public function warning($message, $file, $line)
  120. {
  121. $this->result->addWarning(array($message, $file, $line));
  122. $message .= sprintf("\n(in %s on line %s)", $this->stripBaseDir($file), $line);
  123. $this->printer->printLargeBox($message, LimePrinter::WARNING);
  124. }
  125. public function error(LimeError $error)
  126. {
  127. $this->result->addError($error);
  128. $message = sprintf("%s: %s\n(in %s on line %s)", $error->getType(),
  129. $error->getMessage(), $this->stripBaseDir($error->getFile()), $error->getLine());
  130. $this->printer->printLargeBox($message, LimePrinter::ERROR);
  131. $this->printer->printLine('Exception trace:', LimePrinter::COMMENT);
  132. $this->printTrace(null, $error->getFile(), $error->getLine());
  133. foreach ($error->getTrace() as $trace)
  134. {
  135. // hide the part of the trace that is responsible for getting the
  136. // annotations to work
  137. if (strpos($trace['function'], '__lime_annotation_') === 0 && !$this->options['verbose'])
  138. {
  139. break;
  140. }
  141. if (array_key_exists('class', $trace))
  142. {
  143. $method = sprintf('%s%s%s()', $trace['class'], $trace['type'], $trace['function']);
  144. }
  145. else
  146. {
  147. $method = sprintf('%s()', $trace['function']);
  148. }
  149. if (array_key_exists('file', $trace))
  150. {
  151. $this->printTrace($method, $trace['file'], $trace['line']);
  152. }
  153. else
  154. {
  155. $this->printTrace($method);
  156. }
  157. }
  158. $this->printer->printLine('');
  159. }
  160. private function printTrace($method = null, $file = null, $line = null)
  161. {
  162. if (!is_null($method))
  163. {
  164. $method .= ' ';
  165. }
  166. $this->printer->printText(' '.$method.'at ');
  167. if (!is_null($file) && !is_null($line))
  168. {
  169. $this->printer->printText($this->stripBaseDir($file), LimePrinter::TRACE);
  170. $this->printer->printText(':');
  171. $this->printer->printLine($line, LimePrinter::TRACE);
  172. }
  173. else
  174. {
  175. $this->printer->printLine('[internal function]');
  176. }
  177. }
  178. public function info($message)
  179. {
  180. $this->printer->printLine('# '.$message, LimePrinter::INFO);
  181. }
  182. public function comment($message)
  183. {
  184. $this->printer->printLine('# '.$message, LimePrinter::COMMENT);
  185. }
  186. public static function getMessages($actual, $expected, $passed, $errors, $warnings)
  187. {
  188. $messages = array();
  189. if ($passed == $expected && $passed === $actual && $errors == 0)
  190. {
  191. if ($warnings > 0)
  192. {
  193. $messages[] = array('Looks like you\'re nearly there.', LimePrinter::WARNING);
  194. }
  195. else
  196. {
  197. $messages[] = array('Looks like everything went fine.', LimePrinter::HAPPY);
  198. }
  199. }
  200. else if ($passed != $actual)
  201. {
  202. $messages[] = array(sprintf('Looks like you failed %s tests of %s.', $actual - $passed, $actual), LimePrinter::ERROR);
  203. }
  204. else if ($errors > 0)
  205. {
  206. $messages[] = array('Looks like some errors occurred.', LimePrinter::ERROR);
  207. }
  208. if ($actual > $expected && $expected > 0)
  209. {
  210. $messages[] = array(sprintf('Looks like you only planned %s tests but ran %s.', $expected, $actual), LimePrinter::ERROR);
  211. }
  212. else if ($actual < $expected)
  213. {
  214. $messages[] = array(sprintf('Looks like you planned %s tests but only ran %s.', $expected, $actual), LimePrinter::ERROR);
  215. }
  216. return $messages;
  217. }
  218. public function flush()
  219. {
  220. $result = $this->result;
  221. $this->printer->printLine('1..'.$result->getNbExpected());
  222. $messages = self::getMessages($result->getNbActual(), $result->getNbExpected(), $result->getNbPassed(), $result->getNbErrors(), $result->getNbWarnings());
  223. foreach ($messages as $message)
  224. {
  225. list ($message, $style) = $message;
  226. $this->printer->printBox(' '.$message, $style);
  227. }
  228. }
  229. }