Passed
Push — main ( 9185d0...afd76b )
by Sebastian
03:36
created

InstallerTest::testSetHookAndEnabledOnly()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 8
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 12
rs 10
1
<?php
2
3
/**
4
 * This file is part of CaptainHook
5
 *
6
 * (c) Sebastian Feldmann <[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
12
namespace CaptainHook\App\Runner;
13
14
use CaptainHook\App\Config\Mockery as ConfigMockery;
15
use CaptainHook\App\Console\IO\Mockery as IOMockery;
16
use CaptainHook\App\Exception\InvalidHookName;
17
use CaptainHook\App\Git\DummyRepo;
18
use CaptainHook\App\Hook\Mockery as HookMockery;
19
use CaptainHook\App\Mockery as CHMockery;
20
use Exception;
21
use org\bovigo\vfs\vfsStream;
22
use PHPUnit\Framework\TestCase;
23
use RuntimeException;
24
use SebastianFeldmann\Git\Repository;
25
26
class InstallerTest extends TestCase
27
{
28
    use ConfigMockery;
29
    use IOMockery;
30
    use CHMockery;
31
    use HookMockery;
32
33
    /**
34
     * Tests Installer::setHook
35
     *
36
     * @throws \CaptainHook\App\Exception\InvalidHookName
37
     */
38
    public function testSetInvalidHook(): void
39
    {
40
        $this->expectException(InvalidHookName::class);
41
42
        $io       = $this->createIOMock();
43
        $config   = $this->createConfigMock();
44
        $repo     = $this->createRepositoryMock();
45
        $template = $this->createTemplateMock();
46
47
        $runner = new Installer($io, $config, $repo, $template);
48
        $runner->setHook('itDoNotExist');
49
    }
50
51
    /**
52
     * Tests Installer::setHook
53
     *
54
     * @throws \CaptainHook\App\Exception\InvalidHookName
55
     */
56
    public function testSetMultipleInvalidHooks(): void
57
    {
58
        $this->expectException(InvalidHookName::class);
59
60
        $io       = $this->createIOMock();
61
        $config   = $this->createConfigMock();
62
        $repo     = $this->createRepositoryMock();
63
        $template = $this->createTemplateMock();
64
65
        $runner = new Installer($io, $config, $repo, $template);
66
        $runner->setHook('itDoNotExist1,itDoNotExist2,itDontExist3');
67
    }
68
69
    /**
70
     * Tests Installer::setHook
71
     *
72
     * @throws \CaptainHook\App\Exception\InvalidHookName
73
     */
74
    public function testSetHookAndEnabledOnly(): void
75
    {
76
        $this->expectException(Exception::class);
77
78
        $io       = $this->createIOMock();
79
        $config   = $this->createConfigMock();
80
        $repo     = $this->createRepositoryMock();
81
        $template = $this->createTemplateMock();
82
83
        $runner = new Installer($io, $config, $repo, $template);
84
        $runner->setOnlyEnabled(true);
85
        $runner->setHook('pre-push');
86
    }
87
88
    /**
89
     * Tests Installer::setHook
90
     *
91
     * @throws \CaptainHook\App\Exception\InvalidHookName
92
     */
93
    public function testMoveAfterSkippingFail(): void
94
    {
95
        $this->expectException(RuntimeException::class);
96
97
        $io       = $this->createIOMock();
98
        $config   = $this->createConfigMock();
99
        $repo     = $this->createRepositoryMock();
100
        $template = $this->createTemplateMock();
101
102
        $runner = new Installer($io, $config, $repo, $template);
103
        $runner->setHook('pre-commit');
104
        $runner->setSkipExisting(true);
105
        $runner->setMoveExistingTo('/tmp/');
106
    }
107
108
    /**
109
     * Tests Installer::setHook
110
     *
111
     * @throws \CaptainHook\App\Exception\InvalidHookName
112
     */
113
    public function testSkipAfterMovingFail(): void
114
    {
115
        $this->expectException(RuntimeException::class);
116
117
        $io       = $this->createIOMock();
118
        $config   = $this->createConfigMock();
119
        $repo     = $this->createRepositoryMock();
120
        $template = $this->createTemplateMock();
121
122
        $runner = new Installer($io, $config, $repo, $template);
123
        $runner->setHook('pre-commit');
124
        $runner->setMoveExistingTo('/tmp/');
125
        $runner->setSkipExisting(true);
126
    }
127
128
    /**
129
     * Tests Installer::run
130
     */
131
    public function testHookInstallationDeclined(): void
132
    {
133
        $fakeRepo = new DummyRepo();
134
135
        $io       = $this->createIOMock();
136
        $config   = $this->createConfigMock();
137
        $repo     = $this->createRepositoryMock($fakeRepo->getRoot());
138
        $template = $this->createTemplateMock();
139
140
        $io->expects($this->atLeast(5))->method('ask')->willReturn('n');
141
142
        $runner = new Installer($io, $config, $repo, $template);
143
        $runner->setHook('');
144
        $runner->run();
145
146
        $this->assertFileDoesNotExist($fakeRepo->getHookDir() . '/pre-commit');
147
        $this->assertFileDoesNotExist($fakeRepo->getHookDir() . '/pre-push');
148
    }
149
150
    /**
151
     * Tests Installer::run
152
     */
153
    public function testWriteHook(): void
154
    {
155
        $fakeRepo = new DummyRepo();
156
157
        $io       = $this->createIOMock();
158
        $config   = $this->createConfigMock();
159
        $repo     = $this->createRepositoryMock($fakeRepo->getRoot());
160
        $template = $this->createTemplateMock();
161
162
        $template->expects($this->once())
163
                 ->method('getCode')
164
                 ->with('pre-commit')
165
                 ->willReturn('');
166
167
        $runner = new Installer($io, $config, $repo, $template);
168
        $runner->setHook('pre-commit');
169
        $runner->run();
170
171
        $this->assertFileExists($fakeRepo->getHookDir() . '/pre-commit');
172
    }
173
174
    /**
175
     * Tests Installer::run
176
     */
177
    public function testWriteMultipleHooks(): void
178
    {
179
        $fakeRepo = new DummyRepo();
180
181
        $io       = $this->createIOMock();
182
        $config   = $this->createConfigMock();
183
        $repo     = $this->createRepositoryMock($fakeRepo->getRoot());
184
        $template = $this->createTemplateMock();
185
186
        $runner = new Installer($io, $config, $repo, $template);
187
        $runner->setHook('pre-commit,pre-push,post-checkout');
188
        $runner->run();
189
190
        $this->assertFileExists($fakeRepo->getHookDir() . '/pre-commit');
191
        $this->assertFileExists($fakeRepo->getHookDir() . '/pre-push');
192
        $this->assertFileExists($fakeRepo->getHookDir() . '/post-checkout');
193
    }
194
195
    /**
196
     * Tests Installer::run
197
     */
198
    public function testMoveExistingHook(): void
199
    {
200
        $fakeRepo = new DummyRepo(
201
            // git repo
202
            [
203
                'config' => '# fake git config',
204
                'hooks'  => [
205
                    'pre-commit' => '# fake pre-commit file',
206
                    'pre-push'   => '# fake pre-push file',
207
                ]
208
            ],
209
            // files
210
            [
211
                'foo' => []
212
            ]
213
        );
214
215
        $io       = $this->createIOMock();
216
        $config   = $this->createConfigMock(true, $fakeRepo->getRoot() . '/captainhook.json');
217
        $template = $this->createTemplateMock();
218
        $repo     = new Repository($fakeRepo->getRoot());
219
220
        $template->expects($this->once())
221
                 ->method('getCode')
222
                 ->with('pre-commit')
223
                 ->willReturn('');
224
225
        $runner = new Installer($io, $config, $repo, $template);
226
        $runner->setHook('pre-commit')
227
               ->setMoveExistingTo('foo/bar/')
228
               ->run();
229
230
        $this->assertFileExists($fakeRepo->getHookDir() . '/pre-commit');
231
        $this->assertFileExists($fakeRepo->getRoot() . '/foo/bar/pre-commit');
232
    }
233
234
    /**
235
     * Tests Installer::run
236
     */
237
    public function testMoveNotExistingHook(): void
238
    {
239
        $fakeRepo = new DummyRepo(
240
            // git repo
241
            [
242
                'config' => '# fake git config',
243
                'hooks'  => [
244
                    'pre-push' => '# fake pre-push file',
245
                ]
246
            ],
247
            // files
248
            [
249
                'foo' => []
250
            ]
251
        );
252
253
        $io       = $this->createIOMock();
254
        $config   = $this->createConfigMock(true, $fakeRepo->getRoot() . '/captainhook.json');
255
        $template = $this->createTemplateMock();
256
        $repo     = new Repository($fakeRepo->getRoot());
257
258
        $template->expects($this->once())
259
                 ->method('getCode')
260
                 ->with('pre-commit')
261
                 ->willReturn('');
262
263
        $runner = new Installer($io, $config, $repo, $template);
264
        $runner->setHook('pre-commit')
265
               ->setMoveExistingTo('foo/bar/')
266
               ->run();
267
268
        $this->assertFileExists($fakeRepo->getHookDir() . '/pre-commit');
269
    }
270
271
    /**
272
     * Tests Installer::run
273
     */
274
    public function testMoveExistingHookTargetIsFile(): void
275
    {
276
        $this->expectException(RuntimeException::class);
277
278
        $fakeRepo = new DummyRepo(
279
            // git repo
280
            [
281
                'config' => '# fake git config',
282
                'hooks'  => [
283
                    'pre-commit' => '# fake pre-commit file',
284
                    'pre-push'   => '# fake pre-push file',
285
                ]
286
            ],
287
            // files
288
            [
289
                'foo' => '# some random file'
290
            ]
291
        );
292
293
        $io       = $this->createIOMock();
294
        $config   = $this->createConfigMock(true, $fakeRepo->getRoot() . '/captainhook.json');
295
        $template = $this->createTemplateMock();
296
        $repo     = new Repository($fakeRepo->getRoot());
297
298
        $runner = new Installer($io, $config, $repo, $template);
299
        $runner->setHook('pre-commit')
300
               ->setMoveExistingTo('foo')
301
               ->run();
302
    }
303
304
    /**
305
     * Tests Installer::writeHookFile
306
     */
307
    public function testSkipExisting(): void
308
    {
309
        $io       = $this->createIOMock();
310
        $config   = $this->createConfigMock();
311
        $repo     = $this->createRepositoryMock();
312
        $template = $this->createTemplateMock();
313
314
        $io->expects($this->atLeast(1))->method('write');
315
        $repo->expects($this->once())->method('hookExists')->willReturn(true);
316
317
        $runner = new Installer($io, $config, $repo, $template);
318
        $runner->setSkipExisting(true);
319
        $runner->setHook('pre-commit');
320
        $runner->run();
321
    }
322
323
    /**
324
     * Tests Installer::writeHookFile
325
     */
326
    public function testOnlyEnabledAndHooksToHandle(): void
327
    {
328
        $this->expectException(Exception::class);
329
330
        $io       = $this->createIOMock();
331
        $config   = $this->createConfigMock();
332
        $repo     = $this->createRepositoryMock();
333
        $template = $this->createTemplateMock();
334
335
        $runner = new Installer($io, $config, $repo, $template);
336
        $runner->setHook('pre-commit');
337
        $runner->setOnlyEnabled(true);
338
    }
339
340
    /**
341
     * Tests Installer::writeHookFile
342
     */
343
    public function testDeclineOverwrite(): void
344
    {
345
        $io       = $this->createIOMock();
346
        $config   = $this->createConfigMock();
347
        $repo     = $this->createRepositoryMock();
348
        $template = $this->createTemplateMock();
349
350
        $io->expects($this->once())->method('ask')->willReturn('n');
351
        $repo->expects($this->once())->method('hookExists')->willReturn(true);
352
353
        $runner = new Installer($io, $config, $repo, $template);
354
        $runner->setHook('pre-commit');
355
        $runner->run();
356
    }
357
358
    public function testMoveExistingHookWhenMoveExistingIsAnAbsolutePath(): void
359
    {
360
        $virtualFs = vfsStream::setup('root');
361
362
        $fakeRepo = new DummyRepo(
363
        // git repo
364
            [
365
                'config' => '# fake git config',
366
                'hooks'  => [
367
                    'pre-commit' => '# fake pre-commit file',
368
                    'pre-push'   => '# fake pre-push file',
369
                ]
370
            ],
371
            // files
372
            [
373
                'foo' => []
374
            ]
375
        );
376
377
        $io       = $this->createIOMock();
378
        $config   = $this->createConfigMock(true, $fakeRepo->getRoot() . '/captainhook.json');
379
        $template = $this->createTemplateMock();
380
        $repo     = new Repository($fakeRepo->getRoot());
381
382
        $template->expects($this->once())
383
            ->method('getCode')
384
            ->with('pre-commit')
385
            ->willReturn('');
386
387
        $runner = new Installer($io, $config, $repo, $template);
388
        $runner->setHook('pre-commit')
389
            ->setMoveExistingTo($virtualFs->url() . '/foo/bar')
390
            ->run();
391
392
        $this->assertFileExists($fakeRepo->getHookDir() . '/pre-commit');
393
        $this->assertFileExists($fakeRepo->getRoot() . '/foo/bar/pre-commit');
394
    }
395
}
396