RunSqlCommandTest.php 4.08 KB
Newer Older
1 2
<?php

3
namespace Doctrine\DBAL\Tests\Tools\Console;
4

Sergei Morozov's avatar
Sergei Morozov committed
5
use Doctrine\DBAL\Connection;
6
use Doctrine\DBAL\Tools\Console\Command\RunSqlCommand;
7
use Doctrine\DBAL\Tools\Console\ConnectionProvider\SingleConnectionProvider;
Sergei Morozov's avatar
Sergei Morozov committed
8
use LogicException;
Grégoire Paris's avatar
Grégoire Paris committed
9
use PHPUnit\Framework\MockObject\MockObject;
Sergei Morozov's avatar
Sergei Morozov committed
10 11
use PHPUnit\Framework\TestCase;
use RuntimeException;
12 13 14
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Tester\CommandTester;

Sergei Morozov's avatar
Sergei Morozov committed
15
class RunSqlCommandTest extends TestCase
16 17 18 19 20 21
{
    /** @var CommandTester */
    private $commandTester;
    /** @var RunSqlCommand */
    private $command;

Grégoire Paris's avatar
Grégoire Paris committed
22
    /** @var Connection&MockObject */
23 24
    private $connectionMock;

25
    protected function setUp(): void
26
    {
Sergei Morozov's avatar
Sergei Morozov committed
27
        $this->connectionMock = $this->createMock(Connection::class);
28

29 30 31 32 33
        $application = new Application();
        $application->add(new RunSqlCommand(new SingleConnectionProvider($this->connectionMock)));

        $this->command       = $application->find('dbal:run-sql');
        $this->commandTester = new CommandTester($this->command);
34 35
    }

36
    public function testMissingSqlArgument(): void
37 38
    {
        try {
Sergei Morozov's avatar
Sergei Morozov committed
39
            $this->commandTester->execute([
40 41
                'command' => $this->command->getName(),
                'sql' => null,
Sergei Morozov's avatar
Sergei Morozov committed
42
            ]);
43
            self::fail('Expected a runtime exception when omitting sql argument');
Sergei Morozov's avatar
Sergei Morozov committed
44
        } catch (RuntimeException $e) {
45
            self::assertStringContainsString("Argument 'SQL", $e->getMessage());
46 47 48
        }
    }

49
    public function testIncorrectDepthOption(): void
50 51
    {
        try {
Sergei Morozov's avatar
Sergei Morozov committed
52
            $this->commandTester->execute([
53 54 55
                'command' => $this->command->getName(),
                'sql' => 'SELECT 1',
                '--depth' => 'string',
Sergei Morozov's avatar
Sergei Morozov committed
56
            ]);
57
            self::fail('Expected a logic exception when executing with a stringy depth');
Sergei Morozov's avatar
Sergei Morozov committed
58
        } catch (LogicException $e) {
59
            self::assertStringContainsString("Option 'depth'", $e->getMessage());
60 61 62
        }
    }

63
    public function testSelectStatementsPrintsResult(): void
64
    {
65
        $this->expectConnectionFetchAllAssociative();
66

67
        $exitCode = $this->commandTester->execute([
68 69
            'command' => $this->command->getName(),
            'sql' => 'SELECT 1',
Sergei Morozov's avatar
Sergei Morozov committed
70
        ]);
71
        self::assertSame(0, $exitCode);
72

73 74
        self::assertMatchesRegularExpression('@int.*1.*@', $this->commandTester->getDisplay());
        self::assertMatchesRegularExpression('@array.*1.*@', $this->commandTester->getDisplay());
75 76
    }

77
    public function testUpdateStatementsPrintsAffectedLines(): void
78
    {
79
        $this->expectConnectionExecuteStatement();
80

Sergei Morozov's avatar
Sergei Morozov committed
81
        $this->commandTester->execute([
82 83
            'command' => $this->command->getName(),
            'sql' => 'UPDATE foo SET bar = 42',
Sergei Morozov's avatar
Sergei Morozov committed
84
        ]);
85

86 87
        self::assertMatchesRegularExpression('@int.*42.*@', $this->commandTester->getDisplay());
        self::assertDoesNotMatchRegularExpression('@array.*1.*@', $this->commandTester->getDisplay());
88 89
    }

90
    private function expectConnectionExecuteStatement(): void
91 92
    {
        $this->connectionMock
93
            ->expects(self::once())
94
            ->method('executeStatement')
95 96
            ->willReturn(42);

97
        $this->connectionMock
98
            ->expects(self::never())
99
            ->method('fetchAllAssociative');
100 101
    }

102
    private function expectConnectionFetchAllAssociative(): void
103 104
    {
        $this->connectionMock
105
            ->expects(self::once())
106 107 108
            ->method('fetchAllAssociative')
            ->willReturn([[1]]);

109
        $this->connectionMock
110
            ->expects(self::never())
111
            ->method('executeStatement');
112
    }
113

114
    public function testStatementsWithFetchResultPrintsResult(): void
115
    {
116
        $this->expectConnectionFetchAllAssociative();
117

Sergei Morozov's avatar
Sergei Morozov committed
118
        $this->commandTester->execute([
119 120
            'command' => $this->command->getName(),
            'sql' => '"WITH bar as (SELECT 1) SELECT * FROM bar',
121
            '--force-fetch' => true,
Sergei Morozov's avatar
Sergei Morozov committed
122
        ]);
123

124 125
        self::assertMatchesRegularExpression('@int.*1.*@', $this->commandTester->getDisplay());
        self::assertMatchesRegularExpression('@array.*1.*@', $this->commandTester->getDisplay());
126
    }
127
}