| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- "use strict";
- var assert = require("assert"),
- VariablesParseState = require("../../../../lib/pipeline/expressions/VariablesParseState"),
- VariablesIdGenerator = require("../../../../lib/pipeline/expressions/VariablesIdGenerator"),
- NaryExpression = require("../../../../lib/pipeline/expressions/NaryExpression"),
- ConstantExpression = require("../../../../lib/pipeline/expressions/ConstantExpression"),
- FieldPathExpression = require("../../../../lib/pipeline/expressions/FieldPathExpression"),
- Expression = require("../../../../lib/pipeline/expressions/Expression");
- // A dummy child of NaryExpression used for testing
- var TestableExpression = (function(){
- // CONSTRUCTOR
- var klass = function TestableExpression(operands, haveFactory){
- base.call(this);
- if (operands) {
- var self = this;
- operands.forEach(function(operand) {
- self.addOperand(operand);
- });
- }
- this.haveFactory = !!haveFactory;
- }, base = NaryExpression, proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
- // PROTOTYPE MEMBERS
- proto.evaluateInternal = function evaluateInternal(vps) {
- // Just put all the values in a list. This is not associative/commutative so
- // the results will change if a factory is provided and operations are reordered.
- return this.operands.map(function(operand) {
- return operand.evaluateInternal(vps);
- });
- };
- proto.isAssociativeAndCommutative = function isAssociativeAndCommutative(){
- return this.isAssociativeAndCommutative;
- };
- proto.getOpName = function getOpName() {
- return "$testable";
- };
- klass.createFromOperands = function(operands) {
- var vps = new VariablesParseState(new VariablesIdGenerator()),
- testable = new TestableExpression();
- operands.forEach(function(x) {
- testable.addOperand(Expression.parseOperand(x, vps));
- });
- return testable;
- };
- return klass;
- })();
- module.exports = {
- "NaryExpression": {
- "constructor()": {
- },
- "#optimize()": {
- "should suboptimize": function() {
- var testable = TestableExpression.createFromOperands([{"$and": []}, "$abc"], true);
- testable = testable.optimize();
- assert.deepEqual(testable.serialize(), {$testable: [true,"$abc"]});
- },
- "should fold constants": function() {
- var testable = TestableExpression.createFromOperands([1,2], true);
- testable = testable.optimize();
- assert.deepEqual(testable.serialize(), {$const: [1,2]});
- },
- "should place constants at the end of operands array": function() {
- var testable = TestableExpression.createFromOperands([55,65, "$path"], true);
- testable = testable.optimize();
- assert.deepEqual(testable.serialize(), {$testable:["$path", [55,66]]});
- },
- "should flatten two layers" : function() {
- var testable = TestableExpression.createFromOperands([55, "$path", {$add: [5,6,"$q"]}], true);
- testable.addOperand(TestableExpression.createFromOperands([99,100,"$another_path"], true));
- testable = testable.optimize();
- assert.deepEqual(testable.serialize(), {$testable: ["$path", {$add: [5,6,"$q"]}, "$another_path", [55,66,[99,100]]]});
- },
- "should flatten three layers": function(){
- var bottom = TestableExpression.createFromOperands([5,6,"$c"], true),
- middle = TestableExpression.createFromOperands([3,4,"$b"], true).addOperand(bottom),
- top = TestableExpression.createFromOperands([1,2,"$a"], true);
- var testable = top.optimize();
- assert.deepEqual(testable.serialize(), {$testable: ["$a", "$b", "$c", [1,2,[3,4,[5,6]]]]});
- }
- },
- "#addOperand() should be able to add operands to expressions": function testAddOperand(){
- var foo = new TestableExpression([new ConstantExpression(9)]).serialize();
- var bar = new TestableExpression([new ConstantExpression(9)]).serialize();
- var baz = {"$testable":[{"$const":9}]};
- assert.deepEqual(foo,bar);
- assert.deepEqual(foo, baz);
- assert.deepEqual(baz,foo);
- assert.deepEqual(new TestableExpression([new ConstantExpression(9)]).serialize(), {"$testable":[{"$const":9}]});
- assert.deepEqual(new TestableExpression([new FieldPathExpression("ab.c")]).serialize(), {$testable:["$ab.c"]});
- },
- "#serialize() should convert an object to json": function(){
- var testable = new TestableExpression();
- testable.addOperand(new ConstantExpression(5));
- assert.deepEqual({foo: testable.serialize()}, {foo:{$testable:[{$const: 5}]}});
- },
- //the following test case is eagerly awaiting ObjectExpression
- "#addDependencies()": function testDependencies(){
- var testableExpr = new TestableExpression();
- var deps = {};
- // no arguments
- testableExpr.addDependencies(deps);
- assert.deepEqual(deps, {});
- // add a constant argument
- testableExpr.addOperand(new ConstantExpression(1));
- deps = {};
- testableExpr.addDependencies(deps);
- assert.deepEqual(deps, {});
- // add a field path argument
- testableExpr.addOperand(new FieldPathExpression("ab.c"));
- deps = {};
- testableExpr.addDependencies(deps);
- assert.deepEqual(deps, {"ab.c":1});
- // add an object expression
- testableExpr.addOperand(Expression.parseObject({a:"$x",q:"$r"}, new Expression.ObjectCtx({isDocumentOk:1})));
- deps = {};
- testableExpr.addDependencies(deps);
- assert.deepEqual(deps, {"ab.c":1, "x":1, "r":1});
- }
- }
- };
- if (!module.parent)(new(require("mocha"))()).ui("exports").reporter("spec").addFile(__filename).run(process.exit);
|