diff --git a/lib/shared/Activator.js b/lib/shared/Activator.js index 5b739cba..a2c74419 100644 --- a/lib/shared/Activator.js +++ b/lib/shared/Activator.js @@ -79,7 +79,11 @@ Activator.prototype.destroy = function () { if (this.onClick) { document.body.removeEventListener('click', this.onClick); } - + // remove keycharm + if (this.keycharm !== undefined) { + this.keycharm.destroy(); + } + this.keycharm = null; // cleanup hammer instances this.hammer.destroy(); this.hammer = null; diff --git a/lib/shared/ColorPicker.js b/lib/shared/ColorPicker.js index 0d875174..e0694fb2 100644 --- a/lib/shared/ColorPicker.js +++ b/lib/shared/ColorPicker.js @@ -2,6 +2,9 @@ let Hammer = require('../module/hammer'); let hammerUtil = require('../hammerUtil'); let util = require('../util'); + +var htmlColors = {black: '#000000', navy: '#000080', darkblue: '#00008B', mediumblue: '#0000CD', blue: '#0000FF', darkgreen: '#006400', green: '#008000', teal: '#008080', darkcyan: '#008B8B', deepskyblue: '#00BFFF', darkturquoise: '#00CED1', mediumspringgreen: '#00FA9A', lime: '#00FF00', springgreen: '#00FF7F', aqua: '#00FFFF', cyan: '#00FFFF', midnightblue: '#191970', dodgerblue: '#1E90FF', lightseagreen: '#20B2AA', forestgreen: '#228B22', seagreen: '#2E8B57', darkslategray: '#2F4F4F', limegreen: '#32CD32', mediumseagreen: '#3CB371', turquoise: '#40E0D0', royalblue: '#4169E1', steelblue: '#4682B4', darkslateblue: '#483D8B', mediumturquoise: '#48D1CC', indigo: '#4B0082', darkolivegreen: '#556B2F', cadetblue: '#5F9EA0', cornflowerblue: '#6495ED', mediumaquamarine: '#66CDAA', dimgray: '#696969', slateblue: '#6A5ACD', olivedrab: '#6B8E23', slategray: '#708090', lightslategray: '#778899', mediumslateblue: '#7B68EE', lawngreen: '#7CFC00', chartreuse: '#7FFF00', aquamarine: '#7FFFD4', maroon: '#800000', purple: '#800080', olive: '#808000', gray: '#808080', skyblue: '#87CEEB', lightskyblue: '#87CEFA', blueviolet: '#8A2BE2', darkred: '#8B0000', darkmagenta: '#8B008B', saddlebrown: '#8B4513', darkseagreen: '#8FBC8F', lightgreen: '#90EE90', mediumpurple: '#9370D8', darkviolet: '#9400D3', palegreen: '#98FB98', darkorchid: '#9932CC', yellowgreen: '#9ACD32', sienna: '#A0522D', brown: '#A52A2A', darkgray: '#A9A9A9', lightblue: '#ADD8E6', greenyellow: '#ADFF2F', paleturquoise: '#AFEEEE', lightsteelblue: '#B0C4DE', powderblue: '#B0E0E6', firebrick: '#B22222', darkgoldenrod: '#B8860B', mediumorchid: '#BA55D3', rosybrown: '#BC8F8F', darkkhaki: '#BDB76B', silver: '#C0C0C0', mediumvioletred: '#C71585', indianred: '#CD5C5C', peru: '#CD853F', chocolate: '#D2691E', tan: '#D2B48C', lightgrey: '#D3D3D3', palevioletred: '#D87093', thistle: '#D8BFD8', orchid: '#DA70D6', goldenrod: '#DAA520', crimson: '#DC143C', gainsboro: '#DCDCDC', plum: '#DDA0DD', burlywood: '#DEB887', lightcyan: '#E0FFFF', lavender: '#E6E6FA', darksalmon: '#E9967A', violet: '#EE82EE', palegoldenrod: '#EEE8AA', lightcoral: '#F08080', khaki: '#F0E68C', aliceblue: '#F0F8FF', honeydew: '#F0FFF0', azure: '#F0FFFF', sandybrown: '#F4A460', wheat: '#F5DEB3', beige: '#F5F5DC', whitesmoke: '#F5F5F5', mintcream: '#F5FFFA', ghostwhite: '#F8F8FF', salmon: '#FA8072', antiquewhite: '#FAEBD7', linen: '#FAF0E6', lightgoldenrodyellow: '#FAFAD2', oldlace: '#FDF5E6', red: '#FF0000', fuchsia: '#FF00FF', magenta: '#FF00FF', deeppink: '#FF1493', orangered: '#FF4500', tomato: '#FF6347', hotpink: '#FF69B4', coral: '#FF7F50', darkorange: '#FF8C00', lightsalmon: '#FFA07A', orange: '#FFA500', lightpink: '#FFB6C1', pink: '#FFC0CB', gold: '#FFD700', peachpuff: '#FFDAB9', navajowhite: '#FFDEAD', moccasin: '#FFE4B5', bisque: '#FFE4C4', mistyrose: '#FFE4E1', blanchedalmond: '#FFEBCD', papayawhip: '#FFEFD5', lavenderblush: '#FFF0F5', seashell: '#FFF5EE', cornsilk: '#FFF8DC', lemonchiffon: '#FFFACD', floralwhite: '#FFFAF0', snow: '#FFFAFA', yellow: '#FFFF00', lightyellow: '#FFFFE0', ivory: '#FFFFF0', white: '#FFFFFF'}; + /** * @param {number} [pixelRatio=1] */ @@ -78,7 +81,6 @@ class ColorPicker { * @private */ _isColorString(color) { - var htmlColors = {black: '#000000',navy: '#000080',darkblue: '#00008B',mediumblue: '#0000CD',blue: '#0000FF',darkgreen: '#006400',green: '#008000',teal: '#008080',darkcyan: '#008B8B',deepskyblue: '#00BFFF',darkturquoise: '#00CED1',mediumspringgreen: '#00FA9A',lime: '#00FF00',springgreen: '#00FF7F',aqua: '#00FFFF',cyan: '#00FFFF',midnightblue: '#191970',dodgerblue: '#1E90FF',lightseagreen: '#20B2AA',forestgreen: '#228B22',seagreen: '#2E8B57',darkslategray: '#2F4F4F',limegreen: '#32CD32',mediumseagreen: '#3CB371',turquoise: '#40E0D0',royalblue: '#4169E1',steelblue: '#4682B4',darkslateblue: '#483D8B',mediumturquoise: '#48D1CC',indigo: '#4B0082',darkolivegreen: '#556B2F',cadetblue: '#5F9EA0',cornflowerblue: '#6495ED',mediumaquamarine: '#66CDAA',dimgray: '#696969',slateblue: '#6A5ACD',olivedrab: '#6B8E23',slategray: '#708090',lightslategray: '#778899',mediumslateblue: '#7B68EE',lawngreen: '#7CFC00',chartreuse: '#7FFF00',aquamarine: '#7FFFD4',maroon: '#800000',purple: '#800080',olive: '#808000',gray: '#808080',skyblue: '#87CEEB',lightskyblue: '#87CEFA',blueviolet: '#8A2BE2',darkred: '#8B0000',darkmagenta: '#8B008B',saddlebrown: '#8B4513',darkseagreen: '#8FBC8F',lightgreen: '#90EE90',mediumpurple: '#9370D8',darkviolet: '#9400D3',palegreen: '#98FB98',darkorchid: '#9932CC',yellowgreen: '#9ACD32',sienna: '#A0522D',brown: '#A52A2A',darkgray: '#A9A9A9',lightblue: '#ADD8E6',greenyellow: '#ADFF2F',paleturquoise: '#AFEEEE',lightsteelblue: '#B0C4DE',powderblue: '#B0E0E6',firebrick: '#B22222',darkgoldenrod: '#B8860B',mediumorchid: '#BA55D3',rosybrown: '#BC8F8F',darkkhaki: '#BDB76B',silver: '#C0C0C0',mediumvioletred: '#C71585',indianred: '#CD5C5C',peru: '#CD853F',chocolate: '#D2691E',tan: '#D2B48C',lightgrey: '#D3D3D3',palevioletred: '#D87093',thistle: '#D8BFD8',orchid: '#DA70D6',goldenrod: '#DAA520',crimson: '#DC143C',gainsboro: '#DCDCDC',plum: '#DDA0DD',burlywood: '#DEB887',lightcyan: '#E0FFFF',lavender: '#E6E6FA',darksalmon: '#E9967A',violet: '#EE82EE',palegoldenrod: '#EEE8AA',lightcoral: '#F08080',khaki: '#F0E68C',aliceblue: '#F0F8FF',honeydew: '#F0FFF0',azure: '#F0FFFF',sandybrown: '#F4A460',wheat: '#F5DEB3',beige: '#F5F5DC',whitesmoke: '#F5F5F5',mintcream: '#F5FFFA',ghostwhite: '#F8F8FF',salmon: '#FA8072',antiquewhite: '#FAEBD7',linen: '#FAF0E6',lightgoldenrodyellow: '#FAFAD2',oldlace: '#FDF5E6',red: '#FF0000',fuchsia: '#FF00FF',magenta: '#FF00FF',deeppink: '#FF1493',orangered: '#FF4500',tomato: '#FF6347',hotpink: '#FF69B4',coral: '#FF7F50',darkorange: '#FF8C00',lightsalmon: '#FFA07A',orange: '#FFA500',lightpink: '#FFB6C1',pink: '#FFC0CB',gold: '#FFD700',peachpuff: '#FFDAB9',navajowhite: '#FFDEAD',moccasin: '#FFE4B5',bisque: '#FFE4C4',mistyrose: '#FFE4E1',blanchedalmond: '#FFEBCD',papayawhip: '#FFEFD5',lavenderblush: '#FFF0F5',seashell: '#FFF5EE',cornsilk: '#FFF8DC',lemonchiffon: '#FFFACD',floralwhite: '#FFFAF0',snow: '#FFFAFA',yellow: '#FFFF00',lightyellow: '#FFFFE0',ivory: '#FFFFF0',white: '#FFFFFF'}; if (typeof color === 'string') { return htmlColors[color]; } @@ -90,7 +92,7 @@ class ColorPicker { * Supported formats: * 'red' --> HTML color string * '#ffffff' --> hex string - * 'rbg(255,255,255)' --> rgb string + * 'rgb(255,255,255)' --> rgb string * 'rgba(255,255,255,1.0)' --> rgba string * {r:255,g:255,b:255} --> rgb object * {r:255,g:255,b:255,a:1.0} --> rgba object @@ -359,7 +361,6 @@ class ColorPicker { ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1); - this.colorPickerCanvas.getContext("2d").setTransform(this.pixelRatio, 0, 0, this.pixelRatio, 0, 0); } diff --git a/lib/shared/Configurator.js b/lib/shared/Configurator.js index 7dcb8b09..0f973430 100644 --- a/lib/shared/Configurator.js +++ b/lib/shared/Configurator.js @@ -66,6 +66,9 @@ class Configurator { this.options.filter = options.join(); } else if (typeof options === 'object') { + if (options == null) { + throw new TypeError('options cannot be null'); + } if (options.container !== undefined) { this.options.container = options.container; } @@ -150,22 +153,7 @@ class Configurator { counter++; } } - - if (this.options.showButton === true) { - let generateButton = document.createElement('div'); - generateButton.className = 'vis-configuration vis-config-button'; - generateButton.innerHTML = 'generate options'; - generateButton.onclick = () => {this._printOptions();}; - generateButton.onmouseover = () => {generateButton.className = 'vis-configuration vis-config-button hover';}; - generateButton.onmouseout = () => {generateButton.className = 'vis-configuration vis-config-button';}; - - this.optionsContainer = document.createElement('div'); - this.optionsContainer.className = 'vis-configuration vis-config-option-container'; - - this.domElements.push(this.optionsContainer); - this.domElements.push(generateButton); - } - + this._makeButton(); this._push(); //~ this.colorPicker.insertTo(this.container); } @@ -383,7 +371,27 @@ class Configurator { this.popupHistory[itemIndex] = popupValue; this._setupPopup(popupString, itemIndex); } + } + /** + * make a button object + * @private + */ + _makeButton() { + if (this.options.showButton === true) { + let generateButton = document.createElement('div'); + generateButton.className = 'vis-configuration vis-config-button'; + generateButton.innerHTML = 'generate options'; + generateButton.onclick = () => {this._printOptions();}; + generateButton.onmouseover = () => {generateButton.className = 'vis-configuration vis-config-button hover';}; + generateButton.onmouseout = () => {generateButton.className = 'vis-configuration vis-config-button';}; + + this.optionsContainer = document.createElement('div'); + this.optionsContainer.className = 'vis-configuration vis-config-option-container'; + + this.domElements.push(this.optionsContainer); + this.domElements.push(generateButton); + } } diff --git a/lib/util.js b/lib/util.js index ab23f6af..41549de0 100644 --- a/lib/util.js +++ b/lib/util.js @@ -30,25 +30,6 @@ exports.recursiveDOMDelete = function (DOMobject) { } }; -/** - * this function gives you a range between 0 and 1 based on the min and max values in the set, the total sum of all values and the current value. - * - * @param {number} min - * @param {number} max - * @param {number} total - * @param {number} value - * @returns {number} - */ -exports.giveRange = function (min, max, total, value) { - if (max == min) { - return 0.5; - } - else { - var scale = 1 / (max - min); - return Math.max(0, (value - min) * scale); - } -}; - /** * Test whether given object is a string * @param {*} object @@ -82,29 +63,13 @@ exports.isDate = function (object) { }; /** - * Create a semi UUID - * source: http://stackoverflow.com/a/105074/1262753 + * Create a UUID * @return {string} uuid */ exports.randomUUID = function () { return uuid.v4(); }; -/** - * assign all keys of an object that are not nested objects to a certain value (used for color objects). - * @param {object} obj - * @param {number} value - */ -exports.assignAllKeys = function (obj, value) { - for (var prop in obj) { - if (obj.hasOwnProperty(prop)) { - if (typeof obj[prop] !== 'object') { - obj[prop] = value; - } - } - } -}; - /** * Copy property from b to a if property present in a. @@ -1272,7 +1237,7 @@ exports.insertSort = function (a,compare) { a[j] = k; } return a; -} +}; /** @@ -1592,8 +1557,6 @@ exports.topMost = function (pile, accessors) { for (let i = 1; i < accessors.length; i++){ if (candidate) { candidate = candidate[accessors[i]] - } else { - continue; } } if (typeof candidate != 'undefined') { diff --git a/package.json b/package.json index b40222c9..b92d607e 100644 --- a/package.json +++ b/package.json @@ -67,6 +67,7 @@ "mocha": "^3.4.2", "nyc": "^11.2.1", "rimraf": "^2.6.1", + "sinon": "^4.0.1", "test-console": "^1.0.0", "uglify-js": "^2.8.29", "uuid": "^3.1.0", diff --git a/test/Activator.test.js b/test/Activator.test.js new file mode 100644 index 00000000..a589a992 --- /dev/null +++ b/test/Activator.test.js @@ -0,0 +1,90 @@ +var assert = require('assert'); +var sinon = require('sinon'); +var jsdom = require('jsdom'); +var jsdom_global = require('jsdom-global'); + + +var canvasMockify = require('./canvas-mock'); +var Activator = require('../lib/shared/Activator'); + + +describe('Activator', function () { + beforeEach(function() { + this.jsdom_global = canvasMockify("
"); + this.container = document.getElementById('mynetwork'); + }); + + afterEach(function() { + this.jsdom_global(); + this.container.remove(); + this.container = undefined; + }); + + describe('constructor', function () { + + it('sets defaults', function () { + var activator = new Activator(this.container); + assert.equal(activator.active, false); + }); + + it('creates overlay', function () { + var activator = new Activator(this.container); + assert.equal(activator.dom.container.children[0].className, 'vis-overlay'); + }); + }); + + describe('activate', function () { + it('emits an `activate` event', function () { + var eventSpy = sinon.spy(); + var activator = new Activator(this.container); + activator.on('activate', eventSpy); + activator.activate(); + assert.equal(activator.active, true); + assert(eventSpy.called, 'Event did not fire.'); + assert(eventSpy.calledOnce, 'Event fired more than once'); + }); + + it('emits a `change` event', function () { + var eventSpy = sinon.spy(); + var activator = new Activator(this.container); + activator.on('change', eventSpy); + activator.activate(); + assert.equal(activator.active, true); + assert(eventSpy.called, 'Event did not fire.'); + assert(eventSpy.calledOnce, 'Event fired more than once'); + }); + }); + + describe('deactivate', function () { + it('emits a `deactivate` event', function () { + var eventSpy = sinon.spy(); + var activator = new Activator(this.container); + activator.on('deactivate', eventSpy); + activator.deactivate(); + assert.equal(activator.active, false); + assert(eventSpy.called, 'Event did not fire.'); + assert(eventSpy.calledOnce, 'Event fired more than once'); + }); + + it('emits a `change` event', function () { + var eventSpy = sinon.spy(); + var activator = new Activator(this.container); + activator.on('change', eventSpy); + activator.deactivate(); + assert.equal(activator.active, false); + assert(eventSpy.called, 'Event did not fire.'); + assert(eventSpy.calledOnce, 'Event fired more than once'); + }); + }); + + describe('destroy', function () { + + it('sets inactive, removes keycharm, and removes hammer', function () { + var activator = new Activator(this.container); + activator.destroy(); + assert.equal(activator.active, false); + assert.equal(activator.keycharm, null); + assert.equal(activator.hammer, null); + }); + }); +}); diff --git a/test/ColorPicker.test.js b/test/ColorPicker.test.js new file mode 100644 index 00000000..efa4c344 --- /dev/null +++ b/test/ColorPicker.test.js @@ -0,0 +1,224 @@ +var assert = require('assert'); +var sinon = require('sinon'); +var jsdom_global = require('jsdom-global'); + +var canvasMockify = require('./canvas-mock'); +var ColorPicker = require('../lib/shared/ColorPicker').default; + +describe('ColorPicker', function () { + beforeEach(function() { + this.jsdom_global = canvasMockify("
"); + this.container = document.getElementById('mynetwork'); + }); + + afterEach(function() { + this.jsdom_global(); + this.container.remove(); + this.container = undefined; + }); + + describe('constructor', function () { + + it('sets defaults', function () { + var colorPicker = new ColorPicker(); + assert.equal(colorPicker.pixelRatio, 1); + assert.equal(colorPicker.generated, false); + assert.deepEqual(colorPicker.centerCoordinates, {x:289/2, y:289/2}); + assert.equal(colorPicker.r, 289 * 0.49); + assert.deepEqual(colorPicker.color, {r:255,g:255,b:255,a:1.0}); + assert.equal(colorPicker.hueCircle, undefined); + assert.deepEqual(colorPicker.initialColor, {r:255,g:255,b:255,a:1.0}); + assert.equal(colorPicker.previousColor, undefined); + assert.equal(colorPicker.applied, false); + }); + + // TODO: This gets overridden during instantiation - Is this a bug? + xit('can overwrite default pixelRation', function () { + var colorPicker = new ColorPicker(777); + assert.equal(colorPicker.pixelRatio, 777); + }); + + }); + + describe('insertTo', function () { + + it('inserts the colorPicker into a div from the DOM', function () { + var colorPicker = new ColorPicker(); + colorPicker.insertTo(this.container); + assert.equal(colorPicker.container, this.container); + assert.equal(this.container.children[this.container.children.length-1], colorPicker.frame); + }); + }); + + describe('setUpdateCallback', function () { + + it('prevents non-functions from being set as callback', function () { + var colorPicker = new ColorPicker(); + assert.throws(function () {colorPicker.setUpdateCallback(null);}, Error, null); + assert.throws(function () {colorPicker.setUpdateCallback(undefined);}, Error, null); + assert.throws(function () {colorPicker.setUpdateCallback([1, 2, 3]);}, Error, null); + assert.throws(function () {colorPicker.setUpdateCallback({a: 42});}, Error, null); + assert.throws(function () {colorPicker.setUpdateCallback(42);}, Error, null); + assert.throws(function () {colorPicker.setUpdateCallback('meow');}, Error, null); + }); + }); + + describe('setCloseCallback', function () { + + it('prevents non-functions from being set as callback', function () { + var colorPicker = new ColorPicker(); + assert.throws(function () {colorPicker.setCloseCallback(null);}, Error, null); + assert.throws(function () {colorPicker.setCloseCallback(undefined);}, Error, null); + assert.throws(function () {colorPicker.setCloseCallback([1, 2, 3]);}, Error, null); + assert.throws(function () {colorPicker.setCloseCallback({a: 42});}, Error, null); + assert.throws(function () {colorPicker.setCloseCallback(42);}, Error, null); + assert.throws(function () {colorPicker.setCloseCallback('meow');}, Error, null); + }); + }); + + describe('_hide', function () { + + it('runs updateCallback when applied', function () { + var callback = sinon.spy(); + var colorPicker = new ColorPicker(); + var colorBeforeHide = colorPicker.color; + colorPicker.setUpdateCallback(callback); + colorPicker.applied = true; + colorPicker._hide(); + assert.equal(callback.callCount, 1); + assert.deepEqual(colorBeforeHide, colorPicker.previousColor); + }); + + it('does not run updateCallback when not applied', function () { + var callback = sinon.spy(); + var colorPicker = new ColorPicker(); + var colorBeforeHide = colorPicker.color; + colorPicker.setUpdateCallback(callback); + colorPicker.applied = false; + colorPicker._hide(); + assert.equal(callback.callCount, 0); + assert.deepEqual(colorBeforeHide, colorPicker.previousColor); + }); + + it('does not set previous color when storePrevious is false', function () { + var colorPicker = new ColorPicker(); + colorPicker._hide(false); + assert.deepEqual(colorPicker.previousColor, undefined); + }); + }); + + describe('_isColorString', function () { + + it('returns color code when color is found', function () { + var colorPicker = new ColorPicker(); + var color = colorPicker._isColorString('black'); + assert.equal(color, '#000000'); + }); + + it('returns undefined when color is not found', function () { + var colorPicker = new ColorPicker(); + var color = colorPicker._isColorString('zing!'); + assert.equal(color, undefined); + }); + }); + + describe('setColor', function () { + + it('does not change when \'none\'', function () { + var colorPicker = new ColorPicker(); + colorPicker.setColor('none'); + assert.deepEqual(colorPicker.color, { r: 255, g: 255, b: 255, a: 1 }); + }); + + it('throws error when color is a bad value', function () { + var colorPicker = new ColorPicker(); + assert.throws(function () {colorPicker.setColor(null);}, Error, null); + assert.throws(function () {colorPicker.setColor(undefined);}, Error, null); + assert.throws(function () {colorPicker.setColor([1, 2, 3]);}, Error, null); + assert.throws(function () {colorPicker.setColor({a: 42});}, Error, null); + assert.throws(function () {colorPicker.setColor(42);}, Error, null); + assert.throws(function () {colorPicker.setColor('meow');}, Error, null); + }); + + it('handles html color string', function () { + var colorPicker = new ColorPicker(); + colorPicker.setColor('black'); + assert.deepEqual(colorPicker.color, { r: 0, g: 0, b: 0, a: 1 }); + }); + + it('handles hex string', function () { + var colorPicker = new ColorPicker(); + colorPicker.setColor('#ffff00'); + assert.deepEqual(colorPicker.color, { r: 255, g: 255, b: 0, a: 1 }); + }); + + it('handles rgb string', function () { + var colorPicker = new ColorPicker(); + colorPicker.setColor('rgb(255,255,255)'); + assert.deepEqual(colorPicker.color, { r: 255, g: 255, b: 255, a: 1 }); + }); + + it('handles rgba string', function () { + var colorPicker = new ColorPicker(); + colorPicker.setColor('rgba(255,255,255,1)'); + assert.deepEqual(colorPicker.color, { r: 255, g: 255, b: 255, a: 1 }); + }); + + it('handles rgb object', function () { + var colorPicker = new ColorPicker(); + colorPicker.setColor({r:255,g:255,b:255}); + assert.deepEqual(colorPicker.color, { r: 255, g: 255, b: 255, a: 1 }); + }); + + it('handles rgba object', function () { + var colorPicker = new ColorPicker(); + colorPicker.setColor({r:255,g:255,b:255,a:1}); + assert.deepEqual(colorPicker.color, { r: 255, g: 255, b: 255, a: 1 }); + }); + }); + + describe('show', function () { + + it('calls closeCallback', function () { + var colorPicker = new ColorPicker(); + var callback = sinon.spy(); + colorPicker.setCloseCallback(callback); + colorPicker.show(); + assert(callback.called); + assert(callback.calledOnce); + assert(colorPicker.generated) + }); + + it('resets applied state and frame display style to `block`', function () { + var colorPicker = new ColorPicker(); + colorPicker.show(); + assert.equal(colorPicker.applied, false); + assert.equal(colorPicker.frame.style.display, 'block'); + assert(colorPicker.generated) + }); + }); + + describe('_save', function () { + + it('triggers updateCallback', function () { + var colorPicker = new ColorPicker(); + var callback = sinon.spy(); + colorPicker.setUpdateCallback(callback); + colorPicker._save(); + assert(callback.called); + assert(callback.calledOnce); + }); + }); + + describe('_apply', function () { + + it('triggers updateCallback', function () { + var colorPicker = new ColorPicker(); + var callback = sinon.spy(); + colorPicker.setUpdateCallback(callback); + colorPicker._apply(); + assert(callback.called); + assert(callback.calledOnce); + }); + }); +}); diff --git a/test/Configurator.test.js b/test/Configurator.test.js new file mode 100644 index 00000000..69cb199e --- /dev/null +++ b/test/Configurator.test.js @@ -0,0 +1,137 @@ +var assert = require('assert'); +var jsdom_global = require('jsdom-global'); + +var canvasMockify = require('./canvas-mock'); +var Configurator = require('../lib/shared/Configurator').default; +var Network = require('../lib/network/Network'); +var {allOptions, configureOptions} = require('../lib/network/options.js'); + +describe('Configurator', function () { + beforeEach(function() { + this.jsdom_global = canvasMockify("
"); + this.container = document.getElementById('mynetwork'); + }); + + afterEach(function() { + this.jsdom_global(); + this.container.remove(); + this.container = undefined; + }); + + describe('constructor', function () { + + it('sets extends options with default options', function () { + var config = new Configurator(); + assert.deepEqual(config.options, config.defaultOptions); + }); + }); + + describe('setOptions', function () { + + it('with undefined will not modify defaults', function () { + var config = new Configurator(Network, this.container); + config.setOptions(); + assert.deepEqual(config.options, config.defaultOptions); + }); + + it('with undefined will set enabled to false', function () { + var config = new Configurator(Network, this.container); + config.options.enabled = false; + config.setOptions(); + assert.equal(config.options.enabled, false); + }); + + it('with string sets filter and set enabled to true', function () { + var config = new Configurator(Network, this.container); + config.setOptions('stringFilter!'); + assert.equal(config.options.filter, 'stringFilter!'); + assert.equal(config.options.enabled, true); + }); + + it('with array sets filter and set enabled to true', function () { + var config = new Configurator(Network, this.container); + config.setOptions(['array', 'Filter', '!']); + assert.equal(config.options.filter, 'array,Filter,!'); + assert.equal(config.options.enabled, true); + }); + + it('with object sets filter', function () { + var config = new Configurator(Network, this.container); + config.setOptions( + {container: 'newContainer', + filter: 'newFilter', + showButton: 'newShowButton', + enabled: false + }); + assert.equal(config.options.container, 'newContainer'); + assert.equal(config.options.filter, 'newFilter'); + assert.equal(config.options.showButton, 'newShowButton'); + assert.equal(config.options.enabled, false); + }); + + it('with object and filter is false enabled will be false', function () { + var config = new Configurator(Network, this.container); + config.setOptions({filter: false}); + assert.equal(config.options.enabled, false); + }); + + it('with boolean true sets filter', function () { + var config = new Configurator(Network, this.container); + config.setOptions(true); + assert.equal(config.options.enabled, true); + }); + + it('with boolean false sets filter', function () { + var config = new Configurator(Network, this.container); + config.setOptions(false); + assert.equal(config.options.enabled, false); + }); + + it('with function sets filter', function () { + var config = new Configurator(Network, this.container); + config.setOptions(function () {}); + assert.equal(config.options.enabled, true); + }); + + it('with null raises exception', function () { + var config = new Configurator(Network, this.container); + assert.throws(function () {config.setOptions(null)}, TypeError, null); + }); + + }); + + describe('setModuleOptions', function () { + + it('creates no new dom elements if enabled is false', function () { + var config = new Configurator(Network, this.container); + config.setModuleOptions(); + assert.equal(this.container.children.length, 0); + }); + + it('adds div with vis-configuration-wrapper class when enabled', function () { + var config = new Configurator(Network, this.container); + config.options.enabled = true; + config.setModuleOptions(); + assert.equal(this.container.children.length, 1); + assert.equal(this.container.children[0].className, 'vis-configuration-wrapper'); + }); + + it('overwrites config.container with config.options.container', function () { + var config = new Configurator(Network, this.container); + config.options.enabled = true; + config.options.container = document.getElementById('other'); + config.setModuleOptions(); + assert.equal(config.container, config.options.container); + assert.equal(config.container.children[0].className, 'vis-configuration-wrapper'); + }); + }); + + // TODO: This test needs work + describe('getOptions', function () { + + xit('creates no new dom elements if enabled is false', function () { + var config = new Configurator(Network, this.container, configureOptions); + var options = config.getOptions(); + }); + }); +}); diff --git a/test/DataSet.test.js b/test/DataSet.test.js index 2d88c054..372ad2d8 100644 --- a/test/DataSet.test.js +++ b/test/DataSet.test.js @@ -181,10 +181,15 @@ describe('DataSet', function () { {_id: 2, content: 'Item 2', start: now.toISOString()} ], {fieldId: '_id'}); assert.deepEqual(data.getIds(), [1, 2]); + }); - // TODO: extensively test DataSet - // TODO: test subscribing to events + it('constructor should prevent duplicate ids', function () { + assert.throws(function () { new DataSet([{id: 'duplicate'}, {id: 'duplicate'}]) }, Error, "duplicate id throws error"); + }); + it('add should prevent duplicate ids', function () { + var dataset = new DataSet([{id: 'duplicate'}]); + assert.throws(function () { dataset.add({id: 'duplicate'}) }, Error, "duplicate id throws error"); }); it('should queue and flush changes', function () { @@ -398,4 +403,87 @@ describe('DataSet', function () { assert.equal(count, 1); }); }); + + describe('min', function () { + + it('finds the minimum value', function () { + var dataset = new DataSet([{id: 1}, {id: 2}, {id: 3}]); + var minValue = dataset.min('id'); + assert.deepEqual(minValue, {id: 1}); + }); + + it('returns null for empty dataset', function () { + var dataset = new DataSet([]); + var minValue = dataset.min('id'); + assert.equal(minValue, null); + }); + + it('handles undefined values', function () { + var dataset = new DataSet([{id: undefined}, {id: 1}, {id: 2}, {id: 3}]); + var minValue = dataset.min('id'); + assert.deepEqual(minValue, {id: 1}); + }); + + it('handles big values', function () { + var dataset = new DataSet([{id: 10000000000000001}, {id: 10000000000000002}, {id: 10000000000000003}]); + var minValue = dataset.min('id'); + assert.deepEqual(minValue, {id: 10000000000000001}); + }); + }); + + + describe('max', function () { + + it('finds the maximum value', function () { + var dataset = new DataSet([{id: 1}, {id: 2}, {id: 3}]); + var maxValue = dataset.max('id'); + assert.deepEqual(maxValue, {id: 3}); + }); + + it('returns null for empty dataset', function () { + var dataset = new DataSet([]); + var maxValue = dataset.max('id'); + assert.equal(maxValue, null); + }); + + it('handles undefined values', function () { + var dataset = new DataSet([{id: undefined}, {id: 1}, {id: 2}, {id: 3}]); + var maxValue = dataset.max('id'); + assert.deepEqual(maxValue, {id: 3}); + }); + }); + + describe('distinct', function () { + + it('finds distinct values', function () { + var dataset = new DataSet([{val: 1}, {val: 2}, {val: 3}]); + var distinctValues = dataset.distinct('val'); + assert.deepEqual(distinctValues, [1, 2, 3]); + }); + + it('returns empty list for empty dataset', function () { + var dataset = new DataSet([]); + var distinctValues = dataset.distinct('val'); + assert.deepEqual(distinctValues, []); + }); + + it('handles undefined values', function () { + var dataset = new DataSet([{val: undefined}, {val: 1}, {val: 2}, {val: 3}]); + var distinctValues = dataset.distinct('val'); + assert.deepEqual(distinctValues, [1, 2, 3]); + }); + + it('handles duplicate values', function () { + var dataset = new DataSet([{val: 1}, {val: 1}, {val: 2}, {val: 3}]); + var distinctValues = dataset.distinct('val'); + assert.deepEqual(distinctValues, [1, 2, 3]); + }); + }); + + describe('getDataSet', function () { + it('returns this', function () { + var dataset = new DataSet([{val: 1}, {val: 2}, {val: 3}]); + assert.equal(dataset, dataset.getDataSet()); + }); + }); }); diff --git a/test/Popup.test.js b/test/Popup.test.js new file mode 100644 index 00000000..f4fac1ea --- /dev/null +++ b/test/Popup.test.js @@ -0,0 +1,142 @@ +var assert = require('assert'); +var jsdom_global = require('jsdom-global'); + +var canvasMockify = require('./canvas-mock'); +var Popup = require('../lib/shared/Popup').default; + + +describe('Popup', function () { + beforeEach(function() { + this.jsdom_global = canvasMockify("
"); + this.container = document.getElementById('mynetwork'); + }); + + afterEach(function() { + this.jsdom_global(); + this.container.remove(); + this.container = undefined; + }); + + describe('constructor', function () { + + it('defaults overflowMethod to "cap"', function () { + var popup = new Popup(this.container); + assert.equal(popup.overflowMethod, 'cap'); + }); + + it('defaults hidden to false', function () { + var popup = new Popup(this.container); + assert.equal(popup.hidden, false); + }); + }); + + describe('setPosition', function () { + + it('handles ints', function () { + var popup = new Popup(this.container); + popup.setPosition(1, 2); + assert.equal(popup.x, 1); + assert.equal(popup.y, 2); + }); + + it('handles strings', function () { + var popup = new Popup(this.container); + popup.setPosition('1', '2'); + assert.equal(popup.x, 1); + assert.equal(popup.y, 2); + }); + + it('handles null with NaN', function () { + var popup = new Popup(this.container); + popup.setPosition(null, null); + assert(isNaN(popup.x)); + assert(isNaN(popup.y)); + }); + + it('handles undefined with NaN', function () { + var popup = new Popup(this.container); + popup.setPosition(undefined, undefined); + assert(isNaN(popup.x)); + assert(isNaN(popup.y)); + }); + }); + + describe('setText', function () { + + it('using Element replaces innerHTML', function () { + var popup = new Popup(this.container); + popup.frame.innerHTML = '
This will get cleared!
'; + popup.setText(document.createElement('div')); + assert.equal(popup.frame.innerHTML, '
'); + }); + + it('using string replaces innerHTML', function () { + var popup = new Popup(this.container); + popup.frame.innerHTML = '
This will get cleared!
'; + popup.setText('your text here!'); + assert.equal(popup.frame.innerHTML, 'your text here!'); + }); + }); + + describe('show', function () { + + it('set to undefined will show', function () { + var popup = new Popup(this.container); + popup.show(undefined); + assert.equal(popup.hidden, false); + assert.notEqual(popup.frame.style.left, "0px"); + assert.notEqual(popup.frame.style.top, "0px"); + assert.equal(popup.frame.style.visibility, "visible"); + }); + + it('set to true will show', function () { + var popup = new Popup(this.container); + popup.show(true); + assert.equal(popup.hidden, false); + assert.notEqual(popup.frame.style.left, "0px"); + assert.notEqual(popup.frame.style.top, "0px"); + assert.equal(popup.frame.style.visibility, "visible"); + }); + + it('set to true with overflowMethod "flip" will show', function () { + var popup = new Popup(this.container, 'flip'); + popup.show(true); + assert.equal(popup.hidden, false); + assert.equal(popup.frame.style.left, "0px"); + assert.equal(popup.frame.style.top, "0px"); + assert.equal(popup.frame.style.visibility, "visible"); + }); + + it('set to false will hide', function () { + var popup = new Popup(this.container); + popup.show(false); + assert.equal(popup.hidden, true); + assert.equal(popup.frame.style.left, "0px"); + assert.equal(popup.frame.style.top, "0px"); + assert.equal(popup.frame.style.visibility, "hidden"); + }); + }); + + describe('hide', function () { + + it('sets hidden to true, frame style to 0,0 and visibility to hidden', function () { + var popup = new Popup(this.container); + popup.hide(); + assert.equal(popup.hidden, true); + assert.equal(popup.frame.style.left, "0px"); + assert.equal(popup.frame.style.top, "0px"); + assert.equal(popup.frame.style.visibility, "hidden"); + }); + }); + + describe('destroy', function () { + + it('removes frame from container', function () { + assert.equal(this.container.children.length, 0); + var popup = new Popup(this.container); + assert.equal(this.container.children.length, 1); + popup.destroy(); + assert.equal(this.container.children.length, 0); + }); + }); +}); diff --git a/test/canvas-mock.js b/test/canvas-mock.js index e75cab4d..9ea5c535 100644 --- a/test/canvas-mock.js +++ b/test/canvas-mock.js @@ -24,6 +24,7 @@ function replaceCanvasContext (el) { setTransform: function(){}, drawImage: function(){}, save: function(){}, + text: function(){}, fillText: function(){}, restore: function(){}, beginPath: function(){}, @@ -34,6 +35,7 @@ function replaceCanvasContext (el) { translate: function(){}, scale: function(){}, rotate: function(){}, + circle: function(){}, arc: function(){}, fill: function(){}, @@ -46,10 +48,10 @@ function replaceCanvasContext (el) { width: 12*text.length, height: 14 }; - }, + } }; } -}; +} /** @@ -61,7 +63,7 @@ function replaceCanvasContext (el) { * The override is only done if there is no 2D context already present. * This allows for normal running in a browser, and for node.js the usage of 'canvas'. * - * @param {object} the current global window object. This can possibly come from module 'jsdom', + * @param {object} window - current global window object. This can possibly come from module 'jsdom', * when running under node.js. * @private */ @@ -94,7 +96,7 @@ function overrideCreateElement(window) { /** * Initialize the mock, jsdom and jsdom_global for unit test usage. * - * Suppresses a warning from `jsdom` on usage of `getContext()`. A mock definition is added for + * Suppresses a warning from `jsdom` on usage of `getContext()`. A mock definition is added for * it, so the message is not relevant. * * @param {string} [html=''] html definitions which should be added to the jsdom definition @@ -105,7 +107,7 @@ function mockify(html = '') { let msg = 'Error: Not implemented: HTMLCanvasElement.prototype.getContext' + ' (without installing the canvas npm package)'; - // Override default virtual console of jsdom + // Override default virtual console of jsdom const virtualConsole = new jsdom.VirtualConsole(); // Set up a simple 'mock' console output. Only 'error' needs to be overridden diff --git a/test/util.test.js b/test/util.test.js index c5d7fc28..49159f67 100644 --- a/test/util.test.js +++ b/test/util.test.js @@ -1,6 +1,8 @@ +var jsdom_global = require('jsdom-global'); var assert = require('assert'); var util = require('../lib/util'); - +var moment = require('../lib//module/moment'); +var ASPDateRegex = /^\/?Date\((\-?\d+)/i; describe('util', function () { @@ -468,4 +470,432 @@ describe('mergeOptions', function () { }); }); // mergeOptions -}); // util + + describe('recursiveDOMDelete', function () { + beforeEach(function() { + this.jsdom_global = jsdom_global(); + }); + + afterEach(function() { + this.jsdom_global(); + }); + + it('removes children', function () { + var root = document.createElement("div"); + // Create children for root + var parent = document.createElement("div"); + var parentSibiling = document.createElement("div"); + // Attach parents to root + root.appendChild(parent); + root.appendChild(parentSibiling); + // Create children for the respective parents + var child = document.createElement("div"); + var childSibling = document.createElement("div"); + // Attach children to parents + parent.appendChild(child); + parentSibiling.appendChild(childSibling); + + util.recursiveDOMDelete(root); + assert.equal(root.children.length, 0); + assert.equal(parent.children.length, 0); + assert.equal(parentSibiling.children.length, 0); + assert.equal(child.children.length, 0); + assert.equal(childSibling.children.length, 0); + }); + }); + + describe('isDate', function () { + it('identifies a Date', function () { + assert(util.isDate(new Date())); + }); + + it('identifies an ASPDate as String', function () { + assert(util.isDate('Date(1198908717056)')); + }); + + it('identifies a date string', function () { + assert(util.isDate('1995-01-01')); + }); + + it('identifies a date string', function () { + assert.equal(util.isDate(''), false); + }); + + it('identifies non-dates', function () { + assert.equal(util.isDate(null), false); + assert.equal(util.isDate(undefined), false); + assert.equal(util.isDate([1, 2, 3]), false); + assert.equal(util.isDate({a: 42}), false); + assert.equal(util.isDate(42), false); + assert.equal(util.isDate('meow'), false); + }); + }); + + describe('convert', function () { + it('handles null', function () { + assert.equal(util.convert(null), null); + }); + + it('handles undefined', function () { + assert.equal(util.convert(undefined), undefined); + }); + + it('undefined type returns original object', function () { + assert.deepEqual(util.convert({}), {}); + }); + + it('non-string type throws', function () { + assert.throws(function () {util.convert({}, {});}, Error, null); + }); + + it('converts to boolean', function () { + assert(util.convert({}, 'boolean')); + }); + + it('converts to number', function () { + assert.equal(typeof util.convert('1198908717056', 'number'), "number"); + }); + + it('converts to String', function () { + assert.equal(typeof util.convert({}, 'string'), "string"); + }); + + it('converts to Date from Number', function () { + assert(util.convert(1198908717056, 'Date') instanceof Date); + }); + + it('converts to Date from String', function () { + assert(util.convert('1198908717056', 'Date') instanceof Date); + }); + + it('converts to Date from Moment', function () { + assert(util.convert(new moment(), 'Date') instanceof Date); + }); + + it('throws when converting unknown object to Date', function () { + assert.throws(function () {util.convert({}, 'Date');}, Error, null); + }); + + xit('converts to Moment from Numbern - Throws a deprecation warning', function () { + assert(util.convert(1198908717056, 'Moment') instanceof moment); + }); + + it('converts to Moment from String', function () { + assert(util.convert('1198908717056', 'Moment') instanceof moment); + }); + + it('converts to Moment from Date', function () { + assert(util.convert(new Date(), 'Moment') instanceof moment); + }); + + it('converts to Moment from Moment', function () { + assert(util.convert(new moment(), 'Moment') instanceof moment); + }); + + it('throws when converting unknown object to Moment', function () { + assert.throws(function () {util.convert({}, 'Moment');}, Error, null); + }); + + it('converts to ISODate from Number', function () { + assert(util.convert(1198908717056, 'ISODate') instanceof Date); + }); + + it('converts to ISODate from String', function () { + assert.equal(typeof util.convert('1995-01-01', 'ISODate'), 'string'); + }); + + it('converts to ISODate from Date - Throws a deprecation warning', function () { + assert.equal(typeof util.convert(new Date(), 'ISODate'), 'string'); + }); + + it('converts to ISODate from Moment', function () { + assert.equal(typeof util.convert(new moment(), 'ISODate'), 'string'); + }); + + it('throws when converting unknown object to ISODate', function () { + assert.throws(function () {util.convert({}, 'ISODate');}, Error, null); + }); + + it('converts to ASPDate from Number', function () { + assert(ASPDateRegex.test(util.convert(1198908717056, 'ASPDate'))); + }); + + it('converts to ASPDate from String', function () { + assert(ASPDateRegex.test(util.convert('1995-01-01', 'ASPDate'))); + }); + + it('converts to ASPDate from Date', function () { + assert(ASPDateRegex.test(util.convert(new Date(), 'ASPDate'))); + }); + + it('converts to ASPDate from ASPDate', function () { + assert(ASPDateRegex.test(util.convert('/Date(12344444)/', 'ASPDate'))); + }); + + xit('converts to ASPDate from Moment - skipped, because it fails', function () { + assert(ASPDateRegex.test(util.convert(new moment(), 'ASPDate'))); + }); + + it('throws when converting unknown object to ASPDate', function () { + assert.throws(function () {util.convert({}, 'ASPDate');}, Error, null); + }); + + it('throws when converting unknown type', function () { + assert.throws(function () {util.convert({}, 'UnknownType');}, Error, null); + }); + }); + + describe('getType', function () { + + it('of object null is null', function () { + assert.equal(util.getType(null), 'null'); + }); + + it('of object Boolean is Boolean', function () { + function Tester () {} + Tester.prototype = Object.create(Boolean.prototype); + assert.equal(util.getType(new Tester('true')), 'Boolean'); + }); + + it('of object Number is Number', function () { + function Tester () {} + Tester.prototype = Object.create(Number.prototype); + assert.equal(util.getType(new Tester(1)), 'Number'); + }); + + it('of object String is String', function () { + function Tester () {} + Tester.prototype = Object.create(String.prototype); + assert.equal(util.getType(new Tester('stringy!')), 'String'); + }); + + it('of object Array is Array', function () { + assert.equal(util.getType(new Array([])), 'Array'); + }); + + it('of object Date is Date', function () { + assert.equal(util.getType(new Date()), 'Date'); + }); + + it('of object any other type is Object', function () { + assert.equal(util.getType({}), 'Object'); + }); + + it('of number is Number', function () { + assert.equal(util.getType(1), 'Number'); + }); + + it('of boolean is Boolean', function () { + assert.equal(util.getType(true), 'Boolean'); + }); + + it('of string is String', function () { + assert.equal(util.getType('string'), 'String'); + }); + + it('of undefined is undefined', function () { + assert.equal(util.getType(), 'undefined'); + }); + }); + + describe('easingFunctions', function () { + + it('take a number and output a number', function () { + for (var key in util.easingFunctions) { + if (util.easingFunctions.hasOwnProperty(key)) { + assert.equal(typeof util.easingFunctions[key](1), 'number'); + assert.equal(typeof util.easingFunctions[key](0.2), 'number'); + } + } + }); + }); + + describe('getScrollBarWidth', function () { + + beforeEach(function() { + this.jsdom_global = jsdom_global(); + }); + + afterEach(function() { + this.jsdom_global(); + }); + + it('returns 0 when there is no content', function () { + assert.equal(util.getScrollBarWidth(), 0); + }); + }); + + describe('equalArray', function () { + + it('arrays of different lengths are not equal', function () { + assert.equal(util.equalArray([1, 2, 3], [1, 2]), false) + }); + + it('arrays with different content are not equal', function () { + assert.equal(util.equalArray([1, 2, 3], [3, 2, 1]), false) + }); + + it('same content arrays are equal', function () { + assert(util.equalArray([1, 2, 3], [1, 2, 3])) + }); + + it('empty arrays are equal', function () { + assert(util.equalArray([], [])) + }); + + it('the same array is equal', function () { + var arr = [1, 2, 3]; + assert(util.equalArray(arr, arr)) + }); + }); + + describe('asBoolean', function () { + + it('resolves value from a function', function () { + assert(util.option.asBoolean(function () {return true}, false)); + }); + + it('returns default value for null', function () { + assert(util.option.asBoolean(null, true)); + }); + + it('returns true for other types', function () { + assert(util.option.asBoolean('should be true', false)); + }); + + it('returns null for undefined', function () { + assert.equal(util.option.asBoolean(), null); + }); + }); + + describe('asNumber', function () { + + it('resolves value from a function', function () { + assert.equal(util.option.asNumber(function () {return 777}, 13), 777); + }); + + it('returns default value for null', function () { + assert.equal(util.option.asNumber(null, 13), 13); + }); + + it('returns number for other types', function () { + assert.equal(util.option.asNumber('777', 13), 777); + }); + + it('returns default for NaN', function () { + assert.equal(util.option.asNumber(NaN, 13), 13); + }); + + it('returns null for undefined', function () { + assert.equal(util.option.asNumber(), null); + }); + }); + + describe('asString', function () { + + it('resolves value from a function', function () { + assert.equal(util.option.asString(function () {return 'entered'}, 'default'), 'entered'); + }); + + it('returns default value for null', function () { + assert.equal(util.option.asString(null, 'default'), 'default'); + }); + + it('returns string for other types', function () { + assert.equal(util.option.asString(777, 'default'), '777'); + }); + + it('returns default for undefined', function () { + assert.equal(util.option.asString(undefined, 'default'), 'default'); + }); + + it('returns null for undefined', function () { + assert.equal(util.option.asString(), null); + }); + }); + + describe('asSize', function () { + + it('resolves value from a function', function () { + assert.equal(util.option.asSize(function () {return '100px'}, '50px'), '100px'); + }); + + it('returns default value for null', function () { + assert.equal(util.option.asSize(null, '50px'), '50px'); + }); + + it('returns string with px for other number', function () { + assert.equal(util.option.asSize(100, '50px'), '100px'); + }); + + it('returns default for undefined', function () { + assert.equal(util.option.asSize(undefined, '50px'), '50px'); + }); + + it('returns null for undefined', function () { + assert.equal(util.option.asSize(), null); + }); + }); + + describe('asElement', function () { + + before(function() { + this.jsdom_global = jsdom_global(); + this.value = document.createElement("div"); + this.defaultValue = document.createElement("div"); + }); + + it('resolves value from a function', function () { + var me = this; + assert.equal(util.option.asElement(function () {return me.value}, this.defaultValue), this.value); + }); + + it('returns Element', function () { + assert.equal(util.option.asElement(this.value, this.defaultValue), this.value); + }); + + it('returns default value for null', function () { + assert.equal(util.option.asElement(null, this.defaultValue), this.defaultValue); + }); + + it('returns null for undefined', function () { + assert.equal(util.option.asElement(), null); + }); + }); + + describe('binarySearchValue', function () { + + it('Finds center target on odd sized array', function () { + assert.equal( + util.binarySearchValue( + [{id: 'a', val: 0}, {id: 'b', val: 1}, {id: 'c', val: 2}], + 1, + 'val' + ), + 1 + ); + }); + + it('Finds target on odd sized array', function () { + assert.equal( + util.binarySearchValue( + [{id: 'a', val: 0}, {id: 'b', val: 1}, {id: 'c', val: 2}], + 2, + 'val' + ), + 2 + ); + }); + + it('Cannot find target', function () { + assert.equal( + util.binarySearchValue( + [{id: 'a', val: 0}, {id: 'b', val: 1}, {id: 'c', val: 2}], + 7, + 'val' + ), + -1 + ); + }); + }); +}); diff --git a/test/uuid.test.js b/test/uuid.test.js new file mode 100644 index 00000000..7d5c1c04 --- /dev/null +++ b/test/uuid.test.js @@ -0,0 +1,19 @@ +var assert = require('assert'); +var uuid = require('../lib/module/uuid'); + +describe('UUID', function () { + + describe('v1', function () { + it('generates valid, parseable uuid1', function () { + assert(/^[0-9A-F]{8}-[0-9A-F]{4}-[1][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i.test(uuid.v1())); + assert.equal(uuid.parse(uuid.v1()).length, 16) + }); + }); + + describe('v4', function () { + it('generates valid, parseable uuid4', function () { + assert(/^[0-9A-F]{8}-[0-9A-F]{4}-[4][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i.test(uuid.v4())); + assert.equal(uuid.parse(uuid.v4()).length, 16) + }); + }); +});