Passed
Push — main ( 4ee39f...33155d )
by Justin
03:54
created

InterceptorTest::test_add_options()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 1
Metric Value
cc 1
eloc 13
c 1
b 1
f 1
nc 1
nop 0
dl 0
loc 20
rs 9.8333
1
<?php
2
3
namespace Tests\Feature;
4
5
use Illuminate\Contracts\Console\Application;
6
use Illuminate\Contracts\Console\Kernel;
7
use Illuminate\Foundation\Testing\RefreshDatabase;
8
use Illuminate\Foundation\Testing\WithFaker;
9
use Illuminate\Support\Facades\Artisan;
10
use Modulate\Artisan\Interceptor\Contracts\Interceptor;
11
use Modulate\Artisan\Interceptor\InterceptedCommand;
12
use Modulate\Artisan\Interceptor\OptionBuilder;
13
use Orchestra\Testbench\TestCase;
14
use Symfony\Component\Console\Input\InputOption;
15
use Modulate\Artisan\Interceptor\Facades\ArtisanInterceptor;
16
use Symfony\Component\Console\Command\Command;
17
use Symfony\Component\Console\Input\InputInterface;
18
use Symfony\Component\Console\Output\OutputInterface;
19
20
class InterceptorTest extends TestCase
21
{
22
    protected $enablesPackageDiscoveries = true; 
23
24
    public function setUp(): void
25
    {
26
        parent::setUp();
27
        $this->app->make(Interceptor::class);
0 ignored issues
show
Bug introduced by
The method make() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

27
        $this->app->/** @scrutinizer ignore-call */ 
28
                    make(Interceptor::class);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
28
    }
29
30
    /**
31
     * A basic feature test example.
32
     */
33
    public function test_add_option(): void
34
    {
35
        $builder = new OptionBuilder();
36
        $inputOption = $builder
37
            ->name('foo')
38
            ->get();
39
        ArtisanInterceptor::addOption($inputOption);
0 ignored issues
show
Bug introduced by
The method addOption() does not exist on Modulate\Artisan\Interce...ades\ArtisanInterceptor. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

39
        ArtisanInterceptor::/** @scrutinizer ignore-call */ 
40
                            addOption($inputOption);
Loading history...
40
        $this->artisan('list');
41
        $artisan = ArtisanInterceptor::getArtisan();
0 ignored issues
show
Bug introduced by
The method getArtisan() does not exist on Modulate\Artisan\Interce...ades\ArtisanInterceptor. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

41
        /** @scrutinizer ignore-call */ 
42
        $artisan = ArtisanInterceptor::getArtisan();
Loading history...
42
        $this->assertTrue($artisan->getDefinition()->hasOption('foo'));
43
    }
44
    
45
    public function test_add_options(): void
46
    {
47
        $inputOption1 = ArtisanInterceptor::optionBuilder()
48
            ->name('username')
49
            ->required()
50
            ->get();
51
52
        $inputOption2 = ArtisanInterceptor::optionBuilder()
53
            ->name('password')
54
            ->required()
55
            ->get();
56
57
        ArtisanInterceptor::addOptions([ $inputOption1, $inputOption2 ]);
0 ignored issues
show
Bug introduced by
The method addOptions() does not exist on Modulate\Artisan\Interce...ades\ArtisanInterceptor. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

57
        ArtisanInterceptor::/** @scrutinizer ignore-call */ 
58
                            addOptions([ $inputOption1, $inputOption2 ]);
Loading history...
58
        
59
        // Call a command to start the interceptor
60
        $this->artisan('list');
61
62
        $artisan = ArtisanInterceptor::getArtisan();
63
        $this->assertTrue($artisan->getDefinition()->hasOption('username'));
64
        $this->assertTrue($artisan->getDefinition()->hasOption('password'));
65
    }
66
    public function test_start_callback(): void
67
    {
68
        $started = false;
69
70
        $func = function() use(&$started) {
71
            $started = true;
72
        };
73
74
        // Ensure the symfony events are wired up for the test so CommandStarting and CommandFinished events are dispatched correctly
75
        // as this is disabled in unit tests by default
76
        $this->app->make(Kernel::class)->rerouteSymfonyCommandEvents();
77
78
        ArtisanInterceptor::start($func);
0 ignored issues
show
Bug introduced by
The method start() does not exist on Modulate\Artisan\Interce...ades\ArtisanInterceptor. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

78
        ArtisanInterceptor::/** @scrutinizer ignore-call */ 
79
                            start($func);
Loading history...
79
80
        $this->artisan('list');
81
82
        $this->assertTrue($started);
83
    }
84
    
85
    public function test_before_callback(): void
86
    {
87
88
        $func = function(InterceptedCommand $command) {
89
            $command->getOutput()->write('intercepted');
90
        };
91
92
        // Ensure the symfony events are wired up for the test so CommandStarting and CommandFinished events are dispatched correctly
93
        // as this is disabled in unit tests by default
94
        $this->app->make(Kernel::class)->rerouteSymfonyCommandEvents();
95
96
        ArtisanInterceptor::before($func);
0 ignored issues
show
Bug introduced by
The method before() does not exist on Modulate\Artisan\Interce...ades\ArtisanInterceptor. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

96
        ArtisanInterceptor::/** @scrutinizer ignore-call */ 
97
                            before($func);
Loading history...
97
98
        $this->artisan('list')
99
            ->expectsOutputToContain('intercepted');
100
101
    }
102
    public function test_after_callback(): void
103
    {
104
105
        $func = function(InterceptedCommand $command) {
106
            $command->getOutput()->write('the end');
107
        };
108
109
        // Ensure the symfony events are wired up for the test so CommandStarting and CommandFinished events are dispatched correctly
110
        // as this is disabled in unit tests by default
111
        $this->app->make(Kernel::class)->rerouteSymfonyCommandEvents();
112
113
        ArtisanInterceptor::before($func);
114
115
        $this->artisan('list')
116
            ->expectsOutputToContain('the end');
117
    }
118
    
119
    public function test_option_callback(): void
120
    {
121
        
122
        $inputOption = ArtisanInterceptor::optionBuilder()
123
            ->name('foo')
124
            ->optional()
125
            ->get();
126
        ArtisanInterceptor::addOption($inputOption);
127
128
        $func = function(InterceptedCommand $command) {
129
            $command->getOutput()->write('has foo');
130
        };
131
132
        // Ensure the symfony events are wired up for the test so CommandStarting and CommandFinished events are dispatched correctly
133
        // as this is disabled in unit tests by default
134
        $this->app->make(Kernel::class)->rerouteSymfonyCommandEvents();
135
136
        ArtisanInterceptor::before($func, 'foo');
137
138
        $this->artisan('list --foo=bar')
139
            ->expectsOutputToContain('has foo');
140
        
141
        $this->artisan('list')
142
            ->doesntExpectOutputToContain('has foo');
143
    }
144
    
145
    public function test_intercepted(): void
146
    {
147
        $startCalled = false;
148
        $start = function(Application $app) use (&$startCalled) {
149
            $this->assertInstanceOf(Application::class, $app);
150
            $startCalled = true;
151
        };
152
        
153
        $beforeCalled = false;
154
        $before = function(InterceptedCommand $command) use (&$beforeCalled) {
155
            $this->assertInstanceOf(InterceptedCommand::class, $command);
156
            $this->assertTrue($command->getCommand() == 'list');
157
            $this->assertInstanceOf(Command::class, $command->getCommandInstance());
158
            $this->assertInstanceOf(Application::class, $command->getArtisan());
159
            $this->assertInstanceOf(InputInterface::class, $command->getInput());
160
            $this->assertInstanceOf(OutputInterface::class, $command->getOutput());
161
            $beforeCalled = true;
162
        };
163
164
        $afterCalled = false;
165
        $after = function(InterceptedCommand $command) use (&$afterCalled) {
166
            $this->assertEquals($command->getExitCode(), 0);
167
            $this->assertTrue($command->hasFinished());
168
            $afterCalled = true;
169
        };
170
171
        // Ensure the symfony events are wired up for the test so CommandStarting and CommandFinished events are dispatched correctly
172
        // as this is disabled in unit tests by default
173
        $this->app->make(Kernel::class)->rerouteSymfonyCommandEvents();
174
175
        ArtisanInterceptor::start($start);
176
        ArtisanInterceptor::before($before);
177
        ArtisanInterceptor::after($after);
0 ignored issues
show
Bug introduced by
The method after() does not exist on Modulate\Artisan\Interce...ades\ArtisanInterceptor. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

177
        ArtisanInterceptor::/** @scrutinizer ignore-call */ 
178
                            after($after);
Loading history...
178
179
        $this->artisan('list');
180
181
        $this->assertTrue($startCalled);
182
        $this->assertTrue($beforeCalled);
183
        $this->assertTrue($afterCalled);
184
    }
185
    
186
    public function test_wrapped(): void
187
    {
188
        $builder = new OptionBuilder();
189
        $inputOption = $builder
190
            ->name('foo')
191
            ->optional()
192
            ->default('bar')
193
            ->get();
194
195
        ArtisanInterceptor::addOption($inputOption);
196
        
197
        $before = function(InterceptedCommand $command) {
198
            $this->assertEquals($command->getOption('foo'), 'bar');
199
            $this->assertTrue($command->hasOption('foo'));
200
            $command->setOption('foo', 'baz');
201
            $this->assertEquals($command->getOption('foo'), 'baz');
202
            $this->assertEquals($command->getArgument('config'), 'app.env');
203
            $this->assertTrue($command->hasArgument('config'));
204
            $command->setArgument('config', 'app.name');
205
            $this->assertEquals($command->getArgument('config'), 'app.name');
206
        };
207
208
        // Ensure the symfony events are wired up for the test so CommandStarting and CommandFinished events are dispatched correctly
209
        // as this is disabled in unit tests by default
210
        $this->app->make(Kernel::class)->rerouteSymfonyCommandEvents();
211
212
        ArtisanInterceptor::before($before);
213
214
        $this->artisan('config:show app.env --foo=bar');
215
    }
216
}
217