소스 검색

EAGLESIX-2651: CoerceToBool: minor fixes, missing test

Kyle P Davis 11 년 전
부모
커밋
fc8955ea88
2개의 변경된 파일65개의 추가작업 그리고 81개의 파일을 삭제
  1. 12 15
      lib/pipeline/expressions/CoerceToBoolExpression.js
  2. 53 66
      test/lib/pipeline/expressions/CoerceToBoolExpression.js

+ 12 - 15
lib/pipeline/expressions/CoerceToBoolExpression.js

@@ -6,14 +6,13 @@
  * @namespace mungedb-aggregate.pipeline.expressions
  * @module mungedb-aggregate
  * @constructor
- **/
-var CoerceToBoolExpression = module.exports = function CoerceToBoolExpression(expression){
-	if (arguments.length !== 1) throw new Error("CoerceToBoolExpression constructor takes one arg.");
-	this.expression = expression;
+ */
+var CoerceToBoolExpression = module.exports = function CoerceToBoolExpression(theExpression){
+	if (arguments.length !== 1) throw new Error(klass.name + ": expected args: expr");
+	this.expression = theExpression;
 	base.call(this);
 }, klass = CoerceToBoolExpression, base = require("./Expression"), proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
 
-// DEPENDENCIES
 var Value = require("../Value"),
 	AndExpression = require("./AndExpression"),
 	OrExpression = require("./OrExpression"),
@@ -23,16 +22,16 @@ var Value = require("../Value"),
 klass.create = function create(expression) {
 	var newExpr = new CoerceToBoolExpression(expression);
 	return newExpr;
-
-}
+};
 
 proto.optimize = function optimize() {
-	this.expression = this.expression.optimize();   // optimize the operand
+	// optimize the operand
+	this.expression = this.expression.optimize();
 
 	// if the operand already produces a boolean, then we don't need this
 	// LATER - Expression to support a "typeof" query?
 	var expr = this.expression;
-	if(expr instanceof AndExpression ||
+	if (expr instanceof AndExpression ||
 			expr instanceof OrExpression ||
 			expr instanceof NotExpression ||
 			expr instanceof CoerceToBoolExpression)
@@ -44,18 +43,16 @@ proto.addDependencies = function addDependencies(deps, path) {
 	this.expression.addDependencies(deps);
 };
 
-// PROTOTYPE MEMBERS
-proto.evaluateInternal = function evaluateInternal(vars){
+proto.evaluateInternal = function evaluateInternal(vars) {
 	var result = this.expression.evaluateInternal(vars);
 	return Value.coerceToBool(result);
 };
 
 proto.serialize = function serialize(explain) {
+	// When not explaining, serialize to an $and expression. When parsed, the $and expression
+	// will be optimized back into a ExpressionCoerceToBool.
 	var name = explain ? "$coerceToBool" : "$and",
 		obj = {};
-		obj[name] = [this.expression.serialize(explain)];
+	obj[name] = [this.expression.serialize(explain)];
 	return obj;
 };
-
-//TODO: proto.addToBsonObj   --- may be required for $project to work
-//TODO: proto.addToBsonArray

+ 53 - 66
test/lib/pipeline/expressions/CoerceToBoolExpression.js

@@ -1,94 +1,81 @@
 "use strict";
 var assert = require("assert"),
 	CoerceToBoolExpression = require("../../../../lib/pipeline/expressions/CoerceToBoolExpression"),
+	Expression = require("../../../../lib/pipeline/expressions/Expression"),
 	FieldPathExpression = require("../../../../lib/pipeline/expressions/FieldPathExpression"),
 	ConstantExpression = require("../../../../lib/pipeline/expressions/ConstantExpression"),
 	DepsTracker = require("../../../../lib/pipeline/DepsTracker");
 
-function errMsg(expr, args, tree, expected, result) {
-	return "for expression " + expr +
-		" with argument " + args +
-		" full tree: " + JSON.stringify(tree) +
-		" expected: " + expected +
-		" result: " + result;
-}
+exports.CoerceToBoolExpression = {
 
-module.exports = {
-
-	"CoerceToBoolExpression": {
-
-		"constructor()": {
-
-			"should throw Error if no args": function construct(){
-				assert.throws(function(){
-					new CoerceToBoolExpression();
-				});
-			},
-
-			"should throw Error if more than 1 arg": function construct(){
-				assert.throws(function(){
-					var a = b = "foo";
-					new CoerceToBoolExpression(a,b);
-				});
-			},
-
-			"should not throw Error if 1 arg": function construct(){
-				assert.doesNotThrow(function(){
-					var a = "foo";
-					new CoerceToBoolExpression(a);
-				});
-			},
+	"constructor()": {
 
+		"should create instance": function() {
+			var nested = ConstantExpression.create(5);
+			assert(new CoerceToBoolExpression(nested) instanceof Expression);
 		},
 
-		"#evaluate()": {
+		"should throw Error unless one arg": function() {
+			assert.throws(function() {
+				new CoerceToBoolExpression();
+			});
+			assert.throws(function() {
+				new CoerceToBoolExpression("foo", "bar");
+			});
+		},
 
-			"should return true if nested expression is coerced to true; {$const:5}": function testEvaluateTrue(){
-				var expr = new CoerceToBoolExpression(new ConstantExpression(5));
-				assert.equal(expr.evaluateInternal({}), true);
-			},
+	},
 
-			"should return false if nested expression is coerced to false; {$const:0}": function testEvaluateFalse(){
-				var expr = new CoerceToBoolExpression(new ConstantExpression(0));
-				assert.equal(expr.evaluateInternal({}), false);
-			}
+	"#evaluate()": {
 
+		"should return true if nested expression is coerced to true; {$const:5}": function testEvaluateTrue() {
+			/** Nested expression coerced to true. */
+			var nested = ConstantExpression.create(5),
+				expr = CoerceToBoolExpression.create(nested);
+			assert.strictEqual(expr.evaluate({}), true);
 		},
 
-		/**
-		 * These tests should just work after the FieldPathExpression Stuff is ported.
-		**/
+		"should return false if nested expression is coerced to false; {$const:0}": function testEvaluateFalse() {
+			/** Nested expression coerced to false. */
+			var expr = CoerceToBoolExpression.create(ConstantExpression.create(0));
+			assert.strictEqual(expr.evaluate({}), false);
+		},
 
-		"#serialize": {
+	},
 
-			"should serialize as $and which will coerceToBool; '$foo'": function(){
-				var expr = new CoerceToBoolExpression(FieldPathExpression.create('foo'));
-				assert.deepEqual(expr.serialize(), {$and:['$foo']});
-			}
+	"#addDependencies()": {
 
+		"should forward dependencies of nested expression": function testDependencies() {
+			/** Dependencies forwarded from nested expression. */
+			var nested = FieldPathExpression.create("a.b"),
+				expr = CoerceToBoolExpression.create(nested),
+				deps = new DepsTracker();
+			expr.addDependencies(deps);
+			assert.strictEqual( Object.keys(deps.fields).length, 1 );
+			assert.strictEqual("a.b" in deps.fields, true);
+			assert.strictEqual(deps.needWholeDocument, false);
+			assert.strictEqual(deps.needTextScore, false);
 		},
 
-		"#addDependencies()": {
-
-			"should forward dependencies of nested expression": function testDependencies(){
-				var nested = FieldPathExpression.create("a.b"),
-					expr = new CoerceToBoolExpression(nested),
-					deps = new DepsTracker(),
-					depsArray = [];
-					expr.addDependencies(deps);
+	},
 
-					Object.keys(deps).forEach(function (key){
-						if (deps[key]){
-							depsArray.push(key);
-						}
-					});
+	"#serialize": {
 
-				assert.equal(depsArray.length, 1);
-			}
+		"should be able to output in to JSON Object": function testAddToBsonObj() {
+			/** Output to BSONObj. */
+			var expr = CoerceToBoolExpression.create(FieldPathExpression.create("foo"));
+            // serialized as $and because CoerceToBool isn't an ExpressionNary
+			assert.deepEqual({field:{$and:["$foo"]}}, {field:expr.serialize(false)});
+		},
 
-		}
+		"should be able to output in to JSON Array": function testAddToBsonArray() {
+			/** Output to BSONArray. */
+			var expr = CoerceToBoolExpression.create(FieldPathExpression.create("foo"));
+			// serialized as $and because CoerceToBool isn't an ExpressionNary
+			assert.deepEqual([{$and:["$foo"]}], [expr.serialize(false)]);
+		},
 
-	}
+	},
 
 };