Passed
Push — pulls/good-things-from-phpstan ( 7312f2...8f8b5f )
by Sam
10:36
created

testUtf8mb4GeneralCollation()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 25
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 17
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 25
rs 9.7
1
<?php
2
3
namespace SilverStripe\ORM\Tests;
4
5
use PDO;
6
use SilverStripe\Core\Config\Config;
7
use SilverStripe\ORM\Connect\MySQLDatabase;
8
use SilverStripe\Dev\SapphireTest;
9
use SilverStripe\Dev\TestOnly;
10
use SilverStripe\ORM\Tests\MySQLPDOConnectorTest\PDOConnector;
11
use SilverStripe\ORM\DB;
12
13
/**
14
 * @requires extension PDO
15
 * @requires extension pdo_mysql
16
 */
17
class MySQLPDOConnectorTest extends SapphireTest implements TestOnly
18
{
19
    /**
20
     * @dataProvider charsetProvider
21
     */
22
    public function testConnectionCharsetControl($charset, $defaultCollation)
23
    {
24
        $config = DB::getConfig();
25
        $config['driver'] = 'mysql';
26
        $config['charset'] = $charset;
27
        $config['database'] = 'information_schema';
28
        Config::inst()->set(MySQLDatabase::class, 'connection_collation', $defaultCollation);
0 ignored issues
show
Bug introduced by
The method set() does not exist on SilverStripe\Config\Coll...nfigCollectionInterface. It seems like you code against a sub-type of SilverStripe\Config\Coll...nfigCollectionInterface such as SilverStripe\Config\Coll...nfigCollectionInterface. ( Ignorable by Annotation )

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

28
        Config::inst()->/** @scrutinizer ignore-call */ set(MySQLDatabase::class, 'connection_collation', $defaultCollation);
Loading history...
29
30
        if (strtolower(substr($config['type'], 0, 5)) !== 'mysql') {
31
            return $this->markTestSkipped('The test only relevant for MySQL');
32
        }
33
34
        $connector = new PDOConnector();
35
        $connector->connect($config);
36
        $connection = $connector->getPDOConnection();
37
38
        $cset = $connection->query('show variables like "character_set_connection"')->fetch(PDO::FETCH_NUM)[1];
39
        $collation = $connection->query('show variables like "collation_connection"')->fetch(PDO::FETCH_NUM)[1];
40
41
        $this->assertEquals($charset, $cset);
42
        $this->assertEquals($defaultCollation, $collation);
43
44
        unset($cset, $connection, $connector, $config);
45
    }
46
47
    /**
48
     * @depends testConnectionCharsetControl
49
     * @dataProvider charsetProvider
50
     */
51
    public function testConnectionCollationControl($charset, $defaultCollation, $customCollation)
0 ignored issues
show
Unused Code introduced by
The parameter $defaultCollation is not used and could be removed. ( Ignorable by Annotation )

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

51
    public function testConnectionCollationControl($charset, /** @scrutinizer ignore-unused */ $defaultCollation, $customCollation)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
52
    {
53
        $config = DB::getConfig();
54
        $config['charset'] = $charset;
55
        $config['driver'] = 'mysql';
56
        $config['database'] = 'information_schema';
57
        Config::inst()->set(MySQLDatabase::class, 'connection_collation', $customCollation);
58
59
        if (strtolower(substr($config['type'], 0, 5)) !== 'mysql') {
60
            return $this->markTestSkipped('The test only relevant for MySQL');
61
        }
62
63
        $connector = new PDOConnector();
64
        $connector->connect($config);
65
        $connection = $connector->getPDOConnection();
66
67
        $cset = $connection->query('show variables like "character_set_connection"')->fetch(PDO::FETCH_NUM)[1];
68
        $collation = $connection->query('show variables like "collation_connection"')->fetch(PDO::FETCH_NUM)[1];
69
70
        $this->assertEquals($charset, $cset);
71
        $this->assertEquals($customCollation, $collation);
72
73
        unset($cset, $connection, $connector, $config);
74
    }
75
76
    public function charsetProvider()
77
    {
78
        return [
79
            ['ascii', 'ascii_general_ci', 'ascii_bin'],
80
            ['utf8', 'utf8_general_ci', 'utf8_unicode_520_ci'],
81
            ['utf8mb4', 'utf8mb4_general_ci', 'utf8mb4_unicode_520_ci']
82
        ];
83
    }
84
85
    public function testUtf8mb4GeneralCollation()
86
    {
87
        $charset = 'utf8mb4';
88
        $collation = 'utf8mb4_general_ci';
89
90
        $config = DB::getConfig();
91
        $config['charset'] = $charset;
92
        $config['driver'] = 'mysql';
93
        $config['database'] = 'information_schema';
94
        Config::inst()->set(MySQLDatabase::class, 'connection_collation', $collation);
95
96
        if (strtolower(substr($config['type'], 0, 5)) !== 'mysql') {
97
            return $this->markTestSkipped('The test only relevant for MySQL');
98
        }
99
100
        $connector = new PDOConnector();
101
        $connector->connect($config);
102
        $connection = $connector->getPDOConnection();
103
104
        $result = $connection->query(
105
            "select `a`.`value` from (select 'rst' `value` union select 'rßt' `value`) `a` order by `value`"
106
        )->fetchAll();
107
108
        $this->assertCount(1, $result, '`utf8mb4_general_ci` handles both values as equal to "rst"');
109
        $this->assertEquals('rst', $result[0][0]);
110
    }
111
112
    public function testUtf8mb4UnicodeCollation()
113
    {
114
        $charset = 'utf8mb4';
115
        $collation = 'utf8mb4_unicode_ci';
116
117
        $config = DB::getConfig();
118
        $config['charset'] = $charset;
119
        $config['driver'] = 'mysql';
120
        $config['database'] = 'information_schema';
121
        Config::inst()->set(MySQLDatabase::class, 'connection_collation', $collation);
122
123
        if (strtolower(substr($config['type'], 0, 5)) !== 'mysql') {
124
            return $this->markTestSkipped('The test only relevant for MySQL');
125
        }
126
127
        $connector = new PDOConnector();
128
        $connector->connect($config);
129
        $connection = $connector->getPDOConnection();
130
131
        $result = $connection->query(
132
            "select `a`.`value` from (select 'rst' `value` union select 'rßt' `value`) `a` order by `value`"
133
        )->fetchAll();
134
135
        $this->assertCount(2, $result, '`utf8mb4_unicode_ci` must recognise "rst" and "rßt" as different values');
136
        $this->assertEquals('rßt', $result[0][0]);
137
        $this->assertEquals('rst', $result[1][0]);
138
    }
139
}
140