SortDocumentSource.js 11 KB

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