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.
140 lines
3.8 KiB
140 lines
3.8 KiB
12 years ago
|
/*
|
||
|
* Test the property list (2nd argument) of JSON.stringify().
|
||
|
*/
|
||
|
|
||
|
/*===
|
||
|
{"foo":1,"bar":2,"baz":4}
|
||
|
{"baz":4,"foo":1,"bar":2}
|
||
|
{"foo":1,"bar":2,"baz":4}
|
||
|
{"baz":4,"foo":1,"bar":2}
|
||
|
===*/
|
||
|
|
||
|
/* If the 2nd argument to stringify() is an array, it becomes the
|
||
|
* PropertyList of the serialization algorithm and affects the JO()
|
||
|
* algorithm concretely.
|
||
|
*
|
||
|
* The specification requires that serialization of properties will:
|
||
|
*
|
||
|
* (1) allow serialization of non-enumerable properties
|
||
|
* (2) will follow PropertyList order, not the object's enumeration
|
||
|
* order (order of properties in Object.keys())
|
||
|
* (3) block serializing the same property name multiple times
|
||
|
* (E5.1 Section 15.12.3, main algorithm, step 4.b.ii.5)
|
||
|
*
|
||
|
* E5.1 Section 15.12.3, main algorithm, step 4.b.ii.ii is tricky:
|
||
|
* it requires that array indexed properties are enumerated in
|
||
|
* ascending order. This is stricter than normal enumeration
|
||
|
* requirements and causes some compliance issues in the current
|
||
|
* implementation when a sparse array is used. There are separate
|
||
|
* tests for this case.
|
||
|
*
|
||
|
* Note that at least V8 does not block serialization of the same
|
||
|
* property name. There is a separate test for this, too.
|
||
|
*/
|
||
|
|
||
|
function stringifyPropertyListTest1() {
|
||
|
var obj = {
|
||
|
"foo": 1,
|
||
|
"bar": 2,
|
||
|
"quux": 3
|
||
|
};
|
||
|
|
||
|
Object.defineProperties(obj, {
|
||
|
baz: { value: 4, enumerable: false, configurable: true, writable: true }
|
||
|
});
|
||
|
|
||
|
// baz is non-enumerable
|
||
|
var txt = JSON.stringify(obj, [ 'foo', 'bar', 'baz' ]);
|
||
|
print(txt);
|
||
|
|
||
|
// different order
|
||
|
var txt = JSON.stringify(obj, [ 'baz', 'foo', 'bar' ]);
|
||
|
print(txt);
|
||
|
}
|
||
|
|
||
|
function stringifyPropertyListTest2() {
|
||
|
// test that inherited properties are also correctly enumerated
|
||
|
// when using a PropertyList
|
||
|
|
||
|
var proto = {};
|
||
|
|
||
|
function F() {
|
||
|
// quux and baz are inherited
|
||
|
this.foo = 1;
|
||
|
this.bar = 2;
|
||
|
}
|
||
|
F.prototype = proto;
|
||
|
|
||
|
var obj;
|
||
|
|
||
|
Object.defineProperties(proto, {
|
||
|
quux: { value: 3, enumerable: true, writable: true, configurable: true },
|
||
|
baz: { value: 4, enumerable: false, writable: true, configurable: true },
|
||
|
});
|
||
|
|
||
|
obj = new F();
|
||
|
|
||
|
var txt = JSON.stringify(obj, [ 'foo', 'bar', 'baz' ]);
|
||
|
print(txt);
|
||
|
|
||
|
var txt = JSON.stringify(obj, [ 'baz', 'foo', 'bar' ]);
|
||
|
print(txt);
|
||
|
}
|
||
|
|
||
|
try {
|
||
|
stringifyPropertyListTest1();
|
||
|
stringifyPropertyListTest2();
|
||
|
} catch (e) {
|
||
|
print(e.name);
|
||
|
}
|
||
|
|
||
|
/*===
|
||
|
{"foo":1,"baz":4}
|
||
|
{"foo":1,"baz":4,"bar":2}
|
||
|
{"foo":1,"baz":4}
|
||
|
{"foo":1,"1.2":"val:1.2","2.2":"val:2.2","NaN":"val:NaN"}
|
||
|
===*/
|
||
|
|
||
|
/* Test invalid values in the property list: anything other than a number,
|
||
|
* a string, a Number object, or a String object is ignored.
|
||
|
*/
|
||
|
|
||
|
function stringifyPropertyListTest3() {
|
||
|
var obj = { foo: 1, bar: 2, quux: 3, baz: 4 };
|
||
|
|
||
|
// add some properties to ensure invalid PropertyList keys are not
|
||
|
// coerced incorrectly and look up one of these
|
||
|
obj['' + true] = 'val:true';
|
||
|
obj['' + false] = 'val:false';
|
||
|
obj['null'] = 'val:null';
|
||
|
obj['0'] = 'val:0';
|
||
|
obj['1'] = 'val:1';
|
||
|
|
||
|
// these will be legitimately accessed, numbers are coerced
|
||
|
obj['1.2'] = 'val:1.2';
|
||
|
obj['2.2'] = 'val:2.2';
|
||
|
obj['NaN'] = 'val:NaN';
|
||
|
|
||
|
// undefined will be skipped
|
||
|
print(JSON.stringify(obj, [ 'foo', undefined, 'baz' ]));
|
||
|
|
||
|
// null, true, false will be skipped
|
||
|
print(JSON.stringify(obj, [ 'foo', null, 'baz', true, false, 'bar' ]));
|
||
|
|
||
|
// function will be skipped, Date will be skipped, array and object
|
||
|
// will be skipped
|
||
|
print(JSON.stringify(obj, [ 'foo', function () {}, new Date(0), {}, [], 'baz' ]));
|
||
|
|
||
|
// null will be skipped
|
||
|
// ToString(1.2) = '1.2'; ToString(new Number(2.2)) = '2.2', ToString(0/0) = 'NaN'
|
||
|
print(JSON.stringify(obj, [ 'foo', null, 1.2, new Number(2.2), 0/0 ]));
|
||
|
}
|
||
|
|
||
|
try {
|
||
|
stringifyPropertyListTest3();
|
||
|
} catch (e) {
|
||
|
print(e.name);
|
||
|
}
|
||
|
|
||
|
|