소스 검색

Fixes #991 Added LastAccumulator and Fixed a bug in FieldPathExpression that caused it to fail when no document was passed

http://source.rd.rcg.local/trac/eagle6/changeset/1307/Eagle6_SVN
Adam Bell 12 년 전
부모
커밋
3e21a22b78
3개의 변경된 파일102개의 추가작업 그리고 1개의 파일을 삭제
  1. 22 0
      lib/pipeline/accumulators/LastAccumulator.js
  2. 1 1
      lib/pipeline/expressions/FieldPathExpression.js
  3. 79 0
      test/lib/pipeline/accumulators/LastAccumulator.js

+ 22 - 0
lib/pipeline/accumulators/LastAccumulator.js

@@ -0,0 +1,22 @@
+var LastAccumulator = module.exports = (function(){
+
+	// Constructor
+	var klass = module.exports = function LastAccumulator(){
+		base.call(this);
+	}, SingleValueAccumulator = require("./SingleValueAccumulator"), base = SingleValueAccumulator, proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
+
+	proto.evaluate = function evaluate(doc){
+		if(this.operands.length != 1) throw new Error("this should never happen");
+		this.value = this.operands[0].evaluate(doc);
+	};
+
+
+	proto.getOpName = function getOpName(){
+		return "$last";
+	};
+
+	return klass;
+
+})();
+
+

+ 1 - 1
lib/pipeline/expressions/FieldPathExpression.js

@@ -34,7 +34,7 @@ var FieldPathExpression = module.exports = (function(){
 	**/
 	proto._evaluatePath = function _evaluatePath(obj, i, len){
 		var fieldName = this.path.fields[i],
-			field = obj[fieldName];
+			field = obj ? obj[fieldName] : undefined; // It is possible we won't have an obj (document) and we need to not fail if that is the case
 
 		// if the field doesn't exist, quit with an undefined value
 		if (field === undefined) return undefined;

+ 79 - 0
test/lib/pipeline/accumulators/LastAccumulator.js

@@ -0,0 +1,79 @@
+var assert = require("assert"),
+	LastAccumulator = require("../../../../lib/pipeline/accumulators/LastAccumulator"),
+	FieldPathExpression = require("../../../../lib/pipeline/expressions/FieldPathExpression");
+
+
+function createAccumulator(){
+	var lastAccumulator = new LastAccumulator();
+	lastAccumulator.addOperand(new FieldPathExpression("b") );
+	return lastAccumulator;
+}
+
+
+module.exports = {
+
+	"LastAccumulator": {
+
+		"constructor()": {
+
+			"should not throw Error when constructing without args": function testConstructor(){
+				assert.doesNotThrow(function(){
+					new LastAccumulator();
+				});
+			}
+
+		},
+
+		"#getOpName()": {
+
+			"should return the correct op name; $mod": function testOpName(){
+				assert.strictEqual(new LastAccumulator().getOpName(), "$last");
+			}
+
+		},
+
+		"#evaluate()": {
+
+			"should evaluate no documents": function testStuff(){
+				var lastAccumulator = createAccumulator();
+				lastAccumulator.evaluate();
+				assert.strictEqual(lastAccumulator.getValue(), undefined);
+			},
+
+
+			"should evaluate one document and retains its value": function testStuff(){
+				var lastAccumulator = createAccumulator();
+				lastAccumulator.evaluate({b:5});
+				assert.strictEqual(lastAccumulator.getValue(), 5);
+
+			},
+
+
+			"should evaluate one document with the field missing retains undefined": function testStuff(){
+				var lastAccumulator = createAccumulator();
+				lastAccumulator.evaluate({});
+				assert.strictEqual(lastAccumulator.getValue(), undefined);
+			},
+
+
+			"should evaluate two documents and retains the value in the last": function testStuff(){
+				var lastAccumulator = createAccumulator();
+				lastAccumulator.evaluate({b:5});
+				lastAccumulator.evaluate({b:7});
+				assert.strictEqual(lastAccumulator.getValue(), 7);
+			},
+
+
+			"should evaluate two documents and retains the undefined value in the last": function testStuff(){
+				var lastAccumulator = createAccumulator();
+				lastAccumulator.evaluate({b:5});
+				lastAccumulator.evaluate({});
+				assert.strictEqual(lastAccumulator.getValue(), undefined);
+			}
+		}
+
+	}
+
+};
+
+if (!module.parent)(new(require("mocha"))()).ui("exports").reporter("spec").addFile(__filename).run(process.exit);