DbalFunctionalTestCase.php 3.15 KB
Newer Older
1 2 3
<?php

namespace Doctrine\Tests;
Sergei Morozov's avatar
Sergei Morozov committed
4 5 6 7 8 9

use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Logging\DebugStack;
use Exception;
use PHPUnit\Framework\AssertionFailedError;
use Throwable;
10

11 12 13 14 15 16 17 18 19
use function array_map;
use function array_reverse;
use function count;
use function get_class;
use function implode;
use function is_object;
use function is_scalar;
use function strpos;
use function var_export;
20

Grégoire Paris's avatar
Grégoire Paris committed
21
use const PHP_EOL;
22

23
abstract class DbalFunctionalTestCase extends DbalTestCase
24
{
25 26 27
    /**
     * Shared connection when a TestCase is run alone (outside of it's functional suite)
     *
Sergei Morozov's avatar
Sergei Morozov committed
28
     * @var Connection
29
     */
Sergei Morozov's avatar
Sergei Morozov committed
30
    private static $sharedConnection;
31

Sergei Morozov's avatar
Sergei Morozov committed
32
    /** @var Connection */
Sergei Morozov's avatar
Sergei Morozov committed
33
    protected $connection;
34

Sergei Morozov's avatar
Sergei Morozov committed
35
    /** @var DebugStack */
Sergei Morozov's avatar
Sergei Morozov committed
36
    protected $sqlLoggerStack;
37

38
    protected function resetSharedConn(): void
39
    {
Sergei Morozov's avatar
Sergei Morozov committed
40
        if (! self::$sharedConnection) {
Sergei Morozov's avatar
Sergei Morozov committed
41
            return;
42
        }
Sergei Morozov's avatar
Sergei Morozov committed
43

Sergei Morozov's avatar
Sergei Morozov committed
44 45
        self::$sharedConnection->close();
        self::$sharedConnection = null;
46 47
    }

48
    protected function setUp(): void
49
    {
Sergei Morozov's avatar
Sergei Morozov committed
50 51
        if (! isset(self::$sharedConnection)) {
            self::$sharedConnection = TestUtil::getConnection();
52
        }
Grégoire Paris's avatar
Grégoire Paris committed
53

Sergei Morozov's avatar
Sergei Morozov committed
54
        $this->connection = self::$sharedConnection;
55

Sergei Morozov's avatar
Sergei Morozov committed
56 57
        $this->sqlLoggerStack = new DebugStack();
        $this->connection->getConfiguration()->setSQLLogger($this->sqlLoggerStack);
58 59
    }

60
    protected function tearDown(): void
61
    {
Sergei Morozov's avatar
Sergei Morozov committed
62 63
        while ($this->connection->isTransactionActive()) {
            $this->connection->rollBack();
64 65 66
        }
    }

67
    protected function onNotSuccessfulTest(Throwable $t): void
68
    {
Sergei Morozov's avatar
Sergei Morozov committed
69
        if ($t instanceof AssertionFailedError) {
Luís Cobucci's avatar
Luís Cobucci committed
70
            throw $t;
71 72
        }

Sergei Morozov's avatar
Sergei Morozov committed
73
        if (isset($this->sqlLoggerStack->queries) && count($this->sqlLoggerStack->queries)) {
Sergei Morozov's avatar
Sergei Morozov committed
74
            $queries = '';
Sergei Morozov's avatar
Sergei Morozov committed
75 76
            $i       = count($this->sqlLoggerStack->queries);
            foreach (array_reverse($this->sqlLoggerStack->queries) as $query) {
Sergei Morozov's avatar
Sergei Morozov committed
77
                $params   = array_map(static function ($p) {
78 79
                    if (is_object($p)) {
                        return get_class($p);
80 81 82
                    }

                    if (is_scalar($p)) {
Sergei Morozov's avatar
Sergei Morozov committed
83
                        return "'" . $p . "'";
84
                    }
Gabriel Caruso's avatar
Gabriel Caruso committed
85 86

                    return var_export($p, true);
Sergei Morozov's avatar
Sergei Morozov committed
87 88
                }, $query['params'] ?: []);
                $queries .= $i . ". SQL: '" . $query['sql'] . "' Params: " . implode(', ', $params) . PHP_EOL;
89
                $i--;
90 91
            }

Sergei Morozov's avatar
Sergei Morozov committed
92 93 94 95 96 97
            $trace    = $t->getTrace();
            $traceMsg = '';
            foreach ($trace as $part) {
                if (! isset($part['file'])) {
                    continue;
                }
98

Sergei Morozov's avatar
Sergei Morozov committed
99 100 101
                if (strpos($part['file'], 'PHPUnit/') !== false) {
                    // Beginning with PHPUnit files we don't print the trace anymore.
                    break;
102
                }
Sergei Morozov's avatar
Sergei Morozov committed
103 104

                $traceMsg .= $part['file'] . ':' . $part['line'] . PHP_EOL;
105 106
            }

Sergei Morozov's avatar
Sergei Morozov committed
107 108
            $message = '[' . get_class($t) . '] ' . $t->getMessage() . PHP_EOL . PHP_EOL
                . 'With queries:' . PHP_EOL . $queries . PHP_EOL . 'Trace:' . PHP_EOL . $traceMsg;
109

Sergei Morozov's avatar
Sergei Morozov committed
110
            throw new Exception($message, (int) $t->getCode(), $t);
111
        }
Grégoire Paris's avatar
Grégoire Paris committed
112

Luís Cobucci's avatar
Luís Cobucci committed
113
        throw $t;
114
    }
115
}