Skip to content

Commit

Permalink
applied requested changes
Browse files Browse the repository at this point in the history
  • Loading branch information
lpizzinidev committed Oct 19, 2022
1 parent 0b95f7e commit c7f051e
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 7 deletions.
13 changes: 11 additions & 2 deletions lib/document.js
Expand Up @@ -4593,12 +4593,21 @@ Document.prototype.getChanges = function() {
*/

Document.prototype.$clone = function() {
const clonedDoc = Object.assign(Object.create(Object.getPrototypeOf(this)), this);
const Model = this.constructor;
const clonedDoc = new Model();
for (const p of Object.getOwnPropertyNames(this)) {
clonedDoc[p] = clone(this[p]);
}
if (this._doc) {
clonedDoc._doc = clone(this._doc);
}
if (this.$__) {
clonedDoc.$__ = Object.assign(Object.create(Object.getPrototypeOf(this.$__)), this.$__);
const Cache = this.$__.constructor;
const clonedCache = new Cache();
for (const p of Object.getOwnPropertyNames(this.$__)) {
clonedCache[p] = clone(this.$__[p]);
}
clonedDoc.$__ = clonedCache;
}
return clonedDoc;
};
Expand Down
48 changes: 43 additions & 5 deletions test/document.test.js
Expand Up @@ -11930,17 +11930,55 @@ describe('document', function() {
});

it('$clone() (gh-11849)', async function() {
const schema = new mongoose.Schema({ name: String });
const schema = new mongoose.Schema({
name: {
type: String,
validate: {
validator: (v) => v !== 'Invalid'
}
}
});
const Test = db.model('Test', schema);

const item = await Test.create({ name: 'Mongoose' });
const item = await Test.create({ name: 'Test' });

const doc = await Test.findById(item._id);
const clonedDoc = doc.$clone();

assert.deepEqual(doc, clonedDoc);
assert.deepEqual(doc._doc, clonedDoc._doc);
assert.deepEqual(doc.$__, clonedDoc.$__);
assert.deepEqual(clonedDoc, doc);
assert.deepEqual(clonedDoc._doc, doc._doc);
assert.deepEqual(clonedDoc.$__, doc.$__);

// Editing a field in the cloned doc does not effect
// the original doc
clonedDoc.name = 'Test 2';
assert.equal(doc.name, 'Test');
assert.equal(clonedDoc.name, 'Test 2');

// Saving the cloned doc does not effect `modifiedPaths`
// in the original doc
const modifiedPaths = doc.modifiedPaths;
await clonedDoc.save();
assert.deepEqual(doc.modifiedPaths, modifiedPaths);

// Cloning a doc with invalid field preserve the
// invalid field value
doc.name = 'Invalid';
await assert.rejects(async() => {
await doc.validate();
});
const invalidClonedDoc = doc.$clone();
doc.name = 'Test';
await assert.rejects(async() => {
await invalidClonedDoc.validate();
});

// Setting a session on the cloned doc does not
// affect the session in the original doc
const session = await Test.startSession();
clonedDoc.$session(session);
assert.strictEqual(doc.$session(), null);
assert.strictEqual(clonedDoc.$session(), session);
});
});

Expand Down

0 comments on commit c7f051e

Please sign in to comment.