ArrayLoader.php 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  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\Loader;
  10. use Behat\Gherkin\Node\BackgroundNode;
  11. use Behat\Gherkin\Node\ExampleTableNode;
  12. use Behat\Gherkin\Node\FeatureNode;
  13. use Behat\Gherkin\Node\OutlineNode;
  14. use Behat\Gherkin\Node\PyStringNode;
  15. use Behat\Gherkin\Node\ScenarioNode;
  16. use Behat\Gherkin\Node\StepNode;
  17. use Behat\Gherkin\Node\TableNode;
  18. /**
  19. * From-array loader.
  20. *
  21. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  22. */
  23. class ArrayLoader implements LoaderInterface
  24. {
  25. /**
  26. * Checks if current loader supports provided resource.
  27. *
  28. * @param mixed $resource Resource to load
  29. *
  30. * @return Boolean
  31. */
  32. public function supports($resource)
  33. {
  34. return is_array($resource) && (isset($resource['features']) || isset($resource['feature']));
  35. }
  36. /**
  37. * Loads features from provided resource.
  38. *
  39. * @param mixed $resource Resource to load
  40. *
  41. * @return FeatureNode[]
  42. */
  43. public function load($resource)
  44. {
  45. $features = array();
  46. if (isset($resource['features'])) {
  47. foreach ($resource['features'] as $iterator => $hash) {
  48. $feature = $this->loadFeatureHash($hash, $iterator);
  49. $features[] = $feature;
  50. }
  51. } elseif (isset($resource['feature'])) {
  52. $feature = $this->loadFeatureHash($resource['feature']);
  53. $features[] = $feature;
  54. }
  55. return $features;
  56. }
  57. /**
  58. * Loads feature from provided feature hash.
  59. *
  60. * @param array $hash Feature hash
  61. * @param integer $line
  62. *
  63. * @return FeatureNode
  64. */
  65. protected function loadFeatureHash(array $hash, $line = 0)
  66. {
  67. $hash = array_merge(
  68. array(
  69. 'title' => null,
  70. 'description' => null,
  71. 'tags' => array(),
  72. 'keyword' => 'Feature',
  73. 'language' => 'en',
  74. 'line' => $line,
  75. 'scenarios' => array(),
  76. ),
  77. $hash
  78. );
  79. $background = isset($hash['background']) ? $this->loadBackgroundHash($hash['background']) : null;
  80. $scenarios = array();
  81. foreach ((array) $hash['scenarios'] as $scenarioIterator => $scenarioHash) {
  82. if (isset($scenarioHash['type']) && 'outline' === $scenarioHash['type']) {
  83. $scenarios[] = $this->loadOutlineHash($scenarioHash, $scenarioIterator);
  84. } else {
  85. $scenarios[] = $this->loadScenarioHash($scenarioHash, $scenarioIterator);
  86. }
  87. }
  88. return new FeatureNode($hash['title'], $hash['description'], $hash['tags'], $background, $scenarios, $hash['keyword'], $hash['language'], null, $hash['line']);
  89. }
  90. /**
  91. * Loads background from provided hash.
  92. *
  93. * @param array $hash Background hash
  94. *
  95. * @return BackgroundNode
  96. */
  97. protected function loadBackgroundHash(array $hash)
  98. {
  99. $hash = array_merge(
  100. array(
  101. 'title' => null,
  102. 'keyword' => 'Background',
  103. 'line' => 0,
  104. 'steps' => array(),
  105. ),
  106. $hash
  107. );
  108. $steps = $this->loadStepsHash($hash['steps']);
  109. return new BackgroundNode($hash['title'], $steps, $hash['keyword'], $hash['line']);
  110. }
  111. /**
  112. * Loads scenario from provided scenario hash.
  113. *
  114. * @param array $hash Scenario hash
  115. * @param integer $line Scenario definition line
  116. *
  117. * @return ScenarioNode
  118. */
  119. protected function loadScenarioHash(array $hash, $line = 0)
  120. {
  121. $hash = array_merge(
  122. array(
  123. 'title' => null,
  124. 'tags' => array(),
  125. 'keyword' => 'Scenario',
  126. 'line' => $line,
  127. 'steps' => array(),
  128. ),
  129. $hash
  130. );
  131. $steps = $this->loadStepsHash($hash['steps']);
  132. return new ScenarioNode($hash['title'], $hash['tags'], $steps, $hash['keyword'], $hash['line']);
  133. }
  134. /**
  135. * Loads outline from provided outline hash.
  136. *
  137. * @param array $hash Outline hash
  138. * @param integer $line Outline definition line
  139. *
  140. * @return OutlineNode
  141. */
  142. protected function loadOutlineHash(array $hash, $line = 0)
  143. {
  144. $hash = array_merge(
  145. array(
  146. 'title' => null,
  147. 'tags' => array(),
  148. 'keyword' => 'Scenario Outline',
  149. 'line' => $line,
  150. 'steps' => array(),
  151. 'examples' => array(),
  152. ),
  153. $hash
  154. );
  155. $steps = $this->loadStepsHash($hash['steps']);
  156. if (isset($hash['examples']['keyword'])) {
  157. $examplesKeyword = $hash['examples']['keyword'];
  158. unset($hash['examples']['keyword']);
  159. } else {
  160. $examplesKeyword = 'Examples';
  161. }
  162. $examples = new ExampleTableNode($hash['examples'], $examplesKeyword);
  163. return new OutlineNode($hash['title'], $hash['tags'], $steps, $examples, $hash['keyword'], $hash['line']);
  164. }
  165. /**
  166. * Loads steps from provided hash.
  167. *
  168. * @param array $hash
  169. *
  170. * @return StepNode[]
  171. */
  172. private function loadStepsHash(array $hash)
  173. {
  174. $steps = array();
  175. foreach ($hash as $stepIterator => $stepHash) {
  176. $steps[] = $this->loadStepHash($stepHash, $stepIterator);
  177. }
  178. return $steps;
  179. }
  180. /**
  181. * Loads step from provided hash.
  182. *
  183. * @param array $hash Step hash
  184. * @param integer $line Step definition line
  185. *
  186. * @return StepNode
  187. */
  188. protected function loadStepHash(array $hash, $line = 0)
  189. {
  190. $hash = array_merge(
  191. array(
  192. 'keyword_type' => 'Given',
  193. 'type' => 'Given',
  194. 'text' => null,
  195. 'keyword' => 'Scenario',
  196. 'line' => $line,
  197. 'arguments' => array(),
  198. ),
  199. $hash
  200. );
  201. $arguments = array();
  202. foreach ($hash['arguments'] as $argumentHash) {
  203. if ('table' === $argumentHash['type']) {
  204. $arguments[] = $this->loadTableHash($argumentHash['rows']);
  205. } elseif ('pystring' === $argumentHash['type']) {
  206. $arguments[] = $this->loadPyStringHash($argumentHash, $hash['line'] + 1);
  207. }
  208. }
  209. return new StepNode($hash['type'], $hash['text'], $arguments, $hash['line'], $hash['keyword_type']);
  210. }
  211. /**
  212. * Loads table from provided hash.
  213. *
  214. * @param array $hash Table hash
  215. *
  216. * @return TableNode
  217. */
  218. protected function loadTableHash(array $hash)
  219. {
  220. return new TableNode($hash);
  221. }
  222. /**
  223. * Loads PyString from provided hash.
  224. *
  225. * @param array $hash PyString hash
  226. * @param integer $line
  227. *
  228. * @return PyStringNode
  229. */
  230. protected function loadPyStringHash(array $hash, $line = 0)
  231. {
  232. $line = isset($hash['line']) ? $hash['line'] : $line;
  233. $strings = array();
  234. foreach (explode("\n", $hash['text']) as $string) {
  235. $strings[] = $string;
  236. }
  237. return new PyStringNode($strings, $line);
  238. }
  239. }