Skip to content

Commit

Permalink
Infinity and NaN in EJSON
Browse files Browse the repository at this point in the history
  • Loading branch information
Naomi Seyfer committed Oct 2, 2013
1 parent 0d8bfba commit c3fb774
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 0 deletions.
33 changes: 33 additions & 0 deletions packages/ejson/ejson.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,27 @@ var builtinConverters = [
return new Date(obj.$date);
}
},
{ //NaN, Inf, -Inf
matchJSONValue: function (obj) {
return _.has(obj, '$InfNaN') && _.size(obj) === 1;
},
matchObject: function (obj) {
return _.isNaN(obj) || obj === Infinity || obj === -Infinity;
},
toJSONValue: function (obj) {
var sign;
if (_.isNaN(obj))
sign = 0;
else if (obj === Infinity)
sign = 1;
else
sign = -1;
return {$InfNaN: sign};
},
fromJSONValue: function (obj) {
return obj.$InfNaN/0;
}
},
{ // Binary
matchJSONValue: function (obj) {
return _.has(obj, '$binary') && _.size(obj) === 1;
Expand Down Expand Up @@ -110,6 +131,15 @@ EJSON._adjustTypesToJSONValue = function (obj) {
if (maybeChanged !== undefined)
return maybeChanged;
_.each(obj, function (value, key) {
if (typeof value === 'number') {
if (_.isNaN(value))
obj[key] = {$InfNaN: 0};
else if (value === Infinity)
obj[key] = {$InfNaN: 1};
else if (value === -Infinity)
obj[key] = {$InfNaN: -1};
return; // continue
}
if (typeof value !== 'object' && value !== undefined)
return; // continue
var changed = toJSONValueHelper(value);
Expand Down Expand Up @@ -231,6 +261,9 @@ EJSON.equals = function (a, b, options) {
var keyOrderSensitive = !!(options && options.keyOrderSensitive);
if (a === b)
return true;
if (_.isNaN(a) && _.isNaN(b))
return true; // This differs from the IEEE spec for NaN equality, b/c we don't want
// anything ever with a NaN to be poisoned from becoming equal to anything.
if (!a || !b) // if either one is falsy, they'd have to be === to be equal
return false;
if (!(typeof a === 'object' && typeof b === 'object'))
Expand Down
25 changes: 25 additions & 0 deletions packages/ejson/ejson_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,31 @@ Tinytest.add("ejson - equality and falsiness", function (test) {
test.isFalse(EJSON.equals({foo: "foo"}, undefined));
});

Tinytest.add("ejson - NaN and Inf", function (test) {
test.equal(EJSON.parse("{\"$InfNaN\": 1}"), Infinity);
test.equal(EJSON.parse("{\"$InfNaN\": -1}"), -Infinity);
test.isTrue(_.isNaN(EJSON.parse("{\"$InfNaN\": 0}")));
test.equal(EJSON.parse(EJSON.stringify(Infinity)), Infinity);
test.equal(EJSON.parse(EJSON.stringify(-Infinity)), -Infinity);
test.isTrue(_.isNaN(EJSON.parse(EJSON.stringify(NaN))));
test.isTrue(EJSON.equals(NaN, NaN));
test.isTrue(EJSON.equals(Infinity, Infinity));
test.isTrue(EJSON.equals(-Infinity, -Infinity));
test.isFalse(EJSON.equals(Infinity, -Infinity));
test.isFalse(EJSON.equals(Infinity, NaN));
test.isFalse(EJSON.equals(Infinity, 0));
test.isFalse(EJSON.equals(NaN, 0));

test.isTrue(EJSON.equals(
EJSON.parse("{\"a\": {\"$InfNaN\": 1}}"),
{a: Infinity}
));
test.isTrue(EJSON.equals(
EJSON.parse("{\"a\": {\"$InfNaN\": 0}}"),
{a: NaN}
));
});

Tinytest.add("ejson - clone", function (test) {
var cloneTest = function (x, identical) {
var y = EJSON.clone(x);
Expand Down

0 comments on commit c3fb774

Please sign in to comment.