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' );
25 IP
::isIPAddress( '2001:0DB8::A:1::' ),
26 'IPv6 with a double :: occurrence, last at end'
29 IP
::isIPAddress( '::2001:0DB8::5:1' ),
30 'IPv6 with a double :: occurrence, firt at beginning'
32 $this->assertFalse( IP
::isIPAddress( '124.24.52' ), 'IPv4 not enough quads' );
33 $this->assertFalse( IP
::isIPAddress( '24.324.52.13' ), 'IPv4 out of range' );
34 $this->assertFalse( IP
::isIPAddress( '.24.52.13' ), 'IPv4 starts with period' );
35 $this->assertFalse( IP
::isIPAddress( 'fc:100:300' ), 'IPv6 with only 3 words' );
37 $this->assertTrue( IP
::isIPAddress( '::' ), 'RFC 4291 IPv6 Unspecified Address' );
38 $this->assertTrue( IP
::isIPAddress( '::1' ), 'RFC 4291 IPv6 Loopback Address' );
39 $this->assertTrue( IP
::isIPAddress( '74.24.52.13/20', 'IPv4 range' ) );
40 $this->assertTrue( IP
::isIPAddress( 'fc:100:a:d:1:e:ac:0/24' ), 'IPv6 range' );
41 $this->assertTrue( IP
::isIPAddress( 'fc::100:a:d:1:e:ac/96' ), 'IPv6 range with "::"' );
43 $validIPs = array( 'fc:100::', 'fc:100:a:d:1:e:ac::', 'fc::100', '::fc:100:a:d:1:e:ac',
44 '::fc', 'fc::100:a:d:1:e:ac', 'fc:100:a:d:1:e:ac:0', '124.24.52.13', '1.24.52.13' );
45 foreach ( $validIPs as $ip ) {
46 $this->assertTrue( IP
::isIPAddress( $ip ), "$ip is a valid IP address" );
53 public function testisIPv6() {
54 $this->assertFalse( IP
::isIPv6( ':fc:100::' ), 'IPv6 starting with lone ":"' );
55 $this->assertFalse( IP
::isIPv6( 'fc:100:::' ), 'IPv6 ending with a ":::"' );
56 $this->assertFalse( IP
::isIPv6( 'fc:300' ), 'IPv6 with only 2 words' );
57 $this->assertFalse( IP
::isIPv6( 'fc:100:300' ), 'IPv6 with only 3 words' );
59 $this->assertTrue( IP
::isIPv6( 'fc:100::' ) );
60 $this->assertTrue( IP
::isIPv6( 'fc:100:a::' ) );
61 $this->assertTrue( IP
::isIPv6( 'fc:100:a:d::' ) );
62 $this->assertTrue( IP
::isIPv6( 'fc:100:a:d:1::' ) );
63 $this->assertTrue( IP
::isIPv6( 'fc:100:a:d:1:e::' ) );
64 $this->assertTrue( IP
::isIPv6( 'fc:100:a:d:1:e:ac::' ) );
66 $this->assertFalse( IP
::isIPv6( 'fc:100:a:d:1:e:ac:0::' ), 'IPv6 with 8 words ending with "::"' );
68 IP
::isIPv6( 'fc:100:a:d:1:e:ac:0:1::' ),
69 'IPv6 with 9 words ending with "::"'
72 $this->assertFalse( IP
::isIPv6( ':::' ) );
73 $this->assertFalse( IP
::isIPv6( '::0:' ), 'IPv6 ending in a lone ":"' );
75 $this->assertTrue( IP
::isIPv6( '::' ), 'IPv6 zero address' );
76 $this->assertTrue( IP
::isIPv6( '::0' ) );
77 $this->assertTrue( IP
::isIPv6( '::fc' ) );
78 $this->assertTrue( IP
::isIPv6( '::fc:100' ) );
79 $this->assertTrue( IP
::isIPv6( '::fc:100:a' ) );
80 $this->assertTrue( IP
::isIPv6( '::fc:100:a:d' ) );
81 $this->assertTrue( IP
::isIPv6( '::fc:100:a:d:1' ) );
82 $this->assertTrue( IP
::isIPv6( '::fc:100:a:d:1:e' ) );
83 $this->assertTrue( IP
::isIPv6( '::fc:100:a:d:1:e:ac' ) );
85 $this->assertFalse( IP
::isIPv6( '::fc:100:a:d:1:e:ac:0' ), 'IPv6 with "::" and 8 words' );
86 $this->assertFalse( IP
::isIPv6( '::fc:100:a:d:1:e:ac:0:1' ), 'IPv6 with 9 words' );
88 $this->assertFalse( IP
::isIPv6( ':fc::100' ), 'IPv6 starting with lone ":"' );
89 $this->assertFalse( IP
::isIPv6( 'fc::100:' ), 'IPv6 ending with lone ":"' );
90 $this->assertFalse( IP
::isIPv6( 'fc:::100' ), 'IPv6 with ":::" in the middle' );
92 $this->assertTrue( IP
::isIPv6( 'fc::100' ), 'IPv6 with "::" and 2 words' );
93 $this->assertTrue( IP
::isIPv6( 'fc::100:a' ), 'IPv6 with "::" and 3 words' );
94 $this->assertTrue( IP
::isIPv6( 'fc::100:a:d', 'IPv6 with "::" and 4 words' ) );
95 $this->assertTrue( IP
::isIPv6( 'fc::100:a:d:1' ), 'IPv6 with "::" and 5 words' );
96 $this->assertTrue( IP
::isIPv6( 'fc::100:a:d:1:e' ), 'IPv6 with "::" and 6 words' );
97 $this->assertTrue( IP
::isIPv6( 'fc::100:a:d:1:e:ac' ), 'IPv6 with "::" and 7 words' );
98 $this->assertTrue( IP
::isIPv6( '2001::df' ), 'IPv6 with "::" and 2 words' );
99 $this->assertTrue( IP
::isIPv6( '2001:5c0:1400:a::df' ), 'IPv6 with "::" and 5 words' );
100 $this->assertTrue( IP
::isIPv6( '2001:5c0:1400:a::df:2' ), 'IPv6 with "::" and 6 words' );
102 $this->assertFalse( IP
::isIPv6( 'fc::100:a:d:1:e:ac:0' ), 'IPv6 with "::" and 8 words' );
103 $this->assertFalse( IP
::isIPv6( 'fc::100:a:d:1:e:ac:0:1' ), 'IPv6 with 9 words' );
105 $this->assertTrue( IP
::isIPv6( 'fc:100:a:d:1:e:ac:0' ) );
111 public function testisIPv4() {
112 $this->assertFalse( IP
::isIPv4( false ), 'Boolean false is not an IP' );
113 $this->assertFalse( IP
::isIPv4( true ), 'Boolean true is not an IP' );
114 $this->assertFalse( IP
::isIPv4( "" ), 'Empty string is not an IP' );
115 $this->assertFalse( IP
::isIPv4( 'abc' ) );
116 $this->assertFalse( IP
::isIPv4( ':' ) );
117 $this->assertFalse( IP
::isIPv4( '124.24.52' ), 'IPv4 not enough quads' );
118 $this->assertFalse( IP
::isIPv4( '24.324.52.13' ), 'IPv4 out of range' );
119 $this->assertFalse( IP
::isIPv4( '.24.52.13' ), 'IPv4 starts with period' );
121 $this->assertTrue( IP
::isIPv4( '124.24.52.13' ) );
122 $this->assertTrue( IP
::isIPv4( '1.24.52.13' ) );
123 $this->assertTrue( IP
::isIPv4( '74.24.52.13/20', 'IPv4 range' ) );
127 * @covers IP::isValid
129 public function testValidIPs() {
130 foreach ( range( 0, 255 ) as $i ) {
131 $a = sprintf( "%03d", $i );
132 $b = sprintf( "%02d", $i );
133 $c = sprintf( "%01d", $i );
134 foreach ( array_unique( array( $a, $b, $c ) ) as $f ) {
136 $this->assertTrue( IP
::isValid( $ip ), "$ip is a valid IPv4 address" );
139 foreach ( range( 0x0, 0xFFFF, 0xF ) as $i ) {
140 $a = sprintf( "%04x", $i );
141 $b = sprintf( "%03x", $i );
142 $c = sprintf( "%02x", $i );
143 foreach ( array_unique( array( $a, $b, $c ) ) as $f ) {
144 $ip = "$f:$f:$f:$f:$f:$f:$f:$f";
145 $this->assertTrue( IP
::isValid( $ip ), "$ip is a valid IPv6 address" );
148 // test with some abbreviations
149 $this->assertFalse( IP
::isValid( ':fc:100::' ), 'IPv6 starting with lone ":"' );
150 $this->assertFalse( IP
::isValid( 'fc:100:::' ), 'IPv6 ending with a ":::"' );
151 $this->assertFalse( IP
::isValid( 'fc:300' ), 'IPv6 with only 2 words' );
152 $this->assertFalse( IP
::isValid( 'fc:100:300' ), 'IPv6 with only 3 words' );
154 $this->assertTrue( IP
::isValid( 'fc:100::' ) );
155 $this->assertTrue( IP
::isValid( 'fc:100:a:d:1:e::' ) );
156 $this->assertTrue( IP
::isValid( 'fc:100:a:d:1:e:ac::' ) );
158 $this->assertTrue( IP
::isValid( 'fc::100' ), 'IPv6 with "::" and 2 words' );
159 $this->assertTrue( IP
::isValid( 'fc::100:a' ), 'IPv6 with "::" and 3 words' );
160 $this->assertTrue( IP
::isValid( '2001::df' ), 'IPv6 with "::" and 2 words' );
161 $this->assertTrue( IP
::isValid( '2001:5c0:1400:a::df' ), 'IPv6 with "::" and 5 words' );
162 $this->assertTrue( IP
::isValid( '2001:5c0:1400:a::df:2' ), 'IPv6 with "::" and 6 words' );
163 $this->assertTrue( IP
::isValid( 'fc::100:a:d:1' ), 'IPv6 with "::" and 5 words' );
164 $this->assertTrue( IP
::isValid( 'fc::100:a:d:1:e:ac' ), 'IPv6 with "::" and 7 words' );
167 IP
::isValid( 'fc:100:a:d:1:e:ac:0::' ),
168 'IPv6 with 8 words ending with "::"'
171 IP
::isValid( 'fc:100:a:d:1:e:ac:0:1::' ),
172 'IPv6 with 9 words ending with "::"'
177 * @covers IP::isValid
179 public function testInvalidIPs() {
181 foreach ( range( 256, 999 ) as $i ) {
182 $a = sprintf( "%03d", $i );
183 $b = sprintf( "%02d", $i );
184 $c = sprintf( "%01d", $i );
185 foreach ( array_unique( array( $a, $b, $c ) ) as $f ) {
187 $this->assertFalse( IP
::isValid( $ip ), "$ip is not a valid IPv4 address" );
190 foreach ( range( 'g', 'z' ) as $i ) {
191 $a = sprintf( "%04s", $i );
192 $b = sprintf( "%03s", $i );
193 $c = sprintf( "%02s", $i );
194 foreach ( array_unique( array( $a, $b, $c ) ) as $f ) {
195 $ip = "$f:$f:$f:$f:$f:$f:$f:$f";
196 $this->assertFalse( IP
::isValid( $ip ), "$ip is not a valid IPv6 address" );
206 'c:ff:12:1:ea:d:321:5/120',
208 foreach ( $ipCIDRs as $i ) {
209 $this->assertFalse( IP
::isValid( $i ),
210 "$i is an invalid IP address because it is a block" );
212 // Incomplete/garbage
214 'www.xn--var-xla.net',
221 foreach ( $invalid as $i ) {
222 $this->assertFalse( IP
::isValid( $i ), "$i is an invalid IP address" );
227 * @covers IP::isValidBlock
229 public function testValidBlocks() {
244 foreach ( $valid as $i ) {
245 $this->assertTrue( IP
::isValidBlock( $i ), "$i is a valid IP block" );
250 * @covers IP::isValidBlock
252 public function testInvalidBlocks() {
267 foreach ( $invalid as $i ) {
268 $this->assertFalse( IP
::isValidBlock( $i ), "$i is not a valid IP block" );
273 * Improve IP::sanitizeIP() code coverage
274 * @todo Most probably incomplete
276 public function testSanitizeIP() {
277 $this->assertNull( IP
::sanitizeIP( '' ) );
278 $this->assertNull( IP
::sanitizeIP( ' ' ) );
282 * @covers IP::toUnsigned
283 * @dataProvider provideToUnsigned
285 public function testToUnsigned( $expected, $input ) {
286 $result = IP
::toUnsigned( $input );
287 $this->assertTrue( $result === false ||
is_string( $result ) ||
is_int( $result ) );
288 $this->assertEquals( $expected, $result );
292 * Provider for IP::testToUnsigned()
294 public static function provideToUnsigned() {
296 array( 1, '0.0.0.1' ),
297 array( 16909060, '1.2.3.4' ),
298 array( 2130706433, '127.0.0.1' ),
299 array( '2147483648', '128.0.0.0' ),
300 array( '3735931646', '222.173.202.254' ),
301 array( pow( 2, 32 ) - 1, '255.255.255.255' ),
302 array( false, 'IN.VA.LI.D' ),
304 array( '42540766452641154071740215577757643572', '2001:0db8:85a3:0000:0000:8a2e:0370:7334' ),
305 array( '42540766452641154071740215577757643572', '2001:db8:85a3::8a2e:0370:7334' ),
306 array( false, 'IN:VA::LI:D' ),
307 array( false, ':::1' )
313 * @dataProvider provideToHex
315 public function testToHex( $expected, $input ) {
316 $result = IP
::toHex( $input );
317 $this->assertTrue( $result === false ||
is_string( $result ) );
318 $this->assertEquals( $expected, $result );
322 * Provider for IP::testToHex()
324 public static function provideToHex() {
326 array( '00000001', '0.0.0.1' ),
327 array( '01020304', '1.2.3.4' ),
328 array( '7F000001', '127.0.0.1' ),
329 array( '80000000', '128.0.0.0' ),
330 array( 'DEADCAFE', '222.173.202.254' ),
331 array( 'FFFFFFFF', '255.255.255.255' ),
332 array( false, 'IN.VA.LI.D' ),
333 array( 'v6-00000000000000000000000000000001', '::1' ),
334 array( 'v6-20010DB885A3000000008A2E03707334', '2001:0db8:85a3:0000:0000:8a2e:0370:7334' ),
335 array( 'v6-20010DB885A3000000008A2E03707334', '2001:db8:85a3::8a2e:0370:7334' ),
336 array( false, 'IN:VA::LI:D' ),
337 array( false, ':::1' )
342 * @covers IP::isPublic
344 public function testPrivateIPs() {
345 $private = array( 'fc00::3', 'fc00::ff', '::1', '10.0.0.1', '172.16.0.1', '192.168.0.1' );
346 foreach ( $private as $p ) {
347 $this->assertFalse( IP
::isPublic( $p ), "$p is not a public IP address" );
349 $public = array( '2001:5c0:1000:a::133', 'fc::3', '00FC::' );
350 foreach ( $public as $p ) {
351 $this->assertTrue( IP
::isPublic( $p ), "$p is a public IP address" );
355 // Private wrapper used to test CIDR Parsing.
356 private function assertFalseCIDR( $CIDR, $msg = '' ) {
357 $ff = array( false, false );
358 $this->assertEquals( $ff, IP
::parseCIDR( $CIDR ), $msg );
361 // Private wrapper to test network shifting using only dot notation
362 private function assertNet( $expected, $CIDR ) {
363 $parse = IP
::parseCIDR( $CIDR );
364 $this->assertEquals( $expected, long2ip( $parse[0] ), "network shifting $CIDR" );
368 * @covers IP::hexToQuad
370 public function testHexToQuad() {
371 $this->assertEquals( '0.0.0.1', IP
::hexToQuad( '00000001' ) );
372 $this->assertEquals( '255.0.0.0', IP
::hexToQuad( 'FF000000' ) );
373 $this->assertEquals( '255.255.255.255', IP
::hexToQuad( 'FFFFFFFF' ) );
374 $this->assertEquals( '10.188.222.255', IP
::hexToQuad( '0ABCDEFF' ) );
375 // hex not left-padded...
376 $this->assertEquals( '0.0.0.0', IP
::hexToQuad( '0' ) );
377 $this->assertEquals( '0.0.0.1', IP
::hexToQuad( '1' ) );
378 $this->assertEquals( '0.0.0.255', IP
::hexToQuad( 'FF' ) );
379 $this->assertEquals( '0.0.255.0', IP
::hexToQuad( 'FF00' ) );
383 * @covers IP::hexToOctet
385 public function testHexToOctet() {
386 $this->assertEquals( '0:0:0:0:0:0:0:1',
387 IP
::hexToOctet( '00000000000000000000000000000001' ) );
388 $this->assertEquals( '0:0:0:0:0:0:FF:3',
389 IP
::hexToOctet( '00000000000000000000000000FF0003' ) );
390 $this->assertEquals( '0:0:0:0:0:0:FF00:6',
391 IP
::hexToOctet( '000000000000000000000000FF000006' ) );
392 $this->assertEquals( '0:0:0:0:0:0:FCCF:FAFF',
393 IP
::hexToOctet( '000000000000000000000000FCCFFAFF' ) );
394 $this->assertEquals( 'FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF',
395 IP
::hexToOctet( 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' ) );
396 // hex not left-padded...
397 $this->assertEquals( '0:0:0:0:0:0:0:0', IP
::hexToOctet( '0' ) );
398 $this->assertEquals( '0:0:0:0:0:0:0:1', IP
::hexToOctet( '1' ) );
399 $this->assertEquals( '0:0:0:0:0:0:0:FF', IP
::hexToOctet( 'FF' ) );
400 $this->assertEquals( '0:0:0:0:0:0:0:FFD0', IP
::hexToOctet( 'FFD0' ) );
401 $this->assertEquals( '0:0:0:0:0:0:FA00:0', IP
::hexToOctet( 'FA000000' ) );
402 $this->assertEquals( '0:0:0:0:0:0:FCCF:FAFF', IP
::hexToOctet( 'FCCFFAFF' ) );
406 * IP::parseCIDR() returns an array containing a signed IP address
407 * representing the network mask and the bit mask.
408 * @covers IP::parseCIDR
410 public function testCIDRParsing() {
411 $this->assertFalseCIDR( '192.0.2.0', "missing mask" );
412 $this->assertFalseCIDR( '192.0.2.0/', "missing bitmask" );
414 // Verify if statement
415 $this->assertFalseCIDR( '256.0.0.0/32', "invalid net" );
416 $this->assertFalseCIDR( '192.0.2.0/AA', "mask not numeric" );
417 $this->assertFalseCIDR( '192.0.2.0/-1', "mask < 0" );
418 $this->assertFalseCIDR( '192.0.2.0/33', "mask > 32" );
420 // Check internal logic
421 # 0 mask always result in array(0,0)
422 $this->assertEquals( array( 0, 0 ), IP
::parseCIDR( '192.0.0.2/0' ) );
423 $this->assertEquals( array( 0, 0 ), IP
::parseCIDR( '0.0.0.0/0' ) );
424 $this->assertEquals( array( 0, 0 ), IP
::parseCIDR( '255.255.255.255/0' ) );
426 // @todo FIXME: Add more tests.
428 # This part test network shifting
429 $this->assertNet( '192.0.0.0', '192.0.0.2/24' );
430 $this->assertNet( '192.168.5.0', '192.168.5.13/24' );
431 $this->assertNet( '10.0.0.160', '10.0.0.161/28' );
432 $this->assertNet( '10.0.0.0', '10.0.0.3/28' );
433 $this->assertNet( '10.0.0.0', '10.0.0.3/30' );
434 $this->assertNet( '10.0.0.4', '10.0.0.4/30' );
435 $this->assertNet( '172.17.32.0', '172.17.35.48/21' );
436 $this->assertNet( '10.128.0.0', '10.135.0.0/9' );
437 $this->assertNet( '134.0.0.0', '134.0.5.1/8' );
441 * @covers IP::canonicalize
443 public function testIPCanonicalizeOnValidIp() {
444 $this->assertEquals( '192.0.2.152', IP
::canonicalize( '192.0.2.152' ),
445 'Canonicalization of a valid IP returns it unchanged' );
449 * @covers IP::canonicalize
451 public function testIPCanonicalizeMappedAddress() {
454 IP
::canonicalize( '::ffff:192.0.2.152' )
458 IP
::canonicalize( '::192.0.2.152' )
463 * Issues there are most probably from IP::toHex() or IP::parseRange()
464 * @covers IP::isInRange
465 * @dataProvider provideIPsAndRanges
467 public function testIPIsInRange( $expected, $addr, $range, $message = '' ) {
470 IP
::isInRange( $addr, $range ),
475 /** Provider for testIPIsInRange() */
476 public static function provideIPsAndRanges() {
477 # Format: (expected boolean, address, range, optional message)
480 array( true, '192.0.2.0', '192.0.2.0/24', 'Network address' ),
481 array( true, '192.0.2.77', '192.0.2.0/24', 'Simple address' ),
482 array( true, '192.0.2.255', '192.0.2.0/24', 'Broadcast address' ),
484 array( false, '0.0.0.0', '192.0.2.0/24' ),
485 array( false, '255.255.255', '192.0.2.0/24' ),
488 array( false, '::1', '2001:DB8::/32' ),
489 array( false, '::', '2001:DB8::/32' ),
490 array( false, 'FE80::1', '2001:DB8::/32' ),
492 array( true, '2001:DB8::', '2001:DB8::/32' ),
493 array( true, '2001:0DB8::', '2001:DB8::/32' ),
494 array( true, '2001:DB8::1', '2001:DB8::/32' ),
495 array( true, '2001:0DB8::1', '2001:DB8::/32' ),
496 array( true, '2001:0DB8:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF',
499 array( false, '2001:0DB8:F::', '2001:DB8::/96' ),
504 * Test for IP::splitHostAndPort().
505 * @dataProvider provideSplitHostAndPort
507 public function testSplitHostAndPort( $expected, $input, $description ) {
508 $this->assertEquals( $expected, IP
::splitHostAndPort( $input ), $description );
512 * Provider for IP::splitHostAndPort()
514 public static function provideSplitHostAndPort() {
516 array( false, '[', 'Unclosed square bracket' ),
517 array( false, '[::', 'Unclosed square bracket 2' ),
518 array( array( '::', false ), '::', 'Bare IPv6 0' ),
519 array( array( '::1', false ), '::1', 'Bare IPv6 1' ),
520 array( array( '::', false ), '[::]', 'Bracketed IPv6 0' ),
521 array( array( '::1', false ), '[::1]', 'Bracketed IPv6 1' ),
522 array( array( '::1', 80 ), '[::1]:80', 'Bracketed IPv6 with port' ),
523 array( false, '::x', 'Double colon but no IPv6' ),
524 array( array( 'x', 80 ), 'x:80', 'Hostname and port' ),
525 array( false, 'x:x', 'Hostname and invalid port' ),
526 array( array( 'x', false ), 'x', 'Plain hostname' )
531 * Test for IP::combineHostAndPort()
532 * @dataProvider provideCombineHostAndPort
534 public function testCombineHostAndPort( $expected, $input, $description ) {
535 list( $host, $port, $defaultPort ) = $input;
538 IP
::combineHostAndPort( $host, $port, $defaultPort ),
543 * Provider for IP::combineHostAndPort()
545 public static function provideCombineHostAndPort() {
547 array( '[::1]', array( '::1', 2, 2 ), 'IPv6 default port' ),
548 array( '[::1]:2', array( '::1', 2, 3 ), 'IPv6 non-default port' ),
549 array( 'x', array( 'x', 2, 2 ), 'Normal default port' ),
550 array( 'x:2', array( 'x', 2, 3 ), 'Normal non-default port' ),
555 * Test for IP::sanitizeRange()
556 * @dataProvider provideIPCIDRs
558 public function testSanitizeRange( $input, $expected, $description ) {
559 $this->assertEquals( $expected, IP
::sanitizeRange( $input ), $description );
563 * Provider for IP::testSanitizeRange()
565 public static function provideIPCIDRs() {
567 array( '35.56.31.252/16', '35.56.0.0/16', 'IPv4 range' ),
568 array( '135.16.21.252/24', '135.16.21.0/24', 'IPv4 range' ),
569 array( '5.36.71.252/32', '5.36.71.252/32', 'IPv4 silly range' ),
570 array( '5.36.71.252', '5.36.71.252', 'IPv4 non-range' ),
571 array( '0:1:2:3:4:c5:f6:7/96', '0:1:2:3:4:C5:0:0/96', 'IPv6 range' ),
572 array( '0:1:2:3:4:5:6:7/120', '0:1:2:3:4:5:6:0/120', 'IPv6 range' ),
573 array( '0:e1:2:3:4:5:e6:7/128', '0:E1:2:3:4:5:E6:7/128', 'IPv6 silly range' ),
574 array( '0:c1:A2:3:4:5:c6:7', '0:C1:A2:3:4:5:C6:7', 'IPv6 non range' ),
579 * Test for IP::prettifyIP()
580 * @dataProvider provideIPsToPrettify
582 public function testPrettifyIP( $ip, $prettified ) {
583 $this->assertEquals( $prettified, IP
::prettifyIP( $ip ), "Prettify of $ip" );
587 * Provider for IP::testPrettifyIP()
589 public static function provideIPsToPrettify() {
591 array( '0:0:0:0:0:0:0:0', '::' ),
592 array( '0:0:0::0:0:0', '::' ),
593 array( '0:0:0:1:0:0:0:0', '0:0:0:1::' ),
594 array( '0:0::f', '::f' ),
595 array( '0::0:0:0:33:fef:b', '::33:fef:b' ),
596 array( '3f:535:0:0:0:0:e:fbb', '3f:535::e:fbb' ),
597 array( '0:0:fef:0:0:0:e:fbb', '0:0:fef::e:fbb' ),
598 array( 'abbc:2004::0:0:0:0', 'abbc:2004::' ),
599 array( 'cebc:2004:f:0:0:0:0:0', 'cebc:2004:f::' ),
600 array( '0:0:0:0:0:0:0:0/16', '::/16' ),
601 array( '0:0:0::0:0:0/64', '::/64' ),
602 array( '0:0::f/52', '::f/52' ),
603 array( '::0:0:33:fef:b/52', '::33:fef:b/52' ),
604 array( '3f:535:0:0:0:0:e:fbb/48', '3f:535::e:fbb/48' ),
605 array( '0:0:fef:0:0:0:e:fbb/96', '0:0:fef::e:fbb/96' ),
606 array( 'abbc:2004:0:0::0:0/40', 'abbc:2004::/40' ),
607 array( 'aebc:2004:f:0:0:0:0:0/80', 'aebc:2004:f::/80' ),