UNPKG

modifyjs

Version:

Modify your objects with a mongo syntax.

372 lines (308 loc) 13.8 kB
import update from 'immutability-helper'; import modify from './modify.js'; // Examples are taken from https://docs.mongodb.com/manual/reference/ describe("modify", function () { describe("$currentDate", function () { it.skip("sets a field with a currentDate", function () { var myObject = { existingItem: "here" }; var updatedObject = modify(myObject, { $currentDate: "lastModified" }); var expectedObject = { existingItem: "here", lastModified: new Date() }; // placeholder, obviously wrong expect(updatedObject).toEqual(expectedObject); }); }); describe("$min", function () { it("updates a field when the passed value is lower than an existing one", function () { var myObject = { _id: 1, highScore: 800, lowScore: 200 }; var updatedObject = modify(myObject, { $min: { lowScore: 150 } }); var expectedObject = babelHelpers.extends({}, myObject, { lowScore: 150 }); expect(updatedObject).toEqual(expectedObject); }); it("doesn't update a field when the passed value is higher than an existing one", function () { var myObject = { _id: 1, highScore: 800, lowScore: 200 }; var updatedObject = modify(myObject, { $min: { lowScore: 250 } }); var expectedObject = babelHelpers.extends({}, myObject); expect(updatedObject).toEqual(expectedObject); }); }); describe("$max", function () { it("updates a field when the passed value is higher than an existing one", function () { var myObject = { _id: 1, highScore: 800, lowScore: 200 }; var updatedObject = modify(myObject, { $max: { highScore: 950 } }); var expectedObject = babelHelpers.extends({}, myObject, { highScore: 950 }); expect(updatedObject).toEqual(expectedObject); }); it("doesn't update a field when the passed value is lower than an existing one", function () { var myObject = { _id: 1, highScore: 950, lowScore: 200 }; var updatedObject = modify(myObject, { $max: { highScore: 870 } }); var expectedObject = babelHelpers.extends({}, myObject); expect(updatedObject).toEqual(expectedObject); }); }); describe("$inc", function () { it("can increment with positive and negative values at the same time", function () { var myObject = { _id: 1, sku: "abc123", quantity: 10, metrics: { orders: 2, ratings: 3.5 } }; var updatedObject = modify(myObject, { $inc: { quantity: -2, "metrics.orders": 1 } }); var expectedObject = update(myObject, { quantity: { $set: myObject.quantity - 2 }, metrics: { orders: { $set: myObject.metrics.orders + 1 } } }); expect(updatedObject).toEqual(expectedObject); }); }); describe("$set", function () { // https://docs.mongodb.com/manual/reference/operator/update/set/#set-top-level-fields it("sets top-level fields", function () { var myObject = { _id: 100, sku: "abc123", quantity: 250, instock: true, reorder: false, details: { model: "14Q2", make: "xyz" }, tags: ["apparel", "clothing"], ratings: [{ by: "ijk", rating: 4 }] }; var updatedObject = modify(myObject, { $set: { quantity: 500, details: { model: "14Q3", make: "xyz" }, tags: ["coats", "outerwear", "clothing"] } }); var expectedObject = update(myObject, { quantity: { $set: 500 }, details: { $set: { model: "14Q3", make: "xyz" } }, tags: { $set: ["coats", "outerwear", "clothing"] } }); expect(updatedObject).toEqual(expectedObject); }); // https://docs.mongodb.com/manual/reference/operator/update/set/#set-fields-in-embedded-documents it("sets fields in embedded documents", function () { var myObject = { _id: 100, sku: "abc123", quantity: 250, instock: true, reorder: false, details: { model: "14Q2", make: "xyz" }, tags: ["apparel", "clothing"], ratings: [{ by: "ijk", rating: 4 }] }; var updatedObject = modify(myObject, { $set: { "details.make": "zzz" } }); var expectedObject = update(myObject, { details: { make: { $set: "zzz" } } }); expect(updatedObject).toEqual(expectedObject); }); // https://docs.mongodb.com/manual/reference/operator/update/set/#set-elements-in-arrays it("sets elements in arrays", function () { var myObject = { _id: 100, sku: "abc123", quantity: 250, instock: true, reorder: false, details: { model: "14Q2", make: "xyz" }, tags: ["apparel", "clothing"], ratings: [{ by: "ijk", rating: 4 }] }; var updatedObject = modify(myObject, { $set: { "tags.1": "rain gear", "ratings.0.rating": 2 } }); var expectedObject = update(myObject, { tags: { 1: { $set: "rain gear" } }, ratings: { 0: { rating: { $set: 2 } } } }); expect(updatedObject).toEqual(expectedObject); }); }); // https://docs.mongodb.com/manual/reference/operator/update/unset/ describe("$unset", function () { it("deletes a particular field", function () { var myObject = { sku: "unknown", quantity: 2, instock: true }; var updatedObject = modify(myObject, { $unset: { quantity: "", instock: "" } }); var expectedObject = babelHelpers.extends({}, myObject); delete expectedObject.quantity; delete expectedObject.instock; expect(updatedObject).toEqual(updatedObject); }); }); describe("$push", function () { // https://docs.mongodb.com/manual/reference/operator/update/push/#append-a-value-to-an-array it("appends a value to an array", function () { var myObject = { _id: 1, scores: [50] }; var updatedObject = modify(myObject, { $push: { scores: 89 } }); var expectedObject = update(myObject, { scores: { $push: [89] } }); expect(updatedObject).toEqual(expectedObject); }); // https://docs.mongodb.com/manual/reference/operator/update/push/#append-multiple-values-to-an-array it("appends multiple values to an array", function () { var myObject = { name: "joe", scores: [50] }; var updatedObject = modify(myObject, { $push: { scores: { $each: [90, 92, 85] } } }); var expectedObject = update(myObject, { scores: { $push: [90, 92, 85] } }); expect(updatedObject).toEqual(expectedObject); }); // https://docs.mongodb.com/manual/reference/operator/update/push/#use-push-operator-with-multiple-modifiers // Looks like this is not fully supported in minimongo yet! // I get MinimongoError: $slice in $push must be zero or negative for field 'quizzes' //TODO When I change slice to negative, turns out I don't have minimongo sorter yet, will investigate this later it.skip("can update an array with multiple modifiers", function () { var myObject = { "_id": 5, "quizzes": [{ "wk": 1, "score": 10 }, { "wk": 2, "score": 8 }, { "wk": 3, "score": 5 }, { "wk": 4, "score": 6 }] }; var updatedObject = modify(myObject, { $push: { quizzes: { $each: [{ wk: 5, score: 8 }, { wk: 6, score: 7 }, { wk: 7, score: 6 }], $sort: { score: -1 }, $slice: 3 } } }); var expectedObject = { "_id": 5, "quizzes": [{ "wk": 1, "score": 10 }, { "wk": 2, "score": 8 }, { "wk": 5, "score": 8 }] }; expect(updatedObject).toEqual(expectedObject); }); }); // deprecated since mongo 2.4, based on the example of $push "appends multiple values to an array" above // describe("$pushAll", function () { it("appends multiple values to an array without $each", function () { var myObject = { name: "joe", scores: [50] }; // compare with - notice the $each // {$push: {scores: {$each: [90, 92, 85]}}}; var updatedObject = modify(myObject, { $pushAll: { scores: [90, 92, 85] } }); var expectedObject = update(myObject, { scores: { $push: [90, 92, 85] } }); expect(updatedObject).toEqual(expectedObject); }); }); // https://docs.mongodb.com/manual/reference/operator/update/addToSet/#behavior describe("$addToSet", function () { it("appends array with an array", function () { var myObject = { _id: 1, letters: ["a", "b"] }; var updatedObject = modify(myObject, { $addToSet: { letters: ["c", "d"] } }); var expectedObject = { _id: 1, letters: ["a", "b", ["c", "d"]] }; expect(updatedObject).toEqual(expectedObject); }); // https://docs.mongodb.com/manual/reference/operator/update/addToSet/#examples it("adds element to an array if element doesn't already exist", function () { var myObject = { _id: 1, item: "polarizing_filter", tags: ["electronics", "camera"] }; var updatedObject = modify(myObject, { $addToSet: { tags: "accessories" } }); var expectedObject = update(myObject, { tags: { $push: ["accessories"] } }); expect(updatedObject).toEqual(expectedObject); }); it("doesn't add an element to the array if it does already exists", function () { var myObject = { _id: 1, item: "polarizing_filter", tags: ["electronics", "camera"] }; var updatedObject = modify(myObject, { $addToSet: { tags: "camera" } }); var expectedObject = babelHelpers.extends({}, myObject); expect(updatedObject).toEqual(expectedObject); }); // https://docs.mongodb.com/manual/reference/operator/update/addToSet/#each-modifier it("adds multiple values to the array field with $each modifier, omitting existing ones", function () { var myObject = { _id: 2, item: "cable", tags: ["electronics", "supplies"] }; var updatedObject = modify(myObject, { $addToSet: { tags: { $each: ["camera", "electronics", "accessories"] } } }); var expectedObject = update(myObject, { tags: { $push: ["camera", "accessories"] } }); expect(updatedObject).toEqual(expectedObject); }); }); describe("$pop", function () { // https://docs.mongodb.com/manual/reference/operator/update/pop/#remove-the-first-item-of-an-array it("removes the first element from an array", function () { var myObject = { _id: 1, scores: [8, 9, 10] }; var updatedObject = modify(myObject, { $pop: { scores: -1 } }); var expectedObject = { _id: 1, scores: [9, 10] }; expect(updatedObject).toEqual(expectedObject); }); // https://docs.mongodb.com/manual/reference/operator/update/pop/#remove-the-last-item-of-an-array it("removes the last item of an array", function () { var myObject = { _id: 1, scores: [9, 10] }; var updatedObject = modify(myObject, { $pop: { scores: 1 } }); var expectedObject = { _id: 1, scores: [9] }; expect(updatedObject).toEqual(expectedObject); }); }); describe("$pull", function () { // https://docs.mongodb.com/manual/reference/operator/update/pull/#remove-all-items-that-equals-a-specified-value it.skip("removes all items that equals a specified value", function () { var myObject = { _id: 1, fruits: ["apples", "pears", "oranges", "grapes", "bananas"], vegetables: ["carrots", "celery", "squash", "carrots"] }; var updatedObject = modify(myObject, { $pull: { fruits: { $in: ["apples", "oranges"] }, vegetables: "carrots" } }); var expectedObject = { "_id": 1, "fruits": ["pears", "grapes", "bananas"], "vegetables": ["celery", "squash"] }; // notice two carrots missing from the vegetables array expect(updatedObject).toEqual(expectedObject); }); // https://docs.mongodb.com/manual/reference/operator/update/pull/#remove-all-items-that-match-a-specified-pull-condition it.skip("Remove All Items That Match a Specified $pull Condition", function () { var myObject = { _id: 1, votes: [3, 5, 6, 7, 7, 8] }; var updatedObject = modify(myObject, { $pull: { votes: { $gte: 6 } } }); var expectedObject = { _id: 1, votes: [3, 5] }; expect(updatedObject).toEqual(expectedObject); }); }); describe("$pullAll", function () { // https://docs.mongodb.com/manual/reference/operator/update/pullAll/#up._S_pullAll it("removes all instances of the specified values from an existing array", function () { var myObject = { _id: 1, scores: [0, 2, 5, 5, 1, 0] }; var updatedObject = modify(myObject, { $pullAll: { scores: [0, 5] } }); var expectedObject = { _id: 1, scores: [2, 1] }; expect(updatedObject).toEqual(expectedObject); }); }); // https://docs.mongodb.com/manual/reference/operator/update/rename/ describe("$rename", function () { it("updates the name of a field", function () { var myObject = { "_id": 1, "alias": ["The American Cincinnatus", "The American Fabius"], "mobile": "555-555-5555", "nmae": { "first": "george", "last": "washington" } }; var updatedObject = modify(myObject, { $rename: { "nmae": "name" } }); var expectedObject = babelHelpers.extends({}, myObject); delete expectedObject.nmae; expectedObject.name = babelHelpers.extends({}, myObject.nmae); expect(updatedObject).toEqual(expectedObject); }); }); it("throws an error when the operand path contains an empty field name", function () { var myObject = {}; expect(function () { modify(myObject, { $set: { "test.abc.": "name" } }); }).toThrow(/empty field name/); }); });