314 lines
12 KiB
JavaScript
314 lines
12 KiB
JavaScript
description("This test checks the ES6 string functions startsWith(), endsWith(), and includes().");
|
|
|
|
// Test includes
|
|
shouldBe("String.prototype.includes.name", "'includes'");
|
|
shouldBe("String.prototype.includes.length", "1");
|
|
shouldBe("'foo bar'.includes('bar')", "true");
|
|
shouldBe("'foo bar'.includes('bar', 4)", "true");
|
|
shouldBe("'foo bar'.includes('ar', 5)", "true");
|
|
shouldBe("'foo bar'.includes('qux')", "false");
|
|
shouldBe("'foo bar'.includes('foo')", "true");
|
|
shouldBe("'foo bar'.includes('foo', 0)", "true");
|
|
shouldBe("'foo bar'.includes('foo', -1)", "true");
|
|
shouldBe("'foo bar'.includes('')", "true");
|
|
shouldBe("'foo bar'.includes()", "false");
|
|
shouldBe("'foo bar qux'.includes('qux', 7)", "true");
|
|
shouldBe("'foo bar qux'.includes('bar', 7)", "false");
|
|
shouldBe("'foo null bar'.includes()", "false");
|
|
shouldBe("'foo null bar'.includes(null)", "true");
|
|
shouldBe("'foo null bar'.includes(null)", "true");
|
|
shouldBe("'foo undefined bar'.includes()", "true");
|
|
shouldBe("'foo undefined bar'.includes(undefined)", "true");
|
|
shouldBe("'foo undefined bar'.includes()", "true");
|
|
shouldBe("'foo undefined bar'.includes()", "true");
|
|
shouldBe("'foo true bar'.includes(true)", "true");
|
|
shouldBe("'foo false bar'.includes(false)", "true");
|
|
shouldBe("'foo 1 bar'.includes(1)", "true");
|
|
shouldBe("'foo 1.1 bar'.includes(1.1)", "true");
|
|
shouldBe("'foo NaN bar'.includes(NaN)", "true");
|
|
shouldBe("'foo 1.0 bar'.includes(1.0)", "true");
|
|
shouldBe("'foo 1e+100 bar'.includes(1e+100)", "true");
|
|
shouldBe("'foo 1e100 bar'.includes(1e100)", "false");
|
|
shouldBe("'フーバー'.includes('ーバ')", "true");
|
|
shouldBe("'フーバー'.includes('クー')", "false");
|
|
shouldBeFalse("'abc'.includes('a', 'abc'.length)");
|
|
shouldBeFalse("'abc'.includes('a', Math.pow(2, 33))");
|
|
shouldBeFalse("'abc'.includes('a', Infinity)");
|
|
shouldBeTrue("'abc'.includes('ab', -Infinity)");
|
|
shouldBeFalse("'abc'.includes('cd', -Infinity)");
|
|
shouldBeTrue("'abc'.includes('ab', 0)");
|
|
shouldBeFalse("'abc'.includes('cd', 0)");
|
|
|
|
// Test startsWith
|
|
shouldBe("String.prototype.startsWith.name", "'startsWith'");
|
|
shouldBe("String.prototype.startsWith.length", "1");
|
|
shouldBe("'foo bar'.startsWith('foo')", "true");
|
|
shouldBe("'foo bar'.startsWith('foo', 0)", "true");
|
|
shouldBe("'foo bar'.startsWith('foo', -1)", "true");
|
|
shouldBe("'foo bar'.startsWith('oo', 1)", "true");
|
|
shouldBe("'foo bar'.startsWith('qux')", "false");
|
|
shouldBe("'foo bar'.startsWith('')", "true");
|
|
shouldBe("'foo bar'.startsWith()", "false");
|
|
shouldBe("'null'.startsWith()", "false");
|
|
shouldBe("'null'.startsWith(null)", "true");
|
|
shouldBe("'null bar'.startsWith(null)", "true");
|
|
shouldBe("'undefined'.startsWith()", "true");
|
|
shouldBe("'undefined'.startsWith(undefined)", "true");
|
|
shouldBe("'undefined bar'.startsWith()", "true");
|
|
shouldBe("'undefined bar'.startsWith()", "true");
|
|
shouldBe("'true bar'.startsWith(true)", "true");
|
|
shouldBe("'false bar'.startsWith(false)", "true");
|
|
shouldBe("'1 bar'.startsWith(1)", "true");
|
|
shouldBe("'1.1 bar'.startsWith(1.1)", "true");
|
|
shouldBe("'NaN bar'.startsWith(NaN)", "true");
|
|
shouldBe("'1e+100 bar'.startsWith(1e+100)", "true");
|
|
shouldBe("'1e100 bar'.startsWith(1e100)", "false");
|
|
shouldBe("'フーバー'.startsWith('フー')", "true");
|
|
shouldBe("'フーバー'.startsWith('バー')", "false");
|
|
shouldBe("'フーバー'.startsWith('abc')", "false");
|
|
shouldBe("'フーバー'.startsWith('abc', 1)", "false");
|
|
shouldBe("'foo bar'.startsWith('フー')", "false");
|
|
shouldBe("'foo bar'.startsWith('フー', 1)", "false");
|
|
shouldBeFalse("'abc'.startsWith('a', Infinity)");
|
|
shouldBeFalse("'abc'.startsWith('a', 1)");
|
|
shouldBeTrue("'abc'.startsWith('b', 1)");
|
|
shouldBeFalse("'abc'.startsWith('b', 2)");
|
|
shouldBeTrue("'abc'.startsWith('c', 2)");
|
|
shouldBeFalse("'abc'.startsWith('a', Math.pow(2, 33))");
|
|
|
|
// Test endsWith
|
|
shouldBe("String.prototype.endsWith.name", "'endsWith'");
|
|
shouldBe("String.prototype.endsWith.length", "1");
|
|
shouldBe("'foo bar'.endsWith('bar')", "true");
|
|
shouldBe("'foo bar'.endsWith('ba', 6)", "true");
|
|
shouldBe("'foo bar'.endsWith(' ba', 6)", "true");
|
|
shouldBe("'foo bar'.endsWith('foo bar')", "true");
|
|
shouldBe("'foo bar'.endsWith('foo bar', 7)", "true");
|
|
shouldBe("'foo bar'.endsWith('foo bar', 8)", "true");
|
|
shouldBe("'foo bar'.endsWith('foo bar', -1)", "false");
|
|
shouldBe("'foo bar'.endsWith('qux')", "false");
|
|
shouldBe("'foo bar'.endsWith('')", "true");
|
|
shouldBe("'foo bar'.endsWith()", "false");
|
|
shouldBe("'foo null'.endsWith()", "false");
|
|
shouldBe("'foo null'.endsWith(null)", "true");
|
|
shouldBe("'foo null'.endsWith(null)", "true");
|
|
shouldBe("'foo undefined'.endsWith()", "true");
|
|
shouldBe("'foo undefined'.endsWith(undefined)", "true");
|
|
shouldBe("'foo undefined'.endsWith()", "true");
|
|
shouldBe("'foo undefined'.endsWith()", "true");
|
|
shouldBe("'foo true'.endsWith(true)", "true");
|
|
shouldBe("'foo false'.endsWith(false)", "true");
|
|
shouldBe("'foo 1'.endsWith(1)", "true");
|
|
shouldBe("'foo 1.1'.endsWith(1.1)", "true");
|
|
shouldBe("'foo NaN'.endsWith(NaN)", "true");
|
|
shouldBe("'foo 1e+100'.endsWith(1e+100)", "true");
|
|
shouldBe("'foo 1e100'.endsWith(1e100)", "false");
|
|
shouldBe("'フーバー'.endsWith('バー')", "true");
|
|
shouldBe("'フーバー'.endsWith('フー')", "false");
|
|
shouldBe("'フーバー'.endsWith('abc')", "false");
|
|
shouldBe("'フーバー'.endsWith('abc')", "false");
|
|
shouldBe("'foo bar'.endsWith('フー')", "false");
|
|
shouldBe("'foo bar'.endsWith('フー', 3)", "false");
|
|
shouldBeTrue("'abc'.endsWith('bc', Infinity)");
|
|
shouldBeTrue("'abc'.endsWith('bc', Math.pow(2, 33))");
|
|
shouldBeFalse("'abc'.endsWith('a', 0)");
|
|
shouldBeTrue("'abc'.endsWith('a', 1)");
|
|
shouldBeFalse("'abc'.endsWith('b', 1)");
|
|
shouldBeTrue("'abc'.endsWith('b', 2)");
|
|
shouldBeFalse("'abc'.endsWith('bc', 2)");
|
|
shouldBeTrue("'abc'.endsWith('bc', 3)");
|
|
|
|
// Call functions with an environment record as 'this'.
|
|
shouldThrow("(function() { var f = String.prototype.startsWith; (function() { f('a'); })(); })()");
|
|
shouldThrow("(function() { var f = String.prototype.endsWith; (function() { f('a'); })(); })()");
|
|
shouldThrow("(function() { var f = String.prototype.includes; (function() { f('a'); })(); })()");
|
|
|
|
// ES6 spec says a regex as argument should throw an Exception.
|
|
shouldThrow("'foo bar'.startsWith(/\w+/)");
|
|
shouldThrow("'foo bar'.endsWith(/\w+/)");
|
|
shouldThrow("'foo bar'.includes(/\w+/)");
|
|
|
|
// Check side effects in startsWith.
|
|
var sideEffect = "";
|
|
var stringToSearchIn = new String("foo bar");
|
|
stringToSearchIn.toString = function() {
|
|
sideEffect += "A";
|
|
return this;
|
|
}
|
|
var searchString = new String("foo");
|
|
searchString.toString = function() {
|
|
sideEffect += "B";
|
|
return this;
|
|
}
|
|
var startOffset = new Number(0);
|
|
startOffset.valueOf = function() {
|
|
sideEffect += "C";
|
|
return this;
|
|
}
|
|
// Calling stringToSearchIn.startsWith implicitly calls stringToSearchIn.toString(),
|
|
// searchString.toString() and startOffset.valueOf(), in that respective order.
|
|
shouldBe("stringToSearchIn.startsWith(searchString, startOffset)", "true");
|
|
shouldBe("sideEffect == 'ABC'", "true");
|
|
|
|
// If stringToSearchIn throws an exception searchString.toString() and
|
|
// startOffset.valueOf() are not called.
|
|
stringToSearchIn.toString = function() {
|
|
throw "error";
|
|
}
|
|
sideEffect = "";
|
|
shouldThrow("stringToSearchIn.startsWith(searchString, startOffset)", "'error'");
|
|
shouldBe("sideEffect == ''", "true");
|
|
|
|
// If searchString throws an exception stringToSearchIn.toString() is called but
|
|
// startOffset.valueOf() is not.
|
|
stringToSearchIn.toString = function() {
|
|
sideEffect += "A";
|
|
return this;
|
|
}
|
|
searchString.toString = function() {
|
|
throw "error";
|
|
}
|
|
sideEffect = "";
|
|
shouldThrow("stringToSearchIn.startsWith(searchString, startOffset)", "'error'");
|
|
shouldBe("sideEffect == 'A'", "true");
|
|
|
|
// If startOffset.valueOf() throws an exception stringToSearchIn.toString() and
|
|
// searchString.toString() were called.
|
|
stringToSearchIn.toString = function() {
|
|
sideEffect += "A";
|
|
return this;
|
|
}
|
|
searchString.toString = function() {
|
|
sideEffect += "B";
|
|
return this;
|
|
}
|
|
startOffset.valueOf = function() {
|
|
throw "error";
|
|
}
|
|
sideEffect = "";
|
|
shouldThrow("stringToSearchIn.startsWith(searchString, startOffset)", "'error'");
|
|
shouldBe("sideEffect == 'AB'", "true");
|
|
|
|
// Check side effects in endsWith.
|
|
sideEffect = "";
|
|
stringToSearchIn = new String('foo bar');
|
|
stringToSearchIn.toString = function() {
|
|
sideEffect += "A";
|
|
return this;
|
|
}
|
|
searchString = new String('bar');
|
|
searchString.toString = function() {
|
|
sideEffect += "B";
|
|
return this;
|
|
}
|
|
var endOffset = new Number(stringToSearchIn.length);
|
|
endOffset.valueOf = function() {
|
|
sideEffect += "C";
|
|
return this;
|
|
}
|
|
|
|
// Calling stringToSearchIn.endsWith implicitly calls stringToSearchIn.toString(),
|
|
// searchString.toString() and endOffset.valueOf(), in that respective order.
|
|
shouldBe("stringToSearchIn.endsWith(searchString, endOffset)", "true");
|
|
shouldBe("sideEffect == 'ABC'", "true");
|
|
|
|
// If stringToSearchIn throws an exception searchString.toString() and
|
|
// endOffset.valueOf() are not called.
|
|
stringToSearchIn.toString = function() {
|
|
throw "error";
|
|
}
|
|
sideEffect = "";
|
|
shouldThrow("stringToSearchIn.endsWith(searchString, endOffset)", "'error'");
|
|
shouldBe("sideEffect == ''", "true");
|
|
|
|
// If searchString throws an exception stringToSearchIn.toString() is called but
|
|
// endOffset.valueOf() is not.
|
|
stringToSearchIn.toString = function() {
|
|
sideEffect += "A";
|
|
return this;
|
|
}
|
|
searchString.toString = function() {
|
|
throw "error";
|
|
}
|
|
sideEffect = "";
|
|
shouldThrow("stringToSearchIn.endsWith(searchString, endOffset)", "'error'");
|
|
shouldBe("sideEffect == 'A'", "true");
|
|
|
|
// If endOffset.valueOf() throws an exception stringToSearchIn.toString() and
|
|
// searchString.toString() were called.
|
|
stringToSearchIn.toString = function() {
|
|
sideEffect += "A";
|
|
return this;
|
|
}
|
|
searchString.toString = function() {
|
|
sideEffect += "B";
|
|
return this;
|
|
}
|
|
endOffset.valueOf = function() {
|
|
throw "error";
|
|
}
|
|
sideEffect = "";
|
|
shouldThrow("stringToSearchIn.endsWith(searchString, endOffset)", "'error'");
|
|
shouldBe("sideEffect == 'AB'", "true");
|
|
|
|
// Check side effects in includes.
|
|
var sideEffect = "";
|
|
stringToSearchIn = new String("foo bar");
|
|
stringToSearchIn.toString = function() {
|
|
sideEffect += "A";
|
|
return this;
|
|
}
|
|
searchString = new String("foo");
|
|
searchString.toString = function() {
|
|
sideEffect += "B";
|
|
return this;
|
|
}
|
|
var startOffset = new Number(0);
|
|
startOffset.valueOf = function() {
|
|
sideEffect += "C";
|
|
return this;
|
|
}
|
|
// Calling stringToSearchIn.includes implicitly calls stringToSearchIn.toString(),
|
|
// searchString.toString() and startOffset.valueOf(), in that respective order.
|
|
shouldBe("stringToSearchIn.includes(searchString, startOffset)", "true");
|
|
shouldBe("sideEffect == 'ABC'", "true");
|
|
|
|
// If stringToSearchIn throws an exception searchString.toString() and
|
|
// startOffset.valueOf() are not called.
|
|
stringToSearchIn.toString = function() {
|
|
throw "error";
|
|
}
|
|
sideEffect = "";
|
|
shouldThrow("stringToSearchIn.includes(searchString, startOffset)", "'error'");
|
|
shouldBe("sideEffect == ''", "true");
|
|
|
|
// If searchString throws an exception stringToSearchIn.toString() is called but
|
|
// startOffset.valueOf() is not.
|
|
stringToSearchIn.toString = function() {
|
|
sideEffect += "A";
|
|
return this;
|
|
}
|
|
searchString.toString = function() {
|
|
throw "error";
|
|
}
|
|
sideEffect = "";
|
|
shouldThrow("stringToSearchIn.includes(searchString, startOffset)", "'error'");
|
|
shouldBe("sideEffect == 'A'", "true");
|
|
|
|
// If startOffset.valueOf() throws an exception stringToSearchIn.toString() and
|
|
// searchString.toString() were called.
|
|
stringToSearchIn.toString = function() {
|
|
sideEffect += "A";
|
|
return this;
|
|
}
|
|
searchString.toString = function() {
|
|
sideEffect += "B";
|
|
return this;
|
|
}
|
|
startOffset.valueOf = function() {
|
|
throw "error";
|
|
}
|
|
sideEffect = "";
|
|
shouldThrow("stringToSearchIn.includes(searchString, startOffset)", "'error'");
|
|
shouldBe("sideEffect == 'AB'", "true");
|