Completed
Pull Request — develop (#165)
by
unknown
01:52
created

TestCase::addCommandToMockContainer()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
1
<?php
2
3
/**
4
 * This file is part of the GitElephant package.
5
 *
6
 * (c) Matteo Giachino <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 *
11
 * Just for fun...
12
 */
13
14
namespace GitElephant;
15
16
use \Mockery as m;
17
use \GitElephant\Repository;
18
use \GitElephant\Objects\Author;
19
use \GitElephant\Objects\Commit;
20
use \GitElephant\Command\MvCommand;
21
use \Symfony\Component\Finder\Finder;
22
use \GitElephant\Command\Caller\Caller;
23
use \PHPUnit\Framework\MockObject\MockObject;
24
use \Symfony\Component\Filesystem\Filesystem;
25
use GitElephant\Command\Caller\CallerInterface;
26
27
/**
28
 * Class TestCase
29
 *
30
 * @package GitElephant
31
 */
32
class TestCase extends \PHPUnit\Framework\TestCase
33
{
34
    /**
35
     * @var \GitElephant\Command\Caller\CallerInterface
36
     */
37
    protected $caller;
38
39
    /**
40
     * @var Repository
41
     */
42
    protected $repository;
43
44
    /**
45
     * @var string
46
     */
47
    protected $path;
48
49
    /**
50
     * @var Finder
51
     */
52
    protected $finder;
53
54
    /**
55
     * @param string $name
56
     *
57
     * @return \GitElephant\Repository
58
     */
59
    protected function getRepository(string $name = null)
60
    {
61
        if ($this->repository == null) {
62
            $this->initRepository($name);
63
        }
64
        if (is_null($name)) {
65
            return $this->repository;
66
        } else {
67
            return $this->repository[$name];
68
        }
69
    }
70
71
    /**
72
     * @return CallerInterface the real/not mocked caller
73
     */
74
    protected function getCaller(): CallerInterface
75
    {
76
        if ($this->caller == null) {
77
            $this->initRepository();
78
        }
79
80
        return $this->caller;
81
    }
82
83
    /**
84
     * @param null|string $name  the folder name
85
     * @param int         $index the repository index (for getting them back)
86
     *
87
     * @return void
88
     */
89
    protected function initRepository(string $name = null, int $index = null): void
90
    {
91
        $tempDir = realpath(sys_get_temp_dir());
92
        $tempName = null === $name 
93
            ? tempnam($tempDir, 'gitelephant') 
94
            : $tempDir . DIRECTORY_SEPARATOR . $name;
95
        $this->path = $tempName;
96
        @unlink($this->path);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
97
        $fs = new Filesystem();
98
        $fs->mkdir($this->path);
99
        $this->caller = new Caller(null, $this->path);
100
        if (is_null($index)) {
101
            $this->repository = Repository::open($this->path);
102
            $this->assertInstanceOf(Repository::class, $this->repository);
103
        } else {
104
            if (!is_array($this->repository)) {
105
                $this->repository = array();
0 ignored issues
show
Documentation Bug introduced by
It seems like array() of type array is incompatible with the declared type object<GitElephant\Repository> of property $repository.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
106
            }
107
            $this->repository[$index] = Repository::open($this->path);
108
            $this->assertInstanceOf(Repository::class, $this->repository[$index]);
109
        }
110
    }
111
112
    protected function tearDown(): void
113
    {
114
        $fs = new Filesystem();
115
        if (is_array($this->repository)) {
116
            array_map(function (Repository $repo) use ($fs) {
117
                $fs->remove($repo->getPath());
118
            }, $this->repository);
119
        } else {
120
            $fs->remove($this->path);
121
        }
122
        m::close();
123
    }
124
125
    /**
126
     * @param string      $name       file name
127
     * @param string|null $folder     folder name
128
     * @param null        $content    content
129
     * @param Repository  $repository repository to add file to
130
     *
131
     * @return void
132
     */
133
    protected function addFile(string $name, string $folder = null, string $content = null, Repository $repository = null): void
134
    {
135
        $path = is_null($repository) ? $this->path : $repository->getPath();
136
        $filename = $folder == null
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $folder of type null|string against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
137
            ? $path . DIRECTORY_SEPARATOR . $name
138
            : $path . DIRECTORY_SEPARATOR . $folder . DIRECTORY_SEPARATOR . $name;
139
        $handle = fopen($filename, 'w');
140
        $fileContent = $content === null ? 'test content' : $content;
141
        $this->assertTrue(false !== fwrite($handle, $fileContent), sprintf('unable to write the file %s', $name));
142
        fclose($handle);
143
    }
144
145
    /**
146
     * remove file from repo
147
     *
148
     * @param string $name
149
     */
150
    protected function removeFile(string $name): void
151
    {
152
        $filename = $this->path . DIRECTORY_SEPARATOR . $name;
153
        $this->assertTrue(unlink($filename));
154
    }
155
156
    /**
157
     * update a file in the repository
158
     *
159
     * @param string $name    file name
160
     * @param string $content content
161
     */
162
    protected function updateFile(string $name, string $content): void
163
    {
164
        $filename = $this->path . DIRECTORY_SEPARATOR . $name;
165
        $this->assertTrue(false !== file_put_contents($filename, $content));
166
    }
167
168
    /**
169
     * rename a file in the repository
170
     *
171
     * @param string $originName file name
172
     * @param string $targetName new file name
173
     * @param bool   $gitMv      use git mv, otherwise uses php rename function (with the Filesystem component)
174
     */
175
    protected function renameFile(string $originName, string $targetName, bool $gitMv = true): void
176
    {
177
        if ($gitMv) {
178
            $this->getRepository()
179
                ->getCaller()
180
                ->execute(MvCommand::getInstance()->rename($originName, $targetName));
181
182
            return;
183
        }
184
        $origin = $this->path . DIRECTORY_SEPARATOR . $originName;
185
        $target = $this->path . DIRECTORY_SEPARATOR . $targetName;
186
        $fs = new Filesystem();
187
        $fs->rename($origin, $target);
188
    }
189
190
    /**
191
     * @param string $name name
192
     *
193
     * @return void
194
     */
195
    protected function addFolder($name): void
196
    {
197
        $fs = new Filesystem();
198
        $fs->mkdir($this->path . DIRECTORY_SEPARATOR . $name);
199
    }
200
201
    protected function addSubmodule($url, $path): void
202
    {
203
        $this->getRepository()->addSubmodule($url, $path);
204
    }
205
206
    /**
207
     * @param $classname
208
     *
209
     * @return MockObject
210
     */
211
    protected function getMock($classname): MockObject
212
    {
213
        return $this
214
            ->getMockBuilder($classname)
215
            ->disableOriginalConstructor()
216
            ->getMock();
217
    }
218
219
    /**
220
     * mock the caller
221
     *
222
     * @param string $command command
223
     * @param string $output  output
224
     *
225
     * @return MockObject
226
     */
227
    protected function getMockCaller($command, $output): MockObject
228
    {
229
        $mock = $this->createMock(CallerInterface::class);
230
        $mock
231
            ->expects($this->any())
232
            ->method('execute')
233
            ->willReturn($mock);
234
        $mock
235
            ->expects($this->any())
236
            ->method('getOutputLines')
237
            ->willReturn($output);
238
239
        return $mock;
240
    }
241
242
    protected function addCommandToMockContainer(MockObject $container, string $commandName): void
243
    {
244
        $container
245
            ->expects($this->any())
246
            ->method('get')
247
            ->with($this->equalTo($commandName))
248
            ->willReturn($this->getMockCommand());
249
    }
250
251
    protected function addOutputToMockRepo(MockObject $repo, array $output): void
252
    {
253
        $repo
254
            ->expects($this->any())
255
            ->method('getCaller')
256
            ->willReturn($this->getMockCaller('', $output));
257
    }
258
259
    protected function getMockCommand(): MockObject
260
    {
261
        $command = $this->getMock('Command', array('showCommit'));
262
        $command
263
            ->expects($this->any())
264
            ->method('showCommit')
265
            ->willReturn('');
266
267
        return $command;
268
    }
269
270
    protected function getMockRepository(): MockObject
271
    {
272
        $mockRepo = $this->getMock(
273
            Repository::class,
274
            array(),
275
            array(
276
                $this->repository->getPath(),
277
                null,
278
            )
279
        );
280
        
281
        return $mockRepo;
282
    }
283
284
    protected function doCommitTest(
285
        Commit $commit,
286
        $sha,
287
        $tree,
288
        $author,
289
        $committer,
290
        $emailAuthor,
291
        $emailCommitter,
292
        $datetimeAuthor,
293
        $datetimeCommitter,
294
        $message
295
    ): void {
296
        $this->assertInstanceOf(Commit::class, $commit);
297
        $this->assertEquals($sha, $commit->getSha());
298
        $this->assertEquals($tree, $commit->getTree());
299
        $this->assertInstanceOf(Author::class, $commit->getAuthor());
300
        $this->assertEquals($author, $commit->getAuthor()->getName());
301
        $this->assertEquals($emailAuthor, $commit->getAuthor()->getEmail());
302
        $this->assertInstanceOf(Author::class, $commit->getCommitter());
303
        $this->assertEquals($committer, $commit->getCommitter()->getName());
304
        $this->assertEquals($emailCommitter, $commit->getCommitter()->getEmail());
305
        $this->assertInstanceOf(\DateTime::class, $commit->getDatetimeAuthor());
306
        $this->assertEquals($datetimeAuthor, $commit->getDatetimeAuthor()->format('U'));
307
        $this->assertInstanceOf(\DateTime::class, $commit->getDatetimeCommitter());
308
        $this->assertEquals($datetimeCommitter, $commit->getDatetimeCommitter()->format('U'));
309
        $this->assertEquals($message, $commit->getMessage()->getShortMessage());
310
    }
311
}
312