mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
fix tests, rename option, more style fixes
This commit is contained in:
@@ -207,15 +207,12 @@ EJSON.fromJSONValue = function (item) {
|
||||
};
|
||||
|
||||
EJSON.stringify = function (item, options) {
|
||||
var keyOrderSensitive = !!(options && options.keyOrderSensitive);
|
||||
var indent = options && options.indent || null;
|
||||
if (indent === true)
|
||||
indent = 2;
|
||||
var json = EJSON.toJSONValue(item);
|
||||
if (keyOrderSensitive)
|
||||
return JSON.stringify(json, null, indent);
|
||||
else
|
||||
return EJSON._canonicalStringify(json, null, indent);
|
||||
if (options && (options.canonical || options.indent)) {
|
||||
return EJSON._canonicalStringify(json, options);
|
||||
} else {
|
||||
return JSON.stringify(json);
|
||||
}
|
||||
};
|
||||
|
||||
EJSON.parse = function (item) {
|
||||
@@ -315,6 +312,7 @@ EJSON.clone = function (v) {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
// XXX: Use something better than underscore's isArray
|
||||
if (_.isArray(v) || _.isArguments(v)) {
|
||||
// For some reason, _.map doesn't work in this context on Opera (weird test
|
||||
// failures).
|
||||
|
||||
@@ -86,10 +86,10 @@ Tinytest.add("ejson - stringify", function (test) {
|
||||
test.equal(EJSON.stringify([1, 2, 3], {indent: true}),
|
||||
"[\n 1,\n 2,\n 3\n]"
|
||||
);
|
||||
test.equal(EJSON.stringify([1, 2, 3], {keyOrderSensitive: true}),
|
||||
test.equal(EJSON.stringify([1, 2, 3], {canonical: false}),
|
||||
"[1,2,3]"
|
||||
);
|
||||
test.equal(EJSON.stringify([1, 2, 3], {indent: true, keyOrderSensitive: true}),
|
||||
test.equal(EJSON.stringify([1, 2, 3], {indent: true, canonical: false}),
|
||||
"[\n 1,\n 2,\n 3\n]"
|
||||
);
|
||||
|
||||
@@ -102,14 +102,18 @@ Tinytest.add("ejson - stringify", function (test) {
|
||||
|
||||
test.equal(
|
||||
EJSON.stringify(
|
||||
{b: [2, {d: 4, c: 3}], a: 1}
|
||||
{b: [2, {d: 4, c: 3}], a: 1},
|
||||
{canonical: true}
|
||||
),
|
||||
"{\"a\":1,\"b\":[2,{\"c\":3,\"d\":4}]}"
|
||||
);
|
||||
test.equal(
|
||||
EJSON.stringify(
|
||||
{b: [2, {d: 4, c: 3}], a: 1},
|
||||
{indent: true}
|
||||
{
|
||||
indent: true,
|
||||
canonical: true
|
||||
}
|
||||
),
|
||||
"{\n" +
|
||||
" \"a\": 1,\n" +
|
||||
@@ -125,14 +129,14 @@ Tinytest.add("ejson - stringify", function (test) {
|
||||
test.equal(
|
||||
EJSON.stringify(
|
||||
{b: [2, {d: 4, c: 3}], a: 1},
|
||||
{keyOrderSensitive: true}
|
||||
{canonical: false}
|
||||
),
|
||||
"{\"b\":[2,{\"d\":4,\"c\":3}],\"a\":1}"
|
||||
);
|
||||
test.equal(
|
||||
EJSON.stringify(
|
||||
{b: [2, {d: 4, c: 3}], a: 1},
|
||||
{indent: true, keyOrderSensitive: true}
|
||||
{indent: true, canonical: false}
|
||||
),
|
||||
"{\n" +
|
||||
" \"b\": [\n" +
|
||||
|
||||
@@ -8,8 +8,8 @@ Package.on_use(function (api) {
|
||||
api.export('EJSON');
|
||||
api.export('EJSONTest', {testOnly: true});
|
||||
api.add_files('ejson.js', ['client', 'server']);
|
||||
api.add_files('base64.js', ['client', 'server']);
|
||||
api.add_files('stringify.js', ['client', 'server']);
|
||||
api.add_files('base64.js', ['client', 'server']);
|
||||
});
|
||||
|
||||
Package.on_test(function (api) {
|
||||
|
||||
@@ -7,182 +7,112 @@
|
||||
//
|
||||
// NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
|
||||
|
||||
EJSON = {}; // Global!
|
||||
|
||||
function quote(string) {
|
||||
return JSON.stringify(string);
|
||||
}
|
||||
|
||||
var rep, gap, indent;
|
||||
var str = function (key, holder, singleIndent, outerIndent, canonical) {
|
||||
|
||||
function str(key, holder) {
|
||||
// Produce a string from holder[key].
|
||||
|
||||
// Produce a string from holder[key].
|
||||
var i; // The loop counter.
|
||||
var k; // The member key.
|
||||
var v; // The member value.
|
||||
var length;
|
||||
var innerIndent = outerIndent;
|
||||
var partial;
|
||||
var value = holder[key];
|
||||
|
||||
var i, // The loop counter.
|
||||
k, // The member key.
|
||||
v, // The member value.
|
||||
length,
|
||||
mind = gap,
|
||||
partial,
|
||||
value = holder[key];
|
||||
// What happens next depends on the value's type.
|
||||
|
||||
// If the value has a toJSON method, call it to obtain a replacement value.
|
||||
switch (typeof value) {
|
||||
case 'string':
|
||||
return quote(value);
|
||||
case 'number':
|
||||
// JSON numbers must be finite. Encode non-finite numbers as null.
|
||||
return isFinite(value) ? String(value) : 'null';
|
||||
case 'boolean':
|
||||
return String(value);
|
||||
// If the type is 'object', we might be dealing with an object or an array or
|
||||
// null.
|
||||
case 'object':
|
||||
// Due to a specification blunder in ECMAScript, typeof null is 'object',
|
||||
// so watch out for that case.
|
||||
if (!value) {
|
||||
return 'null';
|
||||
}
|
||||
// Make an array to hold the partial results of stringifying this object value.
|
||||
innerIndent = outerIndent + singleIndent;
|
||||
partial = [];
|
||||
|
||||
if (value && typeof value === 'object' &&
|
||||
typeof value.toJSON === 'function') {
|
||||
value = value.toJSON(key);
|
||||
// Is the value an array?
|
||||
if (_.isArray(value) || _.isArguments(value)) {
|
||||
|
||||
// The value is an array. Stringify every element. Use null as a placeholder
|
||||
// for non-JSON values.
|
||||
|
||||
length = value.length;
|
||||
for (i = 0; i < length; i += 1) {
|
||||
partial[i] = str(i, value, singleIndent, innerIndent, canonical) || 'null';
|
||||
}
|
||||
|
||||
// Join all of the elements together, separated with commas, and wrap them in
|
||||
// brackets.
|
||||
|
||||
if (partial.length === 0) {
|
||||
v = '[]';
|
||||
} else if (innerIndent) {
|
||||
v = '[\n' + innerIndent + partial.join(',\n' + innerIndent) + '\n' + outerIndent + ']';
|
||||
} else {
|
||||
v = '[' + partial.join(',') + ']';
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
// If we were called with a replacer function, then call the replacer to
|
||||
// obtain a replacement value.
|
||||
|
||||
if (typeof rep === 'function') {
|
||||
value = rep.call(holder, key, value);
|
||||
}
|
||||
|
||||
// What happens next depends on the value's type.
|
||||
|
||||
switch (typeof value) {
|
||||
case 'string':
|
||||
return quote(value);
|
||||
|
||||
case 'number':
|
||||
|
||||
// JSON numbers must be finite. Encode non-finite numbers as null.
|
||||
|
||||
return isFinite(value) ? String(value) : 'null';
|
||||
|
||||
case 'boolean':
|
||||
case 'null':
|
||||
|
||||
// If the value is a boolean or null, convert it to a string. Note:
|
||||
// typeof null does not produce 'null'. The case is included here in
|
||||
// the remote chance that this gets fixed someday.
|
||||
|
||||
return String(value);
|
||||
|
||||
// If the type is 'object', we might be dealing with an object or an array or
|
||||
// null.
|
||||
|
||||
case 'object':
|
||||
|
||||
// Due to a specification blunder in ECMAScript, typeof null is 'object',
|
||||
// so watch out for that case.
|
||||
|
||||
if (!value) {
|
||||
return 'null';
|
||||
}
|
||||
|
||||
// Make an array to hold the partial results of stringifying this object value.
|
||||
|
||||
gap += indent;
|
||||
partial = [];
|
||||
|
||||
// Is the value an array?
|
||||
|
||||
if (Object.prototype.toString.apply(value) === '[object Array]') {
|
||||
|
||||
// The value is an array. Stringify every element. Use null as a placeholder
|
||||
// for non-JSON values.
|
||||
|
||||
length = value.length;
|
||||
for (i = 0; i < length; i += 1) {
|
||||
partial[i] = str(i, value) || 'null';
|
||||
}
|
||||
|
||||
// Join all of the elements together, separated with commas, and wrap them in
|
||||
// brackets.
|
||||
|
||||
v = partial.length === 0
|
||||
? '[]'
|
||||
: gap
|
||||
? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']'
|
||||
: '[' + partial.join(',') + ']';
|
||||
gap = mind;
|
||||
return v;
|
||||
}
|
||||
|
||||
// If the replacer is an array, use it to select the members to be stringified.
|
||||
|
||||
if (rep && typeof rep === 'object') {
|
||||
length = rep.length;
|
||||
for (i = 0; i < length; i += 1) {
|
||||
if (typeof rep[i] === 'string') {
|
||||
k = rep[i];
|
||||
v = str(k, value);
|
||||
if (v) {
|
||||
partial.push(quote(k) + (gap ? ': ' : ':') + v);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
// Otherwise, iterate through all of the keys in the object.
|
||||
|
||||
_.each(_.keys(value).sort(), function (k) {
|
||||
v = str(k, value);
|
||||
if (v) {
|
||||
partial.push(quote(k) + (gap ? ': ' : ':') + v);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Join all of the member texts together, separated with commas,
|
||||
// and wrap them in braces.
|
||||
|
||||
v = partial.length === 0
|
||||
? '{}'
|
||||
: gap
|
||||
? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
|
||||
: '{' + partial.join(',') + '}';
|
||||
gap = mind;
|
||||
return v;
|
||||
// Iterate through all of the keys in the object.
|
||||
var keys = _.keys(value);
|
||||
if (canonical)
|
||||
keys = keys.sort();
|
||||
_.each(keys, function (k) {
|
||||
v = str(k, value, singleIndent, innerIndent, canonical);
|
||||
if (v) {
|
||||
partial.push(quote(k) + (innerIndent ? ': ' : ':') + v);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Join all of the member texts together, separated with commas,
|
||||
// and wrap them in braces.
|
||||
|
||||
if (partial.length === 0) {
|
||||
v = '{}';
|
||||
} else if (innerIndent) {
|
||||
v = '{\n' + innerIndent + partial.join(',\n' + innerIndent) + '\n' + outerIndent + '}';
|
||||
} else {
|
||||
v = '{' + partial.join(',') + '}';
|
||||
}
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
// If the JSON object does not yet have a stringify method, give it one.
|
||||
|
||||
function stringify(value, replacer, space) {
|
||||
|
||||
// The stringify method takes a value and an optional replacer, and an optional
|
||||
// space parameter, and returns a JSON text. The replacer can be a function
|
||||
// that can replace values, or an array of strings that will select the keys.
|
||||
// A default replacer method can be provided. Use of the space parameter can
|
||||
// produce text that is more easily readable.
|
||||
|
||||
var i;
|
||||
gap = '';
|
||||
indent = '';
|
||||
|
||||
// If the space parameter is a number, make an indent string containing that
|
||||
// many spaces.
|
||||
|
||||
if (typeof space === 'number') {
|
||||
for (i = 0; i < space; i += 1) {
|
||||
indent += ' ';
|
||||
}
|
||||
|
||||
// If the space parameter is a string, it will be used as the indent string.
|
||||
|
||||
} else if (typeof space === 'string') {
|
||||
indent = space;
|
||||
}
|
||||
|
||||
// If there is a replacer, it must be a function or an array.
|
||||
// Otherwise, throw an error.
|
||||
|
||||
rep = replacer;
|
||||
if (replacer && typeof replacer !== 'function' &&
|
||||
(typeof replacer !== 'object' ||
|
||||
typeof replacer.length !== 'number')) {
|
||||
throw new Error('JSON.stringify');
|
||||
}
|
||||
|
||||
// Make a fake root object containing our value under the key of ''.
|
||||
// Return the result of stringifying the value.
|
||||
|
||||
return str('', {'': value});
|
||||
}
|
||||
|
||||
EJSON._canonicalStringify = stringify;
|
||||
EJSON._canonicalStringify = function (value, options) {
|
||||
// Make a fake root object containing our value under the key of ''.
|
||||
// Return the result of stringifying the value.
|
||||
options = _.extend({
|
||||
indent: "",
|
||||
canonical: false
|
||||
}, options);
|
||||
if (options.indent === true) {
|
||||
options.indent = " ";
|
||||
} else if (typeof options.indent === 'number') {
|
||||
var newIndent = "";
|
||||
for (var i = 0; i < options.indent; i++) {
|
||||
newIndent += ' ';
|
||||
}
|
||||
options.indent = newIndent;
|
||||
}
|
||||
return str('', {'': value}, options.indent, "", options.canonical);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user