Completed
Push — master ( df4d09...dfc47a )
by Ciaran
08:37
created

KeywordsDumper::dumpStep()   B

Complexity

Conditions 6
Paths 2

Size

Total Lines 38

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 6.1215

Importance

Changes 0
Metric Value
dl 0
loc 38
ccs 17
cts 20
cp 0.85
rs 8.6897
c 0
b 0
f 0
cc 6
nc 2
nop 4
crap 6.1215
1
<?php
2
3
/*
4
 * This file is part of the Behat Gherkin.
5
 * (c) Konstantin Kudryashov <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Behat\Gherkin\Keywords;
12
13
/**
14
 * Gherkin keywords dumper.
15
 *
16
 * @author Konstantin Kudryashov <[email protected]>
17
 */
18
class KeywordsDumper
19
{
20
    private $keywords;
21
    private $keywordsDumper;
22
23
    /**
24
     * Initializes dumper.
25
     *
26
     * @param KeywordsInterface $keywords Keywords instance
27
     */
28 4
    public function __construct(KeywordsInterface $keywords)
29
    {
30 4
        $this->keywords = $keywords;
31 4
        $this->keywordsDumper = array($this, 'dumpKeywords');
32 4
    }
33
34
    /**
35
     * Sets keywords mapper function.
36
     *
37
     * Callable should accept 2 arguments (array $keywords and Boolean $isShort)
38
     *
39
     * @param callable $mapper Mapper function
40
     */
41 1
    public function setKeywordsDumperFunction($mapper)
42
    {
43 1
        $this->keywordsDumper = $mapper;
44 1
    }
45
46
    /**
47
     * Defaults keywords dumper.
48
     *
49
     * @param array   $keywords Keywords list
50
     * @param Boolean $isShort  Is short version
51
     *
52
     * @return string
53
     */
54 3
    public function dumpKeywords(array $keywords, $isShort)
55
    {
56 3
        if ($isShort) {
57 2
            return 1 < count($keywords) ? '(' . implode('|', $keywords) . ')' : $keywords[0];
58
        }
59
60 1
        return $keywords[0];
61
    }
62
63
    /**
64
     * Dumps keyworded feature into string.
65
     *
66
     * @param string  $language Keywords language
67
     * @param Boolean $short    Dump short version
68
     * @param bool    $excludeAsterisk
69
     *
70
     * @return string|array String for short version and array of features for extended
71
     */
72 4
    public function dump($language, $short = true, $excludeAsterisk = false)
73
    {
74 4
        $this->keywords->setLanguage($language);
75 4
        $languageComment = '';
76 4
        if ('en' !== $language) {
77 3
            $languageComment = "# language: $language\n";
78
        }
79
80 4
        $keywords = explode('|', $this->keywords->getFeatureKeywords());
81
82 4
        if ($short) {
83 3
            $keywords = call_user_func($this->keywordsDumper, $keywords, $short);
84
85 3
            return trim($languageComment . $this->dumpFeature($keywords, $short, $excludeAsterisk));
86
        }
87
88 1
        $features = array();
89 1
        foreach ($keywords as $keyword) {
90 1
            $keyword = call_user_func($this->keywordsDumper, array($keyword), $short);
91 1
            $features[] = trim($languageComment . $this->dumpFeature($keyword, $short, $excludeAsterisk));
92
        }
93
94 1
        return $features;
95
    }
96
97
    /**
98
     * Dumps feature example.
99
     *
100
     * @param string  $keyword Item keyword
101
     * @param Boolean $short   Dump short version?
102
     *
103
     * @return string
104
     */
105 4
    protected function dumpFeature($keyword, $short = true, $excludeAsterisk = false)
106
    {
107
        $dump = <<<GHERKIN
108 4
{$keyword}: Internal operations
109
  In order to stay secret
110
  As a secret organization
111
  We need to be able to erase past agents' memory
112
113
114
GHERKIN;
115
116
        // Background
117 4
        $keywords = explode('|', $this->keywords->getBackgroundKeywords());
118 4 View Code Duplication
        if ($short) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
119 3
            $keywords = call_user_func($this->keywordsDumper, $keywords, $short);
120 3
            $dump .= $this->dumpBackground($keywords, $short, $excludeAsterisk);
121
        } else {
122 1
            $keyword = call_user_func($this->keywordsDumper, array($keywords[0]), $short);
123 1
            $dump .= $this->dumpBackground($keyword, $short, $excludeAsterisk);
124
        }
125
126
        // Scenario
127 4
        $keywords = explode('|', $this->keywords->getScenarioKeywords());
128 4 View Code Duplication
        if ($short) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
129 3
            $keywords = call_user_func($this->keywordsDumper, $keywords, $short);
130 3
            $dump .= $this->dumpScenario($keywords, $short, $excludeAsterisk);
131
        } else {
132 1
            foreach ($keywords as $keyword) {
133 1
                $keyword = call_user_func($this->keywordsDumper, array($keyword), $short);
134 1
                $dump .= $this->dumpScenario($keyword, $short, $excludeAsterisk);
135
            }
136
        }
137
138
        // Outline
139 4
        $keywords = explode('|', $this->keywords->getOutlineKeywords());
140 4 View Code Duplication
        if ($short) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
141 3
            $keywords = call_user_func($this->keywordsDumper, $keywords, $short);
142 3
            $dump .= $this->dumpOutline($keywords, $short, $excludeAsterisk);
143
        } else {
144 1
            foreach ($keywords as $keyword) {
145 1
                $keyword = call_user_func($this->keywordsDumper, array($keyword), $short);
146 1
                $dump .= $this->dumpOutline($keyword, $short, $excludeAsterisk);
147
            }
148
        }
149
150 4
        return $dump;
151
    }
152
153
    /**
154
     * Dumps background example.
155
     *
156
     * @param string  $keyword Item keyword
157
     * @param Boolean $short   Dump short version?
158
     *
159
     * @return string
160
     */
161 4
    protected function dumpBackground($keyword, $short = true, $excludeAsterisk = false)
162
    {
163
        $dump = <<<GHERKIN
164 4
  {$keyword}:
165
166
GHERKIN;
167
168
        // Given
169 4
        $dump .= $this->dumpStep(
170 4
            $this->keywords->getGivenKeywords(),
171 4
            'there is agent A',
172 4
            $short,
173 4
            $excludeAsterisk
174
        );
175
176
        // And
177 4
        $dump .= $this->dumpStep(
178 4
            $this->keywords->getAndKeywords(),
179 4
            'there is agent B',
180 4
            $short,
181 4
            $excludeAsterisk
182
        );
183
184 4
        return $dump . "\n";
185
    }
186
187
    /**
188
     * Dumps scenario example.
189
     *
190
     * @param string  $keyword Item keyword
191
     * @param Boolean $short   Dump short version?
192
     *
193
     * @return string
194
     */
195 4
    protected function dumpScenario($keyword, $short = true, $excludeAsterisk = false)
196
    {
197
        $dump = <<<GHERKIN
198 4
  {$keyword}: Erasing agent memory
199
200
GHERKIN;
201
202
        // Given
203 4
        $dump .= $this->dumpStep(
204 4
            $this->keywords->getGivenKeywords(),
205 4
            'there is agent J',
206 4
            $short,
207 4
            $excludeAsterisk
208
        );
209
210
        // And
211 4
        $dump .= $this->dumpStep(
212 4
            $this->keywords->getAndKeywords(),
213 4
            'there is agent K',
214 4
            $short,
215 4
            $excludeAsterisk
216
        );
217
218
        // When
219 4
        $dump .= $this->dumpStep(
220 4
            $this->keywords->getWhenKeywords(),
221 4
            'I erase agent K\'s memory',
222 4
            $short,
223 4
            $excludeAsterisk
224
        );
225
226
        // Then
227 4
        $dump .= $this->dumpStep(
228 4
            $this->keywords->getThenKeywords(),
229 4
            'there should be agent J',
230 4
            $short,
231 4
            $excludeAsterisk
232
        );
233
234
        // But
235 4
        $dump .= $this->dumpStep(
236 4
            $this->keywords->getButKeywords(),
237 4
            'there should not be agent K',
238 4
            $short,
239 4
            $excludeAsterisk
240
        );
241
242 4
        return $dump . "\n";
243
    }
244
245
    /**
246
     * Dumps outline example.
247
     *
248
     * @param string  $keyword Item keyword
249
     * @param Boolean $short   Dump short version?
250
     *
251
     * @return string
252
     */
253 4
    protected function dumpOutline($keyword, $short = true, $excludeAsterisk = false)
254
    {
255
        $dump = <<<GHERKIN
256 4
  {$keyword}: Erasing other agents' memory
257
258
GHERKIN;
259
260
        // Given
261 4
        $dump .= $this->dumpStep(
262 4
            $this->keywords->getGivenKeywords(),
263 4
            'there is agent <agent1>',
264 4
            $short,
265 4
            $excludeAsterisk
266
        );
267
268
        // And
269 4
        $dump .= $this->dumpStep(
270 4
            $this->keywords->getAndKeywords(),
271 4
            'there is agent <agent2>',
272 4
            $short,
273 4
            $excludeAsterisk
274
        );
275
276
        // When
277 4
        $dump .= $this->dumpStep(
278 4
            $this->keywords->getWhenKeywords(),
279 4
            'I erase agent <agent2>\'s memory',
280 4
            $short,
281 4
            $excludeAsterisk
282
        );
283
284
        // Then
285 4
        $dump .= $this->dumpStep(
286 4
            $this->keywords->getThenKeywords(),
287 4
            'there should be agent <agent1>',
288 4
            $short,
289 4
            $excludeAsterisk
290
        );
291
292
        // But
293 4
        $dump .= $this->dumpStep(
294 4
            $this->keywords->getButKeywords(),
295 4
            'there should not be agent <agent2>',
296 4
            $short,
297 4
            $excludeAsterisk
298
        );
299
300 4
        $keywords = explode('|', $this->keywords->getExamplesKeywords());
301 4
        if ($short) {
302 3
            $keyword = call_user_func($this->keywordsDumper, $keywords, $short);
303
        } else {
304 1
            $keyword = call_user_func($this->keywordsDumper, array($keywords[0]), $short);
305
        }
306
307
        $dump .= <<<GHERKIN
308
309 4
    {$keyword}:
310
      | agent1 | agent2 |
311
      | D      | M      |
312
313
GHERKIN;
314
315 4
        return $dump . "\n";
316
    }
317
318
    /**
319
     * Dumps step example.
320
     *
321
     * @param string  $keywords Item keyword
322
     * @param string  $text     Step text
323
     * @param Boolean $short    Dump short version?
324
     *
325
     * @return string
326
     */
327 4
    protected function dumpStep($keywords, $text, $short = true, $excludeAsterisk = false)
328
    {
329 4
        $dump = '';
330
331 4
        $keywords = explode('|', $keywords);
332 4
        if ($short) {
333 3
            $keywords = array_map(
334
                function ($keyword) {
335 3
                    return str_replace('<', '', $keyword);
336 3
                },
337 3
                $keywords
338
            );
339 3
            $keywords = call_user_func($this->keywordsDumper, $keywords, $short);
340
            $dump .= <<<GHERKIN
341 3
    {$keywords} {$text}
342
343
GHERKIN;
344
        } else {
345 1
            foreach ($keywords as $keyword) {
346 1
                if ($excludeAsterisk && '*' === $keyword) {
347
                    continue;
348
                }
349
350 1
                $indent = ' ';
351 1
                if (false !== mb_strpos($keyword, '<', 0, 'utf8')) {
352
                    $keyword = mb_substr($keyword, 0, -1, 'utf8');
353
                    $indent = '';
354
                }
355 1
                $keyword = call_user_func($this->keywordsDumper, array($keyword), $short);
356
                $dump .= <<<GHERKIN
357 1
    {$keyword}{$indent}{$text}
358
359
GHERKIN;
360
            }
361
        }
362
363 4
        return $dump;
364
    }
365
}
366