From f83adad4bd1e2005401fb7791fa86f8cf749908e Mon Sep 17 00:00:00 2001 From: Josh Wolfe Date: Tue, 29 Aug 2017 18:06:37 -0700 Subject: [PATCH] test for String.prototype.indexOf first parameter type coercion --- harness/typeCoercion.js | 61 ++++++++++++++++++- .../indexOf/searchstring-tostring.js | 25 ++++++++ 2 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 test/built-ins/String/prototype/indexOf/searchstring-tostring.js diff --git a/harness/typeCoercion.js b/harness/typeCoercion.js index 7c32a2c8db..296694fcfb 100644 --- a/harness/typeCoercion.js +++ b/harness/typeCoercion.js @@ -129,9 +129,15 @@ function testCoercibleToPrimitiveWithMethod(hint, method, test) { [methodNames[0]]: method, [methodNames[1]]: function() { throw new Test262Error(); }, }); - test({ - [methodNames[1]]: method, - }); + if (hint === "number") { + // The default valueOf returns an object, which is unsuitable. + // The default toString returns a String, which is suitable. + // Therefore this test only works for valueOf falling back to toString. + test({ + // this is toString: + [methodNames[1]]: method, + }); + } // GetMethod: if func is undefined or null, return undefined. test({ @@ -228,3 +234,52 @@ function testNotCoercibleToPrimitive(hint, test) { testUnsuitableMethod(function() { return Object(1); }); testUnsuitableMethod(function() { return {}; }); } + +function testCoercibleToString(test) { + function testPrimitiveValue(value, expectedString) { + test(value, expectedString); + // ToPrimitive + testPrimitiveWrappers(value, "string", function(value) { + test(value, expectedString); + }); + } + + testPrimitiveValue(undefined, "undefined"); + testPrimitiveValue(null, "null"); + testPrimitiveValue(true, "true"); + testPrimitiveValue(false, "false"); + testPrimitiveValue(0, "0"); + testPrimitiveValue(-0, "0"); + testPrimitiveValue(Infinity, "Infinity"); + testPrimitiveValue(-Infinity, "-Infinity"); + testPrimitiveValue(123.456, "123.456"); + testPrimitiveValue(-123.456, "-123.456"); + testPrimitiveValue("", ""); + testPrimitiveValue("foo", "foo"); + + if (typeof BigInt !== "undefined") { + // BigInt -> TypeError + testPrimitiveValue(BigInt(0), "0"); + } + + // toString of a few objects + test([], ""); + test(["foo", "bar"], "foo,bar"); + test({}, "[object Object]"); +} + +function testNotCoercibleToString(test) { + function testPrimitiveValue(value) { + test(TypeError, value); + // ToPrimitive + testPrimitiveWrappers(value, "string", function(value) { + test(TypeError, value); + }); + } + + // Symbol -> TypeError + testPrimitiveValue(Symbol("1")); + + // ToPrimitive + testNotCoercibleToPrimitive("string", test); +} diff --git a/test/built-ins/String/prototype/indexOf/searchstring-tostring.js b/test/built-ins/String/prototype/indexOf/searchstring-tostring.js new file mode 100644 index 0000000000..e2dddda89a --- /dev/null +++ b/test/built-ins/String/prototype/indexOf/searchstring-tostring.js @@ -0,0 +1,25 @@ +// Copyright (C) 2017 Josh Wolfe. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-string.prototype.indexof +description: String.prototype.indexOf type coercion for searchString parameter +info: > + String.prototype.indexOf ( searchString [ , position ] ) + + 3. Let searchStr be ? ToString(searchString). + +includes: [typeCoercion.js] +---*/ + +testCoercibleToString(function(value, expectedString) { + if (expectedString.length === 0) { + assert.sameValue(("x_x_x").indexOf(value), 0); + } else { + assert.sameValue(expectedString.indexOf("\x00"), -1, "sanity check"); + assert.sameValue(("\x00\x00" + expectedString + "\x00\x00").indexOf(value), 2); + } +}); + +testNotCoercibleToString(function(error, value) { + assert.throws(error, function() { "".indexOf(value); }); +});