3 * Holds tests for DatabaseMysqlBase MediaWiki class.
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.
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.
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
22 * @author Antoine Musso
24 * @copyright © 2013 Antoine Musso
25 * @copyright © 2013 Bryan Davis
26 * @copyright © 2013 Wikimedia Foundation Inc.
30 * Fake class around abstract class so we can call concrete methods.
32 class FakeDatabaseMysqlBase
extends DatabaseMysqlBase
{
34 function __construct() {
37 protected function closeConnection() {
40 protected function doQuery( $sql ) {
44 protected function mysqlConnect( $realServer ) {
47 protected function mysqlSetCharset( $charset ) {
50 protected function mysqlFreeResult( $res ) {
53 protected function mysqlFetchObject( $res ) {
56 protected function mysqlFetchArray( $res ) {
59 protected function mysqlNumRows( $res ) {
62 protected function mysqlNumFields( $res ) {
65 protected function mysqlFieldName( $res, $n ) {
68 protected function mysqlFieldType( $res, $n ) {
71 protected function mysqlDataSeek( $res, $row ) {
74 protected function mysqlError( $conn = null ) {
77 protected function mysqlFetchField( $res, $n ) {
80 protected function mysqlPing() {
83 // From interface DatabaseType
87 function lastErrno() {
90 function affectedRows() {
93 function getServerVersion() {
97 class DatabaseMysqlBaseTest
extends MediaWikiTestCase
{
99 * @dataProvider provideDiapers
100 * @covers DatabaseMysqlBase::addIdentifierQuotes
102 public function testAddIdentifierQuotes( $expected, $in ) {
103 $db = new FakeDatabaseMysqlBase();
104 $quoted = $db->addIdentifierQuotes( $in );
105 $this->assertEquals( $expected, $quoted );
109 * Feeds testAddIdentifierQuotes
111 * Named per bug 20281 convention.
113 function provideDiapers() {
115 // Format: expected, input
118 // Yeah I really hate loosely typed PHP idiocies nowadays
121 // Dear codereviewer, guess what addIdentifierQuotes()
122 // will return with thoses:
123 array( '``', false ),
124 array( '`1`', true ),
126 // We never know what could happen
130 // Whatchout! Should probably use something more meaningful
131 array( "`'`", "'" ), # single quote
132 array( '`"`', '"' ), # double quote
133 array( '````', '`' ), # backtick
134 array( '`’`', '’' ), # apostrophe (look at your encyclopedia)
136 // sneaky NUL bytes are lurking everywhere
138 array( '`xyzzy`', "\0x\0y\0z\0z\0y\0" ),
142 self
::createUnicodeString( '`\u0001a\uFFFFb`' ),
143 self
::createUnicodeString( '\u0001a\uFFFFb' )
146 self
::createUnicodeString( '`\u0001\uFFFF`' ),
147 self
::createUnicodeString( '\u0001\u0000\uFFFF\u0000' )
150 array( '`メインページ`', 'メインページ' ),
151 array( '`Басты_бет`', 'Басты_бет' ),
154 array( '`Alix`', 'Alix' ), # while( ! $recovered ) { sleep(); }
155 array( '`Backtick: ```', 'Backtick: `' ),
156 array( '`This is a test`', 'This is a test' ),
160 private static function createUnicodeString( $str ) {
161 return json_decode( '"' . $str . '"' );
164 function getMockForViews() {
165 $db = $this->getMockBuilder( 'DatabaseMysql' )
166 ->disableOriginalConstructor()
167 ->setMethods( array( 'fetchRow', 'query' ) )
170 $db->expects( $this->any() )
172 ->with( $this->anything() )
174 $this->returnValue( null )
177 $db->expects( $this->any() )
178 ->method( 'fetchRow' )
179 ->with( $this->anything() )
180 ->will( $this->onConsecutiveCalls(
181 array( 'Tables_in_' => 'view1' ),
182 array( 'Tables_in_' => 'view2' ),
183 array( 'Tables_in_' => 'myview' ),
189 * @covers DatabaseMysqlBase::listViews
191 function testListviews() {
192 $db = $this->getMockForViews();
194 // The first call populate an internal cache of views
195 $this->assertEquals( array( 'view1', 'view2', 'myview' ),
197 $this->assertEquals( array( 'view1', 'view2', 'myview' ),
201 $this->assertEquals( array( 'view1', 'view2' ),
202 $db->listViews( 'view' ) );
203 $this->assertEquals( array( 'myview' ),
204 $db->listViews( 'my' ) );
205 $this->assertEquals( array(),
206 $db->listViews( 'UNUSED_PREFIX' ) );
207 $this->assertEquals( array( 'view1', 'view2', 'myview' ),
208 $db->listViews( '' ) );
212 * @covers DatabaseMysqlBase::isView
213 * @dataProvider provideViewExistanceChecks
215 function testIsView( $isView, $viewName ) {
216 $db = $this->getMockForViews();
220 $this->assertTrue( $db->isView( $viewName ),
221 "$viewName should be considered a view" );
225 $this->assertFalse( $db->isView( $viewName ),
226 "$viewName has not been defined as a view" );
232 function provideViewExistanceChecks() {
234 // format: whether it is a view, view name
235 array( true, 'view1' ),
236 array( true, 'view2' ),
237 array( true, 'myview' ),
239 array( false, 'user' ),
241 array( false, 'view10' ),
242 array( false, 'my' ),
243 array( false, 'OH_MY_GOD' ), # they killed kenny!