Completed
Pull Request — master (#3)
by Harry
03:17
created

MergeFilesTest::testSimpleMergeFiles()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 30
Code Lines 19

Duplication

Lines 30
Ratio 100 %
Metric Value
dl 30
loc 30
rs 8.8571
cc 1
eloc 19
nc 1
nop 0
1
<?php
2
/**
3
 * This file is part of graze/data-file
4
 *
5
 * Copyright (c) 2016 Nature Delivered Ltd. <https://www.graze.com>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 *
10
 * @license https://github.com/graze/data-file/blob/master/LICENSE.md
11
 * @link    https://github.com/graze/data-file
12
 */
13
14
namespace Graze\DataFile\Test\Integration\Modify\Contract;
15
16
use Graze\DataFile\Helper\Process\ProcessFactory;
17
use Graze\DataFile\Modify\Compress\CompressionFactory;
18
use Graze\DataFile\Modify\Compress\Gzip;
19
use Graze\DataFile\Modify\Contract\FileContractorInterface;
20
use Graze\DataFile\Modify\Contract\MergeFiles;
21
use Graze\DataFile\Modify\MakeDirectory;
22
use Graze\DataFile\Node\FileNodeCollection;
23
use Graze\DataFile\Node\FileNodeCollectionInterface;
24
use Graze\DataFile\Node\FileNodeInterface;
25
use Graze\DataFile\Node\LocalFile;
26
use Graze\DataFile\Test\AbstractFileTestCase;
27
use InvalidArgumentException;
28
use Mockery as m;
29
use Symfony\Component\Process\Exception\ProcessFailedException;
30
31
class MergeFilesTest extends AbstractFileTestCase
32
{
33
    /**
34
     * @var ProcessFactory|m\MockInterface
35
     */
36
    protected $processFactory;
37
38
    /**
39
     * @var MergeFiles
40
     */
41
    private $merge;
42
43
    public function setUp()
44
    {
45
        $this->processFactory = m::mock(ProcessFactory::class)->makePartial();
46
        $this->merge = new MergeFiles();
47
        $this->merge->setProcessFactory($this->processFactory);
48
    }
49
50
    public function testInstanceOf()
51
    {
52
        static::assertInstanceOf(FileContractorInterface::class, $this->merge);
53
    }
54
55
    public function testCanContractAcceptsFileNodeCollectionInterface()
56
    {
57
        $collection = m::mock(FileNodeCollectionInterface::class);
58
        $collection->shouldReceive('getIterator')
59
                   ->andReturn([]);
60
61
        $node = m::mock(LocalFile::class);
62
        static::assertTrue($this->merge->canContract($collection, $node));
63
    }
64
65 View Code Duplication
    public function testCanContractOnlyAcceptsLocalFiles()
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...
66
    {
67
        $collection = new FileNodeCollection();
68
        $file1 = m::mock(LocalFile::class);
69
        $file1->shouldReceive('exists')
70
              ->andReturn(true);
71
        $file1->shouldReceive('getCompression')
72
              ->andReturn(CompressionFactory::TYPE_NONE);
73
        $collection->add($file1);
74
75
        $out = m::mock(LocalFile::class);
76
77
        static::assertTrue($this->merge->canContract($collection, $out));
78
79
        $file2 = m::mock(FileNodeInterface::class);
80
        $file2->shouldReceive('getCompression')
81
              ->andReturn(CompressionFactory::TYPE_NONE);
82
        $collection->add($file2);
83
84
        static::assertFalse($this->merge->canContract($collection, $out));
85
    }
86
87 View Code Duplication
    public function testCanContractOnlyWithFilesThatExist()
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...
88
    {
89
        $collection = new FileNodeCollection();
90
        $file1 = m::mock(LocalFile::class);
91
        $file1->shouldReceive('exists')
92
              ->andReturn(true);
93
        $file1->shouldReceive('getCompression')
94
              ->andReturn(CompressionFactory::TYPE_NONE);
95
        $collection->add($file1);
96
97
        $out = m::mock(LocalFile::class);
98
99
        static::assertTrue($this->merge->canContract($collection, $out));
100
101
        $file2 = m::mock(LocalFile::class);
102
        $file2->shouldReceive('exists')
103
              ->andReturn(false);
104
        $file2->shouldReceive('getCompression')
105
              ->andReturn(CompressionFactory::TYPE_NONE);
106
        $collection->add($file2);
107
108
        static::assertFalse($this->merge->canContract($collection, $out));
109
    }
110
111 View Code Duplication
    public function testCanContractOnlyUncompressedFiles()
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...
112
    {
113
        $collection = new FileNodeCollection();
114
        $file1 = m::mock(LocalFile::class);
115
        $file1->shouldReceive('exists')
116
              ->andReturn(true);
117
        $file1->shouldReceive('getCompression')
118
              ->andReturn(CompressionFactory::TYPE_NONE);
119
        $collection->add($file1);
120
121
        $out = m::mock(LocalFile::class);
122
123
        static::assertTrue($this->merge->canContract($collection, $out));
124
125
        $file2 = m::mock(LocalFile::class);
126
        $file2->shouldReceive('exists')
127
              ->andReturn(true);
128
        $file2->shouldReceive('getCompression')
129
              ->andReturn(Gzip::NAME);
130
        $collection->add($file2);
131
132
        static::assertFalse($this->merge->canContract($collection, $out));
133
    }
134
135 View Code Duplication
    public function testCallingContractWithAFileThatCannotBeContractedWillThrowAnException()
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...
136
    {
137
        $collection = new FileNodeCollection();
138
        $file = m::mock(LocalFile::class);
139
        $file->shouldReceive('exists')
140
             ->andReturn(false);
141
        $file->shouldReceive('getCompression')
142
             ->andReturn(CompressionFactory::TYPE_NONE);
143
        $collection->add($file);
144
145
        $target = m::mock(LocalFile::class);
146
147
        $this->expectException(InvalidArgumentException::class);
148
149
        $this->merge->contract($collection, $target);
150
    }
151
152 View Code Duplication
    public function testCallingContractWithANonLocalTargetWillThrowAnException()
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...
153
    {
154
        $collection = new FileNodeCollection();
155
        $file = m::mock(LocalFile::class);
156
        $file->shouldReceive('exists')
157
             ->andReturn(true);
158
        $file->shouldReceive('getCompression')
159
             ->andReturn(CompressionFactory::TYPE_NONE);
160
        $collection->add($file);
161
162
        $target = m::mock(FileNodeInterface::class);
163
164
        static::assertFalse($this->merge->canContract($collection, $target));
165
166
        $this->expectException(InvalidArgumentException::class);
167
168
        $this->merge->contract($collection, $target);
169
    }
170
171 View Code Duplication
    public function testSimpleMergeFiles()
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...
172
    {
173
        $collection = $this->createCollection('simple.merge/', 3);
174
175
        $outputFile = new LocalFile(static::$dir . 'simple.merge.output');
176
177
        $file = $this->merge->contract($collection, $outputFile);
178
179
        static::assertSame($file, $outputFile);
180
        static::assertEquals(
181
            [
182
                "File 1 Line 1",
183
                "File 1 Line 2",
184
                "File 1 Line 3",
185
                "File 2 Line 1",
186
                "File 2 Line 2",
187
                "File 2 Line 3",
188
                "File 3 Line 1",
189
                "File 3 Line 2",
190
                "File 3 Line 3",
191
            ],
192
            $file->getContents()
193
        );
194
195
        $exists = $collection->filter(function (FileNodeInterface $item) {
196
            return $item->exists();
197
        });
198
199
        static::assertCount(3, $exists);
200
    }
201
202
    /**
203
     * @param string $rootDir
204
     * @param int    $numFiles
205
     *
206
     * @return FileNodeCollectionInterface
207
     */
208
    private function createCollection($rootDir, $numFiles)
209
    {
210
        $mkDir = new MakeDirectory();
211
        $collection = new FileNodeCollection();
212
        for ($i = 1; $i <= $numFiles; $i++) {
213
            $file = new LocalFile(static::$dir . $rootDir . 'part_' . $i);
214
            $mkDir->makeDirectory($file);
215
            $file->put("File $i Line 1\nFile $i Line 2\nFile $i Line 3\n");
216
            $collection->add($file);
217
        }
218
        return $collection;
219
    }
220
221 View Code Duplication
    public function testCallingMergeWithKeepOldFilesAsFalseDeletesAllTheFilesInTheCollection()
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...
222
    {
223
        $collection = $this->createCollection('simple.merge.delete/', 3);
224
225
        $outputFile = new LocalFile(static::$dir . 'simple.merge.delete.output');
226
227
        $file = $this->merge->contract($collection, $outputFile, ['keepOldFiles' => false]);
228
229
        static::assertSame($file, $outputFile);
230
        static::assertEquals(
231
            [
232
                "File 1 Line 1",
233
                "File 1 Line 2",
234
                "File 1 Line 3",
235
                "File 2 Line 1",
236
                "File 2 Line 2",
237
                "File 2 Line 3",
238
                "File 3 Line 1",
239
                "File 3 Line 2",
240
                "File 3 Line 3",
241
            ],
242
            $file->getContents()
243
        );
244
245
        $exists = $collection->filter(function (FileNodeInterface $item) {
246
            return $item->exists();
247
        });
248
249
        static::assertCount(0, $exists);
250
    }
251
252
    public function testProcessFailedThrowException()
253
    {
254
        $process = m::mock('Symfony\Component\Process\Process')->makePartial();
255
        $this->processFactory->shouldReceive('createProcess')
256
                             ->andReturn($process);
257
258
        $process->shouldReceive('isSuccessful')->andReturn(false);
259
260
        // set exception as no guarantee process will run on local system
261
        $this->expectException(ProcessFailedException::class);
262
263
        $collection = $this->createCollection('simple.merge/', 3);
264
265
        $outputFile = new LocalFile(static::$dir . 'simple.merge.output');
266
267
        $this->merge->contract($collection, $outputFile);
268
    }
269
270 View Code Duplication
    public function testCallingContractWillPassThroughOptions()
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...
271
    {
272
        $collection = $this->createCollection('simple.contract.pass.through/', 3);
273
        $outputFile = new LocalFile(static::$dir . 'simple.contract.pass.through.output');
274
275
        $file = $this->merge->contract(
276
            $collection,
277
            $outputFile,
278
            [
279
                'keepOldFiles' => true,
280
            ]
281
        );
282
283
        static::assertEquals(
284
            [
285
                "File 1 Line 1",
286
                "File 1 Line 2",
287
                "File 1 Line 3",
288
                "File 2 Line 1",
289
                "File 2 Line 2",
290
                "File 2 Line 3",
291
                "File 3 Line 1",
292
                "File 3 Line 2",
293
                "File 3 Line 3",
294
            ],
295
            $file->getContents()
296
        );
297
298
        $exists = $collection->filter(function (FileNodeInterface $item) {
299
            return $item->exists();
300
        });
301
302
        static::assertCount(3, $exists);
303
    }
304
305
    public function testDeleteOldFilesWillDeleteAnyEmptyDirectories()
306
    {
307
        $collection = $this->createCollection('simple.merge.delete.folder/', 3);
308
309
        $outputFile = new LocalFile(static::$dir . 'simple.merge.delete.output');
310
311
        $file = $this->merge->contract($collection, $outputFile, ['keepOldFiles' => false]);
312
313
        static::assertSame($file, $outputFile);
314
        static::assertEquals(
315
            [
316
                "File 1 Line 1",
317
                "File 1 Line 2",
318
                "File 1 Line 3",
319
                "File 2 Line 1",
320
                "File 2 Line 2",
321
                "File 2 Line 3",
322
                "File 3 Line 1",
323
                "File 3 Line 2",
324
                "File 3 Line 3",
325
            ],
326
            $file->getContents()
327
        );
328
329
        static::assertFalse(file_exists($collection->getAll()[0]->getDirectory()));
330
331
        $exists = $collection->filter(function (FileNodeInterface $item) {
332
            return $item->exists();
333
        });
334
335
        static::assertCount(0, $exists);
336
        static::assertTrue($file->exists(), 'output file should exist');
337
    }
338
}
339