mirror of https://github.com/mongodb/mongo
SERVER-100172 Add toEJSON() function to serialize to EJSON (#31797)
GitOrigin-RevId: c21938a9eab69c7854e497c1c0863b5206696255
This commit is contained in:
parent
520e3777aa
commit
2be3f39d85
|
|
@ -65,6 +65,7 @@ globals:
|
|||
tojsononeline: true
|
||||
tostrictjson: true
|
||||
tojsonObject: true
|
||||
toEJSON: true
|
||||
print: true
|
||||
printjson: true
|
||||
printjsononeline: true
|
||||
|
|
|
|||
|
|
@ -29,14 +29,24 @@ x = {
|
|||
};
|
||||
assertToJson({
|
||||
fn: () => tojson(x, "", false),
|
||||
expectedStr:
|
||||
'{\n\t"x" : null,\n\t"y" : true,\n\t"z" : 123,\n\t"w" : "foo",\n\t"a" : undefined\n}',
|
||||
expectedStr: `{
|
||||
"x" : null,
|
||||
"y" : true,
|
||||
"z" : 123,
|
||||
"w" : "foo",
|
||||
"a" : undefined
|
||||
}`,
|
||||
assertMsg: "C1"
|
||||
});
|
||||
assertToJson({
|
||||
fn: () => tojson(x, "", false),
|
||||
expectedStr:
|
||||
'{\n\t"x" : null,\n\t"y" : true,\n\t"z" : 123,\n\t"w" : "foo",\n\t"a" : undefined\n}',
|
||||
expectedStr: `{
|
||||
"x" : null,
|
||||
"y" : true,
|
||||
"z" : 123,
|
||||
"w" : "foo",
|
||||
"a" : undefined
|
||||
}`,
|
||||
assertMsg: "C2",
|
||||
logFormat: "json"
|
||||
});
|
||||
|
|
@ -46,6 +56,23 @@ assertToJson({
|
|||
assertMsg: "C3",
|
||||
logFormat: "json"
|
||||
});
|
||||
assertToJson({
|
||||
fn: () => toEJSON(x, "", false),
|
||||
expectedStr: `{
|
||||
"x" : null,
|
||||
"y" : true,
|
||||
"z" : 123,
|
||||
"w" : "foo",
|
||||
"a" : undefined
|
||||
}`,
|
||||
assertMsg: "C4"
|
||||
});
|
||||
assertToJson({
|
||||
fn: () => toEJSON(x, "", false),
|
||||
expectedStr: '{"x":null,"y":true,"z":123,"w":"foo"}',
|
||||
assertMsg: "C5",
|
||||
logFormat: "json"
|
||||
});
|
||||
|
||||
x = {
|
||||
"x": [],
|
||||
|
|
@ -53,12 +80,22 @@ x = {
|
|||
};
|
||||
assertToJson({
|
||||
fn: () => tojson(x, "", false),
|
||||
expectedStr: '{\n\t"x" : [ ],\n\t"y" : {\n\t\t\n\t}\n}',
|
||||
expectedStr: `{
|
||||
"x" : [ ],
|
||||
"y" : {
|
||||
|
||||
}
|
||||
}`,
|
||||
assertMsg: "D1"
|
||||
});
|
||||
assertToJson({
|
||||
fn: () => tojson(x, "", false),
|
||||
expectedStr: '{\n\t"x" : [ ],\n\t"y" : {\n\t\t\n\t}\n}',
|
||||
expectedStr: `{
|
||||
"x" : [ ],
|
||||
"y" : {
|
||||
|
||||
}
|
||||
}`,
|
||||
assertMsg: "D2",
|
||||
logFormat: "json"
|
||||
});
|
||||
|
|
@ -68,6 +105,18 @@ assertToJson({
|
|||
assertMsg: "D3",
|
||||
logFormat: "json"
|
||||
});
|
||||
assertToJson({
|
||||
fn: () => toEJSON(x, "", false),
|
||||
expectedStr: `{
|
||||
"x" : [ ],
|
||||
"y" : {
|
||||
|
||||
}
|
||||
}`,
|
||||
assertMsg: "D4"
|
||||
});
|
||||
assertToJson(
|
||||
{fn: () => toEJSON(x), expectedStr: '{"x":[],"y":{}}', assertMsg: "D5", logFormat: "json"});
|
||||
|
||||
// nested
|
||||
x = {
|
||||
|
|
@ -76,8 +125,25 @@ x = {
|
|||
};
|
||||
assertToJson({
|
||||
fn: () => tojson(x),
|
||||
expectedStr:
|
||||
'{\n\t"x" : [\n\t\t{\n\t\t\t"x" : [\n\t\t\t\t1,\n\t\t\t\t2,\n\t\t\t\t[ ]\n\t\t\t],\n\t\t\t"z" : "ok",\n\t\t\t"y" : [\n\t\t\t\t[ ]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t"foo" : "bar"\n\t\t}\n\t],\n\t"y" : null\n}',
|
||||
expectedStr: `{
|
||||
"x" : [
|
||||
{
|
||||
"x" : [
|
||||
1,
|
||||
2,
|
||||
[ ]
|
||||
],
|
||||
"z" : "ok",
|
||||
"y" : [
|
||||
[ ]
|
||||
]
|
||||
},
|
||||
{
|
||||
"foo" : "bar"
|
||||
}
|
||||
],
|
||||
"y" : null
|
||||
}`,
|
||||
assertMsg: "E1"
|
||||
});
|
||||
assertToJson({
|
||||
|
|
@ -87,6 +153,35 @@ assertToJson({
|
|||
assertMsg: "E2",
|
||||
logFormat: "json"
|
||||
});
|
||||
assertToJson({
|
||||
fn: () => toEJSON(x),
|
||||
expectedStr: `{
|
||||
"x" : [
|
||||
{
|
||||
"x" : [
|
||||
1,
|
||||
2,
|
||||
[ ]
|
||||
],
|
||||
"z" : "ok",
|
||||
"y" : [
|
||||
[ ]
|
||||
]
|
||||
},
|
||||
{
|
||||
"foo" : "bar"
|
||||
}
|
||||
],
|
||||
"y" : null
|
||||
}`,
|
||||
assertMsg: "E3"
|
||||
});
|
||||
assertToJson({
|
||||
fn: () => toEJSON(x),
|
||||
expectedStr: '{"x":[{"x":[1,2,[]],"z":"ok","y":[[]]},{"foo":"bar"}],"y":null}',
|
||||
assertMsg: "E4",
|
||||
logFormat: "json"
|
||||
});
|
||||
|
||||
// special types
|
||||
x = {
|
||||
|
|
@ -95,12 +190,18 @@ x = {
|
|||
};
|
||||
assertToJson({
|
||||
fn: () => tojson(x, "", false),
|
||||
expectedStr: '{\n\t"x" : ObjectId("4ad35a73d2e34eb4fc43579a"),\n\t"z" : /xd?/gi\n}',
|
||||
expectedStr: `{
|
||||
"x" : ObjectId("4ad35a73d2e34eb4fc43579a"),
|
||||
"z" : /xd?/gi
|
||||
}`,
|
||||
assertMsg: "F1"
|
||||
});
|
||||
assertToJson({
|
||||
fn: () => tojson(x, "", false),
|
||||
expectedStr: '{\n\t"x" : ObjectId("4ad35a73d2e34eb4fc43579a"),\n\t"z" : /xd?/gi\n}',
|
||||
expectedStr: `{
|
||||
"x" : ObjectId("4ad35a73d2e34eb4fc43579a"),
|
||||
"z" : /xd?/gi
|
||||
}`,
|
||||
assertMsg: "F2",
|
||||
logFormat: "json"
|
||||
});
|
||||
|
|
@ -110,6 +211,20 @@ assertToJson({
|
|||
assertMsg: "F3",
|
||||
logFormat: "json"
|
||||
});
|
||||
assertToJson({
|
||||
fn: () => toEJSON(x, "", false),
|
||||
expectedStr: `{
|
||||
"x" : ObjectId("4ad35a73d2e34eb4fc43579a"),
|
||||
"z" : /xd?/gi
|
||||
}`,
|
||||
assertMsg: "F4"
|
||||
});
|
||||
assertToJson({
|
||||
fn: () => toEJSON(x),
|
||||
expectedStr: '{"x":{"$oid":"4ad35a73d2e34eb4fc43579a"},"z":{"$regex":"xd?","$options":"gi"}}',
|
||||
assertMsg: "F5",
|
||||
logFormat: "json"
|
||||
});
|
||||
|
||||
// Timestamp type
|
||||
x = {
|
||||
|
|
@ -117,12 +232,16 @@ x = {
|
|||
};
|
||||
assertToJson({
|
||||
fn: () => tojson(x, "", false),
|
||||
expectedStr: '{\n\t"x" : Timestamp(0, 0)\n}',
|
||||
expectedStr: `{
|
||||
"x" : Timestamp(0, 0)
|
||||
}`,
|
||||
assertMsg: "G1"
|
||||
});
|
||||
assertToJson({
|
||||
fn: () => tojson(x, "", false),
|
||||
expectedStr: '{\n\t"x" : Timestamp(0, 0)\n}',
|
||||
expectedStr: `{
|
||||
"x" : Timestamp(0, 0)
|
||||
}`,
|
||||
assertMsg: "G2",
|
||||
logFormat: "json"
|
||||
});
|
||||
|
|
@ -132,6 +251,19 @@ assertToJson({
|
|||
assertMsg: "G3",
|
||||
logFormat: "json"
|
||||
});
|
||||
assertToJson({
|
||||
fn: () => toEJSON(x, "", false),
|
||||
expectedStr: `{
|
||||
"x" : Timestamp(0, 0)
|
||||
}`,
|
||||
assertMsg: "G4"
|
||||
});
|
||||
assertToJson({
|
||||
fn: () => toEJSON(x),
|
||||
expectedStr: '{"x":{"$timestamp":{"t":0,"i":0}}}',
|
||||
assertMsg: "G5",
|
||||
logFormat: "json"
|
||||
});
|
||||
|
||||
// Timestamp type, second
|
||||
x = {
|
||||
|
|
@ -139,12 +271,16 @@ x = {
|
|||
};
|
||||
assertToJson({
|
||||
fn: () => tojson(x, "", false),
|
||||
expectedStr: '{\n\t"x" : Timestamp(10, 2)\n}',
|
||||
expectedStr: `{
|
||||
"x" : Timestamp(10, 2)
|
||||
}`,
|
||||
assertMsg: "H1"
|
||||
});
|
||||
assertToJson({
|
||||
fn: () => tojson(x, "", false),
|
||||
expectedStr: '{\n\t"x" : Timestamp(10, 2)\n}',
|
||||
expectedStr: `{
|
||||
"x" : Timestamp(10, 2)
|
||||
}`,
|
||||
assertMsg: "H2",
|
||||
logFormat: "json"
|
||||
});
|
||||
|
|
@ -154,18 +290,63 @@ assertToJson({
|
|||
assertMsg: "H3",
|
||||
logFormat: "json"
|
||||
});
|
||||
assertToJson({
|
||||
fn: () => toEJSON(x, "", false),
|
||||
expectedStr: `{
|
||||
"x" : Timestamp(10, 2)
|
||||
}`,
|
||||
assertMsg: "H4"
|
||||
});
|
||||
assertToJson({
|
||||
fn: () => toEJSON(x),
|
||||
expectedStr: '{"x":{"$timestamp":{"t":10,"i":2}}}',
|
||||
assertMsg: "H5",
|
||||
logFormat: "json"
|
||||
});
|
||||
|
||||
// Map type
|
||||
x = new Map();
|
||||
assertToJson({fn: () => tojson(x, "", false), expectedStr: '[ ]', assertMsg: "I"});
|
||||
assertToJson({fn: () => tojson(x, "", false), expectedStr: '[ ]', assertMsg: "I1"});
|
||||
assertToJson({fn: () => toEJSON(x, "", false), expectedStr: '[ ]', assertMsg: "I2"});
|
||||
assertToJson(
|
||||
{fn: () => toEJSON(x), expectedStr: '{"$map":[]}', assertMsg: "I3", logFormat: "json"});
|
||||
|
||||
x = new Map();
|
||||
x.set("one", 1);
|
||||
x.set(2, "two");
|
||||
assertToJson({
|
||||
fn: () => tojson(x, "", false),
|
||||
expectedStr: '[\n\t[\n\t\t\"one\",\n\t\t1\n\t],\n\t[\n\t\t2,\n\t\t\"two\"\n\t]\n]',
|
||||
assertMsg: "J"
|
||||
expectedStr: `[
|
||||
[
|
||||
"one",
|
||||
1
|
||||
],
|
||||
[
|
||||
2,
|
||||
"two"
|
||||
]
|
||||
]`,
|
||||
assertMsg: "J1"
|
||||
});
|
||||
assertToJson({
|
||||
fn: () => toEJSON(x, "", false),
|
||||
expectedStr: `[
|
||||
[
|
||||
"one",
|
||||
1
|
||||
],
|
||||
[
|
||||
2,
|
||||
"two"
|
||||
]
|
||||
]`,
|
||||
assertMsg: "J2"
|
||||
});
|
||||
assertToJson({
|
||||
fn: () => toEJSON(x),
|
||||
expectedStr: '{"$map":[["one",1],[2,"two"]]}',
|
||||
assertMsg: "J3",
|
||||
logFormat: "json"
|
||||
});
|
||||
|
||||
x = new Map();
|
||||
|
|
@ -173,23 +354,74 @@ x.set("one", 1);
|
|||
x.set(2, {y: [3, 4]});
|
||||
assertToJson({
|
||||
fn: () => tojson(x, "", false),
|
||||
expectedStr:
|
||||
'[\n\t[\n\t\t\"one\",\n\t\t1\n\t],\n\t[\n\t\t2,\n\t\t{\n\t\t\t\"y\" : [\n\t\t\t\t3,\n\t\t\t\t4\n\t\t\t]\n\t\t}\n\t]\n]',
|
||||
expectedStr: `[
|
||||
[
|
||||
"one",
|
||||
1
|
||||
],
|
||||
[
|
||||
2,
|
||||
{
|
||||
"y" : [
|
||||
3,
|
||||
4
|
||||
]
|
||||
}
|
||||
]
|
||||
]`,
|
||||
assertMsg: "K1"
|
||||
});
|
||||
assertToJson({
|
||||
fn: () => tojson(x, "", false),
|
||||
expectedStr:
|
||||
'[\n\t[\n\t\t\"one\",\n\t\t1\n\t],\n\t[\n\t\t2,\n\t\t{\n\t\t\t\"y\" : [\n\t\t\t\t3,\n\t\t\t\t4\n\t\t\t]\n\t\t}\n\t]\n]',
|
||||
expectedStr: `[
|
||||
[
|
||||
"one",
|
||||
1
|
||||
],
|
||||
[
|
||||
2,
|
||||
{
|
||||
"y" : [
|
||||
3,
|
||||
4
|
||||
]
|
||||
}
|
||||
]
|
||||
]`,
|
||||
assertMsg: "K2",
|
||||
logFormat: "json"
|
||||
});
|
||||
assertToJson({
|
||||
fn: () => tojson(x),
|
||||
expectedStr: '[ [ \"one\", 1 ], [ 2, { \"y\" : [ 3, 4 ] } ] ]',
|
||||
expectedStr: '[ [ "one", 1 ], [ 2, { "y" : [ 3, 4 ] } ] ]',
|
||||
assertMsg: "K3",
|
||||
logFormat: "json"
|
||||
});
|
||||
assertToJson({
|
||||
fn: () => toEJSON(x, "", false),
|
||||
expectedStr: `[
|
||||
[
|
||||
"one",
|
||||
1
|
||||
],
|
||||
[
|
||||
2,
|
||||
{
|
||||
"y" : [
|
||||
3,
|
||||
4
|
||||
]
|
||||
}
|
||||
]
|
||||
]`,
|
||||
assertMsg: "K4"
|
||||
});
|
||||
assertToJson({
|
||||
fn: () => toEJSON(x),
|
||||
expectedStr: '{"$map":[["one",1],[2,{"y":[3,4]}]]}',
|
||||
assertMsg: "K5",
|
||||
logFormat: "json"
|
||||
});
|
||||
|
||||
assert.eq(x, x);
|
||||
assert.neq(x, new Map());
|
||||
|
|
@ -199,6 +431,104 @@ y.set("one", 1);
|
|||
y.set(2, {y: [3, 4]});
|
||||
assert.eq(x, y);
|
||||
|
||||
// Set type
|
||||
x = new Set([{"x": [1, 2, []], "z": "ok", "y": [[]]}, {"foo": "bar"}]);
|
||||
assertToJson({
|
||||
fn: () => tojson(x, "", false),
|
||||
expectedStr: `[
|
||||
{
|
||||
"x" : [
|
||||
1,
|
||||
2,
|
||||
[ ]
|
||||
],
|
||||
"z" : "ok",
|
||||
"y" : [
|
||||
[ ]
|
||||
]
|
||||
},
|
||||
{
|
||||
"foo" : "bar"
|
||||
}
|
||||
]`,
|
||||
assertMsg: "L1"
|
||||
});
|
||||
assertToJson({
|
||||
fn: () => toEJSON(x, "", false),
|
||||
expectedStr: `[
|
||||
{
|
||||
"x" : [
|
||||
1,
|
||||
2,
|
||||
[ ]
|
||||
],
|
||||
"z" : "ok",
|
||||
"y" : [
|
||||
[ ]
|
||||
]
|
||||
},
|
||||
{
|
||||
"foo" : "bar"
|
||||
}
|
||||
]`,
|
||||
assertMsg: "L2"
|
||||
});
|
||||
assertToJson({
|
||||
fn: () => toEJSON(x),
|
||||
expectedStr: '{"$set":[{"x":[1,2,[]],"z":"ok","y":[[]]},{"foo":"bar"}]}',
|
||||
assertMsg: "L3",
|
||||
logFormat: "json"
|
||||
});
|
||||
|
||||
// Array type
|
||||
x = new Array({"x": [1, 2, []], "z": "ok", "y": [[]]}, {"foo": "bar"});
|
||||
assertToJson({
|
||||
fn: () => tojson(x, "", false),
|
||||
expectedStr: `[
|
||||
{
|
||||
"x" : [
|
||||
1,
|
||||
2,
|
||||
[ ]
|
||||
],
|
||||
"z" : "ok",
|
||||
"y" : [
|
||||
[ ]
|
||||
]
|
||||
},
|
||||
{
|
||||
"foo" : "bar"
|
||||
}
|
||||
]`,
|
||||
assertMsg: "M1"
|
||||
});
|
||||
assertToJson({
|
||||
fn: () => toEJSON(x, "", false),
|
||||
expectedStr: `[
|
||||
{
|
||||
"x" : [
|
||||
1,
|
||||
2,
|
||||
[ ]
|
||||
],
|
||||
"z" : "ok",
|
||||
"y" : [
|
||||
[ ]
|
||||
]
|
||||
},
|
||||
{
|
||||
"foo" : "bar"
|
||||
}
|
||||
]`,
|
||||
assertMsg: "M2"
|
||||
});
|
||||
assertToJson({
|
||||
fn: () => toEJSON(x),
|
||||
expectedStr: '[{"x":[1,2,[]],"z":"ok","y":[[]]},{"foo":"bar"}]',
|
||||
assertMsg: "M3",
|
||||
logFormat: "json"
|
||||
});
|
||||
|
||||
// tostrictjson produces proper output
|
||||
x = {
|
||||
"x": NumberLong(64)
|
||||
|
|
@ -227,16 +557,69 @@ x = {
|
|||
"data_maxkey": MaxKey,
|
||||
"data_numberlong": NumberLong("12345"),
|
||||
"data_numberint": NumberInt(5),
|
||||
"data_numberdecimal": NumberDecimal(3.14)
|
||||
"data_numberdecimal": NumberDecimal(3.14),
|
||||
"data_date": new Date(1970, 0, 1, 23, 59, 59, 999)
|
||||
};
|
||||
|
||||
assert.eq(
|
||||
JSON.stringify(x),
|
||||
'{"data_binary":{"$binary":"VG8gYmUgb3Igbm90IHRvIGJlLi4uIFRoYXQgaXMgdGhlIHF1ZXN0aW9uLg==","$type":"00"},"data_timestamp":{"$timestamp":{"t":987654321,"i":0}},"data_regex":{"$regex":"^acme","$options":"i"},"data_oid":{"$oid":"579a70d9e249393f153b5bc1"},"data_ref":{"$ref":"test","$id":"579a70d9e249393f153b5bc1"},"data_minkey":{"$minKey":1},"data_maxkey":{"$maxKey":1},"data_numberlong":{"$numberLong":"12345"},"data_numberint":5,"data_numberdecimal":{"$numberDecimal":"3.14000000000000"}}');
|
||||
'{"data_binary":{"$binary":"VG8gYmUgb3Igbm90IHRvIGJlLi4uIFRoYXQgaXMgdGhlIHF1ZXN0aW9uLg==","$type":"00"},"data_timestamp":{"$timestamp":{"t":987654321,"i":0}},"data_regex":{"$regex":"^acme","$options":"i"},"data_oid":{"$oid":"579a70d9e249393f153b5bc1"},"data_ref":{"$ref":"test","$id":"579a70d9e249393f153b5bc1"},"data_minkey":{"$minKey":1},"data_maxkey":{"$maxKey":1},"data_numberlong":{"$numberLong":"12345"},"data_numberint":5,"data_numberdecimal":{"$numberDecimal":"3.14000000000000"},"data_date":"1970-01-01T23:59:59.999Z"}');
|
||||
assertToJson({
|
||||
fn: () => toEJSON(x),
|
||||
expectedStr:
|
||||
'{"data_binary":{"$binary":"VG8gYmUgb3Igbm90IHRvIGJlLi4uIFRoYXQgaXMgdGhlIHF1ZXN0aW9uLg==","$type":"00"},"data_timestamp":{"$timestamp":{"t":987654321,"i":0}},"data_regex":{"$regex":"^acme","$options":"i"},"data_oid":{"$oid":"579a70d9e249393f153b5bc1"},"data_ref":{"$ref":"test","$id":"579a70d9e249393f153b5bc1"},"data_minkey":{"$minKey":1},"data_maxkey":{"$maxKey":1},"data_numberlong":{"$numberLong":"12345"},"data_numberint":5,"data_numberdecimal":{"$numberDecimal":"3.14000000000000"},"data_date":{"$date":"1970-01-01T23:59:59.999+00:00"}}',
|
||||
assertMsg: "N1",
|
||||
logFormat: "json"
|
||||
});
|
||||
// Serialize recursive object
|
||||
x = {};
|
||||
x.self = x;
|
||||
assertToJson({
|
||||
fn: () => toEJSON(x),
|
||||
expectedStr: '{"self":"[recursive]"}',
|
||||
assertMsg: "N2",
|
||||
logFormat: "json"
|
||||
});
|
||||
// Serialize containers
|
||||
x = {};
|
||||
x.array = new Array(1, "two", [3, false]);
|
||||
x.set = new Set([1, "two", true]);
|
||||
x.map = new Map([["one", 1], [2, {y: [3, 4]}]]);
|
||||
assertToJson({
|
||||
fn: () => toEJSON(x),
|
||||
expectedStr:
|
||||
'{"array":[1,"two",[3,false]],"set":{"$set":[1,"two",true]},"map":{"$map":[["one",1],[2,{"y":[3,4]}]]}}',
|
||||
assertMsg: "N3",
|
||||
logFormat: "json"
|
||||
});
|
||||
|
||||
// serializing Error instances
|
||||
// Serialize Error instances
|
||||
const stringThatNeedsEscaping = 'ho\"la';
|
||||
assert.eq('\"ho\\\"la\"', JSON.stringify(stringThatNeedsEscaping));
|
||||
assert.eq('\"ho\\\"la\"', tojson(stringThatNeedsEscaping));
|
||||
assertToJson(
|
||||
{fn: () => tojson(stringThatNeedsEscaping), expectedStr: '\"ho\\\"la\"', assertMsg: "O1"});
|
||||
assertToJson(
|
||||
{fn: () => toEJSON(stringThatNeedsEscaping), expectedStr: '\"ho\\\"la\"', assertMsg: "O2"});
|
||||
assertToJson({
|
||||
fn: () => toEJSON(stringThatNeedsEscaping),
|
||||
expectedStr: '\"ho\\\"la\"',
|
||||
assertMsg: "O3",
|
||||
logFormat: "json"
|
||||
});
|
||||
assert.eq('{}', JSON.stringify(new Error(stringThatNeedsEscaping)));
|
||||
assert.eq('Error(\"ho\\\"la\")', tojson(new Error(stringThatNeedsEscaping)));
|
||||
assertToJson({
|
||||
fn: () => tojson(new Error(stringThatNeedsEscaping)),
|
||||
expectedStr: 'Error(\"ho\\\"la\")',
|
||||
assertMsg: "O5"
|
||||
});
|
||||
assertToJson({
|
||||
fn: () => toEJSON(new Error(stringThatNeedsEscaping)),
|
||||
expectedStr: 'Error(\"ho\\\"la\")',
|
||||
assertMsg: "O6"
|
||||
});
|
||||
assertToJson({
|
||||
fn: () => toEJSON(new Error(stringThatNeedsEscaping)),
|
||||
expectedStr: '{"$error":"ho\\\"la"}',
|
||||
assertMsg: "O7",
|
||||
logFormat: "json"
|
||||
});
|
||||
|
|
|
|||
|
|
@ -119,6 +119,7 @@ const expectedGlobalVars = [
|
|||
"tojsonObject",
|
||||
"tojsononeline",
|
||||
"tostrictjson",
|
||||
"toEJSON",
|
||||
"undefined",
|
||||
"unescape",
|
||||
"version",
|
||||
|
|
|
|||
|
|
@ -656,10 +656,27 @@ if (typeof (gc) == "undefined") {
|
|||
}
|
||||
|
||||
// Free Functions
|
||||
|
||||
/**
|
||||
* Functions to serialize to JSON and EJSON.
|
||||
*
|
||||
* 'tojson()' and 'tojsononeline()' serialize to JSON. The purpose of these functions is to preserve
|
||||
* compatibility with 'eval()'. The output produced by tojson()/tojsononeline() can be used by
|
||||
* 'eval()' to deserialize the object (note: eval does not work with EJSON). Use in any non-logging
|
||||
* code.
|
||||
*
|
||||
* 'toEJSON()' is similar to 'tostrictjson()' (and both serialize to EJSON), but it works
|
||||
* on any type (not just BSON objects) and also fixes some of its limitations (ie, circular
|
||||
* dependencies). The purpose of this function is to to make sure log lines are parsable by
|
||||
* non-mongo-shell json parsing tools like Parsely. Use in any logging code.
|
||||
*/
|
||||
|
||||
// Note: use 'toEJSON()' instead if the output is used for assertions and/or logging.
|
||||
tojsononeline = function(x) {
|
||||
return tojson(x, " ", true);
|
||||
};
|
||||
|
||||
// Note: use 'toEJSON()' instead if the output is used for assertions and/or logging.
|
||||
tojson = function(x, indent, nolint, depth, sortKeys) {
|
||||
if (x === null)
|
||||
return "null";
|
||||
|
|
@ -785,6 +802,61 @@ tojsonObject = function(x, indent, nolint, depth, sortKeys) {
|
|||
return s + indent + "}";
|
||||
};
|
||||
|
||||
// Converts a JavaScript value to an EJSON string when 'TestData.logFormat == "json"', otherwise
|
||||
// returns the same result as 'tojson()'.
|
||||
// Compared to standard EJSON, this function outputs a different format for Sets, Maps, and Errors.
|
||||
// * Sets serialize as {"$set": [<value1>,...]}
|
||||
// * Maps serialize as {"$map": [[<key1>, <value1>],...]}
|
||||
// * Errors serialize as {"$error": "<error_message>"}
|
||||
//
|
||||
// Use this function in assertions and/or logging.
|
||||
// Note: Use 'tojson()' or 'tojsononeline()' instead if the output is used to rehydrate objects
|
||||
// using 'eval()'.
|
||||
toEJSON = function(x, indent, nolint, depth, sortKeys) {
|
||||
if (typeof TestData !== "object" || TestData.logFormat !== "json")
|
||||
return tojson(x, indent, nolint, depth, sortKeys);
|
||||
|
||||
function ensureEJSONAndStopOnRecursion() {
|
||||
// Stack of ancestors (objects) of the current 'value'.
|
||||
// eg, For {"x": 1, "y": {"z": 2}} and value = 2,
|
||||
// ancestors = [{"x": 1, "y": {"z": 2}}, {"z": 2}]
|
||||
let ancestors = [];
|
||||
return function(key, value) {
|
||||
if (value instanceof Error) {
|
||||
return {"$error": value.message};
|
||||
}
|
||||
if (value instanceof Map) {
|
||||
return {"$map": [...value]};
|
||||
}
|
||||
if (value instanceof Set) {
|
||||
return {"$set": [...value]};
|
||||
}
|
||||
// 'value' is a a pre-transformed property value (of type string in case of Dates),
|
||||
// so we use 'this[key]' instead to get the original value.
|
||||
if (this[key] instanceof Date) {
|
||||
return {"$date": this[key].toISOString().replace("Z", "+00:00")};
|
||||
}
|
||||
if (typeof value !== "object" || value === null) {
|
||||
return value;
|
||||
}
|
||||
// Remove ancestors not part of the path to current 'value' anymore.
|
||||
// `this` is the object that value is contained in,
|
||||
// i.e., its direct parent.
|
||||
while (ancestors.length > 0 && ancestors.at(-1) !== this) {
|
||||
ancestors.pop();
|
||||
}
|
||||
// 'value' is an object at this point. If it has already been seen, prune the traversal
|
||||
// to avoid a 'TypeError' due to self-referencing objects.
|
||||
if (ancestors.includes(value)) {
|
||||
return "[recursive]";
|
||||
}
|
||||
ancestors.push(value);
|
||||
return value;
|
||||
};
|
||||
}
|
||||
return JSON.stringify(x, ensureEJSONAndStopOnRecursion());
|
||||
};
|
||||
|
||||
printjson = function(x) {
|
||||
print(tojson(x));
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue