Merge "Remove useless $out parameter from SkinTemplate::prepareQuickTemplate()"
[lhc/web/wiklou.git] / tests / phpunit / includes / db / DatabaseMysqlBaseTest.php
1 <?php
2 /**
3 * Holds tests for DatabaseMysqlBase MediaWiki class.
4 *
5 * @section LICENSE
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 * http://www.gnu.org/copyleft/gpl.html
20 *
21 * @file
22 * @author Antoine Musso
23 * @author Bryan Davis
24 * @copyright © 2013 Antoine Musso
25 * @copyright © 2013 Bryan Davis
26 * @copyright © 2013 Wikimedia Foundation Inc.
27 */
28
29 /**
30 * Fake class around abstract class so we can call concrete methods.
31 */
32 class FakeDatabaseMysqlBase extends DatabaseMysqlBase {
33 // From DatabaseBase
34 function __construct() {}
35 protected function closeConnection() {}
36 protected function doQuery( $sql ) {}
37
38 // From DatabaseMysql
39 protected function mysqlConnect( $realServer ) {}
40 protected function mysqlSetCharset( $charset ) {}
41 protected function mysqlFreeResult( $res ) {}
42 protected function mysqlFetchObject( $res ) {}
43 protected function mysqlFetchArray( $res ) {}
44 protected function mysqlNumRows( $res ) {}
45 protected function mysqlNumFields( $res ) {}
46 protected function mysqlFieldName( $res, $n ) {}
47 protected function mysqlFieldType( $res, $n ) {}
48 protected function mysqlDataSeek( $res, $row ) {}
49 protected function mysqlError( $conn = null ) {}
50 protected function mysqlFetchField( $res, $n ) {}
51 protected function mysqlPing() {}
52
53 // From interface DatabaseType
54 function insertId() {}
55 function lastErrno() {}
56 function affectedRows() {}
57 function getServerVersion() {}
58 }
59
60 class DatabaseMysqlBaseTest extends MediaWikiTestCase {
61
62 /**
63 * @dataProvider provideDiapers
64 * @covers DatabaseMysqlBase::addIdentifierQuotes
65 */
66 public function testAddIdentifierQuotes( $expected, $in ) {
67 $db = new FakeDatabaseMysqlBase();
68 $quoted = $db->addIdentifierQuotes( $in );
69 $this->assertEquals( $expected, $quoted );
70 }
71
72 /**
73 * Feeds testAddIdentifierQuotes
74 *
75 * Named per bug 20281 convention.
76 */
77 function provideDiapers() {
78 return array(
79 // Format: expected, input
80 array( '``', '' ),
81
82 // Yeah I really hate loosely typed PHP idiocies nowadays
83 array( '``', null ),
84
85 // Dear codereviewer, guess what addIdentifierQuotes()
86 // will return with thoses:
87 array( '``', false ),
88 array( '`1`', true ),
89
90 // We never know what could happen
91 array( '`0`', 0 ),
92 array( '`1`', 1 ),
93
94 // Whatchout! Should probably use something more meaningful
95 array( "`'`", "'" ), # single quote
96 array( '`"`', '"' ), # double quote
97 array( '````', '`' ), # backtick
98 array( '`’`', '’' ), # apostrophe (look at your encyclopedia)
99
100 // sneaky NUL bytes are lurking everywhere
101 array( '``', "\0" ),
102 array( '`xyzzy`', "\0x\0y\0z\0z\0y\0" ),
103
104 // unicode chars
105 array(
106 self::createUnicodeString( '`\u0001a\uFFFFb`' ),
107 self::createUnicodeString( '\u0001a\uFFFFb' )
108 ),
109 array(
110 self::createUnicodeString( '`\u0001\uFFFF`' ),
111 self::createUnicodeString( '\u0001\u0000\uFFFF\u0000' )
112 ),
113 array( '`☃`', '☃' ),
114 array( '`メインページ`', 'メインページ' ),
115 array( '`Басты_бет`', 'Басты_бет' ),
116
117 // Real world:
118 array( '`Alix`', 'Alix' ), # while( ! $recovered ) { sleep(); }
119 array( '`Backtick: ```', 'Backtick: `' ),
120 array( '`This is a test`', 'This is a test' ),
121 );
122 }
123
124 private static function createUnicodeString( $str ) {
125 return json_decode( '"' . $str . '"' );
126 }
127
128 function getMockForViews() {
129 $db = $this->getMockBuilder( 'DatabaseMysql' )
130 ->disableOriginalConstructor()
131 ->setMethods( array( 'fetchRow', 'query' ) )
132 ->getMock();
133
134 $db->expects( $this->any() )
135 ->method( 'query' )
136 ->with( $this->anything() )
137 ->will(
138 $this->returnValue( null )
139 );
140
141 $db->expects( $this->any() )
142 ->method( 'fetchRow' )
143 ->with( $this->anything() )
144 ->will( $this->onConsecutiveCalls(
145 array( 'Tables_in_' => 'view1' ),
146 array( 'Tables_in_' => 'view2' ),
147 array( 'Tables_in_' => 'myview' ),
148 false # no more rows
149 ));
150 return $db;
151 }
152 /**
153 * @covers DatabaseMysqlBase::listViews
154 */
155 function testListviews() {
156 $db = $this->getMockForViews();
157
158 // The first call populate an internal cache of views
159 $this->assertEquals( array( 'view1', 'view2', 'myview' ),
160 $db->listViews() );
161 $this->assertEquals( array( 'view1', 'view2', 'myview' ),
162 $db->listViews() );
163
164 // Prefix filtering
165 $this->assertEquals( array( 'view1', 'view2' ),
166 $db->listViews( 'view' ) );
167 $this->assertEquals( array( 'myview' ),
168 $db->listViews( 'my' ) );
169 $this->assertEquals( array(),
170 $db->listViews( 'UNUSED_PREFIX' ) );
171 $this->assertEquals( array( 'view1', 'view2', 'myview' ),
172 $db->listViews( '' ) );
173 }
174
175 /**
176 * @covers DatabaseMysqlBase::isView
177 * @dataProvider provideViewExistanceChecks
178 */
179 function testIsView( $isView, $viewName ) {
180 $db = $this->getMockForViews();
181
182 switch ( $isView ) {
183 case true:
184 $this->assertTrue( $db->isView( $viewName ),
185 "$viewName should be considered a view" );
186 break;
187
188 case false:
189 $this->assertFalse( $db->isView( $viewName ),
190 "$viewName has not been defined as a view" );
191 break;
192 }
193
194 }
195
196 function provideViewExistanceChecks() {
197 return array(
198 // format: whether it is a view, view name
199 array( true, 'view1' ),
200 array( true, 'view2' ),
201 array( true, 'myview' ),
202
203 array( false, 'user' ),
204
205 array( false, 'view10' ),
206 array( false, 'my' ),
207 array( false, 'OH_MY_GOD' ), # they killed kenny!
208 );
209 }
210
211 }