SortDocumentSource.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. var assert = require("assert"),
  2. SortDocumentSource = require("../../../../lib/pipeline/documentSources/SortDocumentSource"),
  3. CursorDocumentSource = require("../../../../lib/pipeline/documentSources/CursorDocumentSource"),
  4. Cursor = require("../../../../lib/Cursor"),
  5. FieldPathExpression = require("../../../../lib/pipeline/expressions/FieldPathExpression");
  6. module.exports = {
  7. "SortDocumentSource": {
  8. "constructor()": {
  9. "should not throw Error when constructing without args": function testConstructor(){
  10. assert.doesNotThrow(function(){
  11. new SortDocumentSource();
  12. });
  13. }
  14. },
  15. "#getSourceName()": {
  16. "should return the correct source name; $sort": function testSourceName(){
  17. var sds = new SortDocumentSource();
  18. assert.strictEqual(sds.getSourceName(), "$sort");
  19. }
  20. },
  21. "#getFactory()": {
  22. "should return the constructor for this class": function factoryIsConstructor(){
  23. assert.strictEqual(new SortDocumentSource().getFactory(), SortDocumentSource);
  24. }
  25. },
  26. "#eof()": {
  27. "should return true if there are no more sources": function noSources(){
  28. var sds = new SortDocumentSource();
  29. sds.pSource = {
  30. eof: function(){
  31. return true;
  32. }
  33. };
  34. assert.equal(sds.eof(), true);
  35. },
  36. "should return false if there are more documents": function hitSort(){
  37. var cwc = new CursorDocumentSource.CursorWithContext();
  38. cwc._cursor = new Cursor( [{a: 1}] );
  39. var cds = new CursorDocumentSource(cwc);
  40. var sds = new SortDocumentSource();
  41. sds.setSource(cds);
  42. assert.equal(sds.eof(), false);
  43. }
  44. },
  45. "#getCurrent()": {
  46. "should return the current document source": function currSource(){
  47. var cwc = new CursorDocumentSource.CursorWithContext();
  48. cwc._cursor = new Cursor( [{a: 1}] );
  49. var cds = new CursorDocumentSource(cwc);
  50. var sds = new SortDocumentSource();
  51. sds.setSource(cds);
  52. assert.deepEqual(sds.getCurrent(), { a:1 });
  53. }
  54. },
  55. "#advance()": {
  56. "should return true for moving to the next source": function nextSource(){
  57. var cwc = new CursorDocumentSource.CursorWithContext();
  58. cwc._cursor = new Cursor( [{a: 1}, {b:2}] );
  59. var cds = new CursorDocumentSource(cwc);
  60. var sds = new SortDocumentSource();
  61. sds.setSource(cds);
  62. assert.strictEqual(sds.advance(), true);
  63. },
  64. "should return false for no sources remaining": function noMoar(){
  65. var cwc = new CursorDocumentSource.CursorWithContext();
  66. cwc._cursor = new Cursor( [{a: 1}, {b:2}] );
  67. var cds = new CursorDocumentSource(cwc);
  68. var sds = new SortDocumentSource();
  69. sds.setSource(cds);
  70. sds.advance();
  71. assert.strictEqual(sds.advance(), false);
  72. }
  73. },
  74. "#sourceToJson()": {
  75. "should create an object representation of the SortDocumentSource": function sourceToJsonTest(){
  76. var sds = new SortDocumentSource();
  77. sds.vSortKey.push(new FieldPathExpression("b") );
  78. var t = {};
  79. sds.sourceToJson(t, false);
  80. assert.deepEqual(t, { "$sort": { "b": -1 } });
  81. }
  82. },
  83. "#createFromJson()": {
  84. "should return a new SortDocumentSource object from an input JSON object": function createTest(){
  85. var sds = SortDocumentSource.createFromJson({a:1});
  86. assert.strictEqual(sds.constructor, SortDocumentSource);
  87. var t = {};
  88. sds.sourceToJson(t, false);
  89. assert.deepEqual(t, { "$sort": { "a": 1 } });
  90. },
  91. "should return a new SortDocumentSource object from an input JSON object with a descending field": function createTest(){
  92. var sds = SortDocumentSource.createFromJson({a:-1});
  93. assert.strictEqual(sds.constructor, SortDocumentSource);
  94. var t = {};
  95. sds.sourceToJson(t, false);
  96. assert.deepEqual(t, { "$sort": { "a": -1 } });
  97. },
  98. "should return a new SortDocumentSource object from an input JSON object with dotted paths": function createTest(){
  99. var sds = SortDocumentSource.createFromJson({ "a.b":1 });
  100. assert.strictEqual(sds.constructor, SortDocumentSource);
  101. var t = {};
  102. sds.sourceToJson(t, false);
  103. assert.deepEqual(t, { "$sort": { "a.b" : 1 } });
  104. },
  105. "should throw an exception when not passed an object": function createTest(){
  106. assert.throws(function() {
  107. var sds = SortDocumentSource.createFromJson(7);
  108. });
  109. },
  110. "should throw an exception when passed an empty object": function createTest(){
  111. assert.throws(function() {
  112. var sds = SortDocumentSource.createFromJson({});
  113. });
  114. },
  115. "should throw an exception when passed an object with a non number value": function createTest(){
  116. assert.throws(function() {
  117. var sds = SortDocumentSource.createFromJson({a:"b"});
  118. });
  119. },
  120. "should throw an exception when passed an object with a non valid number value": function createTest(){
  121. assert.throws(function() {
  122. var sds = SortDocumentSource.createFromJson({a:14});
  123. });
  124. }
  125. },
  126. "#sort": {
  127. "should sort a single document": function singleValue() {
  128. var cwc = new CursorDocumentSource.CursorWithContext();
  129. cwc._cursor = new Cursor( [{_id:0, a: 1}] );
  130. var cds = new CursorDocumentSource(cwc);
  131. var sds = new SortDocumentSource();
  132. sds.addKey("_id", false);
  133. sds.setSource(cds);
  134. assert.deepEqual(sds.getCurrent(), {_id:0, a:1});
  135. },
  136. "should sort two documents": function twoValue() {
  137. var cwc = new CursorDocumentSource.CursorWithContext();
  138. var l = [{_id:0, a: 1}, {_id:1, a:0}];
  139. cwc._cursor = new Cursor( l );
  140. var cds = new CursorDocumentSource(cwc);
  141. var sds = new SortDocumentSource();
  142. sds.addKey("_id", false);
  143. sds.setSource(cds);
  144. var c = [];
  145. while (!sds.eof()) {
  146. c.push(sds.getCurrent());
  147. sds.advance();
  148. }
  149. assert.deepEqual(c, [{_id:1, a: 0}, {_id:0, a:1}]);
  150. },
  151. "should sort two documents in ascending order": function ascendingValue() {
  152. var cwc = new CursorDocumentSource.CursorWithContext();
  153. var l = [{_id:0, a: 1}, {_id:5, a:12}, {_id:1, a:0}];
  154. cwc._cursor = new Cursor( l );
  155. var cds = new CursorDocumentSource(cwc);
  156. var sds = new SortDocumentSource();
  157. sds.addKey("_id", true);
  158. sds.setSource(cds);
  159. var c = [];
  160. while (!sds.eof()) {
  161. c.push(sds.getCurrent());
  162. sds.advance();
  163. }
  164. assert.deepEqual(c, [{_id:0, a: 1}, {_id:1, a:0}, {_id:5, a:12}]);
  165. },
  166. "should sort documents with a compound key": function compoundKeySort() {
  167. var cwc = new CursorDocumentSource.CursorWithContext();
  168. var l = [{_id:0, a: 1, b:3}, {_id:5, a:12, b:7}, {_id:1, a:0, b:2}];
  169. cwc._cursor = new Cursor( l );
  170. var cds = new CursorDocumentSource(cwc);
  171. var sds = new SortDocumentSource();
  172. sds.addKey("a", false);
  173. sds.addKey("b", false);
  174. sds.setSource(cds);
  175. var c = [];
  176. while (!sds.eof()) {
  177. c.push(sds.getCurrent());
  178. sds.advance();
  179. }
  180. assert.deepEqual(c, [{_id:5, a:12, b:7}, {_id:0, a:1, b:3}, {_id:1, a:0, b:2}]);
  181. },
  182. "should sort documents with a compound key in ascending order": function compoundAscendingKeySort() {
  183. var cwc = new CursorDocumentSource.CursorWithContext();
  184. var l = [{_id:0, a: 1, b:3}, {_id:5, a:12, b:7}, {_id:1, a:0, b:2}];
  185. cwc._cursor = new Cursor( l );
  186. var cds = new CursorDocumentSource(cwc);
  187. var sds = new SortDocumentSource();
  188. sds.addKey("a", true);
  189. sds.addKey("b", true);
  190. sds.setSource(cds);
  191. var c = [];
  192. while (!sds.eof()) {
  193. c.push(sds.getCurrent());
  194. sds.advance();
  195. }
  196. assert.deepEqual(c, [{_id:1, a:0, b:2}, {_id:0, a:1, b:3}, {_id:5, a:12, b:7}]);
  197. },
  198. "should sort documents with a compound key in mixed order": function compoundMixedKeySort() {
  199. var cwc = new CursorDocumentSource.CursorWithContext();
  200. var l = [{_id:0, a: 1, b:3}, {_id:5, a:12, b:7}, {_id:1, a:0, b:2}, {_id:8, a:7, b:42}];
  201. cwc._cursor = new Cursor( l );
  202. var cds = new CursorDocumentSource(cwc);
  203. var sds = new SortDocumentSource();
  204. sds.addKey("a", true);
  205. sds.addKey("b", false);
  206. sds.setSource(cds);
  207. var c = [];
  208. while (!sds.eof()) {
  209. c.push(sds.getCurrent());
  210. sds.advance();
  211. }
  212. assert.deepEqual(c, [{_id:1, a:0, b:2}, {_id:0, a:1, b:3}, {_id:8, a:7, b:42}, {_id:5, a:12, b:7}]);
  213. },
  214. "should not sort different types": function diffTypesSort() {
  215. var cwc = new CursorDocumentSource.CursorWithContext();
  216. var l = [{_id:0, a: 1}, {_id:1, a:"foo"}];
  217. cwc._cursor = new Cursor( l );
  218. var cds = new CursorDocumentSource(cwc);
  219. var sds = new SortDocumentSource();
  220. sds.addKey("a", false);
  221. assert.throws(sds.setSource(cds));
  222. },
  223. "should sort docs with missing fields": function missingFields() {
  224. var cwc = new CursorDocumentSource.CursorWithContext();
  225. var l = [{_id:0, a: 1}, {_id:1}];
  226. cwc._cursor = new Cursor( l );
  227. var cds = new CursorDocumentSource(cwc);
  228. var sds = new SortDocumentSource();
  229. sds.addKey("a", true);
  230. sds.setSource(cds);
  231. var c = [];
  232. while (!sds.eof()) {
  233. c.push(sds.getCurrent());
  234. sds.advance();
  235. }
  236. assert.deepEqual(c, [{_id:1}, {_id:0, a:1}]);
  237. },
  238. "should sort docs with null fields": function nullFields() {
  239. var cwc = new CursorDocumentSource.CursorWithContext();
  240. var l = [{_id:0, a: 1}, {_id:1, a: null}];
  241. cwc._cursor = new Cursor( l );
  242. var cds = new CursorDocumentSource(cwc);
  243. var sds = new SortDocumentSource();
  244. sds.addKey("a", true);
  245. sds.setSource(cds);
  246. var c = [];
  247. while (!sds.eof()) {
  248. c.push(sds.getCurrent());
  249. sds.advance();
  250. }
  251. assert.deepEqual(c, [{_id:1, a:null}, {_id:0, a:1}]);
  252. },
  253. "should not support a missing object nested in an array": function missingObjectWithinArray() {
  254. var cwc = new CursorDocumentSource.CursorWithContext();
  255. var l = [{_id:0, a: [1]}, {_id:1, a:[0]}];
  256. cwc._cursor = new Cursor( l );
  257. var cds = new CursorDocumentSource(cwc);
  258. var sds = new SortDocumentSource();
  259. assert.throws(function() {
  260. sds.addKey("a.b", false);
  261. sds.setSource(cds);
  262. var c = [];
  263. while (!sds.eof()) {
  264. c.push(sds.getCurrent());
  265. sds.advance();
  266. }
  267. });
  268. },
  269. "should compare nested values from within an array": function extractArrayValues() {
  270. var cwc = new CursorDocumentSource.CursorWithContext();
  271. var l = [{_id:0,a:[{b:1},{b:2}]}, {_id:1,a:[{b:1},{b:1}]} ];
  272. cwc._cursor = new Cursor( l );
  273. var cds = new CursorDocumentSource(cwc);
  274. var sds = new SortDocumentSource();
  275. sds.addKey("a.b", true);
  276. sds.setSource(cds);
  277. var c = [];
  278. while (!sds.eof()) {
  279. c.push(sds.getCurrent());
  280. sds.advance();
  281. }
  282. assert.deepEqual(c, [{_id:1,a:[{b:1},{b:1}]},{_id:0,a:[{b:1},{b:2}]}]);
  283. }
  284. },
  285. "#dependencies": {
  286. "should have Dependant field paths": function dependencies() {
  287. var sds = new SortDocumentSource();
  288. sds.addKey("a", true);
  289. sds.addKey("b.c", false);
  290. var deps = [];
  291. assert.equal("SEE_NEXT", sds.getDependencies(deps));
  292. assert.equal(2, deps.length);
  293. assert.equal(1, deps.filter(function(val) { return "a" == val; }).length);
  294. assert.equal(1, deps.filter(function(val) { return "a" == val; }).length);
  295. }
  296. }
  297. }
  298. };
  299. if (!module.parent)(new(require("mocha"))()).ui("exports").reporter("spec").addFile(__filename).run(process.exit);