Source code

Revision control

Copy as Markdown

Other Tools

// |reftest| skip-if(!xulRuntime.shell)
function IsLatin1String(str) {
for (var i = 0; i < str.length; ++i) {
if (str.charCodeAt(i) > 0xff) {
return false;
}
}
return true;
}
function IsTwoByteString(str) {
return !IsLatin1String(str);
}
const latin1Strings = [
// Empty string.
"",
// Single character string.
"a",
"\0",
"\u{80}",
"\u{ff}",
// Inline strings.
"ascii",
"látïñ-¹",
// Too large for inline string storage.
"This is an ASCII string which is too large for inline storage",
"This is a látïñ-¹ string which is too large for inline storage",
];
assertEq(latin1Strings.every(IsLatin1String), true);
const twoByteStrings = [
// Single code point string.
"\u{100}",
"\u{10ffff}",
// Leading two-byte character.
...latin1Strings.map(s => "\u{100}" + s),
// Trailing two-byte character.
...latin1Strings.map(s => s + "\u{100}"),
// Interspersed two-byte character.
...latin1Strings.map(s => s + "\u{100}" + "-"),
...latin1Strings.map(s => "-" + "\u{100}" + s),
];
assertEq(twoByteStrings.every(IsTwoByteString), true);
const unpairedSurrogates = [
// LeadSurrogateMin and LeadSurrogateMax
"\u{D800}",
"\u{DBFF}",
// TrailSurrogateMin and TrailSurrogateMax
"\u{DC00}",
"\u{DFFF}",
];
const strings = [
...latin1Strings,
...twoByteStrings,
// In case we've missed some special cases above.
// (Assumes it doesn't return a string with unpaired surrogates.)
...representativeStringArray(),
];
function toRope(string) {
try {
let rope = newRope(string[0], string.slice(1));
return {rope, filler: ""};
} catch {}
// |newRope| fails if the input is too short. Add some characters to make
// the input large enough.
let filler = "012345678901234567890123456789";
let rope = newRope(string, filler);
return {rope, filler};
}
for (let string of strings) {
assertEq(string.isWellFormed(), true);
assertEq(string.toWellFormed(), string);
// Need at least two characters to make a rope.
if (string.length >= 2) {
let {rope, filler} = toRope(string);
assertEq(rope.isWellFormed(), true);
assertEq(rope.toWellFormed(), string + filler);
}
// Copy the string to create a non-atom string. (Unless |string| is a static string.)
let copy = newString(string);
assertEq(copy.isWellFormed(), true);
assertEq(copy.toWellFormed(), string);
let twoByte = newString(string, {twoByte: true});
assertEq(twoByte.isWellFormed(), true);
assertEq(twoByte.toWellFormed(), string);
}
// Single unpaired surrogates.
for (let unpaired of unpairedSurrogates) {
assertEq(unpaired.isWellFormed(), false);
assertEq(unpaired.toWellFormed(), "\u{FFFD}");
}
// Add unpaired surrogates.
for (let unpaired of unpairedSurrogates.flatMap(unpaired => {
return [
// Single unpaired.
unpaired,
// Two consecutive unpaired.
unpaired + unpaired,
// Two separate unpaired.
unpaired + "-" + unpaired
];
})) {
for (let string of strings.flatMap(string => {
return [
// Leading unpaired.
unpaired + string,
// Trailing unpaired.
string + unpaired,
// Interspersed unpaired.
string + unpaired + "-",
"-" + unpaired + string,
string + unpaired + string,
];
})) {
assertEq(string.isWellFormed(), false);
assertEq(string.toWellFormed() === string, false);
// Need at least two characters to make a rope.
if (string.length >= 2) {
let {rope, filler} = toRope(string);
assertEq(rope.isWellFormed(), false);
assertEq(rope.toWellFormed() === string + filler, false);
}
// Copy the string to create a non-atom string. (Unless |string| is a static string.)
let copy = newString(string);
assertEq(copy.isWellFormed(), false);
assertEq(copy.toWellFormed() === string, false);
}
}
if (typeof reportCompare === "function")
reportCompare(true, true);