Skip to content

Commit

Permalink
Implementing JsonSerializable for Teamspeak3_Helper_String (#101)
Browse files Browse the repository at this point in the history
* Implemented JsonSerializable

* Added unit test for jsonSerialize().

* Encode string to UTF-8 for JSON compliance

* Utf8 unit test includes boundary condition tests
  • Loading branch information
snegrini authored and ronindesign committed Sep 7, 2018
1 parent 0e31711 commit 69ef579
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 5 deletions.
12 changes: 11 additions & 1 deletion libraries/TeamSpeak3/Helper/String.php
Expand Up @@ -26,7 +26,7 @@
* @class TeamSpeak3_Helper_String
* @brief Helper class for string handling.
*/
class TeamSpeak3_Helper_String implements ArrayAccess, Iterator, Countable
class TeamSpeak3_Helper_String implements ArrayAccess, Iterator, Countable, JsonSerializable
{
/**
* Stores the original string.
Expand Down Expand Up @@ -850,6 +850,16 @@ public function __toString()
return (string) $this->string;
}

/**
* Return UTF-8 encoded string to for serializing to JSON.
*
* @return string
*/
public function jsonSerialize()
{
return $this->toUtf8()->string;
}

/**
* @ignore
*/
Expand Down
89 changes: 85 additions & 4 deletions tests/Unit/Helper/StringTest.php
Expand Up @@ -178,15 +178,86 @@ public function testIsUtf8()
$string = new \TeamSpeak3_Helper_String(utf8_encode("Äpfel"));
$this->assertTrue($string->isUtf8());

$string = new \TeamSpeak3_Helper_String(utf8_decode("Äpfel"));
$this->assertNotTrue($string->isUtf8());
// Well-formed UTF-8 Byte Sequences
// Ref: Unicode (v11.0.0) - §3.9 Unicode Encoding Forms (126, table 3-7)
// https://www.unicode.org/versions/Unicode11.0.0/ch03.pdf#page=55
$unicodeBoundaries = [
// Ignoring first set (ASCII) as isUtf8() does not use it.
//[[0x00],[0x7F]], // U+0000..U+007F
[[0xC2,0x80], [0xDF,0xBF]], // U+0080..U+07FF
[[0xE0,0xA0,0x80], [0xE0,0xBF,0xBF]], // U+0800..U+0FFF
[[0xE1,0x80,0x80], [0xEC,0xBF,0xBF]], // U+1000..U+CFFF
[[0xED,0x80,0x80], [0xED,0x9F,0xBF]], // U+D000..U+D7FF
[[0xEE,0x80,0x80], [0xEF,0xBF,0xBF]], // U+E000..U+FFFF
[[0xF0,0x90,0x80,0x80], [0xF0,0xEF,0xBF,0xBF]], // U+10000..U+3FFFF
[[0xF1,0x80,0x80,0x80], [0xF3,0xBF,0xBF,0xBF]], // U+40000..U+FFFFF
[[0xF4,0x80,0x80,0x80], [0xF4,0x8F,0xBF,0xBF]] // U+100000..U+10FFFF
];

// Lower character precedes lower unicode boundary.
// Upper character follows upper unicode boundary.
$unicodeBoundariesMalformed = [
[[0x80],[0xFF]],
[[0xC2,0x7F], [0xDF,0xC0]],
[[0xE0,0xA0,0x7F], [0xE0,0xBF,0xC0]],
[[0xE1,0x80,0x7F], [0xEC,0xBF,0xC0]],
[[0xED,0x80,0x7F], [0xED,0x9F,0xC0]],
[[0xEE,0x80,0x7F], [0xEF,0xBF,0xC0]],
[[0xF0,0x90,0x80,0x7F], [0xF0,0xEF,0xBF,0xC0]],
[[0xF1,0x80,0x80,0x7F], [0xF3,0xBF,0xBF,0xC0]],
[[0xF4,0x80,0x80,0x7F], [0xF4,0x8F,0xBF,0xC0]]
];

foreach($unicodeBoundaries as $boundary) {
$lowerUtf8MultibyteChar = new \TeamSpeak3_Helper_String(array_reduce(
$boundary[0],
function($mb_string, $item) {
$mb_string .= chr($item);
return $mb_string;
}
));
$this->assertTrue($lowerUtf8MultibyteChar->isUtf8());
$upperUtf8MultibyteChar = new \TeamSpeak3_Helper_String(array_reduce(
$boundary[1],
function($mb_string, $item) {
//var_dump($item);
$mb_string .= chr($item);
return $mb_string;
}
));
$this->assertTrue($upperUtf8MultibyteChar->isUtf8());
}

foreach($unicodeBoundariesMalformed as $boundary) {
$lowerUtf8MultibyteChar = new \TeamSpeak3_Helper_String(array_reduce(
$boundary[0],
function($mb_string, $item) {
$mb_string .= chr($item);
return $mb_string;
}
));
$this->assertNotTrue($lowerUtf8MultibyteChar->isUtf8());
$upperUtf8MultibyteChar = new \TeamSpeak3_Helper_String(array_reduce(
$boundary[1],
function($mb_string, $item) {
//var_dump($item);
$mb_string .= chr($item);
return $mb_string;
}
));
$this->assertNotTrue($upperUtf8MultibyteChar->isUtf8());
}
}

public function testToUft8()
{
$notUtf8 = utf8_decode("Äpfel");
$string = new \TeamSpeak3_Helper_String($notUtf8);
$this->assertEquals(utf8_encode($notUtf8), $string->toUtf8());
$stringNotUtf8 = new \TeamSpeak3_Helper_String($notUtf8);
$this->assertEquals(utf8_encode($notUtf8), $stringNotUtf8->toUtf8()->toString());

$notUtf8 = utf8_decode("");
$stringNotUtf8 = new \TeamSpeak3_Helper_String($notUtf8);
$this->assertEquals(utf8_encode($notUtf8), $stringNotUtf8->toUtf8()->toString());
}

public function testToBase64()
Expand Down Expand Up @@ -444,4 +515,14 @@ public function testSpaceToPercent()
$string = new \TeamSpeak3_Helper_String("Hello world!");
$this->assertEquals("Hello%20world!", $string->spaceToPercent());
}

public function testJsonSerialize()
{
$string = new \TeamSpeak3_Helper_String("Hello world!");

$this->assertJsonStringEqualsJsonString(
json_encode(["a" => $string]),
json_encode(["a" => "Hello world!"])
);
}
}

0 comments on commit 69ef579

Please sign in to comment.