Add new Harmony methods to String.prototype object.
String.prototype.repeat String.prototype.startsWith String.prototype.endsWith String.prototype.contains http://people.mozilla.org/~jorendorff/es6-draft.html BUG=v8:2796,v8:2797,v8:2798,v8:2799 TEST=mjsunit/string-repeat,mjsunit/string-startswith,mjsunit/string-endswith,mjsunit/string-contains R=mstarzinger@chromium.org Review URL: https://codereview.chromium.org/21014007 Patch from Ioseb Dzmanashvili <ioseb.dzmanashvili@gmail.com>. git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15960 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
306d944e3e
commit
0627d433b0
@ -2079,6 +2079,11 @@ bool Genesis::InstallExperimentalNatives() {
|
||||
"native array-iterator.js") == 0) {
|
||||
if (!CompileExperimentalBuiltin(isolate(), i)) return false;
|
||||
}
|
||||
if (FLAG_harmony_strings &&
|
||||
strcmp(ExperimentalNatives::GetScriptName(i).start(),
|
||||
"native harmony-string.js") == 0) {
|
||||
if (!CompileExperimentalBuiltin(isolate(), i)) return false;
|
||||
}
|
||||
}
|
||||
|
||||
InstallExperimentalNativeFunctions();
|
||||
|
@ -173,6 +173,7 @@ DEFINE_bool(harmony_generators, false, "enable harmony generators")
|
||||
DEFINE_bool(harmony_iteration, false, "enable harmony iteration (for-of)")
|
||||
DEFINE_bool(harmony_numeric_literals, false,
|
||||
"enable harmony numeric literals (0o77, 0b11)")
|
||||
DEFINE_bool(harmony_strings, false, "enable harmony string")
|
||||
DEFINE_bool(harmony, false, "enable all harmony features (except typeof)")
|
||||
DEFINE_implication(harmony, harmony_scoping)
|
||||
DEFINE_implication(harmony, harmony_modules)
|
||||
@ -183,6 +184,7 @@ DEFINE_implication(harmony, harmony_observation)
|
||||
DEFINE_implication(harmony, harmony_generators)
|
||||
DEFINE_implication(harmony, harmony_iteration)
|
||||
DEFINE_implication(harmony, harmony_numeric_literals)
|
||||
DEFINE_implication(harmony, harmony_strings)
|
||||
DEFINE_implication(harmony_modules, harmony_scoping)
|
||||
DEFINE_implication(harmony_observation, harmony_collections)
|
||||
// TODO[dslomov] add harmony => harmony_typed_arrays
|
||||
|
154
src/harmony-string.js
Normal file
154
src/harmony-string.js
Normal file
@ -0,0 +1,154 @@
|
||||
// Copyright 2013 the V8 project authors. All rights reserved.
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'use strict';
|
||||
|
||||
// This file relies on the fact that the following declaration has been made
|
||||
// in runtime.js:
|
||||
// var $String = global.String;
|
||||
// var $Array = global.Array;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
// ES6 draft 07-15-13, section 15.5.3.21
|
||||
function StringRepeat(count) {
|
||||
if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
|
||||
throw MakeTypeError("called_on_null_or_undefined",
|
||||
["String.prototype.repeat"]);
|
||||
}
|
||||
|
||||
var s = TO_STRING_INLINE(this);
|
||||
var n = ToInteger(count);
|
||||
if (n < 0 || !NUMBER_IS_FINITE(n)) {
|
||||
throw MakeRangeError("invalid_count_value", []);
|
||||
}
|
||||
|
||||
var elements = new InternalArray(n);
|
||||
for (var i = 0; i < n; i++) {
|
||||
elements[i] = s;
|
||||
}
|
||||
|
||||
return %StringBuilderConcat(elements, n, "");
|
||||
}
|
||||
|
||||
|
||||
// ES6 draft 07-15-13, section 15.5.3.22
|
||||
function StringStartsWith(searchString /* position */) { // length == 1
|
||||
if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
|
||||
throw MakeTypeError("called_on_null_or_undefined",
|
||||
["String.prototype.startsWith"]);
|
||||
}
|
||||
|
||||
var s = TO_STRING_INLINE(this);
|
||||
var ss = TO_STRING_INLINE(searchString);
|
||||
var pos = 0;
|
||||
if (%_ArgumentsLength() > 1) {
|
||||
pos = %_Arguments(1); // position
|
||||
pos = ToInteger(pos);
|
||||
}
|
||||
|
||||
var s_len = s.length;
|
||||
var start = MathMin(MathMax(pos, 0), s_len);
|
||||
var ss_len = ss.length;
|
||||
if (ss_len + start > s_len) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return %StringIndexOf(s, ss, start) === start;
|
||||
}
|
||||
|
||||
|
||||
// ES6 draft 07-15-13, section 15.5.3.23
|
||||
function StringEndsWith(searchString /* position */) { // length == 1
|
||||
if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
|
||||
throw MakeTypeError("called_on_null_or_undefined",
|
||||
["String.prototype.endsWith"]);
|
||||
}
|
||||
|
||||
var s = TO_STRING_INLINE(this);
|
||||
var ss = TO_STRING_INLINE(searchString);
|
||||
var s_len = s.length;
|
||||
var pos = s_len;
|
||||
if (%_ArgumentsLength() > 1) {
|
||||
var arg = %_Arguments(1); // position
|
||||
if (!IS_UNDEFINED(arg)) {
|
||||
pos = ToInteger(arg);
|
||||
}
|
||||
}
|
||||
|
||||
var end = MathMin(MathMax(pos, 0), s_len);
|
||||
var ss_len = ss.length;
|
||||
var start = end - ss_len;
|
||||
if (start < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return %StringLastIndexOf(s, ss, start) === start;
|
||||
}
|
||||
|
||||
|
||||
// ES6 draft 07-15-13, section 15.5.3.24
|
||||
function StringContains(searchString /* position */) { // length == 1
|
||||
if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
|
||||
throw MakeTypeError("called_on_null_or_undefined",
|
||||
["String.prototype.contains"]);
|
||||
}
|
||||
|
||||
var s = TO_STRING_INLINE(this);
|
||||
var ss = TO_STRING_INLINE(searchString);
|
||||
var pos = 0;
|
||||
if (%_ArgumentsLength() > 1) {
|
||||
pos = %_Arguments(1); // position
|
||||
pos = ToInteger(pos);
|
||||
}
|
||||
|
||||
var s_len = s.length;
|
||||
var start = MathMin(MathMax(pos, 0), s_len);
|
||||
var ss_len = ss.length;
|
||||
if (ss_len + start > s_len) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return %StringIndexOf(s, ss, start) !== -1;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
function ExtendStringPrototype() {
|
||||
%CheckIsBootstrapping();
|
||||
|
||||
// Set up the non-enumerable functions on the String prototype object.
|
||||
InstallFunctions($String.prototype, DONT_ENUM, $Array(
|
||||
"repeat", StringRepeat,
|
||||
"startsWith", StringStartsWith,
|
||||
"endsWith", StringEndsWith,
|
||||
"contains", StringContains
|
||||
));
|
||||
}
|
||||
|
||||
ExtendStringPrototype();
|
@ -126,6 +126,7 @@ var kMessages = {
|
||||
|
||||
stack_overflow: ["Maximum call stack size exceeded"],
|
||||
invalid_time_value: ["Invalid time value"],
|
||||
invalid_count_value: ["Invalid count value"],
|
||||
// SyntaxError
|
||||
paren_in_arg_string: ["Function arg string contains parenthesis"],
|
||||
not_isvar: ["builtin %IS_VAR: not a variable"],
|
||||
|
151
test/mjsunit/harmony/string-contains.js
Normal file
151
test/mjsunit/harmony/string-contains.js
Normal file
@ -0,0 +1,151 @@
|
||||
// Copyright 2013 the V8 project authors. All rights reserved.
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Flags: --harmony-strings
|
||||
|
||||
assertEquals(1, String.prototype.contains.length);
|
||||
|
||||
var reString = "asdf[a-z]+(asdf)?";
|
||||
assertTrue(reString.contains("[a-z]+"));
|
||||
assertTrue(reString.contains("(asdf)?"));
|
||||
|
||||
// Random greek letters
|
||||
var twoByteString = "\u039a\u0391\u03a3\u03a3\u0395";
|
||||
|
||||
// Test single char pattern
|
||||
assertTrue(twoByteString.contains("\u039a"), "Lamda");
|
||||
assertTrue(twoByteString.contains("\u0391"), "Alpha");
|
||||
assertTrue(twoByteString.contains("\u03a3"), "First Sigma");
|
||||
assertTrue(twoByteString.contains("\u03a3",3), "Second Sigma");
|
||||
assertTrue(twoByteString.contains("\u0395"), "Epsilon");
|
||||
assertFalse(twoByteString.contains("\u0392"), "Not beta");
|
||||
|
||||
// Test multi-char pattern
|
||||
assertTrue(twoByteString.contains("\u039a\u0391"), "lambda Alpha");
|
||||
assertTrue(twoByteString.contains("\u0391\u03a3"), "Alpha Sigma");
|
||||
assertTrue(twoByteString.contains("\u03a3\u03a3"), "Sigma Sigma");
|
||||
assertTrue(twoByteString.contains("\u03a3\u0395"), "Sigma Epsilon");
|
||||
|
||||
assertFalse(twoByteString.contains("\u0391\u03a3\u0395"),
|
||||
"Not Alpha Sigma Epsilon");
|
||||
|
||||
//single char pattern
|
||||
assertTrue(twoByteString.contains("\u0395"));
|
||||
|
||||
assertThrows("String.prototype.contains.call(null, 'test')", TypeError);
|
||||
assertThrows("String.prototype.contains.call(null, null)", TypeError);
|
||||
assertThrows("String.prototype.contains.call(undefined, undefined)", TypeError);
|
||||
|
||||
assertThrows("String.prototype.contains.apply(null, ['test'])", TypeError);
|
||||
assertThrows("String.prototype.contains.apply(null, [null])", TypeError);
|
||||
assertThrows("String.prototype.contains.apply(undefined, [undefined])", TypeError);
|
||||
|
||||
var TEST_INPUT = [{
|
||||
msg: "Empty string", val: ""
|
||||
}, {
|
||||
msg: "Number 1234.34", val: 1234.34
|
||||
}, {
|
||||
msg: "Integer number 0", val: 0
|
||||
}, {
|
||||
msg: "Negative number -1", val: -1
|
||||
}, {
|
||||
msg: "Boolean true", val: true
|
||||
}, {
|
||||
msg: "Boolean false", val: false
|
||||
}, {
|
||||
msg: "Regular expression /\d+/", val: /\d+/
|
||||
}, {
|
||||
msg: "Empty array []", val: []
|
||||
}, {
|
||||
msg: "Empty object {}", val: {}
|
||||
}, {
|
||||
msg: "Array of size 3", val: new Array(3)
|
||||
}];
|
||||
|
||||
var i = 0;
|
||||
var l = TEST_INPUT.length;
|
||||
|
||||
for (; i < l; i++) {
|
||||
var e = TEST_INPUT[i];
|
||||
var v = e.val;
|
||||
var s = String(v);
|
||||
assertTrue(s.contains(v), e.msg);
|
||||
assertTrue(String.prototype.contains.call(v, v), e.msg);
|
||||
assertTrue(String.prototype.contains.apply(v, [v]), e.msg);
|
||||
}
|
||||
|
||||
// Test cases found in FF
|
||||
assertTrue("abc".contains("a"));
|
||||
assertTrue("abc".contains("b"));
|
||||
assertTrue("abc".contains("abc"));
|
||||
assertTrue("abc".contains("bc"));
|
||||
assertFalse("abc".contains("d"));
|
||||
assertFalse("abc".contains("abcd"));
|
||||
assertFalse("abc".contains("ac"));
|
||||
assertTrue("abc".contains("abc", 0));
|
||||
assertTrue("abc".contains("bc", 0));
|
||||
assertFalse("abc".contains("de", 0));
|
||||
assertTrue("abc".contains("bc", 1));
|
||||
assertTrue("abc".contains("c", 1));
|
||||
assertFalse("abc".contains("a", 1));
|
||||
assertFalse("abc".contains("abc", 1));
|
||||
assertTrue("abc".contains("c", 2));
|
||||
assertFalse("abc".contains("d", 2));
|
||||
assertFalse("abc".contains("dcd", 2));
|
||||
assertFalse("abc".contains("a", 42));
|
||||
assertFalse("abc".contains("a", Infinity));
|
||||
assertTrue("abc".contains("ab", -43));
|
||||
assertFalse("abc".contains("cd", -42));
|
||||
assertTrue("abc".contains("ab", -Infinity));
|
||||
assertFalse("abc".contains("cd", -Infinity));
|
||||
assertTrue("abc".contains("ab", NaN));
|
||||
assertFalse("abc".contains("cd", NaN));
|
||||
assertFalse("xyzzy".contains("zy\0", 2));
|
||||
|
||||
var dots = Array(10000).join('.');
|
||||
assertFalse(dots.contains("\x01", 10000));
|
||||
assertFalse(dots.contains("\0", 10000));
|
||||
|
||||
var myobj = {
|
||||
toString: function () {
|
||||
return "abc";
|
||||
},
|
||||
contains: String.prototype.contains
|
||||
};
|
||||
assertTrue(myobj.contains("abc"));
|
||||
assertFalse(myobj.contains("cd"));
|
||||
|
||||
var gotStr = false;
|
||||
var gotPos = false;
|
||||
myobj = {
|
||||
toString: function () {
|
||||
assertFalse(gotPos);
|
||||
gotStr = true;
|
||||
return "xyz";
|
||||
},
|
||||
contains: String.prototype.contains
|
||||
};
|
136
test/mjsunit/harmony/string-endswith.js
Normal file
136
test/mjsunit/harmony/string-endswith.js
Normal file
@ -0,0 +1,136 @@
|
||||
// Copyright 2013 the V8 project authors. All rights reserved.
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Flags: --harmony-strings
|
||||
|
||||
assertEquals(1, String.prototype.endsWith.length);
|
||||
|
||||
var testString = "Hello World";
|
||||
assertTrue(testString.endsWith(""));
|
||||
assertTrue(testString.endsWith("World"));
|
||||
assertFalse(testString.endsWith("world"));
|
||||
assertFalse(testString.endsWith("Hello World!"));
|
||||
assertFalse(testString.endsWith(null));
|
||||
assertFalse(testString.endsWith(undefined));
|
||||
|
||||
assertTrue("null".endsWith(null));
|
||||
assertTrue("undefined".endsWith(undefined));
|
||||
|
||||
var georgianUnicodeString = "\u10D0\u10D1\u10D2\u10D3\u10D4\u10D5\u10D6\u10D7";
|
||||
assertTrue(georgianUnicodeString.endsWith(georgianUnicodeString));
|
||||
assertTrue(georgianUnicodeString.endsWith("\u10D4\u10D5\u10D6\u10D7"));
|
||||
assertFalse(georgianUnicodeString.endsWith("\u10D0"));
|
||||
|
||||
assertThrows("String.prototype.endsWith.call(null, 'test')", TypeError);
|
||||
assertThrows("String.prototype.endsWith.call(null, null)", TypeError);
|
||||
assertThrows("String.prototype.endsWith.call(undefined, undefined)", TypeError);
|
||||
|
||||
assertThrows("String.prototype.endsWith.apply(null, ['test'])", TypeError);
|
||||
assertThrows("String.prototype.endsWith.apply(null, [null])", TypeError);
|
||||
assertThrows("String.prototype.endsWith.apply(undefined, [undefined])", TypeError);
|
||||
|
||||
var TEST_INPUT = [{
|
||||
msg: "Empty string", val: ""
|
||||
}, {
|
||||
msg: "Number 1234.34", val: 1234.34
|
||||
}, {
|
||||
msg: "Integer number 0", val: 0
|
||||
}, {
|
||||
msg: "Negative number -1", val: -1
|
||||
}, {
|
||||
msg: "Boolean true", val: true
|
||||
}, {
|
||||
msg: "Boolean false", val: false
|
||||
}, {
|
||||
msg: "Regular expression /\d+/", val: /\d+/
|
||||
}, {
|
||||
msg: "Empty array []", val: []
|
||||
}, {
|
||||
msg: "Empty object {}", val: {}
|
||||
}, {
|
||||
msg: "Array of size 3", val: new Array(3)
|
||||
}];
|
||||
|
||||
function testNonStringValues() {
|
||||
var i = 0;
|
||||
var l = TEST_INPUT.length;
|
||||
|
||||
for (; i < l; i++) {
|
||||
var e = TEST_INPUT[i];
|
||||
var v = e.val;
|
||||
var s = String(v);
|
||||
assertTrue(s.endsWith(v), e.msg);
|
||||
assertTrue(String.prototype.endsWith.call(v, v), e.msg);
|
||||
assertTrue(String.prototype.endsWith.apply(v, [v]), e.msg);
|
||||
}
|
||||
}
|
||||
testNonStringValues();
|
||||
|
||||
var CustomType = function(value) {
|
||||
this.endsWith = String.prototype.endsWith;
|
||||
this.toString = function() {
|
||||
return String(value);
|
||||
}
|
||||
};
|
||||
|
||||
function testCutomType() {
|
||||
var i = 0;
|
||||
var l = TEST_INPUT.length;
|
||||
|
||||
for (; i < l; i++) {
|
||||
var e = TEST_INPUT[i];
|
||||
var v = e.val;
|
||||
var o = new CustomType(v);
|
||||
assertTrue(o.endsWith(v), e.msg);
|
||||
}
|
||||
}
|
||||
testCutomType();
|
||||
|
||||
|
||||
// Test cases found in FF
|
||||
assertTrue("abc".endsWith("abc"));
|
||||
assertTrue("abcd".endsWith("bcd"));
|
||||
assertTrue("abc".endsWith("c"));
|
||||
assertFalse("abc".endsWith("abcd"));
|
||||
assertFalse("abc".endsWith("bbc"));
|
||||
assertFalse("abc".endsWith("b"));
|
||||
assertTrue("abc".endsWith("abc", 3));
|
||||
assertTrue("abc".endsWith("bc", 3));
|
||||
assertFalse("abc".endsWith("a", 3));
|
||||
assertTrue("abc".endsWith("bc", 3));
|
||||
assertTrue("abc".endsWith("a", 1));
|
||||
assertFalse("abc".endsWith("abc", 1));
|
||||
assertTrue("abc".endsWith("b", 2));
|
||||
assertFalse("abc".endsWith("d", 2));
|
||||
assertFalse("abc".endsWith("dcd", 2));
|
||||
assertFalse("abc".endsWith("a", 42));
|
||||
assertTrue("abc".endsWith("bc", Infinity));
|
||||
assertFalse("abc".endsWith("a", Infinity));
|
||||
assertTrue("abc".endsWith("bc", undefined));
|
||||
assertFalse("abc".endsWith("bc", -43));
|
||||
assertFalse("abc".endsWith("bc", -Infinity));
|
||||
assertFalse("abc".endsWith("bc", NaN));
|
74
test/mjsunit/harmony/string-repeat.js
Normal file
74
test/mjsunit/harmony/string-repeat.js
Normal file
@ -0,0 +1,74 @@
|
||||
// Copyright 2013 the V8 project authors. All rights reserved.
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Flags: --harmony-strings
|
||||
|
||||
assertEquals("000", String.prototype.repeat.call(0, 3));
|
||||
assertEquals("-1-1-1", String.prototype.repeat.call(-1, 3));
|
||||
assertEquals("2.12.12.1", String.prototype.repeat.call(2.1, 3));
|
||||
assertEquals("", String.prototype.repeat.call([], 3));
|
||||
assertEquals("1,2,3", String.prototype.repeat.call([1, 2, 3], 1));
|
||||
assertEquals("true", String.prototype.repeat.call(true, 1));
|
||||
assertEquals("false", String.prototype.repeat.call(false, 1));
|
||||
assertEquals("[object Object]", String.prototype.repeat.call({}, 1));
|
||||
|
||||
assertEquals("000", String.prototype.repeat.apply(0, [3]));
|
||||
assertEquals("-1-1-1", String.prototype.repeat.apply(-1, [3]));
|
||||
assertEquals("2.12.12.1", String.prototype.repeat.apply(2.1, [3]));
|
||||
assertEquals("", String.prototype.repeat.apply([], [3]));
|
||||
assertEquals("1,2,3", String.prototype.repeat.apply([1, 2, 3], [1]));
|
||||
assertEquals("true", String.prototype.repeat.apply(true, [1]));
|
||||
assertEquals("false", String.prototype.repeat.apply(false, [1]));
|
||||
assertEquals("[object Object]", String.prototype.repeat.apply({}, [1]));
|
||||
|
||||
assertEquals("\u10D8\u10D8\u10D8", "\u10D8".repeat(3));
|
||||
|
||||
assertThrows('String.prototype.repeat.call(null, 1)', TypeError);
|
||||
assertThrows('String.prototype.repeat.call(undefined, 1)', TypeError);
|
||||
assertThrows('String.prototype.repeat.apply(null, [1])', TypeError);
|
||||
assertThrows('String.prototype.repeat.apply(undefined, [1])', TypeError);
|
||||
|
||||
// Test cases found in FF
|
||||
assertEquals("abc", "abc".repeat(1));
|
||||
assertEquals("abcabc", "abc".repeat(2));
|
||||
assertEquals("abcabcabc", "abc".repeat(3));
|
||||
assertEquals("aaaaaaaaaa", "a".repeat(10));
|
||||
assertEquals("", "".repeat(5));
|
||||
assertEquals("", "abc".repeat(0));
|
||||
assertEquals("abcabc", "abc".repeat(2.0));
|
||||
|
||||
assertThrows('"a".repeat(-1)', RangeError);
|
||||
assertThrows('"a".repeat(Number.POSITIVE_INFINITY)', RangeError);
|
||||
|
||||
var myobj = {
|
||||
toString: function() {
|
||||
return "abc";
|
||||
},
|
||||
repeat : String.prototype.repeat
|
||||
};
|
||||
assertEquals("abc", myobj.repeat(1));
|
||||
assertEquals("abcabc", myobj.repeat(2));
|
135
test/mjsunit/harmony/string-startswith.js
Normal file
135
test/mjsunit/harmony/string-startswith.js
Normal file
@ -0,0 +1,135 @@
|
||||
// Copyright 2013 the V8 project authors. All rights reserved.
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Flags: --harmony-strings
|
||||
|
||||
assertEquals(1, String.prototype.startsWith.length);
|
||||
|
||||
var testString = "Hello World";
|
||||
assertTrue(testString.startsWith(""));
|
||||
assertTrue(testString.startsWith("Hello"));
|
||||
assertFalse(testString.startsWith("hello"));
|
||||
assertFalse(testString.startsWith("Hello World!"));
|
||||
assertFalse(testString.startsWith(null));
|
||||
assertFalse(testString.startsWith(undefined));
|
||||
|
||||
assertTrue("null".startsWith(null));
|
||||
assertTrue("undefined".startsWith(undefined));
|
||||
|
||||
var georgianUnicodeString = "\u10D0\u10D1\u10D2\u10D3\u10D4\u10D5\u10D6\u10D7";
|
||||
assertTrue(georgianUnicodeString.startsWith(georgianUnicodeString));
|
||||
assertTrue(georgianUnicodeString.startsWith("\u10D0\u10D1\u10D2"));
|
||||
assertFalse(georgianUnicodeString.startsWith("\u10D8"));
|
||||
|
||||
assertThrows("String.prototype.startsWith.call(null, 'test')", TypeError);
|
||||
assertThrows("String.prototype.startsWith.call(null, null)", TypeError);
|
||||
assertThrows("String.prototype.startsWith.call(undefined, undefined)", TypeError);
|
||||
|
||||
assertThrows("String.prototype.startsWith.apply(null, ['test'])", TypeError);
|
||||
assertThrows("String.prototype.startsWith.apply(null, [null])", TypeError);
|
||||
assertThrows("String.prototype.startsWith.apply(undefined, [undefined])", TypeError);
|
||||
|
||||
var TEST_INPUT = [{
|
||||
msg: "Empty string", val: ""
|
||||
}, {
|
||||
msg: "Number 1234.34", val: 1234.34
|
||||
}, {
|
||||
msg: "Integer number 0", val: 0
|
||||
}, {
|
||||
msg: "Negative number -1", val: -1
|
||||
}, {
|
||||
msg: "Boolean true", val: true
|
||||
}, {
|
||||
msg: "Boolean false", val: false
|
||||
}, {
|
||||
msg: "Regular expression /\d+/", val: /\d+/
|
||||
}, {
|
||||
msg: "Empty array []", val: []
|
||||
}, {
|
||||
msg: "Empty object {}", val: {}
|
||||
}, {
|
||||
msg: "Array of size 3", val: new Array(3)
|
||||
}];
|
||||
|
||||
function testNonStringValues() {
|
||||
var i = 0;
|
||||
var l = TEST_INPUT.length;
|
||||
|
||||
for (; i < l; i++) {
|
||||
var e = TEST_INPUT[i];
|
||||
var v = e.val;
|
||||
var s = String(v);
|
||||
assertTrue(s.startsWith(v), e.msg);
|
||||
assertTrue(String.prototype.startsWith.call(v, v), e.msg);
|
||||
assertTrue(String.prototype.startsWith.apply(v, [v]), e.msg);
|
||||
}
|
||||
}
|
||||
testNonStringValues();
|
||||
|
||||
var CustomType = function(value) {
|
||||
this.startsWith = String.prototype.startsWith;
|
||||
this.toString = function() {
|
||||
return String(value);
|
||||
}
|
||||
};
|
||||
|
||||
function testCutomType() {
|
||||
var i = 0;
|
||||
var l = TEST_INPUT.length;
|
||||
|
||||
for (; i < l; i++) {
|
||||
var e = TEST_INPUT[i];
|
||||
var v = e.val;
|
||||
var o = new CustomType(v);
|
||||
assertTrue(o.startsWith(v), e.msg);
|
||||
}
|
||||
}
|
||||
testCutomType();
|
||||
|
||||
// Test cases found in FF
|
||||
assertTrue("abc".startsWith("abc"));
|
||||
assertTrue("abcd".startsWith("abc"));
|
||||
assertTrue("abc".startsWith("a"));
|
||||
assertFalse("abc".startsWith("abcd"));
|
||||
assertFalse("abc".startsWith("bcde"));
|
||||
assertFalse("abc".startsWith("b"));
|
||||
assertTrue("abc".startsWith("abc", 0));
|
||||
assertFalse("abc".startsWith("bc", 0));
|
||||
assertTrue("abc".startsWith("bc", 1));
|
||||
assertFalse("abc".startsWith("c", 1));
|
||||
assertFalse("abc".startsWith("abc", 1));
|
||||
assertTrue("abc".startsWith("c", 2));
|
||||
assertFalse("abc".startsWith("d", 2));
|
||||
assertFalse("abc".startsWith("dcd", 2));
|
||||
assertFalse("abc".startsWith("a", 42));
|
||||
assertFalse("abc".startsWith("a", Infinity));
|
||||
assertTrue("abc".startsWith("a", NaN));
|
||||
assertFalse("abc".startsWith("b", NaN));
|
||||
assertTrue("abc".startsWith("ab", -43));
|
||||
assertTrue("abc".startsWith("ab", -Infinity));
|
||||
assertFalse("abc".startsWith("bc", -42));
|
||||
assertFalse("abc".startsWith("bc", -Infinity));
|
@ -906,7 +906,8 @@
|
||||
'../../src/arraybuffer.js',
|
||||
'../../src/typedarray.js',
|
||||
'../../src/generator.js',
|
||||
'../../src/array-iterator.js'
|
||||
'../../src/array-iterator.js',
|
||||
'../../src/harmony-string.js'
|
||||
],
|
||||
'i18n_library_files': [
|
||||
'../../src/extensions/i18n/header.js',
|
||||
|
Loading…
Reference in New Issue
Block a user