Skip to content

Commit 9b7a982

Browse files
committed
merge
2 parents 68aa928 + 31e2c81 commit 9b7a982

File tree

2 files changed

+113
-14
lines changed

2 files changed

+113
-14
lines changed

lib/helpers.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ exports.prepareMetaData = meta => {
2626
* @param {Array=} opt_parents Object's parents
2727
*/
2828
function cloneMeta(node, opt_parents) {
29-
if (!(node instanceof Object) || (node instanceof ObjectID)
30-
|| (node instanceof Buffer)) {
29+
if (!((node !== null && typeof node === 'object') || typeof node === 'function')
30+
|| (node instanceof ObjectID) || (node instanceof Buffer)) {
3131
return node;
3232
}
3333
let copy = Array.isArray(node) ? [] : {};
@@ -48,7 +48,7 @@ function cloneMeta(node, opt_parents) {
4848
if (newKey.includes('.') || newKey.includes('$')) {
4949
newKey = newKey.replace(/\./g, '[dot]').replace(/\$/g, '[$]');
5050
}
51-
if (value instanceof Object) {
51+
if ((value !== null && typeof value === 'object') || typeof value === 'function') {
5252
if (opt_parents.indexOf(value) === -1) {
5353
copy[newKey] = cloneMeta(value, opt_parents);
5454
} else {

test/helpers-test.js

+110-11
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77
'use strict';
88
const assert = require('assert');
9+
const ObjectID = require('mongodb').ObjectID;
910
const helpers = require('../lib/helpers');
1011

1112
class CustomError extends Error {
@@ -15,33 +16,131 @@ class CustomError extends Error {
1516
}
1617
}
1718

18-
const originalData = {
19-
customDate: new Date(),
20-
standardError: new Error('some error'),
21-
customError: new CustomError()
22-
};
19+
describe('winston-mongodb-helpers', function() {
20+
describe('#prepareMetaData()', function() {
21+
it('should preserve Date instances', function() {
22+
const originalData = { customDate: new Date() };
23+
24+
const preparedData = helpers.prepareMetaData(originalData);
2325

24-
describe('winston-mongodb-helpers', function () {
25-
describe('#prepareMetaData()', function () {
26-
const preparedData = helpers.prepareMetaData(originalData);
27-
it('should preserve Date instances', function () {
2826
assert(preparedData.customDate instanceof Date);
2927
assert.strictEqual(+preparedData.customDate, +originalData.customDate);
3028
});
31-
it('should store Error objects', function () {
29+
it('should store Error objects', function() {
30+
const originalData = { standardError: new Error('some error') };
31+
32+
const preparedData = helpers.prepareMetaData(originalData);
33+
3234
assert(preparedData.standardError instanceof Object);
3335
assert(!(preparedData.standardError instanceof Error));
3436
assert.strictEqual(preparedData.standardError.message, originalData.standardError.message);
3537
assert.strictEqual(preparedData.standardError.name, originalData.standardError.name);
3638
assert.strictEqual(preparedData.standardError.stack, originalData.standardError.stack);
3739
});
38-
it('should store extra fields for custom Error objects', function () {
40+
it('should store extra fields for custom Error objects', function() {
41+
const originalData = { customError: new CustomError() };
42+
43+
const preparedData = helpers.prepareMetaData(originalData);
44+
3945
assert(preparedData.customError instanceof Object);
4046
assert(!(preparedData.customError instanceof Error));
4147
assert.strictEqual(preparedData.customError.message, originalData.customError.message);
4248
assert.strictEqual(preparedData.customError.name, originalData.customError.name);
4349
assert.strictEqual(preparedData.customError.stack, originalData.customError.stack);
4450
assert.strictEqual(preparedData.customError.testField, originalData.customError.testField);
4551
});
52+
it('should preserve ObjectIds', function() {
53+
const originalData = { objectId: new ObjectID() };
54+
55+
const preparedData = helpers.prepareMetaData(originalData);
56+
57+
assert.strictEqual(preparedData.objectId, originalData.objectId);
58+
});
59+
it('should preserve Buffers', function() {
60+
const originalData = { buffer: new Buffer.from('test') };
61+
62+
const preparedData = helpers.prepareMetaData(originalData);
63+
64+
assert.strictEqual(preparedData.buffer, originalData.buffer);
65+
});
66+
it('should handle objects containing all kinds of values, including arrays, nested objects and functions', function() {
67+
const originalData = {
68+
undefinedValue: undefined,
69+
nullValue: null,
70+
booleanValue: true,
71+
numberValue: 1,
72+
bigIntValue: BigInt(9007199254740991),
73+
stringValue: 'test',
74+
symbolValue: Symbol(),
75+
arrayValue: ['this', 'is', 'an', 'array'],
76+
nestedObjectValue: { objectKey: true },
77+
functionValue: (a, b) => a + b
78+
};
79+
80+
const preparedData = helpers.prepareMetaData(originalData);
81+
82+
const expected = { ...originalData, functionValue: {} }
83+
assert.deepStrictEqual(preparedData, expected);
84+
});
85+
it('should handle arrays containing all kinds of values, including objects, nested arrays and functions', function() {
86+
const originalData = [
87+
undefined,
88+
null,
89+
true,
90+
1,
91+
BigInt(9007199254740991),
92+
'test',
93+
Symbol(),
94+
{ objectKey: true },
95+
['this', 'is', 'an', 'array'],
96+
(a, b) => a + b
97+
];
98+
99+
const preparedData = helpers.prepareMetaData(originalData);
100+
101+
const expected = [...originalData];
102+
expected[expected.length - 1] = {}; // function gets converted to empty object
103+
assert.deepStrictEqual(preparedData, expected);
104+
});
105+
it('should replace dots and dollar signs in object keys', function() {
106+
const originalData = { 'key.with.dots': true, '$test$': true };
107+
108+
const preparedData = helpers.prepareMetaData(originalData);
109+
110+
const expected = { 'key[dot]with[dot]dots': true, '[$]test[$]': true };
111+
assert.deepStrictEqual(preparedData, expected);
112+
});
113+
it('should break circular dependencies', function() {
114+
const originalData = {};
115+
originalData.nestedObjectValue = { nestedKey: originalData };
116+
originalData.arrayValue = [originalData, 'test', { nestedKey: originalData }];
117+
118+
const preparedData = helpers.prepareMetaData(originalData);
119+
120+
const expected = {
121+
nestedObjectValue: { nestedKey: '[Circular]' },
122+
arrayValue: ['[Circular]', 'test', { nestedKey: '[Circular]' }]
123+
};
124+
125+
assert.deepStrictEqual(preparedData, expected);
126+
});
127+
it('should handle objects with null prototype', function() {
128+
const originalData = Object.create(null);
129+
originalData['key.with.dots'] = true;
130+
originalData['$test$'] = true;
131+
originalData.nestedObjectValue = { nestedKey: originalData };
132+
originalData.arrayValue = [originalData, 'test', { nestedKey: originalData }];
133+
134+
const preparedData = helpers.prepareMetaData(originalData);
135+
136+
const expected = {
137+
'key[dot]with[dot]dots': true,
138+
'[$]test[$]': true,
139+
nestedObjectValue: { nestedKey: '[Circular]' },
140+
arrayValue: ['[Circular]', 'test', { nestedKey: '[Circular]' }]
141+
};
142+
143+
assert.deepStrictEqual(preparedData, expected);
144+
});
46145
});
47146
});

0 commit comments

Comments
 (0)