Skip to content

Commit

Permalink
Implement recursive snapshotOriginal
Browse files Browse the repository at this point in the history
  • Loading branch information
ivank committed Jul 5, 2017
1 parent d94c93f commit 4ff2707
Show file tree
Hide file tree
Showing 9 changed files with 252 additions and 41 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mongoose-originals",
"version": "1.2.0",
"version": "1.3.0",
"description": "Get original value of mongoose fields",
"main": "src/index.js",
"repository": "git@github.com:enhancv/mongoose-originals.git",
Expand All @@ -17,7 +17,7 @@
"dotenv": "^4.0.0",
"istanbul": "^0.4.5",
"mocha": "^3.2.0",
"mongoose": "^4.8"
"mongoose": "^4.11.1"
},
"dependencies": {
"lodash": "^4.17.4"
Expand Down
30 changes: 30 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
const { isEqual, pick } = require("lodash/fp");

function eachMongooseOriginalsPath(item, fn, name) {
if (item && item.schema) {
if (item.schema.mongooseOriginals) {
fn(item);
}
item.schema.eachPath((name, type) => {
if (item[name] instanceof Array) {
item[name].forEach(item => eachMongooseOriginalsPath(item, fn, name));
} else {
eachMongooseOriginalsPath(item[name], fn, name);
}
});
}
}

function mongooseOriginals(schema, userOptions) {
var options = Object.assign({ methods: true }, userOptions);

Expand All @@ -11,6 +26,18 @@ function mongooseOriginals(schema, userOptions) {
return !this.original || !isEqual(this.original, pick(options.fields, this.toObject()));
}

function setSnapshotOriginal() {
eachMongooseOriginalsPath(this, item => {
item.snapshotOriginal = item.original;
});
}

function clearSnapshotOriginal() {
eachMongooseOriginalsPath(this, item => {
delete item.snapshotOriginal;
});
}

function saveOriginalNamed() {
this.original = {};
const newValues = this.toObject();
Expand All @@ -26,6 +53,9 @@ function mongooseOriginals(schema, userOptions) {
}
}

schema.mongooseOriginals = true;
schema.method("setSnapshotOriginal", setSnapshotOriginal);
schema.method("clearSnapshotOriginal", clearSnapshotOriginal);
schema.method("initOriginals", initOriginals);
schema.method("isChanged", isChanged);
schema.post("init", saveOriginalNamed);
Expand Down
97 changes: 96 additions & 1 deletion test/indexTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ const database = require("./database");
const mongoose = require("mongoose");
const Customer = require("./models/Customer");
const Subscription = require("./models/Subscription");
const Nested = require("./models/Nested");
const originals = require("../src");

describe(
"Customer",
database([Customer], function() {
database([Customer, Nested], function() {
it("Should throw an error if no fields are defined", function() {
const Schema = mongoose.Schema;

Expand All @@ -22,6 +23,100 @@ describe(
}, /No fields specified for mongoose originals on schema/);
});

it.only("Should test nested setSnapshotOriginal and clearSnapshotOriginal", function() {
const nested = new Nested({
name: "11",
embedded: { name: "22", children: [{ title: "33" }, { title: "44" }] },
children: [
{ category: "55", nested: { type: "66" } },
{ category: "77", nested: { type: "88" } },
],
});

return nested
.save()
.then(nested => {
nested.setSnapshotOriginal();

assert.deepEqual(nested.snapshotOriginal, nested.original);
assert.deepEqual(nested.embedded.snapshotOriginal, nested.embedded.original);
assert.deepEqual(
nested.embedded.children[0].snapshotOriginal,
nested.embedded.children[0].original
);
assert.deepEqual(
nested.embedded.children[1].snapshotOriginal,
nested.embedded.children[1].original
);
assert.deepEqual(
nested.children[0].snapshotOriginal,
nested.children[0].original
);
assert.deepEqual(
nested.children[0].nested.snapshotOriginal,
nested.children[0].nested.original
);
assert.deepEqual(
nested.children[1].snapshotOriginal,
nested.children[1].original
);
assert.deepEqual(
nested.children[1].nested.snapshotOriginal,
nested.children[1].nested.original
);

assert.deepEqual(nested.snapshotOriginal, { name: "11", email: undefined });
assert.deepEqual(nested.embedded.snapshotOriginal, { name: "22" });
assert.deepEqual(nested.embedded.children[0].snapshotOriginal, { title: "33" });
assert.deepEqual(nested.embedded.children[1].snapshotOriginal, { title: "44" });
assert.deepEqual(nested.children[0].snapshotOriginal, { category: "55" });
assert.deepEqual(nested.children[0].nested.snapshotOriginal, { type: "66" });
assert.deepEqual(nested.children[1].snapshotOriginal, { category: "77" });
assert.deepEqual(nested.children[1].nested.snapshotOriginal, { type: "88" });

nested.name = "t1";
nested.embedded.name = "t2";
nested.embedded.children[0].title = "t3";
nested.embedded.children[1].title = "t4";
nested.children[0].category = "t5";
nested.children[0].nested.type = "t6";
nested.children[1].category = "t7";
nested.children[1].nested.type = "t8";

return nested.save();
})
.then(nestedSaved => {
assert.deepEqual(nestedSaved.original, { name: "t1", email: undefined });
assert.deepEqual(nestedSaved.embedded.original, { name: "t2" });
assert.deepEqual(nestedSaved.embedded.children[0].original, { title: "t3" });
assert.deepEqual(nestedSaved.embedded.children[1].original, { title: "t4" });
assert.deepEqual(nestedSaved.children[0].original, { category: "t5" });
assert.deepEqual(nestedSaved.children[0].nested.original, { type: "t6" });
assert.deepEqual(nestedSaved.children[1].original, { category: "t7" });
assert.deepEqual(nestedSaved.children[1].nested.original, { type: "t8" });

assert.deepEqual(nested.snapshotOriginal, { name: "11", email: undefined });
assert.deepEqual(nested.embedded.snapshotOriginal, { name: "22" });
assert.deepEqual(nested.embedded.children[0].snapshotOriginal, { title: "33" });
assert.deepEqual(nested.embedded.children[1].snapshotOriginal, { title: "44" });
assert.deepEqual(nested.children[0].snapshotOriginal, { category: "55" });
assert.deepEqual(nested.children[0].nested.snapshotOriginal, { type: "66" });
assert.deepEqual(nested.children[1].snapshotOriginal, { category: "77" });
assert.deepEqual(nested.children[1].nested.snapshotOriginal, { type: "88" });

nested.clearSnapshotOriginal();

assert.equal(nested.snapshotOriginal, undefined);
assert.equal(nested.embedded.snapshotOriginal, undefined);
assert.equal(nested.embedded.children[0].snapshotOriginal, undefined);
assert.equal(nested.embedded.children[1].snapshotOriginal, undefined);
assert.equal(nested.children[0].snapshotOriginal, undefined);
assert.equal(nested.children[0].nested.snapshotOriginal, undefined);
assert.equal(nested.children[1].snapshotOriginal, undefined);
assert.equal(nested.children[1].nested.snapshotOriginal, undefined);
});
});

it("Should not add collection methods if specified", function() {
const Schema = mongoose.Schema;

Expand Down
13 changes: 13 additions & 0 deletions test/models/DocumentArrayNestedSchema.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const Schema = require("mongoose").Schema;
const originals = require("../../src");

const DocumentArrayNestedSchema = new Schema(
{
type: String,
},
{ _id: false }
);

DocumentArrayNestedSchema.plugin(originals, { fields: ["type"] });

module.exports = DocumentArrayNestedSchema;
15 changes: 15 additions & 0 deletions test/models/DocumentArraySchema.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const Schema = require("mongoose").Schema;
const originals = require("../../src");
const DocumentArrayNestedSchema = require("./DocumentArrayNestedSchema");

const DocumentArraySchema = new Schema(
{
category: String,
nested: DocumentArrayNestedSchema,
},
{ _id: false }
);

DocumentArraySchema.plugin(originals, { fields: ["category"] });

module.exports = DocumentArraySchema;
13 changes: 13 additions & 0 deletions test/models/EmbeddedNestedSchema.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const Schema = require("mongoose").Schema;
const originals = require("../../src");

const EmbeddedNestedSchema = new Schema(
{
title: String,
},
{ _id: false }
);

EmbeddedNestedSchema.plugin(originals, { fields: ["title"] });

module.exports = EmbeddedNestedSchema;
15 changes: 15 additions & 0 deletions test/models/EmbeddedSchema.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const Schema = require("mongoose").Schema;
const originals = require("../../src");
const EmbeddedNestedSchema = require("./EmbeddedNestedSchema");

const EmbeddedSchema = new Schema(
{
name: String,
children: [EmbeddedNestedSchema],
},
{ _id: false }
);

EmbeddedSchema.plugin(originals, { fields: ["name"] });

module.exports = EmbeddedSchema;
18 changes: 18 additions & 0 deletions test/models/Nested.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const originals = require("../../src");
const DocumentArraySchema = require("./DocumentArraySchema");
const EmbeddedSchema = require("./EmbeddedSchema");

const NestedSchema = new Schema({
name: String,
email: String,
embedded: EmbeddedSchema,
children: [DocumentArraySchema],
});

NestedSchema.plugin(originals, { fields: ["name", "email"] });

const Nested = mongoose.model("Nested", NestedSchema);

module.exports = Nested;
Loading

0 comments on commit 4ff2707

Please sign in to comment.