From 67a81f7b3c5535f433b55bc95d3ae7c27cbe5f2f Mon Sep 17 00:00:00 2001 From: Sami Vaarala Date: Fri, 22 Feb 2013 17:28:03 +0200 Subject: [PATCH] improvements to JSON stringify test cases --- testcases/test-builtin-json-enc-replacer.js | 36 +++- testcases/test-builtin-json-enc-tojson.js | 26 ++- testcases/test-builtin-json-enc-types.js | 175 ++++++++++++-------- 3 files changed, 162 insertions(+), 75 deletions(-) diff --git a/testcases/test-builtin-json-enc-replacer.js b/testcases/test-builtin-json-enc-replacer.js index be488fef..179a9181 100644 --- a/testcases/test-builtin-json-enc-replacer.js +++ b/testcases/test-builtin-json-enc-replacer.js @@ -12,6 +12,15 @@ replace top level with foo "foo" replace non-empty primitive values {"foo":"foo","bar":"foo","quux":{"key1":"foo","key2":"foo"},"quuux":["foo","foo","foo"]} +ignored replacers +{"foo":1,"bar":"bar"} +{"foo":1,"bar":"bar"} +{"foo":1,"bar":"bar"} +{"foo":1,"bar":"bar"} +{"foo":1,"bar":"bar"} +{"foo":1,"bar":"bar"} +{"foo":1,"bar":"bar"} +{"foo":1,"bar":"bar"} ===*/ function replacerTest1() { @@ -73,6 +82,28 @@ function replacerTest3() { print(JSON.stringify(obj, repl)); } +function replacerTest4() { + var obj = { + foo: 1, + bar: 'bar' + }; + + // replacer must be: + // 1) a callable function + // 2) an array, in which case it is interpreted as a PropertyList + // + // other types must be ignored + + print(JSON.stringify(obj, undefined)); + print(JSON.stringify(obj, null)); + print(JSON.stringify(obj, true)); + print(JSON.stringify(obj, false)); + print(JSON.stringify(obj, 1.23)); + print(JSON.stringify(obj, 'foo')); + print(JSON.stringify(obj, {})); + print(JSON.stringify(obj, { foo: 1, length: 2 })); +} + try { print('identity replacer'); replacerTest1(); @@ -80,8 +111,11 @@ try { print('replace top level with foo'); replacerTest2(); - print('replace non-empty primitive values') + print('replace non-empty primitive values'); replacerTest3(); + + print('ignored replacers'); + replacerTest4(); } catch (e) { print(e.name); } diff --git a/testcases/test-builtin-json-enc-tojson.js b/testcases/test-builtin-json-enc-tojson.js index 9d649e3c..758d90be 100644 --- a/testcases/test-builtin-json-enc-tojson.js +++ b/testcases/test-builtin-json-enc-tojson.js @@ -1,8 +1,9 @@ /*=== {"foo":1,"bar":"bar/toJSON"} -{"foo":1,"bar":"bar/toJSON","quux":{"toJSON":123}} +{"foo":1,"bar":"bar/toJSON","quux":{"toJSON":123},"quuux":{"toJSON":{"foo":"not callable"}},"quuuux":{"toJSON":["not callable"]}} Error quuux/toJSON error {"foo":1,"bar":"bar/toJSON","quux":{"toJSON":123},"quuux":"2012-01-02T03:04:05.006Z"} +{"foo":1,"bar":"bar/toJSON","quux":{"toJSON":123},"quuux":"inherited toJSON"} ===*/ /* Any Object values with a callable toJSON() property will get called, @@ -18,6 +19,7 @@ function toJsonPropertyTest1() { bar: { toJSON: function() { return 'bar/toJSON'; } } }; + // toJSON is called print(JSON.stringify(obj)); } @@ -25,9 +27,12 @@ function toJsonPropertyTest2() { var obj = { foo: 1, bar: { toJSON: function() { return 'bar/toJSON'; } }, - quux: { toJSON: 123 } + quux: { toJSON: 123 }, + quuux: { toJSON: { foo: 'not callable' } }, + quuuux: { toJSON: [ 'not callable' ] }, }; + // toJSON properties are not callable, and are ignored silently print(JSON.stringify(obj)); } @@ -60,11 +65,28 @@ function toJsonPropertyTest4() { print(JSON.stringify(obj)); } +function toJsonPropertyTest5() { + function F() { + } + F.prototype = { toJSON: function() { return 'inherited toJSON'; } }; + + var obj = { + foo: 1, + bar: { toJSON: function() { return 'bar/toJSON'; } }, + quux: { toJSON: 123 }, + quuux: new F() + }; + + // toJSON() can be inherited + print(JSON.stringify(obj)); +} + try { toJsonPropertyTest1(); toJsonPropertyTest2(); toJsonPropertyTest3(); toJsonPropertyTest4(); + toJsonPropertyTest5(); } catch (e) { print(e.name); } diff --git a/testcases/test-builtin-json-enc-types.js b/testcases/test-builtin-json-enc-types.js index 29076c1a..6618dc8a 100644 --- a/testcases/test-builtin-json-enc-types.js +++ b/testcases/test-builtin-json-enc-types.js @@ -1,8 +1,5 @@ var t; -var i; -var x; -var numbers; /*=== undefined undefined @@ -11,16 +8,20 @@ undefined undefined [1,2,null,4] ===*/ -// result is undefined -t = JSON.stringify(undefined); -print(typeof t, t); +try { + // result is undefined + t = JSON.stringify(undefined); + print(typeof t, t); -// undefined values are not serialized in objects -print(JSON.stringify({bar:undefined})); // empty case perhaps worth extra test -print(JSON.stringify({foo:1,bar:undefined})); + // undefined values are not serialized in objects + print(JSON.stringify({bar:undefined})); // empty case perhaps worth extra test + print(JSON.stringify({foo:1,bar:undefined})); -// undefined values are serialized as 'null' in arrays -print(JSON.stringify([1,2,undefined,4])); + // undefined values are serialized as 'null' in arrays + print(JSON.stringify([1,2,undefined,4])); +} catch (e) { + print(e.name); +} /*=== string null @@ -28,38 +29,37 @@ string null [1,2,null,4] ===*/ -t = JSON.stringify(null); -print(typeof t, t); - -print(JSON.stringify({foo:1,bar:null})); - -print(JSON.stringify([1,2,null,4])); +try { + t = JSON.stringify(null); + print(typeof t, t); + print(JSON.stringify({foo:1,bar:null})); + print(JSON.stringify([1,2,null,4])); +} catch (e) { + print(e.name); +} /*=== string true {"foo":1,"bar":true} [1,2,true,4] -===*/ - -t = JSON.stringify(true); -print(typeof t, t); - -print(JSON.stringify({foo:1,bar:true})); - -print(JSON.stringify([1,2,true,4])); - -/*=== string false {"foo":1,"bar":false} [1,2,false,4] ===*/ -t = JSON.stringify(false); -print(typeof t, t); - -print(JSON.stringify({foo:1,bar:false})); +try { + t = JSON.stringify(true); + print(typeof t, t); + print(JSON.stringify({foo:1,bar:true})); + print(JSON.stringify([1,2,true,4])); -print(JSON.stringify([1,2,false,4])); + t = JSON.stringify(false); + print(typeof t, t); + print(JSON.stringify({foo:1,bar:false})); + print(JSON.stringify([1,2,false,4])); +} catch (e) { + print(e.name); +} /*=== string -123 @@ -93,18 +93,25 @@ string null * NaN - "" - */ -numbers = [ -123, -0, +0, 123, - Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY, Number.NaN ]; +function numbersTest() { + var numbers = [ -123, -0, +0, 123, + Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY, Number.NaN ]; + var i; -for (i = 0; i < numbers.length; i++) { - x = numbers[i]; + for (i = 0; i < numbers.length; i++) { + x = numbers[i]; - t = JSON.stringify(x); - print(typeof t, t); - - print(JSON.stringify({foo:1,bar:x})); + t = JSON.stringify(x); + print(typeof t, t); + print(JSON.stringify({foo:1,bar:x})); + print(JSON.stringify([1,2,x,4])); + } +} - print(JSON.stringify([1,2,x,4])); +try { + numbersTest(); +} catch (e) { + print(e.name); } /*=== @@ -125,17 +132,24 @@ string "foo \n\"bar" /* Basic cases for strings. */ -strings = [ "foo", "foo \n\"bar" ]; +function stringsTest() { + var strings = [ "foo", "foo \n\"bar" ]; + var i; -for (i = 0; i < strings.length; i++) { - x = strings[i]; - - t = JSON.stringify(x); - print(typeof t, t); + for (i = 0; i < strings.length; i++) { + x = strings[i]; - print(JSON.stringify({foo:1,bar:x})); + t = JSON.stringify(x); + print(typeof t, t); + print(JSON.stringify({foo:1,bar:x})); + print(JSON.stringify([1,2,x,4])); + } +} - print(JSON.stringify([1,2,x,4])); +try { + stringsTest(); +} catch (e) { + print(e.name); } /*=== @@ -220,21 +234,30 @@ for (i = 0; i < strings.length; i++) { * be escaped by JSON.stringify(). */ -// special chars -strings = [ '"', '\\', '/' ]; -for (i = 0; i < strings.length; i++) { - t = JSON.stringify(strings[i]); - print(t); -} +function escapeTest() { + var strings = [ '"', '\\', '/' ]; + var i; -for (i = 0; i <= 32; i++) { - t = JSON.stringify(String.fromCharCode(i)); - print(t); + for (i = 0; i < strings.length; i++) { + t = JSON.stringify(strings[i]); + print(t); + } + + for (i = 0; i <= 32; i++) { + t = JSON.stringify(String.fromCharCode(i)); + print(t); + } + + for (i = 0x80; i < 0xa0; i++) { + t = JSON.stringify(String.fromCharCode(i)); + print(t.charCodeAt(0), t.charCodeAt(1), t.charCodeAt(2)); + } } -for (i = 0x80; i < 0xa0; i++) { - t = JSON.stringify(String.fromCharCode(i)); - print(t.charCodeAt(0), t.charCodeAt(1), t.charCodeAt(2)); +try { + escapeTest(); +} catch (e) { + print(e.name); } /*=== @@ -242,8 +265,12 @@ for (i = 0x80; i < 0xa0; i++) { ===*/ /* Very basic object/array serialization test. */ -t = JSON.stringify({foo:1,bar:'text',object:{baz:2},array:[1,2,3]}); -print(t); +try { + t = JSON.stringify({foo:1,bar:'text',object:{baz:2},array:[1,2,3]}); + print(t); +} catch (e) { + print(e.name); +} /*=== [1,2,null,4] @@ -253,15 +280,19 @@ print(t); /* Functions (anything callable) serialize as 'null' */ -// anonymous Ecmascript function -t = JSON.stringify([1,2,function(){},4]); -print(t); +try { + // anonymous Ecmascript function + t = JSON.stringify([1,2,function(){},4]); + print(t); -// native function -t = JSON.stringify([1,2,Object.prototype.toString,4]); -print(t); + // native function + t = JSON.stringify([1,2,Object.prototype.toString,4]); + print(t); -// bound function -t = JSON.stringify([1,2,print.bind('foo'),4]); -print(t); + // bound function + t = JSON.stringify([1,2,print.bind('foo'),4]); + print(t); +} catch (e) { + print(e.name); +}