Browse Source

EAGLESIX-2690 expressions FixedArity

Jared Hall 11 years ago
parent
commit
1fed7542fc
28 changed files with 187 additions and 89 deletions
  1. 3 4
      lib/pipeline/expressions/AllElementsTrueExpression.js
  2. 10 3
      lib/pipeline/expressions/AnyElementTrueExpression.js
  3. 2 2
      lib/pipeline/expressions/CompareExpression.js
  4. 7 8
      lib/pipeline/expressions/CondExpression.js
  5. 9 9
      lib/pipeline/expressions/DayOfMonthExpression.js
  6. 9 3
      lib/pipeline/expressions/DayOfWeekExpression.js
  7. 9 3
      lib/pipeline/expressions/DayOfYearExpression.js
  8. 9 3
      lib/pipeline/expressions/DivideExpression.js
  9. 32 0
      lib/pipeline/expressions/FixedArityExpressionT.js
  10. 9 3
      lib/pipeline/expressions/HourExpression.js
  11. 3 3
      lib/pipeline/expressions/IfNullExpression.js
  12. 3 3
      lib/pipeline/expressions/MillisecondExpression.js
  13. 3 3
      lib/pipeline/expressions/MinuteExpression.js
  14. 3 3
      lib/pipeline/expressions/ModExpression.js
  15. 3 3
      lib/pipeline/expressions/MonthExpression.js
  16. 3 3
      lib/pipeline/expressions/NotExpression.js
  17. 3 3
      lib/pipeline/expressions/SecondExpression.js
  18. 3 3
      lib/pipeline/expressions/SetDifferenceExpression.js
  19. 3 3
      lib/pipeline/expressions/SetIsSubsetExpression.js
  20. 3 3
      lib/pipeline/expressions/SizeExpression.js
  21. 3 3
      lib/pipeline/expressions/StrcasecmpExpression.js
  22. 3 3
      lib/pipeline/expressions/SubstrExpression.js
  23. 3 3
      lib/pipeline/expressions/SubtractExpression.js
  24. 3 3
      lib/pipeline/expressions/ToLowerExpression.js
  25. 3 3
      lib/pipeline/expressions/ToUpperExpression.js
  26. 3 3
      lib/pipeline/expressions/WeekExpression.js
  27. 3 3
      lib/pipeline/expressions/YearExpression.js
  28. 37 0
      test/lib/pipeline/expressions/FixedArityExpressionT.js

+ 3 - 4
lib/pipeline/expressions/AllElementsTrueExpression.js

@@ -8,12 +8,11 @@
  * @constructor
  **/
 var AllElementsTrueExpression = module.exports = function AllElementsTrueExpression() {
-	this.nargs = 1;
 	base.call(this);
 },
 	klass = AllElementsTrueExpression,
-	NaryExpression = require("./NaryExpression"),
-	base = NaryExpression,
+	FixedArityExpression = require("./FixedArityExpressionT")(klass, 1),
+	base = FixedArityExpression,
 	proto = klass.prototype = Object.create(base.prototype, {
 		constructor: {
 			value: klass
@@ -46,4 +45,4 @@ proto.evaluateInternal = function evaluateInternal(vars) {
 };
 
 /** Register Expression */
-Expression.registerExpression("$allElementsTrue", base.parse(AllElementsTrueExpression));
+Expression.registerExpression("$allElementsTrue", base.parse);

+ 10 - 3
lib/pipeline/expressions/AnyElementTrueExpression.js

@@ -8,9 +8,16 @@
  * @constructor
  **/
 var AnyElementTrueExpression = module.exports = function AnyElementTrueExpression(){
-	this.nargs = (1);
 	base.call(this);
-}, klass = AnyElementTrueExpression, NaryExpression = require("./NaryExpression"), base = NaryExpression, proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
+},
+	klass = AnyElementTrueExpression,
+	FixedArityExpression = require("./FixedArityExpressionT")(klass, 1),
+	base = FixedArityExpression,
+	proto = klass.prototype = Object.create(base.prototype,{
+		constructor:{
+			value:klass
+		}
+	});
 
 // DEPENDENCIES
 var Value = require("../Value"),
@@ -38,4 +45,4 @@ proto.evaluateInternal = function evaluateInternal(vars) {
 };
 
 /** Register Expression */
-Expression.registerExpression("$anyElementTrue",base.parse(AnyElementTrueExpression));
+Expression.registerExpression("$anyElementTrue",base.parse);

+ 2 - 2
lib/pipeline/expressions/CompareExpression.js

@@ -8,11 +8,11 @@
  * @constructor
  **/
 var CompareExpression = module.exports = function CompareExpression(cmpOp) {
-    this.nargs = 2;
     this.cmpOp = cmpOp;
     base.call(this);
 }, klass = CompareExpression,
-    base = require("./NaryExpression"),
+    FixedArityExpression = require("./FixedArityExpressionT")(klass, 2),
+	base = FixedArityExpression,
     proto = klass.prototype = Object.create(base.prototype, {
 		constructor: {
 			value: klass

+ 7 - 8
lib/pipeline/expressions/CondExpression.js

@@ -8,19 +8,18 @@
  * @constructor
  **/
 var CondExpression = module.exports = function CondExpression(vars) {
-    this.nargs = 3;
     this.pCond = this.evaluateInternal(vars);
     this.idx = this.pCond.coerceToBool() ? 1 : 2;
-
     if (arguments.length !== 3) throw new Error("three args expected");
     base.call(this);
 }, klass = CondExpression,
-    base = require("./NaryExpression"),
-    proto = klass.prototype = Object.create(base.prototype, {
-	constructor: {
-	    value: klass
-	}
-    });
+	FixedArityExpression = require("./FixedArityExpressionT")(klass, 3),
+	base = FixedArityExpression,
+	proto = klass.prototype = Object.create(base.prototype, {
+		constructor: {
+			value: klass
+		}
+	});
 
 // DEPENDENCIES
 var Value = require("../Value"),

+ 9 - 9
lib/pipeline/expressions/DayOfMonthExpression.js

@@ -8,15 +8,15 @@
  * @constructor
  **/
 var DayOfMonthExpression = module.exports = function DayOfMonthExpression() {
-    this.nargs = 1;
-    base.call(this);
+	base.call(this);
 }, klass = DayOfMonthExpression,
-    base = require("./NaryExpression"),
-    proto = klass.prototype = Object.create(base.prototype, {
+	FixedArityExpression = require("./FixedArityExpressionT")(klass, 1),
+	base = FixedArityExpression,
+	proto = klass.prototype = Object.create(base.prototype, {
 		constructor: {
 			value: klass
 		}
-    });
+	});
 
 // DEPENDENCIES
 var Expression = require("./Expression");
@@ -24,7 +24,7 @@ var Expression = require("./Expression");
 
 // PROTOTYPE MEMBERS
 proto.getOpName = function getOpName() {
-    return "$dayOfMonth";
+	return "$dayOfMonth";
 };
 
 /**
@@ -32,9 +32,9 @@ proto.getOpName = function getOpName() {
  * @method evaluate
  **/
 proto.evaluateInternal = function evaluateInternal(vars) {
-    var date = this.operands[0].evaluateInternal(vars);
-    return date.getUTCDate();
+	var date = this.operands[0].evaluateInternal(vars);
+	return date.getUTCDate();
 };
 
 /** Register Expression */
-Expression.registerExpression("$dayOfMonth", base.parse(DayOfMonthExpression));
+Expression.registerExpression("$dayOfMonth", base.parse);

+ 9 - 3
lib/pipeline/expressions/DayOfWeekExpression.js

@@ -8,9 +8,15 @@
  * @constructor
  **/
 var DayOfWeekExpression = module.exports = function DayOfWeekExpression(){
-	this.nargs = 1;
 	base.call(this);
-}, klass = DayOfWeekExpression, base = require("./NaryExpression"), proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
+}, klass = DayOfWeekExpression,
+	FixedArityExpression = require("./FixedArityExpressionT")(klass, 1),
+	base = FixedArityExpression,
+	proto = klass.prototype = Object.create(base.prototype, {
+		constructor:{
+			value:klass
+		}
+	});
 
 // DEPENDENCIES
 var Expression = require("./Expression");
@@ -30,4 +36,4 @@ proto.evaluateInternal = function evaluateInternal(vars){
 };
 
 /** Register Expression */
-Expression.registerExpression("$dayOfWeek",base.parse(DayOfWeekExpression));
+Expression.registerExpression("$dayOfWeek",base.parse);

+ 9 - 3
lib/pipeline/expressions/DayOfYearExpression.js

@@ -8,9 +8,15 @@
  * @constructor
  **/
 var DayOfYearExpression = module.exports = function DayOfYearExpression(){
-	this.nargs = 1;
 	base.call(this);
-}, klass = DayOfYearExpression, base = require("./NaryExpression"), proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
+}, klass = DayOfYearExpression,
+	FixedArityExpression = require("./FixedArityExpressionT")(klass, 1),
+	base = FixedArityExpression,
+	proto = klass.prototype = Object.create(base.prototype, {
+		constructor:{
+			value:klass
+		}
+	});
 
 // DEPENDENCIES
 var Expression = require("./Expression");
@@ -38,4 +44,4 @@ klass.getDateDayOfYear = function getDateDayOfYear(d){
 };
 
 /** Register Expression */
-Expression.registerExpression("$dayOfYear",base.parse(DayOfYearExpression));
+Expression.registerExpression("$dayOfYear",base.parse);

+ 9 - 3
lib/pipeline/expressions/DivideExpression.js

@@ -9,9 +9,15 @@
  * @constructor
  **/
 var DivideExpression = module.exports = function DivideExpression(){
-    this.nargs = 2;
     base.call(this);
-}, klass = DivideExpression, base = require("./NaryExpression"), proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
+}, klass = DivideExpression,
+	FixedArityExpression = require("./FixedArityExpressionT")(klass, 2),
+	base = FixedArityExpression,
+	proto = klass.prototype = Object.create(base.prototype, {
+		constructor:{
+			value:klass
+		}
+	});
 
 // DEPENDENCIES
 var Value = require("../Value"),
@@ -37,4 +43,4 @@ proto.evaluateInternal = function evaluateInternal(vars) {
 };
 
 /** Register Expression */
-Expression.registerExpression("$divide",base.parse(DivideExpression));
+Expression.registerExpression("$divide",base.parse);

+ 32 - 0
lib/pipeline/expressions/FixedArityExpressionT.js

@@ -0,0 +1,32 @@
+"use strict";
+
+/**
+ * A factory and base class for expressions that take a fixed number of arguments
+ * @class FixedArityExpressionT
+ * @namespace mungedb-aggregate.pipeline.expressions
+ * @module mungedb-aggregate
+ * @constructor
+ **/
+
+var FixedArityExpressionT = module.exports = function FixedArityExpressionT(SubClass, nArgs) {
+
+	var FixedArityExpression = function FixedArityExpression() {
+		if (arguments.length !== 0) throw new Error((SubClass.opName || "(unspecified)") + ": zero args expected");
+		base.call(this);
+	}, klass = FixedArityExpression, base = require("./NaryExpressionT")(SubClass), proto = klass.prototype = Object.create(base.prototype, {constructor: {value: klass}});
+
+	/**
+	 * Check that the number of args is what we expected
+	 * @method validateArguments
+	 * @param args Array The array of arguments to the expression
+	 * @throws
+	 **/
+	proto.validateArguments = function validateArguments(args) {
+		if(args.length !== nArgs) {
+			throw new Error("Expression " + this.getOpName() + " takes exactly " +
+				nArgs + " arguments. " + args.length + " were passed in.")
+		}
+	};
+	return FixedArityExpression;
+};
+

+ 9 - 3
lib/pipeline/expressions/HourExpression.js

@@ -9,9 +9,15 @@
  * @constructor
  **/
 var HourExpression = module.exports = function HourExpression(){
-	this.nargs = 1;
 	base.call(this);
-}, klass = HourExpression, base = require("./NaryExpression"), proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
+}, klass = HourExpression,
+	FixedArityExpression = require("./FixedArityExpressionT")(klass, 1),
+	base = FixedArityExpression,
+	proto = klass.prototype = Object.create(base.prototype, {
+		constructor:{
+			value:klass
+		}
+	});
 
 // PROTOTYPE MEMBERS
 proto.getOpName = function getOpName(){
@@ -32,4 +38,4 @@ proto.evaluateInternal = function evaluateInternal(vars){
 
 
 /** Register Expression */
-Expression.registerExpression("$hour",base.parse(HourExpression));
+Expression.registerExpression("$hour",base.parse);

+ 3 - 3
lib/pipeline/expressions/IfNullExpression.js

@@ -9,11 +9,11 @@
  * @constructor
  **/
 var IfNullExpression = module.exports = function IfNullExpression() {
-	this.nargs = 2;
 	if (arguments.length !== 0) throw new Error("zero args expected");
 	base.call(this);
 }, klass = IfNullExpression,
-	base = require("./NaryExpression"),
+	FixedArityExpression = require("./FixedArityExpressionT")(klass, 2),
+	base = FixedArityExpression,
 	proto = klass.prototype = Object.create(base.prototype, {
 		constructor: {
 			value: klass
@@ -42,4 +42,4 @@ proto.evaluateInternal = function evaluateInternal(vars) {
 };
 
 /** Register Expression */
-Expression.registerExpression("$ifNull", base.parse(IfNullExpression));
+Expression.registerExpression("$ifNull", base.parse);

+ 3 - 3
lib/pipeline/expressions/MillisecondExpression.js

@@ -9,10 +9,10 @@
  * @constructor
  **/
 var MillisecondExpression = module.exports = function MillisecondExpression() {
-	this.nargs = 1;
 	base.call(this);
 }, klass = MillisecondExpression,
-	base = require("./NaryExpression"),
+	FixedArityExpression = require("./FixedArityExpressionT")(klass, 1),
+	base = FixedArityExpression,
 	proto = klass.prototype = Object.create(base.prototype, {
 		constructor: {
 			value: klass
@@ -39,4 +39,4 @@ proto.evaluateInternal = function evaluateInternal(vars) {
 };
 
 /** Register Expression */
-Expression.registerExpression("$millisecond", base.parse(MillisecondExpression));
+Expression.registerExpression("$millisecond", base.parse);

+ 3 - 3
lib/pipeline/expressions/MinuteExpression.js

@@ -9,10 +9,10 @@
  * @constructor
  **/
 var MinuteExpression = module.exports = function MinuteExpression() {
-	this.nargs = 1;
 	base.call(this);
 }, klass = MinuteExpression,
-	base = require("./NaryExpression"),
+	FixedArityExpression = require("./FixedArityExpressionT")(klass, 1),
+	base = FixedArityExpression,
 	proto = klass.prototype = Object.create(base.prototype, {
 		constructor: {
 			value: klass
@@ -37,4 +37,4 @@ proto.evaluateInternal = function evaluateInternal(vars) {
 };
 
 /** Register Expression */
-Expression.registerExpression("$minute", base.parse(MinuteExpression));
+Expression.registerExpression("$minute", base.parse);

+ 3 - 3
lib/pipeline/expressions/ModExpression.js

@@ -9,10 +9,10 @@
  * @constructor
  **/
 var ModExpression = module.exports = function ModExpression() {
-	this.nargs = 2;
 	base.call(this);
 }, klass = ModExpression,
-	base = require("./NaryExpression"),
+	FixedArityExpression = require("./FixedArityExpressionT")(klass, 2),
+	base = FixedArityExpression,
 	proto = klass.prototype = Object.create(base.prototype, {
 		constructor: {
 			value: klass
@@ -51,4 +51,4 @@ proto.evaluateInternal = function evaluateInternal(vars) {
 };
 
 /** Register Expression */
-Expression.registerExpression("$mod", base.parse(ModExpression));
+Expression.registerExpression("$mod", base.parse);

+ 3 - 3
lib/pipeline/expressions/MonthExpression.js

@@ -9,10 +9,10 @@
  * @constructor
  **/
 var MonthExpression = module.exports = function MonthExpression() {
-	this.nargs = 1;
 	base.call(this);
 }, klass = MonthExpression,
-	base = require("./NaryExpression"),
+	FixedArityExpression = require("./FixedArityExpressionT")(klass, 1),
+	base = FixedArityExpression,
 	proto = klass.prototype = Object.create(base.prototype, {
 		constructor: {
 			value: klass
@@ -37,4 +37,4 @@ proto.evaluateInternal = function evaluateInternal(vars) {
 };
 
 /** Register Expression */
-Expression.registerExpression("$month", base.parse(MonthExpression));
+Expression.registerExpression("$month", base.parse);

+ 3 - 3
lib/pipeline/expressions/NotExpression.js

@@ -9,10 +9,10 @@
  * @constructor
  **/
 var NotExpression = module.exports = function NotExpression() {
-	this.nargs = 1;
 	base.call(this);
 }, klass = NotExpression,
-	base = require("./NaryExpression"),
+	FixedArityExpression = require("./FixedArityExpressionT")(klass, 1),
+	base = FixedArityExpression,
 	proto = klass.prototype = Object.create(base.prototype, {
 		constructor: {
 			value: klass
@@ -38,4 +38,4 @@ proto.evaluateInternal = function evaluateInternal(vars) {
 };
 
 /** Register Expression */
-Expression.registerExpression("$not", base.parse(NotExpression));
+Expression.registerExpression("$not", base.parse);

+ 3 - 3
lib/pipeline/expressions/SecondExpression.js

@@ -9,10 +9,10 @@
  * @constructor
  **/
 var SecondExpression = module.exports = function SecondExpression() {
-	this.nargs = 1;
 	base.call(this);
 }, klass = SecondExpression,
-	base = require("./NaryExpression"),
+	FixedArityExpression = require("./FixedArityExpressionT")(klass, 1),
+	base = FixedArityExpression,
 	proto = klass.prototype = Object.create(base.prototype, {
 		constructor: {
 			value: klass
@@ -39,4 +39,4 @@ proto.evaluateInternal = function evaluateInternal(vars) {
 };
 
 /** Register Expression */
-Expression.registerExpression("$second", base.parse(SecondExpression));
+Expression.registerExpression("$second", base.parse);

+ 3 - 3
lib/pipeline/expressions/SetDifferenceExpression.js

@@ -9,10 +9,10 @@
  * @constructor
  **/
 var SetDifferenceExpression = module.exports = function SetDifferenceExpression() {
-	this.nargs = 2;
 	base.call(this);
 }, klass = SetDifferenceExpression,
-	base = require("./NaryExpression"),
+	FixedArityExpression = require("./FixedArityExpressionT")(klass, 2),
+	base = FixedArityExpression,
 	proto = klass.prototype = Object.create(base.prototype, {
 		constructor: {
 			value: klass
@@ -49,4 +49,4 @@ proto.evaluateInternal = function evaluateInternal(vars) {
 };
 
 /** Register Expression */
-Expression.registerExpression("$setdifference", base.parse(SetDifferenceExpression));
+Expression.registerExpression("$setdifference", base.parse);

+ 3 - 3
lib/pipeline/expressions/SetIsSubsetExpression.js

@@ -9,11 +9,11 @@
  * @constructor
  **/
 var SetIsSubsetExpression = module.exports = function SetIsSubsetExpression() {
-	this.nargs = 2;
 	if (arguments.length !== 2) throw new Error("two args expected");
 	base.call(this);
 }, klass = SetIsSubsetExpression,
-	base = require("./NaryExpression"),
+	FixedArityExpression = require("./FixedArityExpressionT")(klass, 2),
+	base = FixedArityExpression,
 	proto = klass.prototype = Object.create(base.prototype, {
 		constructor: {
 			value: klass
@@ -85,4 +85,4 @@ proto.evaluateInternal = function evaluateInternal(vars) {
 };
 
 /** Register Expression */
-Expression.registerExpression("$setissubset", base.parse(SetIsSubsetExpression));
+Expression.registerExpression("$setissubset", base.parse);

+ 3 - 3
lib/pipeline/expressions/SizeExpression.js

@@ -9,10 +9,10 @@
  * @constructor
  **/
 var SizeExpression = module.exports = function SizeExpression() {
-	this.nargs = 1;
 	base.call(this);
 }, klass = SizeExpression,
-	base = require("./NaryExpression"),
+	FixedArityExpression = require("./FixedArityExpressionT")(klass, 1),
+	base = FixedArityExpression,
 	proto = klass.prototype = Object.create(base.prototype, {
 		constructor: {
 			value: klass
@@ -38,4 +38,4 @@ proto.evaluateInternal = function evaluateInternal(vars) {
 };
 
 /** Register Expression */
-Expression.registerExpression("$size", base.parse(SizeExpression));
+Expression.registerExpression("$size", base.parse);

+ 3 - 3
lib/pipeline/expressions/StrcasecmpExpression.js

@@ -9,10 +9,10 @@
  * @constructor
  **/
 var StrcasecmpExpression = module.exports = function StrcasecmpExpression() {
-	this.nargs = 2;
 	base.call(this);
 }, klass = StrcasecmpExpression,
-	base = require("./NaryExpression"),
+	FixedArityExpression = require("./FixedArityExpressionT")(klass, 2),
+	base = FixedArityExpression,
 	proto = klass.prototype = Object.create(base.prototype, {
 		constructor: {
 			value: klass
@@ -43,4 +43,4 @@ proto.evaluateInternal = function evaluateInternal(vars) {
 };
 
 /** Register Expression */
-Expression.registerExpression("$strcasecmp", base.parse(StrcasecmpExpression));
+Expression.registerExpression("$strcasecmp", base.parse);

+ 3 - 3
lib/pipeline/expressions/SubstrExpression.js

@@ -9,10 +9,10 @@
  * @constructor
  **/
 var SubstrExpression = module.exports = function SubstrExpression() {
-	this.nargs = 3;
 	base.call(this);
 }, klass = SubstrExpression,
-	base = require("./NaryExpression"),
+	FixedArityExpression = require("./FixedArityExpressionT")(klass, 3),
+	base = FixedArityExpression,
 	proto = klass.prototype = Object.create(base.prototype, {
 		constructor: {
 			value: klass
@@ -46,4 +46,4 @@ proto.evaluateInternal = function evaluateInternal(vars) {
 };
 
 /** Register Expression */
-Expression.registerExpression("$substr", base.parse(SubstrExpression));
+Expression.registerExpression("$substr", base.parse);

+ 3 - 3
lib/pipeline/expressions/SubtractExpression.js

@@ -9,10 +9,10 @@
  * @constructor
  **/
 var SubtractExpression = module.exports = function SubtractExpression(){
-	this.nargs = 2;
 	base.call(this);
 }, klass = SubtractExpression,
-	base = require("./NaryExpression"),
+	FixedArityExpression = require("./FixedArityExpressionT")(klass, 2),
+	base = FixedArityExpression,
 	proto = klass.prototype = Object.create(base.prototype, {
 		constructor: {
 			value: klass
@@ -39,4 +39,4 @@ proto.evaluateInternal = function evaluateInternal(vars) {
 };
 
 /** Register Expression */
-Expression.registerExpression("$subtract", base.parse(SubtractExpression));
+Expression.registerExpression("$subtract", base.parse);

+ 3 - 3
lib/pipeline/expressions/ToLowerExpression.js

@@ -9,10 +9,10 @@
  * @constructor
  **/
 var ToLowerExpression = module.exports = function ToLowerExpression() {
-	this.nargs = 1;
 	base.call(this);
 }, klass = ToLowerExpression,
-	base = require("./NaryExpression"),
+	FixedArityExpression = require("./FixedArityExpressionT")(klass, 1),
+	base = FixedArityExpression,
 	proto = klass.prototype = Object.create(base.prototype, {
 		constructor: {
 			value: klass
@@ -38,4 +38,4 @@ proto.evaluateInternal = function evaluateInternal(vars) {
 };
 
 /** Register Expression */
-Expression.registerExpression("$toLower", base.parse(ToLowerExpression));
+Expression.registerExpression("$toLower", base.parse);

+ 3 - 3
lib/pipeline/expressions/ToUpperExpression.js

@@ -9,10 +9,10 @@
  * @constructor
  **/
 var ToUpperExpression = module.exports = function ToUpperExpression() {
-	this.nargs = 1;
 	base.call(this);
 }, klass = ToUpperExpression,
-	base = require("./NaryExpression"),
+	FixedArityExpression = require("./FixedArityExpressionT")(klass, 1),
+	base = FixedArityExpression,
 	proto = klass.prototype = Object.create(base.prototype, {
 		constructor: {
 			value: klass
@@ -38,4 +38,4 @@ proto.evaluateInternal = function evaluateInternal(vars) {
 };
 
 /** Register Expression */
-Expression.registerExpression("$toUpper", base.parse(ToUpperExpression));
+Expression.registerExpression("$toUpper", base.parse);

+ 3 - 3
lib/pipeline/expressions/WeekExpression.js

@@ -9,10 +9,10 @@
  * @constructor
  **/
 var WeekExpression = module.exports = function WeekExpression() {
-	this.nargs = 1;
 	base.call(this);
 }, klass = WeekExpression,
-	base = require("./NaryExpression"),
+	FixedArityExpression = require("./FixedArityExpressionT")(klass, 1),
+	base = FixedArityExpression,
 	proto = klass.prototype = Object.create(base.prototype, {
 		constructor: {
 			value: klass
@@ -47,4 +47,4 @@ proto.evaluateInternal = function evaluateInternal(vars) {
 };
 
 /** Register Expression */
-Expression.registerExpression("$week", base.parse(WeekExpression));
+Expression.registerExpression("$week", base.parse);

+ 3 - 3
lib/pipeline/expressions/YearExpression.js

@@ -9,10 +9,10 @@
  * @constructor
  **/
 var YearExpression = module.exports = function YearExpression() {
-	this.nargs = 1;
 	base.call(this);
 }, klass = YearExpression,
-	base = require("./NaryExpression"),
+	FixedArityExpression = require("./FixedArityExpressionT")(klass, 1),
+	base = FixedArityExpression,
 	proto = klass.prototype = Object.create(base.prototype, {
 		constructor: {
 			value: klass
@@ -40,4 +40,4 @@ proto.evaluateInternal = function evaluateInternal(vars) {
 };
 
 /** Register Expression */
-Expression.registerExpression("$year", base.parse(YearExpression));
+Expression.registerExpression("$year", base.parse);

+ 37 - 0
test/lib/pipeline/expressions/FixedArityExpressionT.js

@@ -0,0 +1,37 @@
+"use strict";
+
+var assert = require("assert"),
+	FixedArityExpressionT = require("../../../../lib/pipeline/expressions/FixedArityExpressionT");
+
+
+//TODO: refactor these test cases using Expression.parseOperand() or something because these could be a whole lot cleaner...
+module.exports = {
+
+	"FixedArityExpressionT": {
+
+		"constructor()": {
+
+			"should not throw Error when constructing without args": function testConstructor() {
+				assert.doesNotThrow(function () {
+					new FixedArityExpressionT({}, 1);
+				});
+			},
+
+		},
+
+		"#validateArguments": {
+
+			"should not throw when number of args matches the template nArgs": function matches() {
+				var klass = FixedArityExpressionT(String,1),
+					instance = new klass();
+				assert.doesNotThrow(function() {
+					instance.validateArguments(["arg"]);
+				});
+			}
+
+		}
+	}
+};
+
+
+if (!module.parent)(new(require("mocha"))()).ui("exports").reporter("spec").addFile(__filename).run(process.exit);