Completed
Pull Request — master (#580)
by Greg
03:16
created

CollectionCest::toChainData()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 22
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 22
rs 9.2
c 0
b 0
f 0
cc 1
eloc 18
nc 1
nop 1
1
<?php
2
namespace Robo;
3
4
use \CliGuy;
5
6
use Robo\Collection\Temporary;
7
8
class CollectionCest
9
{
10
    public function _before(CliGuy $I)
11
    {
12
        $I->amInPath(codecept_data_dir().'sandbox');
13
    }
14
15 View Code Duplication
    public function toRunMultipleTasksViaACollectionBuilder(CliGuy $I)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
16
    {
17
        // This tests creating multiple tasks in a single builder,
18
        // which implicitly adds them to a collection.  To keep things
19
        // simple, we are only going to use taskFilesystemStack.  It
20
        // would be possible, of course, to do these operations with
21
        // a single FilesystemStack, but our goal is to test creating
22
        // multiple tasks with a builder, and ensure that a propper
23
        // collection is built.
24
        $collection = $I->collectionBuilder();
25
        $result = $collection->taskFilesystemStack()
26
                ->mkdir('a')
27
                ->touch('a/a.txt')
28
            ->rollback(
29
                $I->taskDeleteDir('a')
30
            )
31
            ->taskFilesystemStack()
32
                ->mkdir('a/b')
33
                ->touch('a/b/b.txt')
34
            ->taskFilesystemStack()
35
                ->mkdir('a/c')
36
                ->touch('a/c/c.txt')
37
            ->run();
38
39
        $I->assertEquals(0, $result->getExitCode(), $result->getMessage());
40
41
        // All of the tasks created by the builder should be added
42
        // to a collection, and `run()` should run them all.
43
        $I->seeDirFound('a');
44
        $I->seeFileFound('a/a.txt');
45
        $I->seeDirFound('a/b');
46
        $I->seeFileFound('a/b/b.txt');
47
        $I->seeDirFound('a/c');
48
        $I->seeFileFound('a/c/c.txt');
49
    }
50
51
    public function toUseAWorkingDirWithACollectionBuilder(CliGuy $I)
52
    {
53
        // Run the same test with a working directory.  The working
54
        // directory path will point to a temporary directory which
55
        // will be moved into place once the tasks complete.
56
        $collection = $I->collectionBuilder();
57
        $workDirPath = $collection->workDir("build");
58
        $I->assertNotEquals("build", basename($workDirPath));
59
        $result = $collection->taskFilesystemStack()
60
                ->mkdir("{$workDirPath}/a")
61
                ->touch("{$workDirPath}/a/a.txt")
62
            ->taskFilesystemStack()
63
                ->mkdir("{$workDirPath}/a/b")
64
                ->touch("{$workDirPath}/a/b/b.txt")
65
            ->taskFilesystemStack()
66
                ->mkdir("{$workDirPath}/a/c")
67
                ->touch("{$workDirPath}/a/c/c.txt")
68
            ->run();
69
70
        $I->assertEquals(0, $result->getExitCode(), $result->getMessage());
71
72
        // All of the tasks created by the builder should be added
73
        // to a collection, and `run()` should run them all.
74
        $I->seeDirFound('build/a');
75
        $I->seeFileFound('build/a/a.txt');
76
        $I->seeDirFound('build/a/b');
77
        $I->seeFileFound('build/a/b/b.txt');
78
        $I->seeDirFound('build/a/c');
79
        $I->seeFileFound('build/a/c/c.txt');
80
    }
81
82 View Code Duplication
    public function toRollbackAfterFailureViaACollectionBuilder(CliGuy $I)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
83
    {
84
        // This is like the previous test, toRunMultipleTasksViaACollectionBuilder,
85
        // except we force an error at the end, and confirm that the
86
        // rollback function is called.
87
        $collection = $I->collectionBuilder();
88
        $result = $collection->taskFilesystemStack()
89
                ->mkdir('j')
90
                ->touch('j/j.txt')
91
            ->rollback(
92
                $I->taskDeleteDir('j')
93
            )
94
            ->taskFilesystemStack()
95
                ->mkdir('j/k')
96
                ->touch('j/k/k.txt')
97
            ->taskFilesystemStack()
98
                ->mkdir('j/k/m')
99
                ->touch('j/k/m/m.txt')
100
            ->taskCopyDir(['doesNotExist' => 'copied'])
101
            ->run();
102
103
        $I->assertEquals(1, $result->getExitCode(), $result->getMessage());
104
105
        // All of the tasks created by the builder should be added
106
        // to a collection, and `run()` should run them all.
107
        $I->dontSeeFileFound('q/q.txt');
108
        $I->dontSeeFileFound('j/j.txt');
109
        $I->dontSeeFileFound('j/k/k.txt');
110
        $I->dontSeeFileFound('j/k/m/m.txt');
111
    }
112
113
    public function toRollbackAWorkingDir(CliGuy $I)
114
    {
115
        // Run the same test with a working directory.  The working
116
        // directory path will point to a temporary directory which
117
        // will be moved into place once the tasks complete.
118
        $collection = $I->collectionBuilder();
119
        $workDirPath = $collection->workDir("build");
120
        $I->assertNotEquals("build", basename($workDirPath));
121
        $result = $collection->taskFilesystemStack()
122
                ->mkdir("{$workDirPath}/a")
123
                ->touch("{$workDirPath}/a/a.txt")
124
            ->taskFilesystemStack()
125
                ->mkdir("{$workDirPath}/a/b")
126
                ->touch("{$workDirPath}/a/b/b.txt")
127
            ->taskFilesystemStack()
128
                ->mkdir("{$workDirPath}/a/c")
129
                ->touch("{$workDirPath}/a/c/c.txt")
130
            ->taskCopyDir(['doesNotExist' => 'copied'])
131
            ->run();
132
133
        $I->assertEquals(1, $result->getExitCode(), $result->getMessage());
134
135
        // All of the tasks created by the builder should be added
136
        // to a collection, and `run()` should run them all.
137
        $I->dontSeeFileFound('build/a');
138
        $I->dontSeeFileFound($workDirPath);
139
    }
140
141
    public function toBuildFilesViaAddIterable(CliGuy $I)
142
    {
143
        $processList = ['cats', 'dogs', 'sheep', 'fish', 'horses', 'cows'];
144
145
        $collection = $I->collectionBuilder();
146
        $result = $collection
147
            ->taskFilesystemStack()
148
                ->mkdir('stuff')
149
            ->taskForEach($processList)
150
                ->withBuilder(
151
                    function ($builder, $key, $value) {
152
                        return $builder
153
                            ->taskFilesystemStack()
154
                                ->touch("stuff/{$value}.txt");
155
                    }
156
                )
157
            ->run();
158
159
        $I->assertEquals(0, $result->getExitCode(), $result->getMessage());
160
161
        $I->seeFileFound('stuff/cats.txt');
162
        $I->seeFileFound('stuff/dogs.txt');
163
        $I->seeFileFound('stuff/sheep.txt');
164
        $I->seeFileFound('stuff/fish.txt');
165
        $I->seeFileFound('stuff/horses.txt');
166
        $I->seeFileFound('stuff/cows.txt');
167
    }
168
169
    public function toRollbackANestedCollection(CliGuy $I)
170
    {
171
        // This is like the previous test, toRunMultipleTasksViaACollectionBuilder,
172
        // except we force an error at the end, and confirm that the
173
        // rollback function is called.
174
        $collection = $I->collectionBuilder();
175
        $collection->taskFilesystemStack()
176
                ->mkdir('j')
177
                ->touch('j/j.txt')
178
            ->rollback(
179
                $I->taskDeleteDir('j')
180
            )
181
            ->taskFilesystemStack()
182
                ->mkdir('j/k')
183
                ->touch('j/k/k.txt')
184
            ->taskFilesystemStack()
185
                ->mkdir('j/k/m')
186
                ->touch('j/k/m/m.txt');
187
188
        $result = $I->collectionBuilder()
189
            ->taskFilesystemStack()
190
                ->mkdir('q')
191
                ->touch('q/q.txt')
192
            ->addTask($collection)
193
            ->taskCopyDir(['doesNotExist' => 'copied'])
194
            ->run();
195
196
        $I->assertEquals(1, $result->getExitCode(), $result->getMessage());
197
198
        // All of the tasks created by the builder should be added
199
        // to a collection, and `run()` should run them all.
200
        $I->seeFileFound('q/q.txt');
201
        $I->dontSeeFileFound('j/j.txt');
202
        $I->dontSeeFileFound('j/k/k.txt');
203
        $I->dontSeeFileFound('j/k/m/m.txt');
204
    }
205
206 View Code Duplication
    public function toCreateDirViaCollection(CliGuy $I)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
207
    {
208
        // Set up a collection to add tasks to
209
        $collection = $I->collectionBuilder();
210
211
        // Set up a filesystem stack
212
        $collection->taskFilesystemStack()
213
            ->mkdir('log')
214
            ->touch('log/error.txt');
215
216
        // FilesystemStack has not run yet, so file should not be found.
217
        $I->dontSeeFileFound('log/error.txt');
218
219
        // Run the task collection; now the files should be present
220
        $collection->run();
221
        $I->seeFileFound('log/error.txt');
222
        $I->seeDirFound('log');
223
    }
224
225
    public function toUseATmpDirAndConfirmItIsDeleted(CliGuy $I)
226
    {
227
        // Set up a collection to add tasks to
228
        $collection = $I->collectionBuilder();
229
230
        // Get a temporary directory to work in. Note that we get a
231
        // name back, but the directory is not created until the task
232
        // runs.  This technically is not thread-safe, but we create
233
        // a random name, so it is unlikely to conflict.
234
        $tmpPath = $collection->tmpDir();
235
236
        // Set up a filesystem stack, but use a collection to defer execution
237
        $collection->taskFilesystemStack()
238
            ->mkdir("$tmpPath/tmp")
239
            ->touch("$tmpPath/tmp/error.txt")
240
            ->rename("$tmpPath/tmp", "$tmpPath/log");
241
242
        // Copy our tmp directory to a location that is not transient
243
        $collection->taskCopyDir([$tmpPath => 'copied']);
244
245
        // FilesystemStack has not run yet, so no files should be found.
246
        $I->dontSeeFileFound("$tmpPath/tmp/error.txt");
247
        $I->dontSeeFileFound("$tmpPath/log/error.txt");
248
        $I->dontSeeFileFound('copied/log/error.txt');
249
250
        // Run the task collection
251
        $result = $collection->run();
252
        $I->assertEquals(0, $result->getExitCode(), $result->getMessage());
253
        $I->assertEquals($result['path'], $tmpPath, "Tmp dir result matches accessor.");
254
255
        // The file 'error.txt' should have been copied into the "copied" dir.
256
        // This also proves that the tmp directory was created.
257
        $I->seeFileFound('copied/log/error.txt');
258
        // $tmpPath should be deleted after $collection->run() completes.
259
        $I->dontSeeFileFound("$tmpPath/tmp/error.txt");
260
        $I->dontSeeFileFound("$tmpPath/log/error.txt");
261
        $I->dontSeeFileFound("$tmpPath");
262
    }
263
264
    public function toUseATmpDirAndChangeWorkingDirectory(CliGuy $I)
265
    {
266
        // Set up a collection to add tasks to
267
        $collection = $I->collectionBuilder();
268
269
        $cwd = getcwd();
270
271
        $tmpPath = $collection->taskTmpDir()
272
            ->cwd()
273
            ->getPath();
274
275
        // Set up a filesystem stack, but use a collection to defer execution.
276
        // Note that since we used 'cwd()' above, the relative file paths
277
        // used below will be inside the temporary directory.
278
        $collection->taskFilesystemStack()
279
            ->mkdir("log")
280
            ->touch("log/error.txt");
281
282
        // Copy our tmp directory to a location that is not transient
283
        $collection->taskCopyDir(['log' => "$cwd/copied2"]);
284
285
        // FilesystemStack has not run yet, so no files should be found.
286
        $I->dontSeeFileFound("$tmpPath/log/error.txt");
287
        $I->dontSeeFileFound('$cwd/copied2/log/error.txt');
288
289
        // Run the task collection
290
        $result = $collection->run();
291
        $I->assertEquals(0, $result->getExitCode(), $result->getMessage());
292
293
        // The file 'error.txt' should have been copied into the "copied" dir
294
        $I->seeFileFound("$cwd/copied2/error.txt");
295
        // $tmpPath should be deleted after $collection->run() completes.
296
        $I->dontSeeFileFound("$tmpPath/log/error.txt");
297
        // Make sure that 'log' was created in the temporary directory, not
298
        // at the current working directory.
299
        $I->dontSeeFileFound("$cwd/log/error.txt");
300
301
        // Make sure that our working directory was restored.
302
        $finalWorkingDir = getcwd();
303
        $I->assertEquals($cwd, $finalWorkingDir);
304
    }
305
306
    public function toCreateATmpFileAndConfirmItIsDeleted(CliGuy $I)
307
    {
308
        // Set up a collection to add tasks to
309
        $collection = $I->collectionBuilder();
310
311
        // Write to a temporary file. Note that we can get the path
312
        // to the tempoary file that will be created, even though the
313
        // the file is not created until the task collecction runs.
314
        $tmpPath = $collection->taskTmpFile('tmp', '.txt')
315
            ->line("This is a test file")
316
            ->getPath();
317
318
        // Copy our tmp directory to a location that is not transient
319
        $collection->taskFilesystemStack()
320
            ->copy($tmpPath, 'copied.txt');
321
322
        // FilesystemStack has not run yet, so no files should be found.
323
        $I->dontSeeFileFound("$tmpPath");
324
        $I->dontSeeFileFound('copied.txt');
325
326
        // Run the task collection
327
        $result = $collection->run();
328
        $I->assertEquals(0, $result->getExitCode(), $result->getMessage());
329
330
        // The file 'copied.txt' should have been copied from the tmp file
331
        $I->seeFileFound('copied.txt');
332
        // $tmpPath should be deleted after $collection->run() completes.
333
        $I->dontSeeFileFound("$tmpPath");
334
    }
335
336
    public function toUseATmpDirWithAlternateSyntax(CliGuy $I)
337
    {
338
        $collection = $I->collectionBuilder();
339
340
        // This test is equivalent to toUseATmpDirAndConfirmItIsDeleted,
341
        // but uses a different technique to create a collection of tasks.
342
        $tmpPath = $collection->tmpDir();
343
344
        // Now, rather than creating the tasks with a collection builder,
345
        // which automatically adds the tasks to the collection as they are
346
        // created, we will instead create them individually and then add
347
        // them to the collection via the addTaskList() method.
348
        $result = $collection->addTaskList(
349
            [
350
                $I->taskFilesystemStack()->mkdir("$tmpPath/log")->touch("$tmpPath/log/error.txt"),
351
                $I->taskCopyDir([$tmpPath => 'copied3']),
352
            ]
353
        )->run();
354
355
        // The results of this operation should be the same.
356
        $I->assertEquals(0, $result->getExitCode(), $result->getMessage());
357
        $I->seeFileFound('copied3/log/error.txt');
358
        $I->dontSeeFileFound("$tmpPath/log/error.txt");
359
    }
360
361
    public function toCreateATmpDirWithoutACollection(CliGuy $I)
362
    {
363
        // Create a temporary directory, using our function name as
364
        // the prefix for the directory name.
365
        $tmpDirTask = $I->taskTmpDir(__FUNCTION__);
366
        $tmpPath = $tmpDirTask->getPath();
367
        $I->dontSeeFileFound($tmpPath);
368
        $tmpDirTask->run();
369
        $I->seeDirFound($tmpPath);
370
        // Creating a temporary directory without a task collection will
371
        // cause the temporary directory to be deleted when the program
372
        // terminates.  We can force it to clean up sooner by calling
373
        // TransientManager::complete(); note that this deletes ALL global tmp
374
        // directories, so this is not thread-safe!  Useful in tests, though.
375
        Temporary::complete();
376
        $I->dontSeeFileFound($tmpPath);
377
    }
378
379
    public function toCreateATmpDirUsingShortcut(CliGuy $I)
380
    {
381
        // Create a temporary directory, using our function name as
382
        // the prefix for the directory name.
383
        $tmpPath = $I->shortcutTmpDir(__FUNCTION__);
384
        $I->seeDirFound($tmpPath);
385
        // Creating a temporary directory without a task collection will
386
        // cause the temporary directory to be deleted when the program
387
        // terminates.  We can force it to clean up sooner by calling
388
        // TransientManager::complete(); note that this deletes ALL global tmp
389
        // directories, so this is not thread-safe!  Useful in tests, though.
390
        Temporary::complete();
391
        $I->dontSeeFileFound($tmpPath);
392
    }
393
394
    public function toThrowAnExceptionAndConfirmItIsCaught(CliGuy $I)
395
    {
396
        $collection = $I->getContainer()->get('collection');
397
398
        $collection->addCode(
399
            function () {
400
                throw new \RuntimeException('Error');
401
            }
402
        );
403
        $result = $collection->run();
404
        $I->assertEquals('Error', $result->getMessage());
405
        $I->assertEquals(1, $result->getExitCode());
406
    }
407
408
    public function toChainData(CliGuy $I)
409
    {
410
        $collection = $I->collectionBuilder();
411
412
        $result = $collection
0 ignored issues
show
Unused Code introduced by
$result is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
413
            ->taskValueProvider()
414
                ->provideMessage('1st')
415
                ->storeState('one')
416
            ->taskValueProvider()
417
                ->provideMessage('2nd')
418
                ->storeState('two')
419
            ->taskValueProvider()
420
                ->chainState('provideItem', 'one')
421
                ->chainState('provideMessage', 'two')
422
                ->storeState('final')
423
            ->run();
424
425
        $state = $collection->getState();
426
        $I->assertEquals('1st', $state['one']);
427
        $I->assertEquals('1st', $state['item']);
428
        $I->assertEquals('2nd', $state['final']);
429
    }
430
}
431