ExampleNode.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. <?php
  2. /*
  3. * This file is part of the Behat Gherkin.
  4. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5. *
  6. * For the full copyright and license information, please view the LICENSE
  7. * file that was distributed with this source code.
  8. */
  9. namespace Behat\Gherkin\Node;
  10. /**
  11. * Represents Gherkin Outline Example.
  12. *
  13. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  14. */
  15. class ExampleNode implements ScenarioInterface
  16. {
  17. /**
  18. * @var string
  19. */
  20. private $title;
  21. /**
  22. * @var string[]
  23. */
  24. private $tags;
  25. /**
  26. * @var StepNode[]
  27. */
  28. private $outlineSteps;
  29. /**
  30. * @var string[]
  31. */
  32. private $tokens;
  33. /**
  34. * @var integer
  35. */
  36. private $line;
  37. /**
  38. * @var null|StepNode[]
  39. */
  40. private $steps;
  41. /**
  42. * @var string
  43. */
  44. private $outlineTitle;
  45. /**
  46. * Initializes outline.
  47. *
  48. * @param string $title
  49. * @param string[] $tags
  50. * @param StepNode[] $outlineSteps
  51. * @param string[] $tokens
  52. * @param integer $line
  53. * @param string|null $outlineTitle
  54. */
  55. public function __construct($title, array $tags, $outlineSteps, array $tokens, $line, $outlineTitle = null)
  56. {
  57. $this->title = $title;
  58. $this->tags = $tags;
  59. $this->outlineSteps = $outlineSteps;
  60. $this->tokens = $tokens;
  61. $this->line = $line;
  62. $this->outlineTitle = $outlineTitle;
  63. }
  64. /**
  65. * Returns node type string
  66. *
  67. * @return string
  68. */
  69. public function getNodeType()
  70. {
  71. return 'Example';
  72. }
  73. /**
  74. * Returns node keyword.
  75. *
  76. * @return string
  77. */
  78. public function getKeyword()
  79. {
  80. return $this->getNodeType();
  81. }
  82. /**
  83. * Returns example title.
  84. *
  85. * @return string
  86. */
  87. public function getTitle()
  88. {
  89. return $this->title;
  90. }
  91. /**
  92. * Checks if outline is tagged with tag.
  93. *
  94. * @param string $tag
  95. *
  96. * @return bool
  97. */
  98. public function hasTag($tag)
  99. {
  100. return in_array($tag, $this->getTags());
  101. }
  102. /**
  103. * Checks if outline has tags (both inherited from feature and own).
  104. *
  105. * @return bool
  106. */
  107. public function hasTags()
  108. {
  109. return 0 < count($this->getTags());
  110. }
  111. /**
  112. * Returns outline tags (including inherited from feature).
  113. *
  114. * @return string[]
  115. */
  116. public function getTags()
  117. {
  118. return $this->tags;
  119. }
  120. /**
  121. * Checks if outline has steps.
  122. *
  123. * @return bool
  124. */
  125. public function hasSteps()
  126. {
  127. return 0 < count($this->outlineSteps);
  128. }
  129. /**
  130. * Returns outline steps.
  131. *
  132. * @return StepNode[]
  133. */
  134. public function getSteps()
  135. {
  136. return $this->steps = $this->steps ? : $this->createExampleSteps();
  137. }
  138. /**
  139. * Returns example tokens.
  140. *
  141. * @return string[]
  142. */
  143. public function getTokens()
  144. {
  145. return $this->tokens;
  146. }
  147. /**
  148. * Returns outline declaration line number.
  149. *
  150. * @return integer
  151. */
  152. public function getLine()
  153. {
  154. return $this->line;
  155. }
  156. /**
  157. * Returns outline title.
  158. *
  159. * @return string
  160. */
  161. public function getOutlineTitle()
  162. {
  163. return $this->outlineTitle;
  164. }
  165. /**
  166. * Creates steps for this example from abstract outline steps.
  167. *
  168. * @return StepNode[]
  169. */
  170. protected function createExampleSteps()
  171. {
  172. $steps = array();
  173. foreach ($this->outlineSteps as $outlineStep) {
  174. $keyword = $outlineStep->getKeyword();
  175. $keywordType = $outlineStep->getKeywordType();
  176. $text = $this->replaceTextTokens($outlineStep->getText());
  177. $args = $this->replaceArgumentsTokens($outlineStep->getArguments());
  178. $line = $outlineStep->getLine();
  179. $steps[] = new StepNode($keyword, $text, $args, $line, $keywordType);
  180. }
  181. return $steps;
  182. }
  183. /**
  184. * Replaces tokens in arguments with row values.
  185. *
  186. * @param ArgumentInterface[] $arguments
  187. *
  188. * @return ArgumentInterface[]
  189. */
  190. protected function replaceArgumentsTokens(array $arguments)
  191. {
  192. foreach ($arguments as $num => $argument) {
  193. if ($argument instanceof TableNode) {
  194. $arguments[$num] = $this->replaceTableArgumentTokens($argument);
  195. }
  196. if ($argument instanceof PyStringNode) {
  197. $arguments[$num] = $this->replacePyStringArgumentTokens($argument);
  198. }
  199. }
  200. return $arguments;
  201. }
  202. /**
  203. * Replaces tokens in table with row values.
  204. *
  205. * @param TableNode $argument
  206. *
  207. * @return TableNode
  208. */
  209. protected function replaceTableArgumentTokens(TableNode $argument)
  210. {
  211. $table = $argument->getTable();
  212. foreach ($table as $line => $row) {
  213. foreach (array_keys($row) as $col) {
  214. $table[$line][$col] = $this->replaceTextTokens($table[$line][$col]);
  215. }
  216. }
  217. return new TableNode($table);
  218. }
  219. /**
  220. * Replaces tokens in PyString with row values.
  221. *
  222. * @param PyStringNode $argument
  223. *
  224. * @return PyStringNode
  225. */
  226. protected function replacePyStringArgumentTokens(PyStringNode $argument)
  227. {
  228. $strings = $argument->getStrings();
  229. foreach ($strings as $line => $string) {
  230. $strings[$line] = $this->replaceTextTokens($strings[$line]);
  231. }
  232. return new PyStringNode($strings, $argument->getLine());
  233. }
  234. /**
  235. * Replaces tokens in text with row values.
  236. *
  237. * @param string $text
  238. *
  239. * @return string
  240. */
  241. protected function replaceTextTokens($text)
  242. {
  243. foreach ($this->tokens as $key => $val) {
  244. $text = str_replace('<' . $key . '>', $val, $text);
  245. }
  246. return $text;
  247. }
  248. }