diff options
| author | Johann-S <[email protected]> | 2019-03-13 16:23:50 +0200 |
|---|---|---|
| committer | Johann-S <[email protected]> | 2019-07-23 14:23:50 +0200 |
| commit | c8c207465043d940aa031570f0bce5e8fff9ffcf (patch) | |
| tree | 482f430ee84aa4cae8f76cebdec75791a60a50d1 /js/tests | |
| parent | 08d81c843706c2b952fadb703f3f9be709a8ca6a (diff) | |
| download | bootstrap-c8c207465043d940aa031570f0bce5e8fff9ffcf.tar.xz bootstrap-c8c207465043d940aa031570f0bce5e8fff9ffcf.zip | |
Switch from QUnit to Jasmine.
Diffstat (limited to 'js/tests')
| -rw-r--r-- | js/tests/README.md | 76 | ||||
| -rw-r--r-- | js/tests/helpers/fixture.js | 20 | ||||
| -rw-r--r-- | js/tests/karma.conf.js | 118 | ||||
| -rw-r--r-- | js/tests/unit/alert.js | 123 | ||||
| -rw-r--r-- | js/tests/unit/dom/data.js | 83 | ||||
| -rw-r--r-- | js/tests/unit/dom/event-handler.js | 340 | ||||
| -rw-r--r-- | js/tests/unit/util/index.js | 191 | ||||
| -rw-r--r-- | js/tests/unit/util/sanitizer.js | 51 |
8 files changed, 112 insertions, 890 deletions
diff --git a/js/tests/README.md b/js/tests/README.md index 3b079d92c..3a01d3399 100644 --- a/js/tests/README.md +++ b/js/tests/README.md @@ -1,20 +1,16 @@ ## How does Bootstrap's test suite work? -Bootstrap uses [QUnit](https://qunitjs.com/) and [Sinon](https://sinonjs.org/). Each plugin has a file dedicated to its tests in `unit/<plugin-name>.js`. +Bootstrap uses [Jasmine](https://jasmine.github.io/). Each plugin has a file dedicated to its tests in `src/<plugin-name>/<plugin-name>.spec.js`. -* `unit/` contains the unit test files for each Bootstrap plugin. -* `vendor/` contains third-party testing-related code (QUnit, jQuery and Sinon). * `visual/` contains "visual" tests which are run interactively in real browsers and require manual verification by humans. To run the unit test suite via [Karma](https://karma-runner.github.io/), run `npm run js-test`. - -To run the unit test suite via a real web browser, open `index.html` in the browser. - +To run the unit test suite via [Karma](https://karma-runner.github.io/) and debug, run `npm run js-debug`. ## How do I add a new unit test? -1. Locate and open the file dedicated to the plugin which you need to add tests to (`unit/<plugin-name>.js`). -2. Review the [QUnit API Documentation](https://api.qunitjs.com/) and use the existing tests as references for how to structure your new tests. +1. Locate and open the file dedicated to the plugin which you need to add tests to (`src/<plugin-name>/<plugin-name>.spec.js`). +2. Review the [Jasmine API Documentation](https://jasmine.github.io/pages/docs_home.html) and use the existing tests as references for how to structure your new tests. 3. Write the necessary unit test(s) for the new or revised functionality. 4. Run `npm run js-test` to see the results of your newly-added test(s). @@ -23,47 +19,53 @@ To run the unit test suite via a real web browser, open `index.html` in the brow ## What should a unit test look like? * Each test should have a unique name clearly stating what unit is being tested. +* Each test should be in the corresponding `describe`. * Each test should test only one unit per test, although one test can include several assertions. Create multiple tests for multiple units of functionality. -* Each test should begin with [`assert.expect`](https://api.qunitjs.com/assert/expect/) to ensure that the expected assertions are run. +* Each test should use [`expect`](https://jasmine.github.io/api/edge/matchers.html) to ensure something is expected. * Each test should follow the project's [JavaScript Code Guidelines](https://github.com/twbs/bootstrap/blob/master/CONTRIBUTING.md#js) ## Code coverage -Currently we're aiming for at least 80% test coverage for our code. To ensure your changes meet or exceed this limit, run `npm run js-compile && npm run js-test` and open the file in `js/coverage/lcov-report/index.html` to see the code coverage for each plugin. See more details when you select a plugin and ensure your change is fully covered by unit tests. +Currently we're aiming for at least 90% test coverage for our code. To ensure your changes meet or exceed this limit, run `npm run js-compile && npm run js-test` and open the file in `js/coverage/lcov-report/index.html` to see the code coverage for each plugin. See more details when you select a plugin and ensure your change is fully covered by unit tests. ### Example tests ```js // Synchronous test -QUnit.test('should describe the unit being tested', function (assert) { - assert.expect(1) - var templateHTML = '<div class="alert alert-danger fade show">' + - '<a class="close" href="#" data-dismiss="alert">×</a>' + - '<p><strong>Template necessary for the test.</p>' + - '</div>' - var $alert = $(templateHTML).appendTo('#qunit-fixture').bootstrapAlert() - - $alert.find('.close').trigger('click') - - // Make assertion - assert.strictEqual($alert.hasClass('show'), false, 'remove .show class on .close click') +describe('_getInstance', () => { + it('should return null if there is no instance', () => { + // Make assertion + expect(Tab._getInstance(fixtureEl)).toEqual(null) + }) + + it('should return this instance', () => { + fixtureEl.innerHTML = '<div></div>' + + const divEl = fixtureEl.querySelector('div') + const tab = new Tab(divEl) + + // Make assertion + expect(Tab._getInstance(divEl)).toEqual(tab) + }) }) // Asynchronous test -QUnit.test('should describe the unit being tested', function (assert) { - assert.expect(2) - var done = assert.async() - - var $tooltip = $('<div title="tooltip title"></div>').bootstrapTooltip() - var tooltipInstance = $tooltip.data('bs.tooltip') - var spyShow = sinon.spy(tooltipInstance, 'show') - - $tooltip.appendTo('#qunit-fixture') - .on('shown.bs.tooltip', function () { - assert.ok(true, '"shown" event was fired after calling "show"') - assert.ok(spyShow.called, 'show called') - done() - }) - .bootstrapTooltip('show') +it('should show a tooltip without the animation', done => { + fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"/>' + + const tooltipEl = fixtureEl.querySelector('a') + const tooltip = new Tooltip(tooltipEl, { + animation: false + }) + + tooltipEl.addEventListener('shown.bs.tooltip', () => { + const tip = document.querySelector('.tooltip') + + expect(tip).toBeDefined() + expect(tip.classList.contains('fade')).toEqual(false) + done() + }) + + tooltip.show() }) ``` diff --git a/js/tests/helpers/fixture.js b/js/tests/helpers/fixture.js new file mode 100644 index 000000000..524d54444 --- /dev/null +++ b/js/tests/helpers/fixture.js @@ -0,0 +1,20 @@ +const fixtureId = 'fixture' + +export const getFixture = () => { + let fixtureEl = document.getElementById(fixtureId) + + if (!fixtureEl) { + fixtureEl = document.createElement('div') + fixtureEl.setAttribute('id', fixtureId) + fixtureEl.style.display = 'none' + document.body.appendChild(fixtureEl) + } + + return fixtureEl +} + +export const clearFixture = () => { + const fixtureEl = getFixture() + + fixtureEl.innerHTML = '' +} diff --git a/js/tests/karma.conf.js b/js/tests/karma.conf.js index e3851663a..b5b9fb373 100644 --- a/js/tests/karma.conf.js +++ b/js/tests/karma.conf.js @@ -7,22 +7,19 @@ const { browsers, browsersKeys } = require('./browsers') +const babel = require('rollup-plugin-babel') +const istanbul = require('rollup-plugin-istanbul') const { env } = process -const bundle = env.BUNDLE === 'true' const browserStack = env.BROWSER === 'true' const debug = env.DEBUG === 'true' - -const jqueryFile = 'node_modules/jquery/dist/jquery.slim.min.js' - const frameworks = [ - 'qunit', - 'sinon' + 'jasmine' ] const plugins = [ - 'karma-qunit', - 'karma-sinon' + 'karma-jasmine', + 'karma-rollup-preprocessor' ] const reporters = ['dots'] @@ -49,10 +46,35 @@ const customLaunchers = { } } -let files = [ - 'node_modules/popper.js/dist/umd/popper.min.js', - 'node_modules/hammer-simulator/index.js' -] +const rollupPreprocessor = { + plugins: [ + istanbul({ + exclude: ['js/src/**/*.spec.js'] + }), + babel({ + // Only transpile our source code + exclude: 'node_modules/**', + // Include only required helpers + externalHelpersWhitelist: [ + 'defineProperties', + 'createClass', + 'inheritsLoose', + 'defineProperty', + 'objectSpread2' + ], + plugins: [ + '@babel/plugin-proposal-object-rest-spread' + ] + }) + ], + output: { + format: 'iife', + name: 'bootstrapTest', + sourcemap: 'inline' + } +} + +let files = [] const conf = { basePath: '../..', @@ -62,28 +84,11 @@ const conf = { singleRun: true, concurrency: Infinity, client: { - qunit: { - showUI: true - } + clearContext: false } } -if (bundle) { - frameworks.push('detectBrowsers') - plugins.push( - 'karma-chrome-launcher', - 'karma-firefox-launcher', - 'karma-detect-browsers' - ) - conf.customLaunchers = customLaunchers - conf.detectBrowsers = detectBrowsers - files = files.concat([ - jqueryFile, - 'js/tests/unit/tests-polyfills.js', - 'dist/js/bootstrap.js', - 'js/tests/unit/!(tests-polyfills).js' - ]) -} else if (browserStack) { +if (browserStack) { conf.hostname = ip.address() conf.browserStack = { username: env.BROWSER_STACK_USERNAME, @@ -92,27 +97,17 @@ if (bundle) { project: 'Bootstrap', retryLimit: 2 } - plugins.push('karma-browserstack-launcher') + plugins.push('karma-browserstack-launcher', 'karma-jasmine-html-reporter') conf.customLaunchers = browsers conf.browsers = browsersKeys - reporters.push('BrowserStack') + reporters.push('BrowserStack', 'kjhtml') files = files.concat([ - jqueryFile, - 'js/tests/unit/tests-polyfills.js', - 'js/coverage/dist/util/index.js', - 'js/coverage/dist/util/sanitizer.js', - 'js/coverage/dist/dom/polyfill.js', - 'js/coverage/dist/dom/event-handler.js', - 'js/coverage/dist/dom/selector-engine.js', - 'js/coverage/dist/dom/data.js', - 'js/coverage/dist/dom/manipulator.js', - 'js/coverage/dist/dom/!(polyfill).js', - 'js/coverage/dist/tooltip.js', - 'js/coverage/dist/!(util|index|tooltip).js', // include all of our js/dist files except util.js, index.js and tooltip.js - 'js/tests/unit/!(tests-polyfills).js', - 'js/tests/unit/dom/*.js', - 'js/tests/unit/util/*.js' + { pattern: 'js/src/**/*.spec.js', watched: false } ]) + conf.preprocessors = { + 'js/src/**/*.spec.js': ['rollup'] + } + conf.rollupPreprocessor = rollupPreprocessor } else { frameworks.push('detectBrowsers') plugins.push( @@ -122,23 +117,13 @@ if (bundle) { 'karma-coverage-istanbul-reporter' ) files = files.concat([ - jqueryFile, - 'js/tests/unit/tests-polyfills.js', - 'js/coverage/dist/util/index.js', - 'js/coverage/dist/util/sanitizer.js', - 'js/coverage/dist/dom/polyfill.js', - 'js/coverage/dist/dom/event-handler.js', - 'js/coverage/dist/dom/selector-engine.js', - 'js/coverage/dist/dom/data.js', - 'js/coverage/dist/dom/manipulator.js', - 'js/coverage/dist/dom/!(polyfill).js', - 'js/coverage/dist/tooltip.js', - 'js/coverage/dist/!(util|index|tooltip).js', // include all of our js/dist files except util.js, index.js and tooltip.js - 'js/tests/unit/!(tests-polyfills).js', - 'js/tests/unit/dom/*.js', - 'js/tests/unit/util/*.js' + { pattern: 'js/src/**/*.spec.js', watched: true } ]) reporters.push('coverage-istanbul') + conf.preprocessors = { + 'js/src/**/*.spec.js': ['rollup'] + } + conf.rollupPreprocessor = rollupPreprocessor conf.customLaunchers = customLaunchers conf.detectBrowsers = detectBrowsers conf.coverageIstanbulReporter = { @@ -148,8 +133,8 @@ if (bundle) { emitWarning: false, global: { statements: 90, - branches: 86, - functions: 89, + branches: 90, + functions: 90, lines: 90 }, each: { @@ -166,6 +151,9 @@ if (bundle) { } if (debug) { + conf.hostname = ip.address() + plugins.push('karma-jasmine-html-reporter') + reporters.push('kjhtml') conf.singleRun = false conf.autoWatch = true } diff --git a/js/tests/unit/alert.js b/js/tests/unit/alert.js deleted file mode 100644 index c03435618..000000000 --- a/js/tests/unit/alert.js +++ /dev/null @@ -1,123 +0,0 @@ -$(function () { - 'use strict' - - var Alert = typeof window.bootstrap === 'undefined' ? window.Alert : window.bootstrap.Alert - - QUnit.module('alert plugin') - - QUnit.test('should be defined on jquery object', function (assert) { - assert.expect(1) - assert.ok($(document.body).alert, 'alert method is defined') - }) - - QUnit.module('alert', { - beforeEach: function () { - // Run all tests in noConflict mode -- it's the only way to ensure that the plugin works in noConflict mode - $.fn.bootstrapAlert = $.fn.alert.noConflict() - }, - afterEach: function () { - $.fn.alert = $.fn.bootstrapAlert - delete $.fn.bootstrapAlert - $('#qunit-fixture').html('') - } - }) - - QUnit.test('should provide no conflict', function (assert) { - assert.expect(1) - assert.strictEqual(typeof $.fn.alert, 'undefined', 'alert was set back to undefined (org value)') - }) - - QUnit.test('should return jquery collection containing the element', function (assert) { - assert.expect(2) - var $el = $('<div/>') - var $alert = $el.bootstrapAlert() - assert.ok($alert instanceof $, 'returns jquery collection') - assert.strictEqual($alert[0], $el[0], 'collection contains element') - }) - - QUnit.test('should fade element out on clicking .close', function (assert) { - assert.expect(1) - var alertHTML = '<div class="alert alert-danger fade show">' + - '<a class="close" href="#" data-dismiss="alert">×</a>' + - '<p><strong>Holy guacamole!</strong> Best check yo self, you\'re not looking too good.</p>' + - '</div>' - - var $alert = $(alertHTML).bootstrapAlert().appendTo($('#qunit-fixture')) - - var closeBtn = $alert.find('.close')[0] - closeBtn.dispatchEvent(new Event('click')) - assert.strictEqual($alert.hasClass('show'), false, 'remove .show class on .close click') - }) - - QUnit.test('should remove element when clicking .close', function (assert) { - assert.expect(2) - var done = assert.async() - var alertHTML = '<div class="alert alert-danger fade show">' + - '<a class="close" href="#" data-dismiss="alert">×</a>' + - '<p><strong>Holy guacamole!</strong> Best check yo self, you\'re not looking too good.</p>' + - '</div>' - var $alert = $(alertHTML).appendTo('#qunit-fixture').bootstrapAlert() - - assert.notEqual($('#qunit-fixture').find('.alert').length, 0, 'element added to dom') - - $alert[0].addEventListener('closed.bs.alert', function () { - assert.strictEqual($('#qunit-fixture').find('.alert').length, 0, 'element removed from dom') - done() - }) - - var closeBtn = $alert.find('.close')[0] - closeBtn.dispatchEvent(new Event('click')) - }) - - QUnit.test('should not fire closed when close is prevented', function (assert) { - assert.expect(1) - var done = assert.async() - var $alert = $('<div class="alert"/>') - $alert.appendTo('#qunit-fixture') - - $alert[0].addEventListener('close.bs.alert', function (e) { - e.preventDefault() - assert.ok(true, 'close event fired') - done() - }) - $alert[0].addEventListener('closed.bs.alert', function () { - assert.ok(false, 'closed event fired') - }) - - $alert.bootstrapAlert('close') - }) - - QUnit.test('close should use internal _element if no element provided', function (assert) { - assert.expect(1) - - var done = assert.async() - var $el = $('<div/>') - var $alert = $el.bootstrapAlert() - var alertInstance = Alert._getInstance($alert[0]) - - $alert[0].addEventListener('closed.bs.alert', function () { - assert.ok('alert closed') - done() - }) - - alertInstance.close() - }) - - QUnit.test('dispose should remove data and the element', function (assert) { - assert.expect(2) - - var $el = $('<div/>') - var $alert = $el.bootstrapAlert() - - assert.ok(typeof Alert._getInstance($alert[0]) !== 'undefined') - - Alert._getInstance($alert[0]).dispose() - - assert.ok(Alert._getInstance($alert[0]) === null) - }) - - QUnit.test('should return the version', function (assert) { - assert.expect(1) - assert.strictEqual(typeof Alert.VERSION, 'string') - }) -}) diff --git a/js/tests/unit/dom/data.js b/js/tests/unit/dom/data.js deleted file mode 100644 index 63d25b292..000000000 --- a/js/tests/unit/dom/data.js +++ /dev/null @@ -1,83 +0,0 @@ -$(function () { - 'use strict' - - QUnit.module('data') - - QUnit.test('should be defined', function (assert) { - assert.expect(1) - assert.ok(Data, 'Data is defined') - }) - - QUnit.test('should set data in a element', function (assert) { - assert.expect(1) - - var $div = $('<div />').appendTo('#qunit-fixture') - var data = { - test: 'bsData' - } - Data.setData($div[0], 'test', data) - - assert.ok($div[0].key, 'element have a data key') - }) - - QUnit.test('should get data from an element', function (assert) { - assert.expect(1) - - var $div = $('<div />').appendTo('#qunit-fixture') - var data = { - test: 'bsData' - } - Data.setData($div[0], 'test', data) - - assert.strictEqual(Data.getData($div[0], 'test'), data) - }) - - QUnit.test('should return null if nothing is stored', function (assert) { - assert.expect(1) - assert.ok(Data.getData(document.body, 'test') === null) - }) - - QUnit.test('should return null if nothing is stored with an existing key', function (assert) { - assert.expect(1) - - var $div = $('<div />').appendTo('#qunit-fixture') - $div[0].key = { - key: 'test2', - data: 'woot woot' - } - - assert.ok(Data.getData($div[0], 'test') === null) - }) - - QUnit.test('should delete data', function (assert) { - assert.expect(2) - - var $div = $('<div />').appendTo('#qunit-fixture') - var data = { - test: 'bsData' - } - Data.setData($div[0], 'test', data) - assert.ok(Data.getData($div[0], 'test') !== null) - - Data.removeData($div[0], 'test') - assert.ok(Data.getData($div[0], 'test') === null) - }) - - QUnit.test('should delete nothing if there are nothing', function (assert) { - assert.expect(0) - - Data.removeData(document.body, 'test') - }) - - QUnit.test('should delete nothing if not the good key', function (assert) { - assert.expect(0) - - var $div = $('<div />').appendTo('#qunit-fixture') - $div[0].key = { - key: 'test2', - data: 'woot woot' - } - - Data.removeData($div[0], 'test') - }) -}) diff --git a/js/tests/unit/dom/event-handler.js b/js/tests/unit/dom/event-handler.js deleted file mode 100644 index 076a28a8a..000000000 --- a/js/tests/unit/dom/event-handler.js +++ /dev/null @@ -1,340 +0,0 @@ -$(function () { - 'use strict' - - QUnit.module('eventHandler') - - QUnit.test('should be defined', function (assert) { - assert.expect(1) - assert.ok(EventHandler, 'EventHandler is defined') - }) - - QUnit.test('should trigger event correctly', function (assert) { - assert.expect(1) - - var element = document.createElement('div') - element.addEventListener('foobar', function () { - assert.ok(true, 'listener called') - }) - - EventHandler.trigger(element, 'foobar') - }) - - QUnit.test('should trigger event through jQuery event system', function (assert) { - assert.expect(1) - - var element = document.createElement('div') - $(element).on('foobar', function () { - assert.ok(true, 'listener called') - }) - - EventHandler.trigger(element, 'foobar') - }) - - QUnit.test('should trigger namespaced event through jQuery event system', function (assert) { - assert.expect(2) - - var element = document.createElement('div') - $(element).on('foobar.namespace', function () { - assert.ok(true, 'first listener called') - }) - element.addEventListener('foobar.namespace', function () { - assert.ok(true, 'second listener called') - }) - - EventHandler.trigger(element, 'foobar.namespace') - }) - - QUnit.test('should mirror preventDefault', function (assert) { - assert.expect(2) - - var element = document.createElement('div') - $(element).on('foobar.namespace', function (event) { - event.preventDefault() - assert.ok(true, 'first listener called') - }) - element.addEventListener('foobar.namespace', function (event) { - assert.ok(event.defaultPrevented, 'defaultPrevented is true in second listener') - }) - - EventHandler.trigger(element, 'foobar.namespace') - }) - - QUnit.test('should mirror preventDefault for native events', function (assert) { - assert.expect(2) - - var element = document.createElement('div') - document.body.appendChild(element) - - $(element).on('click', function (event) { - event.preventDefault() - assert.ok(true, 'first listener called') - }) - element.addEventListener('click', function (event) { - assert.ok(event.defaultPrevented, 'defaultPrevented is true in second listener') - }) - - EventHandler.trigger(element, 'click') - document.body.removeChild(element) - }) - - QUnit.test('on should add event listener', function (assert) { - assert.expect(1) - - var element = document.createElement('div') - EventHandler.on(element, 'foobar', function () { - assert.ok(true, 'listener called') - }) - - EventHandler.trigger(element, 'foobar') - }) - - QUnit.test('on should add namespaced event listener', function (assert) { - assert.expect(1) - - var element = document.createElement('div') - EventHandler.on(element, 'foobar.namespace', function () { - assert.ok(true, 'listener called') - }) - - EventHandler.trigger(element, 'foobar.namespace') - }) - - QUnit.test('on should add native namespaced event listener', function (assert) { - assert.expect(1) - - var element = document.createElement('div') - document.body.appendChild(element) - EventHandler.on(element, 'click.namespace', function () { - assert.ok(true, 'listener called') - }) - - EventHandler.trigger(element, 'click') - document.body.removeChild(element) - }) - - QUnit.test('on should add delegated event listener', function (assert) { - assert.expect(1) - - var element = document.createElement('div') - var subelement = document.createElement('span') - element.appendChild(subelement) - - var anchor = document.createElement('a') - element.appendChild(anchor) - - EventHandler.on(element, 'click.namespace', 'a', function () { - assert.ok(true, 'listener called') - }) - - EventHandler.on(element, 'click', 'span', function () { - assert.notOk(true, 'listener should not be called') - }) - - document.body.appendChild(element) - EventHandler.trigger(anchor, 'click') - document.body.removeChild(element) - }) - - QUnit.test('on should add delegated event listener if delegated selector differs', function (assert) { - assert.expect(1) - - var element = document.createElement('div') - var subelement = document.createElement('span') - element.appendChild(subelement) - - var anchor = document.createElement('a') - element.appendChild(anchor) - - var i = 0 - var handler = function () { - i++ - } - - EventHandler.on(element, 'click', 'a', handler) - EventHandler.on(element, 'click', 'span', handler) - - document.body.appendChild(element) - EventHandler.trigger(anchor, 'click') - EventHandler.trigger(subelement, 'click') - document.body.removeChild(element) - - assert.ok(i === 2, 'listeners called') - }) - - QUnit.test('one should remove the listener after the event', function (assert) { - assert.expect(1) - - var element = document.createElement('div') - EventHandler.one(element, 'foobar', function () { - assert.ok(true, 'listener called') - }) - - EventHandler.trigger(element, 'foobar') - EventHandler.trigger(element, 'foobar') - }) - - QUnit.test('off should remove a listener', function (assert) { - assert.expect(1) - - var element = document.createElement('div') - var handler = function () { - assert.ok(true, 'listener called') - } - - EventHandler.on(element, 'foobar', handler) - EventHandler.trigger(element, 'foobar') - - EventHandler.off(element, 'foobar', handler) - EventHandler.trigger(element, 'foobar') - }) - - QUnit.test('off should remove all the listeners', function (assert) { - assert.expect(2) - - var element = document.createElement('div') - - EventHandler.on(element, 'foobar', function () { - assert.ok(true, 'first listener called') - }) - EventHandler.on(element, 'foobar', function () { - assert.ok(true, 'second listener called') - }) - EventHandler.trigger(element, 'foobar') - - EventHandler.off(element, 'foobar') - EventHandler.trigger(element, 'foobar') - }) - - QUnit.test('off should remove all the namespaced listeners if namespace is passed', function (assert) { - assert.expect(2) - - var element = document.createElement('div') - - EventHandler.on(element, 'foobar.namespace', function () { - assert.ok(true, 'first listener called') - }) - EventHandler.on(element, 'foofoo.namespace', function () { - assert.ok(true, 'second listener called') - }) - EventHandler.trigger(element, 'foobar.namespace') - EventHandler.trigger(element, 'foofoo.namespace') - - EventHandler.off(element, '.namespace') - EventHandler.trigger(element, 'foobar.namespace') - EventHandler.trigger(element, 'foofoo.namespace') - }) - - QUnit.test('off should remove the namespaced listeners', function (assert) { - assert.expect(2) - - var element = document.createElement('div') - - EventHandler.on(element, 'foobar.namespace', function () { - assert.ok(true, 'first listener called') - }) - EventHandler.on(element, 'foofoo.namespace', function () { - assert.ok(true, 'second listener called') - }) - EventHandler.trigger(element, 'foobar.namespace') - - EventHandler.off(element, 'foobar.namespace') - EventHandler.trigger(element, 'foobar.namespace') - - EventHandler.trigger(element, 'foofoo.namespace') - }) - - QUnit.test('off should remove the all the namespaced listeners for native events', function (assert) { - assert.expect(2) - - var element = document.createElement('div') - document.body.appendChild(element) - - EventHandler.on(element, 'click.namespace', function () { - assert.ok(true, 'first listener called') - }) - EventHandler.on(element, 'click.namespace2', function () { - assert.ok(true, 'second listener called') - }) - EventHandler.trigger(element, 'click') - - EventHandler.off(element, 'click') - EventHandler.trigger(element, 'click') - document.body.removeChild(element) - }) - - QUnit.test('off should remove the specified namespaced listeners for native events', function (assert) { - assert.expect(3) - - var element = document.createElement('div') - document.body.appendChild(element) - - EventHandler.on(element, 'click.namespace', function () { - assert.ok(true, 'first listener called') - }) - EventHandler.on(element, 'click.namespace2', function () { - assert.ok(true, 'second listener called') - }) - EventHandler.trigger(element, 'click') - - EventHandler.off(element, 'click.namespace') - EventHandler.trigger(element, 'click') - document.body.removeChild(element) - }) - - QUnit.test('off should remove a listener registered by .one', function (assert) { - assert.expect(0) - - var element = document.createElement('div') - var handler = function () { - assert.notOk(true, 'listener called') - } - - EventHandler.one(element, 'foobar', handler) - EventHandler.off(element, 'foobar', handler) - - EventHandler.trigger(element, 'foobar') - }) - - QUnit.test('off should remove the correct delegated event listener', function (assert) { - assert.expect(5) - - var element = document.createElement('div') - var subelement = document.createElement('span') - element.appendChild(subelement) - - var anchor = document.createElement('a') - element.appendChild(anchor) - - var i = 0 - var handler = function () { - i++ - } - - EventHandler.on(element, 'click', 'a', handler) - EventHandler.on(element, 'click', 'span', handler) - - document.body.appendChild(element) - - EventHandler.trigger(anchor, 'click') - EventHandler.trigger(subelement, 'click') - assert.ok(i === 2, 'first listeners called') - - EventHandler.off(element, 'click', 'span', handler) - EventHandler.trigger(subelement, 'click') - assert.ok(i === 2, 'removed listener not called') - - EventHandler.trigger(anchor, 'click') - assert.ok(i === 3, 'not removed listener called') - - EventHandler.on(element, 'click', 'span', handler) - EventHandler.trigger(anchor, 'click') - EventHandler.trigger(subelement, 'click') - assert.ok(i === 5, 'listener re-registered') - - EventHandler.off(element, 'click', 'span') - EventHandler.trigger(subelement, 'click') - assert.ok(i === 5, 'listener removed again') - - document.body.removeChild(element) - }) -}) diff --git a/js/tests/unit/util/index.js b/js/tests/unit/util/index.js deleted file mode 100644 index 19d3891d3..000000000 --- a/js/tests/unit/util/index.js +++ /dev/null @@ -1,191 +0,0 @@ -$(function () { - 'use strict' - - QUnit.module('util', { - afterEach: function () { - $('#qunit-fixture').html('') - } - }) - - QUnit.test('Util.getSelectorFromElement should return the correct element', function (assert) { - assert.expect(2) - - var $el = $('<div data-target="body"></div>').appendTo($('#qunit-fixture')) - assert.strictEqual(Util.getSelectorFromElement($el[0]), 'body') - - // Not found element - var $el2 = $('<div data-target="#fakeDiv"></div>').appendTo($('#qunit-fixture')) - assert.strictEqual(Util.getSelectorFromElement($el2[0]), null) - }) - - QUnit.test('Util.getSelectorFromElement should return null when there is a bad selector', function (assert) { - assert.expect(2) - - var $el = $('<div data-target="#1"></div>').appendTo($('#qunit-fixture')) - - assert.strictEqual(Util.getSelectorFromElement($el[0]), null) - - var $el2 = $('<a href="/posts"></a>').appendTo($('#qunit-fixture')) - - assert.strictEqual(Util.getSelectorFromElement($el2[0]), null) - }) - - QUnit.test('Util.typeCheckConfig should thrown an error when a bad config is passed', function (assert) { - assert.expect(1) - var namePlugin = 'collapse' - var defaultType = { - toggle: 'boolean', - parent: '(string|element)' - } - var config = { - toggle: true, - parent: 777 - } - - try { - Util.typeCheckConfig(namePlugin, config, defaultType) - } catch (error) { - assert.strictEqual(error.message, 'COLLAPSE: Option "parent" provided type "number" but expected type "(string|element)".') - } - }) - - QUnit.test('Util.isElement should check if we passed an element or not', function (assert) { - assert.expect(3) - var $div = $('<div id="test"></div>').appendTo($('#qunit-fixture')) - - assert.strictEqual(Util.isElement($div), 1) - assert.strictEqual(Util.isElement($div[0]), 1) - assert.strictEqual(typeof Util.isElement({}) === 'undefined', true) - }) - - QUnit.test('Util.getTransitionDurationFromElement should accept transition durations in milliseconds', function (assert) { - assert.expect(1) - var $div = $('<div style="transition: all 300ms ease-out;"></div>').appendTo($('#qunit-fixture')) - - assert.strictEqual(Util.getTransitionDurationFromElement($div[0]), 300) - }) - - QUnit.test('Util.getTransitionDurationFromElement should accept transition durations in seconds', function (assert) { - assert.expect(1) - var $div = $('<div style="transition: all .4s ease-out;"></div>').appendTo($('#qunit-fixture')) - - assert.strictEqual(Util.getTransitionDurationFromElement($div[0]), 400) - }) - - QUnit.test('Util.getTransitionDurationFromElement should return the addition of transition-delay and transition-duration', function (assert) { - assert.expect(2) - var $fixture = $('#qunit-fixture') - var $div = $('<div style="transition: all 0s 150ms ease-out;"></div>').appendTo($fixture) - var $div2 = $('<div style="transition: all .25s 30ms ease-out;"></div>').appendTo($fixture) - - assert.strictEqual(Util.getTransitionDurationFromElement($div[0]), 150) - assert.strictEqual(Util.getTransitionDurationFromElement($div2[0]), 280) - }) - - QUnit.test('Util.getTransitionDurationFromElement should get the first transition duration if multiple transition durations are defined', function (assert) { - assert.expect(1) - var $div = $('<div style="transition: transform .3s ease-out, opacity .2s;"></div>').appendTo($('#qunit-fixture')) - - assert.strictEqual(Util.getTransitionDurationFromElement($div[0]), 300) - }) - - QUnit.test('Util.getTransitionDurationFromElement should return 0 if transition duration is not defined', function (assert) { - assert.expect(1) - var $div = $('<div></div>').appendTo($('#qunit-fixture')) - - assert.strictEqual(Util.getTransitionDurationFromElement($div[0]), 0) - }) - - QUnit.test('Util.getTransitionDurationFromElement should return 0 if element is not found in DOM', function (assert) { - assert.expect(1) - var $div = $('#fake-id') - - assert.strictEqual(Util.getTransitionDurationFromElement($div[0]), 0) - }) - - QUnit.test('Util.getUID should generate a new id uniq', function (assert) { - assert.expect(2) - var id = Util.getUID('test') - var id2 = Util.getUID('test') - - assert.ok(id !== id2, id + ' !== ' + id2) - - id = Util.getUID('test') - $('<div id="' + id + '"></div>').appendTo($('#qunit-fixture')) - - id2 = Util.getUID('test') - assert.ok(id !== id2, id + ' !== ' + id2) - }) - - QUnit.test('Util.findShadowRoot should find the shadow DOM root', function (assert) { - // Only for newer browsers - if (!document.documentElement.attachShadow) { - assert.expect(0) - return - } - - assert.expect(2) - var $div = $('<div id="test"></div>').appendTo($('#qunit-fixture')) - var shadowRoot = $div[0].attachShadow({ - mode: 'open' - }) - - assert.equal(shadowRoot, Util.findShadowRoot(shadowRoot)) - shadowRoot.innerHTML = '<button>Shadow Button</button>' - assert.equal(shadowRoot, Util.findShadowRoot(shadowRoot.firstChild)) - }) - - QUnit.test('Util.findShadowRoot should return null when attachShadow is not available', function (assert) { - assert.expect(1) - - var $div = $('<div id="test"></div>').appendTo($('#qunit-fixture')) - if (document.documentElement.attachShadow) { - var sandbox = sinon.createSandbox() - - sandbox.replace(document.documentElement, 'attachShadow', function () { - // to avoid empty function - return $div - }) - - assert.equal(null, Util.findShadowRoot($div[0])) - sandbox.restore() - } else { - assert.equal(null, Util.findShadowRoot($div[0])) - } - }) - - QUnit.test('noop should return an empty function', function (assert) { - assert.expect(1) - Util.noop().call() - assert.ok(typeof Util.noop() === 'function') - }) - - QUnit.test('should return jQuery if present', function (assert) { - assert.expect(2) - - assert.equal(Util.jQuery, $) - - $.noConflict() - - assert.equal(Util.jQuery, jQuery) - - window.$ = jQuery - }) - - QUnit.test('Util.emulateTransitionEnd should emulate transition end', function (assert) { - assert.expect(1) - var $div = $('<div></div>').appendTo($('#qunit-fixture')) - - var spy = sinon.spy($div[0], 'removeEventListener') - - Util.emulateTransitionEnd($div[0], 7) - - assert.ok(spy.notCalled) - }) - - QUnit.test('Util.makeArray should return empty array on null', function (assert) { - assert.expect(1) - - assert.ok(Util.makeArray(null).length === 0) - }) -}) diff --git a/js/tests/unit/util/sanitizer.js b/js/tests/unit/util/sanitizer.js deleted file mode 100644 index 4120f0767..000000000 --- a/js/tests/unit/util/sanitizer.js +++ /dev/null @@ -1,51 +0,0 @@ -$(function () { - 'use strict' - - QUnit.module('sanitizer', { - afterEach: function () { - $('#qunit-fixture').html('') - } - }) - - QUnit.test('should export a default white list', function (assert) { - assert.expect(1) - - assert.ok(Sanitizer.DefaultWhitelist) - }) - - QUnit.test('should sanitize template by removing tags with XSS', function (assert) { - assert.expect(1) - - var template = [ - '<div>', - ' <a href="javascript:alert(7)">Click me</a>', - ' <span>Some content</span>', - '</div>' - ].join('') - - var result = Sanitizer.sanitizeHtml(template, Sanitizer.DefaultWhitelist, null) - - assert.strictEqual(result.indexOf('script'), -1) - }) - - QUnit.test('should not use native api to sanitize if a custom function passed', function (assert) { - assert.expect(2) - - var template = [ - '<div>', - ' <span>Some content</span>', - '</div>' - ].join('') - - function mySanitize(htmlUnsafe) { - return htmlUnsafe - } - - var spy = sinon.spy(DOMParser.prototype, 'parseFromString') - var result = Sanitizer.sanitizeHtml(template, Sanitizer.DefaultWhitelist, mySanitize) - - assert.strictEqual(result, template) - assert.strictEqual(spy.called, false) - spy.restore() - }) -}) |
