Chris@0: assertEquals($encoded, Unicode::mimeHeaderEncode($value)); Chris@0: $this->assertEquals($value, Unicode::mimeHeaderDecode($encoded)); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Data provider for testMimeHeader(). Chris@0: * Chris@0: * @see testMimeHeader() Chris@0: * Chris@0: * @return array Chris@0: * An array containing a string and its encoded value. Chris@0: */ Chris@0: public function providerTestMimeHeader() { Chris@0: return [ Chris@0: ['tést.txt', '=?UTF-8?B?dMOpc3QudHh0?='], Chris@0: // Simple ASCII characters. Chris@0: ['ASCII', 'ASCII'], Chris@0: ]; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tests multibyte strtolower. Chris@0: * Chris@0: * @dataProvider providerStrtolower Chris@0: * @covers ::strtolower Chris@0: * @covers ::caseFlip Chris@17: * @group legacy Chris@17: * @expectedDeprecation \Drupal\Component\Utility\Unicode::strtolower() is deprecated in Drupal 8.6.0 and will be removed before Drupal 9.0.0. Use mb_strtolower() instead. See https://www.drupal.org/node/2850048. Chris@0: */ Chris@17: public function testStrtolower($text, $expected) { Chris@0: $this->assertEquals($expected, Unicode::strtolower($text)); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Data provider for testStrtolower(). Chris@0: * Chris@0: * @see testStrtolower() Chris@0: * Chris@0: * @return array Chris@17: * An array containing a string and its lowercase version. Chris@0: */ Chris@0: public function providerStrtolower() { Chris@17: return [ Chris@0: ['tHe QUIcK bRoWn', 'the quick brown'], Chris@0: ['FrançAIS is ÜBER-åwesome', 'français is über-åwesome'], Chris@17: ['ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΣὨ', 'αβγδεζηθικλμνξοσὠ'], Chris@0: ]; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tests multibyte strtoupper. Chris@0: * Chris@0: * @dataProvider providerStrtoupper Chris@0: * @covers ::strtoupper Chris@0: * @covers ::caseFlip Chris@17: * @group legacy Chris@17: * @expectedDeprecation \Drupal\Component\Utility\Unicode::strtoupper() is deprecated in Drupal 8.6.0 and will be removed before Drupal 9.0.0. Use mb_strtoupper() instead. See https://www.drupal.org/node/2850048. Chris@0: */ Chris@17: public function testStrtoupper($text, $expected) { Chris@0: $this->assertEquals($expected, Unicode::strtoupper($text)); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Data provider for testStrtoupper(). Chris@0: * Chris@0: * @see testStrtoupper() Chris@0: * Chris@0: * @return array Chris@17: * An array containing a string and its uppercase version. Chris@0: */ Chris@0: public function providerStrtoupper() { Chris@17: return [ Chris@0: ['tHe QUIcK bRoWn', 'THE QUICK BROWN'], Chris@0: ['FrançAIS is ÜBER-åwesome', 'FRANÇAIS IS ÜBER-ÅWESOME'], Chris@17: ['αβγδεζηθικλμνξοσὠ', 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΣὨ'], Chris@0: ]; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tests multibyte ucfirst. Chris@0: * Chris@0: * @dataProvider providerUcfirst Chris@0: * @covers ::ucfirst Chris@0: */ Chris@0: public function testUcfirst($text, $expected) { Chris@0: $this->assertEquals($expected, Unicode::ucfirst($text)); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Data provider for testUcfirst(). Chris@0: * Chris@0: * @see testUcfirst() Chris@0: * Chris@0: * @return array Chris@0: * An array containing a string and its uppercase first version. Chris@0: */ Chris@0: public function providerUcfirst() { Chris@0: return [ Chris@0: ['tHe QUIcK bRoWn', 'THe QUIcK bRoWn'], Chris@0: ['françAIS', 'FrançAIS'], Chris@0: ['über', 'Über'], Chris@0: ['åwesome', 'Åwesome'], Chris@0: // A multibyte string. Chris@0: ['σion', 'Σion'], Chris@0: ]; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tests multibyte lcfirst. Chris@0: * Chris@0: * @dataProvider providerLcfirst Chris@0: * @covers ::lcfirst Chris@0: */ Chris@17: public function testLcfirst($text, $expected) { Chris@0: $this->assertEquals($expected, Unicode::lcfirst($text)); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Data provider for testLcfirst(). Chris@0: * Chris@0: * @see testLcfirst() Chris@0: * Chris@0: * @return array Chris@17: * An array containing a string and its lowercase version. Chris@0: */ Chris@0: public function providerLcfirst() { Chris@0: return [ Chris@0: ['tHe QUIcK bRoWn', 'tHe QUIcK bRoWn'], Chris@0: ['FrançAIS is ÜBER-åwesome', 'françAIS is ÜBER-åwesome'], Chris@0: ['Über', 'über'], Chris@0: ['Åwesome', 'åwesome'], Chris@0: // Add a multibyte string. Chris@17: ['ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΣὨ', 'αΒΓΔΕΖΗΘΙΚΛΜΝΞΟΣὨ'], Chris@0: ]; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tests multibyte ucwords. Chris@0: * Chris@0: * @dataProvider providerUcwords Chris@0: * @covers ::ucwords Chris@0: */ Chris@17: public function testUcwords($text, $expected) { Chris@0: $this->assertEquals($expected, Unicode::ucwords($text)); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Data provider for testUcwords(). Chris@0: * Chris@0: * @see testUcwords() Chris@0: * Chris@0: * @return array Chris@17: * An array containing a string and its capitalized version. Chris@0: */ Chris@0: public function providerUcwords() { Chris@0: return [ Chris@0: ['tHe QUIcK bRoWn', 'THe QUIcK BRoWn'], Chris@0: ['françAIS', 'FrançAIS'], Chris@0: ['über', 'Über'], Chris@0: ['åwesome', 'Åwesome'], Chris@0: // Make sure we don't mangle extra spaces. Chris@0: ['frànçAIS is über-åwesome', 'FrànçAIS Is Über-Åwesome'], Chris@0: // Add a multibyte string. Chris@17: ['σion', 'Σion'], Chris@0: ]; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tests multibyte strlen. Chris@0: * Chris@0: * @dataProvider providerStrlen Chris@0: * @covers ::strlen Chris@17: * @group legacy Chris@17: * @expectedDeprecation \Drupal\Component\Utility\Unicode::strlen() is deprecated in Drupal 8.6.0 and will be removed before Drupal 9.0.0. Use mb_strlen() instead. See https://www.drupal.org/node/2850048. Chris@0: */ Chris@0: public function testStrlen($text, $expected) { Chris@0: $this->assertEquals($expected, Unicode::strlen($text)); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Data provider for testStrlen(). Chris@0: * Chris@0: * @see testStrlen() Chris@0: * Chris@0: * @return array Chris@0: * An array containing a string and its length. Chris@0: */ Chris@0: public function providerStrlen() { Chris@0: return [ Chris@0: ['tHe QUIcK bRoWn', 15], Chris@0: ['ÜBER-åwesome', 12], Chris@0: ['以呂波耳・ほへとち。リヌルヲ。', 15], Chris@0: ]; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tests multibyte substr. Chris@0: * Chris@0: * @dataProvider providerSubstr Chris@0: * @covers ::substr Chris@17: * @group legacy Chris@17: * @expectedDeprecation \Drupal\Component\Utility\Unicode::substr() is deprecated in Drupal 8.6.0 and will be removed before Drupal 9.0.0. Use mb_substr() instead. See https://www.drupal.org/node/2850048. Chris@0: */ Chris@0: public function testSubstr($text, $start, $length, $expected) { Chris@0: $this->assertEquals($expected, Unicode::substr($text, $start, $length)); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Data provider for testSubstr(). Chris@0: * Chris@0: * @see testSubstr() Chris@0: * Chris@0: * @return array Chris@0: * An array containing: Chris@0: * - The string to test. Chris@0: * - The start number to be processed by substr. Chris@0: * - The length number to be processed by substr. Chris@0: * - The expected string result. Chris@0: */ Chris@0: public function providerSubstr() { Chris@0: return [ Chris@0: ['frànçAIS is über-åwesome', 0, NULL, 'frànçAIS is über-åwesome'], Chris@0: ['frànçAIS is über-åwesome', 0, 0, ''], Chris@0: ['frànçAIS is über-åwesome', 0, 1, 'f'], Chris@0: ['frànçAIS is über-åwesome', 0, 8, 'frànçAIS'], Chris@0: ['frànçAIS is über-åwesome', 0, 23, 'frànçAIS is über-åwesom'], Chris@0: ['frànçAIS is über-åwesome', 0, 24, 'frànçAIS is über-åwesome'], Chris@0: ['frànçAIS is über-åwesome', 0, 25, 'frànçAIS is über-åwesome'], Chris@0: ['frànçAIS is über-åwesome', 0, 100, 'frànçAIS is über-åwesome'], Chris@0: ['frànçAIS is über-åwesome', 4, 4, 'çAIS'], Chris@0: ['frànçAIS is über-åwesome', 1, 0, ''], Chris@0: ['frànçAIS is über-åwesome', 100, 0, ''], Chris@0: ['frànçAIS is über-åwesome', -4, 2, 'so'], Chris@0: ['frànçAIS is über-åwesome', -4, 3, 'som'], Chris@0: ['frànçAIS is über-åwesome', -4, 4, 'some'], Chris@0: ['frànçAIS is über-åwesome', -4, 5, 'some'], Chris@0: ['frànçAIS is über-åwesome', -7, 10, 'åwesome'], Chris@0: ['frànçAIS is über-åwesome', 5, -10, 'AIS is üb'], Chris@0: ['frànçAIS is über-åwesome', 0, -10, 'frànçAIS is üb'], Chris@0: ['frànçAIS is über-åwesome', 0, -1, 'frànçAIS is über-åwesom'], Chris@0: ['frànçAIS is über-åwesome', -7, -2, 'åweso'], Chris@0: ['frànçAIS is über-åwesome', -7, -6, 'å'], Chris@0: ['frànçAIS is über-åwesome', -7, -7, ''], Chris@0: ['frànçAIS is über-åwesome', -7, -8, ''], Chris@0: ['...', 0, 2, '..'], Chris@0: ['以呂波耳・ほへとち。リヌルヲ。', 1, 3, '呂波耳'], Chris@0: ]; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tests multibyte truncate. Chris@0: * Chris@0: * @dataProvider providerTruncate Chris@0: * @covers ::truncate Chris@0: */ Chris@0: public function testTruncate($text, $max_length, $expected, $wordsafe = FALSE, $add_ellipsis = FALSE) { Chris@0: $this->assertEquals($expected, Unicode::truncate($text, $max_length, $wordsafe, $add_ellipsis)); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Data provider for testTruncate(). Chris@0: * Chris@0: * @see testTruncate() Chris@0: * Chris@0: * @return array Chris@0: * An array containing: Chris@0: * - The string to test. Chris@0: * - The max length to truncate this string to. Chris@0: * - The expected string result. Chris@0: * - (optional) Boolean for the $wordsafe flag. Defaults to FALSE. Chris@0: * - (optional) Boolean for the $add_ellipsis flag. Defaults to FALSE. Chris@0: */ Chris@0: public function providerTruncate() { Chris@14: $tests = [ Chris@0: ['frànçAIS is über-åwesome', 24, 'frànçAIS is über-åwesome'], Chris@0: ['frànçAIS is über-åwesome', 23, 'frànçAIS is über-åwesom'], Chris@0: ['frànçAIS is über-åwesome', 17, 'frànçAIS is über-'], Chris@0: ['以呂波耳・ほへとち。リヌルヲ。', 6, '以呂波耳・ほ'], Chris@0: ['frànçAIS is über-åwesome', 24, 'frànçAIS is über-åwesome', FALSE, TRUE], Chris@0: ['frànçAIS is über-åwesome', 23, 'frànçAIS is über-åweso…', FALSE, TRUE], Chris@0: ['frànçAIS is über-åwesome', 17, 'frànçAIS is über…', FALSE, TRUE], Chris@0: ['123', 1, '…', TRUE, TRUE], Chris@0: ['123', 2, '1…', TRUE, TRUE], Chris@0: ['123', 3, '123', TRUE, TRUE], Chris@0: ['1234', 3, '12…', TRUE, TRUE], Chris@0: ['1234567890', 10, '1234567890', TRUE, TRUE], Chris@0: ['12345678901', 10, '123456789…', TRUE, TRUE], Chris@0: ['12345678901', 11, '12345678901', TRUE, TRUE], Chris@0: ['123456789012', 11, '1234567890…', TRUE, TRUE], Chris@0: ['12345 7890', 10, '12345 7890', TRUE, TRUE], Chris@0: ['12345 7890', 9, '12345…', TRUE, TRUE], Chris@0: ['123 567 90', 10, '123 567 90', TRUE, TRUE], Chris@0: ['123 567 901', 10, '123 567…', TRUE, TRUE], Chris@0: ['Stop. Hammertime.', 17, 'Stop. Hammertime.', TRUE, TRUE], Chris@0: ['Stop. Hammertime.', 16, 'Stop…', TRUE, TRUE], Chris@0: ['frànçAIS is über-åwesome', 24, 'frànçAIS is über-åwesome', TRUE, TRUE], Chris@0: ['frànçAIS is über-åwesome', 23, 'frànçAIS is über…', TRUE, TRUE], Chris@0: ['frànçAIS is über-åwesome', 17, 'frànçAIS is über…', TRUE, TRUE], Chris@0: ['¿Dónde está el niño?', 20, '¿Dónde está el niño?', TRUE, TRUE], Chris@0: ['¿Dónde está el niño?', 19, '¿Dónde está el…', TRUE, TRUE], Chris@0: ['¿Dónde está el niño?', 13, '¿Dónde está…', TRUE, TRUE], Chris@0: ['¿Dónde está el niño?', 10, '¿Dónde…', TRUE, TRUE], Chris@0: ['Help! Help! Help!', 17, 'Help! Help! Help!', TRUE, TRUE], Chris@0: ['Help! Help! Help!', 16, 'Help! Help!…', TRUE, TRUE], Chris@0: ['Help! Help! Help!', 15, 'Help! Help!…', TRUE, TRUE], Chris@0: ['Help! Help! Help!', 14, 'Help! Help!…', TRUE, TRUE], Chris@0: ['Help! Help! Help!', 13, 'Help! Help!…', TRUE, TRUE], Chris@0: ['Help! Help! Help!', 12, 'Help! Help!…', TRUE, TRUE], Chris@0: ['Help! Help! Help!', 11, 'Help! Help…', TRUE, TRUE], Chris@0: ['Help! Help! Help!', 10, 'Help!…', TRUE, TRUE], Chris@0: ['Help! Help! Help!', 9, 'Help!…', TRUE, TRUE], Chris@0: ['Help! Help! Help!', 8, 'Help!…', TRUE, TRUE], Chris@0: ['Help! Help! Help!', 7, 'Help!…', TRUE, TRUE], Chris@0: ['Help! Help! Help!', 6, 'Help!…', TRUE, TRUE], Chris@0: ['Help! Help! Help!', 5, 'Help…', TRUE, TRUE], Chris@0: ['Help! Help! Help!', 4, 'Hel…', TRUE, TRUE], Chris@0: ['Help! Help! Help!', 3, 'He…', TRUE, TRUE], Chris@0: ['Help! Help! Help!', 2, 'H…', TRUE, TRUE], Chris@0: ]; Chris@14: Chris@14: // Test truncate on text with multiple lines. Chris@14: $multi_line = <<assertEquals($expected, Unicode::truncateBytes($text, $max_length), 'The string was not correctly truncated.'); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Provides data for self::testTruncateBytes(). Chris@0: * Chris@0: * @return array Chris@0: * An array of arrays, each containing the parameters to Chris@0: * self::testTruncateBytes(). Chris@0: */ Chris@0: public function providerTestTruncateBytes() { Chris@0: return [ Chris@0: // String shorter than max length. Chris@0: ['Short string', 42, 'Short string'], Chris@0: // Simple string longer than max length. Chris@0: ['Longer string than previous.', 10, 'Longer str'], Chris@0: // Unicode. Chris@0: ['以呂波耳・ほへとち。リヌルヲ。', 10, '以呂波'], Chris@0: ]; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tests UTF-8 validation. Chris@0: * Chris@0: * @dataProvider providerTestValidateUtf8 Chris@0: * @covers ::validateUtf8 Chris@0: * Chris@0: * @param string $text Chris@0: * The text to validate. Chris@0: * @param bool $expected Chris@0: * The expected return value from Unicode::validateUtf8(). Chris@0: * @param string $message Chris@0: * The message to display on failure. Chris@0: */ Chris@0: public function testValidateUtf8($text, $expected, $message) { Chris@0: $this->assertEquals($expected, Unicode::validateUtf8($text), $message); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Provides data for self::testValidateUtf8(). Chris@0: * Chris@0: * Invalid UTF-8 examples sourced from http://stackoverflow.com/a/11709412/109119. Chris@0: * Chris@0: * @return array Chris@0: * An array of arrays, each containing the parameters for Chris@0: * self::testValidateUtf8(). Chris@0: */ Chris@0: public function providerTestValidateUtf8() { Chris@0: return [ Chris@0: // Empty string. Chris@0: ['', TRUE, 'An empty string did not validate.'], Chris@0: // Simple text string. Chris@0: ['Simple text.', TRUE, 'A simple ASCII text string did not validate.'], Chris@0: // Invalid UTF-8, overlong 5 byte encoding. Chris@0: [chr(0xF8) . chr(0x80) . chr(0x80) . chr(0x80) . chr(0x80), FALSE, 'Invalid UTF-8 was validated.'], Chris@0: // High code-point without trailing characters. Chris@0: [chr(0xD0) . chr(0x01), FALSE, 'Invalid UTF-8 was validated.'], Chris@0: ]; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tests UTF-8 conversion. Chris@0: * Chris@0: * @dataProvider providerTestConvertToUtf8 Chris@0: * @covers ::convertToUtf8 Chris@0: * Chris@0: * @param string $data Chris@0: * The data to be converted. Chris@0: * @param string $encoding Chris@0: * The encoding the data is in. Chris@0: * @param string|bool $expected Chris@0: * The expected result. Chris@0: */ Chris@0: public function testConvertToUtf8($data, $encoding, $expected) { Chris@0: $this->assertEquals($expected, Unicode::convertToUtf8($data, $encoding)); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Provides data to self::testConvertToUtf8(). Chris@0: * Chris@0: * @return array Chris@0: * An array of arrays, each containing the parameters to Chris@0: * self::testConvertUtf8(). } Chris@0: */ Chris@0: public function providerTestConvertToUtf8() { Chris@0: return [ Chris@0: [chr(0x97), 'Windows-1252', '—'], Chris@0: [chr(0x99), 'Windows-1252', '™'], Chris@0: [chr(0x80), 'Windows-1252', '€'], Chris@0: ]; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tests multibyte strpos. Chris@0: * Chris@0: * @dataProvider providerStrpos Chris@0: * @covers ::strpos Chris@17: * @group legacy Chris@17: * @expectedDeprecation \Drupal\Component\Utility\Unicode::strpos() is deprecated in Drupal 8.6.0 and will be removed before Drupal 9.0.0. Use mb_strpos() instead. See https://www.drupal.org/node/2850048. Chris@0: */ Chris@0: public function testStrpos($haystack, $needle, $offset, $expected) { Chris@0: $this->assertEquals($expected, Unicode::strpos($haystack, $needle, $offset)); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Data provider for testStrpos(). Chris@0: * Chris@0: * @see testStrpos() Chris@0: * Chris@0: * @return array Chris@0: * An array containing: Chris@0: * - The haystack string to be searched in. Chris@0: * - The needle string to search for. Chris@0: * - The offset integer to start at. Chris@0: * - The expected integer/FALSE result. Chris@0: */ Chris@0: public function providerStrpos() { Chris@0: return [ Chris@0: ['frànçAIS is über-åwesome', 'frànçAIS is über-åwesome', 0, 0], Chris@0: ['frànçAIS is über-åwesome', 'rànçAIS is über-åwesome', 0, 1], Chris@0: ['frànçAIS is über-åwesome', 'not in string', 0, FALSE], Chris@0: ['frànçAIS is über-åwesome', 'r', 0, 1], Chris@0: ['frànçAIS is über-åwesome', 'nçAIS', 0, 3], Chris@0: ['frànçAIS is über-åwesome', 'nçAIS', 2, 3], Chris@0: ['frànçAIS is über-åwesome', 'nçAIS', 3, 3], Chris@0: ['以呂波耳・ほへとち。リヌルヲ。', '波耳', 0, 2], Chris@0: ['以呂波耳・ほへとち。リヌルヲ。', '波耳', 1, 2], Chris@0: ['以呂波耳・ほへとち。リヌルヲ。', '波耳', 2, 2], Chris@0: ]; Chris@0: } Chris@0: Chris@0: }