NaryExpression.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. var assert = require("assert"),
  2. NaryExpression = require("../../../../lib/pipeline/expressions/NaryExpression"),
  3. ConstantExpression = require("../../../../lib/pipeline/expressions/ConstantExpression"),
  4. FieldPathExpression = require("../../../../lib/pipeline/expressions/FieldPathExpression"),
  5. Expression = require("../../../../lib/pipeline/expressions/Expression");
  6. /** A dummy child of NaryExpression used for testing **/
  7. var TestableExpression = (function(){
  8. // CONSTRUCTOR
  9. var klass = module.exports = function TestableExpression(operands, haveFactory){
  10. base.call(this);
  11. if (operands) {
  12. var self = this;
  13. operands.forEach(function(operand) {
  14. self.addOperand(operand);
  15. });
  16. }
  17. this.haveFactory = !!haveFactory;
  18. }, base = NaryExpression, proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
  19. // PROTOTYPE MEMBERS
  20. proto.evaluate = function evaluate(doc) {
  21. // Just put all the values in a list. This is not associative/commutative so
  22. // the results will change if a factory is provided and operations are reordered.
  23. return this.operands.map(function(operand) {
  24. return operand.evaluate(doc);
  25. });
  26. };
  27. proto.getFactory = function getFactory(){
  28. return this.haveFactory ? this.factory : klass;
  29. };
  30. proto.getOpName = function getOpName() {
  31. return "$testable";
  32. };
  33. return klass;
  34. })();
  35. module.exports = {
  36. "NaryExpression": {
  37. "constructor()": {
  38. },
  39. "#optimize()": {
  40. },
  41. "#addOperand() should be able to add operands to expressions": function testAddOperand(){
  42. assert.deepEqual(new TestableExpression([new ConstantExpression(9)]).toJson(), {$testable:[9]});
  43. assert.deepEqual(new TestableExpression([new FieldPathExpression("ab.c")]).toJson(), {$testable:["$ab.c"]});
  44. },
  45. "#checkArgLimit() should throw Error iff number of operands is over given limit": function testCheckArgLimit(){
  46. var testableExpr = new TestableExpression();
  47. // no arguments
  48. assert.doesNotThrow(function(){
  49. testableExpr.checkArgLimit(1);
  50. });
  51. // one argument
  52. testableExpr.addOperand(new ConstantExpression(1));
  53. assert.throws(function(){
  54. testableExpr.checkArgLimit(1);
  55. });
  56. assert.doesNotThrow(function(){
  57. testableExpr.checkArgLimit(2);
  58. });
  59. // two arguments
  60. testableExpr.addOperand(new ConstantExpression(2));
  61. assert.throws(function(){
  62. testableExpr.checkArgLimit(1);
  63. });
  64. assert.throws(function(){
  65. testableExpr.checkArgLimit(2);
  66. });
  67. assert.doesNotThrow(function(){
  68. testableExpr.checkArgLimit(3);
  69. });
  70. },
  71. "#checkArgCount() should throw Error iff number of operands is not equal to given count": function testCheckArgCount(){
  72. var testableExpr = new TestableExpression();
  73. // no arguments
  74. assert.doesNotThrow(function(){
  75. testableExpr.checkArgCount(0);
  76. });
  77. assert.throws(function(){
  78. testableExpr.checkArgCount(1);
  79. });
  80. // one argument
  81. testableExpr.addOperand(new ConstantExpression(1));
  82. assert.throws(function(){
  83. testableExpr.checkArgCount(0);
  84. });
  85. assert.doesNotThrow(function(){
  86. testableExpr.checkArgCount(1);
  87. });
  88. assert.throws(function(){
  89. testableExpr.checkArgCount(2);
  90. });
  91. // two arguments
  92. testableExpr.addOperand(new ConstantExpression(2));
  93. assert.throws(function(){
  94. testableExpr.checkArgCount(1);
  95. });
  96. assert.doesNotThrow(function(){
  97. testableExpr.checkArgCount(2);
  98. });
  99. assert.throws(function(){
  100. testableExpr.checkArgCount(3);
  101. });
  102. },
  103. "#addDependencies()": function testDependencies(){
  104. var testableExpr = new TestableExpression();
  105. // no arguments
  106. assert.deepEqual(testableExpr.addDependencies([]), []);
  107. // add a constant argument
  108. testableExpr.addOperand(new ConstantExpression(1));
  109. assert.deepEqual(testableExpr.addDependencies([]), []);
  110. // add a field path argument
  111. testableExpr.addOperand(new FieldPathExpression("ab.c"));
  112. assert.deepEqual(testableExpr.addDependencies([]), ["ab.c"]);
  113. // add an object expression
  114. testableExpr.addOperand(Expression.parseObject({a:"$x",q:"$r"}, new Expression.ObjectCtx({isDocumentOk:1})));
  115. assert.deepEqual(testableExpr.addDependencies([]), ["ab.c", "r", "x"]);
  116. }
  117. }
  118. };
  119. if (!module.parent)(new(require("mocha"))()).ui("exports").reporter("spec").addFile(__filename).run(process.exit);