diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..4ef4194
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,6 @@
+root = true
+
+[*]
+indent_style = tab
+end_of_line = lf
+insert_final_newline = true
diff --git a/.gitignore b/.gitignore
index 444ec4d..8effac9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,7 @@ coverage
# Installed npm modules
node_modules
+package-lock.json
# Folder view configuration files
.DS_Store
diff --git a/.npmrc b/.npmrc
new file mode 100644
index 0000000..43c97e7
--- /dev/null
+++ b/.npmrc
@@ -0,0 +1 @@
+package-lock=false
diff --git a/.travis.yml b/.travis.yml
index 6e5919d..7a78e0e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,3 +1,7 @@
+version: ~> 1.0
language: node_js
-node_js:
- - "0.10"
+os:
+ - linux
+import:
+ - ljharb/travis-ci:node/all.yml
+ - ljharb/travis-ci:node/pretest.yml
diff --git a/README.md b/README.md
index 19bb849..4c98afe 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,8 @@
# ES6 `String.prototype.includes` polyfill [![Build status](https://travis-ci.org/mathiasbynens/String.prototype.includes.svg?branch=master)](https://travis-ci.org/mathiasbynens/String.prototype.includes)
-A robust & optimized ES3-compatible polyfill for [the `String.prototype.includes` method (previously known as `String.prototype.contains`) in ECMAScript 6](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.includes).
+A robust & optimized polyfill for [the `String.prototype.includes` method (previously known as `String.prototype.contains`) in ECMAScript 6](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.includes).
+
+This package implements the [es-shim API](https://github.com/es-shims/api) interface. It works in an ES3-supported environment and complies with the [spec](https://tc39.es/ecma262/#sec-string.prototype.includes).
Other polyfills for `String.prototype.includes` are available:
@@ -9,12 +11,6 @@ Other polyfills for `String.prototype.includes` are available:
## Installation
-In a browser:
-
-```html
-
-```
-
Via [npm](http://npmjs.org/):
```bash
@@ -24,13 +20,19 @@ npm install string.prototype.includes
Then, in [Node.js](http://nodejs.org/):
```js
-require('string.prototype.includes');
+var includes = require('string.prototype.includes');
+```
+
+In a browser:
-// On Windows and on Mac systems with default settings, case doesn’t matter,
-// which allows you to do this instead:
-require('String.prototype.includes');
+```html
+
```
+> **NOTE**: It's recommended that you install this module using a package manager
+> such as `npm`, because loading multiple polyfills from a CDN (such as `bundle.run`)
+> will lead to duplicated code.
+
## Notes
Polyfills + test suites for [`String.prototype.startsWith`](https://mths.be/startswith) and [`String.prototype.endsWith`](https://mths.be/endswith) are available, too.
diff --git a/auto.js b/auto.js
new file mode 100644
index 0000000..e6e57f0
--- /dev/null
+++ b/auto.js
@@ -0,0 +1,3 @@
+/*! https://mths.be/includes v2.0.0 by @mathias */
+
+require('./shim')();
diff --git a/implementation.js b/implementation.js
new file mode 100644
index 0000000..15811aa
--- /dev/null
+++ b/implementation.js
@@ -0,0 +1,32 @@
+/*! https://mths.be/includes v2.0.0 by @mathias */
+
+'use strict';
+
+var callBound = require('es-abstract/helpers/callBound')
+var RequireObjectCoercible = require('es-abstract/2019/RequireObjectCoercible');
+var ToString = require('es-abstract/2019/ToString');
+var ToInteger = require('es-abstract/2019/ToInteger');
+var IsRegExp = require('es-abstract/2019/IsRegExp');
+
+var min = Math.min;
+var max = Math.max;
+var indexOf = callBound('String.prototype.indexOf');
+
+module.exports = function includes(searchString) {
+ var O = RequireObjectCoercible(this);
+ var S = ToString(O);
+ if (IsRegExp(searchString)) {
+ throw TypeError('Argument to String.prototype.includes cannot be a RegExp');
+ }
+ var searchStr = String(searchString);
+ var searchLength = searchStr.length;
+ var position = arguments.length > 1 ? arguments[1] : undefined;
+ var pos = ToInteger(position);
+ var len = S.length;
+ var start = min(max(pos, 0), len);
+ // Avoid the `indexOf` call if no match is possible
+ if (searchLength + start > len) {
+ return false;
+ }
+ return indexOf(S, searchStr, pos) != -1;
+};
diff --git a/includes.js b/includes.js
deleted file mode 100644
index ffd41b2..0000000
--- a/includes.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/*! https://mths.be/includes v1.0.0 by @mathias */
-if (!String.prototype.includes) {
- (function() {
- 'use strict'; // needed to support `apply`/`call` with `undefined`/`null`
- var toString = {}.toString;
- var defineProperty = (function() {
- // IE 8 only supports `Object.defineProperty` on DOM elements
- try {
- var object = {};
- var $defineProperty = Object.defineProperty;
- var result = $defineProperty(object, object, object) && $defineProperty;
- } catch(error) {}
- return result;
- }());
- var indexOf = ''.indexOf;
- var includes = function(search) {
- if (this == null) {
- throw TypeError();
- }
- var string = String(this);
- if (search && toString.call(search) == '[object RegExp]') {
- throw TypeError();
- }
- var stringLength = string.length;
- var searchString = String(search);
- var searchLength = searchString.length;
- var position = arguments.length > 1 ? arguments[1] : undefined;
- // `ToInteger`
- var pos = position ? Number(position) : 0;
- if (pos != pos) { // better `isNaN`
- pos = 0;
- }
- var start = Math.min(Math.max(pos, 0), stringLength);
- // Avoid the `indexOf` call if no match is possible
- if (searchLength + start > stringLength) {
- return false;
- }
- return indexOf.call(string, searchString, pos) != -1;
- };
- if (defineProperty) {
- defineProperty(String.prototype, 'includes', {
- 'value': includes,
- 'configurable': true,
- 'writable': true
- });
- } else {
- String.prototype.includes = includes;
- }
- }());
-}
diff --git a/index.js b/index.js
new file mode 100644
index 0000000..9efa4a3
--- /dev/null
+++ b/index.js
@@ -0,0 +1,20 @@
+/*! https://mths.be/includes v2.0.0 by @mathias */
+
+'use strict';
+
+var callBind = require('es-abstract/helpers/callBind');
+var define = require('define-properties');
+
+var implementation = require('./implementation');
+var getPolyfill = require('./polyfill');
+var shim = require('./shim');
+
+var boundIncludes = callBind(getPolyfill());
+
+define(boundIncludes, {
+ getPolyfill: getPolyfill,
+ implementation: implementation,
+ shim: shim
+});
+
+module.exports = boundIncludes;
diff --git a/package.json b/package.json
index 9d733ca..19e151a 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,15 @@
"version": "1.0.0",
"description": "A robust & optimized `String.prototype.includes` polyfill, based on the ECMAScript 6 specification.",
"homepage": "https://mths.be/includes",
- "main": "includes.js",
+ "main": "index.js",
+ "exports": {
+ ".": "./index.js",
+ "./auto": "./auto.js",
+ "./shim": "./shim.js",
+ "./getPolyfill": "./getPolyfill.js",
+ "./implementation": "./implementation.js",
+ "./package.json": "./package.json"
+ },
"keywords": [
"string",
"includes",
@@ -21,12 +29,21 @@
"url": "https://github.com/mathiasbynens/String.prototype.includes.git"
},
"bugs": "https://github.com/mathiasbynens/String.prototype.includes/issues",
- "files": [
- "LICENSE-MIT.txt",
- "includes.js"
- ],
"scripts": {
- "test": "node tests/tests.js",
- "cover": "istanbul cover --report html --verbose --dir coverage tests/tests.js"
+ "pretest": "es-shim-api --bound",
+ "test": "npm run tests-only",
+ "tests-only": "tape 'tests/*.js'",
+ "cover": "istanbul cover --report html --verbose --dir coverage tape 'tests/*.js'"
+ },
+ "dependencies": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.5"
+ },
+ "devDependencies": {
+ "@es-shims/api": "^2.1.2",
+ "function-bind": "^1.1.1",
+ "functions-have-names": "^1.2.1",
+ "istanbul": "^0.4.5",
+ "tape": "^5.0.0"
}
}
diff --git a/polyfill.js b/polyfill.js
new file mode 100644
index 0000000..b6ffd65
--- /dev/null
+++ b/polyfill.js
@@ -0,0 +1,9 @@
+/*! https://mths.be/includes v2.0.0 by @mathias */
+
+'use strict';
+
+var implementation = require('./implementation');
+
+module.exports = function getPolyfill() {
+ return String.prototype.includes || implementation;
+};
diff --git a/shim.js b/shim.js
new file mode 100644
index 0000000..3e67f7e
--- /dev/null
+++ b/shim.js
@@ -0,0 +1,17 @@
+/*! https://mths.be/includes v2.0.0 by @mathias */
+
+'use strict';
+
+var define = require('define-properties');
+
+var getPolyfill = require('./polyfill');
+
+module.exports = function shimIncludes() {
+ var polyfill = getPolyfill();
+
+ if (String.prototype.includes !== polyfill) {
+ define(String.prototype, { includes: polyfill });
+ }
+
+ return polyfill;
+};
diff --git a/tests/index.js b/tests/index.js
new file mode 100644
index 0000000..a748583
--- /dev/null
+++ b/tests/index.js
@@ -0,0 +1,12 @@
+'use strict';
+
+var includes = require('../');
+var test = require('tape');
+
+var runTests = require('./tests');
+
+test('as a function', function (t) {
+ runTests(includes, t);
+
+ t.end();
+});
diff --git a/tests/shimmed.js b/tests/shimmed.js
new file mode 100644
index 0000000..b3ef5a3
--- /dev/null
+++ b/tests/shimmed.js
@@ -0,0 +1,30 @@
+'use strict';
+
+var includes = require('../');
+includes.shim();
+
+var test = require('tape');
+var defineProperties = require('define-properties');
+var bind = require('function-bind');
+var isEnumerable = Object.prototype.propertyIsEnumerable;
+var functionsHaveNames = require('functions-have-names')();
+
+var runTests = require('./tests');
+
+test('shimmed', function (t) {
+ t.equal(String.prototype.includes.length, 1, 'String#includes has a length of 1');
+
+ t.test('Function name', { skip: !functionsHaveNames }, function (st) {
+ st.equal(String.prototype.includes.name, 'includes', 'String#includes has name "includes"');
+ st.end();
+ });
+
+ t.test('enumerability', { skip: !defineProperties.supportsDescriptors }, function (st) {
+ st.equal(false, isEnumerable.call(String.prototype, 'includes'), 'String#includes is not enumerable');
+ st.end();
+ });
+
+ runTests(bind.call(Function.call, String.prototype.includes), t);
+
+ t.end();
+});
diff --git a/tests/tests.js b/tests/tests.js
index bdde023..f965879 100644
--- a/tests/tests.js
+++ b/tests/tests.js
@@ -1,120 +1,138 @@
-var assert = require('assert');
-var assertEquals = assert.equal;
-var assertThrows = assert['throws'];
+'use strict';
-require('../includes.js');
+function fakeArg(fn) {
+ return function(st) {
+ try {
+ Object.prototype[1] = 2; // try to break `arguments[1]`
+ fn(st);
+ } finally {
+ delete Object.prototype[1];
+ }
+ };
+}
-Object.prototype[1] = 2; // try to break `arguments[1]`
+module.exports = function(includes, t) {
+ t.test('cast searchString arg', fakeArg(function(st) {
+ st.equals(includes('abc'), false);
+ st.equals(includes('aundefinedb'), true);
+ st.equals(includes('abc', undefined), false);
+ st.equals(includes('aundefinedb', undefined), true);
+ st.equals(includes('abc', null), false);
+ st.equals(includes('anullb', null), true);
+ st.equals(includes('abc', false), false);
+ st.equals(includes('afalseb', false), true);
+ st.equals(includes('abc', NaN), false);
+ st.equals(includes('aNaNb', NaN), true);
+ st.end();
+ }));
-assertEquals(String.prototype.includes.length, 1);
-assertEquals(String.prototype.propertyIsEnumerable('includes'), false);
+ t.test('basic support', fakeArg(function(st) {
+ st.equals(includes('abc', 'abc'), true);
+ st.equals(includes('abc', 'def'), false);
+ st.equals(includes('abc', ''), true);
+ st.equals(includes('', ''), true);
+ st.equals(includes('abc', 'bc'), true);
+ st.equals(includes('abc', 'bc\0'), false);
+ st.end();
+ }));
-assertEquals('abc'.includes(), false);
-assertEquals('aundefinedb'.includes(), true);
-assertEquals('abc'.includes(undefined), false);
-assertEquals('aundefinedb'.includes(undefined), true);
-assertEquals('abc'.includes(null), false);
-assertEquals('anullb'.includes(null), true);
-assertEquals('abc'.includes(false), false);
-assertEquals('afalseb'.includes(false), true);
-assertEquals('abc'.includes(NaN), false);
-assertEquals('aNaNb'.includes(NaN), true);
-assertEquals('abc'.includes('abc'), true);
-assertEquals('abc'.includes('def'), false);
-assertEquals('abc'.includes(''), true);
-assertEquals(''.includes(''), true);
+ t.test('pos argument', function(st) {
+ st.equals(includes('abc', 'b', -Infinity), true);
+ st.equals(includes('abc', 'b', -1), true);
+ st.equals(includes('abc', 'b', -0), true);
+ st.equals(includes('abc', 'b', +0), true);
+ st.equals(includes('abc', 'b', NaN), true);
+ st.equals(includes('abc', 'b', 'x'), true);
+ st.equals(includes('abc', 'b', false), true);
+ st.equals(includes('abc', 'b', undefined), true);
+ st.equals(includes('abc', 'b', null), true);
+ st.equals(includes('abc', 'b', 1), true);
+ st.equals(includes('abc', 'b', 2), false);
+ st.equals(includes('abc', 'b', 3), false);
+ st.equals(includes('abc', 'b', 4), false);
+ st.equals(includes('abc', 'b', +Infinity), false);
+ st.end();
+ });
-assertEquals('abc'.includes('b', -Infinity), true);
-assertEquals('abc'.includes('b', -1), true);
-assertEquals('abc'.includes('b', -0), true);
-assertEquals('abc'.includes('b', +0), true);
-assertEquals('abc'.includes('b', NaN), true);
-assertEquals('abc'.includes('b', 'x'), true);
-assertEquals('abc'.includes('b', false), true);
-assertEquals('abc'.includes('b', undefined), true);
-assertEquals('abc'.includes('b', null), true);
-assertEquals('abc'.includes('b', 1), true);
-assertEquals('abc'.includes('b', 2), false);
-assertEquals('abc'.includes('b', 3), false);
-assertEquals('abc'.includes('b', 4), false);
-assertEquals('abc'.includes('b', +Infinity), false);
-assertEquals('abc'.includes('bc'), true);
-assertEquals('abc'.includes('bc\0'), false);
+ t.test('cast stringSearch arg with pos - included', function(st) {
+ st.equals(includes('abc123def', 1, -Infinity), true);
+ st.equals(includes('abc123def', 1, -1), true);
+ st.equals(includes('abc123def', 1, -0), true);
+ st.equals(includes('abc123def', 1, +0), true);
+ st.equals(includes('abc123def', 1, NaN), true);
+ st.equals(includes('abc123def', 1, 'x'), true);
+ st.equals(includes('abc123def', 1, false), true);
+ st.equals(includes('abc123def', 1, undefined), true);
+ st.equals(includes('abc123def', 1, null), true);
+ st.equals(includes('abc123def', 1, 1), true);
+ st.equals(includes('abc123def', 1, 2), true);
+ st.equals(includes('abc123def', 1, 3), true);
+ st.equals(includes('abc123def', 1, 4), false);
+ st.equals(includes('abc123def', 1, 5), false);
+ st.equals(includes('abc123def', 1, +Infinity), false);
+ st.end();
+ });
-assertEquals('abc123def'.includes(1, -Infinity), true);
-assertEquals('abc123def'.includes(1, -1), true);
-assertEquals('abc123def'.includes(1, -0), true);
-assertEquals('abc123def'.includes(1, +0), true);
-assertEquals('abc123def'.includes(1, NaN), true);
-assertEquals('abc123def'.includes(1, 'x'), true);
-assertEquals('abc123def'.includes(1, false), true);
-assertEquals('abc123def'.includes(1, undefined), true);
-assertEquals('abc123def'.includes(1, null), true);
-assertEquals('abc123def'.includes(1, 1), true);
-assertEquals('abc123def'.includes(1, 2), true);
-assertEquals('abc123def'.includes(1, 3), true);
-assertEquals('abc123def'.includes(1, 4), false);
-assertEquals('abc123def'.includes(1, 5), false);
-assertEquals('abc123def'.includes(1, +Infinity), false);
+ t.test('cast stringSearch arg with pos - not included', function(st) {
+ st.equals(includes('abc123def', 9, -Infinity), false);
+ st.equals(includes('abc123def', 9, -1), false);
+ st.equals(includes('abc123def', 9, -0), false);
+ st.equals(includes('abc123def', 9, +0), false);
+ st.equals(includes('abc123def', 9, NaN), false);
+ st.equals(includes('abc123def', 9, 'x'), false);
+ st.equals(includes('abc123def', 9, false), false);
+ st.equals(includes('abc123def', 9, undefined), false);
+ st.equals(includes('abc123def', 9, null), false);
+ st.equals(includes('abc123def', 9, 1), false);
+ st.equals(includes('abc123def', 9, 2), false);
+ st.equals(includes('abc123def', 9, 3), false);
+ st.equals(includes('abc123def', 9, 4), false);
+ st.equals(includes('abc123def', 9, 5), false);
+ st.equals(includes('abc123def', 9, +Infinity), false);
+ st.end();
+ });
-assertEquals('abc123def'.includes(9, -Infinity), false);
-assertEquals('abc123def'.includes(9, -1), false);
-assertEquals('abc123def'.includes(9, -0), false);
-assertEquals('abc123def'.includes(9, +0), false);
-assertEquals('abc123def'.includes(9, NaN), false);
-assertEquals('abc123def'.includes(9, 'x'), false);
-assertEquals('abc123def'.includes(9, false), false);
-assertEquals('abc123def'.includes(9, undefined), false);
-assertEquals('abc123def'.includes(9, null), false);
-assertEquals('abc123def'.includes(9, 1), false);
-assertEquals('abc123def'.includes(9, 2), false);
-assertEquals('abc123def'.includes(9, 3), false);
-assertEquals('abc123def'.includes(9, 4), false);
-assertEquals('abc123def'.includes(9, 5), false);
-assertEquals('abc123def'.includes(9, +Infinity), false);
+ t.test('regex searchString', function(st) {
+ st.equals(includes('foo[a-z]+(bar)?', '[a-z]+'), true);
+ st['throws'](function() { includes('foo[a-z]+(bar)?', /[a-z]+/); }, TypeError);
+ st['throws'](function() { includes('foo/[a-z]+/(bar)?', /[a-z]+/); }, TypeError);
+ st.equals(includes('foo[a-z]+(bar)?', '(bar)?'), true);
+ st['throws'](function() { includes('foo[a-z]+(bar)?', /(bar)?/); }, TypeError);
+ st['throws'](function() { includes('foo[a-z]+/(bar)?/', /(bar)?/); }, TypeError);
+ st.end();
+ });
-assertEquals('foo[a-z]+(bar)?'.includes('[a-z]+'), true);
-assertThrows(function() { 'foo[a-z]+(bar)?'.includes(/[a-z]+/); }, TypeError);
-assertThrows(function() { 'foo/[a-z]+/(bar)?'.includes(/[a-z]+/); }, TypeError);
-assertEquals('foo[a-z]+(bar)?'.includes('(bar)?'), true);
-assertThrows(function() { 'foo[a-z]+(bar)?'.includes(/(bar)?/); }, TypeError);
-assertThrows(function() { 'foo[a-z]+/(bar)?/'.includes(/(bar)?/); }, TypeError);
+ t.test('astral symbols', function(st) {
+ // https://mathiasbynens.be/notes/javascript-unicode#poo-test
+ var string = 'I\xF1t\xEBrn\xE2ti\xF4n\xE0liz\xE6ti\xF8n\u2603\uD83D\uDCA9';
+ st.equals(string.includes(''), true);
+ st.equals(string.includes('\xF1t\xEBr'), true);
+ st.equals(string.includes('\xE0liz\xE6'), true);
+ st.equals(string.includes('\xF8n\u2603\uD83D\uDCA9'), true);
+ st.equals(string.includes('\u2603'), true);
+ st.equals(string.includes('\uD83D\uDCA9'), true);
+ st.end();
+ });
-// https://mathiasbynens.be/notes/javascript-unicode#poo-test
-var string = 'I\xF1t\xEBrn\xE2ti\xF4n\xE0liz\xE6ti\xF8n\u2603\uD83D\uDCA9';
-assertEquals(string.includes(''), true);
-assertEquals(string.includes('\xF1t\xEBr'), true);
-assertEquals(string.includes('\xE0liz\xE6'), true);
-assertEquals(string.includes('\xF8n\u2603\uD83D\uDCA9'), true);
-assertEquals(string.includes('\u2603'), true);
-assertEquals(string.includes('\uD83D\uDCA9'), true);
+ t.test('nullish this object', function(st) {
+ st['throws'](function() { includes(undefined); }, TypeError);
+ st['throws'](function() { includes(undefined, 'b'); }, TypeError);
+ st['throws'](function() { includes(undefined, 'b', 4); }, TypeError);
+ st['throws'](function() { includes(null); }, TypeError);
+ st['throws'](function() { includes(null, 'b'); }, TypeError);
+ st['throws'](function() { includes(null, 'b', 4); }, TypeError);
+ st.end();
+ });
-assertThrows(function() { String.prototype.includes.call(undefined); }, TypeError);
-assertThrows(function() { String.prototype.includes.call(undefined, 'b'); }, TypeError);
-assertThrows(function() { String.prototype.includes.call(undefined, 'b', 4); }, TypeError);
-assertThrows(function() { String.prototype.includes.call(null); }, TypeError);
-assertThrows(function() { String.prototype.includes.call(null, 'b'); }, TypeError);
-assertThrows(function() { String.prototype.includes.call(null, 'b', 4); }, TypeError);
-assertEquals(String.prototype.includes.call(42, '2'), true);
-assertEquals(String.prototype.includes.call(42, 'b', 4), false);
-assertEquals(String.prototype.includes.call(42, '2', 4), false);
-assertEquals(String.prototype.includes.call({ 'toString': function() { return 'abc'; } }, 'b', 0), true);
-assertEquals(String.prototype.includes.call({ 'toString': function() { return 'abc'; } }, 'b', 1), true);
-assertEquals(String.prototype.includes.call({ 'toString': function() { return 'abc'; } }, 'b', 2), false);
-assertThrows(function() { String.prototype.includes.call({ 'toString': function() { throw RangeError(); } }, /./); }, RangeError);
-assertThrows(function() { String.prototype.includes.call({ 'toString': function() { return 'abc'; } }, /./); }, TypeError);
-
-assertThrows(function() { String.prototype.includes.apply(undefined); }, TypeError);
-assertThrows(function() { String.prototype.includes.apply(undefined, ['b']); }, TypeError);
-assertThrows(function() { String.prototype.includes.apply(undefined, ['b', 4]); }, TypeError);
-assertThrows(function() { String.prototype.includes.apply(null); }, TypeError);
-assertThrows(function() { String.prototype.includes.apply(null, ['b']); }, TypeError);
-assertThrows(function() { String.prototype.includes.apply(null, ['b', 4]); }, TypeError);
-assertEquals(String.prototype.includes.apply(42, ['2']), true);
-assertEquals(String.prototype.includes.apply(42, ['b', 4]), false);
-assertEquals(String.prototype.includes.apply(42, ['2', 4]), false);
-assertEquals(String.prototype.includes.apply({ 'toString': function() { return 'abc'; } }, ['b', 0]), true);
-assertEquals(String.prototype.includes.apply({ 'toString': function() { return 'abc'; } }, ['b', 1]), true);
-assertEquals(String.prototype.includes.apply({ 'toString': function() { return 'abc'; } }, ['b', 2]), false);
-assertThrows(function() { String.prototype.includes.apply({ 'toString': function() { throw RangeError(); } }, [/./]); }, RangeError);
-assertThrows(function() { String.prototype.includes.apply({ 'toString': function() { return 'abc'; } }, [/./]); }, TypeError);
+ t.test('cast this object', function(st) {
+ st.equals(includes(42, '2'), true);
+ st.equals(includes(42, 'b', 4), false);
+ st.equals(includes(42, '2', 4), false);
+ st.equals(includes({ 'toString': function() { return 'abc'; } }, 'b', 0), true);
+ st.equals(includes({ 'toString': function() { return 'abc'; } }, 'b', 1), true);
+ st.equals(includes({ 'toString': function() { return 'abc'; } }, 'b', 2), false);
+ st['throws'](function() { includes({ 'toString': function() { throw RangeError(); } }, /./); }, RangeError);
+ st['throws'](function() { includes({ 'toString': function() { return 'abc'; } }, /./); }, TypeError);
+ st.end();
+ });
+};