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 PHPUnit_Framework_TestCase
{
14 * @covers IP::isIPAddress
15 * @dataProvider provideInvalidIPs
17 public function isNotIPAddress( $val, $desc ) {
18 $this->assertFalse( IP
::isIPAddress( $val ), $desc );
22 * Provide a list of things that aren't IP addresses
24 public function provideInvalidIPs() {
26 array( false, 'Boolean false is not an IP' ),
27 array( true, 'Boolean true is not an IP' ),
28 array( '', 'Empty string is not an IP' ),
29 array( 'abc', 'Garbage IP string' ),
30 array( ':', 'Single ":" is not an IP' ),
31 array( '2001:0DB8::A:1::1', 'IPv6 with a double :: occurrence' ),
32 array( '2001:0DB8::A:1::', 'IPv6 with a double :: occurrence, last at end' ),
33 array( '::2001:0DB8::5:1', 'IPv6 with a double :: occurrence, firt at beginning' ),
34 array( '124.24.52', 'IPv4 not enough quads' ),
35 array( '24.324.52.13', 'IPv4 out of range' ),
36 array( '.24.52.13', 'IPv4 starts with period' ),
37 array( 'fc:100:300', 'IPv6 with only 3 words' ),
42 * @covers IP::isIPAddress
44 public function testisIPAddress() {
45 $this->assertTrue( IP
::isIPAddress( '::' ), 'RFC 4291 IPv6 Unspecified Address' );
46 $this->assertTrue( IP
::isIPAddress( '::1' ), 'RFC 4291 IPv6 Loopback Address' );
47 $this->assertTrue( IP
::isIPAddress( '74.24.52.13/20', 'IPv4 range' ) );
48 $this->assertTrue( IP
::isIPAddress( 'fc:100:a:d:1:e:ac:0/24' ), 'IPv6 range' );
49 $this->assertTrue( IP
::isIPAddress( 'fc::100:a:d:1:e:ac/96' ), 'IPv6 range with "::"' );
51 $validIPs = array( 'fc:100::', 'fc:100:a:d:1:e:ac::', 'fc::100', '::fc:100:a:d:1:e:ac',
52 '::fc', 'fc::100:a:d:1:e:ac', 'fc:100:a:d:1:e:ac:0', '124.24.52.13', '1.24.52.13' );
53 foreach ( $validIPs as $ip ) {
54 $this->assertTrue( IP
::isIPAddress( $ip ), "$ip is a valid IP address" );
61 public function testisIPv6() {
62 $this->assertFalse( IP
::isIPv6( ':fc:100::' ), 'IPv6 starting with lone ":"' );
63 $this->assertFalse( IP
::isIPv6( 'fc:100:::' ), 'IPv6 ending with a ":::"' );
64 $this->assertFalse( IP
::isIPv6( 'fc:300' ), 'IPv6 with only 2 words' );
65 $this->assertFalse( IP
::isIPv6( 'fc:100:300' ), 'IPv6 with only 3 words' );
67 $this->assertTrue( IP
::isIPv6( 'fc:100::' ) );
68 $this->assertTrue( IP
::isIPv6( 'fc:100:a::' ) );
69 $this->assertTrue( IP
::isIPv6( 'fc:100:a:d::' ) );
70 $this->assertTrue( IP
::isIPv6( 'fc:100:a:d:1::' ) );
71 $this->assertTrue( IP
::isIPv6( 'fc:100:a:d:1:e::' ) );
72 $this->assertTrue( IP
::isIPv6( 'fc:100:a:d:1:e:ac::' ) );
74 $this->assertFalse( IP
::isIPv6( 'fc:100:a:d:1:e:ac:0::' ), 'IPv6 with 8 words ending with "::"' );
76 IP
::isIPv6( 'fc:100:a:d:1:e:ac:0:1::' ),
77 'IPv6 with 9 words ending with "::"'
80 $this->assertFalse( IP
::isIPv6( ':::' ) );
81 $this->assertFalse( IP
::isIPv6( '::0:' ), 'IPv6 ending in a lone ":"' );
83 $this->assertTrue( IP
::isIPv6( '::' ), 'IPv6 zero address' );
84 $this->assertTrue( IP
::isIPv6( '::0' ) );
85 $this->assertTrue( IP
::isIPv6( '::fc' ) );
86 $this->assertTrue( IP
::isIPv6( '::fc:100' ) );
87 $this->assertTrue( IP
::isIPv6( '::fc:100:a' ) );
88 $this->assertTrue( IP
::isIPv6( '::fc:100:a:d' ) );
89 $this->assertTrue( IP
::isIPv6( '::fc:100:a:d:1' ) );
90 $this->assertTrue( IP
::isIPv6( '::fc:100:a:d:1:e' ) );
91 $this->assertTrue( IP
::isIPv6( '::fc:100:a:d:1:e:ac' ) );
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->assertFalse( IP
::isIPv6( ':fc::100' ), 'IPv6 starting with lone ":"' );
97 $this->assertFalse( IP
::isIPv6( 'fc::100:' ), 'IPv6 ending with lone ":"' );
98 $this->assertFalse( IP
::isIPv6( 'fc:::100' ), 'IPv6 with ":::" in the middle' );
100 $this->assertTrue( IP
::isIPv6( 'fc::100' ), 'IPv6 with "::" and 2 words' );
101 $this->assertTrue( IP
::isIPv6( 'fc::100:a' ), 'IPv6 with "::" and 3 words' );
102 $this->assertTrue( IP
::isIPv6( 'fc::100:a:d', 'IPv6 with "::" and 4 words' ) );
103 $this->assertTrue( IP
::isIPv6( 'fc::100:a:d:1' ), 'IPv6 with "::" and 5 words' );
104 $this->assertTrue( IP
::isIPv6( 'fc::100:a:d:1:e' ), 'IPv6 with "::" and 6 words' );
105 $this->assertTrue( IP
::isIPv6( 'fc::100:a:d:1:e:ac' ), 'IPv6 with "::" and 7 words' );
106 $this->assertTrue( IP
::isIPv6( '2001::df' ), 'IPv6 with "::" and 2 words' );
107 $this->assertTrue( IP
::isIPv6( '2001:5c0:1400:a::df' ), 'IPv6 with "::" and 5 words' );
108 $this->assertTrue( IP
::isIPv6( '2001:5c0:1400:a::df:2' ), 'IPv6 with "::" and 6 words' );
110 $this->assertFalse( IP
::isIPv6( 'fc::100:a:d:1:e:ac:0' ), 'IPv6 with "::" and 8 words' );
111 $this->assertFalse( IP
::isIPv6( 'fc::100:a:d:1:e:ac:0:1' ), 'IPv6 with 9 words' );
113 $this->assertTrue( IP
::isIPv6( 'fc:100:a:d:1:e:ac:0' ) );
118 * @dataProvider provideInvalidIPv4Addresses
120 public function testisNotIPv4( $bogusIP, $desc ) {
121 $this->assertFalse( IP
::isIPv4( $bogusIP ), $desc );
124 public function provideInvalidIPv4Addresses() {
126 array( false, 'Boolean false is not an IP' ),
127 array( true, 'Boolean true is not an IP' ),
128 array( '', 'Empty string is not an IP' ),
129 array( 'abc', 'Letters are not an IP' ),
130 array( ':', 'A colon is not an IP' ),
131 array( '124.24.52', 'IPv4 not enough quads' ),
132 array( '24.324.52.13', 'IPv4 out of range' ),
133 array( '.24.52.13', 'IPv4 starts with period' ),
139 * @dataProvider provideValidIPv4Address
141 public function testIsIPv4( $ip, $desc ) {
142 $this->assertTrue( IP
::isIPv4( $ip ), $desc );
146 * Provide some IPv4 addresses and ranges
148 public function provideValidIPv4Address() {
150 array( '124.24.52.13', 'Valid IPv4 address' ),
151 array( '1.24.52.13', 'Another valid IPv4 address' ),
152 array( '74.24.52.13/20', 'An IPv4 range' ),
157 * @covers IP::isValid
159 public function testValidIPs() {
160 foreach ( range( 0, 255 ) as $i ) {
161 $a = sprintf( "%03d", $i );
162 $b = sprintf( "%02d", $i );
163 $c = sprintf( "%01d", $i );
164 foreach ( array_unique( array( $a, $b, $c ) ) as $f ) {
166 $this->assertTrue( IP
::isValid( $ip ), "$ip is a valid IPv4 address" );
169 foreach ( range( 0x0, 0xFFFF, 0xF ) as $i ) {
170 $a = sprintf( "%04x", $i );
171 $b = sprintf( "%03x", $i );
172 $c = sprintf( "%02x", $i );
173 foreach ( array_unique( array( $a, $b, $c ) ) as $f ) {
174 $ip = "$f:$f:$f:$f:$f:$f:$f:$f";
175 $this->assertTrue( IP
::isValid( $ip ), "$ip is a valid IPv6 address" );
178 // test with some abbreviations
179 $this->assertFalse( IP
::isValid( ':fc:100::' ), 'IPv6 starting with lone ":"' );
180 $this->assertFalse( IP
::isValid( 'fc:100:::' ), 'IPv6 ending with a ":::"' );
181 $this->assertFalse( IP
::isValid( 'fc:300' ), 'IPv6 with only 2 words' );
182 $this->assertFalse( IP
::isValid( 'fc:100:300' ), 'IPv6 with only 3 words' );
184 $this->assertTrue( IP
::isValid( 'fc:100::' ) );
185 $this->assertTrue( IP
::isValid( 'fc:100:a:d:1:e::' ) );
186 $this->assertTrue( IP
::isValid( 'fc:100:a:d:1:e:ac::' ) );
188 $this->assertTrue( IP
::isValid( 'fc::100' ), 'IPv6 with "::" and 2 words' );
189 $this->assertTrue( IP
::isValid( 'fc::100:a' ), 'IPv6 with "::" and 3 words' );
190 $this->assertTrue( IP
::isValid( '2001::df' ), 'IPv6 with "::" and 2 words' );
191 $this->assertTrue( IP
::isValid( '2001:5c0:1400:a::df' ), 'IPv6 with "::" and 5 words' );
192 $this->assertTrue( IP
::isValid( '2001:5c0:1400:a::df:2' ), 'IPv6 with "::" and 6 words' );
193 $this->assertTrue( IP
::isValid( 'fc::100:a:d:1' ), 'IPv6 with "::" and 5 words' );
194 $this->assertTrue( IP
::isValid( 'fc::100:a:d:1:e:ac' ), 'IPv6 with "::" and 7 words' );
197 IP
::isValid( 'fc:100:a:d:1:e:ac:0::' ),
198 'IPv6 with 8 words ending with "::"'
201 IP
::isValid( 'fc:100:a:d:1:e:ac:0:1::' ),
202 'IPv6 with 9 words ending with "::"'
207 * @covers IP::isValid
209 public function testInvalidIPs() {
211 foreach ( range( 256, 999 ) as $i ) {
212 $a = sprintf( "%03d", $i );
213 $b = sprintf( "%02d", $i );
214 $c = sprintf( "%01d", $i );
215 foreach ( array_unique( array( $a, $b, $c ) ) as $f ) {
217 $this->assertFalse( IP
::isValid( $ip ), "$ip is not a valid IPv4 address" );
220 foreach ( range( 'g', 'z' ) as $i ) {
221 $a = sprintf( "%04s", $i );
222 $b = sprintf( "%03s", $i );
223 $c = sprintf( "%02s", $i );
224 foreach ( array_unique( array( $a, $b, $c ) ) as $f ) {
225 $ip = "$f:$f:$f:$f:$f:$f:$f:$f";
226 $this->assertFalse( IP
::isValid( $ip ), "$ip is not a valid IPv6 address" );
236 'c:ff:12:1:ea:d:321:5/120',
238 foreach ( $ipCIDRs as $i ) {
239 $this->assertFalse( IP
::isValid( $i ),
240 "$i is an invalid IP address because it is a block" );
242 // Incomplete/garbage
244 'www.xn--var-xla.net',
251 foreach ( $invalid as $i ) {
252 $this->assertFalse( IP
::isValid( $i ), "$i is an invalid IP address" );
257 * Provide some valid IP blocks
259 public function provideValidBlocks() {
261 array( '116.17.184.5/32' ),
262 array( '0.17.184.5/30' ),
263 array( '16.17.184.1/24' ),
264 array( '30.242.52.14/1' ),
265 array( '10.232.52.13/8' ),
266 array( '30.242.52.14/0' ),
267 array( '::e:f:2001/96' ),
268 array( '::c:f:2001/128' ),
269 array( '::10:f:2001/70' ),
270 array( '::fe:f:2001/1' ),
271 array( '::6d:f:2001/8' ),
272 array( '::fe:f:2001/0' ),
277 * @covers IP::isValidBlock
278 * @dataProvider provideValidBlocks
280 public function testValidBlocks( $block ) {
281 $this->assertTrue( IP
::isValidBlock( $block ), "$block is a valid IP block" );
285 * @covers IP::isValidBlock
286 * @dataProvider provideInvalidBlocks
288 public function testInvalidBlocks( $invalid ) {
289 $this->assertFalse( IP
::isValidBlock( $invalid ), "$invalid is not a valid IP block" );
292 public function provideInvalidBlocks() {
294 array( '116.17.184.5/33' ),
295 array( '0.17.184.5/130' ),
296 array( '16.17.184.1/-1' ),
297 array( '10.232.52.13/*' ),
298 array( '7.232.52.13/ab' ),
299 array( '11.232.52.13/' ),
300 array( '::e:f:2001/129' ),
301 array( '::c:f:2001/228' ),
302 array( '::10:f:2001/-1' ),
303 array( '::6d:f:2001/*' ),
304 array( '::86:f:2001/ab' ),
305 array( '::23:f:2001/' ),
310 * Improve IP::sanitizeIP() code coverage
311 * @todo Most probably incomplete
313 public function testSanitizeIP() {
314 $this->assertNull( IP
::sanitizeIP( '' ) );
315 $this->assertNull( IP
::sanitizeIP( ' ' ) );
320 * @dataProvider provideToHex
322 public function testToHex( $expected, $input ) {
323 $result = IP
::toHex( $input );
324 $this->assertTrue( $result === false ||
is_string( $result ) );
325 $this->assertEquals( $expected, $result );
329 * Provider for IP::testToHex()
331 public static function provideToHex() {
333 array( '00000001', '0.0.0.1' ),
334 array( '01020304', '1.2.3.4' ),
335 array( '7F000001', '127.0.0.1' ),
336 array( '80000000', '128.0.0.0' ),
337 array( 'DEADCAFE', '222.173.202.254' ),
338 array( 'FFFFFFFF', '255.255.255.255' ),
339 array( false, 'IN.VA.LI.D' ),
340 array( 'v6-00000000000000000000000000000001', '::1' ),
341 array( 'v6-20010DB885A3000000008A2E03707334', '2001:0db8:85a3:0000:0000:8a2e:0370:7334' ),
342 array( 'v6-20010DB885A3000000008A2E03707334', '2001:db8:85a3::8a2e:0370:7334' ),
343 array( false, 'IN:VA::LI:D' ),
344 array( false, ':::1' )
349 * @covers IP::isPublic
350 * @dataProvider provideIsPublic
352 public function testIsPublic( $expected, $input ) {
353 $result = IP
::isPublic( $input );
354 $this->assertEquals( $expected, $result );
358 * Provider for IP::testIsPublic()
360 public static function provideIsPublic() {
362 array( false, 'fc00::3' ), # RFC 4193 (local)
363 array( false, 'fc00::ff' ), # RFC 4193 (local)
364 array( false, '127.1.2.3' ), # loopback
365 array( false, '::1' ), # loopback
366 array( false, 'fe80::1' ), # link-local
367 array( false, '169.254.1.1' ), # link-local
368 array( false, '10.0.0.1' ), # RFC 1918 (private)
369 array( false, '172.16.0.1' ), # RFC 1918 (private)
370 array( false, '192.168.0.1' ), # RFC 1918 (private)
371 array( true, '2001:5c0:1000:a::133' ), # public
372 array( true, 'fc::3' ), # public
373 array( true, '00FC::' ) # public
377 // Private wrapper used to test CIDR Parsing.
378 private function assertFalseCIDR( $CIDR, $msg = '' ) {
379 $ff = array( false, false );
380 $this->assertEquals( $ff, IP
::parseCIDR( $CIDR ), $msg );
383 // Private wrapper to test network shifting using only dot notation
384 private function assertNet( $expected, $CIDR ) {
385 $parse = IP
::parseCIDR( $CIDR );
386 $this->assertEquals( $expected, long2ip( $parse[0] ), "network shifting $CIDR" );
390 * @covers IP::hexToQuad
391 * @dataProvider provideIPsAndHexes
393 public function testHexToQuad( $ip, $hex ) {
394 $this->assertEquals( $ip, IP
::hexToQuad( $hex ) );
398 * Provide some IP addresses and their equivalent hex representations
400 public function provideIPsandHexes() {
402 array( '0.0.0.1', '00000001' ),
403 array( '255.0.0.0', 'FF000000' ),
404 array( '255.255.255.255', 'FFFFFFFF' ),
405 array( '10.188.222.255', '0ABCDEFF' ),
406 // hex not left-padded...
407 array( '0.0.0.0', '0' ),
408 array( '0.0.0.1', '1' ),
409 array( '0.0.0.255', 'FF' ),
410 array( '0.0.255.0', 'FF00' ),
415 * @covers IP::hexToOctet
416 * @dataProvider provideOctetsAndHexes
418 public function testHexToOctet( $octet, $hex ) {
419 $this->assertEquals( $octet, IP
::hexToOctet( $hex ) );
423 * Provide some hex and octet representations of the same IPs
425 public function provideOctetsAndHexes() {
427 array( '0:0:0:0:0:0:0:1', '00000000000000000000000000000001' ),
428 array( '0:0:0:0:0:0:FF:3', '00000000000000000000000000FF0003' ),
429 array( '0:0:0:0:0:0:FF00:6', '000000000000000000000000FF000006' ),
430 array( '0:0:0:0:0:0:FCCF:FAFF', '000000000000000000000000FCCFFAFF' ),
431 array( 'FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF', 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' ),
432 // hex not left-padded...
433 array( '0:0:0:0:0:0:0:0', '0' ),
434 array( '0:0:0:0:0:0:0:1', '1' ),
435 array( '0:0:0:0:0:0:0:FF', 'FF' ),
436 array( '0:0:0:0:0:0:0:FFD0', 'FFD0' ),
437 array( '0:0:0:0:0:0:FA00:0', 'FA000000' ),
438 array( '0:0:0:0:0:0:FCCF:FAFF', 'FCCFFAFF' ),
443 * IP::parseCIDR() returns an array containing a signed IP address
444 * representing the network mask and the bit mask.
445 * @covers IP::parseCIDR
447 public function testCIDRParsing() {
448 $this->assertFalseCIDR( '192.0.2.0', "missing mask" );
449 $this->assertFalseCIDR( '192.0.2.0/', "missing bitmask" );
451 // Verify if statement
452 $this->assertFalseCIDR( '256.0.0.0/32', "invalid net" );
453 $this->assertFalseCIDR( '192.0.2.0/AA', "mask not numeric" );
454 $this->assertFalseCIDR( '192.0.2.0/-1', "mask < 0" );
455 $this->assertFalseCIDR( '192.0.2.0/33', "mask > 32" );
457 // Check internal logic
458 # 0 mask always result in array(0,0)
459 $this->assertEquals( array( 0, 0 ), IP
::parseCIDR( '192.0.0.2/0' ) );
460 $this->assertEquals( array( 0, 0 ), IP
::parseCIDR( '0.0.0.0/0' ) );
461 $this->assertEquals( array( 0, 0 ), IP
::parseCIDR( '255.255.255.255/0' ) );
463 // @todo FIXME: Add more tests.
465 # This part test network shifting
466 $this->assertNet( '192.0.0.0', '192.0.0.2/24' );
467 $this->assertNet( '192.168.5.0', '192.168.5.13/24' );
468 $this->assertNet( '10.0.0.160', '10.0.0.161/28' );
469 $this->assertNet( '10.0.0.0', '10.0.0.3/28' );
470 $this->assertNet( '10.0.0.0', '10.0.0.3/30' );
471 $this->assertNet( '10.0.0.4', '10.0.0.4/30' );
472 $this->assertNet( '172.17.32.0', '172.17.35.48/21' );
473 $this->assertNet( '10.128.0.0', '10.135.0.0/9' );
474 $this->assertNet( '134.0.0.0', '134.0.5.1/8' );
478 * @covers IP::canonicalize
480 public function testIPCanonicalizeOnValidIp() {
481 $this->assertEquals( '192.0.2.152', IP
::canonicalize( '192.0.2.152' ),
482 'Canonicalization of a valid IP returns it unchanged' );
486 * @covers IP::canonicalize
488 public function testIPCanonicalizeMappedAddress() {
491 IP
::canonicalize( '::ffff:192.0.2.152' )
495 IP
::canonicalize( '::192.0.2.152' )
500 * Issues there are most probably from IP::toHex() or IP::parseRange()
501 * @covers IP::isInRange
502 * @dataProvider provideIPsAndRanges
504 public function testIPIsInRange( $expected, $addr, $range, $message = '' ) {
507 IP
::isInRange( $addr, $range ),
512 /** Provider for testIPIsInRange() */
513 public static function provideIPsAndRanges() {
514 # Format: (expected boolean, address, range, optional message)
517 array( true, '192.0.2.0', '192.0.2.0/24', 'Network address' ),
518 array( true, '192.0.2.77', '192.0.2.0/24', 'Simple address' ),
519 array( true, '192.0.2.255', '192.0.2.0/24', 'Broadcast address' ),
521 array( false, '0.0.0.0', '192.0.2.0/24' ),
522 array( false, '255.255.255', '192.0.2.0/24' ),
525 array( false, '::1', '2001:DB8::/32' ),
526 array( false, '::', '2001:DB8::/32' ),
527 array( false, 'FE80::1', '2001:DB8::/32' ),
529 array( true, '2001:DB8::', '2001:DB8::/32' ),
530 array( true, '2001:0DB8::', '2001:DB8::/32' ),
531 array( true, '2001:DB8::1', '2001:DB8::/32' ),
532 array( true, '2001:0DB8::1', '2001:DB8::/32' ),
533 array( true, '2001:0DB8:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF',
536 array( false, '2001:0DB8:F::', '2001:DB8::/96' ),
541 * Test for IP::splitHostAndPort().
542 * @dataProvider provideSplitHostAndPort
544 public function testSplitHostAndPort( $expected, $input, $description ) {
545 $this->assertEquals( $expected, IP
::splitHostAndPort( $input ), $description );
549 * Provider for IP::splitHostAndPort()
551 public static function provideSplitHostAndPort() {
553 array( false, '[', 'Unclosed square bracket' ),
554 array( false, '[::', 'Unclosed square bracket 2' ),
555 array( array( '::', false ), '::', 'Bare IPv6 0' ),
556 array( array( '::1', false ), '::1', 'Bare IPv6 1' ),
557 array( array( '::', false ), '[::]', 'Bracketed IPv6 0' ),
558 array( array( '::1', false ), '[::1]', 'Bracketed IPv6 1' ),
559 array( array( '::1', 80 ), '[::1]:80', 'Bracketed IPv6 with port' ),
560 array( false, '::x', 'Double colon but no IPv6' ),
561 array( array( 'x', 80 ), 'x:80', 'Hostname and port' ),
562 array( false, 'x:x', 'Hostname and invalid port' ),
563 array( array( 'x', false ), 'x', 'Plain hostname' )
568 * Test for IP::combineHostAndPort()
569 * @dataProvider provideCombineHostAndPort
571 public function testCombineHostAndPort( $expected, $input, $description ) {
572 list( $host, $port, $defaultPort ) = $input;
575 IP
::combineHostAndPort( $host, $port, $defaultPort ),
580 * Provider for IP::combineHostAndPort()
582 public static function provideCombineHostAndPort() {
584 array( '[::1]', array( '::1', 2, 2 ), 'IPv6 default port' ),
585 array( '[::1]:2', array( '::1', 2, 3 ), 'IPv6 non-default port' ),
586 array( 'x', array( 'x', 2, 2 ), 'Normal default port' ),
587 array( 'x:2', array( 'x', 2, 3 ), 'Normal non-default port' ),
592 * Test for IP::sanitizeRange()
593 * @dataProvider provideIPCIDRs
595 public function testSanitizeRange( $input, $expected, $description ) {
596 $this->assertEquals( $expected, IP
::sanitizeRange( $input ), $description );
600 * Provider for IP::testSanitizeRange()
602 public static function provideIPCIDRs() {
604 array( '35.56.31.252/16', '35.56.0.0/16', 'IPv4 range' ),
605 array( '135.16.21.252/24', '135.16.21.0/24', 'IPv4 range' ),
606 array( '5.36.71.252/32', '5.36.71.252/32', 'IPv4 silly range' ),
607 array( '5.36.71.252', '5.36.71.252', 'IPv4 non-range' ),
608 array( '0:1:2:3:4:c5:f6:7/96', '0:1:2:3:4:C5:0:0/96', 'IPv6 range' ),
609 array( '0:1:2:3:4:5:6:7/120', '0:1:2:3:4:5:6:0/120', 'IPv6 range' ),
610 array( '0:e1:2:3:4:5:e6:7/128', '0:E1:2:3:4:5:E6:7/128', 'IPv6 silly range' ),
611 array( '0:c1:A2:3:4:5:c6:7', '0:C1:A2:3:4:5:C6:7', 'IPv6 non range' ),
616 * Test for IP::prettifyIP()
617 * @dataProvider provideIPsToPrettify
619 public function testPrettifyIP( $ip, $prettified ) {
620 $this->assertEquals( $prettified, IP
::prettifyIP( $ip ), "Prettify of $ip" );
624 * Provider for IP::testPrettifyIP()
626 public static function provideIPsToPrettify() {
628 array( '0:0:0:0:0:0:0:0', '::' ),
629 array( '0:0:0::0:0:0', '::' ),
630 array( '0:0:0:1:0:0:0:0', '0:0:0:1::' ),
631 array( '0:0::f', '::f' ),
632 array( '0::0:0:0:33:fef:b', '::33:fef:b' ),
633 array( '3f:535:0:0:0:0:e:fbb', '3f:535::e:fbb' ),
634 array( '0:0:fef:0:0:0:e:fbb', '0:0:fef::e:fbb' ),
635 array( 'abbc:2004::0:0:0:0', 'abbc:2004::' ),
636 array( 'cebc:2004:f:0:0:0:0:0', 'cebc:2004:f::' ),
637 array( '0:0:0:0:0:0:0:0/16', '::/16' ),
638 array( '0:0:0::0:0:0/64', '::/64' ),
639 array( '0:0::f/52', '::f/52' ),
640 array( '::0:0:33:fef:b/52', '::33:fef:b/52' ),
641 array( '3f:535:0:0:0:0:e:fbb/48', '3f:535::e:fbb/48' ),
642 array( '0:0:fef:0:0:0:e:fbb/96', '0:0:fef::e:fbb/96' ),
643 array( 'abbc:2004:0:0::0:0/40', 'abbc:2004::/40' ),
644 array( 'aebc:2004:f:0:0:0:0:0/80', 'aebc:2004:f::/80' ),