Skip to content
This repository was archived by the owner on Feb 3, 2022. It is now read-only.

Commit 15095f8

Browse files
committed
feat(relaxed): default to relaxed extended JSON
BREAKING CHANGE: the default was strict mode previously, but the extended JSON specification requires our default to be relaxed.
1 parent 0cbe79a commit 15095f8

File tree

3 files changed

+34
-30
lines changed

3 files changed

+34
-30
lines changed

lib/ext_json.js

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -120,16 +120,16 @@ function deserializeValue(self, key, value, options) {
120120
*
121121
* @example
122122
* const EJSON = require('mongodb-extjson');
123-
* const text = '{"int32":{"$numberInt":"10"}}';
123+
* const text = '{ "int32": { "$numberInt": "10" } }';
124124
*
125125
* // prints { int32: { [String: '10'] _bsontype: 'Int32', value: '10' } }
126-
* console.log(EJSON.parse(text));
126+
* console.log(EJSON.parse(text, { relaxed: false }));
127127
*
128128
* // prints { int32: 10 }
129-
* console.log(EJSON.parse(text, {strict: false}));
129+
* console.log(EJSON.parse(text));
130130
*/
131131
function parse(text, options) {
132-
options = Object.assign({}, { relaxed: false }, options);
132+
options = Object.assign({}, { relaxed: true }, options);
133133

134134
// relaxed implies not strict
135135
if (typeof options.relaxed === 'boolean') options.strict = !options.relaxed;
@@ -166,14 +166,15 @@ const BSON_INT32_MAX = 0x7fffffff,
166166
* const doc = { int32: new Int32(10) };
167167
*
168168
* // prints '{"int32":{"$numberInt":"10"}}'
169-
* console.log(EJSON.stringify(doc));
169+
* console.log(EJSON.stringify(doc, { relaxed: false }));
170170
*
171171
* // prints '{"int32":10}'
172-
* console.log(EJSON.stringify(doc, {relaxed: true}));
172+
* console.log(EJSON.stringify(doc));
173173
*/
174174
function stringify(value, replacer, space, options) {
175-
if (typeof space === 'object') (options = space), (space = 0);
176-
if (typeof replacer === 'object') (options = replacer), (replacer = null), (space = 0);
175+
if (space != null && typeof space === 'object') (options = space), (space = 0);
176+
if (replacer != null && typeof replacer === 'object')
177+
(options = replacer), (replacer = null), (space = 0);
177178
options = Object.assign({}, { relaxed: true }, options);
178179

179180
const doc = Array.isArray(value)

test/bson_corpus_tests.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ function bsonToNative(bson) {
2323
}
2424

2525
function jsonToNative(json) {
26-
return EJSON.parse(json);
26+
return EJSON.parse(json, { relaxed: false });
2727
}
2828

2929
function nativeToCEJSON(native) {
30-
return EJSON.stringify(native);
30+
return EJSON.stringify(native, { relaxed: false });
3131
}
3232

3333
function nativeToREJSON(native) {

test/extend_mongodb_tests.js

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,12 @@ describe('Extended JSON', function() {
5757
var json =
5858
'{"_id":{"$numberInt":"100"},"gh":{"$numberInt":"1"},"binary":{"$binary":{"base64":"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+Pw==","subType":"00"}},"date":{"$date":{"$numberLong":"1488372056737"}},"code":{"$code":"function() {}","$scope":{"a":{"$numberInt":"1"}}},"dbRef":{"$ref":"tests","$id":{"$numberInt":"1"},"$db":"test"},"decimal":{"$numberDecimal":"100"},"double":{"$numberDouble":"10.1"},"int32":{"$numberInt":"10"},"long":{"$numberLong":"200"},"maxKey":{"$maxKey":1},"minKey":{"$minKey":1},"objectId":{"$oid":"111111111111111111111111"},"regexp":{"$regularExpression":{"pattern":"hello world","options":"i"}},"symbol":{"$symbol":"symbol"},"timestamp":{"$timestamp":{"t":0,"i":1000}},"int32Number":{"$numberInt":"300"},"doubleNumber":{"$numberDouble":"200.2"},"longNumberIntFit":{"$numberLong":"7036874417766400"},"doubleNumberIntFit":{"$numberLong":"19007199250000000"}}';
5959

60-
assert.equal(json, EJSON.stringify(doc, null, 0));
60+
assert.equal(json, EJSON.stringify(doc, null, 0, { relaxed: false }));
6161
});
6262

63-
it('should correctly deserialize using strict, and non-strict mode', function() {
63+
it('should correctly deserialize using the default relaxed mode', function() {
6464
// Deserialize the document using non strict mode
65-
var doc1 = EJSON.parse(EJSON.stringify(doc, null, 0), { strict: false });
65+
var doc1 = EJSON.parse(EJSON.stringify(doc, null, 0));
6666

6767
// Validate the values
6868
assert.equal(300, doc1.int32Number);
@@ -71,7 +71,7 @@ describe('Extended JSON', function() {
7171
assert.equal(19007199250000000.12, doc1.doubleNumberIntFit);
7272

7373
// Deserialize the document using strict mode
74-
doc1 = EJSON.parse(EJSON.stringify(doc, null, 0), { strict: true });
74+
doc1 = EJSON.parse(EJSON.stringify(doc, null, 0), { relaxed: false });
7575

7676
// Validate the values
7777
expect(doc1.int32Number._bsontype).to.equal('Int32');
@@ -89,28 +89,31 @@ describe('Extended JSON', function() {
8989
};
9090

9191
// Serialize the document
92-
var text = EJSON.stringify(doc1, null, 0);
92+
var text = EJSON.stringify(doc1, null, 0, { relaxed: false });
9393
expect(text).to.equal('{"int32":{"$numberInt":"10"}}');
9494

9595
// Deserialize the json in strict and non strict mode
96-
var doc2 = EJSON.parse(text, { strict: true });
96+
var doc2 = EJSON.parse(text, { relaxed: false });
9797
expect(doc2.int32._bsontype).to.equal('Int32');
98-
doc2 = EJSON.parse(text, { strict: false });
98+
doc2 = EJSON.parse(text);
9999
expect(doc2.int32).to.equal(10);
100100
});
101101

102102
it('should correctly serialize bson types when they are values', function() {
103103
var Int32 = EJSON.BSON.Int32;
104-
var serialized = EJSON.stringify(new ObjectID('591801a468f9e7024b6235ea'));
104+
var serialized = EJSON.stringify(new ObjectID('591801a468f9e7024b6235ea'), { relaxed: false });
105105
expect(serialized).to.equal('{"$oid":"591801a468f9e7024b6235ea"}');
106-
serialized = EJSON.stringify(new Int32(42));
106+
serialized = EJSON.stringify(new Int32(42), { relaxed: false });
107107
expect(serialized).to.equal('{"$numberInt":"42"}');
108-
serialized = EJSON.stringify({
109-
_id: { $nin: [new ObjectID('591801a468f9e7024b6235ea')] }
110-
});
108+
serialized = EJSON.stringify(
109+
{
110+
_id: { $nin: [new ObjectID('591801a468f9e7024b6235ea')] }
111+
},
112+
{ relaxed: false }
113+
);
111114
expect(serialized).to.equal('{"_id":{"$nin":[{"$oid":"591801a468f9e7024b6235ea"}]}}');
112115

113-
serialized = EJSON.stringify(new Binary(new Uint8Array([1, 2, 3, 4, 5])));
116+
serialized = EJSON.stringify(new Binary(new Uint8Array([1, 2, 3, 4, 5])), { relaxed: false });
114117
expect(serialized).to.equal('{"$binary":{"base64":"AQIDBAU=","subType":"00"}}');
115118
});
116119

@@ -119,7 +122,7 @@ describe('Extended JSON', function() {
119122
expect(EJSON.parse('[null]')[0]).to.be.null;
120123

121124
var input = '{"result":[{"_id":{"$oid":"591801a468f9e7024b623939"},"emptyField":null}]}';
122-
var parsed = EJSON.parse(input, { strict: false });
125+
var parsed = EJSON.parse(input);
123126

124127
expect(parsed).to.deep.equal({
125128
result: [{ _id: new ObjectID('591801a468f9e7024b623939'), emptyField: null }]
@@ -128,11 +131,11 @@ describe('Extended JSON', function() {
128131

129132
it('should correctly throw when passed a non-string to parse', function() {
130133
expect(() => {
131-
EJSON.parse({}, { strict: true });
134+
EJSON.parse({});
132135
}).to.throw;
133136
});
134137

135-
it('should allow relaxed parsing', function() {
138+
it('should allow relaxed parsing by default', function() {
136139
const dt = new Date(1452124800000);
137140
const inputObject = {
138141
int: { $numberInt: '500' },
@@ -141,7 +144,7 @@ describe('Extended JSON', function() {
141144
date: { $date: { $numberLong: '1452124800000' } }
142145
};
143146

144-
const parsed = EJSON.parse(JSON.stringify(inputObject), { relaxed: true });
147+
const parsed = EJSON.parse(JSON.stringify(inputObject));
145148
expect(parsed).to.eql({
146149
int: 500,
147150
long: 42,
@@ -151,7 +154,7 @@ describe('Extended JSON', function() {
151154
});
152155

153156
it('should allow regexp', function() {
154-
const parsedRegExp = EJSON.stringify({ test: /some-regex/i }, { relaxed: true });
157+
const parsedRegExp = EJSON.stringify({ test: /some-regex/i });
155158
const parsedBSONRegExp = EJSON.stringify(
156159
{ test: new BSONRegExp('some-regex', 'i') },
157160
{ relaxed: true }
@@ -176,7 +179,7 @@ describe('Extended JSON', function() {
176179
timestamp: new Timestamp()
177180
};
178181

179-
const result = EJSON.serialize(doc);
182+
const result = EJSON.serialize(doc, { relaxed: false });
180183
expect(result).to.deep.equal({
181184
binary: { $binary: { base64: '', subType: '00' } },
182185
code: { $code: 'function() {}' },
@@ -211,7 +214,7 @@ describe('Extended JSON', function() {
211214
timestamp: { $timestamp: { t: 0, i: 0 } }
212215
};
213216

214-
const result = EJSON.deserialize(doc);
217+
const result = EJSON.deserialize(doc, { relaxed: false });
215218

216219
// binary
217220
expect(result.binary).to.be.an.instanceOf(BSON.Binary);

0 commit comments

Comments
 (0)