Browse Source

EAGLESIX-2709 MultiplyExpression and related tests are lovely.

Tony Ennis 11 years ago
parent
commit
61f362542a

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

@@ -40,7 +40,7 @@ proto.evaluateInternal = function evaluateInternal(vars) {
 	return true;
 };
 
-proto.isAssociativeAndCommutative = function isAssociativeAndCommutative() { return true; }
+proto.isAssociativeAndCommutative = function isAssociativeAndCommutative() { return true; };
 
 proto.optimize = function optimize() {
 	var expr = base.prototype.optimize.call(this); //optimize the conjunction as much as possible

+ 3 - 1
lib/pipeline/expressions/MultiplyExpression.js

@@ -9,7 +9,7 @@
  * @constructor
  **/
 var MultiplyExpression = module.exports = function MultiplyExpression(){
-	//if (arguments.length !== 0) throw new Error("Zero args expected");
+	if (arguments.length !== 0) throw new Error("Zero args expected");
 	base.call(this);
 }, klass = MultiplyExpression, base = require("./VariadicExpressionT")(MultiplyExpression), proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
 
@@ -23,6 +23,8 @@ proto.getOpName = function getOpName(){
 	return klass.opName;
 };
 
+proto.isAssociativeAndCommutative = function isAssociativeAndCommutative() { return true; };
+
 /**
  * Takes an array of one or more numbers and multiples them, returning the resulting product.
  * @method evaluateInternal

+ 59 - 8
test/lib/pipeline/expressions/MultiplyExpression_test.js

@@ -1,6 +1,10 @@
 "use strict";
 var assert = require("assert"),
 	MultiplyExpression = require("../../../../lib/pipeline/expressions/MultiplyExpression"),
+	VariablesParseState = require("../../../../lib/pipeline/expressions/VariablesParseState"),
+	VariablesIdGenerator = require("../../../../lib/pipeline/expressions/VariablesIdGenerator"),
+	FieldPathExpression = require("../../../../lib/pipeline/expressions/FieldPathExpression"),
+	ConstantExpression = require("../../../../lib/pipeline/expressions/ConstantExpression"),
 	Expression = require("../../../../lib/pipeline/expressions/Expression");
 
 
@@ -8,6 +12,10 @@ module.exports = {
 
 	"MultiplyExpression": {
 
+		beforeEach: function(){
+			this.vps = new VariablesParseState(new VariablesIdGenerator());
+		},
+
 		"constructor()": {
 
 			"should not throw Error when constructing without args": function testConstructor(){
@@ -33,19 +41,62 @@ module.exports = {
 		},
 
 		"#evaluate()": {
+			"should multiply constants": function () {
+				assert.strictEqual(Expression.parseOperand({$multiply: [2, 3, 4]}, this.vps).evaluate(), 2 * 3 * 4);
+			},
+
+			"should 'splode if an operand is a string": function () {
+				assert.throws(function () {
+					Expression.parseOperand({$multiply: [2, "x", 4]}, this.vps).evaluate();
+				});
+			},
+
+			"should 'splode if an operand is a boolean": function () {
+				assert.throws(function () {
+					Expression.parseOperand({$multiply: [2, "x", 4]}, this.vps).evaluate();
+				});
+			},
+
+			"should 'splode if an operand is a date": function () {
+				assert.throws(function () {
+					Expression.parseOperand({$multiply: [2, "x", 4]}, this.vps).evaluate();
+				});
+			},
 
-			"should return result of multiplying numbers": function testStuff(){
-				assert.strictEqual(Expression.parseOperand({$multiply:["$a", "$b"]}).evaluateInternal({a:1, b:2}), 1*2);
-				assert.strictEqual(Expression.parseOperand({$multiply:["$a", "$b", "$c"]}).evaluateInternal({a:1.345, b:2e45, c:0}), 1.345*2e45*0);
-				assert.strictEqual(Expression.parseOperand({$multiply:["$a"]}).evaluateInternal({a:1}), 1);
+			"should multiply mixed numbers": function () {
+				assert.strictEqual(Expression.parseOperand({$multiply: [2.1, 3, 4.4]}, this.vps).evaluate(), 2.1 * 3 * 4.4);
 			},
-			"should throw an exception if the result is not a number": function testStuff(){
-				assert.throws(Expression.parseOperand({$multiply:["$a", "$b"]}).evaluateInternal({a:1e199, b:1e199}));
+
+			"should return result of multiplying simple variables": function () {
+				assert.equal(Expression.parseOperand({$multiply: ["$a", "$b"]}, this.vps).evaluate({a: 1, b: 2}), 1 * 2);
+			},
+
+			"should return result of multiplying large variables": function () {
+				assert.strictEqual(Expression.parseOperand({$multiply: ["$a", "$b", "$c"]}, this.vps).evaluate({a: 1.345, b: 2e45, c: 0}), 1.345 * 2e45 * 0);
+			},
+
+			"should return result of multiplying one number": function () {
+				assert.strictEqual(Expression.parseOperand({$multiply: ["$a"]}, this.vps).evaluate({a: 1}), 1);
+			},
+
+			"should throw an exception if the result is not a number": function () {
+				assert.throws(
+					function () {
+						Expression.parseOperand({$multiply: ["$a", "$b"]}, this.vps).evaluate({a: 1e199, b: 1e199});
+					});
+			}
+		},
+		"optimize": {
+			"should optimize out constants separated by a variable": function () {
+				var a = Expression.parseOperand({$multiply: [2, 3, 4, 5, '$a', 6, 7, 8]}, this.vps).optimize();
+				assert(a instanceof MultiplyExpression);
+				assert.equal(a.operands.length, 2);
+				assert(a.operands[0] instanceof FieldPathExpression);
+				assert(a.operands[1] instanceof ConstantExpression);
+				assert.equal(a.operands[1].evaluateInternal(), 2*3*4*5*6*7*8);
 			}
 		}
-
 	}
-
 };
 
 if (!module.parent)(new(require("mocha"))()).ui("exports").reporter("spec").addFile(__filename).run(process.exit);