ProjectDocumentSource.js 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. var assert = require("assert"),
  2. DocumentSource = require("../../../../lib/pipeline/documentSources/DocumentSource"),
  3. ProjectDocumentSource = require("../../../../lib/pipeline/documentSources/ProjectDocumentSource"),
  4. CursorDocumentSource = require("../../../../lib/pipeline/documentsources/CursorDocumentSource"),
  5. Cursor = require("../../../../lib/Cursor");
  6. //HELPERS
  7. var assertExhausted = function assertExhausted(pds) {
  8. assert.ok(pds.eof());
  9. assert.ok(!pds.advance());
  10. };
  11. /**
  12. * Tests if the given rep is the same as what the pds resolves to as JSON.
  13. * MUST CALL WITH A PDS AS THIS (e.g. checkJsonRepresentation.call(this, rep) where this is a PDS)
  14. **/
  15. var checkJsonRepresentation = function checkJsonRepresentation(self, rep) {
  16. var pdsRep = {};
  17. self.sourceToJson(pdsRep, true);
  18. assert.deepEqual(pdsRep, rep);
  19. };
  20. var createProject = function createProject(projection) {
  21. //let projection be optional
  22. if(!projection){
  23. projection = {a:true};
  24. }
  25. var spec = {"$project": projection},
  26. specElement = projection,
  27. pds = new ProjectDocumentSource(),
  28. project = pds.createFromJson(specElement);
  29. checkJsonRepresentation(project, spec);
  30. return project;
  31. };
  32. //TESTS
  33. module.exports = {
  34. "ProjectDocumentSource": {
  35. "constructor()": {
  36. "should throw Error when constructing with args": function testConstructor(){
  37. assert.throws(function(){
  38. new ProjectDocumentSource({ctx: [1,2]});
  39. });
  40. }
  41. },
  42. "#getSourceName()": {
  43. "should return the correct source name; $project": function testSourceName(){
  44. var pds = new ProjectDocumentSource();
  45. assert.strictEqual(pds.getSourceName(), "$project");
  46. }
  47. },
  48. "#eof()": {
  49. "should return same as this.pSource.eof": function testEOF(){
  50. var pds = new ProjectDocumentSource();
  51. pds.setSource({
  52. eof: function eof() {
  53. return true;
  54. }
  55. });
  56. assert.ok(pds.eof());
  57. },
  58. "should return !eof == true when a document is still in cursor": function testNotEOFTrueIfDocPresent() {
  59. var cwc = new CursorDocumentSource.CursorWithContext();
  60. cwc._cursor = new Cursor( [{a: 1}] );
  61. var cds = new CursorDocumentSource(cwc);
  62. var pds = new ProjectDocumentSource();
  63. pds.setSource(cds);
  64. assert.ok(!pds.eof());
  65. }
  66. },
  67. "#advance()": {
  68. "should return same as this.psource.advance": function testCallsThisPSourceAdvance() {
  69. var pds = new ProjectDocumentSource();
  70. pds.setSource({
  71. advance: function advance() {
  72. return true;
  73. }
  74. });
  75. assert.ok(pds.advance());
  76. },
  77. /*
  78. "can retrieve values from the project when advance is first function call": function testAdvanceFirst() {
  79. var cwc = new CursorDocumentSource.CursorWithContext();
  80. var input = [{_id: 0, a: 1}, {_id: 1, a: 2}];
  81. cwc._cursor = new Cursor( input );
  82. var cds = new CursorDocumentSource(cwc);
  83. var pds = createProject();
  84. pds.setSource(cds);
  85. assert.ok(pds.advance());
  86. assert.equal(2, pds.getCurrent().a);
  87. }
  88. */
  89. },
  90. /* TODO : copy mongo tests, they will probably be more involved */
  91. "#getCurrent()": {
  92. /*
  93. "should work when getCurrent is the first function call": function getCurrentCalledFirst() {
  94. var cwc = new CursorDocumentSource.CursorWithContext();
  95. var input = [{_id: 0, a: 1}];
  96. cwc._cursor = new Cursor( input );
  97. var cds = new CursorDocumentSource(cwc);
  98. var pds = createProject();
  99. pds.setSource(cds);
  100. assert.ok(pds.getCurrent());
  101. assert.equal(1, pds.getCurrent().a);
  102. }
  103. */
  104. },
  105. "combined": {
  106. /*
  107. "The a and c.d fields are included but the b field is not": function testFullProject1() {
  108. var cwc = new CursorDocumentSource.CursorWithContext();
  109. var input = [{_id:0,a:1,b:1,c:{d:1}}];
  110. cwc._cursor = new Cursor( input );
  111. var cds = new CursorDocumentSource(cwc);
  112. var pds = createProject({a:true, c:{d:true}});
  113. pds.setSource(cds);
  114. assert.ok(pds.getCurrent());
  115. assert.equal(1, pds.getCurrent().a);
  116. assert.ok(!pds.getCurrent().b);
  117. assert.equal(0, pds.getCurrent()._id);
  118. assert.equal(1, pds.getCurrent().c.d);
  119. },
  120. "Two documents": function testTwoDocumentsProject() {
  121. var cwc = new CursorDocumentSource.CursorWithContext();
  122. var input = [{a:1, b:2}, {a:3, b:4}];
  123. cwc._cursor = new Cursor( input );
  124. var cds = new CursorDocumentSource(cwc);
  125. var pds = createProject({a:true, c:{d:true}});
  126. pds.setSource(cds);
  127. assert.ok(!pds.eof());
  128. assert.equal(1, pds.getCurrent().a);
  129. assert.ok(!pds.getCurrent().b);
  130. assert.equal(0, pds.getCurrent()._id);
  131. assert.equal(1, pds.getCurrent().c.d);
  132. assert.ok(pds.advance());
  133. assert.ok(!pds.eof());
  134. assert.equal(3, pds.getCurrent().a);
  135. assert.ok(!pds.getCurrent().b);
  136. assert.ok(!project.advance());
  137. assertExhausted(pds);
  138. }
  139. */
  140. },
  141. "#optimize()": {
  142. "Optimize the projection": function optimizeProject() {
  143. var pds = createProject({a:{$and: [true]}});
  144. pds.optimize();
  145. checkJsonRepresentation(pds, {$project:{a:{$const:true}}});
  146. }
  147. },
  148. "#createFromJson()": {
  149. "should error if called with non-object": function testNonObjectPassed() {
  150. //String as arg
  151. assert.throws(function() {
  152. var pds = createProject("not an object");
  153. });
  154. //Date as arg
  155. assert.throws(function() {
  156. var pds = createProject(new Date());
  157. });
  158. //Array as arg
  159. assert.throws(function() {
  160. var pds = createProject([]);
  161. });
  162. //Empty args
  163. assert.throws(function() {
  164. var pds = new ProjectDocumentSource();
  165. pds = pds.createFromJson();
  166. });
  167. //Top level operator
  168. assert.throws(function() {
  169. var pds = createProject({$add: []});
  170. });
  171. //Invalid spec
  172. assert.throws(function() {
  173. var pds = createProject({a:{$invalidOperator:1}});
  174. });
  175. }
  176. },
  177. "#getDependencies()": {
  178. /*
  179. "should return a new ProjectDocumentSource object from an input object": function createTest(){
  180. var cwc = new CursorDocumentSource.CursorWithContext();
  181. var input = [{a:true,x:'$b',y:{$and:['$c','$d']}}];
  182. var pds = createProject(input);
  183. var dependencies = {};
  184. assert.equals(DocumentSource.GetDepsReturn.EXHAUSTIVE, pds.getDependencies(dependencies));
  185. assert.equals(5, dependencies.length);
  186. assert.ok(dependencies._id);
  187. assert.ok(dependencies.a);
  188. assert.ok(dependencies.b);
  189. assert.ok(dependencies.c);
  190. assert.ok(dependencies.d);
  191. }
  192. */
  193. }
  194. }
  195. };
  196. if (!module.parent)(new(require("mocha"))()).ui("exports").reporter("spec").addFile(__filename).run(process.exit);