From 74c9373d3ab26975671b2560101d97ede5a006f5 Mon Sep 17 00:00:00 2001 From: Slava Kim Date: Mon, 11 Nov 2013 11:43:06 -0800 Subject: [PATCH] Define projection function contract: returned doc shouldn't retain anything from the passed argument. --- packages/minimongo/minimongo_tests.js | 31 +++++++++++++++++++++++++++ packages/minimongo/projection.js | 6 ++++++ 2 files changed, 37 insertions(+) diff --git a/packages/minimongo/minimongo_tests.js b/packages/minimongo/minimongo_tests.js index 3f2ce855fa..43dbbf45e9 100644 --- a/packages/minimongo/minimongo_tests.js +++ b/packages/minimongo/minimongo_tests.js @@ -1151,6 +1151,37 @@ Tinytest.add("minimongo - fetch with projection, subarrays", function (test) { {a: [ [ { c: 2 }, { c: 4 } ], { c: 5 }, [ { c: 9 } ] ] }); }); +Tinytest.add("minimongo - fetch with projection, deep copy", function (test) { + // Compiled fields projection defines the contract: returned document doesn't + // retain anything from the passed argument. + var doc = { + a: { x: 42 }, + b: { + y: { z: 33 } + }, + c: "asdf" + }; + + var fields = { + 'a': 1, + 'b.y': 1 + }; + + var projectionFn = LocalCollection._compileProjection(fields); + var filteredDoc = projectionFn(doc); + doc.a.x++; + doc.b.y.z--; + test.equal(filteredDoc.a.x, 42, "projection returning deep copy - including"); + test.equal(filteredDoc.b.y.z, 33, "projection returning deep copy - including"); + + fields = { c: 0 }; + projectionFn = LocalCollection._compileProjection(fields); + filteredDoc = projectionFn(doc); + + doc.a.x = 5; + test.equal(filteredDoc.a.x, 43, "projection returning deep copy - excluding"); +}); + Tinytest.add("minimongo - observe ordered with projection", function (test) { // These tests are copy-paste from "minimongo -observe ordered", // slightly modified to test projection diff --git a/packages/minimongo/projection.js b/packages/minimongo/projection.js index 3230fc6b19..73a10c59cb 100644 --- a/packages/minimongo/projection.js +++ b/packages/minimongo/projection.js @@ -1,4 +1,10 @@ // Knows how to compile a fields projection to a predicate function. +// @returns - Function: a closure that filters out an object according to the +// fields projection rules: +// @param obj - Object: MongoDB-styled document +// @returns - Object: a document with the fields filtered out +// according to projection rules. Doesn't retain subfields +// of passed argument. LocalCollection._compileProjection = function (fields) { var _idProjection = _.isUndefined(fields._id) ? true : fields._id; var details = projectionDetails(fields);