json.html revision 43b5d5546545f891acfcdc4960557d9028fb1109
<!doctype html>
<html>
<head>
<title>Test Page</title>
h1 {
font: normal 125%/1.4 Arial, sans-serif;
}
.yui-skin-sam .yui-console .yui-console-content {
font-size: 10px;
width: 32em;
}
.yui-skin-sam .yui-console .yui-console-bd {
height: 50em;
}
.yui-skin-sam .yui-console-entry-pass .yui-console-entry-cat {
background: #070;
color: #fff;
}
.yui-skin-sam .yui-console-entry-fail .yui-console-entry-cat {
background: #700;
color: #fff;
}
.highlight-example {
display: inline;
float: left;
width: 650px;
}
.highlight-example h2 {
display: none;
}
</style>
</head>
<body class="yui-skin-sam">
<h1>Tests</h1>
<div id="testbed"></div>
<script type="text/javascript">
YUI({
base : '/build/',
filter : 'debug',
useBrowserConsole : false,
logInclude : { TestRunner: true }
}).use('test','console','json',function (Y) {
var d = document,
suite = new Y.Test.Suite("JSON Tests"),
JSON_STRING;
JSON_STRING = '[\
"JSON Test Pattern pass1",\
{"object with 1 member":["array with 1 element"]},\
{},\
[],\
-42,\
true,\
false,\
null,\
{\
"integer": 1234567890,\
"real": -9876.543210,\
"e": 0.123456789e-12,\
"E": 1.234567890E+34,\
"": 23456789012E66,\
"zero": 0,\
"one": 1,\
"space": " ",\
"quote": "\\"",\
"backslash": "\\\\",\
"controls": "\\b\\f\\n\\r\\t",\
"slash": "/ & \\/",\
"alpha": "abcdefghijklmnopqrstuvwxyz",\
"ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWXYZ",\
"digit": "0123456789",\
"0123456789": "digit",\
"special": "`1~!@#$%^&*()_+-={\':[,]}|;.</>?",\
"hex": "\\u0123\\u4567\\u89AB\\uCDEF\\uabcd\\uef4A",\
"true": true,\
"false": false,\
"null": null,\
"array":[ ],\
"object":{ },\
"address": "50 St. James Street",\
"url": "http://www.JSON.org/",\
"comment": "// /* <!-- --",\
"# -- --> */": " ",\
" s p a c e d " :[1,2 , 3\
\
,\
\
4 , 5 , 6 ,7 ],"compact":[1,2,3,4,5,6,7],\
"jsontext": "{\\\"object with 1 member\\\":[\\\"array with 1 element\\\"]}",\
"quotes": "" \\u0022 %22 0x22 034 "",\
"\\/\\\\\\"\\uCAFE\\uBABE\\uAB98\\uFCDE\\ubcda\\uef4A\\b\\f\\n\\r\\t`1~!@#$%^&*()_+-=[]{}|;:\',./<>?" : "A key can be any string"\
},\
0.5 ,98.6\
,\
99.44\
,\
\
1066,\
1e1,\
0.1e1,\
1e-1,\
1e00,\
2e+00,\
2e-00,\
"rosebud"]';
/*****************************/
/* Tests begin here */
/*****************************/
suite.add(new Y.Test.Case({
name : "parse",
_should : {
error : {
//test_failOnNonObjectWrapper : true,
test_failOnEmptyString : true,
test_failOnFunction : true,
test_failOnRegex : true,
test_failOnNew : true,
test_failOnUnquotedVal : true,
test_failOnUnquotedKey : true,
test_failOnUnclosedObject : true,
test_failOnUnclosedArray : true,
//test_failOnExtraCommaInObject : true,
test_failOnDoubleExtraCommaInObject : true,
//test_failOnExtraCommaInArray : true,
//test_failOnDoubleExtraCommaInArray : true,
//test_failOnMissingValue : true,
test_failOnCommaAfterClose : true,
test_failOnValueAfterClose : true,
test_failOnExtraClose : true,
test_failOnExpression : true,
//test_failOnZeroPrefixedNumber : true,
test_failOnHex : true,
test_failOnIllegalBackslashEscape : true,
test_failOnMissingColon : true,
test_failOnDoubleColon : true,
test_failOnCommaInsteadOfColon : true,
//test_failOnExtraClose : true,
test_failOnColonInsteadOfComma : true,
test_failOnSingleQuote : true,
test_failOnTabCharacter : true,
test_failOnLineBreakChar : true,
test_failOnMismatchedClose : true
}
},
test_emptyObject : function () {
Y.Assert.isObject(Y.JSON.parse("{}"));
},
test_emptyArray : function () {
Y.Assert.isObject(Y.JSON.parse("[]"));
},
test_JSONNatives : function () {
// Note: backslashes are double escaped to emulate string returned from
// server.
var data = Y.JSON.parse('{"obj":{},"arr":[],"f":false,"t":true,"n":null,"int":12345,"fl":1.2345,"str":"String\\nwith\\tescapes"}');
Y.Assert.isObject(data);
Y.Assert.areSame(false,data.f);
Y.Assert.areSame(true,data.t);
Y.Assert.areSame(12345,data.int);
Y.Assert.areSame(1.2345,data.fl);
Y.Assert.areSame("String\nwith\tescapes",data.str);
},
test_basics : function () {
var data = Y.JSON.parse(JSON_STRING);
Y.Assert.isArray(data);
Y.Assert.isString(data[0]);
Y.Assert.isObject(data[1]);
Y.Assert.isArray(data[1]["object with 1 member"]);
Y.Assert.areSame(1,data[1]["object with 1 member"].length);
Y.Assert.isNumber(data[4]);
Y.Assert.isBoolean(data[5]);
Y.Assert.isBoolean(data[6]);
Y.Assert.isNull(data[7]);
Y.Assert.areSame(1234567890,data[8].integer);
Y.Assert.areSame(-9876.543210,data[8].real);
Y.Assert.areSame(0.123456789e-12,data[8].e);
Y.Assert.areSame(1.234567890e+34,data[8].E);
Y.Assert.areSame(23456789012E66,data[8][""]);
Y.Assert.areSame(0,data[8].zero);
Y.Assert.areSame(1,data[8].one);
Y.Assert.areSame(" ",data[8].space);
Y.Assert.areSame('"',data[8].quote);
Y.Assert.areSame("\\",data[8].backslash);
Y.Assert.areSame("\b\f\n\r\t",data[8].controls);
Y.Assert.areSame("/ & \/",data[8].slash);
Y.Assert.areSame("abcdefghijklmnopqrstuvwxyz",data[8].alpha);
Y.Assert.areSame("ABCDEFGHIJKLMNOPQRSTUVWXYZ",data[8].ALPHA);
Y.Assert.areSame("0123456789",data[8].digit);
Y.Assert.areSame("digit",data[8]["0123456789"]);
Y.Assert.areSame(1234567890,data[8].integer);
Y.Assert.areSame("`1~!@#$%^&*()_+-={':[,]}|;.</>?",data[8].special);
Y.Assert.areSame("\u0123\u4567\u89AB\uCDEF\uabcd\uef4A",data[8].hex);
Y.Assert.areSame(true,data[8]["true"]);
Y.Assert.areSame(false,data[8]["false"]);
Y.Assert.isNull(data[8]["null"]);
Y.Assert.isArray(data[8]["array"]);
Y.Assert.isObject(data[8]["object"]);
Y.Assert.areSame("http://www.JSON.org/",data[8].url);
Y.Assert.areSame("// /* <!-- --",data[8].comment);
Y.Assert.areSame(" ",data[8]["# -- --> */"]);
Y.ArrayAssert.itemsAreSame([1,2,3,4,5,6,7],data[8][" s p a c e d "]);
Y.ArrayAssert.itemsAreSame([1,2,3,4,5,6,7],data[8].compact);
Y.Assert.areSame("{\"object with 1 member\":[\"array with 1 element\"]}",data[8].jsontext);
Y.Assert.areSame("" \u0022 %22 0x22 034 "",data[8].quotes);
Y.Assert.areSame("A key can be any string",data[8]["\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?"]);
Y.Assert.areSame(0.5,data[9]);
Y.Assert.areSame(98.6,data[10]);
Y.Assert.areSame(99.44,data[11]);
Y.Assert.areSame(1066,data[12]);
Y.Assert.areSame(1e1,data[13]);
Y.Assert.areSame(0.1e1,data[14]);
Y.Assert.areSame(1e-1,data[15]);
Y.Assert.areSame(1e00,data[16]);
Y.Assert.areSame(2e+00,data[17]);
Y.Assert.areSame(2e-00,data[18]);
Y.Assert.areSame("rosebud",data[19]);
},
test_failOnNonObjectWrapper : function () {
// Technically these should fail as invalid JSON
Y.Assert.areSame('this is a string',Y.JSON.parse('"this is a string"'));
Y.log("Parsed raw string, but should have failed.","warn","TestRunner");
Y.Assert.areSame(true,Y.JSON.parse('true'));
Y.log("Parsed raw boolean, but should have failed.","warn","TestRunner");
Y.Assert.areSame(12345,Y.JSON.parse("12345"));
Y.Assert.areSame(1.2345,Y.JSON.parse("1.2345"));
Y.log("Parsed raw number, but should have failed.","warn","TestRunner");
Y.Assert.areSame(null,Y.JSON.parse("null"));
Y.log("Parsed raw null, but should have failed.","warn","TestRunner");
},
test_failOnEmptyString : function () {
// parse should throw an error
Y.log("Parsed empty string, but should have failed.","warn","TestRunner");
},
test_failOnFunction : function () {
// parse should throw an error
Y.JSON.parse('{"fn":function(){}}');
Y.log("Parsed a function, but should have failed.","warn","TestRunner");
},
test_failOnRegex : function () {
// parse should throw an error
Y.JSON.parse('{"re":/abc/}');
Y.log("Parsed regular expression literal, but should have failed.","warn","TestRunner");
},
test_failOnNew : function () {
// parse should throw an error
Y.JSON.parse('{"dt":new Date()}');
},
test_failOnUnquotedVal : function () {
// parse should throw an error
Y.JSON.parse('{"foo":bar}');
Y.log("Parsed unquoted non-native value, but should have failed.","warn","TestRunner");
},
test_failOnUnquotedKey : function () {
// parse should throw an error
Y.JSON.parse('{foo:1}');
Y.log("Parsed unquoted object key, but should have failed.","warn","TestRunner");
},
test_failOnUnclosedObject : function () {
// parse should throw an error
Y.JSON.parse('{"unclosed":"object"');
Y.log("Parsed unclosed object, but should have failed.","warn","TestRunner");
},
test_failOnUnclosedArray : function () {
// parse should throw an error
Y.JSON.parse('["unclosed array"');
Y.log("Parsed unclosed array, but should have failed.","warn","TestRunner");
},
test_failOnExtraCommaInObject : function () {
// Will fail in IE only
// parse should throw an error
Y.JSON.parse('{"extra":"comma",}');
Y.log("Parsed object with extra comma, but should have failed.","warn","TestRunner");
},
test_failOnDoubleExtraCommaInObject : function () {
// parse should throw an error
Y.JSON.parse('{"extra":"commas",,}');
Y.log("Parsed object with two extra commas, but should have failed.","warn","TestRunner");
},
test_failOnExtraCommaInArray : function () {
// Will fail in IE only
// parse should throw an error
Y.JSON.parse('["extra","comma",]');
Y.log("Parsed array with extra comma, but should have failed.","warn","TestRunner");
},
test_failOnDoubleExtraCommaInArray : function () {
// Will fail in IE only
// parse should throw an error
Y.JSON.parse('["extra","commas",,]');
Y.log("Parsed array with two extra commas, but should have failed.","warn","TestRunner");
},
test_failOnMissingValue : function () {
// parse should throw an error
},
test_failOnCommaAfterClose : function () {
// parse should throw an error
},
test_failOnValueAfterClose : function () {
// parse should throw an error
},
test_failOnExtraClose : function () {
// parse should throw an error
},
test_failOnExpression : function () {
// parse should throw an error
},
test_failOnZeroPrefixedNumber : function () {
// parse should throw an error
},
test_failOnHex : function () {
// parse should throw an error
},
test_failOnIllegalBackslashEscape : function () {
// parse should throw an error
},
test_failOnMissingColon : function () {
// parse should throw an error
},
test_failOnDoubleColon : function () {
// parse should throw an error
},
test_failOnCommaInsteadOfColon : function () {
// parse should throw an error
},
test_failOnColonInsteadOfComma : function () {
// parse should throw an error
},
test_failOnSingleQuote : function () {
// parse should throw an error
},
test_failOnLineBreakChar : function () {
// parse should throw an error
},
test_failOnMismatchedClose : function () {
// parse should throw an error
}
}));
suite.add(new Y.Test.Case({
name : "stringify",
test_stringifyNatives: function () {
Y.Assert.areSame('[true,false,null,-0.12345,"string",{"object with one member":["array with one element"]}]',
Y.JSON.stringify([true,false,null,-0.12345,"string",{"object with one member":["array with one element"]}]));
},
test_stringifyObject : function () {
// stringify sorts the keys
Y.Assert.areSame('{"five":"String with\\nnewline","four":null,"one":1,"six":{"nested":-0.12345},"three":false,"two":true}',
Y.JSON.stringify({one:1,two:true,three:false,four:null,five:"String with\nnewline",six : {nested:-0.12345}}));
},
test_stringifyRecursiveObject : function () {
var o = { key: 'value' };
o.recurse = o;
Y.JSON.stringify(o));
o = [1,2,3];
o[3] = o;
Y.Assert.areSame('[1,2,3,null]', Y.JSON.stringify(o));
o = [1,2,3,{key:"value",nest:[4,5,6,{foo:"bar"}]}];
o[4] = o[3].x = o[3].nest[4] =
o[3].nest[3].y = o[3].nest[3].z = o;
Y.Assert.areSame('[1,2,3,{"key":"value","nest":[4,5,6,{"foo":"bar","y":null,"z":null},null],"x":null},null]',
Y.JSON.stringify(o));
},
test_stringifyFunction : function () {
functions : function (are,ignored) {},
arr : [ function () {} ]
}));
},
test_stringifyRegex : function () {
regex : /are treated as objects/,
arr : [ new RegExp("in array") ]
}));
},
test_stringifyUndefined : function () {
undef : undefined,
arr : [ undefined ]
}));
},
test_stringifyDate : function () {
Y.JSON.stringify({dt : new Date(1946,6,6)}));
}
}));
suite.add(new Y.Test.Case({
name : "whitelist",
test_emptyWhitelistArray : function () {
Y.Assert.areSame('{}',
Y.JSON.stringify({foo:1,bar:[1,2,3],baz:true},[]));
1,true,null,{
foo : false,
bar : -0.12345
},["string",undefined,/some regex/]
],[]));
},
test_whitelistArray : function () {
foo : [
1,2,3,{
foo : "FOO",
baz : true
}
],
bar : [1,2,3],
baz : true
},["foo"]));
foo : [
1,2,3,{
foo : "FOO",
baz : true
}
],
bar : [
1,2,3,{
foo : "FOO",
baz : true
}
],
baz : true},["foo","baz"]));
},
test_whitelistObject : function () {
// (undocumented) supports an obj literal as well
foo : [
1,2,3,{
foo : "FOO",
baz : true
}
],
bar : [
1,2,3,{
foo : "FOO",
baz : true
}
],
baz : true
}, {foo : true, baz : false})); // values ignored
}
}));
suite.add(new Y.Test.Case({
name : "depth",
test_depthDeeperThanStruct : function () {
foo : [ 2, {
bar : [ 4, {
baz : [ 6, {
"deep enough" : 7
}]
}]
}]
},null,20));
},
test_depthEqualsStructDepth : function () {
foo : [ 2, {
bar : [ 4, {
baz : [ 6, {
"deep enough" : 7
}]
}]
}]
},null,7));
},
test_depthShallowerThanStruct : function () {
var o = {
foo : [ 2, {
bar : [ 4, {
baz : [ 6, {
"deep enough" : 7
}]
}]
}]
};
Y.JSON.stringify(o,null,6));
Y.JSON.stringify(o,null,5));
Y.JSON.stringify(o,null,4));
Y.JSON.stringify(o,null,3));
Y.Assert.areSame('{}', Y.JSON.stringify(o,null,0));
}
}));
suite.add(new Y.Test.Case({
name : "reviver",
test_reviver : function () {
var data = Y.JSON.parse(JSON_STRING, function (k,v) {
switch (k) {
case "alpha" : return "LOWER CASE";
case "ALPHA" : return "upper case";
case "true" :
case "false" :
case "null" : return undefined;
}
if (typeof v === 'number') {
return -(Math.abs(v|0));
}
if (Y.Lang.isArray(v)) {
v[99] = "NEW ITEM";
}
return v;
});
Y.Assert.areSame(-42, data[4]);
Y.Assert.areSame(-1234567890, data[8].integer);
Y.Assert.areSame(-9876, data[8].real);
Y.Assert.areSame(-1, data[8].one);
},
}));
/*
suite.add(new Y.Test.Case({
name : "replacer",
test_ : function () {
},
}));
suite.add(new Y.Test.Case({
name : "unicode",
test_ : function () {
},
}));
*/
Y.Console.prototype.printLogEntry = function (m) {
m = Y.merge(
this._htmlEscapeMessage(m),
{
cat_class : this.getClassName('entry',m.category),
src_class : this.getClassName('entry',m.source)
});
var n = Y.Node.create(this.get('entryTemplate').replace(/\{([\w-]+)\}/g,
function (_,k) { return k in m ? m[k] : ''; }));
this._addToConsole(n);
return this;
};
var yconsole = new Y.Console({
contentBox:"log",
newestOnTop: false
}).render();
//yconsole.hideCategory('info');
yconsole.printLogEntry = function (m) {
if (m.category === 'section') {
return this;
} else if (m.category === "break") {
this._addToConsole(Y.Node.create("<br>"));
return this;
} else if (m.category === "info") {
return this;
} else {
return Y.Console.prototype.printLogEntry.call(this,m);
}
};
Y.log("Tests","section","TestRunner");
Y.Test.Runner.add(suite);
});
</script>
</body>
</html>