| [ Index ] |
PHP Cross Reference of YOURLS |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * General formatting functions. 5 */ 6 #[\PHPUnit\Framework\Attributes\Group('formatting')] 7 class FormatTest extends PHPUnit\Framework\TestCase { 8 9 /** 10 * Data to serialize 11 */ 12 static function serialize_data(): \Iterator 13 { 14 yield array( null ); 15 yield array( true ); 16 yield array( false ); 17 yield array( -25 ); 18 yield array( 25 ); 19 yield array( 1.1 ); 20 yield array( 'this string will be serialized' ); 21 yield array( "a\nb" ); 22 yield array( array() ); 23 yield array( array(1,1,2,3,5,8,13) ); 24 yield array( (object)array('test' => true, '3', 4) ); 25 } 26 27 /** 28 * Unserialized data 29 */ 30 static function not_serialized_data(): \Iterator 31 { 32 yield array( 'a string' ); 33 yield array( ['array', 'yarra'] ); 34 yield array( 'garbage:a:0:garbage;' ); 35 // array( 'b:4;' ), // this test fails in WP test suite, not sure if intentional or what... 36 yield array( 's:4:test;' ); 37 } 38 39 /** 40 * Check that yourls_is_serialized detects serialized data 41 */ 42 #[\PHPUnit\Framework\Attributes\DataProvider('serialize_data')] 43 public function test_is_serialized( $data ) { 44 $this->assertTrue( yourls_is_serialized( serialize( $data ) ) ); 45 } 46 47 /** 48 * Check that yourls_is_serialized doesn't assume garbage is serialized 49 */ 50 #[\PHPUnit\Framework\Attributes\DataProvider('not_serialized_data')] 51 public function test_is_not_serialized( $data ) { 52 $this->assertFalse( yourls_is_serialized( $data ) ); 53 } 54 55 /** 56 * yourls_maybe_unserialize() unserializes serialized data, and leaves the rest untouched 57 */ 58 #[\PHPUnit\Framework\Attributes\DataProvider('serialize_data')] 59 public function test_maybe_unserialize_serialized( $data ) { 60 $this->assertEquals( $data, yourls_maybe_unserialize( serialize( $data ) ) ); 61 } 62 63 /** 64 * yourls_maybe_unserialize() returns non-serialized input as-is 65 */ 66 #[\PHPUnit\Framework\Attributes\DataProvider('not_serialized_data')] 67 public function test_maybe_unserialize_passthrough($data) { 68 $this->assertSame( $data, yourls_maybe_unserialize( $data ) ); 69 } 70 71 /** 72 * Charsets used by yourls_rnd_string(). Structure: [type, expected character pool] 73 */ 74 static function rnd_string_types(): \Iterator { 75 yield 'type 1' => [ '1', '23456789bcdfghjkmnpqrstvwxyz' ]; 76 yield 'type 2' => [ '2', '23456789bcdfghjkmnpqrstvwxyzBCDFGHJKMNPQRSTVWXYZ' ]; 77 yield 'type 3' => [ '3', 'abcdefghijklmnopqrstuvwxyz' ]; 78 yield 'type 4' => [ '4', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' ]; 79 yield 'type 5' => [ '5', '0123456789abcdefghijklmnopqrstuvwxyz' ]; 80 yield 'type 6' => [ '6', '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' ]; 81 } 82 83 /** 84 * yourls_rnd_string() honors the requested length and only uses characters from 85 * the pool matching the requested type 86 */ 87 #[\PHPUnit\Framework\Attributes\DataProvider('rnd_string_types')] 88 public function test_rnd_string_types( $type, $pool ) { 89 $str = yourls_rnd_string( 8, $type ); 90 91 $this->assertSame( 8, strlen( $str ) ); 92 // Every character belongs to the expected pool 93 $this->assertSame( '', preg_replace( '/[' . preg_quote( $pool, '/' ) . ']/', '', $str ) ); 94 } 95 96 /** 97 * type 0 with a custom char list uses only that list 98 * 99 * Note: the result is str_shuffle()+substr(), so its length is capped at the 100 * size of the pool ; we use a pool larger than the requested length. 101 */ 102 public function test_rnd_string_custom_charlist() { 103 $str = yourls_rnd_string( 6, '0', 'ABCDEFGHIJ' ); 104 $this->assertSame( 6, strlen( $str ) ); 105 $this->assertSame( '', preg_replace( '/[ABCDEFGHIJ]/', '', $str ) ); 106 } 107 108 /** 109 * Short URL charsets for the int<->string 110 * 111 * - null : the charset currently in effect (driven by YOURLS_URL_CONVERT) 112 * - base 36 : '0-9a-z' (YOURLS_URL_CONVERT = 36, or anything but 62/64) 113 * - base 62 : '0-9a-zA-Z' (YOURLS_URL_CONVERT = 62 or 64) 114 */ 115 static function conversion_charsets(): \Iterator { 116 yield 'default (YOURLS_URL_CONVERT)' => array( null ); 117 yield 'base 36' => array( '0123456789abcdefghijklmnopqrstuvwxyz' ); 118 yield 'base 62' => array( '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' ); 119 } 120 121 /** 122 * Random string using only characters from $chars 123 */ 124 private function rand_str_from( string $chars, int $len ): string { 125 $max = strlen( $chars ) - 1; 126 $string = ''; 127 for( $i = 0; $i < $len; $i++ ) { 128 $string .= $chars[ mt_rand( 0, $max ) ]; 129 } 130 // Drop leading zeros (int2string never emits them); never return empty 131 return ltrim( $string, '0' ) ?: $chars[1]; 132 } 133 134 /** 135 * Integer (1337) to string (3jk) to integer 136 */ 137 #[\PHPUnit\Framework\Attributes\DataProvider('conversion_charsets')] 138 public function test_int_to_string_to_int( $chars ) { 139 // 10 random integers 140 for( $i=0; $i<10; $i++ ) { 141 $integer = mt_rand( 1, 1000000 ); 142 $this->assertEquals( $integer, yourls_string2int( yourls_int2string( $integer, $chars ), $chars ) ); 143 } 144 } 145 146 /** 147 * String (3jk) to integer (1337) to string 148 */ 149 #[\PHPUnit\Framework\Attributes\DataProvider('conversion_charsets')] 150 public function test_string_to_int_to_string( $chars ) { 151 // Generate random strings from the charset actually in use 152 $charset = $chars ?? yourls_get_shorturl_charset(); 153 154 for( $i=0; $i<10; $i++ ) { 155 $string = $this->rand_str_from( $charset, mt_rand( 2, 10 ) ); 156 $this->assertEquals( $string, yourls_int2string( yourls_string2int( $string, $chars ), $chars ) ); 157 } 158 } 159 160 /** 161 * Checking that yourls_unique_element_id is a unique string 162 * 163 */ 164 public function test_string2htmlid() { 165 $id1 = yourls_unique_element_id(); 166 $id2 = yourls_unique_element_id(); 167 $id3 = yourls_unique_element_id('foo', 10); 168 $id4 = yourls_unique_element_id(); 169 $this->assertIsString($id1); 170 $this->assertIsString($id2); 171 $this->assertNotSame($id1, $id2); 172 $this->assertEquals('foo10', $id3, 'ID is built using the specified prefix and counter value.'); 173 $this->assertStringEndsWith('11', $id4, 'ID counter continues to increment from the last value.'); 174 } 175 176 /** 177 * Generating valid regexp from the allowed charset 178 */ 179 function test_valid_regexp() { 180 $pattern = yourls_make_regexp_pattern( yourls_get_shorturl_charset() ); 181 182 /* To validate a RegExp just run it against an empty string. 183 If it returns explicit false (=== false), it's broken. Otherwise it's valid. 184 From: https://stackoverflow.com/a/12941133/36850 185 Cool to know :) 186 187 We're testing it as used in yourls_sanitize_keyword() 188 TODO: more random char strings to test? 189 */ 190 191 $this->assertNotFalse( preg_match( '![^' . $pattern . ']!', '' ) ); 192 } 193 194 /** 195 * Trim long strings 196 */ 197 function test_trim_long_strings() { 198 $long = "The Plague That Makes Your Booty Move... It's The Infectious Grooves"; 199 200 $trim = "The Plague That Makes Your Booty Move... It's The Infec[...]"; 201 $this->assertSame( $trim, yourls_trim_long_string( $long ) ); 202 203 $trim = "The Plague That Makes Your Booty[...]"; 204 $this->assertSame( $trim, yourls_trim_long_string( $long, 37 ) ); 205 206 $trim = "The Plague That Makes Your Booty Mo.."; 207 $this->assertSame( $trim, yourls_trim_long_string( $long, 37, '..' ) ); 208 } 209 210 /** 211 * Return true for UTF8 strings 212 * 213 * Note: As of 1.7.1, function yourls_seem_utf8() is still unused. In 2.0 consider simply deleting it if still not needed 214 */ 215 #[\PHPUnit\Framework\Attributes\DataProvider('valid_utf8')] 216 function test_is_utf8( $string ) { 217 $this->assertTrue( yourls_seems_utf8( $string ) ); 218 } 219 220 /** 221 * Return false for non UTF8 strings 222 * 223 * Note: As of 1.7.1, function yourls_seem_utf8() is still unused. In 2.0 consider simply deleting it if still not needed 224 */ 225 #[\PHPUnit\Framework\Attributes\DataProvider('invalid_utf8')] 226 function test_is_not_utf8( $string ) { 227 $this->assertFalse( yourls_seems_utf8( $string ) ); 228 } 229 230 static function valid_utf8() { 231 return self::get_data( YOURLS_TESTDATA_DIR . '/formatting/utf-8.txt' ); 232 } 233 234 static function invalid_utf8() { 235 return self::get_data( YOURLS_TESTDATA_DIR . '/formatting/big5.txt' ); 236 } 237 238 /** 239 * Parse a file and return its content as a data provider 240 */ 241 static function get_data( $filename ) { 242 $strings = file( $filename ); 243 foreach ( $strings as &$string ) { 244 $string = (array) trim( $string ); 245 } 246 unset( $string ); 247 return $strings; 248 } 249 250 /** 251 * Test yourls_backslashit 252 */ 253 function test_backslashit() { 254 $this->assertSame( '\h\e\l\l\o \w\o\r\l\d 123 !', yourls_backslashit( 'hello world 123 !' ) ); 255 $this->assertSame( '\\\1, 2, 3', yourls_backslashit( '1, 2, 3' ) ); 256 } 257 258 /** 259 * Test the bookmarklet generator 260 * 261 * Note: we're not testing that the bookmarklet generator produces valid JS code: the 262 * bookmarklet class has tests for this, see https://github.com/ozh/bookmarkletgen 263 * We're just testing that content is returned 264 */ 265 function test_bookmarklet() { 266 $code = yourls_make_bookmarklet( 'hello' ); 267 $this->assertTrue( is_string( $code ) ); 268 } 269 270 /** 271 * Test yourls_specialchars basics 272 */ 273 function test_specialchars_decode_basics() { 274 $html = "&<hello world>"; 275 $this->assertEquals( $html, yourls_specialchars( $html ) ); 276 277 $double = "&amp;&lt;hello world&gt;"; 278 $this->assertEquals( $double, yourls_specialchars( $html, ENT_NOQUOTES, true ) ); 279 } 280 281 /** 282 * Test yourls_specialchars escape quotes 283 */ 284 function test_specialchars_escapes_quotes() { 285 $source = "\"'hello!'\""; 286 $this->assertEquals( '"'hello!'"', yourls_specialchars( $source, 'single' ) ); 287 $this->assertEquals( ""'hello!'"", yourls_specialchars( $source, 'double' ) ); 288 $this->assertEquals( '"'hello!'"', yourls_specialchars( $source, ENT_QUOTES, true ) ); 289 $this->assertEquals( '"'hello!'"', yourls_specialchars( $source, 'omg', true ) ); // unaccepted value should be treated as ENT_QUOTES 290 $this->assertEquals( $source, yourls_specialchars( $source ) ); 291 } 292 293 /** 294 * Test yourls_specialchars doesn't change allowed entities 295 */ 296 function test_specialchars_allowed_entities() { 297 foreach ( yourls_kses_allowed_entities() as $ent ) { 298 $ent = '&' . $ent . ';'; 299 $this->assertEquals( $ent, yourls_specialchars( $ent ) ); 300 } 301 } 302 303 /** 304 * Test yourls_specialchars with unallowed entities 305 */ 306 function test_specialchars_unallowed_entities() { 307 $ents = array( 'iacut', 'aposs', 'pos', 'apo', 'apo?', 'apo.*', '.*apo.*', 'apos ', ' apos', ' apos ' ); 308 309 foreach ( $ents as $ent ) { 310 $escaped = '&' . $ent . ';'; 311 $ent = '&' . $ent . ';'; 312 $this->assertEquals( $escaped, yourls_specialchars( $ent ) ); 313 } 314 } 315 316 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Sat Jul 11 05:10:54 2026 | Cross-referenced by PHPXref 0.7.1 |