mirror of https://github.com/svaarala/duktape.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
331 lines
13 KiB
331 lines
13 KiB
/*
|
|
* Tests for Object isSealed(), isFrozen(), isExtensible(), seal(),
|
|
* and freeze().
|
|
*/
|
|
|
|
/*===
|
|
sealed: false, frozen: false, extensible: true
|
|
sealed: true, frozen: false, extensible: false
|
|
sealed: false, frozen: false, extensible: true
|
|
sealed: true, frozen: true, extensible: false
|
|
sealed: false, frozen: false, extensible: true
|
|
sealed: true, frozen: false, extensible: false
|
|
sealed: false, frozen: false, extensible: true
|
|
sealed: true, frozen: true, extensible: false
|
|
===*/
|
|
|
|
function basicTest() {
|
|
var obj;
|
|
|
|
function p(o) {
|
|
print('sealed: ' + Object.isSealed(o) +
|
|
', frozen: ' + Object.isFrozen(o) +
|
|
', extensible: ' + Object.isExtensible(o));
|
|
}
|
|
|
|
obj = { foo: 1, bar: 2 };
|
|
p(obj);
|
|
Object.seal(obj);
|
|
p(obj);
|
|
|
|
obj = { foo: 1, bar: 2 };
|
|
p(obj);
|
|
Object.freeze(obj);
|
|
p(obj);
|
|
|
|
// create objects which are already sealed/frozen(), without a
|
|
// seal() or freeze() call.
|
|
|
|
obj = Object.create(Object.prototype, {
|
|
prop1: { value: 123, writable: true, enumerable: true, configurable: false },
|
|
prop2: { get: function(){}, set: function(){}, enumerable: true, configurable: false }
|
|
});
|
|
p(obj); // extensible -> not sealed or frozen
|
|
Object.preventExtensions(obj); // now sealed, but not frozen (writable property exists)
|
|
p(obj);
|
|
|
|
// sealed and frozen
|
|
obj = Object.create(Object.prototype, {
|
|
prop1: { value: 123, writable: false, enumerable: true, configurable: false },
|
|
prop2: { get: function(){}, set: function(){}, enumerable: true, configurable: false }
|
|
});
|
|
p(obj); // extensible -> not sealed or frozen
|
|
Object.preventExtensions(obj); // now sealed and frozen: no writable properties, accessors are OK
|
|
p(obj);
|
|
}
|
|
|
|
try {
|
|
basicTest();
|
|
} catch (e) {
|
|
print(e);
|
|
}
|
|
|
|
/*===
|
|
object, #names: 12, extensible: true
|
|
index: 0, name: prop1, value: 1, writable: true, enumerable: true, configurable: true, get: undefined, set: undefined
|
|
index: 1, name: prop2, value: 2, writable: false, enumerable: true, configurable: true, get: undefined, set: undefined
|
|
index: 2, name: prop3, value: 3, writable: true, enumerable: false, configurable: true, get: undefined, set: undefined
|
|
index: 3, name: prop4, value: 4, writable: false, enumerable: false, configurable: true, get: undefined, set: undefined
|
|
index: 4, name: prop5, value: 5, writable: true, enumerable: true, configurable: false, get: undefined, set: undefined
|
|
index: 5, name: prop6, value: 6, writable: false, enumerable: true, configurable: false, get: undefined, set: undefined
|
|
index: 6, name: prop7, value: 7, writable: true, enumerable: false, configurable: false, get: undefined, set: undefined
|
|
index: 7, name: prop8, value: 8, writable: false, enumerable: false, configurable: false, get: undefined, set: undefined
|
|
index: 8, name: acc1, value: undefined, writable: undefined, enumerable: true, configurable: true, get: function, set: function
|
|
index: 9, name: acc2, value: undefined, writable: undefined, enumerable: false, configurable: true, get: function, set: function
|
|
index: 10, name: acc3, value: undefined, writable: undefined, enumerable: true, configurable: false, get: function, set: function
|
|
index: 11, name: acc4, value: undefined, writable: undefined, enumerable: false, configurable: false, get: function, set: function
|
|
object, #names: 12, extensible: false
|
|
index: 0, name: prop1, value: 1, writable: true, enumerable: true, configurable: false, get: undefined, set: undefined
|
|
index: 1, name: prop2, value: 2, writable: false, enumerable: true, configurable: false, get: undefined, set: undefined
|
|
index: 2, name: prop3, value: 3, writable: true, enumerable: false, configurable: false, get: undefined, set: undefined
|
|
index: 3, name: prop4, value: 4, writable: false, enumerable: false, configurable: false, get: undefined, set: undefined
|
|
index: 4, name: prop5, value: 5, writable: true, enumerable: true, configurable: false, get: undefined, set: undefined
|
|
index: 5, name: prop6, value: 6, writable: false, enumerable: true, configurable: false, get: undefined, set: undefined
|
|
index: 6, name: prop7, value: 7, writable: true, enumerable: false, configurable: false, get: undefined, set: undefined
|
|
index: 7, name: prop8, value: 8, writable: false, enumerable: false, configurable: false, get: undefined, set: undefined
|
|
index: 8, name: acc1, value: undefined, writable: undefined, enumerable: true, configurable: false, get: function, set: function
|
|
index: 9, name: acc2, value: undefined, writable: undefined, enumerable: false, configurable: false, get: function, set: function
|
|
index: 10, name: acc3, value: undefined, writable: undefined, enumerable: true, configurable: false, get: function, set: function
|
|
index: 11, name: acc4, value: undefined, writable: undefined, enumerable: false, configurable: false, get: function, set: function
|
|
object, #names: 12, extensible: true
|
|
index: 0, name: prop1, value: 1, writable: true, enumerable: true, configurable: true, get: undefined, set: undefined
|
|
index: 1, name: prop2, value: 2, writable: false, enumerable: true, configurable: true, get: undefined, set: undefined
|
|
index: 2, name: prop3, value: 3, writable: true, enumerable: false, configurable: true, get: undefined, set: undefined
|
|
index: 3, name: prop4, value: 4, writable: false, enumerable: false, configurable: true, get: undefined, set: undefined
|
|
index: 4, name: prop5, value: 5, writable: true, enumerable: true, configurable: false, get: undefined, set: undefined
|
|
index: 5, name: prop6, value: 6, writable: false, enumerable: true, configurable: false, get: undefined, set: undefined
|
|
index: 6, name: prop7, value: 7, writable: true, enumerable: false, configurable: false, get: undefined, set: undefined
|
|
index: 7, name: prop8, value: 8, writable: false, enumerable: false, configurable: false, get: undefined, set: undefined
|
|
index: 8, name: acc1, value: undefined, writable: undefined, enumerable: true, configurable: true, get: function, set: function
|
|
index: 9, name: acc2, value: undefined, writable: undefined, enumerable: false, configurable: true, get: function, set: function
|
|
index: 10, name: acc3, value: undefined, writable: undefined, enumerable: true, configurable: false, get: function, set: function
|
|
index: 11, name: acc4, value: undefined, writable: undefined, enumerable: false, configurable: false, get: function, set: function
|
|
object, #names: 12, extensible: false
|
|
index: 0, name: prop1, value: 1, writable: false, enumerable: true, configurable: false, get: undefined, set: undefined
|
|
index: 1, name: prop2, value: 2, writable: false, enumerable: true, configurable: false, get: undefined, set: undefined
|
|
index: 2, name: prop3, value: 3, writable: false, enumerable: false, configurable: false, get: undefined, set: undefined
|
|
index: 3, name: prop4, value: 4, writable: false, enumerable: false, configurable: false, get: undefined, set: undefined
|
|
index: 4, name: prop5, value: 5, writable: false, enumerable: true, configurable: false, get: undefined, set: undefined
|
|
index: 5, name: prop6, value: 6, writable: false, enumerable: true, configurable: false, get: undefined, set: undefined
|
|
index: 6, name: prop7, value: 7, writable: false, enumerable: false, configurable: false, get: undefined, set: undefined
|
|
index: 7, name: prop8, value: 8, writable: false, enumerable: false, configurable: false, get: undefined, set: undefined
|
|
index: 8, name: acc1, value: undefined, writable: undefined, enumerable: true, configurable: false, get: function, set: function
|
|
index: 9, name: acc2, value: undefined, writable: undefined, enumerable: false, configurable: false, get: function, set: function
|
|
index: 10, name: acc3, value: undefined, writable: undefined, enumerable: true, configurable: false, get: function, set: function
|
|
index: 11, name: acc4, value: undefined, writable: undefined, enumerable: false, configurable: false, get: function, set: function
|
|
===*/
|
|
|
|
function propertyAttributeTest() {
|
|
var obj;
|
|
var prop_names = [ 'prop1', 'prop2', 'prop3', 'prop4',
|
|
'prop5', 'prop6', 'prop7', 'prop8',
|
|
'acc1', 'acc2', 'acc3', 'acc4' ];
|
|
|
|
function mkGetter() {
|
|
return function getter() {
|
|
print('getter called');
|
|
throw new Error('unexpected getter call');
|
|
};
|
|
}
|
|
function mkSetter() {
|
|
return function getter() {
|
|
print('setter called');
|
|
throw new Error('unexpected setter call');
|
|
};
|
|
}
|
|
function mkObj() {
|
|
var obj = {};
|
|
Object.defineProperties(obj, {
|
|
prop1: { value: 1, writable: true, enumerable: true, configurable: true },
|
|
prop2: { value: 2, writable: false, enumerable: true, configurable: true },
|
|
prop3: { value: 3, writable: true, enumerable: false, configurable: true },
|
|
prop4: { value: 4, writable: false, enumerable: false, configurable: true },
|
|
prop5: { value: 5, writable: true, enumerable: true, configurable: false },
|
|
prop6: { value: 6, writable: false, enumerable: true, configurable: false },
|
|
prop7: { value: 7, writable: true, enumerable: false, configurable: false },
|
|
prop8: { value: 8, writable: false, enumerable: false, configurable: false },
|
|
acc1: { get: mkGetter(), set: mkSetter(), enumerable: true, configurable: true },
|
|
acc2: { get: mkGetter(), set: mkSetter(), enumerable: false, configurable: true },
|
|
acc3: { get: mkGetter(), set: mkSetter(), enumerable: true, configurable: false },
|
|
acc4: { get: mkGetter(), set: mkSetter(), enumerable: false, configurable: false },
|
|
});
|
|
|
|
/*
|
|
For some reason V8 (at least 3.7.12.22) reorders these properties regardless
|
|
of whether one uses defineProperty() or defineProperties(). So, we read back
|
|
properties with explicitly ordered names below instead of relying on
|
|
Object.getOwnPropertyNames().
|
|
|
|
Object.defineProperty(obj, 'prop1', { value: 1, writable: true, enumerable: true, configurable: true });
|
|
Object.defineProperty(obj, 'prop2', { value: 2, writable: false, enumerable: true, configurable: true });
|
|
Object.defineProperty(obj, 'prop3', { value: 3, writable: true, enumerable: false, configurable: true });
|
|
Object.defineProperty(obj, 'prop4', { value: 4, writable: false, enumerable: false, configurable: true });
|
|
Object.defineProperty(obj, 'prop5', { value: 5, writable: true, enumerable: true, configurable: false });
|
|
Object.defineProperty(obj, 'prop6', { value: 6, writable: false, enumerable: true, configurable: false });
|
|
Object.defineProperty(obj, 'prop7', { value: 7, writable: true, enumerable: false, configurable: false });
|
|
Object.defineProperty(obj, 'prop8', { value: 8, writable: false, enumerable: false, configurable: false });
|
|
Object.defineProperty(obj, 'acc1', { get: mkGetter(), set: mkSetter(), enumerable: true, configurable: true });
|
|
Object.defineProperty(obj, 'acc2', { get: mkGetter(), set: mkSetter(), enumerable: false, configurable: true });
|
|
Object.defineProperty(obj, 'acc3', { get: mkGetter(), set: mkSetter(), enumerable: true, configurable: false });
|
|
Object.defineProperty(obj, 'acc4', { get: mkGetter(), set: mkSetter(), enumerable: false, configurable: false });
|
|
*/
|
|
|
|
return obj;
|
|
}
|
|
function printObj(o) {
|
|
var i, pd;
|
|
|
|
names = Object.getOwnPropertyNames(o);
|
|
print('object, #names: ' + names.length + ', extensible: ' + Object.isExtensible(o));
|
|
|
|
/* Use explicit names because V8 loses property order for some reason */
|
|
|
|
for (i = 0; i < prop_names.length; i++) {
|
|
pd = Object.getOwnPropertyDescriptor(o, prop_names[i]);
|
|
print('index: ' + i +
|
|
', name: ' + prop_names[i] +
|
|
', value: ' + pd.value +
|
|
', writable: ' + pd.writable +
|
|
', enumerable: ' + pd.enumerable +
|
|
', configurable: ' + pd.configurable +
|
|
', get: ' + typeof pd.get +
|
|
', set: ' + typeof pd.set);
|
|
}
|
|
}
|
|
|
|
obj = mkObj();
|
|
printObj(obj);
|
|
Object.seal(obj);
|
|
printObj(obj);
|
|
|
|
obj = mkObj();
|
|
printObj(obj);
|
|
Object.freeze(obj);
|
|
printObj(obj);
|
|
}
|
|
|
|
try {
|
|
propertyAttributeTest();
|
|
} catch (e) {
|
|
print(e);
|
|
}
|
|
|
|
/*===
|
|
0 0
|
|
TypeError
|
|
0 1
|
|
TypeError
|
|
0 2
|
|
TypeError
|
|
0 3
|
|
TypeError
|
|
0 4
|
|
TypeError
|
|
0 5
|
|
TypeError
|
|
0 6
|
|
ok
|
|
0 7
|
|
ok
|
|
1 0
|
|
TypeError
|
|
1 1
|
|
TypeError
|
|
1 2
|
|
TypeError
|
|
1 3
|
|
TypeError
|
|
1 4
|
|
TypeError
|
|
1 5
|
|
TypeError
|
|
1 6
|
|
ok
|
|
1 7
|
|
ok
|
|
2 0
|
|
TypeError
|
|
2 1
|
|
TypeError
|
|
2 2
|
|
TypeError
|
|
2 3
|
|
TypeError
|
|
2 4
|
|
TypeError
|
|
2 5
|
|
TypeError
|
|
2 6
|
|
ok
|
|
2 7
|
|
ok
|
|
3 0
|
|
TypeError
|
|
3 1
|
|
TypeError
|
|
3 2
|
|
TypeError
|
|
3 3
|
|
TypeError
|
|
3 4
|
|
TypeError
|
|
3 5
|
|
TypeError
|
|
3 6
|
|
ok
|
|
3 7
|
|
ok
|
|
4 0
|
|
TypeError
|
|
4 1
|
|
TypeError
|
|
4 2
|
|
TypeError
|
|
4 3
|
|
TypeError
|
|
4 4
|
|
TypeError
|
|
4 5
|
|
TypeError
|
|
4 6
|
|
ok
|
|
4 7
|
|
ok
|
|
===*/
|
|
|
|
function coercionTest() {
|
|
var funcs = [
|
|
Object.isSealed, Object.isFrozen, Object.isExtensible,
|
|
Object.seal, Object.freeze
|
|
];
|
|
var values = [
|
|
undefined, null, true, false, 123, 'foo',
|
|
[1,2], { foo: 1, bar: 2 }
|
|
];
|
|
var i, j;
|
|
|
|
function test(func, obj) {
|
|
try {
|
|
func(obj);
|
|
print('ok');
|
|
} catch (e) {
|
|
print(e.name);
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < funcs.length; i++) {
|
|
for (j = 0; j < values.length; j++) {
|
|
print(i, j);
|
|
test(funcs[i], values[j]);
|
|
}
|
|
}
|
|
}
|
|
|
|
try {
|
|
coercionTest();
|
|
} catch (e) {
|
|
print(e);
|
|
}
|
|
|
|
/* FIXME: test that ancestors have no effect and or not affected */
|
|
|
|
|