aggregate.js 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. "use strict";
  2. var assert = require("assert"),
  3. aggregate = require("../../");
  4. module.exports = {
  5. "aggregate": {
  6. "should be able to use an empty pipeline (no-op)": function(){
  7. var i = [1, 2, 3],
  8. p = [],
  9. e = [1, 2, 3],
  10. aggregater = aggregate(p),
  11. a = aggregater(i);
  12. assert.equal(JSON.stringify(a), JSON.stringify(e), "Unexpected value!");
  13. assert.deepEqual(a, e, "Unexpected value (not deepEqual)!");
  14. assert.equal(JSON.stringify(aggregater(i)), JSON.stringify(e), "Reuse of aggregater should yield the same results!");
  15. assert.equal(JSON.stringify(aggregate(p, i)), JSON.stringify(e), "Alternate use of aggregate should yield the same results!");
  16. },
  17. "should be able to use a $limit operator": function(){
  18. var i = [{_id:0}, {_id:1}, {_id:2}, {_id:3}, {_id:4}, {_id:5}],
  19. p = [{$limit:2}],
  20. e = [{_id:0}, {_id:1}],
  21. aggregater = aggregate(p),
  22. a = aggregater(i);
  23. assert.equal(JSON.stringify(a), JSON.stringify(e), "Unexpected value!");
  24. assert.deepEqual(a, e, "Unexpected value (not deepEqual)!");
  25. assert.equal(JSON.stringify(aggregater(i)), JSON.stringify(e), "Reuse of aggregater should yield the same results!");
  26. assert.equal(JSON.stringify(aggregate(p, i)), JSON.stringify(e), "Alternate use of aggregate should yield the same results!");
  27. },
  28. "should be able to use a $match operator": function(){
  29. var i = [{_id:0, e:1}, {_id:1, e:0}, {_id:2, e:1}, {_id:3, e:0}, {_id:4, e:1}, {_id:5, e:0}],
  30. p = [{$match:{e:1}}],
  31. e = [{_id:0, e:1}, {_id:2, e:1}, {_id:4, e:1}],
  32. aggregater = aggregate(p),
  33. a = aggregater(i);
  34. assert.equal(JSON.stringify(a), JSON.stringify(e), "Unexpected value!");
  35. assert.deepEqual(a, e, "Unexpected value (not deepEqual)!");
  36. assert.equal(JSON.stringify(aggregater(i)), JSON.stringify(e), "Reuse of aggregater should yield the same results!");
  37. assert.equal(JSON.stringify(aggregate(p, i)), JSON.stringify(e), "Alternate use of aggregate should yield the same results!");
  38. },
  39. "should be able to use a $skip operator": function(){
  40. var i = [{_id:0}, {_id:1}, {_id:2}, {_id:3}, {_id:4}, {_id:5}],
  41. p = [{$skip:2}, {$skip:1}], //testing w/ 2 ensures independent state variables
  42. e = [{_id:3}, {_id:4}, {_id:5}],
  43. aggregater = aggregate(p),
  44. a = aggregater(i);
  45. assert.equal(JSON.stringify(a), JSON.stringify(e), "Unexpected value!");
  46. assert.deepEqual(a, e, "Unexpected value (not deepEqual)!");
  47. assert.equal(JSON.stringify(aggregater(i)), JSON.stringify(e), "Reuse of aggregater should yield the same results!");
  48. assert.equal(JSON.stringify(aggregate(p, i)), JSON.stringify(e), "Alternate use of aggregate should yield the same results!");
  49. },
  50. "should be able to use a $skip and then a $limit operator together in the same pipeline": function(){
  51. var i = [{_id:0, e:1}, {_id:1, e:0}, {_id:2, e:1}, {_id:3, e:0}, {_id:4, e:1}, {_id:5, e:0}],
  52. p = [{$skip:2}, {$limit:1}],
  53. e = [{_id:2, e:1}],
  54. aggregater = aggregate(p),
  55. a = aggregater(i);
  56. assert.equal(JSON.stringify(a), JSON.stringify(e), "Unexpected value!");
  57. assert.deepEqual(a, e, "Unexpected value (not deepEqual)!");
  58. assert.equal(JSON.stringify(aggregater(i)), JSON.stringify(e), "Reuse of aggregater should yield the same results!");
  59. assert.equal(JSON.stringify(aggregate(p, i)), JSON.stringify(e), "Alternate use of aggregate should yield the same results!");
  60. },
  61. "should be able to construct an instance with $unwind operators properly": function(){
  62. var i = [
  63. {_id:0, nodes:[
  64. {one:[11], two:[2,2]},
  65. {one:[1,1], two:[22]}
  66. ]},
  67. {_id:1, nodes:[
  68. {two:[22], three:[333]},
  69. {one:[1], three:[3,3,3]}
  70. ]}
  71. ],
  72. p = [{$unwind:"$nodes"}, {$unwind:"$nodes.two"}],
  73. e = [
  74. {_id:0,nodes:{one:[11],two:2}},
  75. {_id:0,nodes:{one:[11],two:2}},
  76. {_id:0,nodes:{one:[1,1],two:22}},
  77. {_id:1,nodes:{two:22,three:[333]}}
  78. ],
  79. aggregater = aggregate(p),
  80. a = aggregater(i);
  81. assert.equal(JSON.stringify(a), JSON.stringify(e), "Unexpected value!");
  82. assert.deepEqual(a, e, "Unexpected value (not deepEqual)!");
  83. assert.equal(JSON.stringify(aggregater(i)), JSON.stringify(e), "Reuse of aggregater should yield the same results!");
  84. assert.equal(JSON.stringify(aggregate(p, i)), JSON.stringify(e), "Alternate use of aggregate should yield the same results!");
  85. },
  86. "should be able to use a $project operator": function(){
  87. var i = [{_id:0, e:1, f:23}, {_id:2, e:2, g:34}, {_id:4, e:3}],
  88. p = [{$project:{
  89. e:1,
  90. a:{$add:["$e", "$e"]},
  91. b:{$cond:[{$eq:["$e", 2]}, "two", "not two"]}
  92. //TODO: high level test of all other expression operators
  93. }}],
  94. e = [{_id:0, e:1, b:"not two", a:2}, {_id:2, e:2, b:"two", a:4}, {_id:4, e:3, b:"not two", a:6}],
  95. aggregater = aggregate(p),
  96. a = aggregater(i);
  97. assert.deepEqual(a, e, "Unexpected value (not deepEqual)!");
  98. assert.deepEqual(aggregater(i), e, "Reuse of aggregater should yield the same results!");
  99. assert.deepEqual(aggregate(p, i), e, "Alternate use of aggregate should yield the same results!");
  100. },
  101. "should be able to use a $project operator to exclude the _id field": function(){
  102. var i = [{_id:0, e:1, f:23}, {_id:2, e:2, g:34}, {_id:4, e:3}],
  103. p = [{$project:{
  104. _id:0,
  105. e:1
  106. //TODO: high level test of all other expression operators
  107. }}],
  108. e = [{e:1}, {e:2}, {e:3}],
  109. aggregater = aggregate(p),
  110. a = aggregater(i);
  111. assert.deepEqual(a, e, "Unexpected value (not deepEqual)!");
  112. assert.deepEqual(aggregater(i), e, "Reuse of aggregater should yield the same results!");
  113. assert.deepEqual(aggregate(p, i), e, "Alternate use of aggregate should yield the same results!");
  114. },
  115. "should be able to construct an instance with $sort operators properly (ascending)": function(){
  116. var i = [
  117. {_id:3.14159}, {_id:-273.15},
  118. {_id:42}, {_id:11}, {_id:1},
  119. {_id:null}, {_id:NaN}
  120. ],
  121. p = [{$sort:{_id:1}}],
  122. e = [
  123. {_id:null}, {_id:NaN},
  124. {_id:-273.15}, {_id:1}, {_id:3.14159}, {_id:11}, {_id:42}
  125. ],
  126. aggregater = aggregate(p),
  127. a = aggregater(i);
  128. assert.equal(JSON.stringify(a), JSON.stringify(e), "Unexpected value!");
  129. //assert.deepEqual(a, e); //does not work with NaN
  130. assert.equal(JSON.stringify(aggregater(i)), JSON.stringify(e), "Reuse of aggregater should yield the same results!");
  131. assert.equal(JSON.stringify(aggregate(p, i)), JSON.stringify(e), "Alternate use of aggregate should yield the same results!");
  132. },
  133. "should be able to construct an instance with $group operators properly": function(){
  134. var i = [
  135. {_id:0, a:1},
  136. {_id:0, a:2},
  137. {_id:0, a:3},
  138. {_id:0, a:4},
  139. {_id:0, a:1.5},
  140. {_id:0, a:null},
  141. {_id:1, b:"a"},
  142. {_id:1, b:"b"},
  143. {_id:1, b:"b"},
  144. {_id:1, b:"c"}
  145. ],
  146. p = [{$group:{
  147. _id:"$_id",
  148. sum_a:{$sum:"$a"},
  149. //min_a:{$min:"$a"}, //this is busted in this version of mongo
  150. max_a:{$max:"$a"},
  151. avg_a:{$avg:"$a"},
  152. first_b:{$first:"$b"},
  153. last_b:{$last:"$b"},
  154. addToSet_b:{$addToSet:"$b"},
  155. push_b:{$push:"$b"}
  156. }}],
  157. e = [
  158. {
  159. _id:0,
  160. sum_a:11.5,
  161. //min_a:1,
  162. max_a:4,
  163. avg_a:2.3,
  164. first_b:undefined,
  165. last_b:undefined,
  166. addToSet_b:[],
  167. push_b:[]
  168. },
  169. {
  170. _id:1,
  171. sum_a:0,
  172. //min_a:null,
  173. max_a:undefined,
  174. avg_a:0,
  175. first_b:"a",
  176. last_b:"c",
  177. addToSet_b:["a", "b", "c"],
  178. push_b:["a", "b", "b", "c"]
  179. }
  180. ],
  181. aggregater = aggregate(p),
  182. a = aggregater(i);
  183. assert.equal(JSON.stringify(a), JSON.stringify(e), "Unexpected value!");
  184. //assert.deepEqual(a, e); //does not work with NaN
  185. assert.equal(JSON.stringify(aggregater(i)), JSON.stringify(e), "Reuse of aggregater should yield the same results!");
  186. assert.equal(JSON.stringify(aggregate(p, i)), JSON.stringify(e), "Alternate use of aggregate should yield the same results!");
  187. }
  188. }
  189. };
  190. if(!module.parent) (new (require("mocha"))()).ui("exports").reporter("spec").addFile(__filename).run();