22bf0c0cd3384b84e335ee4900f801e227d74c0b
3 * Tests for IP validity functions.
5 * Ported from /t/inc/IP.t by avar.
8 * @todo Test methods in this call should be split into a method and a
12 class IPTest
extends MediaWikiTestCase
{
14 * not sure it should be tested with boolean false. hashar 20100924
15 * @covers IP::isIPAddress
17 public function testisIPAddress() {
18 $this->assertFalse( IP
::isIPAddress( false ), 'Boolean false is not an IP' );
19 $this->assertFalse( IP
::isIPAddress( true ), 'Boolean true is not an IP' );
20 $this->assertFalse( IP
::isIPAddress( "" ), 'Empty string is not an IP' );
21 $this->assertFalse( IP
::isIPAddress( 'abc' ), 'Garbage IP string' );
22 $this->assertFalse( IP
::isIPAddress( ':' ), 'Single ":" is not an IP' );
23 $this->assertFalse( IP
::isIPAddress( '2001:0DB8::A:1::1' ), 'IPv6 with a double :: occurrence' );
24 $this->assertFalse( IP
::isIPAddress( '2001:0DB8::A:1::' ), 'IPv6 with a double :: occurrence, last at end' );
25 $this->assertFalse( IP
::isIPAddress( '::2001:0DB8::5:1' ), 'IPv6 with a double :: occurrence, firt at beginning' );
26 $this->assertFalse( IP
::isIPAddress( '124.24.52' ), 'IPv4 not enough quads' );
27 $this->assertFalse( IP
::isIPAddress( '24.324.52.13' ), 'IPv4 out of range' );
28 $this->assertFalse( IP
::isIPAddress( '.24.52.13' ), 'IPv4 starts with period' );
29 $this->assertFalse( IP
::isIPAddress( 'fc:100:300' ), 'IPv6 with only 3 words' );
31 $this->assertTrue( IP
::isIPAddress( '::' ), 'RFC 4291 IPv6 Unspecified Address' );
32 $this->assertTrue( IP
::isIPAddress( '::1' ), 'RFC 4291 IPv6 Loopback Address' );
33 $this->assertTrue( IP
::isIPAddress( '74.24.52.13/20', 'IPv4 range' ) );
34 $this->assertTrue( IP
::isIPAddress( 'fc:100:a:d:1:e:ac:0/24' ), 'IPv6 range' );
35 $this->assertTrue( IP
::isIPAddress( 'fc::100:a:d:1:e:ac/96' ), 'IPv6 range with "::"' );
37 $validIPs = array( 'fc:100::', 'fc:100:a:d:1:e:ac::', 'fc::100', '::fc:100:a:d:1:e:ac',
38 '::fc', 'fc::100:a:d:1:e:ac', 'fc:100:a:d:1:e:ac:0', '124.24.52.13', '1.24.52.13' );
39 foreach ( $validIPs as $ip ) {
40 $this->assertTrue( IP
::isIPAddress( $ip ), "$ip is a valid IP address" );
47 public function testisIPv6() {
48 $this->assertFalse( IP
::isIPv6( ':fc:100::' ), 'IPv6 starting with lone ":"' );
49 $this->assertFalse( IP
::isIPv6( 'fc:100:::' ), 'IPv6 ending with a ":::"' );
50 $this->assertFalse( IP
::isIPv6( 'fc:300' ), 'IPv6 with only 2 words' );
51 $this->assertFalse( IP
::isIPv6( 'fc:100:300' ), 'IPv6 with only 3 words' );
53 $this->assertTrue( IP
::isIPv6( 'fc:100::' ) );
54 $this->assertTrue( IP
::isIPv6( 'fc:100:a::' ) );
55 $this->assertTrue( IP
::isIPv6( 'fc:100:a:d::' ) );
56 $this->assertTrue( IP
::isIPv6( 'fc:100:a:d:1::' ) );
57 $this->assertTrue( IP
::isIPv6( 'fc:100:a:d:1:e::' ) );
58 $this->assertTrue( IP
::isIPv6( 'fc:100:a:d:1:e:ac::' ) );
60 $this->assertFalse( IP
::isIPv6( 'fc:100:a:d:1:e:ac:0::' ), 'IPv6 with 8 words ending with "::"' );
61 $this->assertFalse( IP
::isIPv6( 'fc:100:a:d:1:e:ac:0:1::' ), 'IPv6 with 9 words ending with "::"' );
63 $this->assertFalse( IP
::isIPv6( ':::' ) );
64 $this->assertFalse( IP
::isIPv6( '::0:' ), 'IPv6 ending in a lone ":"' );
66 $this->assertTrue( IP
::isIPv6( '::' ), 'IPv6 zero address' );
67 $this->assertTrue( IP
::isIPv6( '::0' ) );
68 $this->assertTrue( IP
::isIPv6( '::fc' ) );
69 $this->assertTrue( IP
::isIPv6( '::fc:100' ) );
70 $this->assertTrue( IP
::isIPv6( '::fc:100:a' ) );
71 $this->assertTrue( IP
::isIPv6( '::fc:100:a:d' ) );
72 $this->assertTrue( IP
::isIPv6( '::fc:100:a:d:1' ) );
73 $this->assertTrue( IP
::isIPv6( '::fc:100:a:d:1:e' ) );
74 $this->assertTrue( IP
::isIPv6( '::fc:100:a:d:1:e:ac' ) );
76 $this->assertFalse( IP
::isIPv6( '::fc:100:a:d:1:e:ac:0' ), 'IPv6 with "::" and 8 words' );
77 $this->assertFalse( IP
::isIPv6( '::fc:100:a:d:1:e:ac:0:1' ), 'IPv6 with 9 words' );
79 $this->assertFalse( IP
::isIPv6( ':fc::100' ), 'IPv6 starting with lone ":"' );
80 $this->assertFalse( IP
::isIPv6( 'fc::100:' ), 'IPv6 ending with lone ":"' );
81 $this->assertFalse( IP
::isIPv6( 'fc:::100' ), 'IPv6 with ":::" in the middle' );
83 $this->assertTrue( IP
::isIPv6( 'fc::100' ), 'IPv6 with "::" and 2 words' );
84 $this->assertTrue( IP
::isIPv6( 'fc::100:a' ), 'IPv6 with "::" and 3 words' );
85 $this->assertTrue( IP
::isIPv6( 'fc::100:a:d', 'IPv6 with "::" and 4 words' ) );
86 $this->assertTrue( IP
::isIPv6( 'fc::100:a:d:1' ), 'IPv6 with "::" and 5 words' );
87 $this->assertTrue( IP
::isIPv6( 'fc::100:a:d:1:e' ), 'IPv6 with "::" and 6 words' );
88 $this->assertTrue( IP
::isIPv6( 'fc::100:a:d:1:e:ac' ), 'IPv6 with "::" and 7 words' );
89 $this->assertTrue( IP
::isIPv6( '2001::df' ), 'IPv6 with "::" and 2 words' );
90 $this->assertTrue( IP
::isIPv6( '2001:5c0:1400:a::df' ), 'IPv6 with "::" and 5 words' );
91 $this->assertTrue( IP
::isIPv6( '2001:5c0:1400:a::df:2' ), 'IPv6 with "::" and 6 words' );
93 $this->assertFalse( IP
::isIPv6( 'fc::100:a:d:1:e:ac:0' ), 'IPv6 with "::" and 8 words' );
94 $this->assertFalse( IP
::isIPv6( 'fc::100:a:d:1:e:ac:0:1' ), 'IPv6 with 9 words' );
96 $this->assertTrue( IP
::isIPv6( 'fc:100:a:d:1:e:ac:0' ) );
102 public function testisIPv4() {
103 $this->assertFalse( IP
::isIPv4( false ), 'Boolean false is not an IP' );
104 $this->assertFalse( IP
::isIPv4( true ), 'Boolean true is not an IP' );
105 $this->assertFalse( IP
::isIPv4( "" ), 'Empty string is not an IP' );
106 $this->assertFalse( IP
::isIPv4( 'abc' ) );
107 $this->assertFalse( IP
::isIPv4( ':' ) );
108 $this->assertFalse( IP
::isIPv4( '124.24.52' ), 'IPv4 not enough quads' );
109 $this->assertFalse( IP
::isIPv4( '24.324.52.13' ), 'IPv4 out of range' );
110 $this->assertFalse( IP
::isIPv4( '.24.52.13' ), 'IPv4 starts with period' );
112 $this->assertTrue( IP
::isIPv4( '124.24.52.13' ) );
113 $this->assertTrue( IP
::isIPv4( '1.24.52.13' ) );
114 $this->assertTrue( IP
::isIPv4( '74.24.52.13/20', 'IPv4 range' ) );
118 * @covers IP::isValid
120 public function testValidIPs() {
121 foreach ( range( 0, 255 ) as $i ) {
122 $a = sprintf( "%03d", $i );
123 $b = sprintf( "%02d", $i );
124 $c = sprintf( "%01d", $i );
125 foreach ( array_unique( array( $a, $b, $c ) ) as $f ) {
127 $this->assertTrue( IP
::isValid( $ip ), "$ip is a valid IPv4 address" );
130 foreach ( range( 0x0, 0xFFFF, 0xF ) as $i ) {
131 $a = sprintf( "%04x", $i );
132 $b = sprintf( "%03x", $i );
133 $c = sprintf( "%02x", $i );
134 foreach ( array_unique( array( $a, $b, $c ) ) as $f ) {
135 $ip = "$f:$f:$f:$f:$f:$f:$f:$f";
136 $this->assertTrue( IP
::isValid( $ip ), "$ip is a valid IPv6 address" );
139 // test with some abbreviations
140 $this->assertFalse( IP
::isValid( ':fc:100::' ), 'IPv6 starting with lone ":"' );
141 $this->assertFalse( IP
::isValid( 'fc:100:::' ), 'IPv6 ending with a ":::"' );
142 $this->assertFalse( IP
::isValid( 'fc:300' ), 'IPv6 with only 2 words' );
143 $this->assertFalse( IP
::isValid( 'fc:100:300' ), 'IPv6 with only 3 words' );
145 $this->assertTrue( IP
::isValid( 'fc:100::' ) );
146 $this->assertTrue( IP
::isValid( 'fc:100:a:d:1:e::' ) );
147 $this->assertTrue( IP
::isValid( 'fc:100:a:d:1:e:ac::' ) );
149 $this->assertTrue( IP
::isValid( 'fc::100' ), 'IPv6 with "::" and 2 words' );
150 $this->assertTrue( IP
::isValid( 'fc::100:a' ), 'IPv6 with "::" and 3 words' );
151 $this->assertTrue( IP
::isValid( '2001::df' ), 'IPv6 with "::" and 2 words' );
152 $this->assertTrue( IP
::isValid( '2001:5c0:1400:a::df' ), 'IPv6 with "::" and 5 words' );
153 $this->assertTrue( IP
::isValid( '2001:5c0:1400:a::df:2' ), 'IPv6 with "::" and 6 words' );
154 $this->assertTrue( IP
::isValid( 'fc::100:a:d:1' ), 'IPv6 with "::" and 5 words' );
155 $this->assertTrue( IP
::isValid( 'fc::100:a:d:1:e:ac' ), 'IPv6 with "::" and 7 words' );
157 $this->assertFalse( IP
::isValid( 'fc:100:a:d:1:e:ac:0::' ), 'IPv6 with 8 words ending with "::"' );
158 $this->assertFalse( IP
::isValid( 'fc:100:a:d:1:e:ac:0:1::' ), 'IPv6 with 9 words ending with "::"' );
162 * @covers IP::isValid
164 public function testInvalidIPs() {
166 foreach ( range( 256, 999 ) as $i ) {
167 $a = sprintf( "%03d", $i );
168 $b = sprintf( "%02d", $i );
169 $c = sprintf( "%01d", $i );
170 foreach ( array_unique( array( $a, $b, $c ) ) as $f ) {
172 $this->assertFalse( IP
::isValid( $ip ), "$ip is not a valid IPv4 address" );
175 foreach ( range( 'g', 'z' ) as $i ) {
176 $a = sprintf( "%04s", $i );
177 $b = sprintf( "%03s", $i );
178 $c = sprintf( "%02s", $i );
179 foreach ( array_unique( array( $a, $b, $c ) ) as $f ) {
180 $ip = "$f:$f:$f:$f:$f:$f:$f:$f";
181 $this->assertFalse( IP
::isValid( $ip ), "$ip is not a valid IPv6 address" );
191 'c:ff:12:1:ea:d:321:5/120',
193 foreach ( $ipCIDRs as $i ) {
194 $this->assertFalse( IP
::isValid( $i ),
195 "$i is an invalid IP address because it is a block" );
197 // Incomplete/garbage
199 'www.xn--var-xla.net',
206 foreach ( $invalid as $i ) {
207 $this->assertFalse( IP
::isValid( $i ), "$i is an invalid IP address" );
212 * @covers IP::isValidBlock
214 public function testValidBlocks() {
229 foreach ( $valid as $i ) {
230 $this->assertTrue( IP
::isValidBlock( $i ), "$i is a valid IP block" );
235 * @covers IP::isValidBlock
237 public function testInvalidBlocks() {
252 foreach ( $invalid as $i ) {
253 $this->assertFalse( IP
::isValidBlock( $i ), "$i is not a valid IP block" );
258 * Improve IP::sanitizeIP() code coverage
259 * @todo Most probably incomplete
261 public function testSanitizeIP() {
262 $this->assertNull( IP
::sanitizeIP( '' ) );
263 $this->assertNull( IP
::sanitizeIP( ' ' ) );
267 * @covers IP::toUnsigned
268 * @dataProvider provideToUnsigned
270 public function testToUnsigned( $expected, $input ) {
271 $result = IP
::toUnsigned( $input );
272 $this->assertTrue( $result === false ||
is_string( $result ) ||
is_int( $result ) );
273 $this->assertEquals( $expected, $result );
277 * Provider for IP::testToUnsigned()
279 public static function provideToUnsigned() {
281 array( 1, '0.0.0.1' ),
282 array( 16909060, '1.2.3.4' ),
283 array( 2130706433, '127.0.0.1' ),
284 array( '2147483648', '128.0.0.0' ),
285 array( '3735931646', '222.173.202.254' ),
286 array( pow( 2, 32 ) - 1, '255.255.255.255' ),
287 array( false, 'IN.VA.LI.D' ),
289 array( '42540766452641154071740215577757643572', '2001:0db8:85a3:0000:0000:8a2e:0370:7334' ),
290 array( '42540766452641154071740215577757643572', '2001:db8:85a3::8a2e:0370:7334' ),
291 array( false, 'IN:VA::LI:D' ),
292 array( false, ':::1' )
298 * @dataProvider provideToHex
300 public function testToHex( $expected, $input ) {
301 $result = IP
::toHex( $input );
302 $this->assertTrue( $result === false ||
is_string( $result ) );
303 $this->assertEquals( $expected, $result );
307 * Provider for IP::testToHex()
309 public static function provideToHex() {
311 array( '00000001', '0.0.0.1' ),
312 array( '01020304', '1.2.3.4' ),
313 array( '7F000001', '127.0.0.1' ),
314 array( '80000000', '128.0.0.0' ),
315 array( 'DEADCAFE', '222.173.202.254' ),
316 array( 'FFFFFFFF', '255.255.255.255' ),
317 array( false, 'IN.VA.LI.D' ),
318 array( 'v6-00000000000000000000000000000001', '::1' ),
319 array( 'v6-20010DB885A3000000008A2E03707334', '2001:0db8:85a3:0000:0000:8a2e:0370:7334' ),
320 array( 'v6-20010DB885A3000000008A2E03707334', '2001:db8:85a3::8a2e:0370:7334' ),
321 array( false, 'IN:VA::LI:D' ),
322 array( false, ':::1' )
327 * @covers IP::isPublic
329 public function testPrivateIPs() {
330 $private = array( 'fc00::3', 'fc00::ff', '::1', '10.0.0.1', '172.16.0.1', '192.168.0.1' );
331 foreach ( $private as $p ) {
332 $this->assertFalse( IP
::isPublic( $p ), "$p is not a public IP address" );
334 $public = array( '2001:5c0:1000:a::133', 'fc::3', '00FC::' );
335 foreach ( $public as $p ) {
336 $this->assertTrue( IP
::isPublic( $p ), "$p is a public IP address" );
340 // Private wrapper used to test CIDR Parsing.
341 private function assertFalseCIDR( $CIDR, $msg = '' ) {
342 $ff = array( false, false );
343 $this->assertEquals( $ff, IP
::parseCIDR( $CIDR ), $msg );
346 // Private wrapper to test network shifting using only dot notation
347 private function assertNet( $expected, $CIDR ) {
348 $parse = IP
::parseCIDR( $CIDR );
349 $this->assertEquals( $expected, long2ip( $parse[0] ), "network shifting $CIDR" );
353 * @covers IP::hexToQuad
355 public function testHexToQuad() {
356 $this->assertEquals( '0.0.0.1', IP
::hexToQuad( '00000001' ) );
357 $this->assertEquals( '255.0.0.0', IP
::hexToQuad( 'FF000000' ) );
358 $this->assertEquals( '255.255.255.255', IP
::hexToQuad( 'FFFFFFFF' ) );
359 $this->assertEquals( '10.188.222.255', IP
::hexToQuad( '0ABCDEFF' ) );
360 // hex not left-padded...
361 $this->assertEquals( '0.0.0.0', IP
::hexToQuad( '0' ) );
362 $this->assertEquals( '0.0.0.1', IP
::hexToQuad( '1' ) );
363 $this->assertEquals( '0.0.0.255', IP
::hexToQuad( 'FF' ) );
364 $this->assertEquals( '0.0.255.0', IP
::hexToQuad( 'FF00' ) );
368 * @covers IP::hexToOctet
370 public function testHexToOctet() {
371 $this->assertEquals( '0:0:0:0:0:0:0:1',
372 IP
::hexToOctet( '00000000000000000000000000000001' ) );
373 $this->assertEquals( '0:0:0:0:0:0:FF:3',
374 IP
::hexToOctet( '00000000000000000000000000FF0003' ) );
375 $this->assertEquals( '0:0:0:0:0:0:FF00:6',
376 IP
::hexToOctet( '000000000000000000000000FF000006' ) );
377 $this->assertEquals( '0:0:0:0:0:0:FCCF:FAFF',
378 IP
::hexToOctet( '000000000000000000000000FCCFFAFF' ) );
379 $this->assertEquals( 'FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF',
380 IP
::hexToOctet( 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' ) );
381 // hex not left-padded...
382 $this->assertEquals( '0:0:0:0:0:0:0:0', IP
::hexToOctet( '0' ) );
383 $this->assertEquals( '0:0:0:0:0:0:0:1', IP
::hexToOctet( '1' ) );
384 $this->assertEquals( '0:0:0:0:0:0:0:FF', IP
::hexToOctet( 'FF' ) );
385 $this->assertEquals( '0:0:0:0:0:0:0:FFD0', IP
::hexToOctet( 'FFD0' ) );
386 $this->assertEquals( '0:0:0:0:0:0:FA00:0', IP
::hexToOctet( 'FA000000' ) );
387 $this->assertEquals( '0:0:0:0:0:0:FCCF:FAFF', IP
::hexToOctet( 'FCCFFAFF' ) );
391 * IP::parseCIDR() returns an array containing a signed IP address
392 * representing the network mask and the bit mask.
393 * @covers IP::parseCIDR
395 function testCIDRParsing() {
396 $this->assertFalseCIDR( '192.0.2.0', "missing mask" );
397 $this->assertFalseCIDR( '192.0.2.0/', "missing bitmask" );
399 // Verify if statement
400 $this->assertFalseCIDR( '256.0.0.0/32', "invalid net" );
401 $this->assertFalseCIDR( '192.0.2.0/AA', "mask not numeric" );
402 $this->assertFalseCIDR( '192.0.2.0/-1', "mask < 0" );
403 $this->assertFalseCIDR( '192.0.2.0/33', "mask > 32" );
405 // Check internal logic
406 # 0 mask always result in array(0,0)
407 $this->assertEquals( array( 0, 0 ), IP
::parseCIDR( '192.0.0.2/0' ) );
408 $this->assertEquals( array( 0, 0 ), IP
::parseCIDR( '0.0.0.0/0' ) );
409 $this->assertEquals( array( 0, 0 ), IP
::parseCIDR( '255.255.255.255/0' ) );
411 // @todo FIXME: Add more tests.
413 # This part test network shifting
414 $this->assertNet( '192.0.0.0', '192.0.0.2/24' );
415 $this->assertNet( '192.168.5.0', '192.168.5.13/24' );
416 $this->assertNet( '10.0.0.160', '10.0.0.161/28' );
417 $this->assertNet( '10.0.0.0', '10.0.0.3/28' );
418 $this->assertNet( '10.0.0.0', '10.0.0.3/30' );
419 $this->assertNet( '10.0.0.4', '10.0.0.4/30' );
420 $this->assertNet( '172.17.32.0', '172.17.35.48/21' );
421 $this->assertNet( '10.128.0.0', '10.135.0.0/9' );
422 $this->assertNet( '134.0.0.0', '134.0.5.1/8' );
426 * @covers IP::canonicalize
428 public function testIPCanonicalizeOnValidIp() {
429 $this->assertEquals( '192.0.2.152', IP
::canonicalize( '192.0.2.152' ),
430 'Canonicalization of a valid IP returns it unchanged' );
434 * @covers IP::canonicalize
436 public function testIPCanonicalizeMappedAddress() {
439 IP
::canonicalize( '::ffff:192.0.2.152' )
443 IP
::canonicalize( '::192.0.2.152' )
448 * Issues there are most probably from IP::toHex() or IP::parseRange()
449 * @covers IP::isInRange
450 * @dataProvider provideIPsAndRanges
452 public function testIPIsInRange( $expected, $addr, $range, $message = '' ) {
455 IP
::isInRange( $addr, $range ),
460 /** Provider for testIPIsInRange() */
461 public static function provideIPsAndRanges() {
462 # Format: (expected boolean, address, range, optional message)
465 array( true, '192.0.2.0', '192.0.2.0/24', 'Network address' ),
466 array( true, '192.0.2.77', '192.0.2.0/24', 'Simple address' ),
467 array( true, '192.0.2.255', '192.0.2.0/24', 'Broadcast address' ),
469 array( false, '0.0.0.0', '192.0.2.0/24' ),
470 array( false, '255.255.255', '192.0.2.0/24' ),
473 array( false, '::1', '2001:DB8::/32' ),
474 array( false, '::', '2001:DB8::/32' ),
475 array( false, 'FE80::1', '2001:DB8::/32' ),
477 array( true, '2001:DB8::', '2001:DB8::/32' ),
478 array( true, '2001:0DB8::', '2001:DB8::/32' ),
479 array( true, '2001:DB8::1', '2001:DB8::/32' ),
480 array( true, '2001:0DB8::1', '2001:DB8::/32' ),
481 array( true, '2001:0DB8:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF',
484 array( false, '2001:0DB8:F::', '2001:DB8::/96' ),
489 * Test for IP::splitHostAndPort().
490 * @dataProvider provideSplitHostAndPort
492 function testSplitHostAndPort( $expected, $input, $description ) {
493 $this->assertEquals( $expected, IP
::splitHostAndPort( $input ), $description );
497 * Provider for IP::splitHostAndPort()
499 public static function provideSplitHostAndPort() {
501 array( false, '[', 'Unclosed square bracket' ),
502 array( false, '[::', 'Unclosed square bracket 2' ),
503 array( array( '::', false ), '::', 'Bare IPv6 0' ),
504 array( array( '::1', false ), '::1', 'Bare IPv6 1' ),
505 array( array( '::', false ), '[::]', 'Bracketed IPv6 0' ),
506 array( array( '::1', false ), '[::1]', 'Bracketed IPv6 1' ),
507 array( array( '::1', 80 ), '[::1]:80', 'Bracketed IPv6 with port' ),
508 array( false, '::x', 'Double colon but no IPv6' ),
509 array( array( 'x', 80 ), 'x:80', 'Hostname and port' ),
510 array( false, 'x:x', 'Hostname and invalid port' ),
511 array( array( 'x', false ), 'x', 'Plain hostname' )
516 * Test for IP::combineHostAndPort()
517 * @dataProvider provideCombineHostAndPort
519 function testCombineHostAndPort( $expected, $input, $description ) {
520 list( $host, $port, $defaultPort ) = $input;
523 IP
::combineHostAndPort( $host, $port, $defaultPort ),
528 * Provider for IP::combineHostAndPort()
530 public static function provideCombineHostAndPort() {
532 array( '[::1]', array( '::1', 2, 2 ), 'IPv6 default port' ),
533 array( '[::1]:2', array( '::1', 2, 3 ), 'IPv6 non-default port' ),
534 array( 'x', array( 'x', 2, 2 ), 'Normal default port' ),
535 array( 'x:2', array( 'x', 2, 3 ), 'Normal non-default port' ),
540 * Test for IP::sanitizeRange()
541 * @dataProvider provideIPCIDRs
543 function testSanitizeRange( $input, $expected, $description ) {
544 $this->assertEquals( $expected, IP
::sanitizeRange( $input ), $description );
548 * Provider for IP::testSanitizeRange()
550 public static function provideIPCIDRs() {
552 array( '35.56.31.252/16', '35.56.0.0/16', 'IPv4 range' ),
553 array( '135.16.21.252/24', '135.16.21.0/24', 'IPv4 range' ),
554 array( '5.36.71.252/32', '5.36.71.252/32', 'IPv4 silly range' ),
555 array( '5.36.71.252', '5.36.71.252', 'IPv4 non-range' ),
556 array( '0:1:2:3:4:c5:f6:7/96', '0:1:2:3:4:C5:0:0/96', 'IPv6 range' ),
557 array( '0:1:2:3:4:5:6:7/120', '0:1:2:3:4:5:6:0/120', 'IPv6 range' ),
558 array( '0:e1:2:3:4:5:e6:7/128', '0:E1:2:3:4:5:E6:7/128', 'IPv6 silly range' ),
559 array( '0:c1:A2:3:4:5:c6:7', '0:C1:A2:3:4:5:C6:7', 'IPv6 non range' ),
564 * Test for IP::prettifyIP()
565 * @dataProvider provideIPsToPrettify
567 function testPrettifyIP( $ip, $prettified ) {
568 $this->assertEquals( $prettified, IP
::prettifyIP( $ip ), "Prettify of $ip" );
572 * Provider for IP::testPrettifyIP()
574 public static function provideIPsToPrettify() {
576 array( '0:0:0:0:0:0:0:0', '::' ),
577 array( '0:0:0::0:0:0', '::' ),
578 array( '0:0:0:1:0:0:0:0', '0:0:0:1::' ),
579 array( '0:0::f', '::f' ),
580 array( '0::0:0:0:33:fef:b', '::33:fef:b' ),
581 array( '3f:535:0:0:0:0:e:fbb', '3f:535::e:fbb' ),
582 array( '0:0:fef:0:0:0:e:fbb', '0:0:fef::e:fbb' ),
583 array( 'abbc:2004::0:0:0:0', 'abbc:2004::' ),
584 array( 'cebc:2004:f:0:0:0:0:0', 'cebc:2004:f::' ),
585 array( '0:0:0:0:0:0:0:0/16', '::/16' ),
586 array( '0:0:0::0:0:0/64', '::/64' ),
587 array( '0:0::f/52', '::f/52' ),
588 array( '::0:0:33:fef:b/52', '::33:fef:b/52' ),
589 array( '3f:535:0:0:0:0:e:fbb/48', '3f:535::e:fbb/48' ),
590 array( '0:0:fef:0:0:0:e:fbb/96', '0:0:fef::e:fbb/96' ),
591 array( 'abbc:2004:0:0::0:0/40', 'abbc:2004::/40' ),
592 array( 'aebc:2004:f:0:0:0:0:0/80', 'aebc:2004:f::/80' ),