/vendor/codeception/codeception/src/Codeception/TestCase/Cest.php

https://gitlab.com/jhonn/rest · PHP · 206 lines · 184 code · 21 blank · 1 comment · 7 complexity · ee7dd29f51aef0afd7f4f0774fd69dce MD5 · raw file

  1. <?php
  2. namespace Codeception\TestCase;
  3. use Codeception\Events;
  4. use Codeception\Event\TestEvent;
  5. use Codeception\Util\Annotation;
  6. class Cest extends \Codeception\TestCase implements
  7. Interfaces\ScenarioDriven,
  8. Interfaces\Descriptive,
  9. Interfaces\Reported,
  10. Interfaces\Configurable
  11. {
  12. use Shared\Actor;
  13. use Shared\Dependencies;
  14. use Shared\ScenarioPrint;
  15. protected $testClassInstance = null;
  16. protected $testMethod = null;
  17. public function __construct(array $data = array(), $dataName = '')
  18. {
  19. parent::__construct('testCodecept', $data, $dataName);
  20. }
  21. public function getName($withDataSet = TRUE)
  22. {
  23. return $this->testMethod;
  24. }
  25. public function preload()
  26. {
  27. $this->scenario->setFeature($this->getSpecFromMethod());
  28. $code = $this->getRawBody();
  29. $params = (new \ReflectionMethod($this->testClassInstance, $this->testMethod))->getParameters();
  30. $scenarioVar = isset($params[1]) ? $params[1]->getName() : null;
  31. $this->parser->parseFeature($code);
  32. $this->parser->parseScenarioOptions($code, $scenarioVar);
  33. $this->fire(Events::TEST_PARSED, new TestEvent($this));
  34. }
  35. public function getRawBody()
  36. {
  37. $method = new \ReflectionMethod($this->testClassInstance, $this->testMethod);
  38. $start_line = $method->getStartLine() - 1; // it's actually - 1, otherwise you wont get the function() block
  39. $end_line = $method->getEndLine();
  40. $source = file($method->getFileName());
  41. return implode("", array_slice($source, $start_line, $end_line - $start_line));
  42. }
  43. public function testCodecept()
  44. {
  45. $this->fire(Events::TEST_BEFORE, new TestEvent($this));
  46. $this->scenario->run();
  47. $I = $this->makeIObject();
  48. try {
  49. $this->executeBefore($this->testMethod, $I);
  50. $this->executeTestMethod($I);
  51. $this->executeAfter($this->testMethod, $I);
  52. } catch (\Exception $e) {
  53. // fails and errors are now handled by Codeception\PHPUnit\Listener
  54. throw $e;
  55. }
  56. $this->fire(Events::TEST_AFTER, new TestEvent($this));
  57. }
  58. protected function executeBefore($testMethod, $I)
  59. {
  60. if (method_exists($this->testClassInstance, '_before')) {
  61. $this->testClassInstance->_before($I);
  62. }
  63. $annotations = \PHPUnit_Util_Test::parseTestMethodAnnotations(get_class($this->testClassInstance), $testMethod);
  64. if (!empty($annotations['method']['before'])) {
  65. foreach ($annotations['method']['before'] as $m) {
  66. $this->executeContextMethod(trim($m), $I);
  67. }
  68. }
  69. }
  70. protected function executeAfter($testMethod, $I)
  71. {
  72. $annotations = \PHPUnit_Util_Test::parseTestMethodAnnotations(get_class($this->testClassInstance), $testMethod);
  73. if (!empty($annotations['method']['after'])) {
  74. foreach ($annotations['method']['after'] as $m) {
  75. $this->executeContextMethod(trim($m), $I);
  76. }
  77. }
  78. if (method_exists($this->testClassInstance, '_after')) {
  79. $this->testClassInstance->_after($I);
  80. }
  81. }
  82. protected function executeContextMethod($context, $I)
  83. {
  84. if (method_exists($this->testClassInstance, $context)) {
  85. $this->executeBefore($context, $I);
  86. $contextMethod = new \ReflectionMethod($this->testClassInstance, $context);
  87. $contextMethod->setAccessible(true);
  88. $contextMethod->invoke($this->testClassInstance, $I);
  89. $this->executeAfter($context, $I);
  90. return;
  91. }
  92. throw new \LogicException(
  93. "Method $context defined in annotation but does not exists in " . get_class($this->testClassInstance)
  94. );
  95. }
  96. protected function makeIObject()
  97. {
  98. $className = '\\' . $this->actor;
  99. $I = new $className($this->scenario);
  100. $spec = $this->getSpecFromMethod();
  101. if ($spec) {
  102. $I->wantTo($spec);
  103. }
  104. return $I;
  105. }
  106. protected function executeTestMethod($I)
  107. {
  108. $testMethodSignature = array($this->testClassInstance, $this->testMethod);
  109. if (! is_callable($testMethodSignature)) {
  110. throw new \Exception("Method {$this->testMethod} can't be found in tested class");
  111. }
  112. call_user_func($testMethodSignature, $I, $this->scenario);
  113. }
  114. public function getTestClass()
  115. {
  116. return $this->testClassInstance;
  117. }
  118. public function getTestMethod()
  119. {
  120. return $this->testMethod;
  121. }
  122. public function getSpecFromMethod()
  123. {
  124. $text = $this->testMethod;
  125. $text = preg_replace('/([A-Z]+)([A-Z][a-z])/', '\\1 \\2', $text);
  126. $text = preg_replace('/([a-z\d])([A-Z])/', '\\1 \\2', $text);
  127. $text = strtolower($text);
  128. return $text;
  129. }
  130. public function configActor($actor)
  131. {
  132. foreach (['actor', 'guy'] as $annotation) {
  133. $definedActor = Annotation::forMethod($this->testClassInstance, $this->testMethod)->fetch($annotation);
  134. if (!$definedActor) {
  135. $definedActor = Annotation::forClass($this->testClassInstance)->fetch($annotation);
  136. }
  137. if ($definedActor) {
  138. $this->actor = $definedActor;
  139. return $this;
  140. }
  141. }
  142. $this->actor = $actor;
  143. return $this;
  144. }
  145. public function configEnv($env)
  146. {
  147. $this->testClassInstance->env = $env;
  148. return $this;
  149. }
  150. public function getSignature()
  151. {
  152. return get_class($this->getTestClass()) . "::" . $this->getTestMethod();
  153. }
  154. public function getFileName()
  155. {
  156. return $this->testFile;
  157. }
  158. public function toString()
  159. {
  160. return $this->getFeature(). " (".$this->getSignature().")";
  161. }
  162. /**
  163. * @return array
  164. */
  165. public function getReportFields()
  166. {
  167. return [
  168. 'file' => $this->getFileName(),
  169. 'name' => $this->getTestMethod(),
  170. 'class' => get_class($this->getTestClass()),
  171. 'feature' => $this->getFeature()
  172. ];
  173. }
  174. }