blob: 73edb03a60c50afa0979479e3c36deaeb8f15a66 [file] [log] [blame]
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
Debug = debug.Debug
var exception = null;
var object_with_symbol_key = {[Symbol("a")]: 1};
var object_with_callbacks = { toString: () => "string", valueOf: () => 3};
var symbol_for_a = Symbol.for("a");
function listener(event, exec_state, event_data, data) {
if (event != Debug.DebugEvent.Break) return;
try {
function success(expectation, source) {
var result = exec_state.frame(0).evaluate(source, true).value();
if (expectation !== undefined) assertEquals(expectation, result);
}
function fail(source) {
assertThrows(() => exec_state.frame(0).evaluate(source, true),
EvalError);
}
// Test some Object functions.
success({}, `new Object()`);
success({p : 3}, `Object.create({}, { p: { value: 3 } })`);
success("[[\"a\",1],[\"b\",2]]",
`JSON.stringify(Object.entries({a:1, b:2}))`);
success({value: 1, writable: true, enumerable: true, configurable: true},
`Object.getOwnPropertyDescriptor({a: 1}, "a")`);
success("{\"a\":{\"value\":1,\"writable\":true," +
"\"enumerable\":true,\"configurable\":true}}",
`JSON.stringify(Object.getOwnPropertyDescriptors({a: 1}))`);
success(["a"], `Object.getOwnPropertyNames({a: 1})`);
success(undefined, `Object.getOwnPropertySymbols(object_with_symbol_key)`);
success({}, `Object.getPrototypeOf(Object.create({}))`);
success(true, `Object.is(Object, Object)`);
success(true, `Object.isExtensible({})`);
success(false, `Object.isFrozen({})`);
success(false, `Object.isSealed({})`);
success([1, 2], `Object.values({a:1, b:2})`);
fail(`Object.assign({}, {})`);
fail(`Object.defineProperties({}, [{p:{value:3}}])`);
fail(`Object.defineProperty({}, {p:{value:3}})`);
fail(`Object.freeze({})`);
fail(`Object.preventExtensions({})`);
fail(`Object.seal({})`);
fail(`Object.setPrototypeOf({}, {})`);
// Test some Object.prototype functions.
success(true, `({a:1}).hasOwnProperty("a")`);
success(true, `Object.prototype.isPrototypeOf({})`);
success(true, `({a:1}).propertyIsEnumerable("a")`);
success("[object Object]", `({a:1}).toString()`);
success("string", `(object_with_callbacks).toString()`);
success(3, `(object_with_callbacks).valueOf()`);
// Test Array functions.
success([], `new Array()`);
var function_param = [
"forEach", "every", "some", "reduce", "reduceRight", "find", "filter",
"map", "findIndex"
];
var fails = ["toString", "join", "toLocaleString", "pop", "push",
"reverse", "shift", "unshift", "slice", "splice", "sort", "filter",
"map", "copyWithin", "fill", "concat"];
for (f of Object.getOwnPropertyNames(Array.prototype)) {
if (typeof Array.prototype[f] === "function") {
if (fails.includes(f)) {
if (function_param.includes(f)) {
fail(`[1, 2, 3].${f}(()=>{});`);
} else {
fail(`[1, 2, 3].${f}();`);
}
} else if (function_param.includes(f)) {
exec_state.frame(0).evaluate(`[1, 2, 3].${f}(()=>{});`, true);
} else {
exec_state.frame(0).evaluate(`[1, 2, 3].${f}();`, true);
}
}
}
// Test Math functions.
for (f of Object.getOwnPropertyNames(Math)) {
if (typeof Math[f] === "function") {
var result = exec_state.frame(0).evaluate(
`Math.${f}(0.5, -0.5);`, true).value();
if (f != "random") assertEquals(Math[f](0.5, -0.5), result);
}
}
// Test Number functions.
success(new Number(0), `new Number()`);
for (f of Object.getOwnPropertyNames(Number)) {
if (typeof Number[f] === "function") {
success(Number[f](0.5), `Number.${f}(0.5);`);
}
}
for (f of Object.getOwnPropertyNames(Number.prototype)) {
if (typeof Number.prototype[f] === "function") {
if (f == "toLocaleString") continue;
success(Number(0.5)[f](5), `Number(0.5).${f}(5);`);
}
}
// Test String functions.
success(new String(), `new String()`);
success(" ", "String.fromCodePoint(0x20)");
success(" ", "String.fromCharCode(0x20)");
for (f of Object.getOwnPropertyNames(String.prototype)) {
if (typeof String.prototype[f] === "function") {
// Do not expect locale-specific or regexp-related functions to work.
// {Lower,Upper}Case (Locale-specific or not) do not work either
// if Intl is enabled.
if (f.indexOf("locale") >= 0) continue;
if (f.indexOf("Locale") >= 0) continue;
if (typeof Intl !== 'undefined') {
if (f == "toUpperCase") continue;
if (f == "toLowerCase") continue;
}
if (f == "normalize") continue;
if (f == "match") continue;
if (f == "search") continue;
if (f == "split" || f == "replace") {
fail(`'abcd'.${f}(2)`);
continue;
}
success("abcd"[f](2), `"abcd".${f}(2);`);
}
}
fail("'abCd'.toLocaleLowerCase()");
fail("'abcd'.toLocaleUpperCase()");
if (typeof Intl !== 'undefined') {
fail("'abCd'.toLowerCase()");
fail("'abcd'.toUpperCase()");
}
fail("'abcd'.match(/a/)");
fail("'abcd'.replace(/a/)");
fail("'abcd'.search(/a/)");
fail("'abcd'.split(/a/)");
// Test JSON functions.
success('{"abc":[1,2]}', "JSON.stringify(JSON.parse('{\"abc\":[1,2]}'))");
// Test Symbol functions.
success(undefined, `Symbol("a")`);
fail(`Symbol.for("a")`); // Symbol.for can be observed via Symbol.keyFor.
success("a", `Symbol.keyFor(symbol_for_a)`);
success("Symbol(a)", `symbol_for_a.valueOf().toString()`);
success("Symbol(a)", `symbol_for_a[Symbol.toPrimitive]().toString()`);
} catch (e) {
exception = e;
print(e, e.stack);
};
};
// Add the debug event listener.
Debug.setListener(listener);
function f() {
debugger;
};
f();
assertNull(exception);