Changeset 30807 for branches/4.1/tests/phpunit/tests/db/charset.php
- Timestamp:
- 12/10/2014 10:56:25 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/4.1/tests/phpunit/tests/db/charset.php
r30699 r30807 1 <?php2 3 require_once dirname( dirname( __FILE__ ) ) . '/db.php';4 5 /**6 * Test WPDB methods7 *8 * @group wpdb9 */10 class Tests_DB_Charset extends WP_UnitTestCase {11 12 /**13 * Our special WPDB14 * @var resource15 */16 protected static $_wpdb;17 18 public static function setUpBeforeClass() {19 self::$_wpdb = new wpdb_exposed_methods_for_testing();20 }21 22 /**23 * @ticket 2121224 */25 function data_strip_invalid_text() {26 $fields = array(27 'latin1' => array(28 // latin1. latin1 never changes.29 'charset' => 'latin1',30 'value' => "\xf0\x9f\x8e\xb7",31 'expected' => "\xf0\x9f\x8e\xb7"32 ),33 'ascii' => array(34 // ascii gets special treatment, make sure it's covered35 'charset' => 'ascii',36 'value' => 'Hello World',37 'expected' => 'Hello World'38 ),39 'utf8' => array(40 // utf8 only allows <= 3-byte chars41 'charset' => 'utf8',42 'value' => "H€llo\xf0\x9f\x98\x88World¢",43 'expected' => 'H€lloWorld¢'44 ),45 'utf8mb3' => array(46 // utf8mb3 should behave the same an utf847 'charset' => 'utf8mb3',48 'value' => "H€llo\xf0\x9f\x98\x88World¢",49 'expected' => 'H€lloWorld¢'50 ),51 'utf8mb4' => array(52 // utf8mb4 allows 4-byte characters, too53 'charset' => 'utf8mb4',54 'value' => "H€llo\xf0\x9f\x98\x88World¢",55 'expected' => "H€llo\xf0\x9f\x98\x88World¢"56 ),57 'koi8r' => array(58 // koi8r is a character set that needs to be checked in MySQL59 'charset' => 'koi8r',60 'value' => "\xfdord\xf2ress",61 'expected' => "\xfdord\xf2ress",62 'db' => true63 ),64 'hebrew' => array(65 // hebrew needs to be checked in MySQL, too66 'charset' => 'hebrew',67 'value' => "\xf9ord\xf7ress",68 'expected' => "\xf9ord\xf7ress",69 'db' => true70 ),71 'false' => array(72 // false is a column with no character set (ie, a number column)73 'charset' => false,74 'value' => 100,75 'expected' => 10076 ),77 );78 79 if ( function_exists( 'mb_convert_encoding' ) ) {80 // big5 is a non-Unicode multibyte charset81 $utf8 = "a\xe5\x85\xb1b"; // UTF-8 Character 2084982 $big5 = mb_convert_encoding( $utf8, 'BIG-5', 'UTF-8' );83 $conv_utf8 = mb_convert_encoding( $big5, 'UTF-8', 'BIG-5' );84 // Make sure PHP's multibyte conversions are working correctly85 $this->assertNotEquals( $utf8, $big5 );86 $this->assertEquals( $utf8, $conv_utf8 );87 88 $fields['big5'] = array(89 'charset' => 'big5',90 'value' => $big5,91 'expected' => $big592 );93 }94 95 // The data above is easy to edit. Now, prepare it for the data provider.96 $data_provider = $multiple = $multiple_expected = array();97 foreach ( $fields as $test_case => $field ) {98 $expected = $field;99 $expected['value'] = $expected['expected'];100 unset( $expected['expected'], $field['expected'] );101 102 // We're keeping track of these for our multiple-field test.103 $multiple[] = $field;104 $multiple_expected[] = $expected;105 106 // strip_invalid_text() expects an array of fields. We're testing one field at a time.107 $data = array( $field );108 $expected = array( $expected );109 110 // First argument is field data. Second is expected. Third is the message.111 $data_provider[] = array( $data, $expected, $test_case );112 }113 114 // Time for our test of multiple fields at once.115 $data_provider[] = array( $multiple, $multiple_expected, 'multiple fields/charsets' );116 117 return $data_provider;118 }119 120 /**121 * @dataProvider data_strip_invalid_text122 * @ticket 21212123 */124 function test_strip_invalid_text( $data, $expected, $message ) {125 if ( $data[0]['charset'] === 'koi8r' ) {126 self::$_wpdb->query( 'SET NAMES koi8r' );127 }128 $actual = self::$_wpdb->strip_invalid_text( $data );129 $this->assertSame( $expected, $actual, $message );130 }131 132 /**133 * @ ticket 21212134 */135 function test_process_fields_failure() {136 global $wpdb;137 $data = array( 'post_content' => "H€llo\xf0\x9f\x98\x88World¢" );138 $this->assertFalse( self::$_wpdb->process_fields( $wpdb->posts, $data, null ) );139 }140 141 /**142 * @ticket 21212143 */144 function data_process_field_charsets() {145 $charset = $GLOBALS['wpdb']->charset; // This is how all tables were installed146 // 'value' and 'format' are $data, 'charset' ends up as part of $expected147 148 $no_string_fields = array(149 'post_parent' => array( 'value' => 10, 'format' => '%d', 'charset' => false ),150 'comment_count' => array( 'value' => 0, 'format' => '%d', 'charset' => false ),151 );152 153 $all_ascii_fields = array(154 'post_content' => array( 'value' => 'foo foo foo!', 'format' => '%s', 'charset' => false ),155 'post_excerpt' => array( 'value' => 'bar bar bar!', 'format' => '%s', 'charset' => false ),156 );157 158 // This is the same data used in process_field_charsets_for_nonexistent_table()159 $non_ascii_string_fields = array(160 'post_content' => array( 'value' => '¡foo foo foo!', 'format' => '%s', 'charset' => $charset, 'ascii' => false ),161 'post_excerpt' => array( 'value' => '¡bar bar bar!', 'format' => '%s', 'charset' => $charset, 'ascii' => false ),162 );163 164 $vars = get_defined_vars();165 unset( $vars['charset'] );166 foreach ( $vars as $var_name => $var ) {167 $data = $expected = $var;168 foreach ( $data as &$datum ) {169 // 'charset' and 'ascii' are part of the expected return only.170 unset( $datum['charset'], $datum['ascii'] );171 }172 173 $vars[ $var_name ] = array( $data, $expected, $var_name );174 }175 176 return array_values( $vars );177 }178 179 /**180 * @dataProvider data_process_field_charsets181 * @ticket 21212182 */183 function test_process_field_charsets( $data, $expected, $message ) {184 $actual = self::$_wpdb->process_field_charsets( $data, $GLOBALS['wpdb']->posts );185 $this->assertSame( $expected, $actual, $message );186 }187 188 /**189 * The test this test depends on first verifies that this190 * would normally work against the posts table.191 *192 * @ticket 21212193 * @depends test_process_field_charsets194 */195 function test_process_field_charsets_on_nonexistent_table() {196 $data = array( 'post_content' => array( 'value' => '¡foo foo foo!', 'format' => '%s' ) );197 self::$_wpdb->suppress_errors( true );198 $this->assertFalse( self::$_wpdb->process_field_charsets( $data, 'nonexistent_table' ) );199 self::$_wpdb->suppress_errors( false );200 }201 202 /**203 * @ticket 21212204 */205 function test_check_ascii() {206 $ascii = "\0\t\n\r '" . '!"#$%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';207 $this->assertTrue( self::$_wpdb->check_ascii( $ascii ) );208 }209 210 /**211 * @ticket 21212212 */213 function test_check_ascii_false() {214 $this->assertFalse( self::$_wpdb->check_ascii( 'ABCDEFGHIJKLMNOPQRSTUVWXYZ¡©«' ) );215 }216 217 /**218 * @ticket 21212219 */220 function test_strip_invalid_text_for_column() {221 global $wpdb;222 // Invalid 3-byte and 4-byte sequences223 $value = "H€llo\xe0\x80\x80World\xf0\xff\xff\xff¢";224 $expected = "H€lloWorld¢";225 $actual = $wpdb->strip_invalid_text_for_column( $wpdb->posts, 'post_content', $value );226 $this->assertEquals( $expected, $actual );227 }228 229 /**230 * Set of table definitions for testing wpdb::get_table_charset and wpdb::get_column_charset231 * @var array232 */233 protected $table_and_column_defs = array(234 array(235 'definition' => '( a INT, b FLOAT )',236 'table_expected' => false,237 'column_expected' => array( 'a' => false, 'b' => false )238 ),239 array(240 'definition' => '( a VARCHAR(50) CHARACTER SET big5, b TEXT CHARACTER SET big5 )',241 'table_expected' => 'big5',242 'column_expected' => array( 'a' => 'big5', 'b' => 'big5' )243 ),244 array(245 'definition' => '( a VARCHAR(50) CHARACTER SET big5, b BINARY )',246 'table_expected' => 'binary',247 'column_expected' => array( 'a' => 'big5', 'b' => false )248 ),249 array(250 'definition' => '( a VARCHAR(50) CHARACTER SET latin1, b BLOB )',251 'table_expected' => 'binary',252 'column_expected' => array( 'a' => 'latin1', 'b' => false )253 ),254 array(255 'definition' => '( a VARCHAR(50) CHARACTER SET latin1, b TEXT CHARACTER SET koi8r )',256 'table_expected' => 'koi8r',257 'column_expected' => array( 'a' => 'latin1', 'b' => 'koi8r' )258 ),259 array(260 'definition' => '( a VARCHAR(50) CHARACTER SET utf8mb3, b TEXT CHARACTER SET utf8mb3 )',261 'table_expected' => 'utf8',262 'column_expected' => array( 'a' => 'utf8', 'b' => 'utf8' )263 ),264 array(265 'definition' => '( a VARCHAR(50) CHARACTER SET utf8, b TEXT CHARACTER SET utf8mb4 )',266 'table_expected' => 'utf8',267 'column_expected' => array( 'a' => 'utf8', 'b' => 'utf8mb4' )268 ),269 array(270 'definition' => '( a VARCHAR(50) CHARACTER SET big5, b TEXT CHARACTER SET koi8r )',271 'table_expected' => 'ascii',272 'column_expected' => array( 'a' => 'big5', 'b' => 'koi8r' )273 ),274 );275 276 /**277 * @ticket 21212278 */279 function data_test_get_table_charset() {280 $table_name = 'test_get_table_charset';281 282 $vars = array();283 foreach( $this->table_and_column_defs as $value ) {284 $this_table_name = $table_name . '_' . rand_str( 5 );285 $drop = "DROP TABLE IF EXISTS $this_table_name";286 $create = "CREATE TABLE $this_table_name {$value['definition']}";287 $vars[] = array( $drop, $create, $this_table_name, $value['table_expected'] );288 }289 290 return $vars;291 }292 293 /**294 * @dataProvider data_test_get_table_charset295 * @ticket 21212296 */297 function test_get_table_charset( $drop, $create, $table, $expected_charset ) {298 self::$_wpdb->query( $drop );299 300 if ( ! self::$_wpdb->has_cap( 'utf8mb4' ) && preg_match( '/utf8mb[34]/i', $create ) ) {301 $this->markTestSkipped( "This version of MySQL doesn't support utf8mb4." );302 return;303 }304 305 self::$_wpdb->query( $create );306 307 $charset = self::$_wpdb->get_table_charset( $table );308 $this->assertEquals( $charset, $expected_charset );309 310 $charset = self::$_wpdb->get_table_charset( strtoupper( $table ) );311 $this->assertEquals( $charset, $expected_charset );312 313 self::$_wpdb->query( $drop );314 }315 316 /**317 * @ticket 21212318 */319 function data_test_get_column_charset() {320 $table_name = 'test_get_column_charset';321 322 $vars = array();323 foreach( $this->table_and_column_defs as $value ) {324 $this_table_name = $table_name . '_' . rand_str( 5 );325 $drop = "DROP TABLE IF EXISTS $this_table_name";326 $create = "CREATE TABLE $this_table_name {$value['definition']}";327 $vars[] = array( $drop, $create, $this_table_name, $value['column_expected'] );328 }329 330 return $vars;331 }332 333 /**334 * @dataProvider data_test_get_column_charset335 * @ticket 21212336 */337 function test_get_column_charset( $drop, $create, $table, $expected_charset ) {338 self::$_wpdb->query( $drop );339 340 if ( ! self::$_wpdb->has_cap( 'utf8mb4' ) && preg_match( '/utf8mb[34]/i', $create ) ) {341 $this->markTestSkipped( "This version of MySQL doesn't support utf8mb4." );342 return;343 }344 345 self::$_wpdb->query( $create );346 347 foreach ( $expected_charset as $column => $charset ) {348 $this->assertEquals( $charset, self::$_wpdb->get_col_charset( $table, $column ) );349 $this->assertEquals( $charset, self::$_wpdb->get_col_charset( strtoupper( $table ), strtoupper( $column ) ) );350 }351 352 self::$_wpdb->query( $drop );353 }354 355 /**356 * @dataProvider data_test_get_column_charset357 * @ticket 21212358 */359 function test_get_column_charset_non_mysql( $drop, $create, $table, $columns ) {360 self::$_wpdb->query( $drop );361 362 if ( ! self::$_wpdb->has_cap( 'utf8mb4' ) && preg_match( '/utf8mb[34]/i', $create ) ) {363 $this->markTestSkipped( "This version of MySQL doesn't support utf8mb4." );364 return;365 }366 367 self::$_wpdb->is_mysql = false;368 369 self::$_wpdb->query( $create );370 371 $columns = array_keys( $columns );372 foreach ( $columns as $column => $charset ) {373 $this->assertEquals( false, self::$_wpdb->get_col_charset( $table, $column ) );374 }375 376 self::$_wpdb->query( $drop );377 378 self::$_wpdb->is_mysql = true;379 }380 381 /**382 * @ticket 21212383 */384 function data_strip_invalid_text_from_query() {385 $table_name = 'strip_invalid_text_from_query_table';386 $data = array(387 array(388 // binary tables don't get stripped389 "( a VARCHAR(50) CHARACTER SET utf8, b BINARY )", // create390 "('foo\xf0\x9f\x98\x88bar', 'foo')", // query391 "('foo\xf0\x9f\x98\x88bar', 'foo')" // expected result392 ),393 array(394 // utf8/utf8mb4 tables default to utf8395 "( a VARCHAR(50) CHARACTER SET utf8, b VARCHAR(50) CHARACTER SET utf8mb4 )",396 "('foo\xf0\x9f\x98\x88bar', 'foo')",397 "('foobar', 'foo')"398 ),399 );400 401 foreach( $data as &$value ) {402 $this_table_name = $table_name . '_' . rand_str( 5 );403 404 $value[0] = "CREATE TABLE $this_table_name {$value[0]}";405 $value[1] = "INSERT INTO $this_table_name VALUES {$value[1]}";406 $value[2] = "INSERT INTO $this_table_name VALUES {$value[2]}";407 $value[3] = "DROP TABLE IF EXISTS $this_table_name";408 }409 unset( $value );410 411 return $data;412 }413 414 /**415 * @dataProvider data_strip_invalid_text_from_query416 * @ticket 21212417 */418 function test_strip_invalid_text_from_query( $create, $query, $expected, $drop ) {419 self::$_wpdb->query( $drop );420 421 if ( ! self::$_wpdb->has_cap( 'utf8mb4' ) && preg_match( '/utf8mb[34]/i', $create ) ) {422 $this->markTestSkipped( "This version of MySQL doesn't support utf8mb4." );423 return;424 }425 426 self::$_wpdb->query( $create );427 428 $return = self::$_wpdb->strip_invalid_text_from_query( $query );429 $this->assertEquals( $expected, $return );430 431 self::$_wpdb->query( $drop );432 }433 434 /**435 * @ticket 21212436 */437 function test_invalid_characters_in_query() {438 global $wpdb;439 $this->assertFalse( $wpdb->query( "INSERT INTO {$wpdb->posts} (post_content) VALUES ('foo\xf0\x9f\x98\x88bar')" ) );440 }441 }
Note: See TracChangeset
for help on using the changeset viewer.