Переглянути джерело

test: add tests for helper functions

Closes #167
Estevao Soares dos Santos 8 роки тому
батько
коміт
fea64bdd3c
6 змінених файлів з 300 додано та 50 видалено
  1. 47 25
      dist/showdown.js
  2. 0 0
      dist/showdown.js.map
  3. 1 1
      dist/showdown.min.js
  4. 0 0
      dist/showdown.min.js.map
  5. 46 24
      src/helpers.js
  6. 206 0
      test/node/showdown.helpers.js

+ 47 - 25
dist/showdown.js

@@ -1,4 +1,4 @@
-;/*! showdown 27-01-2017 */
+;/*! showdown 28-01-2017 */
 (function(){
 /**
  * Created by Tivie on 13-07-2015.
@@ -509,7 +509,7 @@ if (!showdown.hasOwnProperty('helper')) {
  * @param {string} a
  * @returns {boolean}
  */
-showdown.helper.isString = function isString(a) {
+showdown.helper.isString = function (a) {
   'use strict';
   return (typeof a === 'string' || a instanceof String);
 };
@@ -517,39 +517,22 @@ showdown.helper.isString = function isString(a) {
 /**
  * Check if var is a function
  * @static
- * @param {string} a
+ * @param {*} a
  * @returns {boolean}
  */
-showdown.helper.isFunction = function isFunction(a) {
+showdown.helper.isFunction = function (a) {
   'use strict';
   var getType = {};
   return a && getType.toString.call(a) === '[object Function]';
 };
 
-/**
- * ForEach helper function
- * @static
- * @param {*} obj
- * @param {function} callback
- */
-showdown.helper.forEach = function forEach(obj, callback) {
-  'use strict';
-  if (typeof obj.forEach === 'function') {
-    obj.forEach(callback);
-  } else {
-    for (var i = 0; i < obj.length; i++) {
-      callback(obj[i], i, obj);
-    }
-  }
-};
-
 /**
  * isArray helper function
  * @static
  * @param {*} a
  * @returns {boolean}
  */
-showdown.helper.isArray = function isArray(a) {
+showdown.helper.isArray = function (a) {
   'use strict';
   return a.constructor === Array;
 };
@@ -560,11 +543,50 @@ showdown.helper.isArray = function isArray(a) {
  * @param {*} value The value to check.
  * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
  */
-showdown.helper.isUndefined = function isUndefined(value) {
+showdown.helper.isUndefined = function (value) {
   'use strict';
   return typeof value === 'undefined';
 };
 
+/**
+ * ForEach helper function
+ * Iterates over Arrays and Objects (own properties only)
+ * @static
+ * @param {*} obj
+ * @param {function} callback Accepts 3 params: 1. value, 2. key, 3. the original array/object
+ */
+showdown.helper.forEach = function (obj, callback) {
+  'use strict';
+  // check if obj is defined
+  if (showdown.helper.isUndefined(obj)) {
+    throw new Error('obj param is required');
+  }
+
+  if (showdown.helper.isUndefined(callback)) {
+    throw new Error('callback param is required');
+  }
+
+  if (!showdown.helper.isFunction(callback)) {
+    throw new Error('callback param must be a function/closure');
+  }
+
+  if (typeof obj.forEach === 'function') {
+    obj.forEach(callback);
+  } else if (showdown.helper.isArray(obj)) {
+    for (var i = 0; i < obj.length; i++) {
+      callback(obj[i], i, obj);
+    }
+  } else if (typeof (obj) === 'object') {
+    for (var prop in obj) {
+      if (obj.hasOwnProperty(prop)) {
+        callback(obj[prop], prop, obj);
+      }
+    }
+  } else {
+    throw new Error('obj does not seem to be an array or an iterable object');
+  }
+};
+
 /**
  * Standardidize extension name
  * @static
@@ -573,7 +595,7 @@ showdown.helper.isUndefined = function isUndefined(value) {
  */
 showdown.helper.stdExtName = function (s) {
   'use strict';
-  return s.replace(/[_-]||\s/g, '').toLowerCase();
+  return s.replace(/[_?*+\/\\.^-]/g, '').replace(/\s/g, '').toLowerCase();
 };
 
 function escapeCharactersCallback(wholeMatch, m1) {
@@ -599,7 +621,7 @@ showdown.helper.escapeCharactersCallback = escapeCharactersCallback;
  * @param {boolean} afterBackslash
  * @returns {XML|string|void|*}
  */
-showdown.helper.escapeCharacters = function escapeCharacters(text, charsToEscape, afterBackslash) {
+showdown.helper.escapeCharacters = function (text, charsToEscape, afterBackslash) {
   'use strict';
   // First we have to escape the escape characters so that
   // we can build a character class out of them

Різницю між файлами не показано, бо вона завелика
+ 0 - 0
dist/showdown.js.map


Різницю між файлами не показано, бо вона завелика
+ 1 - 1
dist/showdown.min.js


Різницю між файлами не показано, бо вона завелика
+ 0 - 0
dist/showdown.min.js.map


+ 46 - 24
src/helpers.js

@@ -12,7 +12,7 @@ if (!showdown.hasOwnProperty('helper')) {
  * @param {string} a
  * @returns {boolean}
  */
-showdown.helper.isString = function isString(a) {
+showdown.helper.isString = function (a) {
   'use strict';
   return (typeof a === 'string' || a instanceof String);
 };
@@ -20,39 +20,22 @@ showdown.helper.isString = function isString(a) {
 /**
  * Check if var is a function
  * @static
- * @param {string} a
+ * @param {*} a
  * @returns {boolean}
  */
-showdown.helper.isFunction = function isFunction(a) {
+showdown.helper.isFunction = function (a) {
   'use strict';
   var getType = {};
   return a && getType.toString.call(a) === '[object Function]';
 };
 
-/**
- * ForEach helper function
- * @static
- * @param {*} obj
- * @param {function} callback
- */
-showdown.helper.forEach = function forEach(obj, callback) {
-  'use strict';
-  if (typeof obj.forEach === 'function') {
-    obj.forEach(callback);
-  } else {
-    for (var i = 0; i < obj.length; i++) {
-      callback(obj[i], i, obj);
-    }
-  }
-};
-
 /**
  * isArray helper function
  * @static
  * @param {*} a
  * @returns {boolean}
  */
-showdown.helper.isArray = function isArray(a) {
+showdown.helper.isArray = function (a) {
   'use strict';
   return a.constructor === Array;
 };
@@ -63,11 +46,50 @@ showdown.helper.isArray = function isArray(a) {
  * @param {*} value The value to check.
  * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
  */
-showdown.helper.isUndefined = function isUndefined(value) {
+showdown.helper.isUndefined = function (value) {
   'use strict';
   return typeof value === 'undefined';
 };
 
+/**
+ * ForEach helper function
+ * Iterates over Arrays and Objects (own properties only)
+ * @static
+ * @param {*} obj
+ * @param {function} callback Accepts 3 params: 1. value, 2. key, 3. the original array/object
+ */
+showdown.helper.forEach = function (obj, callback) {
+  'use strict';
+  // check if obj is defined
+  if (showdown.helper.isUndefined(obj)) {
+    throw new Error('obj param is required');
+  }
+
+  if (showdown.helper.isUndefined(callback)) {
+    throw new Error('callback param is required');
+  }
+
+  if (!showdown.helper.isFunction(callback)) {
+    throw new Error('callback param must be a function/closure');
+  }
+
+  if (typeof obj.forEach === 'function') {
+    obj.forEach(callback);
+  } else if (showdown.helper.isArray(obj)) {
+    for (var i = 0; i < obj.length; i++) {
+      callback(obj[i], i, obj);
+    }
+  } else if (typeof (obj) === 'object') {
+    for (var prop in obj) {
+      if (obj.hasOwnProperty(prop)) {
+        callback(obj[prop], prop, obj);
+      }
+    }
+  } else {
+    throw new Error('obj does not seem to be an array or an iterable object');
+  }
+};
+
 /**
  * Standardidize extension name
  * @static
@@ -76,7 +98,7 @@ showdown.helper.isUndefined = function isUndefined(value) {
  */
 showdown.helper.stdExtName = function (s) {
   'use strict';
-  return s.replace(/[_-]||\s/g, '').toLowerCase();
+  return s.replace(/[_?*+\/\\.^-]/g, '').replace(/\s/g, '').toLowerCase();
 };
 
 function escapeCharactersCallback(wholeMatch, m1) {
@@ -102,7 +124,7 @@ showdown.helper.escapeCharactersCallback = escapeCharactersCallback;
  * @param {boolean} afterBackslash
  * @returns {XML|string|void|*}
  */
-showdown.helper.escapeCharacters = function escapeCharacters(text, charsToEscape, afterBackslash) {
+showdown.helper.escapeCharacters = function (text, charsToEscape, afterBackslash) {
   'use strict';
   // First we have to escape the escape characters so that
   // we can build a character class out of them

+ 206 - 0
test/node/showdown.helpers.js

@@ -1,6 +1,10 @@
 /**
  * Created by Estevao on 27/01/2017.
  */
+/*jshint expr: true*/
+/*jshint -W053 */
+/*jshint -W010 */
+/*jshint -W009 */
 var bootstrap = require('../bootstrap.js'),
   showdown = bootstrap.showdown;
 
@@ -27,3 +31,205 @@ describe('encodeEmailAddress()', function () {
     decodedEmail.should.equal(email);
   });
 });
+
+describe('isString()', function () {
+  'use strict';
+  var isString = showdown.helper.isString;
+
+  it('should return true for new String Object', function () {
+    isString(new String('some string')).should.be.true;
+  });
+
+  it('should return true for String Object', function () {
+    isString(String('some string')).should.be.true;
+  });
+
+  it('should return true for string literal', function () {
+    isString('some string').should.be.true;
+  });
+
+  it('should return false for integers', function () {
+    isString(5).should.be.false;
+  });
+
+  it('should return false for random objects', function () {
+    isString({foo: 'bar'}).should.be.false;
+  });
+
+  it('should return false for arrays', function () {
+    isString(['bar']).should.be.false;
+  });
+});
+
+describe('isFunction()', function () {
+  'use strict';
+  var isFunction = showdown.helper.isFunction;
+
+  it('should return true for closures', function () {
+    isFunction(function () {}).should.be.true;
+  });
+
+  it('should return true for defined functions', function () {
+    function foo () {}
+    isFunction(foo).should.be.true;
+  });
+
+  it('should return true for function variables', function () {
+    var bar = function () {};
+    isFunction(bar).should.be.true;
+  });
+
+  it('should return false for hash objects', function () {
+    isFunction({}).should.be.false;
+  });
+
+  it('should return false for objects', function () {
+    isFunction(new Object ()).should.be.false;
+  });
+
+  it('should return false for string primitives', function () {
+    isFunction('foo').should.be.false;
+  });
+});
+
+describe('isArray()', function () {
+  'use strict';
+  var isArray = showdown.helper.isArray;
+
+  it('should return true for short syntax arrays', function () {
+    isArray([]).should.be.true;
+  });
+
+  it('should return true for array objects', function () {
+    var myArr = new Array();
+    isArray(myArr).should.be.true;
+  });
+
+  it('should return false for functions', function () {
+    isArray(function () {}).should.be.false;
+    function baz () {}
+    isArray(baz).should.be.false;
+  });
+
+  it('should return false for objects', function () {
+    isArray({}).should.be.false;
+    isArray(new Object ()).should.be.false;
+  });
+
+  it('should return false for strings', function () {
+    isArray('foo').should.be.false;
+    isArray(new String('foo')).should.be.false;
+  });
+});
+
+describe('isUndefined()', function () {
+  'use strict';
+  var isUndefined = showdown.helper.isUndefined;
+
+  it('should return true if nothing is passed', function () {
+    isUndefined().should.be.true;
+  });
+
+  it('should return true if a variable is initialized but not defined', function () {
+    var myVar;
+    isUndefined(myVar).should.be.true;
+  });
+
+  it('should return false for null', function () {
+    isUndefined(null).should.be.false;
+  });
+
+  it('should return false for 0', function () {
+    isUndefined(0).should.be.false;
+  });
+
+  it('should return false for empty string', function () {
+    isUndefined('').should.be.false;
+  });
+
+  it('should return false for empty booleans false or true', function () {
+    isUndefined(false).should.be.false;
+    isUndefined(true).should.be.false;
+  });
+
+  it('should return false for anything not undefined', function () {
+    isUndefined('foo').should.be.false;
+    isUndefined(2).should.be.false;
+    isUndefined({}).should.be.false;
+  });
+});
+
+describe('stdExtName()', function () {
+  'use strict';
+  var stdExtName = showdown.helper.stdExtName;
+
+  it('should remove certain chars', function () {
+    var str = 'bla_-  \nbla';
+    //[_?*+\/\\.^-]
+    stdExtName(str).should.not.match(/[_?*+\/\\.^-]/g);
+  });
+  it('should make everything lowercase', function () {
+    var str = 'BLABLA';
+    //[_?*+\/\\.^-]
+    stdExtName(str).should.equal('blabla');
+  });
+});
+
+describe('forEach()', function () {
+  'use strict';
+  var forEach = showdown.helper.forEach;
+
+  it('should throw an error if first parameter is undefined', function () {
+    (function () {forEach();}).should.throw('obj param is required');
+  });
+
+  it('should throw an error if second parameter is undefined', function () {
+    (function () {forEach([]);}).should.throw('callback param is required');
+  });
+
+  it('should throw an error if second parameter is not a function', function () {
+    (function () {forEach([], 'foo');}).should.throw('callback param must be a function/closure');
+  });
+
+  it('should throw an error if first parameter is not an object or an array', function () {
+    (function () {forEach('foo', function () {});}).should.throw('obj does not seem to be an array or an iterable object');
+  });
+
+  it('should not throw even if object is empty', function () {
+    (function () {forEach({}, function () {});}).should.not.throw();
+  });
+
+  it('should iterate array items', function () {
+    var myArray = ['banana', 'orange', 'grape'];
+    forEach(myArray, function (val, key, obj) {
+      key.should.be.a('number');
+      (key % 1).should.equal(0);
+      val.should.equal(myArray[key]);
+      obj.should.equal(myArray);
+    });
+  });
+
+  it('should iterate over object properties', function () {
+    var myObj = {foo: 'banana', bar: 'orange', baz: 'grape'};
+    forEach(myObj, function (val, key, obj) {
+      myObj.should.have.ownProperty(key);
+      val.should.equal(myObj[key]);
+      obj.should.equal(myObj);
+    });
+  });
+
+  it('should iterate only over object own properties', function () {
+    var Obj1 = {foo: 'banana'},
+        myObj = Object.create(Obj1);
+    myObj.bar = 'orange';
+    myObj.baz = 'grape';
+
+    myObj.should.have.ownProperty('bar');
+    myObj.should.have.ownProperty('baz');
+    myObj.should.not.have.ownProperty('foo');
+
+    forEach(myObj, function (val, key) {
+      key.should.not.equal('foo');
+    });
+  });
+});

Деякі файли не було показано, через те що забагато файлів було змінено