Browse Source

Fixes #990. Finished test cases for FirstAccumulator, added a hack to avoid falsy values not stopping.

http://source.rd.rcg.local/trac/eagle6/changeset/1309/Eagle6_SVN
Spencer Rathbun 12 years ago
parent
commit
580f35d679

+ 11 - 8
lib/pipeline/accumulators/FirstAccumulator.js

@@ -1,12 +1,13 @@
-var Accumulator = module.exports = (function(){
+var FirstAccumulator = module.exports = (function(){
 	// CONSTRUCTOR
 	/** 
-	* A base class for all pipeline accumulators. Uses NaryExpression as a base class.
+	* Constructor for FirstAccumulator, wraps SingleValueAccumulator's constructor and
+	* adds flag to track whether we have started or not
 	*
 	**/
-	var klass = function Accumulator(){
-		if(arguments.length !== 0) throw new Error("zero args expected");
+	var klass = module.exports = function FirstAccumulator(){
 		base.call(this);
+		this.started = 0; //TODO: hack to get around falsy values making us keep going
 	}, base = require("./SingleValueAccumulator"), proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
 
 	// PROTOTYPE MEMBERS
@@ -25,13 +26,15 @@ var Accumulator = module.exports = (function(){
 	* @return the first value
 	**/
 	proto.evaluate = function evaluate(doc){
-		if (this.operands.length == 1) throw new Error("this should never happen");
+		if (this.operands.length != 1) throw new Error("this should never happen");
 
 		/* only remember the first value seen */
-		if (!base.prototype.pValue.get.call(this))
-			this.pValue = this.operands[0].evaluate(doc);
+		if (!base.prototype.getValue.call(this) && this.started === 0) {
+			this.value = this.operands[0].evaluate(doc);
+			this.started = 1;
+		}
 
-		return this.pValue;
+		return this.value;
 	};
 
 	return klass;

+ 22 - 12
test/lib/pipeline/accumulators/FirstAccumulator.js

@@ -1,6 +1,12 @@
 var assert = require("assert"),
 	FirstAccumulator = require("../../../../lib/pipeline/accumulators/FirstAccumulator"),
-	Expression = require("../../../../lib/pipeline/expressions/Expression");
+	FieldPathExpression = require("../../../../lib/pipeline/expressions/FieldPathExpression");
+
+function createAccumulator(){
+	var firstAccumulator = new FirstAccumulator();
+	firstAccumulator.addOperand(new FieldPathExpression("a") );
+	return firstAccumulator;
+}
 
 module.exports = {
 
@@ -34,31 +40,35 @@ module.exports = {
 
 		"#evaluate()": {
 
-			/*
-			"should return day of year; 49 for 2013-02-18": function testStuff(){
-				assert.strictEqual(Expression.parseOperand({$dayOfYear:"$someDate"}).evaluate({someDate:new Date("2013-02-18 EST")}), 49);
-			},
-			*/
-
 			"The accumulator evaluates no documents": function none() {
 				// The accumulator returns no value in this case.
-				assert.ok(Expression.parseOperand({$first:"$a"}).evaluate());
+				var acc = createAccumulator();
+				assert.ok(!acc.getValue());
 			},
 
 			"The accumulator evaluates one document and retains its value": function one() {
-				assert.strictEqual(Expression.parseOperand({$first:"$a"}).evaluate({a:5}), 5);
+				var acc = createAccumulator();
+				acc.evaluate({a:5});
+				assert.strictEqual(acc.getValue(), 5);
 			},
 
 			"The accumulator evaluates one document with the field missing retains undefined": function missing() {
-				assert.strictEqual(Expression.parseOperand({$first:"$a"}).evaluate({}), undefined);
+				var acc = createAccumulator();
+				acc.evaluate({});
+				assert.strictEqual(acc.getValue(), undefined);
 			},
 
 			"The accumulator evaluates two documents and retains the value in the first": function two() {
-				assert.strictEqual(Expression.parseOperand({$first:"$a"}).evaluate([{a:5}, {a:7}]), 5);
+				var acc = createAccumulator();
+				acc.evaluate({a:5});
+				assert.strictEqual(acc.getValue(), 5);
 			},
 
 			"The accumulator evaluates two documents and retains the undefined value in the first": function firstMissing() {
-				assert.strictEqual(Expression.parseOperand({$first:"$a"}).evaluate([{}, {a:7}]), undefined);
+				var acc = createAccumulator();
+				acc.evaluate({});
+				acc.evaluate({a:7});
+				assert.strictEqual(acc.getValue(), undefined);
 			}
 		}