From 2a8b36dc7d826658207183cc6eeccd91f46021b0 Mon Sep 17 00:00:00 2001 From: Nigel Heron Date: Thu, 26 Oct 2017 19:32:21 -0400 Subject: [PATCH] Add BOOMR.utils.arrayFind function --- .eslintrc | 1 + boomerang.js | 45 ++++++++++-- plugins/restiming.js | 2 +- .../11-restiming/00-clear-onbeacon.js | 7 +- .../01-clear-onbeacon-disabled.js | 7 +- .../11-restiming/02-resource-dimensions.js | 13 +++- .../11-restiming/03-url-length.js | 9 +++ .../11-restiming/04-resource-sizes.js | 5 +- .../page-templates/11-restiming/06-iframes.js | 9 +++ .../11-restiming/06-svg-image.js | 32 ++++++-- .../11-restiming/06-type-filter.js | 3 + .../11-restiming/07-page-ready-held.js | 7 +- .../11-restiming/07-script-attrs.js | 6 ++ .../11-restiming/08-cross-origin.js | 18 +++++ .../11-restiming/09-link-attrs.js | 3 +- .../11-restiming/09-server-timing.js | 2 + tests/unit/02-utils-arrayfilter.js | 26 +++++-- tests/unit/02-utils-arrayfind.js | 73 +++++++++++++++++++ tests/unit/02-utils-isarray.js | 20 +++++ tests/unit/index.html | 2 + 20 files changed, 262 insertions(+), 28 deletions(-) create mode 100644 tests/unit/02-utils-arrayfind.js create mode 100644 tests/unit/02-utils-isarray.js diff --git a/.eslintrc b/.eslintrc index 955eb05e3..293a92806 100644 --- a/.eslintrc +++ b/.eslintrc @@ -83,6 +83,7 @@ "comma-dangle": [2, "never"], "operator-linebreak": [2, "after"], "space-in-parens": [2, "never"], + "no-debugger": "error", // // Disabled rules diff --git a/boomerang.js b/boomerang.js index fca205714..611df046c 100644 --- a/boomerang.js +++ b/boomerang.js @@ -469,7 +469,7 @@ BOOMR_check_doc_domain(); nest_level = 0; } - if (Object.prototype.toString.call(o) === "[object Array]") { + if (BOOMR.utils.isArray(o)) { for (k = 0; k < o.length; k++) { if (nest_level > 0 && o[k] !== null && typeof o[k] === "object") { value.push( @@ -615,7 +615,7 @@ BOOMR_check_doc_domain(); * @returns {string} Cleaned up URL */ cleanupURL: function(url, urlLimit) { - if (!url || Object.prototype.toString.call(url) === "[object Array]") { + if (!url || BOOMR.utils.isArray(url)) { return ""; } @@ -689,6 +689,11 @@ BOOMR_check_doc_domain(); arrayFilter: function(array, predicate) { var result = []; + if (!(BOOMR.utils.isArray(array) || (array && typeof array.length === "number")) || + typeof predicate !== "function") { + return result; + } + if (typeof array.filter === "function") { result = array.filter(predicate); } @@ -706,6 +711,37 @@ BOOMR_check_doc_domain(); } return result; }, + /** + * `find` for arrays + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the value of first element that satisfies the predicate. + */ + arrayFind: function(array, predicate) { + if (!(BOOMR.utils.isArray(array) || (array && typeof array.length === "number")) || + typeof predicate !== "function") { + return undefined; + } + + if (typeof array.find === "function") { + return array.find(predicate); + } + else { + var index = -1, + length = array.length, + value; + + while (++index < length) { + value = array[index]; + if (predicate(value, index, array)) { + return value; + } + } + return undefined; + } + }, /** * @desc * Add a MutationObserver for a given element and terminate after `timeout`ms. @@ -818,7 +854,7 @@ BOOMR_check_doc_domain(); for (k in vars) { if (vars.hasOwnProperty(k)) { - if (Object.prototype.toString.call(vars[k]) === "[object Array]") { + if (BOOMR.utils.isArray(vars[k])) { for (i = 0; i < vars[k].length; ++i) { l += BOOMR.utils.pushVars(form, vars[k][i], k + "[" + i + "]"); } @@ -1468,8 +1504,7 @@ BOOMR_check_doc_domain(); return this; } - if (arguments.length === 1 && - Object.prototype.toString.apply(arg0) === "[object Array]") { + if (arguments.length === 1 && BOOMR.utils.isArray(arg0)) { params = arg0; } else { diff --git a/plugins/restiming.js b/plugins/restiming.js index e9d752980..c7566a19b 100644 --- a/plugins/restiming.js +++ b/plugins/restiming.js @@ -467,7 +467,7 @@ see: http://www.w3.org/TR/resource-timing/ // If this is a link, set its flags if (t.initiatorType === "link" && links[t.name]) { // split on ASCII whitespace - links[t.name].rel.split(/[\u0009\u000A\u000C\u000D\u0020]+/).find(function(rel) { //eslint-disable-line no-loop-func + BOOMR.utils.arrayFind(links[t.name].rel.split(/[\u0009\u000A\u000C\u000D\u0020]+/), function(rel) { //eslint-disable-line no-loop-func // `rel`s are case insensitive rel = rel.toLowerCase(); diff --git a/tests/page-templates/11-restiming/00-clear-onbeacon.js b/tests/page-templates/11-restiming/00-clear-onbeacon.js index 59c7bb1dc..c1a5aadad 100644 --- a/tests/page-templates/11-restiming/00-clear-onbeacon.js +++ b/tests/page-templates/11-restiming/00-clear-onbeacon.js @@ -4,14 +4,17 @@ describe("e2e/11-restiming/00-clear-onbeacon", function() { var t = BOOMR_test; - it("Should pass basic beacon validation", function(done){ + it("Should pass basic beacon validation", function(done) { t.validateBeaconWasSent(done); }); - it("Should clear ResourceTiming array after beacon (if ResourceTiming is enabled)", function(){ + it("Should clear ResourceTiming array after beacon (if ResourceTiming is enabled)", function() { if (t.isResourceTimingSupported()) { var entries = window.performance.getEntriesByType("resource"); assert.equal(entries.length, 0); } + else { + this.skip(); + } }); }); diff --git a/tests/page-templates/11-restiming/01-clear-onbeacon-disabled.js b/tests/page-templates/11-restiming/01-clear-onbeacon-disabled.js index 997c3283e..2c692ed28 100644 --- a/tests/page-templates/11-restiming/01-clear-onbeacon-disabled.js +++ b/tests/page-templates/11-restiming/01-clear-onbeacon-disabled.js @@ -4,14 +4,17 @@ describe("e2e/11-restiming/01-clear-onbeacon-disabled", function() { var t = BOOMR_test; - it("Should pass basic beacon validation", function(done){ + it("Should pass basic beacon validation", function(done) { t.validateBeaconWasSent(done); }); - it("Should not clear ResourceTiming array after beacon (if ResourceTiming is enabled)", function(){ + it("Should not clear ResourceTiming array after beacon (if ResourceTiming is enabled)", function() { if (t.isResourceTimingSupported()) { var entries = window.performance.getEntriesByType("resource"); assert.isTrue(entries.length > 0); } + else { + this.skip(); + } }); }); diff --git a/tests/page-templates/11-restiming/02-resource-dimensions.js b/tests/page-templates/11-restiming/02-resource-dimensions.js index 39489423e..43ec1382c 100644 --- a/tests/page-templates/11-restiming/02-resource-dimensions.js +++ b/tests/page-templates/11-restiming/02-resource-dimensions.js @@ -9,7 +9,7 @@ describe("e2e/11-restiming/02-resource-dimensions", function() { t.validateBeaconWasSent(done); }); - it("Should have dimensions for the IMG on the page (if ResourceTiming is supported)", function(){ + it("Should have dimensions for the IMG on the page (if ResourceTiming is supported)", function() { if (t.isResourceTimingSupported()) { var b = tf.beacons[0]; @@ -21,9 +21,12 @@ describe("e2e/11-restiming/02-resource-dimensions", function() { // 2000 nw = 1jk assert.match(b.restiming, /\*05k,b4,dw,2s,km,1jk\b/); } + else { + this.skip(); + } }); - it("Should have dimensions for the IFRAME on the page (if ResourceTiming is supported)", function(){ + it("Should have dimensions for the IFRAME on the page (if ResourceTiming is supported)", function() { if (t.isResourceTimingSupported()) { var b = tf.beacons[0]; @@ -33,6 +36,9 @@ describe("e2e/11-restiming/02-resource-dimensions", function() { // 200 x = 5k assert.include(b.restiming, "*01e,1e,m8,5k"); } + else { + this.skip(); + } }); it("Should not have timepoints for resources on the page (even if ResourceTiming is supported)", function() { @@ -51,5 +57,8 @@ describe("e2e/11-restiming/02-resource-dimensions", function() { assert.strictEqual(decompressed[tp[0]][1], 21400); */ } + else { + this.skip(); + } }); }); diff --git a/tests/page-templates/11-restiming/03-url-length.js b/tests/page-templates/11-restiming/03-url-length.js index 5c6376910..a0de6751b 100644 --- a/tests/page-templates/11-restiming/03-url-length.js +++ b/tests/page-templates/11-restiming/03-url-length.js @@ -14,6 +14,9 @@ describe("e2e/11-restiming/03-url-length", function() { var b = tf.lastBeacon(); assert.isDefined(b.restiming); } + else { + this.skip(); + } }); it("Should have trimmed the long URL (if ResourceTiming is supported)", function() { @@ -27,6 +30,9 @@ describe("e2e/11-restiming/03-url-length", function() { return r.name.indexOf("blackhole?...") !== -1; }), "Find blackhole?..."); } + else { + this.skip(); + } }); it("Should have trimmed the pixel URL (if ResourceTiming is supported)", function() { @@ -39,5 +45,8 @@ describe("e2e/11-restiming/03-url-length", function() { return r.name.indexOf("/foo/...") !== -1; }), "Find /foo/..."); } + else { + this.skip(); + } }); }); diff --git a/tests/page-templates/11-restiming/04-resource-sizes.js b/tests/page-templates/11-restiming/04-resource-sizes.js index 252831b0f..04cc1dc9a 100644 --- a/tests/page-templates/11-restiming/04-resource-sizes.js +++ b/tests/page-templates/11-restiming/04-resource-sizes.js @@ -9,7 +9,7 @@ describe("e2e/11-restiming/04-resource-sizes", function() { t.validateBeaconWasSent(done); }); - it("Should have sizes for the IMG on the page (if ResourceTiming2 is supported)", function(){ + it("Should have sizes for the IMG on the page (if ResourceTiming2 is supported)", function() { if (t.isResourceTimingSupported()) { var b = tf.beacons[0]; @@ -28,5 +28,8 @@ describe("e2e/11-restiming/04-resource-sizes", function() { } assert.equal(3, cnt); } + else { + this.skip(); + } }); }); diff --git a/tests/page-templates/11-restiming/06-iframes.js b/tests/page-templates/11-restiming/06-iframes.js index b740aa20a..ead8e757f 100644 --- a/tests/page-templates/11-restiming/06-iframes.js +++ b/tests/page-templates/11-restiming/06-iframes.js @@ -15,6 +15,9 @@ describe("e2e/11-restiming/06-iframes", function() { var b = tf.lastBeacon(); assert.isDefined(b.restiming); } + else { + this.skip(); + } }); it("Should have all of the resouces on the page", function() { @@ -37,6 +40,9 @@ describe("e2e/11-restiming/06-iframes", function() { }), "Finding " + url); } } + else { + this.skip(); + } }); it("Should have the IMG in the IFRAME", function() { @@ -49,5 +55,8 @@ describe("e2e/11-restiming/06-iframes", function() { return r.name.indexOf("/assets/img.jpg?iframe") !== -1; }), "Finding /assets/img.jpg?iframe in the IFRAME"); } + else { + this.skip(); + } }); }); diff --git a/tests/page-templates/11-restiming/06-svg-image.js b/tests/page-templates/11-restiming/06-svg-image.js index 23bc38b89..a3d12d08a 100644 --- a/tests/page-templates/11-restiming/06-svg-image.js +++ b/tests/page-templates/11-restiming/06-svg-image.js @@ -15,11 +15,11 @@ describe("e2e/11-restiming/06-svg-image", function() { return null; } - it("Should pass basic beacon validation", function(done){ + it("Should pass basic beacon validation", function(done) { t.validateBeaconWasSent(done); }); - it("Should found the SVG:image element", function(){ + it("Should found the SVG:image element", function() { if (t.isResourceTimingSupported()) { var b = tf.beacons[0]; @@ -27,9 +27,12 @@ describe("e2e/11-restiming/06-svg-image", function() { var img = findSvgImage(resources); assert.isDefined(img, "Image is not null"); } + else { + this.skip(); + } }); - it("Should have set the SVG:image initiatorType to IMAGE", function(){ + it("Should have set the SVG:image initiatorType to IMAGE", function() { if (t.isResourceTimingSupported()) { var b = tf.beacons[0]; @@ -37,9 +40,12 @@ describe("e2e/11-restiming/06-svg-image", function() { var img = findSvgImage(resources); assert.equal(img.initiatorType, "image"); } + else { + this.skip(); + } }); - it("Should have captured the SVG:image element height", function(){ + it("Should have captured the SVG:image element height", function() { if (t.isResourceTimingSupported()) { var b = tf.beacons[0]; @@ -47,9 +53,12 @@ describe("e2e/11-restiming/06-svg-image", function() { var img = findSvgImage(resources); assert.equal(img.height, 200); } + else { + this.skip(); + } }); - it("Should have captured the SVG:image element width", function(){ + it("Should have captured the SVG:image element width", function() { if (t.isResourceTimingSupported()) { var b = tf.beacons[0]; @@ -57,9 +66,12 @@ describe("e2e/11-restiming/06-svg-image", function() { var img = findSvgImage(resources); assert.equal(img.width, 400); } + else { + this.skip(); + } }); - it("Should have captured the SVG:image element top", function(){ + it("Should have captured the SVG:image element top", function() { if (t.isResourceTimingSupported()) { var b = tf.beacons[0]; @@ -67,9 +79,12 @@ describe("e2e/11-restiming/06-svg-image", function() { var img = findSvgImage(resources); assert.operator(img.y, ">=", 20); } + else { + this.skip(); + } }); - it("Should have captured the SVG:image element left", function(){ + it("Should have captured the SVG:image element left", function() { if (t.isResourceTimingSupported()) { var b = tf.beacons[0]; @@ -77,5 +92,8 @@ describe("e2e/11-restiming/06-svg-image", function() { var img = findSvgImage(resources); assert.operator(img.x, ">=", 10); } + else { + this.skip(); + } }); }); diff --git a/tests/page-templates/11-restiming/06-type-filter.js b/tests/page-templates/11-restiming/06-type-filter.js index aef7471c0..12a42aab8 100644 --- a/tests/page-templates/11-restiming/06-type-filter.js +++ b/tests/page-templates/11-restiming/06-type-filter.js @@ -20,5 +20,8 @@ describe("e2e/11-restiming/06-type-filter", function() { assert.equal(resources[0].initiatorType, "img"); assert.include(resources[0].name, "img.jpg"); } + else { + this.skip(); + } }); }); diff --git a/tests/page-templates/11-restiming/07-page-ready-held.js b/tests/page-templates/11-restiming/07-page-ready-held.js index 037f53b99..5ef536cc4 100644 --- a/tests/page-templates/11-restiming/07-page-ready-held.js +++ b/tests/page-templates/11-restiming/07-page-ready-held.js @@ -5,11 +5,11 @@ describe("e2e/11-restiming/07-page-ready-held", function() { var t = BOOMR_test; var tf = BOOMR.plugins.TestFramework; - it("Should pass basic beacon validation", function(done){ + it("Should pass basic beacon validation", function(done) { t.validateBeaconWasSent(done); }); - it("Should include img.jpg in the ResourceTiming data", function(){ + it("Should include img.jpg in the ResourceTiming data", function() { if (t.isResourceTimingSupported()) { var b = tf.beacons[0]; @@ -25,5 +25,8 @@ describe("e2e/11-restiming/07-page-ready-held", function() { assert.isTrue(found, "Found img.jpg"); } + else { + this.skip(); + } }); }); diff --git a/tests/page-templates/11-restiming/07-script-attrs.js b/tests/page-templates/11-restiming/07-script-attrs.js index d1c9465b5..4991ec947 100644 --- a/tests/page-templates/11-restiming/07-script-attrs.js +++ b/tests/page-templates/11-restiming/07-script-attrs.js @@ -30,6 +30,9 @@ describe("e2e/11-restiming/07-script-attrs", function() { assert.strictEqual(interesting.length, 7); } + else { + this.skip(); + } }); it("Should find attributes for script elements", function() { @@ -92,5 +95,8 @@ describe("e2e/11-restiming/07-script-attrs", function() { assertBodyAsync(js_link_async); } + else { + this.skip(); + } }); }); diff --git a/tests/page-templates/11-restiming/08-cross-origin.js b/tests/page-templates/11-restiming/08-cross-origin.js index e631fa0c7..258b1b818 100644 --- a/tests/page-templates/11-restiming/08-cross-origin.js +++ b/tests/page-templates/11-restiming/08-cross-origin.js @@ -15,6 +15,9 @@ describe("e2e/11-restiming/06-iframes", function() { var b = tf.lastBeacon(); assert.isDefined(b.restiming); } + else { + this.skip(); + } }); it("Should have all of the resouces on the page", function() { @@ -37,6 +40,9 @@ describe("e2e/11-restiming/06-iframes", function() { }), "Finding " + url); } } + else { + this.skip(); + } }); it("Should have the same-origin IFRAME", function() { @@ -49,6 +55,9 @@ describe("e2e/11-restiming/06-iframes", function() { return r.name.indexOf("support/iframe.html?same-origin") !== -1; }), "Finding support/iframe.html?same-origin"); } + else { + this.skip(); + } }); it("Should have the IMG from the same-origin IFRAME", function() { @@ -61,6 +70,9 @@ describe("e2e/11-restiming/06-iframes", function() { return r.name.indexOf("/assets/img.jpg?iframe") !== -1; }), "Finding /assets/img.jpg?iframe in the IFRAME"); } + else { + this.skip(); + } }); it("Should have the cross-origin IFRAME", function() { @@ -73,6 +85,9 @@ describe("e2e/11-restiming/06-iframes", function() { return r.name.indexOf("support/iframe.html?cross-origin") !== -1; }), "Finding support/iframe.html?cross-origin"); } + else { + this.skip(); + } }); it("Should not have the IMG from the cross-origin IFRAME", function() { @@ -86,5 +101,8 @@ describe("e2e/11-restiming/06-iframes", function() { r.name.indexOf(":" + window.crossOriginPort) !== -1; }), "Not finding /assets/img.jpg?afteriframe from cross-origin iframe"); } + else { + this.skip(); + } }); }); diff --git a/tests/page-templates/11-restiming/09-link-attrs.js b/tests/page-templates/11-restiming/09-link-attrs.js index eca393552..1f63ef8a8 100644 --- a/tests/page-templates/11-restiming/09-link-attrs.js +++ b/tests/page-templates/11-restiming/09-link-attrs.js @@ -11,6 +11,7 @@ describe("e2e/11-restiming/09-link-attrs", function() { it("Should find the link elements", function() { if (!t.isResourceTimingSupported()) { + this.skip(); return; } @@ -21,7 +22,6 @@ describe("e2e/11-restiming/09-link-attrs", function() { arr.push(r.name); return arr; }, []); - debugger; var a = document.createElement("a"); var expectedURLs = [ @@ -40,6 +40,7 @@ describe("e2e/11-restiming/09-link-attrs", function() { it("Should find `rel` for link elements", function() { if (!t.isResourceTimingSupported()) { + this.skip(); return; } diff --git a/tests/page-templates/11-restiming/09-server-timing.js b/tests/page-templates/11-restiming/09-server-timing.js index 2131cdce0..8e892a2d5 100644 --- a/tests/page-templates/11-restiming/09-server-timing.js +++ b/tests/page-templates/11-restiming/09-server-timing.js @@ -11,6 +11,7 @@ describe("e2e/11-restiming/09-server-timing", function() { it("Should have optimized server timing entries as `servertiming`", function() { if (!t.isServerTimingSupported()) { + this.skip(); return; } @@ -23,6 +24,7 @@ describe("e2e/11-restiming/09-server-timing", function() { it("Should have server timing data on `restiming`", function() { if (!t.isServerTimingSupported()) { + this.skip(); return; } var b = tf.beacons[0]; diff --git a/tests/unit/02-utils-arrayfilter.js b/tests/unit/02-utils-arrayfilter.js index bdb2e657e..2588764d9 100644 --- a/tests/unit/02-utils-arrayfilter.js +++ b/tests/unit/02-utils-arrayfilter.js @@ -4,7 +4,23 @@ describe("BOOMR.utils.arrayFilter()", function() { var assert = chai.assert; - it("Should return an empty array if the function only returns false", function(){ + it("Should return an empty array if input is not an array", function() { + var expect = []; + + var filterFunction = function() { + return false; + }; + assert.deepEqual(BOOMR.utils.arrayFilter(null, filterFunction), expect); + }); + + it("Should return an empty array if predicate is not a function", function() { + var input = [1, 2, 3, 4], + expect = []; + + assert.deepEqual(BOOMR.utils.arrayFilter(input, null), expect); + }); + + it("Should return an empty array if the predicate only returns false", function() { var input = [1, 2, 3, 4], expect = []; @@ -14,7 +30,7 @@ describe("BOOMR.utils.arrayFilter()", function() { assert.deepEqual(BOOMR.utils.arrayFilter(input, filterFunction), expect); }); - it("Should return an array of length one if only one returns true", function(){ + it("Should return an array of length one if only one returns true", function() { var input = [true, false], expect = [true]; @@ -25,7 +41,7 @@ describe("BOOMR.utils.arrayFilter()", function() { assert.deepEqual(BOOMR.utils.arrayFilter(input, filterFunction), expect); }); - it("Should have the array passed in as the third value and return the complete array as passed in", function(){ + it("Should have the array passed in as the third value and return the complete array as passed in", function() { var input = [1, 2, 3], expect = input; @@ -37,7 +53,7 @@ describe("BOOMR.utils.arrayFilter()", function() { assert.deepEqual(BOOMR.utils.arrayFilter(input, filterFunction), expect); }); - it("Should return half the array of numbers as it matches the rule we defined in the filter function", function(){ + it("Should return half the array of numbers as it matches the rule we defined in the filter function", function() { var input = [1, 2, 3, 4], expect = [1, 2]; @@ -48,7 +64,7 @@ describe("BOOMR.utils.arrayFilter()", function() { assert.deepEqual(BOOMR.utils.arrayFilter(input, filterFunction), expect); }); - it("Should also work if filter has been set to null or undefined (ie. lacking [].filter support)", function(){ + it("Should also work if filter has been set to null or undefined (ie. lacking [].filter support)", function() { var input = [1, 2, 3, 4], expect = [1, 2]; diff --git a/tests/unit/02-utils-arrayfind.js b/tests/unit/02-utils-arrayfind.js new file mode 100644 index 000000000..561421865 --- /dev/null +++ b/tests/unit/02-utils-arrayfind.js @@ -0,0 +1,73 @@ +/*eslint-env mocha*/ +/*global chai*/ + +describe("BOOMR.utils.arrayFind()", function() { + var assert = chai.assert; + + it("Should return undefined if input is not an array", function() { + var findFunction = function() { + return false; + }; + assert.isUndefined(BOOMR.utils.arrayFind(null, findFunction)); + }); + + it("Should return undefined if predicate is not a function", function() { + var input = [1, 2, 3, 4]; + + assert.isUndefined(BOOMR.utils.arrayFind(input, null)); + }); + + it("Should return undefined if the predicate only returns false", function() { + var input = [1, 2, 3, 4]; + + var findFunction = function() { + return false; + }; + assert.isUndefined(BOOMR.utils.arrayFind(input, findFunction)); + }); + + it("Should return value of match if only one matches", function() { + var input = [1, 2, 3, 4], + expect = 3; + + var findFunction = function(value) { + return value === 3; + }; + + assert.equal(BOOMR.utils.arrayFind(input, findFunction), expect); + }); + + it("Should return value of first match if multiple matches", function() { + var input = [1, 2, 3, 4], + expect = 2; + + var findFunction = function(value, index, array) { + return value >= 2; + }; + + assert.equal(BOOMR.utils.arrayFind(input, findFunction), expect); + }); + + it("Should return undefined if no matches", function() { + var input = [1, 2, 3, 4]; + + var findFunction = function(value) { + return value === 0; + }; + + assert.isUndefined(BOOMR.utils.arrayFind(input, findFunction)); + }); + + it("Should also work if find has been set to null or undefined (ie. lacking [].find support)", function() { + var input = [1, 2, 3, 4], + expect = 2; + + input.filter = undefined; + + var findFunction = function(value) { + return value >= 2; + }; + + assert.equal(BOOMR.utils.arrayFind(input, findFunction), expect); + }); +}); diff --git a/tests/unit/02-utils-isarray.js b/tests/unit/02-utils-isarray.js new file mode 100644 index 000000000..b397407d7 --- /dev/null +++ b/tests/unit/02-utils-isarray.js @@ -0,0 +1,20 @@ +/*eslint-env mocha*/ +/*global chai*/ + +describe("BOOMR.utils.isArray()", function() { + var assert = chai.assert; + + it("Should return false if input is not an array", function() { + assert.isFalse(BOOMR.utils.isArray(null)); + assert.isFalse(BOOMR.utils.isArray(undefined)); + assert.isFalse(BOOMR.utils.isArray("a")); + assert.isFalse(BOOMR.utils.isArray(1)); + assert.isFalse(BOOMR.utils.isArray({})); + assert.isFalse(BOOMR.utils.isArray(function() {})); + }); + + it("Should return true if input is an array", function() { + assert.isTrue(BOOMR.utils.isArray([])); + assert.isTrue(BOOMR.utils.isArray([1, 2, 3, null, undefined])); + }); +}); diff --git a/tests/unit/index.html b/tests/unit/index.html index c1a08fd64..076efb9d1 100644 --- a/tests/unit/index.html +++ b/tests/unit/index.html @@ -33,10 +33,12 @@ + +