summaryrefslogtreecommitdiff
path: root/test/built-ins/String
diff options
context:
space:
mode:
Diffstat (limited to 'test/built-ins/String')
-rw-r--r--test/built-ins/String/prototype/indexOf/position-tointeger-bigint.js39
-rw-r--r--test/built-ins/String/prototype/indexOf/position-tointeger-errors.js39
-rw-r--r--test/built-ins/String/prototype/indexOf/position-tointeger-toprimitive.js165
-rw-r--r--test/built-ins/String/prototype/indexOf/position-tointeger-wrapped-values.js109
-rw-r--r--test/built-ins/String/prototype/indexOf/position-tointeger.js48
-rw-r--r--test/built-ins/String/prototype/indexOf/searchstring-tostring-bigint.js31
-rw-r--r--test/built-ins/String/prototype/indexOf/searchstring-tostring-errors.js40
-rw-r--r--test/built-ins/String/prototype/indexOf/searchstring-tostring-toprimitive.js161
-rw-r--r--test/built-ins/String/prototype/indexOf/searchstring-tostring-wrapped-values.js98
-rw-r--r--test/built-ins/String/prototype/indexOf/searchstring-tostring.js35
10 files changed, 728 insertions, 37 deletions
diff --git a/test/built-ins/String/prototype/indexOf/position-tointeger-bigint.js b/test/built-ins/String/prototype/indexOf/position-tointeger-bigint.js
new file mode 100644
index 000000000..c4e98a007
--- /dev/null
+++ b/test/built-ins/String/prototype/indexOf/position-tointeger-bigint.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2017 Josh Wolfe. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: String.prototype.indexOf type coercion for position parameter
+esid: sec-string.prototype.indexof
+info: |
+ String.prototype.indexOf ( searchString [ , position ] )
+
+ 4. Let pos be ? ToInteger(position).
+features: [BigInt, Symbol.toPrimitive, computed-property-names]
+---*/
+
+assert.throws(TypeError, function() {
+ "".indexOf("", 0n);
+}, "ToInteger: BigInt => TypeError");
+assert.throws(TypeError, function() {
+ "".indexOf("", Object(0n));
+}, "ToInteger: unbox object with internal slot => BigInt => TypeError");
+assert.throws(TypeError, function() {
+ "".indexOf("", {
+ [Symbol.toPrimitive]: function() {
+ return 0n;
+ }
+ });
+}, "ToInteger: @@toPrimitive => BigInt => TypeError");
+assert.throws(TypeError, function() {
+ "".indexOf("", {
+ valueOf: function() {
+ return 0n;
+ }
+ });
+}, "ToInteger: valueOf => BigInt => TypeError");
+assert.throws(TypeError, function() {
+ "".indexOf("", {
+ toString: function() {
+ return 0n;
+ }
+ });
+}, "ToInteger: toString => BigInt => TypeError");
diff --git a/test/built-ins/String/prototype/indexOf/position-tointeger-errors.js b/test/built-ins/String/prototype/indexOf/position-tointeger-errors.js
new file mode 100644
index 000000000..b3ee4e7d8
--- /dev/null
+++ b/test/built-ins/String/prototype/indexOf/position-tointeger-errors.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2017 Josh Wolfe. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: String.prototype.indexOf type coercion for position parameter
+esid: sec-string.prototype.indexof
+info: |
+ String.prototype.indexOf ( searchString [ , position ] )
+
+ 4. Let pos be ? ToInteger(position).
+features: [Symbol, Symbol.toPrimitive, computed-property-names]
+---*/
+
+assert.throws(TypeError, function() {
+ "".indexOf("", Symbol("1"));
+}, "ToInteger: Symbol => TypeError");
+assert.throws(TypeError, function() {
+ "".indexOf("", Object(Symbol("1")));
+}, "ToInteger: unbox object with internal slot => Symbol => TypeError");
+assert.throws(TypeError, function() {
+ "".indexOf("", {
+ [Symbol.toPrimitive]: function() {
+ return Symbol("1");
+ }
+ });
+}, "ToInteger: @@toPrimitive => Symbol => TypeError");
+assert.throws(TypeError, function() {
+ "".indexOf("", {
+ valueOf: function() {
+ return Symbol("1");
+ }
+ });
+}, "ToInteger: valueOf => Symbol => TypeError");
+assert.throws(TypeError, function() {
+ "".indexOf("", {
+ toString: function() {
+ return Symbol("1");
+ }
+ });
+}, "ToInteger: toString => Symbol => TypeError");
diff --git a/test/built-ins/String/prototype/indexOf/position-tointeger-toprimitive.js b/test/built-ins/String/prototype/indexOf/position-tointeger-toprimitive.js
new file mode 100644
index 000000000..6da0c861e
--- /dev/null
+++ b/test/built-ins/String/prototype/indexOf/position-tointeger-toprimitive.js
@@ -0,0 +1,165 @@
+// Copyright (C) 2017 Josh Wolfe. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: String.prototype.indexOf type coercion for position parameter
+esid: sec-string.prototype.indexof
+info: |
+ String.prototype.indexOf ( searchString [ , position ] )
+
+ 4. Let pos be ? ToInteger(position).
+features: [Symbol.toPrimitive, computed-property-names]
+---*/
+
+function err() {
+ throw new Test262Error();
+}
+
+function MyError() {}
+
+assert.sameValue("aaaa".indexOf("aa", {
+ [Symbol.toPrimitive]: function() {
+ return 1;
+ },
+ valueOf: err,
+ toString: err
+}), 1, "ToPrimitive: @@toPrimitive takes precedence");
+assert.sameValue("aaaa".indexOf("aa", {
+ valueOf: function() {
+ return 1;
+ },
+ toString: err
+}), 1, "ToPrimitive: valueOf takes precedence over toString");
+assert.sameValue("aaaa".indexOf("aa", {
+ toString: function() {
+ return 1;
+ }
+}), 1, "ToPrimitive: toString with no valueOf");
+assert.sameValue("aaaa".indexOf("aa", {
+ [Symbol.toPrimitive]: undefined,
+ valueOf: function() {
+ return 1;
+ }
+}), 1, "ToPrimitive: skip @@toPrimitive when it's undefined");
+assert.sameValue("aaaa".indexOf("aa", {
+ [Symbol.toPrimitive]: null,
+ valueOf: function() {
+ return 1;
+ }
+}), 1, "ToPrimitive: skip @@toPrimitive when it's null");
+assert.sameValue("aaaa".indexOf("aa", {
+ valueOf: null,
+ toString: function() {
+ return 1;
+ }
+}), 1, "ToPrimitive: skip valueOf when it's not callable");
+assert.sameValue("aaaa".indexOf("aa", {
+ valueOf: 1,
+ toString: function() {
+ return 1;
+ }
+}), 1, "ToPrimitive: skip valueOf when it's not callable");
+assert.sameValue("aaaa".indexOf("aa", {
+ valueOf: {},
+ toString: function() {
+ return 1;
+ }
+}), 1, "ToPrimitive: skip valueOf when it's not callable");
+assert.sameValue("aaaa".indexOf("aa", {
+ valueOf: function() {
+ return {};
+ },
+ toString: function() {
+ return 1;
+ }
+}), 1, "ToPrimitive: skip valueOf when it returns an object");
+assert.sameValue("aaaa".indexOf("aa", {
+ valueOf: function() {
+ return Object(12345);
+ },
+ toString: function() {
+ return 1;
+ }
+}), 1, "ToPrimitive: skip valueOf when it returns an object");
+assert.throws(TypeError, function() {
+ "".indexOf("", {
+ [Symbol.toPrimitive]: 1
+ });
+}, "ToPrimitive: throw when @@toPrimitive is not callable");
+assert.throws(TypeError, function() {
+ "".indexOf("", {
+ [Symbol.toPrimitive]: {}
+ });
+}, "ToPrimitive: throw when @@toPrimitive is not callable");
+assert.throws(TypeError, function() {
+ "".indexOf("", {
+ [Symbol.toPrimitive]: function() {
+ return Object(1);
+ }
+ });
+}, "ToPrimitive: throw when @@toPrimitive returns an object");
+assert.throws(TypeError, function() {
+ "".indexOf("", {
+ [Symbol.toPrimitive]: function() {
+ return {};
+ }
+ });
+}, "ToPrimitive: throw when @@toPrimitive returns an object");
+assert.throws(MyError, function() {
+ "".indexOf("", {
+ [Symbol.toPrimitive]: function() {
+ throw new MyError();
+ }
+ });
+}, "ToPrimitive: propagate errors from @@toPrimitive");
+assert.throws(MyError, function() {
+ "".indexOf("", {
+ valueOf: function() {
+ throw new MyError();
+ }
+ });
+}, "ToPrimitive: propagate errors from valueOf");
+assert.throws(MyError, function() {
+ "".indexOf("", {
+ toString: function() {
+ throw new MyError();
+ }
+ });
+}, "ToPrimitive: propagate errors from toString");
+assert.throws(TypeError, function() {
+ "".indexOf("", {
+ valueOf: null,
+ toString: null
+ });
+}, "ToPrimitive: throw when skipping both valueOf and toString");
+assert.throws(TypeError, function() {
+ "".indexOf("", {
+ valueOf: 1,
+ toString: 1
+ });
+}, "ToPrimitive: throw when skipping both valueOf and toString");
+assert.throws(TypeError, function() {
+ "".indexOf("", {
+ valueOf: {},
+ toString: {}
+ });
+}, "ToPrimitive: throw when skipping both valueOf and toString");
+assert.throws(TypeError, function() {
+ "".indexOf("", {
+ valueOf: function() {
+ return Object(1);
+ },
+ toString: function() {
+ return Object(1);
+ }
+ });
+}, "ToPrimitive: throw when skipping both valueOf and toString");
+assert.throws(TypeError, function() {
+ "".indexOf("", {
+ valueOf: function() {
+ return {};
+ },
+ toString: function() {
+ return {};
+ }
+ });
+}, "ToPrimitive: throw when skipping both valueOf and toString");
diff --git a/test/built-ins/String/prototype/indexOf/position-tointeger-wrapped-values.js b/test/built-ins/String/prototype/indexOf/position-tointeger-wrapped-values.js
new file mode 100644
index 000000000..5ba833061
--- /dev/null
+++ b/test/built-ins/String/prototype/indexOf/position-tointeger-wrapped-values.js
@@ -0,0 +1,109 @@
+// Copyright (C) 2017 Josh Wolfe. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: String.prototype.indexOf type coercion for position parameter
+esid: sec-string.prototype.indexof
+info: |
+ String.prototype.indexOf ( searchString [ , position ] )
+
+ 4. Let pos be ? ToInteger(position).
+features: [Symbol.toPrimitive, computed-property-names]
+---*/
+
+assert.sameValue("aaaa".indexOf("aa", Object(0)), 0, "ToPrimitive: unbox object with internal slot");
+assert.sameValue("aaaa".indexOf("aa", {
+ [Symbol.toPrimitive]: function() {
+ return 0;
+ }
+}), 0, "ToPrimitive: @@toPrimitive");
+assert.sameValue("aaaa".indexOf("aa", {
+ valueOf: function() {
+ return 0;
+ }
+}), 0, "ToPrimitive: valueOf");
+assert.sameValue("aaaa".indexOf("aa", {
+ toString: function() {
+ return 0;
+ }
+}), 0, "ToPrimitive: toString");
+assert.sameValue("aaaa".indexOf("aa", Object(NaN)), 0,
+ "ToInteger: unbox object with internal slot => NaN => 0");
+assert.sameValue("aaaa".indexOf("aa", {
+ [Symbol.toPrimitive]: function() {
+ return NaN;
+ }
+}), 0, "ToInteger: @@toPrimitive => NaN => 0");
+assert.sameValue("aaaa".indexOf("aa", {
+ valueOf: function() {
+ return NaN;
+ }
+}), 0, "ToInteger: valueOf => NaN => 0");
+assert.sameValue("aaaa".indexOf("aa", {
+ toString: function() {
+ return NaN;
+ }
+}), 0, "ToInteger: toString => NaN => 0");
+assert.sameValue("aaaa".indexOf("aa", {
+ [Symbol.toPrimitive]: function() {
+ return undefined;
+ }
+}), 0, "ToInteger: @@toPrimitive => undefined => NaN => 0");
+assert.sameValue("aaaa".indexOf("aa", {
+ valueOf: function() {
+ return undefined;
+ }
+}), 0, "ToInteger: valueOf => undefined => NaN => 0");
+assert.sameValue("aaaa".indexOf("aa", {
+ toString: function() {
+ return undefined;
+ }
+}), 0, "ToInteger: toString => undefined => NaN => 0");
+assert.sameValue("aaaa".indexOf("aa", {
+ [Symbol.toPrimitive]: function() {
+ return null;
+ }
+}), 0, "ToInteger: @@toPrimitive => null => 0");
+assert.sameValue("aaaa".indexOf("aa", {
+ valueOf: function() {
+ return null;
+ }
+}), 0, "ToInteger: valueOf => null => 0");
+assert.sameValue("aaaa".indexOf("aa", {
+ toString: function() {
+ return null;
+ }
+}), 0, "ToInteger: toString => null => 0");
+assert.sameValue("aaaa".indexOf("aa", Object(true)), 1,
+ "ToInteger: unbox object with internal slot => true => 1");
+assert.sameValue("aaaa".indexOf("aa", {
+ [Symbol.toPrimitive]: function() {
+ return true;
+ }
+}), 1, "ToInteger: @@toPrimitive => true => 1");
+assert.sameValue("aaaa".indexOf("aa", {
+ valueOf: function() {
+ return true;
+ }
+}), 1, "ToInteger: valueOf => true => 1");
+assert.sameValue("aaaa".indexOf("aa", {
+ toString: function() {
+ return true;
+ }
+}), 1, "ToInteger: toString => true => 1");
+assert.sameValue("aaaa".indexOf("aa", Object("1.9")), 1,
+ "ToInteger: unbox object with internal slot => parse Number => 1.9 => 1");
+assert.sameValue("aaaa".indexOf("aa", {
+ [Symbol.toPrimitive]: function() {
+ return "1.9";
+ }
+}), 1, "ToInteger: @@toPrimitive => parse Number => 1.9 => 1");
+assert.sameValue("aaaa".indexOf("aa", {
+ valueOf: function() {
+ return "1.9";
+ }
+}), 1, "ToInteger: valueOf => parse Number => 1.9 => 1");
+assert.sameValue("aaaa".indexOf("aa", {
+ toString: function() {
+ return "1.9";
+ }
+}), 1, "ToInteger: toString => parse Number => 1.9 => 1");
diff --git a/test/built-ins/String/prototype/indexOf/position-tointeger.js b/test/built-ins/String/prototype/indexOf/position-tointeger.js
index 0bd2f1352..e6118544b 100644
--- a/test/built-ins/String/prototype/indexOf/position-tointeger.js
+++ b/test/built-ins/String/prototype/indexOf/position-tointeger.js
@@ -1,29 +1,37 @@
// 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 position parameter
-info: >
+esid: sec-string.prototype.indexof
+info: |
String.prototype.indexOf ( searchString [ , position ] )
4. Let pos be ? ToInteger(position).
-
-includes: [typeCoercion.js]
-features: [BigInt, Symbol.toPrimitive]
---*/
-testCoercibleToIntegerZero(function(zero) {
- assert.sameValue("aaaa".indexOf("aa", zero), 0);
-});
-
-testCoercibleToIntegerOne(function(one) {
- assert.sameValue("aaaa".indexOf("aa", one), 1);
-});
-
-testCoercibleToIntegerFromInteger(2, function(two) {
- assert.sameValue("aaaa".indexOf("aa", two), 2);
-});
-
-testNotCoercibleToInteger(function(error, value) {
- assert.throws(error, function() { "".indexOf("", value); });
-});
+assert.sameValue("aaaa".indexOf("aa", 0), 0);
+assert.sameValue("aaaa".indexOf("aa", 1), 1);
+assert.sameValue("aaaa".indexOf("aa", -0.9), 0, "ToInteger: truncate towards 0");
+assert.sameValue("aaaa".indexOf("aa", 0.9), 0, "ToInteger: truncate towards 0");
+assert.sameValue("aaaa".indexOf("aa", 1.9), 1, "ToInteger: truncate towards 0");
+assert.sameValue("aaaa".indexOf("aa", NaN), 0, "ToInteger: NaN => 0");
+assert.sameValue("aaaa".indexOf("aa", Infinity), -1);
+assert.sameValue("aaaa".indexOf("aa", undefined), 0, "ToInteger: undefined => NaN => 0");
+assert.sameValue("aaaa".indexOf("aa", null), 0, "ToInteger: null => 0");
+assert.sameValue("aaaa".indexOf("aa", false), 0, "ToInteger: false => 0");
+assert.sameValue("aaaa".indexOf("aa", true), 1, "ToInteger: true => 1");
+assert.sameValue("aaaa".indexOf("aa", "0"), 0, "ToInteger: parse Number");
+assert.sameValue("aaaa".indexOf("aa", "1.9"), 1, "ToInteger: parse Number => 1.9 => 1");
+assert.sameValue("aaaa".indexOf("aa", "Infinity"), -1, "ToInteger: parse Number");
+assert.sameValue("aaaa".indexOf("aa", ""), 0, "ToInteger: unparseable string => NaN => 0");
+assert.sameValue("aaaa".indexOf("aa", "foo"), 0, "ToInteger: unparseable string => NaN => 0");
+assert.sameValue("aaaa".indexOf("aa", "true"), 0, "ToInteger: unparseable string => NaN => 0");
+assert.sameValue("aaaa".indexOf("aa", 2), 2);
+assert.sameValue("aaaa".indexOf("aa", "2"), 2, "ToInteger: parse Number");
+assert.sameValue("aaaa".indexOf("aa", 2.9), 2, "ToInteger: truncate towards 0");
+assert.sameValue("aaaa".indexOf("aa", "2.9"), 2, "ToInteger: parse Number => truncate towards 0");
+assert.sameValue("aaaa".indexOf("aa", [0]), 0, 'ToInteger: [0].toString() => "0" => 0');
+assert.sameValue("aaaa".indexOf("aa", ["1"]), 1, 'ToInteger: ["1"].toString() => "1" => 1');
+assert.sameValue("aaaa".indexOf("aa", {}), 0,
+ 'ToInteger: ({}).toString() => "[object Object]" => NaN => 0');
+assert.sameValue("aaaa".indexOf("aa", []), 0, 'ToInteger: [].toString() => "" => NaN => 0');
diff --git a/test/built-ins/String/prototype/indexOf/searchstring-tostring-bigint.js b/test/built-ins/String/prototype/indexOf/searchstring-tostring-bigint.js
new file mode 100644
index 000000000..ea0b4e2a5
--- /dev/null
+++ b/test/built-ins/String/prototype/indexOf/searchstring-tostring-bigint.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2017 Josh Wolfe. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: String.prototype.indexOf type coercion for searchString parameter
+esid: sec-string.prototype.indexof
+info: |
+ String.prototype.indexOf ( searchString [ , position ] )
+
+ 3. Let searchStr be ? ToString(searchString).
+features: [BigInt, Symbol.toPrimitive, computed-property-names]
+---*/
+
+assert.sameValue("__0__".indexOf(0n), 2, "ToString: BigInt to String");
+assert.sameValue("__0__".indexOf(Object(0n)), 2,
+ "ToString: unbox object with internal slot => BigInt to String");
+assert.sameValue("__0__".indexOf({
+ [Symbol.toPrimitive]: function() {
+ return 0n;
+ }
+}), 2, "ToString: @@toPrimitive => BigInt to String");
+assert.sameValue("__0__".indexOf({
+ valueOf: function() {
+ return 0n;
+ },
+ toString: null
+}), 2, "ToString: valueOf => BigInt to String");
+assert.sameValue("__0__".indexOf({
+ toString: function() {
+ return 0n;
+ }
+}), 2, "ToString: toString => BigInt to String");
diff --git a/test/built-ins/String/prototype/indexOf/searchstring-tostring-errors.js b/test/built-ins/String/prototype/indexOf/searchstring-tostring-errors.js
new file mode 100644
index 000000000..e27208c09
--- /dev/null
+++ b/test/built-ins/String/prototype/indexOf/searchstring-tostring-errors.js
@@ -0,0 +1,40 @@
+// Copyright (C) 2017 Josh Wolfe. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: String.prototype.indexOf type coercion for searchString parameter
+esid: sec-string.prototype.indexof
+info: |
+ String.prototype.indexOf ( searchString [ , position ] )
+
+ 3. Let searchStr be ? ToString(searchString).
+features: [Symbol, Symbol.toPrimitive, computed-property-names]
+---*/
+
+assert.throws(TypeError, function() {
+ "".indexOf(Symbol("1"));
+}, "ToString: Symbol => TypeError");
+assert.throws(TypeError, function() {
+ "".indexOf(Object(Symbol("1")));
+}, "ToString: unbox object with internal slot => Symbol => TypeError");
+assert.throws(TypeError, function() {
+ "".indexOf({
+ [Symbol.toPrimitive]: function() {
+ return Symbol("1");
+ }
+ });
+}, "ToString: @@toPrimitive => Symbol => TypeError");
+assert.throws(TypeError, function() {
+ "".indexOf({
+ valueOf: function() {
+ return Symbol("1");
+ },
+ toString: null
+ });
+}, "ToString: valueOf => Symbol => TypeError");
+assert.throws(TypeError, function() {
+ "".indexOf({
+ toString: function() {
+ return Symbol("1");
+ }
+ });
+}, "ToString: toString => Symbol => TypeError");
diff --git a/test/built-ins/String/prototype/indexOf/searchstring-tostring-toprimitive.js b/test/built-ins/String/prototype/indexOf/searchstring-tostring-toprimitive.js
new file mode 100644
index 000000000..ccc1f86a4
--- /dev/null
+++ b/test/built-ins/String/prototype/indexOf/searchstring-tostring-toprimitive.js
@@ -0,0 +1,161 @@
+// Copyright (C) 2017 Josh Wolfe. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: String.prototype.indexOf type coercion for searchString parameter
+esid: sec-string.prototype.indexof
+info: |
+ String.prototype.indexOf ( searchString [ , position ] )
+
+ 3. Let searchStr be ? ToString(searchString).
+features: [Symbol.toPrimitive, computed-property-names]
+---*/
+
+function err() {
+ throw new Test262Error();
+}
+
+function MyError() {}
+
+assert.sameValue("__foo__".indexOf({
+ [Symbol.toPrimitive]: function() {
+ return "foo";
+ },
+ toString: err,
+ valueOf: err
+}), 2, "ToPrimitive: @@toPrimitive takes precedence");
+assert.sameValue("__foo__".indexOf({
+ toString: function() {
+ return "foo";
+ },
+ valueOf: err
+}), 2, "ToPrimitive: toString takes precedence over valueOf");
+assert.sameValue("__foo__".indexOf({
+ [Symbol.toPrimitive]: undefined,
+ toString: function() {
+ return "foo";
+ }
+}), 2, "ToPrimitive: skip @@toPrimitive when it's undefined");
+assert.sameValue("__foo__".indexOf({
+ [Symbol.toPrimitive]: null,
+ toString: function() {
+ return "foo";
+ }
+}), 2, "ToPrimitive: skip @@toPrimitive when it's null");
+assert.sameValue("__foo__".indexOf({
+ toString: null,
+ valueOf: function() {
+ return "foo";
+ }
+}), 2, "ToPrimitive: skip toString when it's not callable");
+assert.sameValue("__foo__".indexOf({
+ toString: 1,
+ valueOf: function() {
+ return "foo";
+ }
+}), 2, "ToPrimitive: skip toString when it's not callable");
+assert.sameValue("__foo__".indexOf({
+ toString: {},
+ valueOf: function() {
+ return "foo";
+ }
+}), 2, "ToPrimitive: skip toString when it's not callable");
+assert.sameValue("__foo__".indexOf({
+ toString: function() {
+ return {};
+ },
+ valueOf: function() {
+ return "foo";
+ }
+}), 2, "ToPrimitive: skip toString when it returns an object");
+assert.sameValue("__foo__".indexOf({
+ toString: function() {
+ return Object(12345);
+ },
+ valueOf: function() {
+ return "foo";
+ }
+}), 2, "ToPrimitive: skip toString when it returns an object");
+assert.throws(TypeError, function() {
+ "".indexOf({
+ [Symbol.toPrimitive]: 1
+ });
+}, "ToPrimitive: throw when @@toPrimitive is not callable");
+assert.throws(TypeError, function() {
+ "".indexOf({
+ [Symbol.toPrimitive]: {}
+ });
+}, "ToPrimitive: throw when @@toPrimitive is not callable");
+assert.throws(TypeError, function() {
+ "".indexOf({
+ [Symbol.toPrimitive]: function() {
+ return Object(1);
+ }
+ });
+}, "ToPrimitive: throw when @@toPrimitive returns an object");
+assert.throws(TypeError, function() {
+ "".indexOf({
+ [Symbol.toPrimitive]: function() {
+ return {};
+ }
+ });
+}, "ToPrimitive: throw when @@toPrimitive returns an object");
+assert.throws(MyError, function() {
+ "".indexOf({
+ [Symbol.toPrimitive]: function() {
+ throw new MyError();
+ }
+ });
+}, "ToPrimitive: propagate errors from @@toPrimitive");
+assert.throws(MyError, function() {
+ "".indexOf({
+ valueOf: function() {
+ throw new MyError();
+ },
+ toString: null
+ });
+}, "ToPrimitive: propagate errors from valueOf");
+assert.throws(MyError, function() {
+ "".indexOf({
+ toString: function() {
+ throw new MyError();
+ }
+ });
+}, "ToPrimitive: propagate errors from toString");
+assert.throws(TypeError, function() {
+ "".indexOf({
+ valueOf: null,
+ toString: null
+ });
+}, "ToPrimitive: throw when skipping both valueOf and toString");
+assert.throws(TypeError, function() {
+ "".indexOf({
+ valueOf: 1,
+ toString: 1
+ });
+}, "ToPrimitive: throw when skipping both valueOf and toString");
+assert.throws(TypeError, function() {
+ "".indexOf({
+ valueOf: {},
+ toString: {}
+ });
+}, "ToPrimitive: throw when skipping both valueOf and toString");
+assert.throws(TypeError, function() {
+ "".indexOf({
+ valueOf: function() {
+ return Object(1);
+ },
+ toString: function() {
+ return Object(1);
+ }
+ });
+}, "ToPrimitive: throw when skipping both valueOf and toString");
+assert.throws(TypeError, function() {
+ "".indexOf({
+ valueOf: function() {
+ return {};
+ },
+ toString: function() {
+ return {};
+ }
+ });
+}, "ToPrimitive: throw when skipping both valueOf and toString");
diff --git a/test/built-ins/String/prototype/indexOf/searchstring-tostring-wrapped-values.js b/test/built-ins/String/prototype/indexOf/searchstring-tostring-wrapped-values.js
new file mode 100644
index 000000000..b20f3c346
--- /dev/null
+++ b/test/built-ins/String/prototype/indexOf/searchstring-tostring-wrapped-values.js
@@ -0,0 +1,98 @@
+// Copyright (C) 2017 Josh Wolfe. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: String.prototype.indexOf type coercion for searchString parameter
+esid: sec-string.prototype.indexof
+info: |
+ String.prototype.indexOf ( searchString [ , position ] )
+
+ 3. Let searchStr be ? ToString(searchString).
+features: [Symbol.toPrimitive, computed-property-names]
+---*/
+
+assert.sameValue("__foo__".indexOf(Object("foo")), 2,
+ "ToPrimitive: unbox object with internal slot");
+assert.sameValue("__foo__".indexOf({
+ [Symbol.toPrimitive]: function() {
+ return "foo";
+ }
+}), 2, "ToPrimitive: @@toPrimitive");
+assert.sameValue("__foo__".indexOf({
+ valueOf: function() {
+ return "foo";
+ },
+ toString: null
+}), 2, "ToPrimitive: valueOf");
+assert.sameValue("__foo__".indexOf({
+ toString: function() {
+ return "foo";
+ }
+}), 2, "ToPrimitive: toString");
+assert.sameValue("__undefined__".indexOf({
+ [Symbol.toPrimitive]: function() {
+ return undefined;
+ }
+}), 2, 'ToString: @@toPrimitive => undefined => "undefined"');
+assert.sameValue("__undefined__".indexOf({
+ valueOf: function() {
+ return undefined;
+ },
+ toString: null
+}), 2, 'ToString: valueOf => undefined => "undefined"');
+assert.sameValue("__undefined__".indexOf({
+ toString: function() {
+ return undefined;
+ }
+}), 2, 'ToString: toString => undefined => "undefined"');
+assert.sameValue("__null__".indexOf({
+ [Symbol.toPrimitive]: function() {
+ return null;
+ }
+}), 2, 'ToString: @@toPrimitive => null => "null"');
+assert.sameValue("__null__".indexOf({
+ valueOf: function() {
+ return null;
+ },
+ toString: null
+}), 2, 'ToString: valueOf => null => "null"');
+assert.sameValue("__null__".indexOf({
+ toString: function() {
+ return null;
+ }
+}), 2, 'ToString: toString => null => "null"');
+assert.sameValue("__false__".indexOf(Object(false)), 2,
+ 'ToString: unbox object with internal slot => false => "false"');
+assert.sameValue("__false__".indexOf({
+ [Symbol.toPrimitive]: function() {
+ return false;
+ }
+}), 2, 'ToString: @@toPrimitive => false => "false"');
+assert.sameValue("__false__".indexOf({
+ valueOf: function() {
+ return false;
+ },
+ toString: null
+}), 2, 'ToString: valueOf => false => "false"');
+assert.sameValue("__false__".indexOf({
+ toString: function() {
+ return false;
+ }
+}), 2, 'ToString: toString => false => "false"');
+assert.sameValue("__0__".indexOf(Object(0)), 2,
+ "ToString: unbox object with internal slot => Number to String");
+assert.sameValue("__0__".indexOf({
+ [Symbol.toPrimitive]: function() {
+ return 0;
+ }
+}), 2, "ToString: @@toPrimitive => Number to String");
+assert.sameValue("__0__".indexOf({
+ valueOf: function() {
+ return 0;
+ },
+ toString: null
+}), 2, "ToString: valueOf => Number to String");
+assert.sameValue("__0__".indexOf({
+ toString: function() {
+ return 0;
+ }
+}), 2, "ToString: toString => Number to String");
diff --git a/test/built-ins/String/prototype/indexOf/searchstring-tostring.js b/test/built-ins/String/prototype/indexOf/searchstring-tostring.js
index 44d23a4d4..f2dea4af3 100644
--- a/test/built-ins/String/prototype/indexOf/searchstring-tostring.js
+++ b/test/built-ins/String/prototype/indexOf/searchstring-tostring.js
@@ -1,26 +1,27 @@
// 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: >
+esid: sec-string.prototype.indexof
+info: |
String.prototype.indexOf ( searchString [ , position ] )
3. Let searchStr be ? ToString(searchString).
-
-includes: [typeCoercion.js]
-features: [Symbol.toPrimitive, BigInt]
---*/
-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); });
-});
+assert.sameValue("foo".indexOf(""), 0);
+assert.sameValue("__foo__".indexOf("foo"), 2);
+assert.sameValue("__undefined__".indexOf(undefined), 2, 'ToString: undefined => "undefined"');
+assert.sameValue("__null__".indexOf(null), 2, 'ToString: null => "null"');
+assert.sameValue("__true__".indexOf(true), 2, 'ToString: true => "true"');
+assert.sameValue("__false__".indexOf(false), 2, 'ToString: false => "false"');
+assert.sameValue("__0__".indexOf(0), 2, "ToString: Number to String");
+assert.sameValue("__0__".indexOf(-0), 2, 'ToString: -0 => "0"');
+assert.sameValue("__Infinity__".indexOf(Infinity), 2, 'ToString: Infinity => "Infinity"');
+assert.sameValue("__-Infinity__".indexOf(-Infinity), 2, 'ToString: -Infinity => "-Infinity"');
+assert.sameValue("__NaN__".indexOf(NaN), 2, 'ToString: NaN => "NaN"');
+assert.sameValue("__123.456__".indexOf(123.456), 2, "ToString: Number to String");
+assert.sameValue("__-123.456__".indexOf(-123.456), 2, "ToString: Number to String");
+assert.sameValue("foo".indexOf([]), 0, "ToString: .toString()");
+assert.sameValue("__foo,bar__".indexOf(["foo", "bar"]), 2, "ToString: .toString()");
+assert.sameValue("__[object Object]__".indexOf({}), 2, "ToString: .toString()");