From e50ff0a6f80a82a899f347e69b2d271a7412b3ac Mon Sep 17 00:00:00 2001 From: Sami Vaarala Date: Thu, 7 Mar 2013 22:51:52 +0200 Subject: [PATCH] object test cases --- .../test-builtin-object-constructor-custom.js | 38 ++ testcases/test-builtin-object-constructor.js | 125 +++++++ .../test-builtin-object-defineproperties.js | 336 ++++++++++++++++++ ...st-builtin-object-proto-tostring-custom.js | 13 + 4 files changed, 512 insertions(+) create mode 100644 testcases/test-builtin-object-constructor-custom.js create mode 100644 testcases/test-builtin-object-constructor.js create mode 100644 testcases/test-builtin-object-defineproperties.js create mode 100644 testcases/test-builtin-object-proto-tostring-custom.js diff --git a/testcases/test-builtin-object-constructor-custom.js b/testcases/test-builtin-object-constructor-custom.js new file mode 100644 index 00000000..efae1367 --- /dev/null +++ b/testcases/test-builtin-object-constructor-custom.js @@ -0,0 +1,38 @@ + +/*--- +{ + "skip": true +} +---*/ + +/*=== +FIXME +===*/ + +print('object constructor as function'); + +function constructorAsFunctionTest() { +} + +try { + constructorAsFunctionTest(); +} catch (e) { + print(e.name); +} + +/*=== +FIXME +===*/ + +print('object constructor as constructor'); + +function constructorTest() { +} + +try { + constructorTest(); +} catch (e) { + print(e.name); +} + + diff --git a/testcases/test-builtin-object-constructor.js b/testcases/test-builtin-object-constructor.js new file mode 100644 index 00000000..62e997e7 --- /dev/null +++ b/testcases/test-builtin-object-constructor.js @@ -0,0 +1,125 @@ + +function dumpObject(o) { + print(typeof o, + Object.prototype.toString.call(o), + Object.getPrototypeOf(o) === Object.prototype, + Object.isExtensible(o)); +} + +/*=== +object constructor as function +object [object Object] true true +object [object Object] true true +object [object Object] true true +object [object Boolean] false true +object [object Boolean] false true +object [object Number] false true +object [object String] false true +object [object Array] false true +true +object [object Object] true true +true +function [object Function] false true +true +===*/ + +/* Object constructor called as a function. */ + +print('object constructor as function'); + +function constructorAsFunctionTest() { + var t1, t2; + + dumpObject(Object()); + dumpObject(Object(undefined)); + dumpObject(Object(null)); + dumpObject(Object(true)); + dumpObject(Object(false)); + dumpObject(Object(123.0)); + dumpObject(Object('foo')); + + // check that the same object comes back + + t1 = []; + t2 = Object(t1); + dumpObject(t1); + print(t1 === t2); + + t1 = {}; + t2 = Object(t1); + dumpObject(t1); + print(t1 === t2); + + t1 = function() {}; + t2 = Object(t1); + dumpObject(t1); + print(t1 === t2); +} + +try { + constructorAsFunctionTest(); +} catch (e) { + print(e.name); +} + +/*=== +object constructor as constructor +object [object Object] true true +object [object Object] true true +object [object Object] true true +object [object Boolean] false true +object [object Boolean] false true +object [object Number] false true +object [object String] false true +object [object Array] false true +true +object [object Object] true true +true +function [object Function] false true +true +object [object Number] false true +===*/ + +/* Object constructor called as a constructor */ + +print('object constructor as constructor'); + +function constructorTest() { + var t1, t2; + + dumpObject(new Object()); + dumpObject(new Object(undefined)); + dumpObject(new Object(null)); + dumpObject(new Object(true)); + dumpObject(new Object(false)); + dumpObject(new Object(123.0)); + dumpObject(new Object('foo')); + + // check that the same object comes back + + t1 = []; + t2 = new Object(t1); + dumpObject(t1); + print(t1 === t2); + + t1 = {}; + t2 = new Object(t1); + dumpObject(t1); + print(t1 === t2); + + t1 = function() {}; + t2 = new Object(t1); + dumpObject(t1); + print(t1 === t2); + + // arguments beyond first optional arg are ignored + t2 = new Object(123, 'foo'); + dumpObject(t2); +} + +try { + constructorTest(); +} catch (e) { + print(e.name); +} + diff --git a/testcases/test-builtin-object-defineproperties.js b/testcases/test-builtin-object-defineproperties.js new file mode 100644 index 00000000..758e9ed3 --- /dev/null +++ b/testcases/test-builtin-object-defineproperties.js @@ -0,0 +1,336 @@ +// FIXME: util +function formatValue(v) { + if (typeof v === 'function') { + // avoid implementation dependent string formatting + if (v.funcName) { + return '[function ' + v.funcName + ']'; + } else { + return Object.prototype.toString.call(v); + } + } + if (typeof v === 'number') { + if (v === 0) { + if (1/v === Number.NEGATIVE_INFINITY) { + // format negative zero specially to detect them in the output + return '-0'; + } + } + } + return String(v); +} + +function getDesc(obj, prop) { + var pd; + + if (typeof obj !== 'object' || obj === null) { + return prop + ': non-object (' + Object.prototype.toString.call(obj) + ')'; + } + + pd = Object.getOwnPropertyDescriptor(obj, prop); + + if (pd === undefined) { + return prop + ': undefined'; + } + + return prop + ': ' + + 'value=' + formatValue(pd.value) + + ', writable=' + formatValue(pd.writable) + + ', enumerable=' + formatValue(pd.enumerable) + + ', configurable=' + formatValue(pd.configurable) + + ', typeof(get)=' + formatValue(pd.get) + + ', typeof(set)=' + formatValue(pd.set); +} + +function printDesc(obj, prop) { + print(getDesc(obj, prop)); +} + +/*=== +coercion +[object Undefined] [object Undefined] TypeError +[object Undefined] [object Object] TypeError +[object Null] [object Object] TypeError +[object Boolean] [object Object] TypeError +[object Boolean] [object Object] TypeError +[object Number] [object Object] TypeError +[object String] [object Object] TypeError +[object Array] [object Object] ok +[object Object] [object Object] ok +[object Object] [object Undefined] TypeError +[object Object] [object Undefined] TypeError +[object Object] [object Null] TypeError +[object Object] [object Boolean] ok +[object Object] [object Boolean] ok +[object Object] [object Number] ok +[object Object] [object String] ok +[object Object] [object Array] ok +[object Object] [object Object] ok +===*/ + +/* Test coercion of 'O' and 'Properties' arguments. */ + +print('coercion'); + +function coercionTest() { + function test(o, p, arg_count) { + var t; + + try { + if (arg_count === 0) { + t = Object.defineProperties(); + } else if (arg_count === 1) { + t = Object.defineProperties(o); + } else { + t = Object.defineProperties(o, p); + } + print(Object.prototype.toString.call(o), + Object.prototype.toString.call(p), 'ok'); + } catch (e) { + print(Object.prototype.toString.call(o), + Object.prototype.toString.call(p), e.name); + } + } + + // coercion of 'O' + test(undefined, undefined, 0); + test(undefined, {}); + test(null, {}); + test(true, {}); + test(false, {}); + test(123, {}); + test('quux', {}); + test([1,2], {}); + test({ foo: 1, bar: 2 }, {}); + + // coercion of 'P' + test({}, undefined, 1); + test({}, undefined); + test({}, null); + test({}, true); + test({}, false); + test({}, 123); + test({}, ''); // <-- careful to avoid TypeError from ToPropertyDescriptor() + test({}, []); // (use empty string, array, object) + test({}, {}); // + + // coercion of 'O' and 'P'; 'O' is checked first -- how to test this? +} + +try { + coercionTest(); +} catch (e) { + print(e); +} + +/*=== +proplist +prop1 +prop2 +proto-prop +proto-prop: undefined +nonenum-prop: undefined +prop1: value=prop1, writable=true, enumerable=true, configurable=true, typeof(get)=undefined, typeof(set)=undefined +prop2: value=prop2, writable=true, enumerable=true, configurable=true, typeof(get)=undefined, typeof(set)=undefined +prop1 +prop2 +===*/ + +/* Property list is created from own, enumerable properties of 'Properties' + * argument. + * + * This test expects enum order to match insertion order (but the testcase + * is not marked custom). + */ + +print('proplist'); + +function propListTest() { + var proto = {}; + var props; + var obj; + var i; + + props = Object.create(proto); + + // enumerable, but not 'own property' + Object.defineProperty(proto, 'proto-prop', { + value: { value: 'from-proto', writable: true, enumerable: true, configurable: true }, + writable: true, enumerable: true, configurable: true + }); + + // own property but not enumerable + Object.defineProperty(props, 'nonenum-prop', { + value: { value: 'nonenum', writable: true, enumerable: true, configurable: true }, + writable: true, enumerable: false, configurable: true + }); + + // own property, enumerable -> will appear + Object.defineProperty(props, 'prop1', { + value: { value: 'prop1', writable: true, enumerable: true, configurable: true }, + writable: true, enumerable: true, configurable: true + }); + Object.defineProperty(props, 'prop2', { + value: { value: 'prop2', writable: true, enumerable: true, configurable: true }, + writable: false, enumerable: true, configurable: false + }); + + // for-in will enumerate also inherited properties + for (i in props) { + print(i); + } + + obj = {}; + Object.defineProperties(obj, props); + + printDesc(obj, 'proto-prop'); + printDesc(obj, 'nonenum-prop'); + printDesc(obj, 'prop1'); + printDesc(obj, 'prop2'); + + // prop1 and prop2 addition order should match order in 'props' + for (i in obj) { + print(i); + } +} + +try { + propListTest(); +} catch (e) { + print(e); +} + +/*=== +topropdesc +foo: value=2, writable=true, enumerable=true, configurable=true, typeof(get)=undefined, typeof(set)=undefined +TypeError +foo: value=1, writable=true, enumerable=true, configurable=true, typeof(get)=undefined, typeof(set)=undefined +===*/ + +/* All ToPropertyDescriptor() coercions and checks happen before any object + * properties/attributes are changed. + */ + +print('topropdesc'); + +function toPropDescTest() { + var obj; + + // base case: works + obj = { foo: 1 }; + Object.defineProperties(obj, { + foo: { value: 2 } + }); + printDesc(obj, 'foo'); + + // invalid desc -> nothing is changed + obj = { foo: 1 }; + try { + Object.defineProperties(obj, { + foo: { value: 3 }, // ok + bar: { set: function(){}, value: 123 } // conflict + }); + } catch (e) { + print(e.name); + } + printDesc(obj, 'foo'); +} + +try { + toPropDescTest(); +} catch (e) { + print(e); +} + +/*=== +multiple +foo: value=1, writable=true, enumerable=true, configurable=true, typeof(get)=undefined, typeof(set)=undefined +bar: value=2, writable=false, enumerable=true, configurable=false, typeof(get)=undefined, typeof(set)=undefined +foo +bar +TypeError +foo: value=1, writable=true, enumerable=true, configurable=true, typeof(get)=undefined, typeof(set)=undefined +bar: value=immutable, writable=false, enumerable=false, configurable=false, typeof(get)=undefined, typeof(set)=undefined +foo +===*/ + +/* Multiple changes in one go. Note that since 'Properties' is an Object, + * the same property cannot be edited twice in one defineProperties() call. + * + * Unlike the ToPropertyDescriptor() step, the first TypeError (or other + * error) causes defineProperties() to bail out. + */ + +print('multiple'); + +function multiplePropsTest() { + var obj; + var i; + + // base case + obj = {}; + Object.defineProperties(obj, { + foo: { value: 1, writable: true, enumerable: true, configurable: true }, + bar: { value: 2, writable: false, enumerable: true, configurable: false } + }); + printDesc(obj, 'foo'); + printDesc(obj, 'bar'); + for (i in obj) { + // demonstrate enum order + print(i); + } + + // first edit bails out, so second one is not made + obj = {}; + Object.defineProperty(obj, 'foo', { + value: 'configurable', writable: false, enumerable: false, configurable: true + }); + Object.defineProperty(obj, 'bar', { + value: 'immutable', writable: false, enumerable: false, configurable: false + }); + try { + Object.defineProperties(obj, { + foo: { value: 1, writable: true, enumerable: true, configurable: true }, + bar: { value: 2, writable: false, enumerable: true, configurable: false } + }); + } catch (e) { + print(e.name); + } + printDesc(obj, 'foo'); + printDesc(obj, 'bar'); + for (i in obj) { + // demonstrate enum order + print(i); + } +} + +try { + multiplePropsTest(); +} catch (e) { + print(e); +} + +/*=== +return +true +===*/ + +/* Return value is 'O'. */ + +print('return'); + +function returnValueTest() { + var obj = {}; + var ret; + + ret = Object.defineProperties(obj, { + foo: { value: 1, writable: true, enumerable: true, configurable: true } + }); + print(ret === obj); +} + +try { + returnValueTest(); +} catch (e) { + print(e); +} + diff --git a/testcases/test-builtin-object-proto-tostring-custom.js b/testcases/test-builtin-object-proto-tostring-custom.js new file mode 100644 index 00000000..864f5a7b --- /dev/null +++ b/testcases/test-builtin-object-proto-tostring-custom.js @@ -0,0 +1,13 @@ +/*--- +{ + "skip": true +} +---*/ + +// FIXME: buffer, pointer, etc + +/*=== +FIXME +===*/ + +