| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322 | 
							- "use strict";
 
- var assert = require("assert"),
 
- 	DocumentSource = require("../../../../lib/pipeline/documentSources/DocumentSource"),
 
- 	UnwindDocumentSource = require("../../../../lib/pipeline/documentSources/UnwindDocumentSource"),
 
- 	CursorDocumentSource = require("../../../../lib/pipeline/documentSources/CursorDocumentSource"),
 
- 	Cursor = require("../../../../lib/Cursor");
 
- //HELPERS
 
- var assertExhausted = function assertExhausted(pds) {
 
-     assert.ok(pds.eof());
 
-     assert.ok(!pds.advance());
 
- };
 
- /**
 
- *   Tests if the given rep is the same as what the pds resolves to as JSON.
 
- *   MUST CALL WITH A PDS AS THIS (e.g. checkJsonRepresentation.call(this, rep) where this is a PDS)
 
- **/
 
- var checkJsonRepresentation = function checkJsonRepresentation(self, rep) {
 
- 	var pdsRep = {};
 
- 	self.sourceToJson(pdsRep, true);
 
- 	assert.deepEqual(pdsRep, rep);
 
- };
 
- var createUnwind = function createUnwind(unwind) {
 
-     //let unwind be optional
 
-     if (!unwind) {
 
- 		unwind = "$a";
 
-     }
 
-     var spec = {"$unwind": unwind},
 
-         specElement = unwind,
 
- 		unwindDs = UnwindDocumentSource.createFromJson(specElement);
 
-     checkJsonRepresentation(unwindDs, spec);
 
-     return unwindDs;
 
- };
 
- var addSource = function addSource(unwind, data) {
 
- 	var cwc = new CursorDocumentSource.CursorWithContext();
 
- 	cwc._cursor = new Cursor(data);
 
- 	var cds = new CursorDocumentSource(cwc);
 
- 	var pds = new UnwindDocumentSource();
 
- 	unwind.setSource(cds);
 
- };
 
- var checkResults = function checkResults(data, expectedResults, path) {
 
- 	//poplateData?
 
- 	//createSource?
 
- 	var unwind = createUnwind(path);
 
- 	addSource(unwind, data || []);
 
- 	expectedResults = expectedResults || [];
 
- 	//Load the results from the DocumentSourceUnwind
 
- 	var resultSet = [];
 
-     while (!unwind.eof()) {
 
- 		// If not eof, current is non null.
 
- 		assert.ok(unwind.getCurrent());
 
- 		// Get the current result.
 
- 		resultSet.push(unwind.getCurrent());
 
- 		// Advance.
 
- 		if (unwind.advance()) {
 
- 			// If advance succeeded, eof() is false.
 
- 			assert.equal(unwind.eof(), false);
 
- 		}
 
-     }
 
- 	// Verify the DocumentSourceUnwind is exhausted.
 
- 	assertExhausted(unwind);
 
-     assert.deepEqual(resultSet, expectedResults);
 
- };
 
- var throwsException = function throwsException(data, path, expectedResults) {
 
- 	assert.throws(function () {
 
- 		checkResults(data, path, expectedResults);
 
- 	});
 
- };
 
- //TESTS
 
- module.exports = {
 
-     "UnwindDocumentSource": {
 
-         "constructor()": {
 
-             "should not throw Error when constructing without args": function (){
 
-                 assert.doesNotThrow(function(){
 
-                     new UnwindDocumentSource();
 
-                 });
 
-             }
 
-         },
 
-         "#getSourceName()": {
 
-             "should return the correct source name; $unwind": function (){
 
-                 var pds = new UnwindDocumentSource();
 
-                 assert.strictEqual(pds.getSourceName(), "$unwind");
 
-             }
 
-         },
 
-         "#eof()": {
 
-             "should return true if source is empty": function (){
 
-                 var pds = createUnwind();
 
-                 addSource(pds, []);
 
-                 assert.strictEqual(pds.eof(), true);
 
-             },
 
-             
 
-             "should return false if source documents exist": function (){
 
-                 var pds = createUnwind();
 
-                 addSource(pds, [{_id:0, a:[1]}]);
 
-                 assert.strictEqual(pds.eof(), false);
 
-             }
 
-         },
 
-         "#advance()": {
 
-             "should return false if there are no documents in the parent source": function () {
 
-                 var pds = createUnwind();
 
-                 addSource(pds, []);
 
-                 assert.strictEqual(pds.advance(), false);
 
-             },
 
-             "should return true if source documents exist and advance the source": function (){
 
-                 var pds = createUnwind();
 
-                 addSource(pds, [{_id:0, a:[1,2]}]);
 
-                 assert.strictEqual(pds.advance(), true);
 
-                 assert.strictEqual(pds.getCurrent().a, 2);
 
-             }
 
-         },
 
-         "#getCurrent()": {
 
-             "should return null if there are no documents in the parent source": function () {
 
-                 var pds = createUnwind();
 
-                 addSource(pds, []);
 
-                 assert.strictEqual(pds.getCurrent(), null);
 
-             },
 
-             "should return unwound documents": function (){
 
-                 var pds = createUnwind();
 
-                 addSource(pds, [{_id:0, a:[1,2]}]);
 
-                 assert.ok(pds.getCurrent());
 
-                 assert.strictEqual(pds.getCurrent().a, 1);
 
-             },
 
-             
 
-             "A document without the unwind field produces no results.": function(){
 
- 				checkResults([{}]);
 
-             },
 
-             "A document with a null field produces no results.": function(){
 
- 				checkResults([{a:null}]);
 
-             },
 
-             "A document with an empty array produces no results.": function(){
 
- 				checkResults([{a:[]}]);
 
-             },
 
-             "A document with a number field produces a UserException.": function(){
 
- 				throwsException([{a:1}]);
 
-             },
 
-             "An additional document with a number field produces a UserException.": function(){
 
- 				throwsException([{a:[1]}, {a:1}]);
 
-             },
 
-             "A document with a string field produces a UserException.": function(){
 
- 				throwsException([{a:"foo"}]);
 
-             },
 
-             "A document with an object field produces a UserException.": function(){
 
- 				throwsException([{a:{}}]);
 
-             },
 
-             "Unwind an array with one value.": function(){
 
- 				checkResults(
 
- 					[{_id:0, a:[1]}],
 
- 					[{_id:0,a:1}]
 
- 				);
 
-             },
 
-             "Unwind an array with two values.": function(){
 
- 				checkResults(
 
- 					[{_id:0, a:[1, 2]}],
 
- 					[{_id:0,a:1}, {_id:0,a:2}]
 
- 				);
 
-             },
 
-             "Unwind an array with two values, one of which is null.": function(){
 
- 				checkResults(
 
- 					[{_id:0, a:[1, null]}],
 
- 					[{_id:0,a:1}, {_id:0,a:null}]
 
- 				);
 
-             },
 
-             "Unwind two documents with arrays.": function(){
 
- 				checkResults(
 
- 					[{_id:0, a:[1,2]}, {_id:0, a:[3,4]}],
 
- 					[{_id:0,a:1}, {_id:0,a:2}, {_id:0,a:3}, {_id:0,a:4}]
 
- 				);
 
-             },
 
-             "Unwind an array in a nested document.": function(){
 
- 				checkResults(
 
- 					[{_id:0,a:{b:[1,2],c:3}}],
 
- 					[{_id:0,a:{b:1,c:3}},{_id:0,a:{b:2,c:3}}],
 
- 					"$a.b"
 
- 				);
 
-             },
 
-             "A missing array (that cannot be nested below a non object field) produces no results.": function(){
 
- 				checkResults(
 
- 					[{_id:0,a:4}],
 
- 					[],
 
- 					"$a.b"
 
- 				);
 
-             },
 
-             "Unwind an array in a doubly nested document.": function(){
 
- 				checkResults(
 
- 					[{_id:0,a:{b:{d:[1,2],e:4},c:3}}],
 
- 					[{_id:0,a:{b:{d:1,e:4},c:3}},{_id:0,a:{b:{d:2,e:4},c:3}}],
 
- 					"$a.b.d"
 
- 				);
 
-             },
 
-             "Unwind several documents in a row.": function(){
 
- 				checkResults(
 
- 					[
 
- 						{_id:0,a:[1,2,3]},
 
- 						{_id:1},
 
- 						{_id:2},
 
- 						{_id:3,a:[10,20]},
 
- 						{_id:4,a:[30]}
 
- 					],
 
- 					[
 
- 						{_id:0,a:1},
 
- 						{_id:0,a:2},
 
- 						{_id:0,a:3},
 
- 						{_id:3,a:10},
 
-                         {_id:3,a:20},
 
-                         {_id:4,a:30}
 
-                     ]
 
- 				);
 
-             },
 
-             "Unwind several more documents in a row.": function(){
 
- 				checkResults(
 
- 					[
 
- 						{_id:0,a:null},
 
- 						{_id:1},
 
- 						{_id:2,a:['a','b']},
 
- 						{_id:3},
 
- 						{_id:4,a:[1,2,3]},
 
- 						{_id:5,a:[4,5,6]},
 
- 						{_id:6,a:[7,8,9]},
 
- 						{_id:7,a:[]}
 
- 					],
 
- 					[
 
- 						{_id:2,a:'a'},
 
- 						{_id:2,a:'b'},
 
- 						{_id:4,a:1},
 
- 						{_id:4,a:2},
 
-                         {_id:4,a:3},
 
-                         {_id:5,a:4},
 
-                         {_id:5,a:5},
 
-                         {_id:5,a:6},
 
-                         {_id:6,a:7},
 
-                         {_id:6,a:8},
 
-                         {_id:6,a:9}
 
- 					]
 
- 				);
 
-             }
 
-             
 
-         },
 
-         "#createFromJson()": {
 
-             "should error if called with non-string": function testNonObjectPassed() {
 
-                 //Date as arg
 
-                 assert.throws(function() {
 
-                     var pds = createUnwind(new Date());
 
-                 });
 
-                 //Array as arg
 
-                 assert.throws(function() {
 
-                     var pds = createUnwind([]);
 
-                 });
 
-                 //Empty args
 
-                 assert.throws(function() {
 
-                     var pds = UnwindDocumentSource.createFromJson();
 
-                 });
 
-                 //Top level operator
 
-                 assert.throws(function() {
 
-                     var pds = createUnwind({$add: []});
 
-                 });
 
-             }
 
-         },
 
-         "#getDependencies": {
 
- 			"should get dependent field paths": function () {
 
-                 var pds = createUnwind("$x.y.z"),
 
- 					deps = {};
 
-                 assert.strictEqual(pds.getDependencies(deps), DocumentSource.GetDepsReturn.SEE_NEXT);
 
-                 assert.deepEqual(deps, {"x.y.z":1});
 
- 			}
 
-         }
 
-     }
 
- };
 
- if (!module.parent)(new(require("mocha"))()).ui("exports").reporter("spec").addFile(__filename).run(process.exit);
 
 
  |