|
|
@@ -5,9 +5,65 @@ var assert = require("assert"),
|
|
|
SortDocumentSource = require("../../../../lib/pipeline/documentSources/SortDocumentSource"),
|
|
|
LimitDocumentSource = require("../../../../lib/pipeline/documentSources/LimitDocumentSource"),
|
|
|
CursorDocumentSource = require("../../../../lib/pipeline/documentSources/CursorDocumentSource"),
|
|
|
- Cursor = require("../../../../lib/Cursor"),
|
|
|
+ ArrayRunner = require("../../../../lib/query/ArrayRunner"),
|
|
|
FieldPathExpression = require("../../../../lib/pipeline/expressions/FieldPathExpression");
|
|
|
|
|
|
+var getCursorDocumentSource = function(values) {
|
|
|
+ return new CursorDocumentSource(null, new ArrayRunner(values), null);
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
+/// An assertion for `ObjectExpression` instances based on Mongo's `ExpectedResultBase` class
|
|
|
+function assertExpectedResult(args) {
|
|
|
+ {// check for required args
|
|
|
+ if (args === undefined) throw new TypeError("missing arg: `args` is required");
|
|
|
+ if (args.spec && args.throw === undefined) args.throw = true; // Assume that spec only tests expect an error to be thrown
|
|
|
+ //if (args.spec === undefined) throw new Error("missing arg: `args.spec` is required");
|
|
|
+ if (args.expected !== undefined && args.docs === undefined) throw new Error("must provide docs with expected value");
|
|
|
+ }// check for required args
|
|
|
+
|
|
|
+ // run implementation
|
|
|
+ if(args.expected && args.docs){
|
|
|
+ var sds = SortDocumentSource.createFromJson(args.spec),
|
|
|
+ next,
|
|
|
+ results = [],
|
|
|
+ cds = new CursorDocumentSource(null, new ArrayRunner(args.docs), null);
|
|
|
+ sds.setSource(cds);
|
|
|
+ async.whilst(
|
|
|
+ function() {
|
|
|
+ return next !== null;
|
|
|
+ },
|
|
|
+ function(done) {
|
|
|
+ sds.getNext(function(err, doc) {
|
|
|
+ if(err) return done(err);
|
|
|
+ next = doc;
|
|
|
+ if(next === null) {
|
|
|
+ return done();
|
|
|
+ } else {
|
|
|
+ results.push(next);
|
|
|
+ return done();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ function(err) {
|
|
|
+ assert.equal(JSON.stringify(results), JSON.stringify(args.expected));
|
|
|
+ if(args.done) {
|
|
|
+ return args.done();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ );
|
|
|
+ }else{
|
|
|
+ if(args.throw) {
|
|
|
+ assert.throws(function(){
|
|
|
+ SortDocumentSource.createFromJson(args.spec);
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ assert.doesNotThrow(function(){
|
|
|
+ var gds = SortDocumentSource.createFromJson(args.spec);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
module.exports = {
|
|
|
|
|
|
@@ -15,11 +71,28 @@ module.exports = {
|
|
|
|
|
|
"constructor()": {
|
|
|
|
|
|
- "should not throw Error when constructing without args": function testConstructor(){
|
|
|
- assert.doesNotThrow(function(){
|
|
|
- new SortDocumentSource();
|
|
|
+ // $sort spec is not an object
|
|
|
+ "should throw Error when constructing without args": function testConstructor(){
|
|
|
+ assertExpectedResult({"throw":true});
|
|
|
+ },
|
|
|
+
|
|
|
+ // $sort spec is not an object
|
|
|
+ "should throw Error when $sort spec is not an object": function testConstructor(){
|
|
|
+ assertExpectedResult({spec:"Foo"});
|
|
|
+ },
|
|
|
+
|
|
|
+ // $sort spec is an empty object
|
|
|
+ "should throw Error when $sort spec is an empty object": function testConstructor(){
|
|
|
+ assertExpectedResult({spec:{}});
|
|
|
+ },
|
|
|
+
|
|
|
+
|
|
|
+ // $sort _id is specified as an invalid object expression
|
|
|
+ "should throw error when _id is an invalid object expression": function testConstructor(){
|
|
|
+ assertExpectedResult({
|
|
|
+ spec:{_id:{$add:1, $and:1}},
|
|
|
});
|
|
|
- }
|
|
|
+ },
|
|
|
|
|
|
},
|
|
|
|
|
|
@@ -41,71 +114,82 @@ module.exports = {
|
|
|
},
|
|
|
|
|
|
"#getNext()": {
|
|
|
-
|
|
|
+ /** Assert that iterator state accessors consistently report the source is exhausted. */
|
|
|
"should return EOF if there are no more sources": function noSources(next){
|
|
|
- var cwc = new CursorDocumentSource.CursorWithContext();
|
|
|
- cwc._cursor = new Cursor( [{a: 1}] );
|
|
|
- var cds = new CursorDocumentSource(cwc);
|
|
|
- var sds = SortDocumentSource.createFromJson({a:1});
|
|
|
+ var cds = getCursorDocumentSource([{"a": 1}]);
|
|
|
+ var sds = SortDocumentSource.createFromJson({"sort":1});
|
|
|
sds.setSource(cds);
|
|
|
sds.getNext(function(err, val) {
|
|
|
assert.deepEqual(val, {a:1});
|
|
|
sds.getNext(function(err, val) {
|
|
|
- assert.equal(val, DocumentSource.EOF);
|
|
|
- next();
|
|
|
+ if (err) throw err;
|
|
|
+ assert.equal(val, null);
|
|
|
+ return next();
|
|
|
});
|
|
|
});
|
|
|
+
|
|
|
},
|
|
|
- "should return EOF if there are more documents": function hitSort(next){
|
|
|
- var cwc = new CursorDocumentSource.CursorWithContext();
|
|
|
- cwc._cursor = new Cursor( [{a: 1}] );
|
|
|
- var cds = new CursorDocumentSource(cwc);
|
|
|
- var sds = SortDocumentSource.createFromJson({a:1});
|
|
|
+
|
|
|
+ "should not return EOF if there are documents": function hitSort(next){
|
|
|
+ var cds = getCursorDocumentSource([{a: 1}]);
|
|
|
+ var sds = SortDocumentSource.createFromJson({"sort":1});
|
|
|
sds.setSource(cds);
|
|
|
- sds.getNext(function(err, doc) {
|
|
|
- assert.notEqual(doc, DocumentSource.EOF);
|
|
|
- next();
|
|
|
- });
|
|
|
+ async.series([
|
|
|
+ cds.getNext.bind(cds),
|
|
|
+ ],
|
|
|
+ function(err,res) {
|
|
|
+ if (err) throw err;
|
|
|
+ assert.notEqual(res, null);
|
|
|
+ return next();
|
|
|
+ }
|
|
|
+ );
|
|
|
},
|
|
|
|
|
|
"should return the current document source": function currSource(next){
|
|
|
- var cwc = new CursorDocumentSource.CursorWithContext();
|
|
|
- cwc._cursor = new Cursor( [{a: 1}] );
|
|
|
- var cds = new CursorDocumentSource(cwc);
|
|
|
- var sds = SortDocumentSource.createFromJson({a:1});
|
|
|
+ var cds = getCursorDocumentSource([{a: 1}]);
|
|
|
+ var sds = SortDocumentSource.createFromJson({"sort":1});
|
|
|
sds.setSource(cds);
|
|
|
- sds.getNext(function(err, doc) {
|
|
|
- assert.deepEqual(doc, { a:1 });
|
|
|
- next();
|
|
|
- });
|
|
|
+ async.series([
|
|
|
+ cds.getNext.bind(cds),
|
|
|
+ ],
|
|
|
+ function(err,res) {
|
|
|
+ if (err) throw err;
|
|
|
+ assert.deepEqual(res, [ { a: 1 } ]);
|
|
|
+ return next();
|
|
|
+ }
|
|
|
+ );
|
|
|
},
|
|
|
|
|
|
- "should return next document when moving to the next source": function nextSource(next){
|
|
|
- var cwc = new CursorDocumentSource.CursorWithContext();
|
|
|
- cwc._cursor = new Cursor( [{a: 1}, {b:2}] );
|
|
|
- var cds = new CursorDocumentSource(cwc);
|
|
|
- var sds = SortDocumentSource.createFromJson({a:1});
|
|
|
+ "should return next document when moving to the next source sorted descending": function nextSource(next){
|
|
|
+ var cds = getCursorDocumentSource([{a: 1}, {b:2}]);
|
|
|
+ var sds = SortDocumentSource.createFromJson({"sort":1});
|
|
|
sds.setSource(cds);
|
|
|
- sds.getNext(function(err, doc) {
|
|
|
- assert.deepEqual(doc, {b:2});
|
|
|
- next();
|
|
|
- });
|
|
|
+ async.series([
|
|
|
+ cds.getNext.bind(cds),
|
|
|
+ ],
|
|
|
+ function(err,res) {
|
|
|
+ if (err) throw err;
|
|
|
+ assert.deepEqual(res, [ { a: 1 } ]);
|
|
|
+ return next();
|
|
|
+ }
|
|
|
+ );
|
|
|
},
|
|
|
|
|
|
- "should return false for no sources remaining": function noMoar(next){
|
|
|
- var cwc = new CursorDocumentSource.CursorWithContext();
|
|
|
- cwc._cursor = new Cursor( [{a: 1}, {b:2}] );
|
|
|
- var cds = new CursorDocumentSource(cwc);
|
|
|
- var sds = SortDocumentSource.createFromJson({a:1});
|
|
|
+ "should return false for no sources remaining sorted descending": function noMoar(next){
|
|
|
+ var cds = getCursorDocumentSource([{a: 1}, {b:2}]);
|
|
|
+ var sds = SortDocumentSource.createFromJson({"sort":1});
|
|
|
sds.setSource(cds);
|
|
|
- sds.getNext(function(err, doc) {
|
|
|
- sds.getNext(function(err, doc) {
|
|
|
- assert.deepEqual(doc, {a:1});
|
|
|
- next();
|
|
|
- });
|
|
|
- });
|
|
|
+ async.series([
|
|
|
+ cds.getNext.bind(cds),
|
|
|
+ cds.getNext.bind(cds),
|
|
|
+ ],
|
|
|
+ function(err,res) {
|
|
|
+ if (err) throw err;
|
|
|
+ assert.deepEqual(res, [ { a: 1 }, { b: 2 } ]);
|
|
|
+ return next();
|
|
|
+ }
|
|
|
+ );
|
|
|
}
|
|
|
-
|
|
|
},
|
|
|
|
|
|
"#serialize()": {
|
|
|
@@ -114,93 +198,108 @@ module.exports = {
|
|
|
var sds = new SortDocumentSource();
|
|
|
assert.throws(sds.serialize.bind(sds));
|
|
|
}
|
|
|
-
|
|
|
},
|
|
|
|
|
|
"#serializeToArray()": {
|
|
|
|
|
|
- "should create an object representation of the SortDocumentSource": function serializeToArrayTest(){
|
|
|
+ /**
|
|
|
+ * Check that the BSON representation generated by the souce matches the BSON it was
|
|
|
+ * created with.
|
|
|
+ */
|
|
|
+ "should have equal json representation": function serializeToArrayCheck(next){
|
|
|
+ var sds = SortDocumentSource.createFromJson({"sort":1}, {});
|
|
|
+ var array = [];
|
|
|
+ sds.serializeToArray(array, false);
|
|
|
+ assert.deepEqual(array, [{"$sort":{"sort":1}}]);
|
|
|
+ return next();
|
|
|
+ },
|
|
|
+
|
|
|
+ "should create an object representation of the SortDocumentSource": function serializeToArrayTest(next){
|
|
|
var sds = new SortDocumentSource();
|
|
|
- sds.vSortKey.push(new FieldPathExpression("b") );
|
|
|
- var t = [];
|
|
|
- sds.serializeToArray(t, false);
|
|
|
- assert.deepEqual(t, [{ "$sort": { "b": -1 } }]);
|
|
|
+ var fieldPathVar;
|
|
|
+ sds.vSortKey.push(new FieldPathExpression("b", fieldPathVar) );
|
|
|
+ var array = [];
|
|
|
+ sds.serializeToArray(array, false);
|
|
|
+ assert.deepEqual(array, [{"$sort":{"":-1}}] );
|
|
|
+ return next();
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
"#createFromJson()": {
|
|
|
|
|
|
- "should return a new SortDocumentSource object from an input JSON object": function createTest(){
|
|
|
+ "should return a new SortDocumentSource object from an input JSON object": function createTest(next){
|
|
|
var sds = SortDocumentSource.createFromJson({a:1});
|
|
|
assert.strictEqual(sds.constructor, SortDocumentSource);
|
|
|
var t = [];
|
|
|
sds.serializeToArray(t, false);
|
|
|
- assert.deepEqual(t, [{ "$sort": { "a": 1 } }]);
|
|
|
+ assert.deepEqual(t, [{"$sort":{"a":1}}] );
|
|
|
+ return next();
|
|
|
},
|
|
|
|
|
|
- "should return a new SortDocumentSource object from an input JSON object with a descending field": function createTest(){
|
|
|
+ "should return a new SortDocumentSource object from an input JSON object with a descending field": function createTest(next){
|
|
|
var sds = SortDocumentSource.createFromJson({a:-1});
|
|
|
assert.strictEqual(sds.constructor, SortDocumentSource);
|
|
|
var t = [];
|
|
|
sds.serializeToArray(t, false);
|
|
|
- assert.deepEqual(t, [{ "$sort": { "a": -1 } }]);
|
|
|
+ assert.deepEqual(t, [{"$sort":{"a":-1}}]);
|
|
|
+ return next();
|
|
|
},
|
|
|
|
|
|
- "should return a new SortDocumentSource object from an input JSON object with dotted paths": function createTest(){
|
|
|
+ "should return a new SortDocumentSource object from an input JSON object with dotted paths": function createTest(next){
|
|
|
var sds = SortDocumentSource.createFromJson({ "a.b":1 });
|
|
|
assert.strictEqual(sds.constructor, SortDocumentSource);
|
|
|
var t = [];
|
|
|
sds.serializeToArray(t, false);
|
|
|
- assert.deepEqual(t, [{ "$sort": { "a.b" : 1 } }]);
|
|
|
+ assert.deepEqual(t, [{"$sort":{"a.b":1}}]);
|
|
|
+ return next();
|
|
|
},
|
|
|
|
|
|
- "should throw an exception when not passed an object": function createTest(){
|
|
|
+ "should throw an exception when not passed an object": function createTest(next){
|
|
|
assert.throws(function() {
|
|
|
var sds = SortDocumentSource.createFromJson(7);
|
|
|
});
|
|
|
+ return next();
|
|
|
},
|
|
|
|
|
|
- "should throw an exception when passed an empty object": function createTest(){
|
|
|
+ "should throw an exception when passed an empty object": function createTest(next){
|
|
|
assert.throws(function() {
|
|
|
var sds = SortDocumentSource.createFromJson({});
|
|
|
});
|
|
|
+ return next();
|
|
|
},
|
|
|
|
|
|
- "should throw an exception when passed an object with a non number value": function createTest(){
|
|
|
+ "should throw an exception when passed an object with a non number value": function createTest(next){
|
|
|
assert.throws(function() {
|
|
|
var sds = SortDocumentSource.createFromJson({a:"b"});
|
|
|
});
|
|
|
+ return next();
|
|
|
},
|
|
|
|
|
|
- "should throw an exception when passed an object with a non valid number value": function createTest(){
|
|
|
+ "should throw an exception when passed an object with a non valid number value": function createTest(next){
|
|
|
assert.throws(function() {
|
|
|
var sds = SortDocumentSource.createFromJson({a:14});
|
|
|
});
|
|
|
+ next();
|
|
|
}
|
|
|
-
|
|
|
},
|
|
|
|
|
|
"#sort": {
|
|
|
|
|
|
"should sort a single document": function singleValue(next) {
|
|
|
- var cwc = new CursorDocumentSource.CursorWithContext();
|
|
|
- cwc._cursor = new Cursor( [{_id:0, a: 1}] );
|
|
|
- var cds = new CursorDocumentSource(cwc);
|
|
|
+ var cds = getCursorDocumentSource([{_id:0, a: 1}]);
|
|
|
var sds = new SortDocumentSource();
|
|
|
sds.addKey("_id", false);
|
|
|
sds.setSource(cds);
|
|
|
sds.getNext(function(err, actual) {
|
|
|
+ if (err) throw err;
|
|
|
assert.deepEqual(actual, {_id:0, a:1});
|
|
|
- next();
|
|
|
+ return next();
|
|
|
});
|
|
|
},
|
|
|
|
|
|
"should sort two documents": function twoValue(next) {
|
|
|
- var cwc = new CursorDocumentSource.CursorWithContext();
|
|
|
- var l = [{_id:0, a: 1}, {_id:1, a:0}];
|
|
|
- cwc._cursor = new Cursor( l );
|
|
|
- var cds = new CursorDocumentSource(cwc);
|
|
|
+ var cds = getCursorDocumentSource([{_id:0, a: 1}, {_id:1, a:0}]);
|
|
|
var sds = new SortDocumentSource();
|
|
|
sds.addKey("_id", false);
|
|
|
sds.setSource(cds);
|
|
|
@@ -210,17 +309,15 @@ module.exports = {
|
|
|
sds.getNext.bind(sds),
|
|
|
],
|
|
|
function(err,res) {
|
|
|
- assert.deepEqual([{_id:1, a: 0}, {_id:0, a:1}], res);
|
|
|
- next();
|
|
|
+ if (err) throw err;
|
|
|
+ assert.deepEqual([ { _id: 1, a: 0 }, { _id: 0, a: 1 } ], res);
|
|
|
+ return next();
|
|
|
}
|
|
|
);
|
|
|
},
|
|
|
|
|
|
"should sort two documents in ascending order": function ascendingValue(next) {
|
|
|
- var cwc = new CursorDocumentSource.CursorWithContext();
|
|
|
- var l = [{_id:0, a: 1}, {_id:5, a:12}, {_id:1, a:0}];
|
|
|
- cwc._cursor = new Cursor( l );
|
|
|
- var cds = new CursorDocumentSource(cwc);
|
|
|
+ var cds = getCursorDocumentSource([{_id:0, a: 1}, {_id:5, a:12}, {_id:1, a:0}]);
|
|
|
var sds = new SortDocumentSource();
|
|
|
sds.addKey("_id", true);
|
|
|
sds.setSource(cds);
|
|
|
@@ -234,21 +331,20 @@ module.exports = {
|
|
|
});
|
|
|
},
|
|
|
function() {
|
|
|
- return docs[i++] !== DocumentSource.EOF;
|
|
|
+ return docs[i++] !== null;
|
|
|
},
|
|
|
function(err) {
|
|
|
- assert.deepEqual([{_id:0, a: 1}, {_id:1, a:0}, {_id:5, a:12}, DocumentSource.EOF], docs);
|
|
|
- next();
|
|
|
+ if (err) throw err;
|
|
|
+ assert.deepEqual([{_id:0, a: 1}, {_id:1, a:0}, {_id:5, a:12}, null], docs);
|
|
|
+ return next();
|
|
|
}
|
|
|
);
|
|
|
},
|
|
|
|
|
|
"should sort documents with a compound key": function compoundKeySort(next) {
|
|
|
- var cwc = new CursorDocumentSource.CursorWithContext();
|
|
|
- var l = [{_id:0, a: 1, b:3}, {_id:5, a:12, b:7}, {_id:1, a:0, b:2}];
|
|
|
- cwc._cursor = new Cursor( l );
|
|
|
- var cds = new CursorDocumentSource(cwc);
|
|
|
- var sds = new SortDocumentSource();
|
|
|
+ var cds = getCursorDocumentSource([{_id:0, a: 1, b:3}, {_id:5, a:12, b:7}, {_id:1, a:0, b:2}]);
|
|
|
+ var sds = SortDocumentSource.createFromJson({"sort":1});
|
|
|
+
|
|
|
sds.addKey("a", false);
|
|
|
sds.addKey("b", false);
|
|
|
sds.setSource(cds);
|
|
|
@@ -262,20 +358,18 @@ module.exports = {
|
|
|
});
|
|
|
},
|
|
|
function() {
|
|
|
- return docs[i++] !== DocumentSource.EOF;
|
|
|
+ return docs[i++] !== null;
|
|
|
},
|
|
|
function(err) {
|
|
|
- assert.deepEqual([{_id:5, a:12, b:7}, {_id:0, a:1, b:3}, {_id:1, a:0, b:2}, DocumentSource.EOF], docs);
|
|
|
- next();
|
|
|
+ if (err) throw err;
|
|
|
+ assert.deepEqual([{_id:5, a:12, b:7}, {_id:0, a:1, b:3}, {_id:1, a:0, b:2}, null], docs);
|
|
|
+ return next();
|
|
|
}
|
|
|
);
|
|
|
},
|
|
|
|
|
|
"should sort documents with a compound key in ascending order": function compoundAscendingKeySort(next) {
|
|
|
- var cwc = new CursorDocumentSource.CursorWithContext();
|
|
|
- var l = [{_id:0, a: 1, b:3}, {_id:5, a:12, b:7}, {_id:1, a:0, b:2}];
|
|
|
- cwc._cursor = new Cursor( l );
|
|
|
- var cds = new CursorDocumentSource(cwc);
|
|
|
+ var cds = getCursorDocumentSource([{_id:0, a: 1, b:3}, {_id:5, a:12, b:7}, {_id:1, a:0, b:2}]);
|
|
|
var sds = new SortDocumentSource();
|
|
|
sds.addKey("a", true);
|
|
|
sds.addKey("b", true);
|
|
|
@@ -290,20 +384,18 @@ module.exports = {
|
|
|
});
|
|
|
},
|
|
|
function() {
|
|
|
- return docs[i++] !== DocumentSource.EOF;
|
|
|
+ return docs[i++] !== null;
|
|
|
},
|
|
|
function(err) {
|
|
|
- assert.deepEqual([{_id:1, a:0, b:2}, {_id:0, a:1, b:3}, {_id:5, a:12, b:7}, DocumentSource.EOF], docs);
|
|
|
- next();
|
|
|
+ if (err) throw err;
|
|
|
+ assert.deepEqual([{_id:1, a:0, b:2}, {_id:0, a:1, b:3}, {_id:5, a:12, b:7}, null], docs);
|
|
|
+ return next();
|
|
|
}
|
|
|
);
|
|
|
},
|
|
|
|
|
|
"should sort documents with a compound key in mixed order": function compoundMixedKeySort(next) {
|
|
|
- var cwc = new CursorDocumentSource.CursorWithContext();
|
|
|
- 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}];
|
|
|
- cwc._cursor = new Cursor( l );
|
|
|
- var cds = new CursorDocumentSource(cwc);
|
|
|
+ var cds = getCursorDocumentSource([{_id:0, a: 1, b:3}, {_id:5, a:12, b:7}, {_id:1, a:0, b:2}, {_id:8, a:7, b:42}]);
|
|
|
var sds = new SortDocumentSource();
|
|
|
sds.addKey("a", true);
|
|
|
sds.addKey("b", false);
|
|
|
@@ -318,30 +410,26 @@ module.exports = {
|
|
|
});
|
|
|
},
|
|
|
function() {
|
|
|
- return docs[i++] !== DocumentSource.EOF;
|
|
|
+ return docs[i++] !== null;
|
|
|
},
|
|
|
function(err) {
|
|
|
- assert.deepEqual([{_id:1, a:0, b:2}, {_id:0, a:1, b:3}, {_id:8, a:7, b:42}, {_id:5, a:12, b:7}, DocumentSource.EOF], docs);
|
|
|
- next();
|
|
|
+ if (err) throw err;
|
|
|
+ assert.deepEqual([{_id:1, a:0, b:2}, {_id:0, a:1, b:3}, {_id:8, a:7, b:42}, {_id:5, a:12, b:7}, null], docs);
|
|
|
+ return next();
|
|
|
}
|
|
|
);
|
|
|
},
|
|
|
|
|
|
- "should not sort different types": function diffTypesSort() {
|
|
|
- var cwc = new CursorDocumentSource.CursorWithContext();
|
|
|
- var l = [{_id:0, a: 1}, {_id:1, a:"foo"}];
|
|
|
- cwc._cursor = new Cursor( l );
|
|
|
- var cds = new CursorDocumentSource(cwc);
|
|
|
+ "should not sort different types": function diffTypesSort(next) {
|
|
|
+ var cds = getCursorDocumentSource([{_id:0, a: 1}, {_id:1, a:"foo"}]);
|
|
|
var sds = new SortDocumentSource();
|
|
|
sds.addKey("a", false);
|
|
|
assert.throws(sds.setSource(cds));
|
|
|
+ return next();
|
|
|
},
|
|
|
|
|
|
"should sort docs with missing fields": function missingFields(next) {
|
|
|
- var cwc = new CursorDocumentSource.CursorWithContext();
|
|
|
- var l = [{_id:0, a: 1}, {_id:1}];
|
|
|
- cwc._cursor = new Cursor( l );
|
|
|
- var cds = new CursorDocumentSource(cwc);
|
|
|
+ var cds = getCursorDocumentSource([{_id:0, a: 1}, {_id:1}]);
|
|
|
var sds = new SortDocumentSource();
|
|
|
sds.addKey("a", true);
|
|
|
sds.setSource(cds);
|
|
|
@@ -355,20 +443,18 @@ module.exports = {
|
|
|
});
|
|
|
},
|
|
|
function() {
|
|
|
- return docs[i++] !== DocumentSource.EOF;
|
|
|
+ return docs[i++] !== null;
|
|
|
},
|
|
|
function(err) {
|
|
|
- assert.deepEqual([{_id:1}, {_id:0, a:1}, DocumentSource.EOF], docs);
|
|
|
- next();
|
|
|
+ if (err) throw err;
|
|
|
+ assert.deepEqual([{_id:1}, {_id:0, a:1}, null], docs);
|
|
|
+ return next();
|
|
|
}
|
|
|
);
|
|
|
},
|
|
|
|
|
|
"should sort docs with null fields": function nullFields(next) {
|
|
|
- var cwc = new CursorDocumentSource.CursorWithContext();
|
|
|
- var l = [{_id:0, a: 1}, {_id:1, a: null}];
|
|
|
- cwc._cursor = new Cursor( l );
|
|
|
- var cds = new CursorDocumentSource(cwc);
|
|
|
+ var cds = getCursorDocumentSource([{_id:0, a: 1}, {_id:1, a: null}]);
|
|
|
var sds = new SortDocumentSource();
|
|
|
sds.addKey("a", true);
|
|
|
sds.setSource(cds);
|
|
|
@@ -382,20 +468,18 @@ module.exports = {
|
|
|
});
|
|
|
},
|
|
|
function() {
|
|
|
- return docs[i++] !== DocumentSource.EOF;
|
|
|
+ return docs[i++] !== null;
|
|
|
},
|
|
|
function(err) {
|
|
|
- assert.deepEqual([{_id:1, a:null}, {_id:0, a:1}, DocumentSource.EOF], docs);
|
|
|
- next();
|
|
|
+ if (err) throw err;
|
|
|
+ assert.deepEqual([{_id:1, a:null}, {_id:0, a:1}, null], docs);
|
|
|
+ return next();
|
|
|
}
|
|
|
);
|
|
|
},
|
|
|
|
|
|
- "should not support a missing object nested in an array": function missingObjectWithinArray() {
|
|
|
- var cwc = new CursorDocumentSource.CursorWithContext();
|
|
|
- var l = [{_id:0, a: [1]}, {_id:1, a:[0]}];
|
|
|
- cwc._cursor = new Cursor( l );
|
|
|
- var cds = new CursorDocumentSource(cwc);
|
|
|
+ "should not support a missing object nested in an array": function missingObjectWithinArray(next) {
|
|
|
+ var cds = getCursorDocumentSource([{_id:0, a: [1]}, {_id:1, a:[0]}]);
|
|
|
var sds = new SortDocumentSource();
|
|
|
assert.throws(function() {
|
|
|
sds.addKey("a.b", false);
|
|
|
@@ -406,13 +490,11 @@ module.exports = {
|
|
|
sds.advance();
|
|
|
}
|
|
|
});
|
|
|
+ return next();
|
|
|
},
|
|
|
|
|
|
"should compare nested values from within an array": function extractArrayValues(next) {
|
|
|
- var cwc = new CursorDocumentSource.CursorWithContext();
|
|
|
- var l = [{_id:0,a:[{b:1},{b:2}]}, {_id:1,a:[{b:1},{b:1}]} ];
|
|
|
- cwc._cursor = new Cursor( l );
|
|
|
- var cds = new CursorDocumentSource(cwc);
|
|
|
+ var cds = getCursorDocumentSource([{_id:0,a:[{b:1},{b:2}]}, {_id:1,a:[{b:1},{b:1}]}]);
|
|
|
var sds = new SortDocumentSource();
|
|
|
sds.addKey("a.b", true);
|
|
|
sds.setSource(cds);
|
|
|
@@ -426,33 +508,37 @@ module.exports = {
|
|
|
});
|
|
|
},
|
|
|
function() {
|
|
|
- return docs[i++] !== DocumentSource.EOF;
|
|
|
+ return docs[i++] !== null;
|
|
|
},
|
|
|
function(err) {
|
|
|
- assert.deepEqual([{_id:1,a:[{b:1},{b:1}]},{_id:0,a:[{b:1},{b:2}]}, DocumentSource.EOF], docs);
|
|
|
- next();
|
|
|
+ if (err) throw err;
|
|
|
+ assert.deepEqual([{_id:1,a:[{b:1},{b:1}]},{_id:0,a:[{b:1},{b:2}]}, null], docs);
|
|
|
+ return next();
|
|
|
}
|
|
|
);
|
|
|
}
|
|
|
-
|
|
|
},
|
|
|
|
|
|
"#coalesce()": {
|
|
|
- "should return false when coalescing a non-limit source": function nonLimitSource() {
|
|
|
- var cwc = new CursorDocumentSource.CursorWithContext();
|
|
|
- var l = [{_id:0,a:[{b:1},{b:2}]}, {_id:1,a:[{b:1},{b:1}]} ];
|
|
|
- cwc._cursor = new Cursor( l );
|
|
|
- var cds = new CursorDocumentSource(cwc),
|
|
|
- sds = SortDocumentSource.createFromJson({a:1});
|
|
|
+ "should return false when coalescing a non-limit source": function nonLimitSource(next) {
|
|
|
+ var cds = getCursorDocumentSource([{_id:0,a:[{b:1},{b:2}]}, {_id:1,a:[{b:1},{b:1}]} ]);
|
|
|
+ var sds = SortDocumentSource.createFromJson({a:1});
|
|
|
|
|
|
var newSrc = sds.coalesce(cds);
|
|
|
assert.equal(newSrc, false);
|
|
|
+ return next();
|
|
|
},
|
|
|
|
|
|
- "should return limit source when coalescing a limit source": function limitSource() {
|
|
|
+
|
|
|
+ "should return limit source when coalescing a limit source": function limitSource(next) {
|
|
|
var sds = SortDocumentSource.createFromJson({a:1}),
|
|
|
lds = LimitDocumentSource.createFromJson(1);
|
|
|
|
|
|
+ // TODO: add missing test cases.
|
|
|
+ // array json getLimit
|
|
|
+ // getShardSource
|
|
|
+ // getMergeSource
|
|
|
+
|
|
|
var newSrc = sds.coalesce(LimitDocumentSource.createFromJson(10));
|
|
|
assert.ok(newSrc instanceof LimitDocumentSource);
|
|
|
assert.equal(sds.getLimit(), 10);
|
|
|
@@ -464,24 +550,36 @@ module.exports = {
|
|
|
var arr = [];
|
|
|
sds.serializeToArray(arr);
|
|
|
assert.deepEqual(arr, [{$sort: {a:1}}, {$limit: 5}]);
|
|
|
+
|
|
|
+ // TODO: add missing test cases
|
|
|
+ // doc array get limit
|
|
|
+ // getShardSource
|
|
|
+ // get MergeSource
|
|
|
+ return next();
|
|
|
},
|
|
|
},
|
|
|
|
|
|
"#dependencies": {
|
|
|
- "should have Dependant field paths": function dependencies() {
|
|
|
- var sds = new SortDocumentSource();
|
|
|
- sds.addKey("a", true);
|
|
|
- sds.addKey("b.c", false);
|
|
|
- var deps = {};
|
|
|
- assert.equal("SEE_NEXT", sds.getDependencies(deps));
|
|
|
- assert.equal(2, Object.keys(deps).length);
|
|
|
- assert.ok(deps.a);
|
|
|
- assert.ok(deps["b.c"]);
|
|
|
+ /** Dependant field paths. */
|
|
|
+ "should have Dependant field paths": function dependencies(next) {
|
|
|
+ var sds = SortDocumentSource.createFromJson({sort: 1});
|
|
|
+
|
|
|
+ sds.addKey('a', true);
|
|
|
+ sds.addKey('b.c', false);
|
|
|
+
|
|
|
+ var deps = {fields: {}, needWholeDocument: false, needTextScore: false};
|
|
|
+
|
|
|
+ assert.equal('SEE_NEXT', sds.getDependencies(deps));
|
|
|
+ // Sort keys are now part of deps fields.
|
|
|
+ assert.equal(3, Object.keys(deps.fields).length);
|
|
|
+ assert.equal(1, deps.fields.a);
|
|
|
+ assert.equal(1, deps.fields['b.c']);
|
|
|
+ assert.equal(false, deps.needWholeDocument);
|
|
|
+ assert.equal(false, deps.needTextScore);
|
|
|
+ return next();
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
-
|
|
|
};
|
|
|
|
|
|
if (!module.parent)(new(require("mocha"))()).ui("exports").reporter("spec").addFile(__filename).grep(process.env.MOCHA_GREP || '').run(process.exit);
|