blob: 1ae22ec71620b4cdc716f849f90e404c9ea3b816 [file] [log] [blame]
utatane.tea@gmail.comd19d59c2015-04-25 22:00:51 +00001function shouldBe(actual, expected) {
2 if (actual !== expected)
3 throw new Error("bad value: " + String(actual));
4}
5
6function shouldThrow(func, message) {
7 var error = null;
8 try {
9 func();
10 } catch (e) {
11 error = e;
12 }
13 if (!error)
14 throw new Error("not thrown.");
15 if (String(error) !== message)
16 throw new Error("bad error: " + String(error));
17}
18
19function toCodePoints(string) {
20 var result = [];
21 for (var codePoint of string) {
22 result.push(codePoint.codePointAt(0));
23 }
24 return result;
25}
26
27shouldBe(String.fromCodePoint(), "");
28shouldBe(String.fromCodePoint(0), "\0");
29shouldBe(String.fromCodePoint(0, 0), "\0\0");
30
31var tests = [
32 "",
33 "Hello",
34 "Cocoa",
35 "Cappuccino Cocoa",
36 "日本語",
37 "マルチバイト",
38 "吉野屋",
39 "𠮷野家", // Contain a surrogate pair.
40];
41
42for (var test of tests) {
43 shouldBe(String.fromCodePoint.apply(String, toCodePoints(test)), test);
44}
45
46function passThrough(codePoint) {
47 var string = String.fromCodePoint(codePoint);
48 shouldBe(string.codePointAt(0), codePoint);
49}
50
51var numberTests = [
52 [ 0x10FFFF, "\uDBFF\uDFFF" ],
53 [ 0x10FFFE, "\uDBFF\uDFFE" ],
54 [ 0xFFFF, "\uFFFF" ],
55 [ 0x10000, "\uD800\uDC00" ],
56 [ 0x10001, "\uD800\uDC01" ],
57 [ -0.0, "\u0000" ],
58 [ 0xD800, "\uD800" ],
59 [ 0xDC00, "\uDC00" ],
60];
61
62for (var test of numberTests) {
63 shouldBe(String.fromCodePoint(test[0]), test[1]);
64}
65
66shouldBe(String.fromCodePoint(0xD800, 0xDC00).codePointAt(0), 0x10000);
67
68// Non-character code points.
69for (var i = 0; i < 17; ++i) {
70 var plane = 0x10000 * i;
71 passThrough(plane + 0xFFFE);
72 passThrough(plane + 0xFFFF);
73}
74
75for (var start = 0xFDD0; start <= 0xFDEF; ++start) {
76 passThrough(start);
77}
78
79var invalidTests = [
80 -1,
81 1.2,
82 1.5,
83 30.01,
84 -11.0,
85 NaN,
86 Number.Infinity,
87 -Number.Infinity,
88 0x10FFFF + 1,
89 0x7FFFFFFF,
90 0x7FFFFFFF + 1,
91 0xFFFFFFFF,
92 0xFFFFFFFF + 1,
93 0x100000000 + 32, // String.fromCharCode(0x100000000 + 32) produces a space, but String.fromCodePoint should throw an error.
94 "Hello",
95 undefined,
96 {},
97];
98
99for (var test of invalidTests) {
100 shouldThrow(function () {
101 String.fromCodePoint(test);
102 }, "RangeError: Arguments contain a value that is out of range of code points");
103}
104
105// toNumber causes errors.
106shouldThrow(function () {
107 String.fromCodePoint(Symbol.iterator);
utatane.tea@gmail.com5d80e952016-05-04 01:21:38 +0000108}, "TypeError: Cannot convert a symbol to a number")
utatane.tea@gmail.comd19d59c2015-04-25 22:00:51 +0000109
110var toNumberObject = {
111 valueOf() {
112 throw new Error("valueOf is called");
113 }
114};
115
116shouldThrow(function () {
117 String.fromCodePoint(toNumberObject);
118}, "Error: valueOf is called")
119
120shouldThrow(function () {
121 String.fromCodePoint(Symbol.iterator, toNumberObject);
utatane.tea@gmail.com5d80e952016-05-04 01:21:38 +0000122}, "TypeError: Cannot convert a symbol to a number")
utatane.tea@gmail.comd19d59c2015-04-25 22:00:51 +0000123
124var convertAndPassTests = [
125 [ null, "\0" ],
126 [ [], "\0" ],
127 [ "0x41", "A" ],
128 [ "", "\0" ],
129 [ true, "\u0001" ],
130 [ false, "\u0000" ],
131];
132
133for (var test of convertAndPassTests) {
134 shouldBe(String.fromCodePoint(test[0]), test[1]);
135}