Merge "Add mobile as a target on VisualEditor dependencies."
[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 mysqlDataSeek( $res, $row ) {}
48 protected function mysqlError( $conn = null ) {}
49 protected function mysqlFetchField( $res, $n ) {}
50 protected function mysqlPing() {}
51
52 // From interface DatabaseType
53 function insertId() {}
54 function lastErrno() {}
55 function affectedRows() {}
56 function getServerVersion() {}
57 }
58
59 class DatabaseMysqlBaseTest extends MediaWikiTestCase {
60
61 /**
62 * @dataProvider provideDiapers
63 * @covers DatabaseMysqlBase::addIdentifierQuotes
64 */
65 public function testAddIdentifierQuotes( $expected, $in ) {
66 $db = new FakeDatabaseMysqlBase();
67 $quoted = $db->addIdentifierQuotes( $in );
68 $this->assertEquals( $expected, $quoted );
69 }
70
71 /**
72 * Feeds testAddIdentifierQuotes
73 *
74 * Named per bug 20281 convention.
75 */
76 function provideDiapers() {
77 return array(
78 // Format: expected, input
79 array( '``', '' ),
80
81 // Yeah I really hate loosely typed PHP idiocies nowadays
82 array( '``', null ),
83
84 // Dear codereviewer, guess what addIdentifierQuotes()
85 // will return with thoses:
86 array( '``', false ),
87 array( '`1`', true ),
88
89 // We never know what could happen
90 array( '`0`', 0 ),
91 array( '`1`', 1 ),
92
93 // Whatchout! Should probably use something more meaningful
94 array( "`'`", "'" ), # single quote
95 array( '`"`', '"' ), # double quote
96 array( '````', '`' ), # backtick
97 array( '`’`', '’' ), # apostrophe (look at your encyclopedia)
98
99 // sneaky NUL bytes are lurking everywhere
100 array( '``', "\0" ),
101 array( '`xyzzy`', "\0x\0y\0z\0z\0y\0" ),
102
103 // unicode chars
104 array(
105 self::createUnicodeString( '`\u0001a\uFFFFb`' ),
106 self::createUnicodeString( '\u0001a\uFFFFb' )
107 ),
108 array(
109 self::createUnicodeString( '`\u0001\uFFFF`' ),
110 self::createUnicodeString( '\u0001\u0000\uFFFF\u0000' )
111 ),
112 array( '`☃`', '☃' ),
113 array( '`メインページ`', 'メインページ' ),
114 array( '`Басты_бет`', 'Басты_бет' ),
115
116 // Real world:
117 array( '`Alix`', 'Alix' ), # while( ! $recovered ) { sleep(); }
118 array( '`Backtick: ```', 'Backtick: `' ),
119 array( '`This is a test`', 'This is a test' ),
120 );
121 }
122
123 private static function createUnicodeString( $str ) {
124 return json_decode( '"' . $str . '"' );
125 }
126
127 function getMockForViews() {
128 $db = $this->getMockBuilder( 'DatabaseMysql' )
129 ->disableOriginalConstructor()
130 ->setMethods( array( 'fetchRow', 'query' ) )
131 ->getMock();
132
133 $db->expects( $this->any() )
134 ->method( 'query' )
135 ->with( $this->anything() )
136 ->will(
137 $this->returnValue( null )
138 );
139
140 $db->expects( $this->any() )
141 ->method( 'fetchRow' )
142 ->with( $this->anything() )
143 ->will( $this->onConsecutiveCalls(
144 array( 'Tables_in_' => 'view1' ),
145 array( 'Tables_in_' => 'view2' ),
146 array( 'Tables_in_' => 'myview' ),
147 false # no more rows
148 ));
149 return $db;
150 }
151 /**
152 * @covers DatabaseMysqlBase::listViews
153 */
154 function testListviews() {
155 $db = $this->getMockForViews();
156
157 // The first call populate an internal cache of views
158 $this->assertEquals( array( 'view1', 'view2', 'myview' ),
159 $db->listViews() );
160 $this->assertEquals( array( 'view1', 'view2', 'myview' ),
161 $db->listViews() );
162
163 // Prefix filtering
164 $this->assertEquals( array( 'view1', 'view2' ),
165 $db->listViews( 'view' ) );
166 $this->assertEquals( array( 'myview' ),
167 $db->listViews( 'my' ) );
168 $this->assertEquals( array(),
169 $db->listViews( 'UNUSED_PREFIX' ) );
170 $this->assertEquals( array( 'view1', 'view2', 'myview' ),
171 $db->listViews( '' ) );
172 }
173
174 /**
175 * @covers DatabaseMysqlBase::isView
176 * @dataProvider provideViewExistanceChecks
177 */
178 function testIsView( $isView, $viewName ) {
179 $db = $this->getMockForViews();
180
181 switch ( $isView ) {
182 case true:
183 $this->assertTrue( $db->isView( $viewName ),
184 "$viewName should be considered a view" );
185 break;
186
187 case false:
188 $this->assertFalse( $db->isView( $viewName ),
189 "$viewName has not been defined as a view" );
190 break;
191 }
192
193 }
194
195 function provideViewExistanceChecks() {
196 return array(
197 // format: whether it is a view, view name
198 array( true, 'view1' ),
199 array( true, 'view2' ),
200 array( true, 'myview' ),
201
202 array( false, 'user' ),
203
204 array( false, 'view10' ),
205 array( false, 'my' ),
206 array( false, 'OH_MY_GOD' ), # they killed kenny!
207 );
208 }
209
210 }