blob: 1ae22ec71620b4cdc716f849f90e404c9ea3b816 [file] [log] [blame]
function shouldBe(actual, expected) {
if (actual !== expected)
throw new Error("bad value: " + String(actual));
}
function shouldThrow(func, message) {
var error = null;
try {
func();
} catch (e) {
error = e;
}
if (!error)
throw new Error("not thrown.");
if (String(error) !== message)
throw new Error("bad error: " + String(error));
}
function toCodePoints(string) {
var result = [];
for (var codePoint of string) {
result.push(codePoint.codePointAt(0));
}
return result;
}
shouldBe(String.fromCodePoint(), "");
shouldBe(String.fromCodePoint(0), "\0");
shouldBe(String.fromCodePoint(0, 0), "\0\0");
var tests = [
"",
"Hello",
"Cocoa",
"Cappuccino Cocoa",
"日本語",
"マルチバイト",
"吉野屋",
"𠮷野家", // Contain a surrogate pair.
];
for (var test of tests) {
shouldBe(String.fromCodePoint.apply(String, toCodePoints(test)), test);
}
function passThrough(codePoint) {
var string = String.fromCodePoint(codePoint);
shouldBe(string.codePointAt(0), codePoint);
}
var numberTests = [
[ 0x10FFFF, "\uDBFF\uDFFF" ],
[ 0x10FFFE, "\uDBFF\uDFFE" ],
[ 0xFFFF, "\uFFFF" ],
[ 0x10000, "\uD800\uDC00" ],
[ 0x10001, "\uD800\uDC01" ],
[ -0.0, "\u0000" ],
[ 0xD800, "\uD800" ],
[ 0xDC00, "\uDC00" ],
];
for (var test of numberTests) {
shouldBe(String.fromCodePoint(test[0]), test[1]);
}
shouldBe(String.fromCodePoint(0xD800, 0xDC00).codePointAt(0), 0x10000);
// Non-character code points.
for (var i = 0; i < 17; ++i) {
var plane = 0x10000 * i;
passThrough(plane + 0xFFFE);
passThrough(plane + 0xFFFF);
}
for (var start = 0xFDD0; start <= 0xFDEF; ++start) {
passThrough(start);
}
var invalidTests = [
-1,
1.2,
1.5,
30.01,
-11.0,
NaN,
Number.Infinity,
-Number.Infinity,
0x10FFFF + 1,
0x7FFFFFFF,
0x7FFFFFFF + 1,
0xFFFFFFFF,
0xFFFFFFFF + 1,
0x100000000 + 32, // String.fromCharCode(0x100000000 + 32) produces a space, but String.fromCodePoint should throw an error.
"Hello",
undefined,
{},
];
for (var test of invalidTests) {
shouldThrow(function () {
String.fromCodePoint(test);
}, "RangeError: Arguments contain a value that is out of range of code points");
}
// toNumber causes errors.
shouldThrow(function () {
String.fromCodePoint(Symbol.iterator);
}, "TypeError: Cannot convert a symbol to a number")
var toNumberObject = {
valueOf() {
throw new Error("valueOf is called");
}
};
shouldThrow(function () {
String.fromCodePoint(toNumberObject);
}, "Error: valueOf is called")
shouldThrow(function () {
String.fromCodePoint(Symbol.iterator, toNumberObject);
}, "TypeError: Cannot convert a symbol to a number")
var convertAndPassTests = [
[ null, "\0" ],
[ [], "\0" ],
[ "0x41", "A" ],
[ "", "\0" ],
[ true, "\u0001" ],
[ false, "\u0000" ],
];
for (var test of convertAndPassTests) {
shouldBe(String.fromCodePoint(test[0]), test[1]);
}