Permalink
Browse files

[all] Add argscheck module.

This will allow us to check parameter types more succinctly.
https://issues.apache.org/jira/browse/CB-1892
  • Loading branch information...
agrieve committed Nov 22, 2012
1 parent 6798d21 commit 1dfa2ac54a41287279e6726d2b748060e1cc44bf
Showing with 155 additions and 0 deletions.
  1. +74 −0 lib/common/argscheck.js
  2. +81 −0 test/test.argscheck.js
View
@@ -0,0 +1,74 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+var exec = require('cordova/exec');
+var moduleExports = module.exports;
+
+var typeMap = {
+ 'A': 'Array',
+ 'D': 'Date',
+ 'N': 'Number',
+ 'S': 'String',
+ 'F': 'Function',
+ 'O': 'Object'
+};
+
+function extractParamName(callee, argIndex) {
+ return (/.*?\((.*?)\)/).exec(callee)[1].split(', ')[argIndex];
+}
+
+function checkArgs(spec, functionName, args, opt_callee) {
+ if (!moduleExports.enableChecks) {
+ return;
+ }
+ var errMsg = null;
+ var type;
+ for (var i = 0; i < spec.length; ++i) {
+ var c = spec.charAt(i),
+ cUpper = c.toUpperCase(),
+ arg = args[i];
+ // Asterix means allow anything.
+ if (c == '*') {
+ continue;
+ }
+ type = Object.prototype.toString.call(arg).slice(8, -1);
+ if ((arg === null || arg === undefined) && c == cUpper) {
+ continue;
+ }
+ if (type != typeMap[cUpper]) {
+ errMsg = 'Expected ' + typeMap[cUpper];
+ break;
+ }
+ }
+ if (errMsg) {
+ errMsg += ', but got ' + type + '.';
+ errMsg = 'Wrong type for parameter "' + extractParamName(opt_callee || args.callee, i) + '" of ' + functionName + ': ' + errMsg;
+ // Don't log when running jake test.
+ if (typeof jasmine == 'undefined') {
+ console.error(errMsg);
+ }
+ throw TypeError(errMsg);
+ }
+}
+
+moduleExports.checkArgs = checkArgs;
+moduleExports.enableChecks = true;
+
View
@@ -0,0 +1,81 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+describe('argscheck', function() {
+ var argscheck = require('cordova/argscheck');
+
+ function createTestFunc(allowNull) {
+ return function testFunc(num, obj, arr, str, date, func) {
+ var spec = allowNull ? 'NOASDF*' : 'noasdf*';
+ argscheck.checkArgs(spec, 'testFunc', arguments);
+ };
+ }
+ afterEach(function() {
+ argscheck.enableChecks = true;
+ });
+
+ it('should not throw when given valid args', function() {
+ var testFunc = createTestFunc(false);
+ testFunc(0, {}, [], '', new Date(), testFunc, 1);
+ });
+ it('should not throw when given valid optional args', function() {
+ var testFunc = createTestFunc(true);
+ testFunc(0, {}, [], '', new Date(), testFunc, '');
+ });
+ it('should not throw when given missing optional args', function() {
+ var testFunc = createTestFunc(true);
+ testFunc();
+ });
+ it('should not throw when given null optional args', function() {
+ var testFunc = createTestFunc(true);
+ testFunc(null, null, null, null, null, null, null);
+ });
+ it('should throw when given invalid number', function() {
+ var testFunc = createTestFunc(true);
+ expect(function() { testFunc('foo', null, null, null, null, null) }).toThrow('Wrong type for parameter "num" of testFunc: Expected Number, but got String.');
+ });
+ it('should throw when given invalid object', function() {
+ var testFunc = createTestFunc(true);
+ // Do not allow arrays for objects since we're usually dealing with JSON when expecting objects.
+ expect(function() { testFunc(null, [], null, null, null, null) }).toThrow('Wrong type for parameter "obj" of testFunc: Expected Object, but got Array.');
+ });
+ it('should throw when given invalid array', function() {
+ var testFunc = createTestFunc(true);
+ expect(function() { testFunc(null, null, {}, null, null, null) }).toThrow('Wrong type for parameter "arr" of testFunc: Expected Array, but got Object.');
+ });
+ it('should throw when given invalid string', function() {
+ var testFunc = createTestFunc(true);
+ expect(function() { testFunc(null, null, null, 5, null, null) }).toThrow('Wrong type for parameter "str" of testFunc: Expected String, but got Number.');
+ });
+ it('should throw when given invalid date', function() {
+ var testFunc = createTestFunc(true);
+ expect(function() { testFunc(null, null, null, null, 233, null) }).toThrow('Wrong type for parameter "date" of testFunc: Expected Date, but got Number.');
+ });
+ it('should throw when given invalid function', function() {
+ var testFunc = createTestFunc(true);
+ expect(function() { testFunc(null, null, null, null, null, new Date) }).toThrow('Wrong type for parameter "func" of testFunc: Expected Function, but got Date.');
+ });
+ it('should not throw when checking is disabled', function() {
+ var testFunc = createTestFunc(false);
+ argscheck.enableChecks = false;
+ testFunc();
+ });
+});

0 comments on commit 1dfa2ac

Please sign in to comment.