ProjectDocumentSource.js 8.1 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. project = ProjectDocumentSource.createFromJson(specElement);
  28. checkJsonRepresentation(project, spec);
  29. return project;
  30. };
  31. //TESTS
  32. module.exports = {
  33. "ProjectDocumentSource": {
  34. "constructor()": {
  35. "should throw Error when constructing with args": function testConstructor(){
  36. assert.throws(function(){
  37. new ProjectDocumentSource({ctx: [1,2]});
  38. });
  39. }
  40. },
  41. "#getSourceName()": {
  42. "should return the correct source name; $project": function testSourceName(){
  43. var pds = new ProjectDocumentSource();
  44. assert.strictEqual(pds.getSourceName(), "$project");
  45. }
  46. },
  47. "#eof()": {
  48. "should return same as this.pSource.eof": function testEOF(){
  49. var pds = new ProjectDocumentSource();
  50. pds.setSource({
  51. eof: function eof() {
  52. return true;
  53. }
  54. });
  55. assert.ok(pds.eof());
  56. },
  57. "should return !eof == true when a document is still in cursor": function testNotEOFTrueIfDocPresent() {
  58. var cwc = new CursorDocumentSource.CursorWithContext();
  59. cwc._cursor = new Cursor( [{a: 1}] );
  60. var cds = new CursorDocumentSource(cwc);
  61. var pds = new ProjectDocumentSource();
  62. pds.setSource(cds);
  63. assert.ok(!pds.eof());
  64. }
  65. },
  66. "#advance()": {
  67. "should return same as this.psource.advance": function testCallsThisPSourceAdvance() {
  68. var pds = new ProjectDocumentSource();
  69. pds.setSource({
  70. advance: function advance() {
  71. return true;
  72. }
  73. });
  74. assert.ok(pds.advance());
  75. },
  76. /*
  77. "can retrieve values from the project when advance is first function call": function testAdvanceFirst() {
  78. var cwc = new CursorDocumentSource.CursorWithContext();
  79. var input = [{_id: 0, a: 1}, {_id: 1, a: 2}];
  80. cwc._cursor = new Cursor( input );
  81. var cds = new CursorDocumentSource(cwc);
  82. var pds = createProject();
  83. pds.setSource(cds);
  84. assert.ok(pds.advance());
  85. assert.equal(2, pds.getCurrent().a);
  86. }
  87. */
  88. },
  89. /* TODO : copy mongo tests, they will probably be more involved */
  90. "#getCurrent()": {
  91. /*
  92. "should work when getCurrent is the first function call": function getCurrentCalledFirst() {
  93. var cwc = new CursorDocumentSource.CursorWithContext();
  94. var input = [{_id: 0, a: 1}];
  95. cwc._cursor = new Cursor( input );
  96. var cds = new CursorDocumentSource(cwc);
  97. var pds = createProject();
  98. pds.setSource(cds);
  99. assert.ok(pds.getCurrent());
  100. assert.equal(1, pds.getCurrent().a);
  101. }
  102. */
  103. },
  104. "combined": {
  105. /*
  106. "The a and c.d fields are included but the b field is not": function testFullProject1() {
  107. var cwc = new CursorDocumentSource.CursorWithContext();
  108. var input = [{_id:0,a:1,b:1,c:{d:1}}];
  109. cwc._cursor = new Cursor( input );
  110. var cds = new CursorDocumentSource(cwc);
  111. var pds = createProject({a:true, c:{d:true}});
  112. pds.setSource(cds);
  113. assert.ok(pds.getCurrent());
  114. assert.equal(1, pds.getCurrent().a);
  115. assert.ok(!pds.getCurrent().b);
  116. assert.equal(0, pds.getCurrent()._id);
  117. assert.equal(1, pds.getCurrent().c.d);
  118. },
  119. "Two documents": function testTwoDocumentsProject() {
  120. var cwc = new CursorDocumentSource.CursorWithContext();
  121. var input = [{a:1, b:2}, {a:3, b:4}];
  122. cwc._cursor = new Cursor( input );
  123. var cds = new CursorDocumentSource(cwc);
  124. var pds = createProject({a:true, c:{d:true}});
  125. pds.setSource(cds);
  126. assert.ok(!pds.eof());
  127. assert.equal(1, pds.getCurrent().a);
  128. assert.ok(!pds.getCurrent().b);
  129. assert.equal(0, pds.getCurrent()._id);
  130. assert.equal(1, pds.getCurrent().c.d);
  131. assert.ok(pds.advance());
  132. assert.ok(!pds.eof());
  133. assert.equal(3, pds.getCurrent().a);
  134. assert.ok(!pds.getCurrent().b);
  135. assert.ok(!project.advance());
  136. assertExhausted(pds);
  137. }
  138. */
  139. },
  140. "#optimize()": {
  141. /*
  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. },
  149. "#createFromJson()": {
  150. "should error if called with non-object": function testNonObjectPassed() {
  151. //String as arg
  152. assert.throws(function() {
  153. var pds = createProject("not an object");
  154. });
  155. //Date as arg
  156. assert.throws(function() {
  157. var pds = createProject(new Date());
  158. });
  159. //Array as arg
  160. assert.throws(function() {
  161. var pds = createProject([]);
  162. });
  163. //Empty args
  164. assert.throws(function() {
  165. pds = ProjectDocumentSource.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);