author | Till Schneidereit <till@tillschneidereit.net> |
Fri, 10 Jan 2014 15:19:05 +0100 | |
changeset 162949 | 71bb7391184e7c3aa1b9c2c98dc39f5dc16b4f20 |
parent 162948 | 441af05d123b8795d84024323c34d6298adf4796 |
child 162950 | d20c762cc1b6b00b0560baa06534fba8c7eee992 |
push id | 25975 |
push user | ryanvm@gmail.com |
push date | Fri, 10 Jan 2014 19:46:47 +0000 |
treeherder | autoland@e89afc241513 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jwalden |
bugs | 952898 |
milestone | 29.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/src/jit-test/tests/basic/string-endswith.js +++ b/js/src/jit-test/tests/basic/string-endswith.js @@ -1,39 +1,262 @@ -assertEq("abc".endsWith("abc"), true); -assertEq("abcd".endsWith("bcd"), true); -assertEq("abc".endsWith("c"), true); -assertEq("abc".endsWith("abcd"), false); -assertEq("abc".endsWith("bbc"), false); -assertEq("abc".endsWith("b"), false); -assertEq("abc".endsWith("abc", 3), true); -assertEq("abc".endsWith("bc", 3), true); -assertEq("abc".endsWith("a", 3), false); -assertEq("abc".endsWith("bc", 3), true); -assertEq("abc".endsWith("a", 1), true); -assertEq("abc".endsWith("abc", 1), false); -assertEq("abc".endsWith("b", 2), true); -assertEq("abc".endsWith("d", 2), false); -assertEq("abc".endsWith("dcd", 2), false); -assertEq("abc".endsWith("a", 42), false); -assertEq("abc".endsWith("bc", Infinity), true); -assertEq("abc".endsWith("a", Infinity), false); -assertEq("abc".endsWith("bc", undefined), true); -assertEq("abc".endsWith("bc", -43), false); -assertEq("abc".endsWith("bc", -Infinity), false); -assertEq("abc".endsWith("bc", NaN), false); -var myobj = {toString : (function () "abc"), endsWith : String.prototype.endsWith}; -assertEq(myobj.endsWith("abc"), true); -assertEq(myobj.endsWith("ab"), false); -var gotStr = false, gotPos = false; -myobj = {toString : (function () { - assertEq(gotPos, false); - gotStr = true; - return "xyz"; -}), -endsWith : String.prototype.endsWith}; -var idx = {valueOf : (function () { - assertEq(gotStr, true); - gotPos = true; - return 42; -})}; -myobj.endsWith("elephant", idx); -assertEq(gotPos, true); +/* +* Copyright (c) 2013 Mathias Bynens. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +* DEALINGS IN THE SOFTWARE. +*/ + +function assertThrows(fun, errorType) { + try { + fun(); + assertEq(true, false, "Expected error, but none was thrown"); + } catch (e) { + assertEq(e instanceof errorType, true, "Wrong error type thrown"); + } +} +assertEq(String.prototype.endsWith.length, 1); +assertEq(String.prototype.propertyIsEnumerable('endsWith'), false); + +assertEq('undefined'.endsWith(), true); +assertEq('undefined'.endsWith(undefined), true); +assertEq('undefined'.endsWith(null), false); +assertEq('null'.endsWith(), false); +assertEq('null'.endsWith(undefined), false); +assertEq('null'.endsWith(null), true); + +assertEq('abc'.endsWith(), false); +assertEq('abc'.endsWith(''), true); +assertEq('abc'.endsWith('\0'), false); +assertEq('abc'.endsWith('c'), true); +assertEq('abc'.endsWith('b'), false); +assertEq('abc'.endsWith('a'), false); +assertEq('abc'.endsWith('ab'), false); +assertEq('abc'.endsWith('bc'), true); +assertEq('abc'.endsWith('abc'), true); +assertEq('abc'.endsWith('bcd'), false); +assertEq('abc'.endsWith('abcd'), false); +assertEq('abc'.endsWith('bcde'), false); + +assertEq('abc'.endsWith('', NaN), true); +assertEq('abc'.endsWith('\0', NaN), false); +assertEq('abc'.endsWith('c', NaN), false); +assertEq('abc'.endsWith('b', NaN), false); +assertEq('abc'.endsWith('a', NaN), false); +assertEq('abc'.endsWith('ab', NaN), false); +assertEq('abc'.endsWith('bc', NaN), false); +assertEq('abc'.endsWith('abc', NaN), false); +assertEq('abc'.endsWith('bcd', NaN), false); +assertEq('abc'.endsWith('abcd', NaN), false); +assertEq('abc'.endsWith('bcde', NaN), false); + +assertEq('abc'.endsWith('', false), true); +assertEq('abc'.endsWith('\0', false), false); +assertEq('abc'.endsWith('c', false), false); +assertEq('abc'.endsWith('b', false), false); +assertEq('abc'.endsWith('a', false), false); +assertEq('abc'.endsWith('ab', false), false); +assertEq('abc'.endsWith('bc', false), false); +assertEq('abc'.endsWith('abc', false), false); +assertEq('abc'.endsWith('bcd', false), false); +assertEq('abc'.endsWith('abcd', false), false); +assertEq('abc'.endsWith('bcde', false), false); + +assertEq('abc'.endsWith('', undefined), true); +assertEq('abc'.endsWith('\0', undefined), false); +assertEq('abc'.endsWith('c', undefined), true); +assertEq('abc'.endsWith('b', undefined), false); +assertEq('abc'.endsWith('a', undefined), false); +assertEq('abc'.endsWith('ab', undefined), false); +assertEq('abc'.endsWith('bc', undefined), true); +assertEq('abc'.endsWith('abc', undefined), true); +assertEq('abc'.endsWith('bcd', undefined), false); +assertEq('abc'.endsWith('abcd', undefined), false); +assertEq('abc'.endsWith('bcde', undefined), false); + +assertEq('abc'.endsWith('', null), true); +assertEq('abc'.endsWith('\0', null), false); +assertEq('abc'.endsWith('c', null), false); +assertEq('abc'.endsWith('b', null), false); +assertEq('abc'.endsWith('a', null), false); +assertEq('abc'.endsWith('ab', null), false); +assertEq('abc'.endsWith('bc', null), false); +assertEq('abc'.endsWith('abc', null), false); +assertEq('abc'.endsWith('bcd', null), false); +assertEq('abc'.endsWith('abcd', null), false); +assertEq('abc'.endsWith('bcde', null), false); + +assertEq('abc'.endsWith('', -Infinity), true); +assertEq('abc'.endsWith('\0', -Infinity), false); +assertEq('abc'.endsWith('c', -Infinity), false); +assertEq('abc'.endsWith('b', -Infinity), false); +assertEq('abc'.endsWith('a', -Infinity), false); +assertEq('abc'.endsWith('ab', -Infinity), false); +assertEq('abc'.endsWith('bc', -Infinity), false); +assertEq('abc'.endsWith('abc', -Infinity), false); +assertEq('abc'.endsWith('bcd', -Infinity), false); +assertEq('abc'.endsWith('abcd', -Infinity), false); +assertEq('abc'.endsWith('bcde', -Infinity), false); + +assertEq('abc'.endsWith('', -1), true); +assertEq('abc'.endsWith('\0', -1), false); +assertEq('abc'.endsWith('c', -1), false); +assertEq('abc'.endsWith('b', -1), false); +assertEq('abc'.endsWith('a', -1), false); +assertEq('abc'.endsWith('ab', -1), false); +assertEq('abc'.endsWith('bc', -1), false); +assertEq('abc'.endsWith('abc', -1), false); +assertEq('abc'.endsWith('bcd', -1), false); +assertEq('abc'.endsWith('abcd', -1), false); +assertEq('abc'.endsWith('bcde', -1), false); + +assertEq('abc'.endsWith('', -0), true); +assertEq('abc'.endsWith('\0', -0), false); +assertEq('abc'.endsWith('c', -0), false); +assertEq('abc'.endsWith('b', -0), false); +assertEq('abc'.endsWith('a', -0), false); +assertEq('abc'.endsWith('ab', -0), false); +assertEq('abc'.endsWith('bc', -0), false); +assertEq('abc'.endsWith('abc', -0), false); +assertEq('abc'.endsWith('bcd', -0), false); +assertEq('abc'.endsWith('abcd', -0), false); +assertEq('abc'.endsWith('bcde', -0), false); + +assertEq('abc'.endsWith('', +0), true); +assertEq('abc'.endsWith('\0', +0), false); +assertEq('abc'.endsWith('c', +0), false); +assertEq('abc'.endsWith('b', +0), false); +assertEq('abc'.endsWith('a', +0), false); +assertEq('abc'.endsWith('ab', +0), false); +assertEq('abc'.endsWith('bc', +0), false); +assertEq('abc'.endsWith('abc', +0), false); +assertEq('abc'.endsWith('bcd', +0), false); +assertEq('abc'.endsWith('abcd', +0), false); +assertEq('abc'.endsWith('bcde', +0), false); + +assertEq('abc'.endsWith('', 1), true); +assertEq('abc'.endsWith('\0', 1), false); +assertEq('abc'.endsWith('c', 1), false); +assertEq('abc'.endsWith('b', 1), false); +assertEq('abc'.endsWith('ab', 1), false); +assertEq('abc'.endsWith('bc', 1), false); +assertEq('abc'.endsWith('abc', 1), false); +assertEq('abc'.endsWith('bcd', 1), false); +assertEq('abc'.endsWith('abcd', 1), false); +assertEq('abc'.endsWith('bcde', 1), false); + +assertEq('abc'.endsWith('', 2), true); +assertEq('abc'.endsWith('\0', 2), false); +assertEq('abc'.endsWith('c', 2), false); +assertEq('abc'.endsWith('b', 2), true); +assertEq('abc'.endsWith('ab', 2), true); +assertEq('abc'.endsWith('bc', 2), false); +assertEq('abc'.endsWith('abc', 2), false); +assertEq('abc'.endsWith('bcd', 2), false); +assertEq('abc'.endsWith('abcd', 2), false); +assertEq('abc'.endsWith('bcde', 2), false); + +assertEq('abc'.endsWith('', +Infinity), true); +assertEq('abc'.endsWith('\0', +Infinity), false); +assertEq('abc'.endsWith('c', +Infinity), true); +assertEq('abc'.endsWith('b', +Infinity), false); +assertEq('abc'.endsWith('a', +Infinity), false); +assertEq('abc'.endsWith('ab', +Infinity), false); +assertEq('abc'.endsWith('bc', +Infinity), true); +assertEq('abc'.endsWith('abc', +Infinity), true); +assertEq('abc'.endsWith('bcd', +Infinity), false); +assertEq('abc'.endsWith('abcd', +Infinity), false); +assertEq('abc'.endsWith('bcde', +Infinity), false); + +assertEq('abc'.endsWith('', true), true); +assertEq('abc'.endsWith('\0', true), false); +assertEq('abc'.endsWith('c', true), false); +assertEq('abc'.endsWith('b', true), false); +assertEq('abc'.endsWith('ab', true), false); +assertEq('abc'.endsWith('bc', true), false); +assertEq('abc'.endsWith('abc', true), false); +assertEq('abc'.endsWith('bcd', true), false); +assertEq('abc'.endsWith('abcd', true), false); +assertEq('abc'.endsWith('bcde', true), false); + +assertEq('abc'.endsWith('', 'x'), true); +assertEq('abc'.endsWith('\0', 'x'), false); +assertEq('abc'.endsWith('c', 'x'), false); +assertEq('abc'.endsWith('b', 'x'), false); +assertEq('abc'.endsWith('a', 'x'), false); +assertEq('abc'.endsWith('ab', 'x'), false); +assertEq('abc'.endsWith('bc', 'x'), false); +assertEq('abc'.endsWith('abc', 'x'), false); +assertEq('abc'.endsWith('bcd', 'x'), false); +assertEq('abc'.endsWith('abcd', 'x'), false); +assertEq('abc'.endsWith('bcde', 'x'), false); + +assertEq('[a-z]+(bar)?'.endsWith('(bar)?'), true); +assertThrows(function() { '[a-z]+(bar)?'.endsWith(/(bar)?/); }, TypeError); +assertEq('[a-z]+(bar)?'.endsWith('[a-z]+', 6), true); +assertThrows(function() { '[a-z]+(bar)?'.endsWith(/(bar)?/); }, TypeError); +assertThrows(function() { '[a-z]+/(bar)?/'.endsWith(/(bar)?/); }, TypeError); +var global = newGlobal(); +global.eval('this.re = /(bar)?/'); +assertThrows(function() { '[a-z]+/(bar)?/'.endsWith(global.re); }, TypeError); + +// http://mathiasbynens.be/notes/javascript-unicode#poo-test +var string = 'I\xF1t\xEBrn\xE2ti\xF4n\xE0liz\xE6ti\xF8n\u2603\uD83D\uDCA9'; +assertEq(string.endsWith(''), true); +assertEq(string.endsWith('\xF1t\xEBr'), false); +assertEq(string.endsWith('\xF1t\xEBr', 5), true); +assertEq(string.endsWith('\xE0liz\xE6'), false); +assertEq(string.endsWith('\xE0liz\xE6', 16), true); +assertEq(string.endsWith('\xF8n\u2603\uD83D\uDCA9'), true); +assertEq(string.endsWith('\xF8n\u2603\uD83D\uDCA9', 23), true); +assertEq(string.endsWith('\u2603'), false); +assertEq(string.endsWith('\u2603', 21), true); +assertEq(string.endsWith('\uD83D\uDCA9'), true); +assertEq(string.endsWith('\uD83D\uDCA9', 23), true); + +assertThrows(function() { String.prototype.endsWith.call(undefined); }, TypeError); +assertThrows(function() { String.prototype.endsWith.call(undefined, 'b'); }, TypeError); +assertThrows(function() { String.prototype.endsWith.call(undefined, 'b', 4); }, TypeError); +assertThrows(function() { String.prototype.endsWith.call(null); }, TypeError); +assertThrows(function() { String.prototype.endsWith.call(null, 'b'); }, TypeError); +assertThrows(function() { String.prototype.endsWith.call(null, 'b', 4); }, TypeError); +assertEq(String.prototype.endsWith.call(42, '2'), true); +assertEq(String.prototype.endsWith.call(42, '4'), false); +assertEq(String.prototype.endsWith.call(42, 'b', 4), false); +assertEq(String.prototype.endsWith.call(42, '2', 1), false); +assertEq(String.prototype.endsWith.call(42, '2', 4), true); +assertEq(String.prototype.endsWith.call({ 'toString': function() { return 'abc'; } }, 'b', 0), false); +assertEq(String.prototype.endsWith.call({ 'toString': function() { return 'abc'; } }, 'b', 1), false); +assertEq(String.prototype.endsWith.call({ 'toString': function() { return 'abc'; } }, 'b', 2), true); +assertThrows(function() { String.prototype.endsWith.call({ 'toString': function() { throw RangeError(); } }, /./); }, RangeError); +assertThrows(function() { String.prototype.endsWith.call({ 'toString': function() { return 'abc' } }, /./); }, TypeError); + +assertThrows(function() { String.prototype.endsWith.apply(undefined); }, TypeError); +assertThrows(function() { String.prototype.endsWith.apply(undefined, ['b']); }, TypeError); +assertThrows(function() { String.prototype.endsWith.apply(undefined, ['b', 4]); }, TypeError); +assertThrows(function() { String.prototype.endsWith.apply(null); }, TypeError); +assertThrows(function() { String.prototype.endsWith.apply(null, ['b']); }, TypeError); +assertThrows(function() { String.prototype.endsWith.apply(null, ['b', 4]); }, TypeError); +assertEq(String.prototype.endsWith.apply(42, ['2']), true); +assertEq(String.prototype.endsWith.apply(42, ['4']), false); +assertEq(String.prototype.endsWith.apply(42, ['b', 4]), false); +assertEq(String.prototype.endsWith.apply(42, ['2', 1]), false); +assertEq(String.prototype.endsWith.apply(42, ['2', 4]), true); +assertEq(String.prototype.endsWith.apply({ 'toString': function() { return 'abc'; } }, ['b', 0]), false); +assertEq(String.prototype.endsWith.apply({ 'toString': function() { return 'abc'; } }, ['b', 1]), false); +assertEq(String.prototype.endsWith.apply({ 'toString': function() { return 'abc'; } }, ['b', 2]), true); +assertThrows(function() { String.prototype.endsWith.apply({ 'toString': function() { throw RangeError(); } }, [/./]); }, RangeError); +assertThrows(function() { String.prototype.endsWith.apply({ 'toString': function() { return 'abc' } }, [/./]); }, TypeError);
--- a/js/src/jit-test/tests/basic/string-startswith.js +++ b/js/src/jit-test/tests/basic/string-startswith.js @@ -1,39 +1,243 @@ -assertEq("abc".startsWith("abc"), true); -assertEq("abcd".startsWith("abc"), true); -assertEq("abc".startsWith("a"), true); -assertEq("abc".startsWith("abcd"), false); -assertEq("abc".startsWith("bcde"), false); -assertEq("abc".startsWith("b"), false); -assertEq("abc".startsWith("abc", 0), true); -assertEq("abc".startsWith("bc", 0), false); -assertEq("abc".startsWith("bc", 1), true); -assertEq("abc".startsWith("c", 1), false); -assertEq("abc".startsWith("abc", 1), false); -assertEq("abc".startsWith("c", 2), true); -assertEq("abc".startsWith("d", 2), false); -assertEq("abc".startsWith("dcd", 2), false); -assertEq("abc".startsWith("a", 42), false); -assertEq("abc".startsWith("a", Infinity), false); -assertEq("abc".startsWith("a", NaN), true); -assertEq("abc".startsWith("b", NaN), false); -assertEq("abc".startsWith("ab", -43), true); -assertEq("abc".startsWith("ab", -Infinity), true); -assertEq("abc".startsWith("bc", -42), false); -assertEq("abc".startsWith("bc", -Infinity), false); -var myobj = {toString : (function () "abc"), startsWith : String.prototype.startsWith}; -assertEq(myobj.startsWith("abc"), true); -assertEq(myobj.startsWith("bc"), false); -var gotStr = false, gotPos = false; -myobj = {toString : (function () { - assertEq(gotPos, false); - gotStr = true; - return "xyz"; -}), -startsWith : String.prototype.startsWith}; -var idx = {valueOf : (function () { - assertEq(gotStr, true); - gotPos = true; - return 42; -})}; -myobj.startsWith("elephant", idx); -assertEq(gotPos, true); +/* +* Copyright (c) 2013 Mathias Bynens. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +* DEALINGS IN THE SOFTWARE. +*/ + +function assertThrows(fun, errorType) { + try { + fun(); + assertEq(true, false, "Expected error, but none was thrown"); + } catch (e) { + assertEq(e instanceof errorType, true, "Wrong error type thrown"); + } +} + +Object.prototype[1] = 2; // try to break `arguments[1]` + +assertEq(String.prototype.startsWith.length, 1); +assertEq(String.prototype.propertyIsEnumerable('startsWith'), false); + +assertEq('undefined'.startsWith(), true); +assertEq('undefined'.startsWith(undefined), true); +assertEq('undefined'.startsWith(null), false); +assertEq('null'.startsWith(), false); +assertEq('null'.startsWith(undefined), false); +assertEq('null'.startsWith(null), true); + +assertEq('abc'.startsWith(), false); +assertEq('abc'.startsWith(''), true); +assertEq('abc'.startsWith('\0'), false); +assertEq('abc'.startsWith('a'), true); +assertEq('abc'.startsWith('b'), false); +assertEq('abc'.startsWith('ab'), true); +assertEq('abc'.startsWith('bc'), false); +assertEq('abc'.startsWith('abc'), true); +assertEq('abc'.startsWith('bcd'), false); +assertEq('abc'.startsWith('abcd'), false); +assertEq('abc'.startsWith('bcde'), false); + +assertEq('abc'.startsWith('', NaN), true); +assertEq('abc'.startsWith('\0', NaN), false); +assertEq('abc'.startsWith('a', NaN), true); +assertEq('abc'.startsWith('b', NaN), false); +assertEq('abc'.startsWith('ab', NaN), true); +assertEq('abc'.startsWith('bc', NaN), false); +assertEq('abc'.startsWith('abc', NaN), true); +assertEq('abc'.startsWith('bcd', NaN), false); +assertEq('abc'.startsWith('abcd', NaN), false); +assertEq('abc'.startsWith('bcde', NaN), false); + +assertEq('abc'.startsWith('', false), true); +assertEq('abc'.startsWith('\0', false), false); +assertEq('abc'.startsWith('a', false), true); +assertEq('abc'.startsWith('b', false), false); +assertEq('abc'.startsWith('ab', false), true); +assertEq('abc'.startsWith('bc', false), false); +assertEq('abc'.startsWith('abc', false), true); +assertEq('abc'.startsWith('bcd', false), false); +assertEq('abc'.startsWith('abcd', false), false); +assertEq('abc'.startsWith('bcde', false), false); + +assertEq('abc'.startsWith('', undefined), true); +assertEq('abc'.startsWith('\0', undefined), false); +assertEq('abc'.startsWith('a', undefined), true); +assertEq('abc'.startsWith('b', undefined), false); +assertEq('abc'.startsWith('ab', undefined), true); +assertEq('abc'.startsWith('bc', undefined), false); +assertEq('abc'.startsWith('abc', undefined), true); +assertEq('abc'.startsWith('bcd', undefined), false); +assertEq('abc'.startsWith('abcd', undefined), false); +assertEq('abc'.startsWith('bcde', undefined), false); + +assertEq('abc'.startsWith('', null), true); +assertEq('abc'.startsWith('\0', null), false); +assertEq('abc'.startsWith('a', null), true); +assertEq('abc'.startsWith('b', null), false); +assertEq('abc'.startsWith('ab', null), true); +assertEq('abc'.startsWith('bc', null), false); +assertEq('abc'.startsWith('abc', null), true); +assertEq('abc'.startsWith('bcd', null), false); +assertEq('abc'.startsWith('abcd', null), false); +assertEq('abc'.startsWith('bcde', null), false); + +assertEq('abc'.startsWith('', -Infinity), true); +assertEq('abc'.startsWith('\0', -Infinity), false); +assertEq('abc'.startsWith('a', -Infinity), true); +assertEq('abc'.startsWith('b', -Infinity), false); +assertEq('abc'.startsWith('ab', -Infinity), true); +assertEq('abc'.startsWith('bc', -Infinity), false); +assertEq('abc'.startsWith('abc', -Infinity), true); +assertEq('abc'.startsWith('bcd', -Infinity), false); +assertEq('abc'.startsWith('abcd', -Infinity), false); +assertEq('abc'.startsWith('bcde', -Infinity), false); + +assertEq('abc'.startsWith('', -1), true); +assertEq('abc'.startsWith('\0', -1), false); +assertEq('abc'.startsWith('a', -1), true); +assertEq('abc'.startsWith('b', -1), false); +assertEq('abc'.startsWith('ab', -1), true); +assertEq('abc'.startsWith('bc', -1), false); +assertEq('abc'.startsWith('abc', -1), true); +assertEq('abc'.startsWith('bcd', -1), false); +assertEq('abc'.startsWith('abcd', -1), false); +assertEq('abc'.startsWith('bcde', -1), false); + +assertEq('abc'.startsWith('', -0), true); +assertEq('abc'.startsWith('\0', -0), false); +assertEq('abc'.startsWith('a', -0), true); +assertEq('abc'.startsWith('b', -0), false); +assertEq('abc'.startsWith('ab', -0), true); +assertEq('abc'.startsWith('bc', -0), false); +assertEq('abc'.startsWith('abc', -0), true); +assertEq('abc'.startsWith('bcd', -0), false); +assertEq('abc'.startsWith('abcd', -0), false); +assertEq('abc'.startsWith('bcde', -0), false); + +assertEq('abc'.startsWith('', +0), true); +assertEq('abc'.startsWith('\0', +0), false); +assertEq('abc'.startsWith('a', +0), true); +assertEq('abc'.startsWith('b', +0), false); +assertEq('abc'.startsWith('ab', +0), true); +assertEq('abc'.startsWith('bc', +0), false); +assertEq('abc'.startsWith('abc', +0), true); +assertEq('abc'.startsWith('bcd', +0), false); +assertEq('abc'.startsWith('abcd', +0), false); +assertEq('abc'.startsWith('bcde', +0), false); + +assertEq('abc'.startsWith('', 1), true); +assertEq('abc'.startsWith('\0', 1), false); +assertEq('abc'.startsWith('a', 1), false); +assertEq('abc'.startsWith('b', 1), true); +assertEq('abc'.startsWith('ab', 1), false); +assertEq('abc'.startsWith('bc', 1), true); +assertEq('abc'.startsWith('abc', 1), false); +assertEq('abc'.startsWith('bcd', 1), false); +assertEq('abc'.startsWith('abcd', 1), false); +assertEq('abc'.startsWith('bcde', 1), false); + +assertEq('abc'.startsWith('', +Infinity), true); +assertEq('abc'.startsWith('\0', +Infinity), false); +assertEq('abc'.startsWith('a', +Infinity), false); +assertEq('abc'.startsWith('b', +Infinity), false); +assertEq('abc'.startsWith('ab', +Infinity), false); +assertEq('abc'.startsWith('bc', +Infinity), false); +assertEq('abc'.startsWith('abc', +Infinity), false); +assertEq('abc'.startsWith('bcd', +Infinity), false); +assertEq('abc'.startsWith('abcd', +Infinity), false); +assertEq('abc'.startsWith('bcde', +Infinity), false); + +assertEq('abc'.startsWith('', true), true); +assertEq('abc'.startsWith('\0', true), false); +assertEq('abc'.startsWith('a', true), false); +assertEq('abc'.startsWith('b', true), true); +assertEq('abc'.startsWith('ab', true), false); +assertEq('abc'.startsWith('bc', true), true); +assertEq('abc'.startsWith('abc', true), false); +assertEq('abc'.startsWith('bcd', true), false); +assertEq('abc'.startsWith('abcd', true), false); +assertEq('abc'.startsWith('bcde', true), false); + +assertEq('abc'.startsWith('', 'x'), true); +assertEq('abc'.startsWith('\0', 'x'), false); +assertEq('abc'.startsWith('a', 'x'), true); +assertEq('abc'.startsWith('b', 'x'), false); +assertEq('abc'.startsWith('ab', 'x'), true); +assertEq('abc'.startsWith('bc', 'x'), false); +assertEq('abc'.startsWith('abc', 'x'), true); +assertEq('abc'.startsWith('bcd', 'x'), false); +assertEq('abc'.startsWith('abcd', 'x'), false); +assertEq('abc'.startsWith('bcde', 'x'), false); + +assertEq('[a-z]+(bar)?'.startsWith('[a-z]+'), true); +assertThrows(function() { '[a-z]+(bar)?'.startsWith(/[a-z]+/); }, TypeError); +assertEq('[a-z]+(bar)?'.startsWith('(bar)?', 6), true); +assertThrows(function() { '[a-z]+(bar)?'.startsWith(/(bar)?/); }, TypeError); +assertThrows(function() { '[a-z]+/(bar)?/'.startsWith(/(bar)?/); }, TypeError); +var global = newGlobal(); +global.eval('this.re = /(bar)?/'); +assertThrows(function() { '[a-z]+/(bar)?/'.startsWith(global.re); }, TypeError); + +// http://mathiasbynens.be/notes/javascript-unicode#poo-test +var string = 'I\xF1t\xEBrn\xE2ti\xF4n\xE0liz\xE6ti\xF8n\u2603\uD83D\uDCA9'; +assertEq(string.startsWith(''), true); +assertEq(string.startsWith('\xF1t\xEBr'), false); +assertEq(string.startsWith('\xF1t\xEBr', 1), true); +assertEq(string.startsWith('\xE0liz\xE6'), false); +assertEq(string.startsWith('\xE0liz\xE6', 11), true); +assertEq(string.startsWith('\xF8n\u2603\uD83D\uDCA9'), false); +assertEq(string.startsWith('\xF8n\u2603\uD83D\uDCA9', 18), true); +assertEq(string.startsWith('\u2603'), false); +assertEq(string.startsWith('\u2603', 20), true); +assertEq(string.startsWith('\uD83D\uDCA9'), false); +assertEq(string.startsWith('\uD83D\uDCA9', 21), true); + +assertThrows(function() { String.prototype.startsWith.call(undefined); }, TypeError); +assertThrows(function() { String.prototype.startsWith.call(undefined, 'b'); }, TypeError); +assertThrows(function() { String.prototype.startsWith.call(undefined, 'b', 4); }, TypeError); +assertThrows(function() { String.prototype.startsWith.call(null); }, TypeError); +assertThrows(function() { String.prototype.startsWith.call(null, 'b'); }, TypeError); +assertThrows(function() { String.prototype.startsWith.call(null, 'b', 4); }, TypeError); +assertEq(String.prototype.startsWith.call(42, '2'), false); +assertEq(String.prototype.startsWith.call(42, '4'), true); +assertEq(String.prototype.startsWith.call(42, 'b', 4), false); +assertEq(String.prototype.startsWith.call(42, '2', 1), true); +assertEq(String.prototype.startsWith.call(42, '2', 4), false); +assertEq(String.prototype.startsWith.call({ 'toString': function() { return 'abc'; } }, 'b', 0), false); +assertEq(String.prototype.startsWith.call({ 'toString': function() { return 'abc'; } }, 'b', 1), true); +assertEq(String.prototype.startsWith.call({ 'toString': function() { return 'abc'; } }, 'b', 2), false); +assertThrows(function() { String.prototype.startsWith.call({ 'toString': function() { throw RangeError(); } }, /./); }, RangeError); +assertThrows(function() { String.prototype.startsWith.call({ 'toString': function() { return 'abc'; } }, /./); }, TypeError); + +assertThrows(function() { String.prototype.startsWith.apply(undefined); }, TypeError); +assertThrows(function() { String.prototype.startsWith.apply(undefined, ['b']); }, TypeError); +assertThrows(function() { String.prototype.startsWith.apply(undefined, ['b', 4]); }, TypeError); +assertThrows(function() { String.prototype.startsWith.apply(null); }, TypeError); +assertThrows(function() { String.prototype.startsWith.apply(null, ['b']); }, TypeError); +assertThrows(function() { String.prototype.startsWith.apply(null, ['b', 4]); }, TypeError); +assertEq(String.prototype.startsWith.apply(42, ['2']), false); +assertEq(String.prototype.startsWith.apply(42, ['4']), true); +assertEq(String.prototype.startsWith.apply(42, ['b', 4]), false); +assertEq(String.prototype.startsWith.apply(42, ['2', 1]), true); +assertEq(String.prototype.startsWith.apply(42, ['2', 4]), false); +assertEq(String.prototype.startsWith.apply({ 'toString': function() { return 'abc'; } }, ['b', 0]), false); +assertEq(String.prototype.startsWith.apply({ 'toString': function() { return 'abc'; } }, ['b', 1]), true); +assertEq(String.prototype.startsWith.apply({ 'toString': function() { return 'abc'; } }, ['b', 2]), false); +assertThrows(function() { String.prototype.startsWith.apply({ 'toString': function() { throw RangeError(); } }, [/./]); }, RangeError); +assertThrows(function() { String.prototype.startsWith.apply({ 'toString': function() { return 'abc'; } }, [/./]); }, TypeError);
--- a/js/src/js.msg +++ b/js/src/js.msg @@ -429,8 +429,9 @@ MSG_DEF(JSMSG_MODULE_SPEC_AFTER_FROM, MSG_DEF(JSMSG_MODULES_NOT_IMPLEMENTED, 375, 0, JSEXN_SYNTAXERR, "modules are not implemented yet") MSG_DEF(JSMSG_EXPORT_DECL_AT_TOP_LEVEL, 376, 0, JSEXN_SYNTAXERR, "export declarations may only appear at top level") MSG_DEF(JSMSG_RC_AFTER_EXPORT_SPEC_LIST, 377, 0, JSEXN_SYNTAXERR, "missing '}' after export specifier list") MSG_DEF(JSMSG_NO_EXPORT_NAME, 378, 0, JSEXN_SYNTAXERR, "missing export name") MSG_DEF(JSMSG_DECLARATION_AFTER_EXPORT, 379, 0, JSEXN_SYNTAXERR, "missing declaration after 'export' keyword") MSG_DEF(JSMSG_INVALID_PROTOTYPE, 380, 0, JSEXN_TYPEERR, "prototype field is not an object") MSG_DEF(JSMSG_TYPEDOBJECT_HANDLE_TO_UNSIZED, 381, 0, JSEXN_TYPEERR, "cannot create a handle to an unsized type") MSG_DEF(JSMSG_SETPROTOTYPEOF_FAIL, 382, 0, JSEXN_TYPEERR, "[[SetPrototypeOf]] failed") +MSG_DEF(JSMSG_INVALID_ARG_TYPE, 383, 3, JSEXN_TYPEERR, "Invalid type: {0} can't be a{1} {2}")
--- a/js/src/jsstr.cpp +++ b/js/src/jsstr.cpp @@ -1417,125 +1417,137 @@ str_lastIndexOf(JSContext *cx, unsigned } break_continue:; } args.rval().setInt32(-1); return true; } -/* ES6 20120927 draft 15.5.4.22. */ +/* ES6 20131108 draft 21.1.3.18. */ static bool str_startsWith(JSContext *cx, unsigned argc, Value *vp) { CallArgs args = CallArgsFromVp(argc, vp); // Steps 1, 2, and 3 RootedString str(cx, ThisToStringForStringProto(cx, args)); if (!str) return false; - // Steps 4 and 5 + // Step 4 + if (args.get(0).isObject() && IsObjectWithClass(args[0], ESClass_RegExp, cx)) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_INVALID_ARG_TYPE, + "first", "", "Regular Expression"); + return false; + } + + // Steps 5 and 6 Rooted<JSLinearString*> searchStr(cx, ArgToRootedString(cx, args, 0)); if (!searchStr) return false; - // Steps 6 and 7 + // Steps 7 and 8 uint32_t pos = 0; if (args.hasDefined(1)) { if (args[1].isInt32()) { int i = args[1].toInt32(); pos = (i < 0) ? 0U : uint32_t(i); } else { double d; if (!ToInteger(cx, args[1], &d)) return false; pos = uint32_t(Min(Max(d, 0.0), double(UINT32_MAX))); } } - // Step 8 + // Step 9 uint32_t textLen = str->length(); const jschar *textChars = str->getChars(cx); if (!textChars) return false; - // Step 9 + // Step 10 uint32_t start = Min(Max(pos, 0U), textLen); - // Step 10 + // Step 11 uint32_t searchLen = searchStr->length(); const jschar *searchChars = searchStr->chars(); - // Step 11 + // Step 12 if (searchLen + start < searchLen || searchLen + start > textLen) { args.rval().setBoolean(false); return true; } - // Steps 12 and 13 + // Steps 13 and 14 args.rval().setBoolean(PodEqual(textChars + start, searchChars, searchLen)); return true; } -/* ES6 20120708 draft 15.5.4.23. */ +/* ES6 20131108 draft 21.1.3.7. */ static bool str_endsWith(JSContext *cx, unsigned argc, Value *vp) { CallArgs args = CallArgsFromVp(argc, vp); // Steps 1, 2, and 3 RootedString str(cx, ThisToStringForStringProto(cx, args)); if (!str) return false; - // Steps 4 and 5 + // Step 4 + if (args.get(0).isObject() && IsObjectWithClass(args[0], ESClass_RegExp, cx)) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_INVALID_ARG_TYPE, + "first", "", "Regular Expression"); + return false; + } + + // Steps 5 and 6 Rooted<JSLinearString *> searchStr(cx, ArgToRootedString(cx, args, 0)); if (!searchStr) return false; - // Step 6 + // Step 7 uint32_t textLen = str->length(); - - // Steps 7 and 8 + const jschar *textChars = str->getChars(cx); + if (!textChars) + return false; + + // Steps 8 and 9 uint32_t pos = textLen; if (args.hasDefined(1)) { if (args[1].isInt32()) { int i = args[1].toInt32(); pos = (i < 0) ? 0U : uint32_t(i); } else { double d; if (!ToInteger(cx, args[1], &d)) return false; pos = uint32_t(Min(Max(d, 0.0), double(UINT32_MAX))); } } - // Step 6 - const jschar *textChars = str->getChars(cx); - if (!textChars) - return false; - - // Step 9 + // Step 10 uint32_t end = Min(Max(pos, 0U), textLen); - // Step 10 + // Step 11 uint32_t searchLen = searchStr->length(); const jschar *searchChars = searchStr->chars(); - // Step 12 + // Step 13 (reordered) if (searchLen > end) { args.rval().setBoolean(false); return true; } - // Step 11 + // Step 12 uint32_t start = end - searchLen; - // Steps 13 and 14 + // Steps 14 and 15 args.rval().setBoolean(PodEqual(textChars + start, searchChars, searchLen)); return true; } static bool js_TrimString(JSContext *cx, Value *vp, bool trimLeft, bool trimRight) { CallReceiver call = CallReceiverFromVp(vp);