sku-pg
Version:
Skulpt is a Javascript implementation of Python 2.x. Python that runs in your browser!
570 lines (462 loc) • 17.1 kB
HTML
<html>
<!--
Copyright 2006 The Closure Library Authors. All Rights Reserved.
Use of this source code is governed by the Apache License, Version 2.0.
See the COPYING file for details.
-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Closure Unit Tests - goog.json</title>
<script src="../base.js"></script>
<script>
goog.require('goog.functions');
goog.require('goog.json');
goog.require('goog.testing.jsunit');
goog.require('goog.userAgent');
</script>
</head>
<body>
<script>
function allChars(start, end, opt_allowControlCharacters) {
var sb = [];
for (var i = start; i < end; i++) {
// unicode without the control characters 0x00 - 0x1f
if (opt_allowControlCharacters || i > 0x1f) {
sb.push(String.fromCharCode(i));
}
}
return sb.join('');
}
// serialization
function testStringSerialize() {
assertSerialize('""', '');
// unicode
var str = allChars(0, 10000);
eval(goog.json.serialize(str));
assertSerialize('"true"', 'true');
assertSerialize('"false"', 'false');
assertSerialize('"null"', 'null');
assertSerialize('"0"', '0');
}
function testNullSerialize() {
assertSerialize('null', null);
assertSerialize('null', undefined);
assertSerialize('null', NaN);
assertSerialize('0', 0);
assertSerialize('""', '');
assertSerialize('false', false);
}
function testNullPropertySerialize() {
assertSerialize('{"a":null}', {'a': null});
assertSerialize('{"a":null}', {'a': undefined});
}
function testNumberSerialize() {
assertSerialize('0', 0);
assertSerialize('12345', 12345);
assertSerialize('-12345', -12345);
assertSerialize('0.1', 0.1);
// the leading zero may not be omitted
assertSerialize('0.1', .1);
// no leading +
assertSerialize('1', +1);
// either format is OK
var s = goog.json.serialize(1e50);
assertTrue('1e50', s == "1e50" ||
s == "1E50" ||
s == "1e+50" ||
s == "1E+50");
// either format is OK
s = goog.json.serialize(1e-50);
assertTrue('1e50', s == "1e-50" || s == "1E-50");
// These numbers cannot be represented in JSON
assertSerialize('null', NaN);
assertSerialize('null', Infinity);
assertSerialize('null', -Infinity);
}
function testBooleanSerialize() {
assertSerialize('true', true);
assertSerialize('"true"', 'true');
assertSerialize('false', false);
assertSerialize('"false"', 'false');
}
function testArraySerialize() {
assertSerialize('[]', []);
assertSerialize('[1]', [1]);
assertSerialize('[1,2]', [1,2]);
assertSerialize('[1,2,3]', [1,2,3]);
assertSerialize('[[]]', [[]]);
assertNotEquals('{length:0}', goog.json.serialize({length:0}), '[]');
}
function testObjectSerialize_emptyObject() {
assertSerialize('{}', {});
}
function testObjectSerialize_oneItem() {
assertSerialize('{"a":"b"}', {a:'b'});
}
function testObjectSerialize_twoItems() {
assertEquals('{"a":"b","c":"d"}',
goog.json.serialize({a:'b',c:'d'}),
'{"a":"b","c":"d"}');
}
function testObjectSerialize_whitespace() {
assertSerialize('{" ":" "}', {' ':' '});
}
function testSerializeSkipFunction() {
var object = {
s: 'string value',
b: true,
i: 100,
f: function() { var x = 'x'; }
};
assertSerialize('', object.f);
assertSerialize('{"s":"string value","b":true,"i":100}', object);
}
function testObjectSerialize_array() {
assertNotEquals('[0,1]', goog.json.serialize([0,1]), '{"0":"0","1":"1"}');
}
function testObjectSerialize_recursion() {
if (goog.userAgent.WEBKIT) {
return; // this makes safari 4 crash.
}
var anObject = {};
anObject.thisObject = anObject;
assertThrows('expected recursion exception', function() {
goog.json.serialize(anObject);
});
}
function testObjectSerializeWithHasOwnProperty() {
var object = {'hasOwnProperty': null};
if (goog.userAgent.IE && !goog.userAgent.isVersionOrHigher('9')) {
assertEquals('{}', goog.json.serialize(object));
} else {
assertEquals('{"hasOwnProperty":null}', goog.json.serialize(object));
}
}
// parsing
function testStringParse() {
assertEquals('Empty string', goog.json.parse('""'), '');
assertEquals('whitespace string', goog.json.parse('" "'), ' ');
// unicode without the control characters 0x00 - 0x1f, 0x7f - 0x9f
var str = allChars(0, 1000);
var jsonString = goog.json.serialize(str);
var a = eval(jsonString);
assertEquals('unicode string', goog.json.parse(jsonString), a);
assertEquals('true as a string', goog.json.parse('"true"'), 'true');
assertEquals('false as a string', goog.json.parse('"false"'), 'false');
assertEquals('null as a string', goog.json.parse('"null"'), 'null');
assertEquals('number as a string', goog.json.parse('"0"'), '0');
}
function testStringUnsafeParse() {
assertEquals('Empty string', goog.json.unsafeParse('""'), '');
assertEquals('whitespace string', goog.json.unsafeParse('" "'), ' ');
// unicode
var str = allChars(0, 1000);
var jsonString = goog.json.serialize(str);
var a = eval(jsonString);
assertEquals('unicode string', goog.json.unsafeParse(jsonString), a);
assertEquals('true as a string', goog.json.unsafeParse('"true"'), 'true');
assertEquals('false as a string', goog.json.unsafeParse('"false"'), 'false');
assertEquals('null as a string', goog.json.unsafeParse('"null"'), 'null');
assertEquals('number as a string', goog.json.unsafeParse('"0"'), '0');
}
function testNullParse() {
assertEquals('null', goog.json.parse('null'), null);
assertNotEquals('0', goog.json.parse('0'), null);
assertNotEquals('""', goog.json.parse('""'), null);
assertNotEquals('false', goog.json.parse('false'), null);
}
function testNullUnsafeParse() {
assertEquals('null', goog.json.unsafeParse('null'), null);
assertNotEquals('0', goog.json.unsafeParse('0'), null);
assertNotEquals('""', goog.json.unsafeParse('""'), null);
assertNotEquals('false', goog.json.unsafeParse('false'), null);
}
function testNumberParse() {
assertEquals('0', goog.json.parse('0'), 0);
assertEquals('12345', goog.json.parse('12345'), 12345);
assertEquals('-12345', goog.json.parse('-12345'), -12345);
assertEquals('0.1', goog.json.parse('0.1'), 0.1);
// either format is OK
assertEquals(1e50, goog.json.parse('1e50'));
assertEquals(1e50, goog.json.parse('1E50'));
assertEquals(1e50, goog.json.parse('1e+50'));
assertEquals(1e50, goog.json.parse('1E+50'));
// either format is OK
assertEquals(1e-50, goog.json.parse('1e-50'));
assertEquals(1e-50, goog.json.parse('1E-50'));
}
function testNumberUnsafeParse() {
assertEquals('0', goog.json.unsafeParse('0'), 0);
assertEquals('12345', goog.json.unsafeParse('12345'), 12345);
assertEquals('-12345', goog.json.unsafeParse('-12345'), -12345);
assertEquals('0.1', goog.json.unsafeParse('0.1'), 0.1);
// either format is OK
assertEquals(1e50, goog.json.unsafeParse('1e50'));
assertEquals(1e50, goog.json.unsafeParse('1E50'));
assertEquals(1e50, goog.json.unsafeParse('1e+50'));
assertEquals(1e50, goog.json.unsafeParse('1E+50'));
// either format is OK
assertEquals(1e-50, goog.json.unsafeParse('1e-50'));
assertEquals(1e-50, goog.json.unsafeParse('1E-50'));
}
function testBooleanParse() {
assertEquals('true', goog.json.parse('true'), true);
assertEquals('false', goog.json.parse('false'), false);
assertNotEquals('0', goog.json.parse('0'), false);
assertNotEquals('"false"', goog.json.parse('"false"'), false);
assertNotEquals('null', goog.json.parse('null'), false);
assertNotEquals('1', goog.json.parse('1'), true);
assertNotEquals('"true"', goog.json.parse('"true"'), true);
assertNotEquals('{}', goog.json.parse('{}'), true);
assertNotEquals('[]', goog.json.parse('[]'), true);
}
function testBooleanUnsafeParse() {
assertEquals('true', goog.json.unsafeParse('true'), true);
assertEquals('false', goog.json.unsafeParse('false'), false);
assertNotEquals('0', goog.json.unsafeParse('0'), false);
assertNotEquals('"false"', goog.json.unsafeParse('"false"'), false);
assertNotEquals('null', goog.json.unsafeParse('null'), false);
assertNotEquals('1', goog.json.unsafeParse('1'), true);
assertNotEquals('"true"', goog.json.unsafeParse('"true"'), true);
assertNotEquals('{}', goog.json.unsafeParse('{}'), true);
assertNotEquals('[]', goog.json.unsafeParse('[]'), true);
}
function testArrayParse() {
function arrayEquals(a1, a2) {
if (a1.length != a2.length) {
return false;
}
for (var i = 0; i < a1.length; i++) {
if (a1[i] != a2[i]) {
return false;
}
}
return true;
}
assertTrue('[]', arrayEquals(goog.json.parse('[]'), []));
assertTrue('[1]', arrayEquals(goog.json.parse('[1]'), [1]));
assertTrue('[1,2]', arrayEquals(goog.json.parse('[1,2]'), [1,2]));
assertTrue('[1,2,3]', arrayEquals(goog.json.parse('[1,2,3]'), [1,2,3]));
assertTrue('[[]]', arrayEquals(goog.json.parse('[[]]')[0], []));
// make sure we do not get an array for something that looks like an array
assertFalse('{length:0}', 'push' in goog.json.parse('{"length":0}'));
}
function testArrayUnsafeParse() {
function arrayEquals(a1, a2) {
if (a1.length != a2.length) {
return false;
}
for (var i = 0; i < a1.length; i++) {
if (a1[i] != a2[i]) {
return false;
}
}
return true;
}
assertTrue('[]', arrayEquals(goog.json.unsafeParse('[]'), []));
assertTrue('[1]', arrayEquals(goog.json.unsafeParse('[1]'), [1]));
assertTrue('[1,2]', arrayEquals(goog.json.unsafeParse('[1,2]'), [1,2]));
assertTrue('[1,2,3]', arrayEquals(goog.json.unsafeParse('[1,2,3]'), [1,2,3]));
assertTrue('[[]]', arrayEquals(goog.json.unsafeParse('[[]]')[0], []));
// make sure we do not get an array for something that looks like an array
assertFalse('{length:0}', 'push' in goog.json.unsafeParse('{"length":0}'));
}
function testObjectParse() {
function objectEquals(a1, a2) {
for (var key in a1) {
if (a1[key] != a2[key]) {
return false;
}
}
return true;
}
assertTrue('{}', objectEquals(goog.json.parse('{}'), {}));
assertTrue('{"a":"b"}', objectEquals(goog.json.parse('{"a":"b"}'), {a:'b'}));
assertTrue('{"a":"b","c":"d"}',
objectEquals(goog.json.parse('{"a":"b","c":"d"}'),
{a:'b',c:'d'}));
assertTrue('{" ":" "}', objectEquals(goog.json.parse('{" ":" "}'), {' ':' '}));
// make sure we do not get an Object when it is really an array
assertTrue('[0,1]', 'length' in goog.json.parse('[0,1]'));
}
function testObjectUnsafeParse() {
function objectEquals(a1, a2) {
for (var key in a1) {
if (a1[key] != a2[key]) {
return false;
}
}
return true;
}
assertTrue('{}', objectEquals(goog.json.unsafeParse('{}'), {}));
assertTrue('{"a":"b"}', objectEquals(goog.json.unsafeParse('{"a":"b"}'), {a:'b'}));
assertTrue('{"a":"b","c":"d"}',
objectEquals(goog.json.unsafeParse('{"a":"b","c":"d"}'),
{a:'b',c:'d'}));
assertTrue('{" ":" "}', objectEquals(goog.json.unsafeParse('{" ":" "}'), {' ':' '}));
// make sure we do not get an Object when it is really an array
assertTrue('[0,1]', 'length' in goog.json.unsafeParse('[0,1]'));
}
function testForValidJson() {
function error_(msg, s) {
assertThrows(msg + ', Should have raised an exception: ' + s,
goog.partial(goog.json.parse, s));
}
error_('Non closed string', '"dasdas');
error_('undefined is not valid json', 'undefined');
// These numbers cannot be represented in JSON
error_('NaN cannot be presented in JSON', 'NaN');
error_('Infinity cannot be presented in JSON', 'Infinity');
error_('-Infinity cannot be presented in JSON', '-Infinity');
}
function testIsNotValid() {
assertFalse(goog.json.isValid_('t'));
assertFalse(goog.json.isValid_('r'));
assertFalse(goog.json.isValid_('u'));
assertFalse(goog.json.isValid_('e'));
assertFalse(goog.json.isValid_('f'));
assertFalse(goog.json.isValid_('a'));
assertFalse(goog.json.isValid_('l'));
assertFalse(goog.json.isValid_('s'));
assertFalse(goog.json.isValid_('n'));
assertFalse(goog.json.isValid_('E'));
assertFalse(goog.json.isValid_('+'));
assertFalse(goog.json.isValid_('-'));
assertFalse(goog.json.isValid_('t++'));
assertFalse(goog.json.isValid_('++t'));
assertFalse(goog.json.isValid_('t--'));
assertFalse(goog.json.isValid_('--t'));
assertFalse(goog.json.isValid_('-t'));
assertFalse(goog.json.isValid_('+t'));
assertFalse(goog.json.isValid_('"\\"')); // "\"
assertFalse(goog.json.isValid_('"\\')); // "\
// multiline string using \ at the end is not valid
assertFalse(goog.json.isValid_('"a\\\nb"'));
assertFalse(goog.json.isValid_('"\n"'));
assertFalse(goog.json.isValid_('"\r"'));
assertFalse(goog.json.isValid_('"\r\n"'));
// Disallow the unicode newlines
assertFalse(goog.json.isValid_('"\u2028"'));
assertFalse(goog.json.isValid_('"\u2029"'));
assertFalse(goog.json.isValid_(' '));
assertFalse(goog.json.isValid_('\n'));
assertFalse(goog.json.isValid_('\r'));
assertFalse(goog.json.isValid_('\r\n'));
assertFalse(goog.json.isValid_('t.r'));
assertFalse(goog.json.isValid_('1e'));
assertFalse(goog.json.isValid_('1e-'));
assertFalse(goog.json.isValid_('1e+'));
assertFalse(goog.json.isValid_('1e-'));
assertFalse(goog.json.isValid_('"\\\u200D\\"'));
assertFalse(goog.json.isValid_('"\\\0\\"'));
assertFalse(goog.json.isValid_('"\\\0"'));
assertFalse(goog.json.isValid_('"\\0"'));
assertFalse(goog.json.isValid_('"\x0c"'));
assertFalse(goog.json.isValid_('"\\\u200D\\", alert(\'foo\') //"\n'));
}
function testIsValid() {
assertTrue(goog.json.isValid_('\n""\n'));
assertTrue(goog.json.isValid_('[1\n,2\r,3\u2028\n,4\u2029]'));
assertTrue(goog.json.isValid_('"\x7f"'));
assertTrue(goog.json.isValid_('"\x09"'));
// Test tab characters in json.
assertTrue(goog.json.isValid_('{"\t":"\t"}'));
}
function testDoNotSerializeProto() {
function F() {};
F.prototype = {
c: 3
};
var obj = new F;
obj.a = 1;
obj.b = 2;
assertEquals('Should not follow the prototype chain',
'{"a":1,"b":2}',
goog.json.serialize(obj));
}
function testEscape() {
var unescaped = '1a*/]';
assertEquals('Should not escape',
'"' + unescaped + '"',
goog.json.serialize(unescaped));
var escaped = '\n\x7f\u1049';
assertEquals('Should escape',
'',
findCommonChar(escaped, goog.json.serialize(escaped)));
assertEquals('Should eval to the same string after escaping',
escaped,
goog.json.parse(goog.json.serialize(escaped)));
}
function testReplacer() {
assertSerialize('[null,null,0]', [,,0]);
assertSerialize('[0,0,{"x":0}]', [,,{x:0}], function(k, v) {
if (v === undefined && goog.isArray(this)) {
return 0;
}
return v;
});
assertSerialize('[0,1,2,3]', [0, 0, 0, 0], function(k, v) {
var kNum = Number(k);
if (k && !isNaN(kNum)) {
return kNum;
}
return v;
});
assertSerialize(
'{"a":1,"b":{"c":2}}',
{'a': 0, 'b': {'c': 1}},
function(k, v) {
return typeof v == 'number' ? v + 1 : v;
});
}
function testDateSerialize() {
assertSerialize('{}', new Date(0));
}
function testToJSONSerialize() {
assertSerialize('{}', {toJSON: goog.functions.constant('serialized')});
assertSerialize('{"toJSON":"normal"}', {toJSON: 'normal'});
}
/**
* Asserts that the given object serializes to the given value.
* If the current browser has an implementation of JSON.serialize,
* we make sure our version matches that one.
*/
function assertSerialize(expected, obj, opt_replacer) {
assertEquals(expected, goog.json.serialize(obj, opt_replacer));
// I'm pretty sure that the goog.json.serialize behavior is correct by the ES5
// spec, but JSON.stringify(undefined) is undefined on all browsers.
if (obj === undefined) return;
// Browsers don't serialize undefined properties, but goog.json.serialize does
if (goog.isObject(obj) && ('a' in obj) && obj['a'] === undefined) return;
// Replacers are broken on IE and older versions of firefox.
if (opt_replacer && !goog.userAgent.WEBKIT) return;
// goog.json.serialize does not stringify dates the same way.
if (obj instanceof Date) return;
// goog.json.serialize does not stringify functions the same way.
if (obj instanceof Function) return;
// goog.json.serialize doesn't use the toJSON method.
if (goog.isObject(obj) && goog.isFunction(obj.toJSON)) return;
if (typeof JSON != 'undefined') {
assertEquals(
'goog.json.serialize does not match JSON.stringify',
expected,
JSON.stringify(obj, opt_replacer));
}
}
/**
* @param {string} a
* @param {string} b
* @return {string} any common character between two strings a and b.
*/
function findCommonChar(a, b) {
for (var i = 0; i < b.length; i++) {
if (a.indexOf(b.charAt(i)) >= 0) {
return b.charAt(i);
}
}
return '';
}
</script>
</body>
</html>