[
{"fn": "utf8Encode", "name": "the empty string", "args": [""], "expect": []},
{"fn": "utf8Encode", "name": "ASCII is one byte per character", "args": ["A"], "expect": [65]},
{"fn": "utf8Encode", "name": "the pound sign takes two bytes", "args": ["£"], "expect": [194, 163]},
{"fn": "utf8Encode", "name": "the euro sign takes three bytes", "args": ["€"], "expect": [226, 130, 172]},
{"fn": "utf8Encode", "name": "RFC 3629 section 7: A, NOT IDENTICAL TO, ALPHA, full stop", "args": ["A≢Α."], "expect": [65, 226, 137, 162, 206, 145, 46]},
{"fn": "utf8Encode", "name": "RFC 3629 section 7: hangugeo, Korean", "args": ["한국어"], "expect": [237, 149, 156, 234, 181, 173, 236, 150, 180]},
{"fn": "utf8Encode", "name": "RFC 3629 section 7: nihongo, Japanese", "args": ["日本語"], "expect": [230, 151, 165, 230, 156, 172, 232, 170, 158]},
{"fn": "utf8Encode", "name": "an emoji outside the BMP is one four-byte sequence, not two surrogates", "args": ["😀"], "expect": [240, 159, 152, 128]},
{"fn": "utf8Encode", "name": "a NUL character is a zero byte", "args": ["a\u0000b"], "expect": [97, 0, 98]},
{"fn": "utf8Encode", "name": "a lone surrogate becomes U+FFFD, as TextEncoder does", "args": ["a\ud800b"], "expect": [97, 239, 191, 189, 98]},
{"fn": "utf8Decode", "name": "no bytes is the empty string", "args": [[]], "expect": ""},
{"fn": "utf8Decode", "name": "RFC 3629 section 7: A, NOT IDENTICAL TO, ALPHA, full stop", "args": [[65, 226, 137, 162, 206, 145, 46]], "expect": "A≢Α."},
{"fn": "utf8Decode", "name": "RFC 3629 section 7: nihongo, Japanese", "args": [[230, 151, 165, 230, 156, 172, 232, 170, 158]], "expect": "日本語"},
{"fn": "utf8Decode", "name": "a four-byte sequence", "args": [[240, 159, 152, 128]], "expect": "😀"},
{"fn": "utf8Decode", "name": "the highest code point, U+10FFFF", "args": [[244, 143, 191, 191]], "expect": ""},
{"fn": "utf8Decode", "name": "a leading byte order mark is kept, not stripped", "args": [[239, 187, 191, 65]], "expect": "A"},
{"fn": "utf8Decode", "name": "an overlong NUL (C0 80) is refused", "args": [[192, 128]], "expectError": "bytes are not valid UTF-8"},
{"fn": "utf8Decode", "name": "an overlong three-byte slash (E0 80 AF) is refused", "args": [[224, 128, 175]], "expectError": "bytes are not valid UTF-8"},
{"fn": "utf8Decode", "name": "an encoded surrogate (ED A0 80) is refused", "args": [[237, 160, 128]], "expectError": "bytes are not valid UTF-8"},
{"fn": "utf8Decode", "name": "a code point above U+10FFFF (F4 90 80 80) is refused", "args": [[244, 144, 128, 128]], "expectError": "bytes are not valid UTF-8"},
{"fn": "utf8Decode", "name": "a truncated euro sign", "args": [[226, 130]], "expectError": "bytes are not valid UTF-8"},
{"fn": "utf8Decode", "name": "a stray continuation byte", "args": [[65, 128]], "expectError": "bytes are not valid UTF-8"},
{"fn": "utf8Decode", "name": "FF never appears in UTF-8", "args": [[255]], "expectError": "bytes are not valid UTF-8"},
{"fn": "utf8Decode", "name": "a value above 255 is not a byte", "args": [[65, 256]], "expectError": "bytes must be a list of integers from 0 to 255"},
{"fn": "utf8Decode", "name": "a fraction is not a byte", "args": [[65.5]], "expectError": "bytes must be a list of integers from 0 to 255"}
]