aboutsummaryrefslogtreecommitdiff
path: root/js/tests
diff options
context:
space:
mode:
authorMark Otto <[email protected]>2015-03-29 00:08:54 -0700
committerMark Otto <[email protected]>2015-03-29 00:08:54 -0700
commit58082cd83e9244fa05f316b4ba4102891ff5b0aa (patch)
tree4023557bafdc9813369ff067321d0f77304f4c8e /js/tests
parent321c3b66bb6e815e8c7e19f5ee7fc8b854fefead (diff)
parentce75f289f234ac72759efe634a5bd145180a0ae3 (diff)
downloadbootstrap-58082cd83e9244fa05f316b4ba4102891ff5b0aa.tar.xz
bootstrap-58082cd83e9244fa05f316b4ba4102891ff5b0aa.zip
Merge branch 'master' into v4
Conflicts: .gitignore Gruntfile.js _config.yml dist/css/bootstrap-theme.css dist/css/bootstrap-theme.min.css dist/css/bootstrap.css dist/css/bootstrap.css.map dist/css/bootstrap.min.css dist/js/bootstrap.js dist/js/bootstrap.min.js docs/_includes/components/navbar.html docs/_includes/components/progress-bars.html docs/_includes/css/grid.html docs/_includes/css/overview.html docs/_includes/customizer-variables.html docs/_includes/getting-started/accessibility.html docs/_includes/getting-started/browser-device-support.html docs/_includes/getting-started/community.html docs/_includes/getting-started/disabling-responsiveness.html docs/_includes/getting-started/download.html docs/_includes/getting-started/examples.html docs/_includes/getting-started/license.html docs/_includes/getting-started/third-party-support.html docs/_includes/js/alerts.html docs/_includes/js/buttons.html docs/_includes/js/carousel.html docs/_includes/js/collapse.html docs/_includes/js/dropdowns.html docs/_includes/js/modal.html docs/_includes/js/popovers.html docs/_includes/js/scrollspy.html docs/_includes/js/tabs.html docs/_includes/js/tooltips.html docs/_includes/js/transitions.html docs/_includes/nav/javascript.html docs/_includes/nav/main.html docs/about.html docs/assets/css/docs.min.css docs/assets/css/src/docs.css docs/assets/js/customize.min.js docs/assets/js/raw-files.min.js docs/assets/js/src/customizer.js docs/dist/css/bootstrap-theme.css docs/dist/css/bootstrap-theme.min.css docs/dist/css/bootstrap.css docs/dist/css/bootstrap.css.map docs/dist/css/bootstrap.min.css docs/dist/js/bootstrap.js docs/dist/js/bootstrap.min.js docs/migration.html js/affix.js js/alert.js js/button.js js/carousel.js js/collapse.js js/dropdown.js js/modal.js js/popover.js js/scrollspy.js js/tab.js js/tests/unit/affix.js js/tests/unit/button.js js/tests/unit/carousel.js js/tests/unit/modal.js js/tests/unit/tooltip.js js/tests/visual/modal.html js/tooltip.js less/component-animations.less less/jumbotron.less less/mixins/background-variant.less less/mixins/buttons.less less/mixins/responsive-visibility.less less/mixins/text-emphasis.less less/navbar.less less/navs.less less/scaffolding.less less/tooltip.less less/utilities.less less/variables.less package.json scss/_buttons.scss scss/_forms.scss scss/_modal.scss
Diffstat (limited to 'js/tests')
-rw-r--r--js/tests/README.md61
-rw-r--r--js/tests/index.html87
-rw-r--r--js/tests/unit/.jshintrc1
-rw-r--r--js/tests/unit/alert.js10
-rw-r--r--js/tests/unit/collapse.js136
-rw-r--r--js/tests/unit/dropdown.js95
-rw-r--r--js/tests/unit/popover.js35
-rw-r--r--js/tests/unit/scrollspy.js92
-rw-r--r--js/tests/unit/tab.js15
-rw-r--r--js/tests/visual/collapse.html6
10 files changed, 455 insertions, 83 deletions
diff --git a/js/tests/README.md b/js/tests/README.md
new file mode 100644
index 000000000..6cdb41059
--- /dev/null
+++ b/js/tests/README.md
@@ -0,0 +1,61 @@
+## How does Bootstrap's test suite work?
+
+Bootstrap uses [QUnit](http://api.qunitjs.com/), a powerful, easy-to-use JavaScript unit test framework. Each plugin has a file dedicated to its tests in `unit/<plugin-name>.js`.
+
+* `unit/` contains the unit test files for each Bootstrap plugin.
+* `vendor/` contains third-party testing-related code (QUnit and jQuery).
+* `visual/` contains "visual" tests which are run interactively in real browsers and require manual verification by humans.
+
+To run the unit test suite via [PhantomJS](http://phantomjs.org/), run `grunt test-js`.
+
+To run the unit test suite via a real web browser, open `index.html` in the browser.
+
+
+## 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](http://api.qunitjs.com/) 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 `grunt test-js` to see the results of your newly-added test(s).
+
+**Note:** Your new unit tests should fail before your changes are applied to the plugin, and should pass after your changes are applied to the plugin.
+
+## What should a unit test look like?
+
+* Each test should have a unique name clearly stating what unit is being tested.
+* 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`](http://api.qunitjs.com/expect/) to ensure that the expected assertions are run.
+* Each test should follow the project's [JavaScript Code Guidelines](https://github.com/twbs/bootstrap/blob/master/CONTRIBUTING.md#js)
+
+### Example tests
+
+```javascript
+// Synchronous test
+QUnit.test('should describe the unit being tested', function (assert) {
+ assert.expect(1)
+ var templateHTML = '<div class="alert alert-danger fade in">'
+ + '<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').click()
+
+ // Make assertion
+ assert.strictEqual($alert.hasClass('in'), false, 'remove .in class on .close click')
+})
+
+// Asynchronous test
+QUnit.test('should describe the unit being tested', function (assert) {
+ assert.expect(1)
+ var done = assert.async()
+
+ $('<div title="tooltip title"></div>')
+ .appendTo('#qunit-fixture')
+ .on('shown.bs.tooltip', function () {
+ assert.ok(true, '"shown" event was fired after calling "show"')
+ done()
+ })
+ .bootstrapTooltip('show')
+})
+```
diff --git a/js/tests/index.html b/js/tests/index.html
index c1b5b3914..d1ec0a7f4 100644
--- a/js/tests/index.html
+++ b/js/tests/index.html
@@ -7,19 +7,55 @@
<!-- jQuery -->
<script src="vendor/jquery.min.js"></script>
+ <script>
+ // Disable jQuery event aliases to ensure we don't accidentally use any of them
+ (function () {
+ var eventAliases = [
+ 'blur',
+ 'focus',
+ 'focusin',
+ 'focusout',
+ 'load',
+ 'resize',
+ 'scroll',
+ 'unload',
+ 'click',
+ 'dblclick',
+ 'mousedown',
+ 'mouseup',
+ 'mousemove',
+ 'mouseover',
+ 'mouseout',
+ 'mouseenter',
+ 'mouseleave',
+ 'change',
+ 'select',
+ 'submit',
+ 'keydown',
+ 'keypress',
+ 'keyup',
+ 'error',
+ 'contextmenu',
+ 'hover',
+ 'bind',
+ 'unbind',
+ 'delegate',
+ 'undelegate'
+ ]
+ for (var i = 0; i < eventAliases.length; i++) {
+ $.fn[eventAliases[i]] = undefined
+ }
+ })()
+ </script>
<!-- QUnit -->
<link rel="stylesheet" href="vendor/qunit.css" media="screen">
<script src="vendor/qunit.js"></script>
- <style>
- #qunit-fixture {
- top: 0;
- left: 0;
- }
- </style>
<script>
// See https://github.com/axemclion/grunt-saucelabs#test-result-details-with-qunit
var log = []
+ // Require assert.expect in each test.
+ QUnit.config.requireExpects = true
QUnit.done(function (testResults) {
var tests = []
for (var i = 0, len = log.length; i < len; i++) {
@@ -52,6 +88,45 @@
$('#qunit-fixture').empty()
$('#modal-test, .modal-backdrop').remove()
})
+
+ // Display fixture on-screen on iOS to avoid false positives
+ if (/iPhone|iPad|iPod/.test(navigator.userAgent)) {
+ QUnit.begin(function() {
+ $('#qunit-fixture').css({ top: 0, left: 0 })
+ })
+
+ QUnit.done(function () {
+ $('#qunit-fixture').css({ top: '', left: '' })
+ })
+ }
+
+ // Disable deprecated global QUnit method aliases in preparation for QUnit v2
+ (function () {
+ var methodNames = [
+ 'async',
+ 'asyncTest',
+ 'deepEqual',
+ 'equal',
+ 'expect',
+ 'module',
+ 'notDeepEqual',
+ 'notEqual',
+ 'notPropEqual',
+ 'notStrictEqual',
+ 'ok',
+ 'propEqual',
+ 'push',
+ 'start',
+ 'stop',
+ 'strictEqual',
+ 'test',
+ 'throws'
+ ];
+ for (var i = 0; i < methodNames.length; i++) {
+ var methodName = methodNames[i];
+ window[methodName] = undefined;
+ }
+ })();
</script>
<!-- Plugin sources -->
diff --git a/js/tests/unit/.jshintrc b/js/tests/unit/.jshintrc
index 682a49af1..22e878512 100644
--- a/js/tests/unit/.jshintrc
+++ b/js/tests/unit/.jshintrc
@@ -1,5 +1,6 @@
{
"extends" : "../../.jshintrc",
"devel" : true,
+ "es3" : false,
"qunit" : true
}
diff --git a/js/tests/unit/alert.js b/js/tests/unit/alert.js
index 75ae2d2ef..6be990a51 100644
--- a/js/tests/unit/alert.js
+++ b/js/tests/unit/alert.js
@@ -4,6 +4,7 @@ $(function () {
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')
})
@@ -19,10 +20,12 @@ $(function () {
})
QUnit.test('should provide no conflict', function (assert) {
+ assert.expect(1)
assert.strictEqual($.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')
@@ -30,18 +33,20 @@ $(function () {
})
QUnit.test('should fade element out on clicking .close', function (assert) {
+ assert.expect(1)
var alertHTML = '<div class="alert alert-danger fade in">'
+ '<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()
- $alert.find('.close').click()
+ $alert.find('.close').trigger('click')
assert.strictEqual($alert.hasClass('in'), false, 'remove .in class on .close click')
})
QUnit.test('should remove element when clicking .close', function (assert) {
+ assert.expect(2)
var alertHTML = '<div class="alert alert-danger fade in">'
+ '<a class="close" href="#" data-dismiss="alert">×</a>'
+ '<p><strong>Holy guacamole!</strong> Best check yo self, you\'re not looking too good.</p>'
@@ -50,12 +55,13 @@ $(function () {
assert.notEqual($('#qunit-fixture').find('.alert').length, 0, 'element added to dom')
- $alert.find('.close').click()
+ $alert.find('.close').trigger('click')
assert.strictEqual($('#qunit-fixture').find('.alert').length, 0, 'element removed from dom')
})
QUnit.test('should not fire closed when close is prevented', function (assert) {
+ assert.expect(1)
var done = assert.async()
$('<div class="alert"/>')
.on('close.bs.alert', function (e) {
diff --git a/js/tests/unit/collapse.js b/js/tests/unit/collapse.js
index a4d5eec67..0f1b7b119 100644
--- a/js/tests/unit/collapse.js
+++ b/js/tests/unit/collapse.js
@@ -4,6 +4,7 @@ $(function () {
QUnit.module('collapse plugin')
QUnit.test('should be defined on jquery object', function (assert) {
+ assert.expect(1)
assert.ok($(document.body).collapse, 'collapse method is defined')
})
@@ -19,10 +20,12 @@ $(function () {
})
QUnit.test('should provide no conflict', function (assert) {
+ assert.expect(1)
assert.strictEqual($.fn.collapse, undefined, 'collapse 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 $collapse = $el.bootstrapCollapse()
assert.ok($collapse instanceof $, 'returns jquery collection')
@@ -30,6 +33,7 @@ $(function () {
})
QUnit.test('should show a collapsed element', function (assert) {
+ assert.expect(2)
var $el = $('<div class="collapse"/>').bootstrapCollapse('show')
assert.ok($el.hasClass('in'), 'has class "in"')
@@ -37,13 +41,14 @@ $(function () {
})
QUnit.test('should hide a collapsed element', function (assert) {
+ assert.expect(1)
var $el = $('<div class="collapse"/>').bootstrapCollapse('hide')
assert.ok(!$el.hasClass('in'), 'does not have class "in"')
- assert.ok(/height/i.test($el.attr('style')), 'has height set')
})
QUnit.test('should not fire shown when show is prevented', function (assert) {
+ assert.expect(1)
var done = assert.async()
$('<div class="collapse"/>')
@@ -59,6 +64,7 @@ $(function () {
})
QUnit.test('should reset style to auto after finishing opening collapse', function (assert) {
+ assert.expect(2)
var done = assert.async()
$('<div class="collapse" style="height: 0px"/>')
@@ -73,9 +79,10 @@ $(function () {
})
QUnit.test('should remove "collapsed" class from target when collapse is shown', function (assert) {
+ assert.expect(1)
var done = assert.async()
- var $target = $('<a data-toggle="collapse" class="collapsed" href="#test1"/>').appendTo('#qunit-fixture')
+ var $target = $('<a role="button" data-toggle="collapse" class="collapsed" href="#test1"/>').appendTo('#qunit-fixture')
$('<div id="test1"/>')
.appendTo('#qunit-fixture')
@@ -84,13 +91,14 @@ $(function () {
done()
})
- $target.click()
+ $target.trigger('click')
})
QUnit.test('should add "collapsed" class to target when collapse is hidden', function (assert) {
+ assert.expect(1)
var done = assert.async()
- var $target = $('<a data-toggle="collapse" href="#test1"/>').appendTo('#qunit-fixture')
+ var $target = $('<a role="button" data-toggle="collapse" href="#test1"/>').appendTo('#qunit-fixture')
$('<div id="test1" class="in"/>')
.appendTo('#qunit-fixture')
@@ -99,14 +107,15 @@ $(function () {
done()
})
- $target.click()
+ $target.trigger('click')
})
QUnit.test('should remove "collapsed" class from all triggers targeting the collapse when the collapse is shown', function (assert) {
+ assert.expect(2)
var done = assert.async()
- var $target = $('<a data-toggle="collapse" class="collapsed" href="#test1"/>').appendTo('#qunit-fixture')
- var $alt = $('<a data-toggle="collapse" class="collapsed" href="#test1"/>').appendTo('#qunit-fixture')
+ var $target = $('<a role="button" data-toggle="collapse" class="collapsed" href="#test1"/>').appendTo('#qunit-fixture')
+ var $alt = $('<a role="button" data-toggle="collapse" class="collapsed" href="#test1"/>').appendTo('#qunit-fixture')
$('<div id="test1"/>')
.appendTo('#qunit-fixture')
@@ -116,14 +125,15 @@ $(function () {
done()
})
- $target.click()
+ $target.trigger('click')
})
QUnit.test('should add "collapsed" class to all triggers targeting the collapse when the collapse is hidden', function (assert) {
+ assert.expect(2)
var done = assert.async()
- var $target = $('<a data-toggle="collapse" href="#test1"/>').appendTo('#qunit-fixture')
- var $alt = $('<a data-toggle="collapse" href="#test1"/>').appendTo('#qunit-fixture')
+ var $target = $('<a role="button" data-toggle="collapse" href="#test1"/>').appendTo('#qunit-fixture')
+ var $alt = $('<a role="button" data-toggle="collapse" href="#test1"/>').appendTo('#qunit-fixture')
$('<div id="test1" class="in"/>')
.appendTo('#qunit-fixture')
@@ -133,13 +143,12 @@ $(function () {
done()
})
- $target.click()
+ $target.trigger('click')
})
- QUnit.test('should not close a collapse when initialized with "show" if already shown', function (assert) {
- var done = assert.async()
-
+ QUnit.test('should not close a collapse when initialized with "show" option if already shown', function (assert) {
assert.expect(0)
+ var done = assert.async()
var $test = $('<div id="test1" class="in"/>')
.appendTo('#qunit-fixture')
@@ -152,10 +161,9 @@ $(function () {
setTimeout(done, 0)
})
- QUnit.test('should open a collapse when initialized with "show" if not already shown', function (assert) {
- var done = assert.async()
-
+ QUnit.test('should open a collapse when initialized with "show" option if not already shown', function (assert) {
assert.expect(1)
+ var done = assert.async()
var $test = $('<div id="test1" />')
.appendTo('#qunit-fixture')
@@ -168,7 +176,36 @@ $(function () {
setTimeout(done, 0)
})
+ QUnit.test('should not show a collapse when initialized with "hide" option if already hidden', function (assert) {
+ assert.expect(0)
+ var done = assert.async()
+
+ $('<div class="collapse"></div>')
+ .appendTo('#qunit-fixture')
+ .on('show.bs.collapse', function () {
+ assert.ok(false, 'showing a previously-uninitialized hidden collapse when the "hide" method is called')
+ })
+ .bootstrapCollapse('hide')
+
+ setTimeout(done, 0)
+ })
+
+ QUnit.test('should hide a collapse when initialized with "hide" option if not already hidden', function (assert) {
+ assert.expect(1)
+ var done = assert.async()
+
+ $('<div class="collapse in"></div>')
+ .appendTo('#qunit-fixture')
+ .on('hide.bs.collapse', function () {
+ assert.ok(true, 'hiding a previously-uninitialized shown collapse when the "hide" method is called')
+ })
+ .bootstrapCollapse('hide')
+
+ setTimeout(done, 0)
+ })
+
QUnit.test('should remove "collapsed" class from active accordion target', function (assert) {
+ assert.expect(3)
var done = assert.async()
var accordionHTML = '<div class="panel-group" id="accordion">'
@@ -178,15 +215,15 @@ $(function () {
+ '</div>'
var $groups = $(accordionHTML).appendTo('#qunit-fixture').find('.panel')
- var $target1 = $('<a data-toggle="collapse" href="#body1" data-parent="#accordion"/>').appendTo($groups.eq(0))
+ var $target1 = $('<a role="button" data-toggle="collapse" href="#body1" data-parent="#accordion"/>').appendTo($groups.eq(0))
$('<div id="body1" class="in"/>').appendTo($groups.eq(0))
- var $target2 = $('<a class="collapsed" data-toggle="collapse" href="#body2" data-parent="#accordion"/>').appendTo($groups.eq(1))
+ var $target2 = $('<a class="collapsed" data-toggle="collapse" role="button" href="#body2" data-parent="#accordion"/>').appendTo($groups.eq(1))
$('<div id="body2"/>').appendTo($groups.eq(1))
- var $target3 = $('<a class="collapsed" data-toggle="collapse" href="#body3" data-parent="#accordion"/>').appendTo($groups.eq(2))
+ var $target3 = $('<a class="collapsed" data-toggle="collapse" role="button" href="#body3" data-parent="#accordion"/>').appendTo($groups.eq(2))
$('<div id="body3"/>')
.appendTo($groups.eq(2))
@@ -198,10 +235,11 @@ $(function () {
done()
})
- $target3.click()
+ $target3.trigger('click')
})
QUnit.test('should allow dots in data-parent', function (assert) {
+ assert.expect(3)
var done = assert.async()
var accordionHTML = '<div class="panel-group accordion">'
@@ -211,15 +249,15 @@ $(function () {
+ '</div>'
var $groups = $(accordionHTML).appendTo('#qunit-fixture').find('.panel')
- var $target1 = $('<a data-toggle="collapse" href="#body1" data-parent=".accordion"/>').appendTo($groups.eq(0))
+ var $target1 = $('<a role="button" data-toggle="collapse" href="#body1" data-parent=".accordion"/>').appendTo($groups.eq(0))
$('<div id="body1" class="in"/>').appendTo($groups.eq(0))
- var $target2 = $('<a class="collapsed" data-toggle="collapse" href="#body2" data-parent=".accordion"/>').appendTo($groups.eq(1))
+ var $target2 = $('<a class="collapsed" data-toggle="collapse" role="button" href="#body2" data-parent=".accordion"/>').appendTo($groups.eq(1))
$('<div id="body2"/>').appendTo($groups.eq(1))
- var $target3 = $('<a class="collapsed" data-toggle="collapse" href="#body3" data-parent=".accordion"/>').appendTo($groups.eq(2))
+ var $target3 = $('<a class="collapsed" data-toggle="collapse" role="button" href="#body3" data-parent=".accordion"/>').appendTo($groups.eq(2))
$('<div id="body3"/>')
.appendTo($groups.eq(2))
@@ -231,13 +269,14 @@ $(function () {
done()
})
- $target3.click()
+ $target3.trigger('click')
})
QUnit.test('should set aria-expanded="true" on target when collapse is shown', function (assert) {
+ assert.expect(1)
var done = assert.async()
- var $target = $('<a data-toggle="collapse" class="collapsed" href="#test1" aria-expanded="false"/>').appendTo('#qunit-fixture')
+ var $target = $('<a role="button" data-toggle="collapse" class="collapsed" href="#test1" aria-expanded="false"/>').appendTo('#qunit-fixture')
$('<div id="test1"/>')
.appendTo('#qunit-fixture')
@@ -246,13 +285,14 @@ $(function () {
done()
})
- $target.click()
+ $target.trigger('click')
})
QUnit.test('should set aria-expanded="false" on target when collapse is hidden', function (assert) {
+ assert.expect(1)
var done = assert.async()
- var $target = $('<a data-toggle="collapse" href="#test1" aria-expanded="true"/>').appendTo('#qunit-fixture')
+ var $target = $('<a role="button" data-toggle="collapse" href="#test1" aria-expanded="true"/>').appendTo('#qunit-fixture')
$('<div id="test1" class="in"/>')
.appendTo('#qunit-fixture')
@@ -261,14 +301,15 @@ $(function () {
done()
})
- $target.click()
+ $target.trigger('click')
})
QUnit.test('should set aria-expanded="true" on all triggers targeting the collapse when the collapse is shown', function (assert) {
+ assert.expect(2)
var done = assert.async()
- var $target = $('<a data-toggle="collapse" class="collapsed" href="#test1" aria-expanded="false"/>').appendTo('#qunit-fixture')
- var $alt = $('<a data-toggle="collapse" class="collapsed" href="#test1" aria-expanded="false"/>').appendTo('#qunit-fixture')
+ var $target = $('<a role="button" data-toggle="collapse" class="collapsed" href="#test1" aria-expanded="false"/>').appendTo('#qunit-fixture')
+ var $alt = $('<a role="button" data-toggle="collapse" class="collapsed" href="#test1" aria-expanded="false"/>').appendTo('#qunit-fixture')
$('<div id="test1"/>')
.appendTo('#qunit-fixture')
@@ -278,14 +319,15 @@ $(function () {
done()
})
- $target.click()
+ $target.trigger('click')
})
QUnit.test('should set aria-expanded="false" on all triggers targeting the collapse when the collapse is hidden', function (assert) {
+ assert.expect(2)
var done = assert.async()
- var $target = $('<a data-toggle="collapse" href="#test1" aria-expanded="true"/>').appendTo('#qunit-fixture')
- var $alt = $('<a data-toggle="collapse" href="#test1" aria-expanded="true"/>').appendTo('#qunit-fixture')
+ var $target = $('<a role="button" data-toggle="collapse" href="#test1" aria-expanded="true"/>').appendTo('#qunit-fixture')
+ var $alt = $('<a role="button" data-toggle="collapse" href="#test1" aria-expanded="true"/>').appendTo('#qunit-fixture')
$('<div id="test1" class="in"/>')
.appendTo('#qunit-fixture')
@@ -295,10 +337,11 @@ $(function () {
done()
})
- $target.click()
+ $target.trigger('click')
})
QUnit.test('should change aria-expanded from active accordion target to "false" and set the newly active one to "true"', function (assert) {
+ assert.expect(3)
var done = assert.async()
var accordionHTML = '<div class="panel-group" id="accordion">'
@@ -308,15 +351,15 @@ $(function () {
+ '</div>'
var $groups = $(accordionHTML).appendTo('#qunit-fixture').find('.panel')
- var $target1 = $('<a data-toggle="collapse" href="#body1" data-parent="#accordion"/>').appendTo($groups.eq(0))
+ var $target1 = $('<a role="button" data-toggle="collapse" href="#body1" data-parent="#accordion"/>').appendTo($groups.eq(0))
$('<div id="body1" aria-expanded="true" class="in"/>').appendTo($groups.eq(0))
- var $target2 = $('<a class="collapsed" data-toggle="collapse" href="#body2" data-parent="#accordion"/>').appendTo($groups.eq(1))
+ var $target2 = $('<a class="collapsed" data-toggle="collapse" role="button" href="#body2" data-parent="#accordion"/>').appendTo($groups.eq(1))
$('<div id="body2" aria-expanded="false"/>').appendTo($groups.eq(1))
- var $target3 = $('<a class="collapsed" data-toggle="collapse" href="#body3" data-parent="#accordion"/>').appendTo($groups.eq(2))
+ var $target3 = $('<a class="collapsed" data-toggle="collapse" role="button" href="#body3" data-parent="#accordion"/>').appendTo($groups.eq(2))
$('<div id="body3" aria-expanded="false"/>')
.appendTo($groups.eq(2))
@@ -328,10 +371,11 @@ $(function () {
done()
})
- $target3.click()
+ $target3.trigger('click')
})
QUnit.test('should not fire show event if show is prevented because other element is still transitioning', function (assert) {
+ assert.expect(1)
var done = assert.async()
var accordionHTML = '<div id="accordion">'
@@ -341,7 +385,7 @@ $(function () {
var showFired = false
var $groups = $(accordionHTML).appendTo('#qunit-fixture').find('.panel')
- var $target1 = $('<a data-toggle="collapse" href="#body1" data-parent="#accordion"/>').appendTo($groups.eq(0))
+ var $target1 = $('<a role="button" data-toggle="collapse" href="#body1" data-parent="#accordion"/>').appendTo($groups.eq(0))
$('<div id="body1" class="collapse"/>')
.appendTo($groups.eq(0))
@@ -349,16 +393,16 @@ $(function () {
showFired = true
})
- var $target2 = $('<a data-toggle="collapse" href="#body2" data-parent="#accordion"/>').appendTo($groups.eq(1))
+ var $target2 = $('<a role="button" data-toggle="collapse" href="#body2" data-parent="#accordion"/>').appendTo($groups.eq(1))
var $body2 = $('<div id="body2" class="collapse"/>').appendTo($groups.eq(1))
- $target2.click()
+ $target2.trigger('click')
$body2
.toggleClass('in collapsing')
.data('bs.collapse').setTransitioning(true)
- $target1.click()
+ $target1.trigger('click')
setTimeout(function () {
assert.ok(!showFired, 'show event did not fire')
@@ -367,9 +411,10 @@ $(function () {
})
QUnit.test('should add "collapsed" class to target when collapse is hidden via manual invocation', function (assert) {
+ assert.expect(1)
var done = assert.async()
- var $target = $('<a data-toggle="collapse" href="#test1"/>').appendTo('#qunit-fixture')
+ var $target = $('<a role="button" data-toggle="collapse" href="#test1"/>').appendTo('#qunit-fixture')
$('<div id="test1" class="in"/>')
.appendTo('#qunit-fixture')
@@ -381,9 +426,10 @@ $(function () {
})
QUnit.test('should remove "collapsed" class from target when collapse is shown via manual invocation', function (assert) {
+ assert.expect(1)
var done = assert.async()
- var $target = $('<a data-toggle="collapse" class="collapsed" href="#test1"/>').appendTo('#qunit-fixture')
+ var $target = $('<a role="button" data-toggle="collapse" class="collapsed" href="#test1"/>').appendTo('#qunit-fixture')
$('<div id="test1"/>')
.appendTo('#qunit-fixture')
diff --git a/js/tests/unit/dropdown.js b/js/tests/unit/dropdown.js
index 0a425200a..e0d1df970 100644
--- a/js/tests/unit/dropdown.js
+++ b/js/tests/unit/dropdown.js
@@ -4,6 +4,7 @@ $(function () {
QUnit.module('dropdowns plugin')
QUnit.test('should be defined on jquery object', function (assert) {
+ assert.expect(1)
assert.ok($(document.body).dropdown, 'dropdown method is defined')
})
@@ -19,10 +20,12 @@ $(function () {
})
QUnit.test('should provide no conflict', function (assert) {
+ assert.expect(1)
assert.strictEqual($.fn.dropdown, undefined, 'dropdown 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 $dropdown = $el.bootstrapDropdown()
assert.ok($dropdown instanceof $, 'returns jquery collection')
@@ -30,6 +33,7 @@ $(function () {
})
QUnit.test('should not open dropdown if target is disabled via attribute', function (assert) {
+ assert.expect(1)
var dropdownHTML = '<ul class="tabs">'
+ '<li class="dropdown">'
+ '<button disabled href="#" class="btn dropdown-toggle" data-toggle="dropdown">Dropdown</button>'
@@ -41,12 +45,13 @@ $(function () {
+ '</ul>'
+ '</li>'
+ '</ul>'
- var $dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown().click()
+ var $dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown().trigger('click')
assert.ok(!$dropdown.parent('.dropdown').hasClass('open'), '"open" class added on click')
})
QUnit.test('should set aria-expanded="true" on target when dropdown menu is shown', function (assert) {
+ assert.expect(1)
var dropdownHTML = '<ul class="tabs">'
+ '<li class="dropdown">'
+ '<a href="#" class="dropdown-toggle" data-toggle="dropdown" aria-expanded="false">Dropdown</a>'
@@ -61,12 +66,13 @@ $(function () {
var $dropdown = $(dropdownHTML)
.find('[data-toggle="dropdown"]')
.bootstrapDropdown()
- .click()
+ .trigger('click')
assert.strictEqual($dropdown.attr('aria-expanded'), 'true', 'aria-expanded is set to string "true" on click')
})
QUnit.test('should set aria-expanded="false" on target when dropdown menu is hidden', function (assert) {
+ assert.expect(1)
var done = assert.async()
var dropdownHTML = '<ul class="tabs">'
+ '<li class="dropdown">'
@@ -91,11 +97,12 @@ $(function () {
done()
})
- $dropdown.click()
- $(document.body).click()
+ $dropdown.trigger('click')
+ $(document.body).trigger('click')
})
QUnit.test('should not open dropdown if target is disabled via class', function (assert) {
+ assert.expect(1)
var dropdownHTML = '<ul class="tabs">'
+ '<li class="dropdown">'
+ '<button href="#" class="btn dropdown-toggle disabled" data-toggle="dropdown">Dropdown</button>'
@@ -107,12 +114,13 @@ $(function () {
+ '</ul>'
+ '</li>'
+ '</ul>'
- var $dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown().click()
+ var $dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown().trigger('click')
assert.ok(!$dropdown.parent('.dropdown').hasClass('open'), '"open" class added on click')
})
QUnit.test('should add class open to menu if clicked', function (assert) {
+ assert.expect(1)
var dropdownHTML = '<ul class="tabs">'
+ '<li class="dropdown">'
+ '<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>'
@@ -124,12 +132,13 @@ $(function () {
+ '</ul>'
+ '</li>'
+ '</ul>'
- var $dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown().click()
+ var $dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown().trigger('click')
assert.ok($dropdown.parent('.dropdown').hasClass('open'), '"open" class added on click')
})
QUnit.test('should test if element has a # before assuming it\'s a selector', function (assert) {
+ assert.expect(1)
var dropdownHTML = '<ul class="tabs">'
+ '<li class="dropdown">'
+ '<a href="/foo/" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>'
@@ -141,13 +150,14 @@ $(function () {
+ '</ul>'
+ '</li>'
+ '</ul>'
- var $dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown().click()
+ var $dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown().trigger('click')
assert.ok($dropdown.parent('.dropdown').hasClass('open'), '"open" class added on click')
})
QUnit.test('should remove "open" class if body is clicked', function (assert) {
+ assert.expect(2)
var dropdownHTML = '<ul class="tabs">'
+ '<li class="dropdown">'
+ '<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>'
@@ -163,14 +173,15 @@ $(function () {
.appendTo('#qunit-fixture')
.find('[data-toggle="dropdown"]')
.bootstrapDropdown()
- .click()
+ .trigger('click')
assert.ok($dropdown.parent('.dropdown').hasClass('open'), '"open" class added on click')
- $(document.body).click()
+ $(document.body).trigger('click')
assert.ok(!$dropdown.parent('.dropdown').hasClass('open'), '"open" class removed')
})
QUnit.test('should remove "open" class if body is clicked, with multiple dropdowns', function (assert) {
+ assert.expect(7)
var dropdownHTML = '<ul class="nav">'
+ '<li><a href="#menu1">Menu 1</a></li>'
+ '<li class="dropdown" id="testmenu">'
@@ -193,20 +204,21 @@ $(function () {
assert.strictEqual($dropdowns.length, 2, 'two dropdowns')
- $first.click()
+ $first.trigger('click')
assert.strictEqual($first.parents('.open').length, 1, '"open" class added on click')
assert.strictEqual($('#qunit-fixture .open').length, 1, 'only one dropdown is open')
- $(document.body).click()
+ $(document.body).trigger('click')
assert.strictEqual($('#qunit-fixture .open').length, 0, '"open" class removed')
- $last.click()
+ $last.trigger('click')
assert.strictEqual($last.parent('.open').length, 1, '"open" class added on click')
assert.strictEqual($('#qunit-fixture .open').length, 1, 'only one dropdown is open')
- $(document.body).click()
+ $(document.body).trigger('click')
assert.strictEqual($('#qunit-fixture .open').length, 0, '"open" class removed')
})
QUnit.test('should fire show and hide event', function (assert) {
+ assert.expect(2)
var dropdownHTML = '<ul class="tabs">'
+ '<li class="dropdown">'
+ '<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>'
@@ -235,12 +247,13 @@ $(function () {
done()
})
- $dropdown.click()
- $(document.body).click()
+ $dropdown.trigger('click')
+ $(document.body).trigger('click')
})
QUnit.test('should fire shown and hidden event', function (assert) {
+ assert.expect(2)
var dropdownHTML = '<ul class="tabs">'
+ '<li class="dropdown">'
+ '<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>'
@@ -269,11 +282,12 @@ $(function () {
done()
})
- $dropdown.click()
- $(document.body).click()
+ $dropdown.trigger('click')
+ $(document.body).trigger('click')
})
QUnit.test('should ignore keyboard events within <input>s and <textarea>s', function (assert) {
+ assert.expect(3)
var done = assert.async()
var dropdownHTML = '<ul class="tabs">'
@@ -302,19 +316,20 @@ $(function () {
.on('shown.bs.dropdown', function () {
assert.ok(true, 'shown was fired')
- $input.focus().trigger($.Event('keydown', { which: 38 }))
+ $input.trigger('focus').trigger($.Event('keydown', { which: 38 }))
assert.ok($(document.activeElement).is($input), 'input still focused')
- $textarea.focus().trigger($.Event('keydown', { which: 38 }))
+ $textarea.trigger('focus').trigger($.Event('keydown', { which: 38 }))
assert.ok($(document.activeElement).is($textarea), 'textarea still focused')
done()
})
- $dropdown.click()
+ $dropdown.trigger('click')
})
QUnit.test('should skip disabled element when using keyboard navigation', function (assert) {
+ assert.expect(1)
var dropdownHTML = '<ul class="tabs">'
+ '<li class="dropdown">'
+ '<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>'
@@ -328,11 +343,49 @@ $(function () {
.appendTo('#qunit-fixture')
.find('[data-toggle="dropdown"]')
.bootstrapDropdown()
- .click()
+ .trigger('click')
$dropdown.trigger($.Event('keydown', { which: 40 }))
$dropdown.trigger($.Event('keydown', { which: 40 }))
assert.ok(!$(document.activeElement).parent().is('.disabled'), '.disabled is not focused')
})
+
+ QUnit.test('should not close the dropdown if the user clicks on a text field', function (assert) {
+ assert.expect(1)
+ var dropdownHTML = '<div class="btn-group">'
+ + '<button type="button" data-toggle="dropdown">Dropdown</button>'
+ + '<ul class="dropdown-menu" role="menu">'
+ + '<li><input id="textField" type="text" /></li>'
+ + '</ul>'
+ + '</div>'
+ var $dropdown = $(dropdownHTML)
+ .appendTo('#qunit-fixture')
+ .find('[data-toggle="dropdown"]')
+ .bootstrapDropdown()
+ .trigger('click')
+
+ $('#textField').trigger('click')
+
+ assert.ok($dropdown.parent('.btn-group').hasClass('open'), 'dropdown menu is open')
+ })
+
+ QUnit.test('should not close the dropdown if the user clicks on a textarea', function (assert) {
+ assert.expect(1)
+ var dropdownHTML = '<div class="btn-group">'
+ + '<button type="button" data-toggle="dropdown">Dropdown</button>'
+ + '<ul class="dropdown-menu" role="menu">'
+ + '<li><textarea id="textArea"></textarea></li>'
+ + '</ul>'
+ + '</div>'
+ var $dropdown = $(dropdownHTML)
+ .appendTo('#qunit-fixture')
+ .find('[data-toggle="dropdown"]')
+ .bootstrapDropdown()
+ .trigger('click')
+
+ $('#textArea').trigger('click')
+
+ assert.ok($dropdown.parent('.btn-group').hasClass('open'), 'dropdown menu is open')
+ })
})
diff --git a/js/tests/unit/popover.js b/js/tests/unit/popover.js
index d2cdadd75..2cbc70138 100644
--- a/js/tests/unit/popover.js
+++ b/js/tests/unit/popover.js
@@ -4,6 +4,7 @@ $(function () {
QUnit.module('popover plugin')
QUnit.test('should be defined on jquery object', function (assert) {
+ assert.expect(1)
assert.ok($(document.body).popover, 'popover method is defined')
})
@@ -19,10 +20,12 @@ $(function () {
})
QUnit.test('should provide no conflict', function (assert) {
+ assert.expect(1)
assert.strictEqual($.fn.popover, undefined, 'popover 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 $popover = $el.bootstrapPopover()
assert.ok($popover instanceof $, 'returns jquery collection')
@@ -30,6 +33,7 @@ $(function () {
})
QUnit.test('should render popover element', function (assert) {
+ assert.expect(2)
var $popover = $('<a href="#" title="mdo" data-content="https://twitter.com/mdo">@mdo</a>')
.appendTo('#qunit-fixture')
.bootstrapPopover('show')
@@ -40,12 +44,14 @@ $(function () {
})
QUnit.test('should store popover instance in popover data object', function (assert) {
+ assert.expect(1)
var $popover = $('<a href="#" title="mdo" data-content="https://twitter.com/mdo">@mdo</a>').bootstrapPopover()
assert.ok($popover.data('bs.popover'), 'popover instance exists')
})
QUnit.test('should store popover trigger in popover instance data object', function (assert) {
+ assert.expect(1)
var $popover = $('<a href="#" title="ResentedHook">@ResentedHook</a>')
.appendTo('#qunit-fixture')
.bootstrapPopover()
@@ -56,6 +62,7 @@ $(function () {
})
QUnit.test('should get title and content from options', function (assert) {
+ assert.expect(4)
var $popover = $('<a href="#">@fat</a>')
.appendTo('#qunit-fixture')
.bootstrapPopover({
@@ -78,6 +85,7 @@ $(function () {
})
QUnit.test('should not duplicate HTML object', function (assert) {
+ assert.expect(6)
var $div = $('<div/>').html('loves writing tests (╯°□°)╯︵ ┻━┻')
var $popover = $('<a href="#">@fat</a>')
@@ -104,6 +112,7 @@ $(function () {
})
QUnit.test('should get title and content from attributes', function (assert) {
+ assert.expect(4)
var $popover = $('<a href="#" title="@mdo" data-content="loves data attributes (づ。◕‿‿◕。)づ ︵ ┻━┻" >@mdo</a>')
.appendTo('#qunit-fixture')
.bootstrapPopover()
@@ -119,6 +128,7 @@ $(function () {
QUnit.test('should get title and content from attributes ignoring options passed via js', function (assert) {
+ assert.expect(4)
var $popover = $('<a href="#" title="@mdo" data-content="loves data attributes (づ。◕‿‿◕。)づ ︵ ┻━┻" >@mdo</a>')
.appendTo('#qunit-fixture')
.bootstrapPopover({
@@ -136,6 +146,7 @@ $(function () {
})
QUnit.test('should respect custom template', function (assert) {
+ assert.expect(3)
var $popover = $('<a href="#">@fat</a>')
.appendTo('#qunit-fixture')
.bootstrapPopover({
@@ -154,6 +165,7 @@ $(function () {
})
QUnit.test('should destroy popover', function (assert) {
+ assert.expect(7)
var $popover = $('<div/>')
.bootstrapPopover({
trigger: 'hover'
@@ -174,6 +186,7 @@ $(function () {
})
QUnit.test('should render popover element using delegated selector', function (assert) {
+ assert.expect(2)
var $div = $('<div><a href="#" title="mdo" data-content="http://twitter.com/mdo">@mdo</a></div>')
.appendTo('#qunit-fixture')
.bootstrapPopover({
@@ -181,18 +194,19 @@ $(function () {
trigger: 'click'
})
- $div.find('a').click()
+ $div.find('a').trigger('click')
assert.notEqual($('.popover').length, 0, 'popover was inserted')
- $div.find('a').click()
+ $div.find('a').trigger('click')
assert.strictEqual($('.popover').length, 0, 'popover was removed')
})
QUnit.test('should detach popover content rather than removing it so that event handlers are left intact', function (assert) {
+ assert.expect(1)
var $content = $('<div class="content-with-handler"><a class="btn btn-warning">Button with event handler</a></div>').appendTo('#qunit-fixture')
var handlerCalled = false
- $('.content-with-handler .btn').click(function () {
+ $('.content-with-handler .btn').on('click', function () {
handlerCalled = true
})
@@ -214,7 +228,7 @@ $(function () {
.one('hidden.bs.popover', function () {
$div
.one('shown.bs.popover', function () {
- $('.content-with-handler .btn').click()
+ $('.content-with-handler .btn').trigger('click')
$div.bootstrapPopover('destroy')
assert.ok(handlerCalled, 'content\'s event handler still present')
done()
@@ -227,9 +241,22 @@ $(function () {
})
QUnit.test('should throw an error when initializing popover on the document object without specifying a delegation selector', function (assert) {
+ assert.expect(1)
assert.throws(function () {
$(document).bootstrapPopover({ title: 'What am I on?', content: 'My selector is missing' })
}, new Error('`selector` option must be specified when initializing popover on the window.document object!'))
})
+ QUnit.test('should do nothing when an attempt is made to hide an uninitialized popover', function (assert) {
+ assert.expect(1)
+
+ var $popover = $('<span data-toggle="popover" data-title="some title" data-content="some content">some text</span>')
+ .appendTo('#qunit-fixture')
+ .on('hidden.bs.popover shown.bs.popover', function () {
+ assert.ok(false, 'should not fire any popover events')
+ })
+ .bootstrapPopover('hide')
+ assert.strictEqual($popover.data('bs.popover'), undefined, 'should not initialize the popover')
+ })
+
})
diff --git a/js/tests/unit/scrollspy.js b/js/tests/unit/scrollspy.js
index 41d82e0e5..bf5fa0bff 100644
--- a/js/tests/unit/scrollspy.js
+++ b/js/tests/unit/scrollspy.js
@@ -4,6 +4,7 @@ $(function () {
QUnit.module('scrollspy plugin')
QUnit.test('should be defined on jquery object', function (assert) {
+ assert.expect(1)
assert.ok($(document.body).scrollspy, 'scrollspy method is defined')
})
@@ -19,10 +20,12 @@ $(function () {
})
QUnit.test('should provide no conflict', function (assert) {
+ assert.expect(1)
assert.strictEqual($.fn.scrollspy, undefined, 'scrollspy 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 $scrollspy = $el.bootstrapScrollspy()
assert.ok($scrollspy instanceof $, 'returns jquery collection')
@@ -30,6 +33,7 @@ $(function () {
})
QUnit.test('should only switch "active" class on current target', function (assert) {
+ assert.expect(1)
var done = assert.async()
var sectionHTML = '<div id="root" class="active">'
@@ -74,6 +78,7 @@ $(function () {
})
QUnit.test('should correctly select middle navigation option when large offset is used', function (assert) {
+ assert.expect(3)
var done = assert.async()
var sectionHTML = '<div id="header" style="height: 500px;"></div>'
@@ -107,6 +112,7 @@ $(function () {
})
QUnit.test('should add the active class to the correct element', function (assert) {
+ assert.expect(2)
var navbarHtml =
'<nav class="navbar">'
+ '<ul class="nav">'
@@ -142,7 +148,47 @@ $(function () {
.then(function () { return testElementIsActiveAfterScroll('#li-2', '#div-2') })
})
+ QUnit.test('should add the active class correctly when there are nested elements at 0 scroll offset', function (assert) {
+ assert.expect(6)
+ var times = 0
+ var done = assert.async()
+ var navbarHtml = '<nav id="navigation" class="navbar">'
+ + '<ul class="nav">'
+ + '<li id="li-1"><a href="#div-1">div 1</a>'
+ + '<ul>'
+ + '<li id="li-2"><a href="#div-2">div 2</a></li>'
+ + '</ul>'
+ + '</li>'
+ + '</ul>'
+ + '</nav>'
+
+ var contentHtml = '<div class="content" style="position: absolute; top: 0px; overflow: auto; height: 50px">'
+ + '<div id="div-1" style="padding: 0; margin: 0">'
+ + '<div id="div-2" style="height: 200px; padding: 0; margin: 0">div 2</div>'
+ + '</div>'
+ + '</div>'
+
+ $(navbarHtml).appendTo('#qunit-fixture')
+
+ var $content = $(contentHtml)
+ .appendTo('#qunit-fixture')
+ .bootstrapScrollspy({ offset: 0, target: '#navigation' })
+
+ !function testActiveElements() {
+ if (++times > 3) return done()
+
+ $content.one('scroll', function () {
+ assert.ok($('#li-1').hasClass('active'), 'nav item for outer element has "active" class')
+ assert.ok($('#li-2').hasClass('active'), 'nav item for inner element has "active" class')
+ testActiveElements()
+ })
+
+ $content.scrollTop($content.scrollTop() + 10)
+ }()
+ })
+
QUnit.test('should clear selection if above the first section', function (assert) {
+ assert.expect(3)
var done = assert.async()
var sectionHTML = '<div id="header" style="height: 500px;"></div>'
@@ -183,4 +229,50 @@ $(function () {
.scrollTop(201)
})
+ QUnit.test('should correctly select navigation element on backward scrolling when each target section height is 100%', function (assert) {
+ assert.expect(5)
+ var navbarHtml =
+ '<nav class="navbar">'
+ + '<ul class="nav">'
+ + '<li id="li-100-1"><a href="#div-100-1">div 1</a></li>'
+ + '<li id="li-100-2"><a href="#div-100-2">div 2</a></li>'
+ + '<li id="li-100-3"><a href="#div-100-3">div 3</a></li>'
+ + '<li id="li-100-4"><a href="#div-100-4">div 4</a></li>'
+ + '<li id="li-100-5"><a href="#div-100-5">div 5</a></li>'
+ + '</ul>'
+ + '</nav>'
+ var contentHtml =
+ '<div class="content" style="position: relative; overflow: auto; height: 100px">'
+ + '<div id="div-100-1" style="position: relative; height: 100%; padding: 0; margin: 0">div 1</div>'
+ + '<div id="div-100-2" style="position: relative; height: 100%; padding: 0; margin: 0">div 2</div>'
+ + '<div id="div-100-3" style="position: relative; height: 100%; padding: 0; margin: 0">div 3</div>'
+ + '<div id="div-100-4" style="position: relative; height: 100%; padding: 0; margin: 0">div 4</div>'
+ + '<div id="div-100-5" style="position: relative; height: 100%; padding: 0; margin: 0">div 5</div>'
+ + '</div>'
+
+ $(navbarHtml).appendTo('#qunit-fixture')
+ var $content = $(contentHtml)
+ .appendTo('#qunit-fixture')
+ .bootstrapScrollspy({ offset: 0, target: '.navbar' })
+
+ var testElementIsActiveAfterScroll = function (element, target) {
+ var deferred = $.Deferred()
+ var scrollHeight = Math.ceil($content.scrollTop() + $(target).position().top)
+ var done = assert.async()
+ $content.one('scroll', function () {
+ assert.ok($(element).hasClass('active'), 'target:' + target + ', element: ' + element)
+ done()
+ deferred.resolve()
+ })
+ $content.scrollTop(scrollHeight)
+ return deferred.promise()
+ }
+
+ $.when(testElementIsActiveAfterScroll('#li-100-5', '#div-100-5'))
+ .then(function () { return testElementIsActiveAfterScroll('#li-100-4', '#div-100-4') })
+ .then(function () { return testElementIsActiveAfterScroll('#li-100-3', '#div-100-3') })
+ .then(function () { return testElementIsActiveAfterScroll('#li-100-2', '#div-100-2') })
+ .then(function () { return testElementIsActiveAfterScroll('#li-100-1', '#div-100-1') })
+ })
+
})
diff --git a/js/tests/unit/tab.js b/js/tests/unit/tab.js
index d497de454..85d9f67a2 100644
--- a/js/tests/unit/tab.js
+++ b/js/tests/unit/tab.js
@@ -4,6 +4,7 @@ $(function () {
QUnit.module('tabs plugin')
QUnit.test('should be defined on jquery object', function (assert) {
+ assert.expect(1)
assert.ok($(document.body).tab, 'tabs method is defined')
})
@@ -19,10 +20,12 @@ $(function () {
})
QUnit.test('should provide no conflict', function (assert) {
+ assert.expect(1)
assert.strictEqual($.fn.tab, undefined, 'tab 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 $tab = $el.bootstrapTab()
assert.ok($tab instanceof $, 'returns jquery collection')
@@ -30,6 +33,7 @@ $(function () {
})
QUnit.test('should activate element by tab id', function (assert) {
+ assert.expect(2)
var tabsHTML = '<ul class="tabs">'
+ '<li><a href="#home">Home</a></li>'
+ '<li><a href="#profile">Profile</a></li>'
@@ -45,6 +49,7 @@ $(function () {
})
QUnit.test('should activate element by tab id', function (assert) {
+ assert.expect(2)
var pillsHTML = '<ul class="pills">'
+ '<li><a href="#home">Home</a></li>'
+ '<li><a href="#profile">Profile</a></li>'
@@ -60,6 +65,7 @@ $(function () {
})
QUnit.test('should not fire shown when show is prevented', function (assert) {
+ assert.expect(1)
var done = assert.async()
$('<div class="tab"/>')
@@ -75,6 +81,7 @@ $(function () {
})
QUnit.test('show and shown events should reference correct relatedTarget', function (assert) {
+ assert.expect(2)
var done = assert.async()
var dropHTML = '<ul class="drop">'
@@ -102,6 +109,7 @@ $(function () {
})
QUnit.test('should fire hide and hidden events', function (assert) {
+ assert.expect(2)
var done = assert.async()
var tabsHTML = '<ul class="tabs">'
@@ -132,6 +140,7 @@ $(function () {
})
QUnit.test('should not fire hidden when hide is prevented', function (assert) {
+ assert.expect(1)
var done = assert.async()
var tabsHTML = '<ul class="tabs">'
@@ -156,6 +165,7 @@ $(function () {
})
QUnit.test('hide and hidden events contain correct relatedTarget', function (assert) {
+ assert.expect(2)
var done = assert.async()
var tabsHTML = '<ul class="tabs">'
@@ -179,6 +189,7 @@ $(function () {
})
QUnit.test('selected tab should have aria-expanded', function (assert) {
+ assert.expect(8)
var tabsHTML = '<ul class="nav nav-tabs">'
+ '<li class="active"><a href="#home" toggle="tab" aria-expanded="true">Home</a></li>'
+ '<li><a href="#profile" toggle="tab" aria-expanded="false">Profile</a></li>'
@@ -189,7 +200,7 @@ $(function () {
assert.strictEqual($tabs.find('.active a').attr('aria-expanded'), 'true', 'shown tab has aria-expanded = true')
assert.strictEqual($tabs.find('li:not(.active) a').attr('aria-expanded'), 'false', 'hidden tab has aria-expanded = false')
- $tabs.find('li:last a').click()
+ $tabs.find('li:last a').trigger('click')
assert.strictEqual($tabs.find('.active a').attr('aria-expanded'), 'true', 'after click, shown tab has aria-expanded = true')
assert.strictEqual($tabs.find('li:not(.active) a').attr('aria-expanded'), 'false', 'after click, hidden tab has aria-expanded = false')
@@ -197,7 +208,7 @@ $(function () {
assert.strictEqual($tabs.find('.active a').attr('aria-expanded'), 'true', 'shown tab has aria-expanded = true')
assert.strictEqual($tabs.find('li:not(.active) a').attr('aria-expanded'), 'false', 'hidden tab has aria-expanded = false')
- $tabs.find('li:first a').click()
+ $tabs.find('li:first a').trigger('click')
assert.strictEqual($tabs.find('.active a').attr('aria-expanded'), 'true', 'after second show event, shown tab still has aria-expanded = true')
assert.strictEqual($tabs.find('li:not(.active) a').attr('aria-expanded'), 'false', 'after second show event, hidden tab has aria-expanded = false')
})
diff --git a/js/tests/visual/collapse.html b/js/tests/visual/collapse.html
index 1b81cf5ca..42ac0aaa2 100644
--- a/js/tests/visual/collapse.html
+++ b/js/tests/visual/collapse.html
@@ -19,7 +19,7 @@
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
- <a data-toggle="collapse" data-parent="#accordion" href="#collapseOne">
+ <a role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseOne">
Collapsible Group Item #1
</a>
</h4>
@@ -33,7 +33,7 @@
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
- <a data-toggle="collapse" data-parent="#accordion" href="#collapseTwo">
+ <a role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseTwo">
Collapsible Group Item #2
</a>
</h4>
@@ -47,7 +47,7 @@
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
- <a data-toggle="collapse" data-parent="#accordion" href="#collapseThree">
+ <a role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseThree">
Collapsible Group Item #3
</a>
</h4>