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.
 
 
 
 
 
 

343 lines
12 KiB

/*===
basic reviver
reviver called
name:
val: foo
holder: [object Object]
{"":"foo"}
===*/
/* Basic reviver test. */
print('basic reviver');
function basicReviverTest() {
var v;
function reviver(name, val) {
var holder = this;
print('reviver called');
print('name:', name);
print('val:', val);
print('holder:', holder);
print(JSON.stringify(holder));
}
v = JSON.parse('"foo"', reviver);
}
try {
basicReviverTest();
} catch (e) {
print(e.name);
}
/*===
complex reviver test
{"k_null":null, "k_true":true, "k_false":false, "k_num":123, "k_str":"str", "k_arr":[1,2], "k_obj":{"foo":1,"bar":2}}
reviver: json(name)="k_null", json(val)=null, json(holder)={"k_null":null,"k_true":true,"k_false":false,"k_num":123,"k_str":"str","k_arr":[1,2],"k_obj":{"foo":1,"bar":2}}
reviver: json(name)="k_true", json(val)=true, json(holder)={"k_null":null,"k_true":true,"k_false":false,"k_num":123,"k_str":"str","k_arr":[1,2],"k_obj":{"foo":1,"bar":2}}
reviver: json(name)="k_false", json(val)=false, json(holder)={"k_null":null,"k_true":true,"k_false":false,"k_num":123,"k_str":"str","k_arr":[1,2],"k_obj":{"foo":1,"bar":2}}
reviver: json(name)="k_num", json(val)=123, json(holder)={"k_null":null,"k_true":true,"k_false":false,"k_num":123,"k_str":"str","k_arr":[1,2],"k_obj":{"foo":1,"bar":2}}
reviver: json(name)="k_str", json(val)="str", json(holder)={"k_null":null,"k_true":true,"k_false":false,"k_num":123,"k_str":"str","k_arr":[1,2],"k_obj":{"foo":1,"bar":2}}
reviver: json(name)="0", json(val)=1, json(holder)=[1,2]
reviver: json(name)="1", json(val)=2, json(holder)=[1,2]
reviver: json(name)="k_arr", json(val)=[1,2], json(holder)={"k_null":null,"k_true":true,"k_false":false,"k_num":123,"k_str":"str","k_arr":[1,2],"k_obj":{"foo":1,"bar":2}}
reviver: json(name)="foo", json(val)=1, json(holder)={"foo":1,"bar":2}
reviver: json(name)="bar", json(val)=2, json(holder)={"foo":1,"bar":2}
reviver: json(name)="k_obj", json(val)={"foo":1,"bar":2}, json(holder)={"k_null":null,"k_true":true,"k_false":false,"k_num":123,"k_str":"str","k_arr":[1,2],"k_obj":{"foo":1,"bar":2}}
reviver: json(name)="", json(val)={"k_null":null,"k_true":true,"k_false":false,"k_num":123,"k_str":"str","k_arr":[1,2],"k_obj":{"foo":1,"bar":2}}, json(holder)={"":{"k_null":null,"k_true":true,"k_false":false,"k_num":123,"k_str":"str","k_arr":[1,2],"k_obj":{"foo":1,"bar":2}}}
{"k_null":null,"k_true":true,"k_false":false,"k_num":123,"k_str":"str","k_arr":[1,2],"k_obj":{"foo":1,"bar":2}}
===*/
/* A more complex reviver test; no changes are made, just check the
* call order and arguments.
*/
print('complex reviver test');
function complexReviverTest() {
var txt;
var v;
function reviver(name, val) {
var holder = this;
print('reviver: json(name)=' + JSON.stringify(name) +
', json(val)=' + JSON.stringify(val) +
', json(holder)=' + JSON.stringify(holder));
return val;
}
txt = '{"k_null":null, "k_true":true, "k_false":false, ' +
'"k_num":123, "k_str":"str", "k_arr":[1,2], ' +
'"k_obj":{"foo":1,"bar":2}}';
print(txt);
v = JSON.parse(txt, reviver);
print(JSON.stringify(v));
}
try {
complexReviverTest();
} catch (e) {
print(e.name, e);
}
/*===
reviver deletion test
{"k_null":null, "k_true":true, "k_false":false, "k_num":123, "k_str":"str", "k_arr":[1,2], "k_obj":{"foo":1,"bar":2}}
reviver: json(name)="k_null", json(val)=null, json(holder)={"k_null":null,"k_true":true,"k_false":false,"k_num":123,"k_str":"str","k_arr":[1,2],"k_obj":{"foo":1,"bar":2}}
reviver: json(name)="k_true", json(val)=true, json(holder)={"k_null":null,"k_true":true,"k_false":false,"k_num":123,"k_str":"str","k_arr":[1,2],"k_obj":{"foo":1,"bar":2}}
reviver: json(name)="k_false", json(val)=false, json(holder)={"k_null":null,"k_false":false,"k_num":123,"k_str":"str","k_arr":[1,2],"k_obj":{"foo":1,"bar":2}}
reviver: json(name)="k_num", json(val)=123, json(holder)={"k_null":null,"k_false":false,"k_num":123,"k_str":"str","k_arr":[1,2],"k_obj":{"foo":1,"bar":2}}
reviver: json(name)="k_str", json(val)="str", json(holder)={"k_null":null,"k_false":false,"k_num":123,"k_str":"str","k_arr":[1,2],"k_obj":{"foo":1,"bar":2}}
reviver: json(name)="0", json(val)=1, json(holder)=[1,2]
reviver: json(name)="1", json(val)=2, json(holder)=[1,2]
reviver: json(name)="k_arr", json(val)=[1,2], json(holder)={"k_null":null,"k_false":false,"k_num":123,"k_str":"str","k_arr":[1,2],"k_obj":{"foo":1,"bar":2}}
reviver: json(name)="foo", json(val)=1, json(holder)={"foo":1,"bar":2}
reviver: json(name)="bar", json(val)=2, json(holder)={"foo":1,"bar":2}
reviver: json(name)="k_obj", json(val)={"foo":1,"bar":2}, json(holder)={"k_null":null,"k_false":false,"k_num":123,"k_str":"str","k_obj":{"foo":1,"bar":2}}
reviver: json(name)="", json(val)={"k_null":null,"k_false":false,"k_num":123,"k_str":"str","k_obj":{"foo":1,"bar":2}}, json(holder)={"":{"k_null":null,"k_false":false,"k_num":123,"k_str":"str","k_obj":{"foo":1,"bar":2}}}
{"k_null":null,"k_false":false,"k_num":123,"k_str":"str","k_obj":{"foo":1,"bar":2}}
===*/
/* Reviver deletion test. */
print('reviver deletion test');
function reviverDeletionTest() {
var txt;
var v;
function reviver(name, val) {
var holder = this;
print('reviver: json(name)=' + JSON.stringify(name) +
', json(val)=' + JSON.stringify(val) +
', json(holder)=' + JSON.stringify(holder));
// delete k_arr and k_true
if (name === 'k_arr' || name === 'k_true') {
return;
}
return val;
}
txt = '{"k_null":null, "k_true":true, "k_false":false, ' +
'"k_num":123, "k_str":"str", "k_arr":[1,2], ' +
'"k_obj":{"foo":1,"bar":2}}';
print(txt);
v = JSON.parse(txt, reviver);
print(JSON.stringify(v));
}
try {
reviverDeletionTest();
} catch (e) {
print(e.name);
}
/*===
reviver replacement test
{"k_null":null, "k_true":true, "k_false":false, "k_num":123, "k_str":"str", "k_arr":[1,2], "k_obj":{"foo":1,"bar":2}}
reviver: json(name)="k_null", json(val)=null, json(holder)={"k_null":null,"k_true":true,"k_false":false,"k_num":123,"k_str":"str","k_arr":[1,2],"k_obj":{"foo":1,"bar":2}}
reviver: json(name)="k_true", json(val)=true, json(holder)={"k_null":null,"k_true":true,"k_false":false,"k_num":123,"k_str":"str","k_arr":[1,2],"k_obj":{"foo":1,"bar":2}}
reviver: json(name)="k_false", json(val)=false, json(holder)={"k_null":null,"k_true":[3,2,1],"k_false":false,"k_num":123,"k_str":"str","k_arr":[1,2],"k_obj":{"foo":1,"bar":2}}
reviver: json(name)="k_num", json(val)=123, json(holder)={"k_null":null,"k_true":[3,2,1],"k_false":false,"k_num":123,"k_str":"str","k_arr":[1,2],"k_obj":{"foo":1,"bar":2}}
reviver: json(name)="k_str", json(val)="str", json(holder)={"k_null":null,"k_true":[3,2,1],"k_false":false,"k_num":123,"k_str":"str","k_arr":[1,2],"k_obj":{"foo":1,"bar":2}}
reviver: json(name)="0", json(val)=1, json(holder)=[1,2]
reviver: json(name)="1", json(val)=2, json(holder)=[1,2]
reviver: json(name)="k_arr", json(val)=[1,2], json(holder)={"k_null":null,"k_true":[3,2,1],"k_false":false,"k_num":123,"k_str":"str","k_arr":[1,2],"k_obj":{"foo":1,"bar":2}}
reviver: json(name)="foo", json(val)=1, json(holder)={"foo":1,"bar":2}
reviver: json(name)="bar", json(val)=2, json(holder)={"foo":1,"bar":2}
reviver: json(name)="k_obj", json(val)={"foo":1,"bar":2}, json(holder)={"k_null":null,"k_true":[3,2,1],"k_false":false,"k_num":123,"k_str":"str","k_arr":{"foo":"foo","bar":"bar"},"k_obj":{"foo":1,"bar":2}}
reviver: json(name)="", json(val)={"k_null":null,"k_true":[3,2,1],"k_false":false,"k_num":123,"k_str":"str","k_arr":{"foo":"foo","bar":"bar"},"k_obj":{"foo":1,"bar":2}}, json(holder)={"":{"k_null":null,"k_true":[3,2,1],"k_false":false,"k_num":123,"k_str":"str","k_arr":{"foo":"foo","bar":"bar"},"k_obj":{"foo":1,"bar":2}}}
{"k_null":null,"k_true":[3,2,1],"k_false":false,"k_num":123,"k_str":"str","k_arr":{"foo":"foo","bar":"bar"},"k_obj":{"foo":1,"bar":2}}
===*/
/* Reviver replacement test.
*
* In particular, test whether or not reviver will walk through the returned;
* it should not.
*/
print('reviver replacement test');
function reviverReplacementTest() {
var txt;
var v;
function reviver(name, val) {
var holder = this;
print('reviver: json(name)=' + JSON.stringify(name) +
', json(val)=' + JSON.stringify(val) +
', json(holder)=' + JSON.stringify(holder));
// replace k_true with [3,2,1] and k_arr with {foo:'foo',bar:'bar}
if (name === 'k_arr') {
return { foo: 'foo', bar: 'bar' };
} else if (name === 'k_true') {
return [ 3, 2, 1 ];
} else {
return val;
}
}
txt = '{"k_null":null, "k_true":true, "k_false":false, ' +
'"k_num":123, "k_str":"str", "k_arr":[1,2], ' +
'"k_obj":{"foo":1,"bar":2}}';
print(txt);
v = JSON.parse(txt, reviver);
print(JSON.stringify(v));
}
try {
reviverReplacementTest();
} catch (e) {
print(e.name);
}
/*===
reviver object identity
{"foo":1,"bar":2}
reviver: json(name)="foo", json(val)=1, json(holder)={"foo":1,"bar":2}
reviver: json(name)="bar", json(val)=2, json(holder)={"foo":{},"bar":2}
reviver: json(name)="", json(val)={"foo":{},"bar":{}}, json(holder)={"":{"foo":{},"bar":{}}}
{"foo":{},"bar":{}}
true
true
true
===*/
/* Check that replacement values are used as is. In particular,
* returning the same object retains object identity in the result.
*/
print('reviver object identity');
function reviverObjectIdentityTest() {
var txt;
var v;
var repl_value = {}; // test this identity
function reviver(name, val) {
var holder = this;
print('reviver: json(name)=' + JSON.stringify(name) +
', json(val)=' + JSON.stringify(val) +
', json(holder)=' + JSON.stringify(holder));
if (name === 'foo' || name === 'bar') {
return repl_value;
} else {
return val;
}
}
txt = '{"foo":1,"bar":2}';
print(txt);
v = JSON.parse(txt, reviver);
print(JSON.stringify(v));
print(v.foo === repl_value);
print(v.bar === repl_value);
print(v.foo === v.bar);
}
try {
reviverObjectIdentityTest();
} catch (e) {
print(e.name);
}
/*===
reviver name type test
{"foo":1,"bar":[2,3]}
object string number
object string number
object string number
object string object
object string object
{"foo":1,"bar":[2,3]}
===*/
/* Reviver 'name' argument is a string key of an object, or a string
* coercion (ToString(arr_index)) of an array index.
*
* (Rhino uses a numeric array index key.)
*/
print('reviver name type test');
function reviverNameTypeTest() {
function reviver(name, val) {
print(typeof this, typeof name, typeof val);
return val;
}
txt = '{"foo":1,"bar":[2,3]}';
print(txt);
v = JSON.parse(txt, reviver);
print(JSON.stringify(v));
}
try {
reviverNameTypeTest();
} catch (e) {
print(e.name);
}
/*===
invalid revivers
{"foo":1,"bar":2}
{"foo":1,"bar":2}
{"foo":1,"bar":2}
{"foo":1,"bar":2}
{"foo":1,"bar":2}
{"foo":1,"bar":2}
{"foo":1,"bar":2}
{"foo":1,"bar":2}
{"foo":1,"bar":2}
===*/
/* Reviver must callable; other values are ignored silently. */
print('invalid revivers');
function testInvalidRevivers() {
var v;
// base case
v = JSON.parse('{"foo":1,"bar":2}');
print(JSON.stringify(v));
v = JSON.parse('{"foo":1,"bar":2}', undefined);
print(JSON.stringify(v));
v = JSON.parse('{"foo":1,"bar":2}', null);
print(JSON.stringify(v));
v = JSON.parse('{"foo":1,"bar":2}', true);
print(JSON.stringify(v));
v = JSON.parse('{"foo":1,"bar":2}', false);
print(JSON.stringify(v));
v = JSON.parse('{"foo":1,"bar":2}', 1.23);
print(JSON.stringify(v));
v = JSON.parse('{"foo":1,"bar":2}', 'foo');
print(JSON.stringify(v));
v = JSON.parse('{"foo":1,"bar":2}', []);
print(JSON.stringify(v));
v = JSON.parse('{"foo":1,"bar":2}', {});
print(JSON.stringify(v));
}
try {
testInvalidRevivers();
} catch (e) {
print(e.name);
}