Browse Source

Testcase changes for ROM string/object support

- Specific testcases to exercise ROM string/object support.
  Also document current limitations through tests.

- Misc. testcase fixes.
pull/559/head
Sami Vaarala 9 years ago
parent
commit
73ce2f01eb
  1. 34
      tests/api/test-dev-rom-builtins-1.c
  2. 4
      tests/api/test-dump-load-basic.c
  3. 4
      tests/ecmascript/test-bi-string-fromcharcode.js
  4. 453
      tests/ecmascript/test-dev-rom-builtins-1.js

34
tests/api/test-dev-rom-builtins-1.c

@ -0,0 +1,34 @@
/*
* Some tests for using ROM strings and builtins, but a writable global
* object.
*
* Run manually.
*/
/*---
{
"skip": true
}
---*/
/*===
*** test_set_prototype (duk_safe_call)
==> rc=1, result='TypeError: not configurable'
===*/
/* Prevent setting prototype of a built-in object from C code. This is
* different from setPrototypeOf() because the C API does not care if
* the object is non-extensible.
*/
static duk_ret_t test_set_prototype(duk_context *ctx) {
duk_eval_string(ctx, "Math");
duk_push_object(ctx); /* dummy */
duk_set_prototype(ctx, -2);
printf("final top: %ld\n", (long) duk_get_top(ctx));
return 0;
}
void test(duk_context *ctx) {
TEST_SAFE_CALL(test_set_prototype);
}

4
tests/api/test-dump-load-basic.c

@ -40,7 +40,7 @@
/*===
*** test_basic (duk_safe_call)
dump result type: 7
ff000000000e0000000300000001000900000000000100000001300004c0000000f300400052000040c200000114000101400001414c800041c38000820301014030000141000000814201804030000040000000006f00000000057072696e74000000000568656c6c6f0140091eb851eb851f000000030000000000000000000300020000000100000001300604400080009a0000806f0000002f000000020000000561646465720000000f66616b6546696c656e616d652e6a730000000d03000000010000000c000000000000000178000000000000000179000000010000000000000001780000000179000000000000000000000006676c6f62616c0000000f66616b6546696c656e616d652e6a730000000e0e000000010000000c00000000000000000000000000
ff000000000e000000030000000100090000000000010000000130000980000000f300400052000040c200000114000101400001414c800041c38000820301014030000141000000814201804030000040000000006f00000000057072696e74000000000568656c6c6f0140091eb851eb851f000000030000000000000000000300020000000100000001300c08800080009a0000806f0000002f000000020000000561646465720000000f66616b6546696c656e616d652e6a730000000d03000000010000000c000000000000000178000000000000000179000000010000000000000001780000000179000000000000000000000006676c6f62616c0000000f66616b6546696c656e616d652e6a730000000e0e000000010000000c00000000000000000000000000
load result type: 6
hello 3 3.14
call result type: 1
@ -91,7 +91,7 @@ static duk_ret_t test_basic(duk_context *ctx) {
/*===
*** test_mandel (duk_safe_call)
Mandelbrot source length: 884
ff000000005c000000100000000000130000000000010000001e300604c0801300038007004380190083000008338000156e8000016e800000c30080c3ab0003802d800000ee800013ee0000c3b67ffffeae0080c39d8003839c8083821b0000483380000fee800001ee800001030004023300040340000103ab0003802d800000ee80000dee000103b67ffffeae0001039d8103839c818381db0000883380000a6e8000022e80000143800002438000028300010182010143ab0003802d800000ee8000082e000143b67ffffeae048242dc0502831c0602c39a828383ab0003806d800001ae04c0c39c0503839c0403829a0602c39b0383825a7ffffcae810143ab0003806d800000ae000181828000036e838143ab0003806d800000ae000201828000022e848143ab0003806d800000ae00028182800000ee0002c1828000006e7ffff82e0000887300034380000303c20783839800018400008380307ffff26e00004873004343920003440000038442088404180003c48200840030008380307fffec6e000008730000002f014004000000000000013ff400000000000001400800000000000001400000000000000000000000012301401000000000000000000000012e01401400000000000000000000012c01402400000000000000000000012d00000000013d00000000047075736800000000057072696e7400000000046a6f696e000000000000000000000000066d616e64656c000000096d616e64656c2e6a73000000285c000000020000001400000013000000210000002880201001008004244108910080844a02100420000000017700000000000000016800000001000000046974657200000002000000016900000003000000016a00000004000000016b000000050000000163000000060000000278300000000700000002793000000008000000027878000000090000000279790000000a000000037878320000000b000000037979320000000c000000046c696e650000000d0000000000000000
ff000000005c000000100000000000130000000000010000001e300c0980801300038007004380190083000008338000156e8000016e800000c30080c3ab0003802d800000ee800013ee0000c3b67ffffeae0080c39d8003839c8083821b0000483380000fee800001ee800001030004023300040340000103ab0003802d800000ee80000dee000103b67ffffeae0001039d8103839c818381db0000883380000a6e8000022e80000143800002438000028300010182010143ab0003802d800000ee8000082e000143b67ffffeae048242dc0502831c0602c39a828383ab0003806d800001ae04c0c39c0503839c0403829a0602c39b0383825a7ffffcae810143ab0003806d800000ae000181828000036e838143ab0003806d800000ae000201828000022e848143ab0003806d800000ae00028182800000ee0002c1828000006e7ffff82e0000887300034380000303c20783839800018400008380307ffff26e00004873004343920003440000038442088404180003c48200840030008380307fffec6e000008730000002f014004000000000000013ff400000000000001400800000000000001400000000000000000000000012301401000000000000000000000012e01401400000000000000000000012c01402400000000000000000000012d00000000013d00000000047075736800000000057072696e7400000000046a6f696e000000000000000000000000066d616e64656c000000096d616e64656c2e6a73000000285c000000020000001400000013000000210000002880201001008004244108910080844a02100420000000017700000000000000016800000001000000046974657200000002000000016900000003000000016a00000004000000016b000000050000000163000000060000000278300000000700000002793000000008000000027878000000090000000279790000000a000000037878320000000b000000037979320000000c000000046c696e650000000d0000000000000000
..........................,,,,,,,,,,,,,,,,,,,,,,,,,.........................
....................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,...................
................,,,,,,,,,,,,,,,,,,,,,,,,,,,---=----,,,,,,,,,,...............

4
tests/ecmascript/test-bi-string-fromcharcode.js

@ -36,7 +36,7 @@ function fromCharCodeTest() {
var tmp = [];
tmp.push(typeof x);
tmp.push(x.length);
for (i = 0; i < x.length; i++) {
for (var i = 0; i < x.length; i++) {
tmp.push(x.charCodeAt(i));
}
print(tmp.join(' '));
@ -45,7 +45,7 @@ function fromCharCodeTest() {
function mkObj(name, strval, numval) {
return {
toString: function() { print('toString() for ' + name); return strval; },
valueOf: function() { print('valueOf() for ' + name); return numval }
valueOf: function() { print('valueOf() for ' + name); return numval; }
};
}

453
tests/ecmascript/test-dev-rom-builtins-1.js

@ -0,0 +1,453 @@
/*
* Some tests for using ROM strings and builtins, but a writable global
* object.
*
* Run manually. The test case assumes DUK_USE_ROM_GLOBAL_INHERIT.
*/
/*---
{
"custom": true,
"skip": true
}
---*/
var global = new Function('return this;')();
/*===
--- extensibility
Math extensible: false
global extensible: true
===*/
function romObjectExtensibleTest() {
/* ROM objects are marked non-extensible so that attempts to create new
* properties on them will fail.
*/
print('Math extensible: ' + Object.isExtensible(Math));
/* When global object is made writable (DUK_USE_ROM_GLOBAL_CLONE or
* DUK_USE_ROM_GLOBAL_INHERIT) it is extensible to allow new properties
* to be added.
*/
print('global extensible: ' + Object.isExtensible(global));
}
/*===
--- global object
property descriptor of global.RegExp: undefined
RegExp in global: true
===*/
function romObjectGlobalObjectTest() {
var pd;
/* When DUK_USE_ROM_GLOBAL_INHERIT is used, ordinary global object
* properties are inherited from a (non-standard) ROM global object
* so that properties won't appear as "own" properties of the global
* object.
*/
pd = Object.getOwnPropertyDescriptor(global, 'RegExp');
print('property descriptor of global.RegExp:', Duktape.enc('jx', pd));
print('RegExp in global:', 'RegExp' in global);
}
/*===
--- property attributes
property descriptor of RegExp.prototype.exec: {value:{_func:true},writable:true,enumerable:false,configurable:false}
123
in non-strict mode the failed write is ignored silently
nonwritable property
in non-strict mode the failed write is ignored silently
function
number
{value:0,writable:true,enumerable:false,configurable:false}
in non-strict mode the failed write is ignored silently
Array.prototype[0]: undefined
in non-strict mode the failed write is ignored silently
Array.prototype.length: 0
===*/
function romObjectPropertyAttributeTest() {
var pd;
/* Property attributes for properties of ROM objects:
*
* - Configurable: always false, property cannot be edited.
* - Enumerable: depends on property.
* - Writable: depends on property.
*
* The "writable" attribute is set to "true" to allow an inheriting
* object to gain overriding properties, but actual writes to the
* ROM object itself will fail.
*/
pd = Object.getOwnPropertyDescriptor(RegExp.prototype, 'exec');
print('property descriptor of RegExp.prototype.exec:', Duktape.enc('jx', pd));
/* Example of how a non-writable ancestor property would prevent
* creating a new property on an object.
*/
var parent = {};
Object.defineProperty(parent, 'prop', {
value: 'nonwritable property',
writable: false,
enumerable: false,
configurable: false
});
var child = {};
Object.setPrototypeOf(child, parent);
try {
/* Creating an own property "prop" on the child is not allowed
* because parent.prop is not writable. This is why some ROM
* properties are presented as writable from property attributes
* point of view.
*/
print(child.prop = 123);
print('in non-strict mode the failed write is ignored silently');
} catch (e) {
print(e.name);
}
print(child.prop);
/* Even though ROM properties (like Date.prototype.getMonth) appear
* writable, they can't be overwritten directly.
*/
try {
Date.prototype.getMonth = function fake() {};
print('in non-strict mode the failed write is ignored silently');
} catch (e) {
print(e.name);
}
/* But it's possible to inherit and overwrite in the child. */
var child = {};
Object.setPrototypeOf(child, RegExp.prototype);
print(typeof child.exec);
child.exec = 123;
print(typeof child.exec);
/* Array.prototype.length is technically writable too. */
print(Duktape.enc('jx', Object.getOwnPropertyDescriptor(Array.prototype, 'length')));
/* Can't assign to Array.prototype indices nor its length. */
try {
Array.prototype[0] = 1;
print('in non-strict mode the failed write is ignored silently');
} catch (e) {
print(e.name);
}
print('Array.prototype[0]:', Array.prototype[0]);
try {
Array.prototype.length = 0;
print('in non-strict mode the failed write is ignored silently');
} catch (e) {
print(e.name);
}
print('Array.prototype.length:', Array.prototype.length);
}
/*===
--- property write
function
123
function
number
boolean
===*/
function romObjectPropertyWriteTest() {
// duk_hobject_putprop()
/* Trying to overwrite a plain property fails silently. */
try {
print(typeof Date.prototype.getYear);
print(Date.prototype.getYear = 123);
} catch (e) {
print(e.name);
}
print(typeof Date.prototype.getYear);
/* Trying to write to a setter is allowed and captured by the setter.
* The built-in objects don't have many setters, but Error.prototype
* has a few which we can use to test.
*/
try {
var err = new Error('aiee');
print(typeof err.lineNumber);
err.lineNumber = true; // setter captures and operates on 'err'
} catch (e) {
print(e.name);
}
print(typeof err.lineNumber);
}
/*===
--- property delete
true
still here
false
false
still here
true
===*/
function romObjectPropertyDeleteTest() {
// duk_hobject_delprop_raw()
// Attempt to delete a non-existent property succeeds as normal.
try {
print(delete RegExp.prototype.nonExistent);
print('still here');
} catch (e) {
print(e.name);
}
print('nonExistent' in RegExp.prototype);
// Attempt to delete a ROM object property fails.
try {
print(delete Date.prototype.getSeconds);
print('still here');
} catch (e) {
print(e.name);
}
print('getSeconds' in Date.prototype);
}
/*===
--- defineProperty
{value:{_func:true},writable:true,enumerable:false,configurable:false}
still here
still here
TypeError
TypeError
TypeError
TypeError
TypeError
===*/
function romObjectDefinePropertyTest() {
var old;
var pd;
pd = Object.getOwnPropertyDescriptor(Date.prototype, 'getMinutes');
print(Duktape.enc('jx', pd));
old = pd.value;
// Trying to set current property values works and causes no errors.
try {
Object.defineProperty(Date.prototype, 'getMinutes', pd);
print('still here');
} catch (e) {
print(e.name);
}
// Trying to set current property values works and causes no errors,
// here with partial descriptor.
try {
Object.defineProperty(Date.prototype, 'getMinutes', { value: old });
print('still here');
} catch (e) {
print(e.name);
}
// Trying to set a different value fails.
try {
Object.defineProperty(Date.prototype, 'getMinutes', { value: 123 });
print('still here');
} catch (e) {
print(e.name);
}
try {
Object.defineProperty(Date.prototype, 'getMinutes', { writable: false });
print('still here');
} catch (e) {
print(e.name);
}
try {
Object.defineProperty(Date.prototype, 'getMinutes', { enumerable: true });
print('still here');
} catch (e) {
print(e.name);
}
try {
Object.defineProperty(Date.prototype, 'getMinutes', { configurable: true });
print('still here');
} catch (e) {
print(e.name);
}
// Attempt to change descriptor type fails.
try {
Object.defineProperty(Date.prototype, 'getMinutes', { set: function() {}, get: function() {} });
print('still here');
} catch (e) {
print(e.name);
}
}
/*===
--- setPrototypeOf
Math extensible: false
TypeError
===*/
function romObjectSetPrototypeOfTest() {
// Object.setPrototypeOf() for a read-only object causes a type error.
// There's no explicit check, but the built-ins are not extensible which
// prevents setPrototypeOf.
try {
print('Math extensible: ' + Object.isExtensible(Math));
Object.setPrototypeOf(Math, {});
} catch (e) {
print(e.name);
}
}
/*===
--- seal/freeze
TypeError
TypeError
===*/
function romObjectSealFreezeTest() {
// duk_hobject_seal_freeze_helper()
// Object.seal() is ignored with no memory violation.
try {
print(Object.prototype.toString.call(Object.seal(Math)));
} catch (e) {
print(e.name);
}
// Object.freeze() is ignored with no memory violation.
try {
print(Object.prototype.toString.call(Object.freeze(Math)));
} catch (e) {
print(e.name);
}
}
/*===
--- compact
[object Math]
true
===*/
function romObjectCompactTest() {
// duk_hobject_compact_props(): Duktape.compact()
// Compaction of a read-only object is ignored with no memory violation.
// Returned value must still be the argument.
print(Object.prototype.toString.call(Duktape.compact(Math)));
print(Math === Duktape.compact(Math));
}
/*===
--- Date toGMTString/toUTCString
true
===*/
function romObjectDateGmtUtcStringTest() {
// These two references must point to the same built-in function
// object (not just logically same).
print(Date.prototype.toGMTString === Date.prototype.toUTCString);
}
/*===
--- Boolean prototype _Value
false
===*/
function romObjectBooleanInternalValueTest() {
var pfx = Duktape.dec('hex', 'ff');
var key = pfx + 'Value';
print(Duktape.enc('jx', Boolean.prototype[key]));
}
/*===
--- RegExp prototype matches empty string
"\x00\x02\x0b\x00\x0b\x01\x01"
true
[""]
===*/
function romObjectRegExpTest() {
var pfx = Duktape.dec('hex', 'ff');
var key = pfx + 'Bytecode';
print(Duktape.enc('jx', RegExp.prototype[key]));
print(Duktape.enc('jx', RegExp.prototype.test('')));
print(Duktape.enc('jx', RegExp.prototype.exec('')));
}
/*===
--- Error.prototype setter/getter
{get:{_func:true},set:{_func:true},enumerable:false,configurable:false}
get length: 0, set length: 0
{get:{_func:true},set:{_func:true},enumerable:false,configurable:false}
get length: 0, set length: 0
{get:{_func:true},set:{_func:true},enumerable:false,configurable:false}
get length: 0, set length: 0
===*/
function romObjectErrorPrototypeAccessorTest() {
function test(key) {
var pd = Object.getOwnPropertyDescriptor(Error.prototype, key);
print(Duktape.enc('jx', pd));
print('get length: ' + pd.get.length + ', set length: ' + pd.set.length);
}
test('fileName');
test('lineNumber');
test('stack');
}
// Read-only code paths related to object properties which aren't covered:
//
// duk_hobject_props.c:duk_realloc_props(): assert, can't be exercised directly.
// duk_hobject_props.c:duk__putprop_shallow_fastpath_array_tval(): assert, can't be exercised directly.
// duk_hobject_props.c:duk__putprop_fastpath_bufobj_tval(): assert, can't be exercised directly.
try {
print('--- extensibility');
romObjectExtensibleTest();
print('--- global object');
romObjectGlobalObjectTest();
print('--- property attributes');
romObjectPropertyAttributeTest();
print('--- property write');
romObjectPropertyWriteTest();
print('--- property delete');
romObjectPropertyDeleteTest();
print('--- defineProperty');
romObjectDefinePropertyTest();
print('--- setPrototypeOf');
romObjectSetPrototypeOfTest();
print('--- seal/freeze');
romObjectSealFreezeTest();
print('--- compact');
romObjectCompactTest();
print('--- Date toGMTString/toUTCString');
romObjectDateGmtUtcStringTest();
print('--- Boolean prototype _Value');
romObjectBooleanInternalValueTest();
print('--- RegExp prototype matches empty string');
romObjectRegExpTest();
print('--- Error.prototype setter/getter');
romObjectErrorPrototypeAccessorTest();
} catch (e) {
print(e.stack || e);
}
Loading…
Cancel
Save