Преглед изворни кода

EAGLESIX-2695 Completed all test cases expect a full blown test that requires expressions that are not yet available.

Tony Ennis пре 11 година
родитељ
комит
ced5bc4e45

+ 11 - 3
lib/pipeline/expressions/LetExpression.js

@@ -101,7 +101,12 @@ proto.serialize = function serialize(explain) {
 proto.evaluateInternal = function evaluateInternal(vars) {
 	for(var id in this._variables) {
 		for(var name in this._variables[id]) {
-			vars.setValue(id, this._variables[id][name]);
+			// It is guaranteed at parse-time that these expressions don't use the variable ids we
+			// are setting
+			var first = id,
+				second = this._variables[first][name];
+			//Note - The unary plus on first converts it to an int. Don't remove it.
+			vars.setValue(+first, second._expressions[name].evaluateInternal(vars));
 		}
 	}
 
@@ -111,10 +116,13 @@ proto.evaluateInternal = function evaluateInternal(vars) {
 proto.addDependencies = function addDependencies(deps, path){
 	for(var id in this._variables) {
 		for(var name in this._variables[id]) {
-			this._variables[id][name].addDependencies(deps);
+			var first = id,
+				second = this._variables[first][name];
+			second._expressions[name].addDependencies(deps);
+//			this._variables[id][name].addDependencies(deps);
 		}
 	}
-	this._subExpression.addDependencies(deps, path);
+	this._subExpression.addDependencies(deps);
 	return deps; //NOTE: DEVIATION FROM MONGO: The c++ version does not return a value. We seem to use the returned value
 					// (or something from a different method named
 					// addDependencies) in many places.

+ 19 - 7
test/lib/pipeline/expressions/LetExpression_test.js

@@ -1,11 +1,13 @@
 "use strict";
 var assert = require("assert"),
 
+	DepsTracker = require("../../../../lib/pipeline/DepsTracker"),
 	LetExpression = require("../../../../lib/pipeline/expressions/LetExpression"),
 	ConstantExpression = require("../../../../lib/pipeline/expressions/ConstantExpression"),
 	MultiplyExpression = require("../../../../lib/pipeline/expressions/MultiplyExpression"),
 	FieldPathExpression = require("../../../../lib/pipeline/expressions/FieldPathExpression"),
 	VariablesParseState = require("../../../../lib/pipeline/expressions/VariablesParseState"),
+	Variables = require("../../../../lib/pipeline/expressions/Variables"),
 	VariablesIdGenerator = require("../../../../lib/pipeline/expressions/VariablesIdGenerator"),
 	Expression = require("../../../../lib/pipeline/expressions/Expression");
 
@@ -126,24 +128,34 @@ module.exports = {
 
 			"#evaluateInternal()": {
 				"should perform the evaluation for variables and the subexpression": function () {
-					var x = Expression.parseOperand({$let: {vars: {a: '$in1', b: '$in2'}, in: { $multiply: ["$$a", "$$b"] }}}, this.vps).optimize(),
-						vars = new Variables(2, {});
+					var x = Expression.parseOperand({$let: {vars: {a: '$in1', b: '$in2'}, in: { $multiply: ["$$a", "$$b"] }}}, this.vps).optimize();
 					var	y = x.evaluate(new Variables(10, {in1: 6, in2: 7}));
-					assert(x);
+					assert.equal(y, 42);
 				}
 			},
 
 			"#addDependencies()": {
 				"should add dependencies": function(){
-					assert(false, "unimplemented");
+					var expr = Expression.parseOperand({$let: {vars: {a: {$multiply:['$a','$b']}}, in: {$multiply: ['$c','$d']}}}, this.vps);
+					var deps = new DepsTracker();
+					expr.addDependencies(deps);
+					assert.equal(Object.keys(deps.fields).length, 4);
+					assert('a' in deps.fields);
+					assert('b' in deps.fields);
+					assert('c' in deps.fields);
+					assert('d' in deps.fields);
+					assert.strictEqual(deps.needWholeDocument, false);
+					assert.strictEqual(deps.needTextScore, false);
 				}
 			},
+
 			"The Guantlet": {
 				"example from http://docs.mongodb.org/manual/reference/operator/aggregation/let/": function () {
 					var x = Expression.parseOperand(
-						"$let: { vars: { total: { $add: [ '$price', '$tax' ] },	discounted: { $cond: { if: '$applyDiscount', then: 0.9, else: 1 } }}, in: { $multiply: [ '$$total', '$$discounted' ] }",
-						this.vps).optimize().evaluate({price: 90, tax: .05});
-					assertEqual(x.getValue(), 100);
+						{$let: { vars: { total: { $add: [ '$price', '$tax' ] },	discounted: { $cond: { if: '$applyDiscount', then: 0.9, else: 1 } }}, in: { $multiply: [ '$$total', '$$discounted' ] }}},
+						this.vps).optimize();
+					var y = x.evaluate(new Variables(10, {price: 90, tax: .05}));
+					assert.equal(y, 100);
 				}
 			},
 		}