| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- "use strict";
- var assert = require("assert"),
- async = require("async"),
- DocumentSource = require("../../../../lib/pipeline/documentSources/DocumentSource"),
- ProjectDocumentSource = require("../../../../lib/pipeline/documentSources/ProjectDocumentSource"),
- CursorDocumentSource = require("../../../../lib/pipeline/documentSources/CursorDocumentSource"),
- Cursor = require("../../../../lib/Cursor");
- /**
- * 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 createProject = function createProject(projection) {
- //let projection be optional
- if (!projection) {
- projection = {
- a: true
- };
- }
- var spec = {
- "$project": projection
- },
- specElement = projection,
- project = ProjectDocumentSource.createFromJson(specElement);
- checkJsonRepresentation(project, spec);
- return project;
- };
- //TESTS
- module.exports = {
- "ProjectDocumentSource": {
- "constructor()": {
- "should not throw Error when constructing without args": function testConstructor() {
- assert.doesNotThrow(function() {
- new ProjectDocumentSource();
- });
- }
- },
- "#getSourceName()": {
- "should return the correct source name; $project": function testSourceName() {
- var pds = new ProjectDocumentSource();
- assert.strictEqual(pds.getSourceName(), "$project");
- }
- },
- "#getNext()": {
- "should return EOF": function testEOF(next) {
- var pds = createProject();
- pds.setSource({
- getNext: function getNext(cb) {
- return cb(null, DocumentSource.EOF);
- }
- });
- pds.getNext(function(err, doc) {
- assert.equal(DocumentSource.EOF, doc);
- next();
- });
- },
- "iterator state accessors consistently report the source is exhausted": function assertExhausted() {
- var cwc = new CursorDocumentSource.CursorWithContext();
- var input = [{}];
- cwc._cursor = new Cursor( input );
- var cds = new CursorDocumentSource(cwc);
- var pds = createProject();
- pds.setSource(cds);
- pds.getNext(function(err, actual) {
- pds.getNext(function(err, actual1) {
- assert.equal(DocumentSource.EOF, actual1);
- pds.getNext(function(err, actual2) {
- assert.equal(DocumentSource.EOF, actual2);
- pds.getNext(function(err, actual3) {
- assert.equal(DocumentSource.EOF, actual3);
- });
- });
- });
- });
- },
- "callback is required": function requireCallback() {
- var pds = createProject();
- assert.throws(pds.getNext.bind(pds));
- },
- "should not return EOF when a document is still in cursor": function testNotEOFTrueIfDocPresent() {
- var cwc = new CursorDocumentSource.CursorWithContext();
- var input = [{_id: 0, a: 1}, {_id: 1, a: 2}];
- cwc._cursor = new Cursor( input );
- var cds = new CursorDocumentSource(cwc);
- var pds = createProject();
- pds.setSource(cds);
- pds.getNext(function(err,actual) {
- // first go round
- assert.notEqual(actual, DocumentSource.EOF);
- });
- },
- "can retrieve second document from source": function testAdvanceFirst() {
- var cwc = new CursorDocumentSource.CursorWithContext();
- var input = [{_id: 0, a: 1}, {_id: 1, a: 2}];
- cwc._cursor = new Cursor( input );
- var cds = new CursorDocumentSource(cwc);
- var pds = createProject();
- pds.setSource(cds);
- pds.getNext(function(err,val) {
- // eh, ignored
- pds.getNext(function(err,val) {
- assert.equal(2, val.a);
- });
- });
- },
- "should get the first document out of a cursor": function getCurrentCalledFirst() {
- var cwc = new CursorDocumentSource.CursorWithContext();
- var input = [{_id: 0, a: 1}];
- cwc._cursor = new Cursor( input );
- var cds = new CursorDocumentSource(cwc);
- var pds = createProject();
- pds.setSource(cds);
- pds.getNext(function(err, actual) {
- assert.equal(1, actual.a);
- });
- },
- "The a and c.d fields are included but the b field is not": function testFullProject1(next) {
- var cwc = new CursorDocumentSource.CursorWithContext();
- var input = [{
- _id: 0,
- a: 1,
- b: 1,
- c: {
- d: 1
- }
- }];
- cwc._cursor = new Cursor(input);
- var cds = new CursorDocumentSource(cwc);
- var pds = createProject({
- a: true,
- c: {
- d: true
- }
- }),
- expected = {a:1, c:{ d: 1 }};
- pds.setSource(cds);
- pds.getNext(function(err,val) {
- assert.deepEqual(expected, val);
- next();
- });
- },
- "Two documents": function testTwoDocumentsProject(next) {
- var cwc = new CursorDocumentSource.CursorWithContext();
- var input = [{
- a: 1,
- b: 2
- }, {
- a: 3,
- b: 4
- }],
- expected = [
- {a:1},
- {a:3},
- DocumentSource.EOF
- ];
- cwc._cursor = new Cursor(input);
- var cds = new CursorDocumentSource(cwc);
- var pds = createProject({
- a: true,
- c: {
- d: true
- }
- });
- pds.setSource(cds);
- async.series([
- pds.getNext.bind(pds),
- pds.getNext.bind(pds),
- pds.getNext.bind(pds),
- ],
- function(err,res) {
- assert.deepEqual(expected, res);
- next();
- }
- );
- }
- },
- "#optimize()": {
- "Optimize the projection": function optimizeProject() {
- var pds = createProject({
- a: {
- $and: [true]
- }
- });
- pds.optimize();
- checkJsonRepresentation(pds, {
- $project: {
- a: {
- $const: true
- }
- }
- });
- }
- },
- "#createFromJson()": {
- "should error if called with non-object": function testNonObjectPassed() {
- //String as arg
- assert.throws(function() {
- var pds = createProject("not an object");
- });
- //Date as arg
- assert.throws(function() {
- var pds = createProject(new Date());
- });
- //Array as arg
- assert.throws(function() {
- var pds = createProject([]);
- });
- //Empty args
- assert.throws(function() {
- var pds = ProjectDocumentSource.createFromJson();
- });
- //Top level operator
- assert.throws(function() {
- var pds = createProject({
- $add: []
- });
- });
- //Invalid spec
- assert.throws(function() {
- var pds = createProject({
- a: {
- $invalidOperator: 1
- }
- });
- });
- }
- },
- "#getDependencies()": {
- "should properly detect dependencies in project": function testGetDependencies() {
- var cwc = new CursorDocumentSource.CursorWithContext();
- var input = {
- a: true,
- x: '$b',
- y: {
- $and: ['$c', '$d']
- }
- };
- var pds = createProject(input);
- var dependencies = {};
- assert.equal(DocumentSource.GetDepsReturn.EXHAUSTIVE, pds.getDependencies(dependencies));
- assert.equal(5, Object.keys(dependencies).length);
- assert.ok(dependencies._id);
- assert.ok(dependencies.a);
- assert.ok(dependencies.b);
- assert.ok(dependencies.c);
- assert.ok(dependencies.d);
- }
- }
- }
- };
- if (!module.parent)(new(require("mocha"))()).ui("exports").reporter("spec").addFile(__filename).grep(process.env.MOCHA_GREP || '').run(process.exit);
|