diff --git a/Gruntfile.js b/Gruntfile.js index b9a3a792b..f1fb6c5d7 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -281,6 +281,9 @@ grunt.initConfig({ "qunit-assert-classes/qunit-assert-classes.js": "qunit-assert-classes/qunit-assert-classes.js", "qunit-assert-classes/LICENSE.txt": "qunit-assert-classes/LICENSE", + "qunit-assert-close/qunit-assert-close.js": "qunit-assert-close/qunit-assert-close.js", + "qunit-assert-close/MIT-LICENSE.txt": "qunit-assert-close/MIT-LICENSE.txt", + "qunit-composite/qunit-composite.js": "qunit-composite/qunit-composite.js", "qunit-composite/qunit-composite.css": "qunit-composite/qunit-composite.css", "qunit-composite/LICENSE.txt": "qunit-composite/LICENSE.txt", diff --git a/bower.json b/bower.json index e371c03c4..543a98db8 100644 --- a/bower.json +++ b/bower.json @@ -16,6 +16,7 @@ "jshint": "2.4.4", "qunit": "1.18.0", "qunit-assert-classes": "0.1.5", + "qunit-assert-close": "JamesMGreene/qunit-assert-close#v1.1.1", "qunit-composite": "JamesMGreene/qunit-composite#v1.0.4", "requirejs": "2.1.14", diff --git a/external/qunit-assert-close/MIT-LICENSE.txt b/external/qunit-assert-close/MIT-LICENSE.txt new file mode 100644 index 000000000..aed5dc97e --- /dev/null +++ b/external/qunit-assert-close/MIT-LICENSE.txt @@ -0,0 +1,21 @@ +Copyright jQuery Foundation and other contributors +http://jquery.com/ + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/external/qunit-assert-close/qunit-assert-close.js b/external/qunit-assert-close/qunit-assert-close.js new file mode 100644 index 000000000..bd843810a --- /dev/null +++ b/external/qunit-assert-close/qunit-assert-close.js @@ -0,0 +1,106 @@ +/** + * Checks that the first two arguments are equal, or are numbers close enough to be considered equal + * based on a specified maximum allowable difference. + * + * @example assert.close(3.141, Math.PI, 0.001); + * + * @param Number actual + * @param Number expected + * @param Number maxDifference (the maximum inclusive difference allowed between the actual and expected numbers) + * @param String message (optional) + */ +function close(actual, expected, maxDifference, message) { + var actualDiff = (actual === expected) ? 0 : Math.abs(actual - expected), + result = actualDiff <= maxDifference; + message = message || (actual + " should be within " + maxDifference + " (inclusive) of " + expected + (result ? "" : ". Actual: " + actualDiff)); + QUnit.push(result, actual, expected, message); +} + + +/** + * Checks that the first two arguments are equal, or are numbers close enough to be considered equal + * based on a specified maximum allowable difference percentage. + * + * @example assert.close.percent(155, 150, 3.4); // Difference is ~3.33% + * + * @param Number actual + * @param Number expected + * @param Number maxPercentDifference (the maximum inclusive difference percentage allowed between the actual and expected numbers) + * @param String message (optional) + */ +close.percent = function closePercent(actual, expected, maxPercentDifference, message) { + var actualDiff, result; + if (actual === expected) { + actualDiff = 0; + result = actualDiff <= maxPercentDifference; + } + else if (actual !== 0 && expected !== 0 && expected !== Infinity && expected !== -Infinity) { + actualDiff = Math.abs(100 * (actual - expected) / expected); + result = actualDiff <= maxPercentDifference; + } + else { + // Dividing by zero (0)! Should return `false` unless the max percentage was `Infinity` + actualDiff = Infinity; + result = maxPercentDifference === Infinity; + } + message = message || (actual + " should be within " + maxPercentDifference + "% (inclusive) of " + expected + (result ? "" : ". Actual: " + actualDiff + "%")); + + QUnit.push(result, actual, expected, message); +}; + + +/** + * Checks that the first two arguments are numbers with differences greater than the specified + * minimum difference. + * + * @example assert.notClose(3.1, Math.PI, 0.001); + * + * @param Number actual + * @param Number expected + * @param Number minDifference (the minimum exclusive difference allowed between the actual and expected numbers) + * @param String message (optional) + */ +function notClose(actual, expected, minDifference, message) { + var actualDiff = Math.abs(actual - expected), + result = actualDiff > minDifference; + message = message || (actual + " should not be within " + minDifference + " (exclusive) of " + expected + (result ? "" : ". Actual: " + actualDiff)); + QUnit.push(result, actual, expected, message); +} + + +/** + * Checks that the first two arguments are numbers with differences greater than the specified + * minimum difference percentage. + * + * @example assert.notClose.percent(156, 150, 3.5); // Difference is 4.0% + * + * @param Number actual + * @param Number expected + * @param Number minPercentDifference (the minimum exclusive difference percentage allowed between the actual and expected numbers) + * @param String message (optional) + */ +notClose.percent = function notClosePercent(actual, expected, minPercentDifference, message) { + var actualDiff, result; + if (actual === expected) { + actualDiff = 0; + result = actualDiff > minPercentDifference; + } + else if (actual !== 0 && expected !== 0 && expected !== Infinity && expected !== -Infinity) { + actualDiff = Math.abs(100 * (actual - expected) / expected); + result = actualDiff > minPercentDifference; + } + else { + // Dividing by zero (0)! Should only return `true` if the min percentage was `Infinity` + actualDiff = Infinity; + result = minPercentDifference !== Infinity; + } + message = message || (actual + " should not be within " + minPercentDifference + "% (exclusive) of " + expected + (result ? "" : ". Actual: " + actualDiff + "%")); + + QUnit.push(result, actual, expected, message); +}; + + +QUnit.extend(QUnit.assert, { + close: close, + notClose: notClose +}); \ No newline at end of file diff --git a/tests/lib/bootstrap.js b/tests/lib/bootstrap.js index 6d608f2eb..7ca1bbda7 100644 --- a/tests/lib/bootstrap.js +++ b/tests/lib/bootstrap.js @@ -10,13 +10,15 @@ window.requirejs = { "lib": "../../lib", "phantom-bridge": "../../../node_modules/grunt-contrib-qunit/phantomjs/bridge", "qunit-assert-classes": "../../../external/qunit-assert-classes/qunit-assert-classes", + "qunit-assert-close": "../../../external/qunit-assert-close/qunit-assert-close", "qunit": "../../../external/qunit/qunit", "ui": "../../../ui" }, shim: { "globalize/ja-JP": [ "globalize" ], "jquery-simulate": [ "jquery" ], - "qunit-assert-classes": [ "qunit" ] + "qunit-assert-classes": [ "qunit" ], + "qunit-assert-close": [ "qunit" ] } }; @@ -43,11 +45,9 @@ function requireModules( dependencies, callback, modules ) { // Load a set of test file along with the required test infrastructure function requireTests( dependencies, noBackCompat ) { dependencies = [ - "../../lib/qunit", + "lib/qunit", noBackCompat ? "jquery-no-back-compat" : "jquery", - "jquery-simulate", - "qunit-assert-classes", - "../../lib/qunit-assert-domequal" + "jquery-simulate" ].concat( dependencies ); requireModules( dependencies, function( QUnit ) { diff --git a/tests/lib/qunit.js b/tests/lib/qunit.js index 5b0be5d23..757b6a501 100644 --- a/tests/lib/qunit.js +++ b/tests/lib/qunit.js @@ -1,6 +1,9 @@ define( [ "qunit", "jquery", + "qunit-assert-classes", + "qunit-assert-close", + "lib/qunit-assert-domequal", "phantom-bridge" ], function( QUnit, $ ) { @@ -40,12 +43,6 @@ QUnit.reset = ( function( reset ) { }; } )( QUnit.reset ); -// TODO: switch to qunit-assert-close plugin -QUnit.assert.close = function( actual, expected, maxDifference, message ) { - var passes = ( actual === expected ) || Math.abs( actual - expected ) <= maxDifference; - QUnit.push( passes, actual, expected, message ); -}; - return QUnit; } );