HookTest.php$4 ➔ testRunHookWithPlugins()   A
last analyzed

Complexity

Conditions 2

Size

Total Lines 51

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
c 0
b 0
f 0
dl 0
loc 51
rs 9.069

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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;
15
use CaptainHook\App\Config\Mockery as ConfigMockery;
16
use CaptainHook\App\Console\IO\Mockery as IOMockery;
17
use CaptainHook\App\Git\DummyRepo;
18
use CaptainHook\App\Hook\Restriction;
19
use CaptainHook\App\Hooks;
20
use CaptainHook\App\Mockery as CHMockery;
21
use CaptainHook\App\Plugin\DummyConstrainedPlugin;
22
use CaptainHook\App\Plugin\DummyConstrainedHookPlugin;
23
use CaptainHook\App\Plugin\DummyConstrainedHookPluginAlt;
24
use CaptainHook\App\Plugin\DummyPlugin;
25
use CaptainHook\App\Plugin\DummyHookPlugin;
26
use CaptainHook\App\Plugin\DummyHookPluginSkipsActions;
27
use Exception;
28
use PHPUnit\Framework\TestCase;
29
30
class HookTest extends TestCase
31
{
32
    use ConfigMockery;
33
    use IOMockery;
34
    use CHMockery;
35
36
    protected function setUp(): void
37
    {
38
        // Ensure the static properties on dummy plugins are all set to their defaults.
39
        DummyHookPlugin::$beforeHookCalled = 0;
40
        DummyHookPlugin::$beforeActionCalled = 0;
41
        DummyHookPlugin::$afterActionCalled = 0;
42
        DummyHookPlugin::$afterHookCalled = 0;
43
        DummyHookPluginSkipsActions::$skipStartIn = 'beforeHook';
44
        DummyHookPluginSkipsActions::$skipStartAt = 1;
45
        DummyConstrainedHookPlugin::$restriction = null;
46
        DummyConstrainedHookPluginAlt::$restriction = null;
47
        DummyConstrainedPlugin::$restriction = null;
48
    }
49
50
    protected function tearDown(): void
51
    {
52
        // Reset the static properties on dummy plugins to their defaults.
53
        DummyHookPlugin::$beforeHookCalled = 0;
54
        DummyHookPlugin::$beforeActionCalled = 0;
55
        DummyHookPlugin::$afterActionCalled = 0;
56
        DummyHookPlugin::$afterHookCalled = 0;
57
        DummyHookPluginSkipsActions::$skipStartIn = 'beforeHook';
58
        DummyHookPluginSkipsActions::$skipStartAt = 1;
59
        DummyConstrainedHookPlugin::$restriction = null;
60
        DummyConstrainedHookPluginAlt::$restriction = null;
61
        DummyConstrainedPlugin::$restriction = null;
62
    }
63
64
    public function testGetName(): void
65
    {
66
        $io = $this->createIOMock();
67
        $config = $this->createConfigMock();
68
        $repo = $this->createRepositoryMock();
69
70
        $runner = new class ($io, $config, $repo) extends Hook {
71
            protected $hook = Hooks::PRE_COMMIT;
72
        };
73
74
        $this->assertSame('pre-commit', $runner->getName());
75
    }
76
77
    public function testShouldSkipActionsIsFalseByDefault(): void
78
    {
79
        $io = $this->createIOMock();
80
        $config = $this->createConfigMock();
81
        $repo = $this->createRepositoryMock();
82
83
        $runner = new class ($io, $config, $repo) extends Hook {
84
            protected $hook = Hooks::PRE_COMMIT;
85
        };
86
87
        $this->assertFalse($runner->shouldSkipActions());
88
    }
89
90
    public function testShouldSkipActionsCanBeSetToTrue(): void
91
    {
92
        $io = $this->createIOMock();
93
        $config = $this->createConfigMock();
94
        $repo = $this->createRepositoryMock();
95
96
        $runner = new class ($io, $config, $repo) extends Hook {
97
            protected $hook = Hooks::PRE_COMMIT;
98
        };
99
100
        $this->assertTrue($runner->shouldSkipActions(true));
101
        $this->assertTrue($runner->shouldSkipActions());
102
    }
103
104
    public function testShouldSkipActionsCanBeSetToFalse(): void
105
    {
106
        $io = $this->createIOMock();
107
        $config = $this->createConfigMock();
108
        $repo = $this->createRepositoryMock();
109
110
        $runner = new class ($io, $config, $repo) extends Hook {
111
            protected $hook = Hooks::PRE_COMMIT;
112
        };
113
114
        $runner->shouldSkipActions(true);
115
116
        $this->assertFalse($runner->shouldSkipActions(false));
117
        $this->assertFalse($runner->shouldSkipActions());
118
    }
119
120
    public function testRunHookWithPlugins(): void
121
    {
122
        if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
123
            $this->markTestSkipped('not tested on windows');
124
        }
125
126
        $restriction1 = new Restriction(Hooks::POST_CHECKOUT);
127
        DummyConstrainedPlugin::$restriction = $restriction1;
128
        DummyConstrainedHookPluginAlt::$restriction = $restriction1;
129
130
        $restriction2 = new Restriction(Hooks::PRE_COMMIT);
131
        DummyConstrainedHookPlugin::$restriction = $restriction2;
132
133
        $pluginConfig1 = new Config\Plugin(DummyPlugin::class);
134
        $pluginConfig2 = new Config\Plugin(DummyHookPlugin::class);
135
        $pluginConfig3 = new Config\Plugin(DummyConstrainedPlugin::class);
136
        $pluginConfig4 = new Config\Plugin(DummyConstrainedHookPlugin::class);
137
        $pluginConfig5 = new Config\Plugin(DummyConstrainedHookPluginAlt::class);
138
139
        $config = $this->createConfigMock();
140
        $config->method('failOnFirstError')->willReturn(true);
141
        $config->method('getPlugins')->willReturn([
142
            $pluginConfig1,
143
            $pluginConfig2,
144
            $pluginConfig3,
145
            $pluginConfig4,
146
            $pluginConfig5,
147
        ]);
148
        $dummy = new DummyRepo(['hooks' => ['pre-commit' => '# hook script']]);
149
        $repo  = $this->createRepositoryMock($dummy->getRoot());
150
        $repo->method('getHooksDir')->willReturn($dummy->getHookDir());
151
152
        $io           = $this->createIOMock();
153
        $hookConfig   = $this->createHookConfigMock();
154
        $actionConfig = $this->createActionConfigMock();
155
        $actionConfig->method('getAction')->willReturn(CH_PATH_FILES . '/bin/success');
156
        $hookConfig->method('isEnabled')->willReturn(true);
157
        $hookConfig->expects($this->once())->method('getActions')->willReturn([$actionConfig, $actionConfig]);
158
        $config->expects($this->once())->method('getHookConfigToExecute')->willReturn($hookConfig);
159
        $config->expects($this->atLeastOnce())->method('isHookEnabled')->willReturn(true);
160
        $io->expects($this->atLeast(1))->method('write');
161
162
        $runner = new class ($io, $config, $repo) extends Hook {
163
            protected $hook = Hooks::PRE_COMMIT;
164
        };
165
        $runner->run();
166
167
        $this->assertSame(2, DummyHookPlugin::$beforeHookCalled);
168
        $this->assertSame(4, DummyHookPlugin::$beforeActionCalled);
169
        $this->assertSame(4, DummyHookPlugin::$afterActionCalled);
170
        $this->assertSame(2, DummyHookPlugin::$afterHookCalled);
171
    }
172
173
    public function testRunHookSkipsActionsFromPluginBeforeHook(): void
174
    {
175
        DummyHookPluginSkipsActions::$skipStartAt = 1;
176
177
        $pluginConfig = new Config\Plugin(DummyHookPluginSkipsActions::class);
178
179
        $dummy = new DummyRepo(['hooks' => ['pre-commit' => '# hook script']]);
180
        $repo  = $this->createRepositoryMock($dummy->getRoot());
181
        $repo->method('getHooksDir')->willReturn($dummy->getHookDir());
182
183
        $config = $this->createConfigMock();
184
        $config->method('failOnFirstError')->willReturn(true);
185
        $config->method('getPlugins')->willReturn([$pluginConfig]);
186
187
        $io = $this->createIOMock();
188
        $hookConfig = $this->createHookConfigMock();
189
        $actionConfig = $this->createActionConfigMock();
190
        $hookConfig->method('isEnabled')->willReturn(true);
191
        $hookConfig->expects($this->once())->method('getActions')->willReturn([
192
            $actionConfig,
193
            $actionConfig,
194
        ]);
195
        $config->expects($this->once())->method('getHookConfigToExecute')->willReturn($hookConfig);
196
        $config->expects($this->atLeastOnce())->method('isHookEnabled')->willReturn(true);
197
        $io->expects($this->atLeast(1))->method('write');
198
199
        $runner = new class ($io, $config, $repo) extends Hook {
200
            protected $hook = Hooks::PRE_COMMIT;
201
        };
202
        $runner->run();
203
204
        $this->assertSame(1, DummyHookPlugin::$beforeHookCalled);
205
        $this->assertSame(0, DummyHookPlugin::$beforeActionCalled);
206
        $this->assertSame(0, DummyHookPlugin::$afterActionCalled);
207
        $this->assertSame(1, DummyHookPlugin::$afterHookCalled);
208
    }
209
210
    public function testRunHookSkipsActionsFromPluginBeforeAction(): void
211
    {
212
        if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
213
            $this->markTestSkipped('not tested on windows');
214
        }
215
216
        DummyHookPluginSkipsActions::$skipStartIn = 'beforeAction';
217
        DummyHookPluginSkipsActions::$skipStartAt = 3;
218
219
        $pluginConfig = new Config\Plugin(DummyHookPluginSkipsActions::class);
220
221
        $dummy = new DummyRepo(['hooks' => ['pre-commit' => '# hook script']]);
222
        $repo  = $this->createRepositoryMock($dummy->getRoot());
223
        $repo->method('getHooksDir')->willReturn($dummy->getHookDir());
224
225
        $config = $this->createConfigMock();
226
        $config->method('failOnFirstError')->willReturn(true);
227
        $config->method('getPlugins')->willReturn([$pluginConfig]);
228
229
        $io = $this->createIOMock();
230
        $hookConfig = $this->createHookConfigMock();
231
        $actionConfig = $this->createActionConfigMock();
232
        $actionConfig->method('getAction')->willReturn(CH_PATH_FILES . '/bin/success');
233
        $hookConfig->method('isEnabled')->willReturn(true);
234
        $hookConfig->expects($this->once())->method('getActions')->willReturn([
235
            $actionConfig,
236
            $actionConfig,
237
            $actionConfig,
238
            $actionConfig,
239
            $actionConfig,
240
        ]);
241
        $config->expects($this->once())->method('getHookConfigToExecute')->willReturn($hookConfig);
242
        $config->expects($this->atLeastOnce())->method('isHookEnabled')->willReturn(true);
243
        $io->expects($this->atLeast(1))->method('write');
244
245
        $runner = new class ($io, $config, $repo) extends Hook {
246
            protected $hook = Hooks::PRE_COMMIT;
247
        };
248
        $runner->run();
249
250
        $this->assertSame(1, DummyHookPlugin::$beforeHookCalled);
251
        $this->assertSame(3, DummyHookPlugin::$beforeActionCalled);
252
        $this->assertSame(3, DummyHookPlugin::$afterActionCalled);
253
        $this->assertSame(1, DummyHookPlugin::$afterHookCalled);
254
    }
255
}
256