From a1789ddde42033f1b05cc4929491214ee6e79383 Mon Sep 17 00:00:00 2001
From: Pierre Schmitz <pierre@archlinux.de>
Date: Thu, 17 Dec 2015 09:15:42 +0100
Subject: Update to MediaWiki 1.26.0

---
 tests/phpunit/includes/utils/AvroValidatorTest.php |  96 ++++++++
 .../phpunit/includes/utils/BatchRowUpdateTest.php  | 243 ++++++++++++++++++
 tests/phpunit/includes/utils/IPTest.php            | 273 +++++++++++++--------
 tests/phpunit/includes/utils/MWFunctionTest.php    |  34 ---
 tests/phpunit/includes/utils/UIDGeneratorTest.php  |  10 +-
 5 files changed, 514 insertions(+), 142 deletions(-)
 create mode 100644 tests/phpunit/includes/utils/AvroValidatorTest.php
 create mode 100644 tests/phpunit/includes/utils/BatchRowUpdateTest.php
 delete mode 100644 tests/phpunit/includes/utils/MWFunctionTest.php

(limited to 'tests/phpunit/includes/utils')

diff --git a/tests/phpunit/includes/utils/AvroValidatorTest.php b/tests/phpunit/includes/utils/AvroValidatorTest.php
new file mode 100644
index 00000000..52c242c1
--- /dev/null
+++ b/tests/phpunit/includes/utils/AvroValidatorTest.php
@@ -0,0 +1,96 @@
+<?php
+/**
+ * Tests for IP validity functions.
+ *
+ * Ported from /t/inc/IP.t by avar.
+ *
+ * @group IP
+ * @todo Test methods in this call should be split into a method and a
+ * dataprovider.
+ */
+
+class AvroValidatorTest extends PHPUnit_Framework_TestCase {
+	public function setUp() {
+		if ( !class_exists( 'AvroSchema' ) ) {
+			$this->markTestSkipped( 'Avro is required to run the AvroValidatorTest' );
+		}
+		parent::setUp();
+	}
+
+	public function getErrorsProvider() {
+		$stringSchema = AvroSchema::parse( json_encode( array( 'type' => 'string' ) ) );
+		$recordSchema = AvroSchema::parse( json_encode( array(
+			'type' => 'record',
+			'name' => 'ut',
+			'fields' => array(
+				array( 'name' => 'id', 'type' => 'int', 'required' => true ),
+			),
+		) ) );
+		$enumSchema = AvroSchema::parse( json_encode( array(
+			'type' => 'record',
+			'name' => 'ut',
+			'fields' => array(
+				array( 'name' => 'count', 'type' => array( 'int', 'null' ) ),
+			),
+		) ) );
+
+		return array(
+			array(
+				'No errors with a simple string serialization',
+				$stringSchema, 'foobar', array(),
+			),
+
+			array(
+				'Cannot serialize integer into string',
+				$stringSchema, 5, 'Expected string, but recieved integer',
+			),
+
+			array(
+				'Cannot serialize array into string',
+				$stringSchema, array(), 'Expected string, but recieved array',
+			),
+
+			array(
+				'allows and ignores extra fields',
+				$recordSchema, array( 'id' => 4, 'foo' => 'bar' ), array(),
+			),
+
+			array(
+				'detects missing fields',
+				$recordSchema, array(), array( 'id' => 'Missing expected field' ),
+			),
+
+			array(
+				'handles first element in enum',
+				$enumSchema, array( 'count' => 4 ), array(),
+			),
+
+			array(
+				'handles second element in enum',
+				$enumSchema, array( 'count' => null ), array(),
+			),
+
+			array(
+				'rejects element not in union',
+				$enumSchema, array( 'count' => 'invalid' ), array( 'count' => array(
+					'Expected any one of these to be true',
+					array(
+						'Expected integer, but recieved string',
+						'Expected null, but recieved string',
+					)
+				) )
+			),
+		);
+	}
+
+	/**
+	 * @dataProvider getErrorsProvider
+	 */
+	public function testGetErrors( $message, $schema, $datum, $expected ) {
+		$this->assertEquals(
+			$expected,
+			AvroValidator::getErrors( $schema, $datum ),
+			$message
+		);
+	}
+}
diff --git a/tests/phpunit/includes/utils/BatchRowUpdateTest.php b/tests/phpunit/includes/utils/BatchRowUpdateTest.php
new file mode 100644
index 00000000..a2b35f39
--- /dev/null
+++ b/tests/phpunit/includes/utils/BatchRowUpdateTest.php
@@ -0,0 +1,243 @@
+<?php
+
+/**
+ * Tests for BatchRowUpdate and its components
+ *
+ * @group db
+ */
+class BatchRowUpdateTest extends MediaWikiTestCase {
+
+	public function testWriterBasicFunctionality() {
+		$db = $this->mockDb();
+		$writer = new BatchRowWriter( $db, 'echo_event' );
+
+		$updates = array(
+			self::mockUpdate( array( 'something' => 'changed' ) ),
+			self::mockUpdate( array( 'otherthing' => 'changed' ) ),
+			self::mockUpdate( array( 'and' => 'something', 'else' => 'changed' ) ),
+		);
+
+		$db->expects( $this->exactly( count( $updates ) ) )
+			->method( 'update' );
+
+		$writer->write( $updates );
+	}
+
+	static protected function mockUpdate( array $changes ) {
+		static $i = 0;
+		return array(
+			'primaryKey' => array( 'event_id' => $i++ ),
+			'changes' => $changes,
+		);
+	}
+
+	public function testReaderBasicIterate() {
+		$db = $this->mockDb();
+		$batchSize = 2;
+		$reader = new BatchRowIterator( $db, 'some_table', 'id_field', $batchSize );
+
+		$response = $this->genSelectResult( $batchSize, /*numRows*/ 5, function() {
+			static $i = 0;
+			return array( 'id_field' => ++$i );
+		} );
+		$db->expects( $this->exactly( count( $response ) ) )
+			->method( 'select' )
+			->will( $this->consecutivelyReturnFromSelect( $response ) );
+
+		$pos = 0;
+		foreach ( $reader as $rows ) {
+			$this->assertEquals( $response[$pos], $rows, "Testing row in position $pos" );
+			$pos++;
+		}
+		// -1 is because the final array() marks the end and isnt included
+		$this->assertEquals( count( $response ) - 1, $pos );
+	}
+
+	static public function provider_readerGetPrimaryKey() {
+		$row = array(
+			'id_field' => 42,
+			'some_col' => 'dvorak',
+			'other_col' => 'samurai',
+		);
+		return array(
+
+			array(
+				'Must return single column pk when requested',
+				array( 'id_field' => 42 ),
+				$row
+			),
+
+			array(
+				'Must return multiple column pks when requested',
+				array( 'id_field' => 42, 'other_col' => 'samurai' ),
+				$row
+			),
+
+		);
+	}
+
+	/**
+	 * @dataProvider provider_readerGetPrimaryKey
+	 */
+	public function testReaderGetPrimaryKey( $message, array $expected, array $row ) {
+		$reader = new BatchRowIterator( $this->mockDb(), 'some_table', array_keys( $expected ), 8675309 );
+		$this->assertEquals( $expected, $reader->extractPrimaryKeys( (object) $row ), $message );
+	}
+
+	static public function provider_readerSetFetchColumns() {
+		return array(
+
+			array(
+				'Must merge primary keys into select conditions',
+				// Expected column select
+				array( 'foo', 'bar' ),
+				// primary keys
+				array( 'foo' ),
+				// setFetchColumn
+				array( 'bar' )
+			),
+
+			array(
+				'Must not merge primary keys into the all columns selector',
+				// Expected column select
+				array( '*' ),
+				// primary keys
+				array( 'foo' ),
+				// setFetchColumn
+				array( '*' ),
+			),
+
+			array(
+				'Must not duplicate primary keys into column selector',
+				// Expected column select.
+				// TODO: figure out how to only assert the array_values portion and not the keys
+				array( 0 => 'foo', 1 => 'bar', 3 => 'baz' ),
+				// primary keys
+				array( 'foo', 'bar', ),
+				// setFetchColumn
+				array( 'bar', 'baz' ),
+			),
+		);
+	}
+
+	/**
+	 * @dataProvider provider_readerSetFetchColumns
+	 */
+	public function testReaderSetFetchColumns( $message, array $columns, array $primaryKeys, array $fetchColumns ) {
+		$db = $this->mockDb();
+		$db->expects( $this->once() )
+			->method( 'select' )
+			->with( 'some_table', $columns ) // only testing second parameter of DatabaseBase::select
+			->will( $this->returnValue( new ArrayIterator( array() ) ) );
+
+		$reader = new BatchRowIterator( $db, 'some_table', $primaryKeys, 22 );
+		$reader->setFetchColumns( $fetchColumns );
+		// triggers first database select
+		$reader->rewind();
+	}
+
+	static public function provider_readerSelectConditions() {
+		return array(
+
+			array(
+				"With single primary key must generate id > 'value'",
+				// Expected second iteration
+				array( "( id_field > '3' )" ),
+				// Primary key(s)
+				'id_field',
+			),
+
+			array(
+				'With multiple primary keys the first conditions must use >= and the final condition must use >',
+				// Expected second iteration
+				array( "( id_field = '3' AND foo > '103' ) OR ( id_field > '3' )" ),
+				// Primary key(s)
+				array( 'id_field', 'foo' ),
+			),
+
+		);
+	}
+
+	/**
+	 * Slightly hackish to use reflection, but asserting different parameters
+	 * to consecutive calls of DatabaseBase::select in phpunit is error prone
+	 *
+	 * @dataProvider provider_readerSelectConditions
+	 */
+	public function testReaderSelectConditionsMultiplePrimaryKeys( $message, $expectedSecondIteration, $primaryKeys, $batchSize = 3 ) {
+		$results = $this->genSelectResult( $batchSize, $batchSize * 3, function() {
+			static $i = 0, $j = 100, $k = 1000;
+			return array( 'id_field' => ++$i, 'foo' => ++$j, 'bar' => ++$k );
+		} );
+		$db = $this->mockDbConsecutiveSelect( $results );
+
+		$conditions = array( 'bar' => 42, 'baz' => 'hai' );
+		$reader = new BatchRowIterator( $db, 'some_table', $primaryKeys, $batchSize );
+		$reader->addConditions( $conditions );
+
+		$buildConditions = new ReflectionMethod( $reader, 'buildConditions' );
+		$buildConditions->setAccessible( true );
+
+		// On first iteration only the passed conditions must be used
+		$this->assertEquals( $conditions, $buildConditions->invoke( $reader ),
+			'First iteration must return only the conditions passed in addConditions' );
+		$reader->rewind();
+
+		// Second iteration must use the maximum primary key of last set
+		$this->assertEquals(
+			$conditions + $expectedSecondIteration,
+			$buildConditions->invoke( $reader ),
+			$message
+		);
+	}
+
+	protected function mockDbConsecutiveSelect( array $retvals ) {
+		$db = $this->mockDb();
+		$db->expects( $this->any() )
+			->method( 'select' )
+			->will( $this->consecutivelyReturnFromSelect( $retvals ) );
+		$db->expects( $this->any() )
+			->method( 'addQuotes' )
+			->will( $this->returnCallback( function( $value ) {
+				return "'$value'"; // not real quoting: doesn't matter in test
+			} ) );
+
+		return $db;
+	}
+
+	protected function consecutivelyReturnFromSelect( array $results ) {
+		$retvals = array();
+		foreach ( $results as $rows ) {
+			// The DatabaseBase::select method returns iterators, so we do too.
+			$retvals[] = $this->returnValue( new ArrayIterator( $rows ) );
+		}
+
+		return call_user_func_array( array( $this, 'onConsecutiveCalls' ), $retvals );
+	}
+
+
+	protected function genSelectResult( $batchSize, $numRows, $rowGenerator ) {
+		$res = array();
+		for ( $i = 0; $i < $numRows; $i += $batchSize ) {
+			$rows = array();
+			for ( $j = 0; $j < $batchSize && $i + $j < $numRows; $j++ ) {
+				$rows [] = (object) call_user_func( $rowGenerator );
+			}
+			$res[] = $rows;
+		}
+		$res[] = array(); // termination condition requires empty result for last row
+		return $res;
+	}
+
+	protected function mockDb() {
+		// Cant mock from DatabaseType or DatabaseBase, they dont
+		// have the full gamut of methods
+		$databaseMysql = $this->getMockBuilder( 'DatabaseMysql' )
+			->disableOriginalConstructor()
+			->getMock();
+		$databaseMysql->expects( $this->any() )
+			->method( 'isOpen' )
+			->will( $this->returnValue( true ) );
+		return $databaseMysql;
+	}
+}
diff --git a/tests/phpunit/includes/utils/IPTest.php b/tests/phpunit/includes/utils/IPTest.php
index 09c1587d..04b8f486 100644
--- a/tests/phpunit/includes/utils/IPTest.php
+++ b/tests/phpunit/includes/utils/IPTest.php
@@ -11,29 +11,37 @@
 
 class IPTest extends PHPUnit_Framework_TestCase {
 	/**
-	 *  not sure it should be tested with boolean false. hashar 20100924
 	 * @covers IP::isIPAddress
+	 * @dataProvider provideInvalidIPs
 	 */
-	public function testisIPAddress() {
-		$this->assertFalse( IP::isIPAddress( false ), 'Boolean false is not an IP' );
-		$this->assertFalse( IP::isIPAddress( true ), 'Boolean true is not an IP' );
-		$this->assertFalse( IP::isIPAddress( "" ), 'Empty string is not an IP' );
-		$this->assertFalse( IP::isIPAddress( 'abc' ), 'Garbage IP string' );
-		$this->assertFalse( IP::isIPAddress( ':' ), 'Single ":" is not an IP' );
-		$this->assertFalse( IP::isIPAddress( '2001:0DB8::A:1::1' ), 'IPv6 with a double :: occurrence' );
-		$this->assertFalse(
-			IP::isIPAddress( '2001:0DB8::A:1::' ),
-			'IPv6 with a double :: occurrence, last at end'
-		);
-		$this->assertFalse(
-			IP::isIPAddress( '::2001:0DB8::5:1' ),
-			'IPv6 with a double :: occurrence, firt at beginning'
+	public function isNotIPAddress( $val, $desc ) {
+		$this->assertFalse( IP::isIPAddress( $val ), $desc );
+	}
+
+	/**
+	 * Provide a list of things that aren't IP addresses
+	 */
+	public function provideInvalidIPs() {
+		return array(
+			array( false, 'Boolean false is not an IP' ),
+			array( true, 'Boolean true is not an IP' ),
+			array( '', 'Empty string is not an IP' ),
+			array( 'abc', 'Garbage IP string' ),
+			array( ':', 'Single ":" is not an IP' ),
+			array( '2001:0DB8::A:1::1', 'IPv6 with a double :: occurrence' ),
+			array( '2001:0DB8::A:1::', 'IPv6 with a double :: occurrence, last at end' ),
+			array( '::2001:0DB8::5:1', 'IPv6 with a double :: occurrence, firt at beginning' ),
+			array( '124.24.52', 'IPv4 not enough quads' ),
+			array( '24.324.52.13', 'IPv4 out of range' ),
+			array( '.24.52.13', 'IPv4 starts with period' ),
+			array( 'fc:100:300', 'IPv6 with only 3 words' ),
 		);
-		$this->assertFalse( IP::isIPAddress( '124.24.52' ), 'IPv4 not enough quads' );
-		$this->assertFalse( IP::isIPAddress( '24.324.52.13' ), 'IPv4 out of range' );
-		$this->assertFalse( IP::isIPAddress( '.24.52.13' ), 'IPv4 starts with period' );
-		$this->assertFalse( IP::isIPAddress( 'fc:100:300' ), 'IPv6 with only 3 words' );
+	}
 
+	/**
+	 * @covers IP::isIPAddress
+	 */
+	public function testisIPAddress() {
 		$this->assertTrue( IP::isIPAddress( '::' ), 'RFC 4291 IPv6 Unspecified Address' );
 		$this->assertTrue( IP::isIPAddress( '::1' ), 'RFC 4291 IPv6 Loopback Address' );
 		$this->assertTrue( IP::isIPAddress( '74.24.52.13/20', 'IPv4 range' ) );
@@ -107,20 +115,42 @@ class IPTest extends PHPUnit_Framework_TestCase {
 
 	/**
 	 * @covers IP::isIPv4
+	 * @dataProvider provideInvalidIPv4Addresses
+	 */
+	public function testisNotIPv4( $bogusIP, $desc ) {
+		$this->assertFalse( IP::isIPv4( $bogusIP ), $desc );
+	}
+
+	public function provideInvalidIPv4Addresses() {
+		return array(
+			array( false, 'Boolean false is not an IP' ),
+			array( true, 'Boolean true is not an IP' ),
+			array( '', 'Empty string is not an IP' ),
+			array( 'abc', 'Letters are not an IP' ),
+			array( ':', 'A colon is not an IP' ),
+			array( '124.24.52', 'IPv4 not enough quads' ),
+			array( '24.324.52.13', 'IPv4 out of range' ),
+			array( '.24.52.13', 'IPv4 starts with period' ),
+		);
+	}
+
+	/**
+	 * @covers IP::isIPv4
+	 * @dataProvider provideValidIPv4Address
 	 */
-	public function testisIPv4() {
-		$this->assertFalse( IP::isIPv4( false ), 'Boolean false is not an IP' );
-		$this->assertFalse( IP::isIPv4( true ), 'Boolean true is not an IP' );
-		$this->assertFalse( IP::isIPv4( "" ), 'Empty string is not an IP' );
-		$this->assertFalse( IP::isIPv4( 'abc' ) );
-		$this->assertFalse( IP::isIPv4( ':' ) );
-		$this->assertFalse( IP::isIPv4( '124.24.52' ), 'IPv4 not enough quads' );
-		$this->assertFalse( IP::isIPv4( '24.324.52.13' ), 'IPv4 out of range' );
-		$this->assertFalse( IP::isIPv4( '.24.52.13' ), 'IPv4 starts with period' );
+	public function testIsIPv4( $ip, $desc ) {
+		$this->assertTrue( IP::isIPv4( $ip ), $desc );
+	}
 
-		$this->assertTrue( IP::isIPv4( '124.24.52.13' ) );
-		$this->assertTrue( IP::isIPv4( '1.24.52.13' ) );
-		$this->assertTrue( IP::isIPv4( '74.24.52.13/20', 'IPv4 range' ) );
+	/**
+	 * Provide some IPv4 addresses and ranges
+	 */
+	public function provideValidIPv4Address() {
+		return array(
+			array( '124.24.52.13', 'Valid IPv4 address' ),
+			array( '1.24.52.13', 'Another valid IPv4 address' ),
+			array( '74.24.52.13/20', 'An IPv4 range' ),
+		);
 	}
 
 	/**
@@ -224,49 +254,56 @@ class IPTest extends PHPUnit_Framework_TestCase {
 	}
 
 	/**
-	 * @covers IP::isValidBlock
+	 * Provide some valid IP blocks
 	 */
-	public function testValidBlocks() {
-		$valid = array(
-			'116.17.184.5/32',
-			'0.17.184.5/30',
-			'16.17.184.1/24',
-			'30.242.52.14/1',
-			'10.232.52.13/8',
-			'30.242.52.14/0',
-			'::e:f:2001/96',
-			'::c:f:2001/128',
-			'::10:f:2001/70',
-			'::fe:f:2001/1',
-			'::6d:f:2001/8',
-			'::fe:f:2001/0',
+	public function provideValidBlocks() {
+		return array(
+			array( '116.17.184.5/32' ),
+			array( '0.17.184.5/30' ),
+			array( '16.17.184.1/24' ),
+			array( '30.242.52.14/1' ),
+			array( '10.232.52.13/8' ),
+			array( '30.242.52.14/0' ),
+			array( '::e:f:2001/96' ),
+			array( '::c:f:2001/128' ),
+			array( '::10:f:2001/70' ),
+			array( '::fe:f:2001/1' ),
+			array( '::6d:f:2001/8' ),
+			array( '::fe:f:2001/0' ),
 		);
-		foreach ( $valid as $i ) {
-			$this->assertTrue( IP::isValidBlock( $i ), "$i is a valid IP block" );
-		}
 	}
 
 	/**
 	 * @covers IP::isValidBlock
+	 * @dataProvider provideValidBlocks
 	 */
-	public function testInvalidBlocks() {
-		$invalid = array(
-			'116.17.184.5/33',
-			'0.17.184.5/130',
-			'16.17.184.1/-1',
-			'10.232.52.13/*',
-			'7.232.52.13/ab',
-			'11.232.52.13/',
-			'::e:f:2001/129',
-			'::c:f:2001/228',
-			'::10:f:2001/-1',
-			'::6d:f:2001/*',
-			'::86:f:2001/ab',
-			'::23:f:2001/',
+	public function testValidBlocks( $block ) {
+		$this->assertTrue( IP::isValidBlock( $block ), "$block is a valid IP block" );
+	}
+
+	/**
+	 * @covers IP::isValidBlock
+	 * @dataProvider provideInvalidBlocks
+	 */
+	public function testInvalidBlocks( $invalid ) {
+		$this->assertFalse( IP::isValidBlock( $invalid ), "$invalid is not a valid IP block" );
+	}
+
+	public function provideInvalidBlocks() {
+		return array(
+			array( '116.17.184.5/33' ),
+			array( '0.17.184.5/130' ),
+			array( '16.17.184.1/-1' ),
+			array( '10.232.52.13/*' ),
+			array( '7.232.52.13/ab' ),
+			array( '11.232.52.13/' ),
+			array( '::e:f:2001/129' ),
+			array( '::c:f:2001/228' ),
+			array( '::10:f:2001/-1' ),
+			array( '::6d:f:2001/*' ),
+			array( '::86:f:2001/ab' ),
+			array( '::23:f:2001/' ),
 		);
-		foreach ( $invalid as $i ) {
-			$this->assertFalse( IP::isValidBlock( $i ), "$i is not a valid IP block" );
-		}
 	}
 
 	/**
@@ -310,16 +347,31 @@ class IPTest extends PHPUnit_Framework_TestCase {
 
 	/**
 	 * @covers IP::isPublic
+	 * @dataProvider provideIsPublic
 	 */
-	public function testPrivateIPs() {
-		$private = array( 'fc00::3', 'fc00::ff', '::1', '10.0.0.1', '172.16.0.1', '192.168.0.1' );
-		foreach ( $private as $p ) {
-			$this->assertFalse( IP::isPublic( $p ), "$p is not a public IP address" );
-		}
-		$public = array( '2001:5c0:1000:a::133', 'fc::3', '00FC::' );
-		foreach ( $public as $p ) {
-			$this->assertTrue( IP::isPublic( $p ), "$p is a public IP address" );
-		}
+	public function testIsPublic( $expected, $input ) {
+		$result = IP::isPublic( $input );
+		$this->assertEquals( $expected, $result );
+	}
+
+	/**
+	 * Provider for IP::testIsPublic()
+	 */
+	public static function provideIsPublic() {
+		return array(
+			array( false, 'fc00::3' ), # RFC 4193 (local)
+			array( false, 'fc00::ff' ), # RFC 4193 (local)
+			array( false, '127.1.2.3' ), # loopback
+			array( false, '::1' ), # loopback
+			array( false, 'fe80::1' ), # link-local
+			array( false, '169.254.1.1' ), # link-local
+			array( false, '10.0.0.1' ), # RFC 1918 (private)
+			array( false, '172.16.0.1' ), # RFC 1918 (private)
+			array( false, '192.168.0.1' ), # RFC 1918 (private)
+			array( true, '2001:5c0:1000:a::133' ), # public
+			array( true, 'fc::3' ), # public
+			array( true, '00FC::' ) # public
+		);
 	}
 
 	// Private wrapper used to test CIDR Parsing.
@@ -336,40 +388,55 @@ class IPTest extends PHPUnit_Framework_TestCase {
 
 	/**
 	 * @covers IP::hexToQuad
+	 * @dataProvider provideIPsAndHexes
 	 */
-	public function testHexToQuad() {
-		$this->assertEquals( '0.0.0.1', IP::hexToQuad( '00000001' ) );
-		$this->assertEquals( '255.0.0.0', IP::hexToQuad( 'FF000000' ) );
-		$this->assertEquals( '255.255.255.255', IP::hexToQuad( 'FFFFFFFF' ) );
-		$this->assertEquals( '10.188.222.255', IP::hexToQuad( '0ABCDEFF' ) );
-		// hex not left-padded...
-		$this->assertEquals( '0.0.0.0', IP::hexToQuad( '0' ) );
-		$this->assertEquals( '0.0.0.1', IP::hexToQuad( '1' ) );
-		$this->assertEquals( '0.0.0.255', IP::hexToQuad( 'FF' ) );
-		$this->assertEquals( '0.0.255.0', IP::hexToQuad( 'FF00' ) );
+	public function testHexToQuad( $ip, $hex ) {
+		$this->assertEquals( $ip, IP::hexToQuad( $hex ) );
+	}
+
+	/**
+	 * Provide some IP addresses and their equivalent hex representations
+	 */
+	public function provideIPsandHexes() {
+		return array(
+			array( '0.0.0.1', '00000001' ),
+			array( '255.0.0.0', 'FF000000' ),
+			array( '255.255.255.255', 'FFFFFFFF' ),
+			array( '10.188.222.255', '0ABCDEFF' ),
+			// hex not left-padded...
+			array( '0.0.0.0', '0' ),
+			array( '0.0.0.1', '1' ),
+			array( '0.0.0.255', 'FF' ),
+			array( '0.0.255.0', 'FF00' ),
+		);
 	}
 
 	/**
 	 * @covers IP::hexToOctet
+	 * @dataProvider provideOctetsAndHexes
 	 */
-	public function testHexToOctet() {
-		$this->assertEquals( '0:0:0:0:0:0:0:1',
-			IP::hexToOctet( '00000000000000000000000000000001' ) );
-		$this->assertEquals( '0:0:0:0:0:0:FF:3',
-			IP::hexToOctet( '00000000000000000000000000FF0003' ) );
-		$this->assertEquals( '0:0:0:0:0:0:FF00:6',
-			IP::hexToOctet( '000000000000000000000000FF000006' ) );
-		$this->assertEquals( '0:0:0:0:0:0:FCCF:FAFF',
-			IP::hexToOctet( '000000000000000000000000FCCFFAFF' ) );
-		$this->assertEquals( 'FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF',
-			IP::hexToOctet( 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' ) );
-		// hex not left-padded...
-		$this->assertEquals( '0:0:0:0:0:0:0:0', IP::hexToOctet( '0' ) );
-		$this->assertEquals( '0:0:0:0:0:0:0:1', IP::hexToOctet( '1' ) );
-		$this->assertEquals( '0:0:0:0:0:0:0:FF', IP::hexToOctet( 'FF' ) );
-		$this->assertEquals( '0:0:0:0:0:0:0:FFD0', IP::hexToOctet( 'FFD0' ) );
-		$this->assertEquals( '0:0:0:0:0:0:FA00:0', IP::hexToOctet( 'FA000000' ) );
-		$this->assertEquals( '0:0:0:0:0:0:FCCF:FAFF', IP::hexToOctet( 'FCCFFAFF' ) );
+	public function testHexToOctet( $octet, $hex ) {
+		$this->assertEquals( $octet, IP::hexToOctet( $hex ) );
+	}
+
+	/**
+	 * Provide some hex and octet representations of the same IPs
+	 */
+	public function provideOctetsAndHexes() {
+		return array(
+			array( '0:0:0:0:0:0:0:1', '00000000000000000000000000000001' ),
+			array( '0:0:0:0:0:0:FF:3', '00000000000000000000000000FF0003' ),
+			array( '0:0:0:0:0:0:FF00:6', '000000000000000000000000FF000006' ),
+			array( '0:0:0:0:0:0:FCCF:FAFF', '000000000000000000000000FCCFFAFF' ),
+			array( 'FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF', 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' ),
+			// hex not left-padded...
+			array( '0:0:0:0:0:0:0:0', '0' ),
+			array( '0:0:0:0:0:0:0:1', '1' ),
+			array( '0:0:0:0:0:0:0:FF', 'FF' ),
+			array( '0:0:0:0:0:0:0:FFD0', 'FFD0' ),
+			array( '0:0:0:0:0:0:FA00:0', 'FA000000' ),
+			array( '0:0:0:0:0:0:FCCF:FAFF', 'FCCFFAFF' ),
+		);
 	}
 
 	/**
diff --git a/tests/phpunit/includes/utils/MWFunctionTest.php b/tests/phpunit/includes/utils/MWFunctionTest.php
deleted file mode 100644
index f4d17999..00000000
--- a/tests/phpunit/includes/utils/MWFunctionTest.php
+++ /dev/null
@@ -1,34 +0,0 @@
-<?php
-
-/**
- * @covers MWFunction
- */
-class MWFunctionTest extends MediaWikiTestCase {
-	public function testNewObjFunction() {
-		$arg1 = 'Foo';
-		$arg2 = 'Bar';
-		$arg3 = array( 'Baz' );
-		$arg4 = new ExampleObject;
-
-		$args = array( $arg1, $arg2, $arg3, $arg4 );
-
-		$newObject = new MWBlankClass( $arg1, $arg2, $arg3, $arg4 );
-		$this->hideDeprecated( 'MWFunction::newObj' );
-		$this->assertEquals(
-			MWFunction::newObj( 'MWBlankClass', $args )->args,
-			$newObject->args
-		);
-	}
-}
-
-class MWBlankClass {
-
-	public $args = array();
-
-	function __construct( $arg1, $arg2, $arg3, $arg4 ) {
-		$this->args = array( $arg1, $arg2, $arg3, $arg4 );
-	}
-}
-
-class ExampleObject {
-}
diff --git a/tests/phpunit/includes/utils/UIDGeneratorTest.php b/tests/phpunit/includes/utils/UIDGeneratorTest.php
index 0e11ccad..fedcc762 100644
--- a/tests/phpunit/includes/utils/UIDGeneratorTest.php
+++ b/tests/phpunit/includes/utils/UIDGeneratorTest.php
@@ -1,6 +1,6 @@
 <?php
 
-class UIDGeneratorTest extends MediaWikiTestCase {
+class UIDGeneratorTest extends PHPUnit_Framework_TestCase {
 
 	protected function tearDown() {
 		// Bug: 44850
@@ -28,7 +28,7 @@ class UIDGeneratorTest extends MediaWikiTestCase {
 
 		$lastId = array_shift( $ids );
 
-		$this->assertArrayEquals( array_unique( $ids ), $ids, "All generated IDs are unique." );
+		$this->assertSame( array_unique( $ids ), $ids, "All generated IDs are unique." );
 
 		foreach ( $ids as $id ) {
 			$id_bin = wfBaseConvert( $id, 10, 2 );
@@ -105,8 +105,8 @@ class UIDGeneratorTest extends MediaWikiTestCase {
 		$id1 = UIDGenerator::newSequentialPerNodeID( 'test', 32 );
 		$id2 = UIDGenerator::newSequentialPerNodeID( 'test', 32 );
 
-		$this->assertType( 'float', $id1, "ID returned as float" );
-		$this->assertType( 'float', $id2, "ID returned as float" );
+		$this->assertInternalType( 'float', $id1, "ID returned as float" );
+		$this->assertInternalType( 'float', $id2, "ID returned as float" );
 		$this->assertGreaterThan( 0, $id1, "ID greater than 1" );
 		$this->assertGreaterThan( $id1, $id2, "IDs increasing in value" );
 	}
@@ -118,7 +118,7 @@ class UIDGeneratorTest extends MediaWikiTestCase {
 		$ids = UIDGenerator::newSequentialPerNodeIDs( 'test', 32, 5 );
 		$lastId = null;
 		foreach ( $ids as $id ) {
-			$this->assertType( 'float', $id, "ID returned as float" );
+			$this->assertInternalType( 'float', $id, "ID returned as float" );
 			$this->assertGreaterThan( 0, $id, "ID greater than 1" );
 			if ( $lastId ) {
 				$this->assertGreaterThan( $lastId, $id, "IDs increasing in value" );
-- 
cgit v1.2.3-54-g00ecf