From bde431bb449b1d957d4e0b736111ff342f2a919d Mon Sep 17 00:00:00 2001 From: Scott González Date: Tue, 7 Apr 2015 10:55:52 -0400 Subject: Tests: Rename files Ref gh-1528 --- tests/lib/bootstrap.js | 12 +- tests/unit/accordion/accordion_common.js | 32 - tests/unit/accordion/accordion_core.js | 207 --- tests/unit/accordion/accordion_events.js | 168 --- tests/unit/accordion/accordion_methods.js | 136 -- tests/unit/accordion/accordion_options.js | 467 ------ tests/unit/accordion/accordion_test_helpers.js | 35 - tests/unit/accordion/common.js | 32 + tests/unit/accordion/core.js | 207 +++ tests/unit/accordion/events.js | 168 +++ tests/unit/accordion/helper.js | 35 + tests/unit/accordion/methods.js | 136 ++ tests/unit/accordion/options.js | 467 ++++++ tests/unit/autocomplete/autocomplete_common.js | 37 - tests/unit/autocomplete/autocomplete_core.js | 401 ------ tests/unit/autocomplete/autocomplete_events.js | 185 --- tests/unit/autocomplete/autocomplete_methods.js | 48 - tests/unit/autocomplete/autocomplete_options.js | 317 ---- tests/unit/autocomplete/common.js | 37 + tests/unit/autocomplete/core.js | 401 ++++++ tests/unit/autocomplete/events.js | 185 +++ tests/unit/autocomplete/methods.js | 48 + tests/unit/autocomplete/options.js | 317 ++++ tests/unit/button/button_common.js | 22 - tests/unit/button/button_core.js | 230 --- tests/unit/button/button_events.js | 36 - tests/unit/button/button_methods.js | 73 - tests/unit/button/button_options.js | 157 -- tests/unit/button/common.js | 22 + tests/unit/button/core.js | 230 +++ tests/unit/button/events.js | 36 + tests/unit/button/methods.js | 73 + tests/unit/button/options.js | 157 ++ tests/unit/datepicker/common.js | 7 + tests/unit/datepicker/core.js | 530 +++++++ tests/unit/datepicker/datepicker_common.js | 7 - tests/unit/datepicker/datepicker_core.js | 530 ------- tests/unit/datepicker/datepicker_events.js | 154 -- tests/unit/datepicker/datepicker_methods.js | 126 -- tests/unit/datepicker/datepicker_options.js | 1127 --------------- tests/unit/datepicker/datepicker_test_helpers.js | 38 - tests/unit/datepicker/events.js | 154 ++ tests/unit/datepicker/helper.js | 38 + tests/unit/datepicker/methods.js | 126 ++ tests/unit/datepicker/options.js | 1127 +++++++++++++++ tests/unit/dialog/common-deprecated.js | 54 + tests/unit/dialog/common.js | 53 + tests/unit/dialog/core.js | 308 ++++ tests/unit/dialog/deprecated.html | 33 + tests/unit/dialog/deprecated.js | 30 + tests/unit/dialog/dialog_common.js | 53 - tests/unit/dialog/dialog_common_deprecated.js | 54 - tests/unit/dialog/dialog_core.js | 308 ---- tests/unit/dialog/dialog_deprecated.html | 33 - tests/unit/dialog/dialog_deprecated.js | 30 - tests/unit/dialog/dialog_events.js | 370 ----- tests/unit/dialog/dialog_methods.js | 267 ---- tests/unit/dialog/dialog_options.js | 557 ------- tests/unit/dialog/dialog_test_helpers.js | 55 - tests/unit/dialog/events.js | 370 +++++ tests/unit/dialog/helper.js | 55 + tests/unit/dialog/methods.js | 267 ++++ tests/unit/dialog/options.js | 557 +++++++ tests/unit/draggable/common.js | 48 + tests/unit/draggable/core.js | 346 +++++ tests/unit/draggable/draggable_common.js | 48 - tests/unit/draggable/draggable_core.js | 346 ----- tests/unit/draggable/draggable_events.js | 164 --- tests/unit/draggable/draggable_methods.js | 104 -- tests/unit/draggable/draggable_options.js | 1493 ------------------- tests/unit/draggable/draggable_test_helpers.js | 158 -- tests/unit/draggable/events.js | 164 +++ tests/unit/draggable/helper.js | 158 ++ tests/unit/draggable/methods.js | 104 ++ tests/unit/draggable/options.js | 1493 +++++++++++++++++++ tests/unit/droppable/common-deprecated.js | 28 + tests/unit/droppable/common.js | 26 + tests/unit/droppable/core.js | 29 + tests/unit/droppable/deprecated.html | 22 + tests/unit/droppable/deprecated.js | 1 + tests/unit/droppable/droppable_common.js | 26 - .../unit/droppable/droppable_common_deprecated.js | 28 - tests/unit/droppable/droppable_core.js | 29 - tests/unit/droppable/droppable_deprecated.html | 22 - tests/unit/droppable/droppable_deprecated.js | 1 - tests/unit/droppable/droppable_events.js | 64 - tests/unit/droppable/droppable_methods.js | 92 -- tests/unit/droppable/droppable_options.js | 205 --- tests/unit/droppable/droppable_test_helpers.js | 18 - tests/unit/droppable/events.js | 64 + tests/unit/droppable/helper.js | 18 + tests/unit/droppable/methods.js | 92 ++ tests/unit/droppable/options.js | 205 +++ tests/unit/effects/core.js | 341 +++++ tests/unit/effects/effects.html | 2 +- tests/unit/effects/effects_core.js | 341 ----- tests/unit/effects/effects_scale.js | 72 - tests/unit/effects/scale.js | 72 + tests/unit/menu/common.js | 29 + tests/unit/menu/core.js | 76 + tests/unit/menu/events.js | 737 ++++++++++ tests/unit/menu/helper.js | 36 + tests/unit/menu/menu_common.js | 29 - tests/unit/menu/menu_core.js | 76 - tests/unit/menu/menu_events.js | 737 ---------- tests/unit/menu/menu_methods.js | 116 -- tests/unit/menu/menu_options.js | 125 -- tests/unit/menu/menu_test_helpers.js | 36 - tests/unit/menu/methods.js | 116 ++ tests/unit/menu/options.js | 125 ++ tests/unit/position/core.js | 770 ++++++++++ tests/unit/position/position.html | 2 +- tests/unit/position/position_core.js | 770 ---------- tests/unit/progressbar/common.js | 24 + tests/unit/progressbar/core.js | 64 + tests/unit/progressbar/events.js | 58 + tests/unit/progressbar/methods.js | 42 + tests/unit/progressbar/options.js | 79 + tests/unit/progressbar/progressbar_common.js | 24 - tests/unit/progressbar/progressbar_core.js | 64 - tests/unit/progressbar/progressbar_events.js | 58 - tests/unit/progressbar/progressbar_methods.js | 42 - tests/unit/progressbar/progressbar_options.js | 79 - tests/unit/resizable/common.js | 40 + tests/unit/resizable/core.js | 244 ++++ tests/unit/resizable/events.js | 242 ++++ tests/unit/resizable/helper.js | 18 + tests/unit/resizable/methods.js | 21 + tests/unit/resizable/options.js | 466 ++++++ tests/unit/resizable/resizable_common.js | 40 - tests/unit/resizable/resizable_core.js | 244 ---- tests/unit/resizable/resizable_events.js | 242 ---- tests/unit/resizable/resizable_methods.js | 21 - tests/unit/resizable/resizable_options.js | 466 ------ tests/unit/resizable/resizable_test_helpers.js | 18 - tests/unit/selectable/common.js | 29 + tests/unit/selectable/core.js | 3 + tests/unit/selectable/events.js | 63 + tests/unit/selectable/methods.js | 111 ++ tests/unit/selectable/options.js | 64 + tests/unit/selectable/selectable_common.js | 29 - tests/unit/selectable/selectable_core.js | 3 - tests/unit/selectable/selectable_events.js | 63 - tests/unit/selectable/selectable_methods.js | 111 -- tests/unit/selectable/selectable_options.js | 64 - tests/unit/selectmenu/common.js | 34 + tests/unit/selectmenu/core.js | 332 +++++ tests/unit/selectmenu/events.js | 136 ++ tests/unit/selectmenu/methods.js | 189 +++ tests/unit/selectmenu/options.js | 128 ++ tests/unit/selectmenu/selectmenu_common.js | 34 - tests/unit/selectmenu/selectmenu_core.js | 332 ----- tests/unit/selectmenu/selectmenu_events.js | 136 -- tests/unit/selectmenu/selectmenu_methods.js | 189 --- tests/unit/selectmenu/selectmenu_options.js | 128 -- tests/unit/slider/common.js | 35 + tests/unit/slider/core.js | 309 ++++ tests/unit/slider/events.js | 208 +++ tests/unit/slider/methods.js | 116 ++ tests/unit/slider/options.js | 349 +++++ tests/unit/slider/slider_common.js | 35 - tests/unit/slider/slider_core.js | 309 ---- tests/unit/slider/slider_events.js | 208 --- tests/unit/slider/slider_methods.js | 116 -- tests/unit/slider/slider_options.js | 349 ----- tests/unit/sortable/common.js | 53 + tests/unit/sortable/core.js | 42 + tests/unit/sortable/events.js | 378 +++++ tests/unit/sortable/helper.js | 16 + tests/unit/sortable/methods.js | 129 ++ tests/unit/sortable/options.js | 496 +++++++ tests/unit/sortable/sortable_common.js | 53 - tests/unit/sortable/sortable_core.js | 42 - tests/unit/sortable/sortable_events.js | 378 ----- tests/unit/sortable/sortable_methods.js | 129 -- tests/unit/sortable/sortable_options.js | 496 ------- tests/unit/sortable/sortable_test_helpers.js | 16 - tests/unit/spinner/common.js | 35 + tests/unit/spinner/core.js | 257 ++++ tests/unit/spinner/events.js | 263 ++++ tests/unit/spinner/helper.js | 14 + tests/unit/spinner/methods.js | 211 +++ tests/unit/spinner/options.js | 271 ++++ tests/unit/spinner/spinner_common.js | 35 - tests/unit/spinner/spinner_core.js | 257 ---- tests/unit/spinner/spinner_events.js | 263 ---- tests/unit/spinner/spinner_methods.js | 211 --- tests/unit/spinner/spinner_options.js | 271 ---- tests/unit/spinner/spinner_test_helpers.js | 14 - tests/unit/tabs/common.js | 31 + tests/unit/tabs/core.js | 667 +++++++++ tests/unit/tabs/events.js | 322 +++++ tests/unit/tabs/helper.js | 74 + tests/unit/tabs/methods.js | 290 ++++ tests/unit/tabs/options.js | 374 +++++ tests/unit/tabs/tabs_common.js | 31 - tests/unit/tabs/tabs_core.js | 667 --------- tests/unit/tabs/tabs_events.js | 322 ----- tests/unit/tabs/tabs_methods.js | 290 ---- tests/unit/tabs/tabs_options.js | 374 ----- tests/unit/tabs/tabs_test_helpers.js | 74 - tests/unit/tooltip/common-deprecated.js | 31 + tests/unit/tooltip/common.js | 30 + tests/unit/tooltip/core.js | 224 +++ tests/unit/tooltip/deprecated.html | 29 + tests/unit/tooltip/deprecated.js | 16 + tests/unit/tooltip/events.js | 60 + tests/unit/tooltip/methods.js | 139 ++ tests/unit/tooltip/options.js | 215 +++ tests/unit/tooltip/tooltip_common.js | 30 - tests/unit/tooltip/tooltip_common_deprecated.js | 31 - tests/unit/tooltip/tooltip_core.js | 224 --- tests/unit/tooltip/tooltip_deprecated.html | 29 - tests/unit/tooltip/tooltip_deprecated.js | 16 - tests/unit/tooltip/tooltip_events.js | 60 - tests/unit/tooltip/tooltip_methods.js | 139 -- tests/unit/tooltip/tooltip_options.js | 215 --- tests/unit/widget/animation.js | 263 ++++ tests/unit/widget/classes.js | 146 ++ tests/unit/widget/core.js | 1514 ++++++++++++++++++++ tests/unit/widget/extend.js | 112 ++ tests/unit/widget/widget.html | 8 +- tests/unit/widget/widget_animation.js | 263 ---- tests/unit/widget/widget_classes.js | 146 -- tests/unit/widget/widget_core.js | 1514 -------------------- tests/unit/widget/widget_extend.js | 112 -- 226 files changed, 21475 insertions(+), 21481 deletions(-) delete mode 100644 tests/unit/accordion/accordion_common.js delete mode 100644 tests/unit/accordion/accordion_core.js delete mode 100644 tests/unit/accordion/accordion_events.js delete mode 100644 tests/unit/accordion/accordion_methods.js delete mode 100644 tests/unit/accordion/accordion_options.js delete mode 100644 tests/unit/accordion/accordion_test_helpers.js create mode 100644 tests/unit/accordion/common.js create mode 100644 tests/unit/accordion/core.js create mode 100644 tests/unit/accordion/events.js create mode 100644 tests/unit/accordion/helper.js create mode 100644 tests/unit/accordion/methods.js create mode 100644 tests/unit/accordion/options.js delete mode 100644 tests/unit/autocomplete/autocomplete_common.js delete mode 100644 tests/unit/autocomplete/autocomplete_core.js delete mode 100644 tests/unit/autocomplete/autocomplete_events.js delete mode 100644 tests/unit/autocomplete/autocomplete_methods.js delete mode 100644 tests/unit/autocomplete/autocomplete_options.js create mode 100644 tests/unit/autocomplete/common.js create mode 100644 tests/unit/autocomplete/core.js create mode 100644 tests/unit/autocomplete/events.js create mode 100644 tests/unit/autocomplete/methods.js create mode 100644 tests/unit/autocomplete/options.js delete mode 100644 tests/unit/button/button_common.js delete mode 100644 tests/unit/button/button_core.js delete mode 100644 tests/unit/button/button_events.js delete mode 100644 tests/unit/button/button_methods.js delete mode 100644 tests/unit/button/button_options.js create mode 100644 tests/unit/button/common.js create mode 100644 tests/unit/button/core.js create mode 100644 tests/unit/button/events.js create mode 100644 tests/unit/button/methods.js create mode 100644 tests/unit/button/options.js create mode 100644 tests/unit/datepicker/common.js create mode 100644 tests/unit/datepicker/core.js delete mode 100644 tests/unit/datepicker/datepicker_common.js delete mode 100644 tests/unit/datepicker/datepicker_core.js delete mode 100644 tests/unit/datepicker/datepicker_events.js delete mode 100644 tests/unit/datepicker/datepicker_methods.js delete mode 100644 tests/unit/datepicker/datepicker_options.js delete mode 100644 tests/unit/datepicker/datepicker_test_helpers.js create mode 100644 tests/unit/datepicker/events.js create mode 100644 tests/unit/datepicker/helper.js create mode 100644 tests/unit/datepicker/methods.js create mode 100644 tests/unit/datepicker/options.js create mode 100644 tests/unit/dialog/common-deprecated.js create mode 100644 tests/unit/dialog/common.js create mode 100644 tests/unit/dialog/core.js create mode 100644 tests/unit/dialog/deprecated.html create mode 100644 tests/unit/dialog/deprecated.js delete mode 100644 tests/unit/dialog/dialog_common.js delete mode 100644 tests/unit/dialog/dialog_common_deprecated.js delete mode 100644 tests/unit/dialog/dialog_core.js delete mode 100644 tests/unit/dialog/dialog_deprecated.html delete mode 100644 tests/unit/dialog/dialog_deprecated.js delete mode 100644 tests/unit/dialog/dialog_events.js delete mode 100644 tests/unit/dialog/dialog_methods.js delete mode 100644 tests/unit/dialog/dialog_options.js delete mode 100644 tests/unit/dialog/dialog_test_helpers.js create mode 100644 tests/unit/dialog/events.js create mode 100644 tests/unit/dialog/helper.js create mode 100644 tests/unit/dialog/methods.js create mode 100644 tests/unit/dialog/options.js create mode 100644 tests/unit/draggable/common.js create mode 100644 tests/unit/draggable/core.js delete mode 100644 tests/unit/draggable/draggable_common.js delete mode 100644 tests/unit/draggable/draggable_core.js delete mode 100644 tests/unit/draggable/draggable_events.js delete mode 100644 tests/unit/draggable/draggable_methods.js delete mode 100644 tests/unit/draggable/draggable_options.js delete mode 100644 tests/unit/draggable/draggable_test_helpers.js create mode 100644 tests/unit/draggable/events.js create mode 100644 tests/unit/draggable/helper.js create mode 100644 tests/unit/draggable/methods.js create mode 100644 tests/unit/draggable/options.js create mode 100644 tests/unit/droppable/common-deprecated.js create mode 100644 tests/unit/droppable/common.js create mode 100644 tests/unit/droppable/core.js create mode 100644 tests/unit/droppable/deprecated.html create mode 100644 tests/unit/droppable/deprecated.js delete mode 100644 tests/unit/droppable/droppable_common.js delete mode 100644 tests/unit/droppable/droppable_common_deprecated.js delete mode 100644 tests/unit/droppable/droppable_core.js delete mode 100644 tests/unit/droppable/droppable_deprecated.html delete mode 100644 tests/unit/droppable/droppable_deprecated.js delete mode 100644 tests/unit/droppable/droppable_events.js delete mode 100644 tests/unit/droppable/droppable_methods.js delete mode 100644 tests/unit/droppable/droppable_options.js delete mode 100644 tests/unit/droppable/droppable_test_helpers.js create mode 100644 tests/unit/droppable/events.js create mode 100644 tests/unit/droppable/helper.js create mode 100644 tests/unit/droppable/methods.js create mode 100644 tests/unit/droppable/options.js create mode 100644 tests/unit/effects/core.js delete mode 100644 tests/unit/effects/effects_core.js delete mode 100644 tests/unit/effects/effects_scale.js create mode 100644 tests/unit/effects/scale.js create mode 100644 tests/unit/menu/common.js create mode 100644 tests/unit/menu/core.js create mode 100644 tests/unit/menu/events.js create mode 100644 tests/unit/menu/helper.js delete mode 100644 tests/unit/menu/menu_common.js delete mode 100644 tests/unit/menu/menu_core.js delete mode 100644 tests/unit/menu/menu_events.js delete mode 100644 tests/unit/menu/menu_methods.js delete mode 100644 tests/unit/menu/menu_options.js delete mode 100644 tests/unit/menu/menu_test_helpers.js create mode 100644 tests/unit/menu/methods.js create mode 100644 tests/unit/menu/options.js create mode 100644 tests/unit/position/core.js delete mode 100644 tests/unit/position/position_core.js create mode 100644 tests/unit/progressbar/common.js create mode 100644 tests/unit/progressbar/core.js create mode 100644 tests/unit/progressbar/events.js create mode 100644 tests/unit/progressbar/methods.js create mode 100644 tests/unit/progressbar/options.js delete mode 100644 tests/unit/progressbar/progressbar_common.js delete mode 100644 tests/unit/progressbar/progressbar_core.js delete mode 100644 tests/unit/progressbar/progressbar_events.js delete mode 100644 tests/unit/progressbar/progressbar_methods.js delete mode 100644 tests/unit/progressbar/progressbar_options.js create mode 100644 tests/unit/resizable/common.js create mode 100644 tests/unit/resizable/core.js create mode 100644 tests/unit/resizable/events.js create mode 100644 tests/unit/resizable/helper.js create mode 100644 tests/unit/resizable/methods.js create mode 100644 tests/unit/resizable/options.js delete mode 100644 tests/unit/resizable/resizable_common.js delete mode 100644 tests/unit/resizable/resizable_core.js delete mode 100644 tests/unit/resizable/resizable_events.js delete mode 100644 tests/unit/resizable/resizable_methods.js delete mode 100644 tests/unit/resizable/resizable_options.js delete mode 100644 tests/unit/resizable/resizable_test_helpers.js create mode 100644 tests/unit/selectable/common.js create mode 100644 tests/unit/selectable/core.js create mode 100644 tests/unit/selectable/events.js create mode 100644 tests/unit/selectable/methods.js create mode 100644 tests/unit/selectable/options.js delete mode 100644 tests/unit/selectable/selectable_common.js delete mode 100644 tests/unit/selectable/selectable_core.js delete mode 100644 tests/unit/selectable/selectable_events.js delete mode 100644 tests/unit/selectable/selectable_methods.js delete mode 100644 tests/unit/selectable/selectable_options.js create mode 100644 tests/unit/selectmenu/common.js create mode 100644 tests/unit/selectmenu/core.js create mode 100644 tests/unit/selectmenu/events.js create mode 100644 tests/unit/selectmenu/methods.js create mode 100644 tests/unit/selectmenu/options.js delete mode 100644 tests/unit/selectmenu/selectmenu_common.js delete mode 100644 tests/unit/selectmenu/selectmenu_core.js delete mode 100644 tests/unit/selectmenu/selectmenu_events.js delete mode 100644 tests/unit/selectmenu/selectmenu_methods.js delete mode 100644 tests/unit/selectmenu/selectmenu_options.js create mode 100644 tests/unit/slider/common.js create mode 100644 tests/unit/slider/core.js create mode 100644 tests/unit/slider/events.js create mode 100644 tests/unit/slider/methods.js create mode 100644 tests/unit/slider/options.js delete mode 100644 tests/unit/slider/slider_common.js delete mode 100644 tests/unit/slider/slider_core.js delete mode 100644 tests/unit/slider/slider_events.js delete mode 100644 tests/unit/slider/slider_methods.js delete mode 100644 tests/unit/slider/slider_options.js create mode 100644 tests/unit/sortable/common.js create mode 100644 tests/unit/sortable/core.js create mode 100644 tests/unit/sortable/events.js create mode 100644 tests/unit/sortable/helper.js create mode 100644 tests/unit/sortable/methods.js create mode 100644 tests/unit/sortable/options.js delete mode 100644 tests/unit/sortable/sortable_common.js delete mode 100644 tests/unit/sortable/sortable_core.js delete mode 100644 tests/unit/sortable/sortable_events.js delete mode 100644 tests/unit/sortable/sortable_methods.js delete mode 100644 tests/unit/sortable/sortable_options.js delete mode 100644 tests/unit/sortable/sortable_test_helpers.js create mode 100644 tests/unit/spinner/common.js create mode 100644 tests/unit/spinner/core.js create mode 100644 tests/unit/spinner/events.js create mode 100644 tests/unit/spinner/helper.js create mode 100644 tests/unit/spinner/methods.js create mode 100644 tests/unit/spinner/options.js delete mode 100644 tests/unit/spinner/spinner_common.js delete mode 100644 tests/unit/spinner/spinner_core.js delete mode 100644 tests/unit/spinner/spinner_events.js delete mode 100644 tests/unit/spinner/spinner_methods.js delete mode 100644 tests/unit/spinner/spinner_options.js delete mode 100644 tests/unit/spinner/spinner_test_helpers.js create mode 100644 tests/unit/tabs/common.js create mode 100644 tests/unit/tabs/core.js create mode 100644 tests/unit/tabs/events.js create mode 100644 tests/unit/tabs/helper.js create mode 100644 tests/unit/tabs/methods.js create mode 100644 tests/unit/tabs/options.js delete mode 100644 tests/unit/tabs/tabs_common.js delete mode 100644 tests/unit/tabs/tabs_core.js delete mode 100644 tests/unit/tabs/tabs_events.js delete mode 100644 tests/unit/tabs/tabs_methods.js delete mode 100644 tests/unit/tabs/tabs_options.js delete mode 100644 tests/unit/tabs/tabs_test_helpers.js create mode 100644 tests/unit/tooltip/common-deprecated.js create mode 100644 tests/unit/tooltip/common.js create mode 100644 tests/unit/tooltip/core.js create mode 100644 tests/unit/tooltip/deprecated.html create mode 100644 tests/unit/tooltip/deprecated.js create mode 100644 tests/unit/tooltip/events.js create mode 100644 tests/unit/tooltip/methods.js create mode 100644 tests/unit/tooltip/options.js delete mode 100644 tests/unit/tooltip/tooltip_common.js delete mode 100644 tests/unit/tooltip/tooltip_common_deprecated.js delete mode 100644 tests/unit/tooltip/tooltip_core.js delete mode 100644 tests/unit/tooltip/tooltip_deprecated.html delete mode 100644 tests/unit/tooltip/tooltip_deprecated.js delete mode 100644 tests/unit/tooltip/tooltip_events.js delete mode 100644 tests/unit/tooltip/tooltip_methods.js delete mode 100644 tests/unit/tooltip/tooltip_options.js create mode 100644 tests/unit/widget/animation.js create mode 100644 tests/unit/widget/classes.js create mode 100644 tests/unit/widget/core.js create mode 100644 tests/unit/widget/extend.js delete mode 100644 tests/unit/widget/widget_animation.js delete mode 100644 tests/unit/widget/widget_classes.js delete mode 100644 tests/unit/widget/widget_core.js delete mode 100644 tests/unit/widget/widget_extend.js (limited to 'tests') diff --git a/tests/lib/bootstrap.js b/tests/lib/bootstrap.js index b9598c6df..6d608f2eb 100644 --- a/tests/lib/bootstrap.js +++ b/tests/lib/bootstrap.js @@ -123,14 +123,14 @@ function swarmInject() { if ( widget ) { modules = modules.concat([ - widget + ( deprecated ? "_common_deprecated" : "_common" ), - widget + "_core", - widget + "_events", - widget + "_methods", - widget + "_options" + ( deprecated ? "common-deprecated" : "common" ), + "core", + "events", + "methods", + "options" ]); if ( deprecated ) { - modules = modules.concat( widget + "_deprecated" ); + modules = modules.concat( "deprecated" ); } } diff --git a/tests/unit/accordion/accordion_common.js b/tests/unit/accordion/accordion_common.js deleted file mode 100644 index 8a859f0ca..000000000 --- a/tests/unit/accordion/accordion_common.js +++ /dev/null @@ -1,32 +0,0 @@ -define( [ - "lib/common", - "ui/accordion" -], function( common ) { - -common.testWidget( "accordion", { - defaults: { - active: 0, - animate: {}, - classes: { - "ui-accordion-header": "ui-corner-top", - "ui-accordion-header-collapsed": "ui-corner-all", - "ui-accordion-content": "ui-corner-bottom" - }, - collapsible: false, - disabled: false, - event: "click", - header: "> li > :first-child, > :not(li):even", - heightStyle: "auto", - icons: { - "activeHeader": "ui-icon-triangle-1-s", - "header": "ui-icon-triangle-1-e" - }, - - // callbacks - activate: null, - beforeActivate: null, - create: null - } -}); - -} ); diff --git a/tests/unit/accordion/accordion_core.js b/tests/unit/accordion/accordion_core.js deleted file mode 100644 index bd3b56752..000000000 --- a/tests/unit/accordion/accordion_core.js +++ /dev/null @@ -1,207 +0,0 @@ -define( [ - "jquery", - "./accordion_test_helpers", - "ui/accordion" -], function( $, testHelper ) { - -var setupTeardown = testHelper.setupTeardown, - state = testHelper.state; - -module( "accordion: core", setupTeardown() ); - -$.each( { div: "#list1", ul: "#navigation", dl: "#accordion-dl" }, function( type, selector ) { - test( "markup structure: " + type, function( assert ) { - expect( 10 ); - var element = $( selector ).accordion(), - headers = element.find( ".ui-accordion-header" ), - content = headers.next(); - - assert.hasClasses( element, "ui-accordion ui-widget" ); - equal( headers.length, 3, ".ui-accordion-header elements exist, correct number" ); - assert.hasClasses( headers[ 0 ], - "ui-accordion-header ui-accordion-header-active ui-accordion-icons" ); - assert.hasClasses( headers[ 1 ], - "ui-accordion-header ui-accordion-header-collapsed ui-accordion-icons" ); - assert.hasClasses( headers[ 2 ], - "ui-accordion-header ui-accordion-header-collapsed ui-accordion-icons" ); - equal( content.length, 3, ".ui-accordion-content elements exist, correct number" ); - assert.hasClasses( content[ 0 ], - "ui-accordion-content ui-widget-content ui-accordion-content-active" ); - assert.hasClasses( content[ 1 ], "ui-accordion-content ui-widget-content" ); - assert.hasClasses( content[ 2 ], "ui-accordion-content ui-widget-content" ); - deepEqual( element.find( ".ui-accordion-header" ).next().get(), - element.find( ".ui-accordion-content" ).get(), - "content panels come immediately after headers" ); - }); -}); - -test( "handle click on header-descendant", function() { - expect( 1 ); - var element = $( "#navigation" ).accordion(); - $( "#navigation h2:eq(1) a" ).click(); - state( element, 0, 1, 0 ); -}); - -test( "accessibility", function () { - expect( 61 ); - var element = $( "#list1" ).accordion({ - active: 1, - collapsible: true - }), - headers = element.find( ".ui-accordion-header" ); - - equal( element.attr( "role" ), "tablist", "element role" ); - headers.each(function( i ) { - var header = headers.eq( i ), - panel = header.next(); - equal( header.attr( "role" ), "tab", "header " + i + " role" ); - equal( header.attr( "aria-controls" ), panel.attr( "id" ), "header " + i + " aria-controls" ); - equal( panel.attr( "role" ), "tabpanel", "panel " + i + " role" ); - equal( panel.attr( "aria-labelledby" ), header.attr( "id" ), "panel " + i + " aria-labelledby" ); - }); - - equal( headers.eq( 1 ).attr( "tabindex" ), 0, "active header has tabindex=0" ); - equal( headers.eq( 1 ).attr( "aria-selected" ), "true", "active tab (1) has aria-selected=true" ); - equal( headers.eq( 1 ).attr( "aria-expanded" ), "true", "active tab (1) has aria-expanded=true" ); - equal( headers.eq( 1 ).next().attr( "aria-hidden" ), "false", "active tabpanel (1) has aria-hidden=false" ); - equal( headers.eq( 0 ).attr( "tabindex" ), -1, "inactive header (0) has tabindex=-1" ); - equal( headers.eq( 0 ).attr( "aria-selected" ), "false", "inactive tab (0) has aria-selected=false" ); - equal( headers.eq( 0 ).attr( "aria-expanded" ), "false", "inactive tab (0) has aria-expanded=false" ); - equal( headers.eq( 0 ).next().attr( "aria-hidden" ), "true", "inactive tabpanel (0) has aria-hidden=true" ); - equal( headers.eq( 2 ).attr( "tabindex" ), -1, "inactive header (2) has tabindex=-1" ); - equal( headers.eq( 2 ).attr( "aria-selected" ), "false", "inactive tab (2) has aria-selected=false" ); - equal( headers.eq( 2 ).attr( "aria-expanded" ), "false", "inactive tab (2) has aria-expanded=false" ); - equal( headers.eq( 2 ).next().attr( "aria-hidden" ), "true", "inactive tabpanel (2) has aria-hidden=true" ); - - element.accordion( "option", "active", 0 ); - equal( headers.eq( 0 ).attr( "tabindex" ), 0, "active header (0) has tabindex=0" ); - equal( headers.eq( 0 ).attr( "aria-selected" ), "true", "active tab (0) has aria-selected=true" ); - equal( headers.eq( 0 ).attr( "aria-expanded" ), "true", "active tab (0) has aria-expanded=true" ); - equal( headers.eq( 0 ).next().attr( "aria-hidden" ), "false", "active tabpanel (0) has aria-hidden=false" ); - equal( headers.eq( 1 ).attr( "tabindex" ), -1, "inactive header (1) has tabindex=-1" ); - equal( headers.eq( 1 ).attr( "aria-selected" ), "false", "inactive tab (1) has aria-selected=false" ); - equal( headers.eq( 1 ).attr( "aria-expanded" ), "false", "inactive tab (1) has aria-expanded=false" ); - equal( headers.eq( 1 ).next().attr( "aria-hidden" ), "true", "inactive tabpanel (1) has aria-hidden=true" ); - equal( headers.eq( 2 ).attr( "tabindex" ), -1, "inactive header (2) has tabindex=-1" ); - equal( headers.eq( 2 ).attr( "aria-selected" ), "false", "inactive tab (2) has aria-selected=false" ); - equal( headers.eq( 2 ).attr( "aria-expanded" ), "false", "inactive tab (2) has aria-expanded=false" ); - equal( headers.eq( 2 ).next().attr( "aria-hidden" ), "true", "inactive tabpanel (2) has aria-hidden=true" ); - - element.accordion( "option", "active", false ); - equal( headers.eq( 0 ).attr( "tabindex" ), 0, "previously active header (0) has tabindex=0" ); - equal( headers.eq( 0 ).attr( "aria-selected" ), "false", "inactive tab (0) has aria-selected=false" ); - equal( headers.eq( 0 ).attr( "aria-expanded" ), "false", "inactive tab (0) has aria-expanded=false" ); - equal( headers.eq( 0 ).next().attr( "aria-hidden" ), "true", "inactive tabpanel (0) has aria-hidden=true" ); - equal( headers.eq( 1 ).attr( "tabindex" ), -1, "inactive header (1) has tabindex=-1" ); - equal( headers.eq( 1 ).attr( "aria-selected" ), "false", "inactive tab (1) has aria-selected=false" ); - equal( headers.eq( 1 ).attr( "aria-expanded" ), "false", "inactive tab (1) has aria-expanded=false" ); - equal( headers.eq( 1 ).next().attr( "aria-hidden" ), "true", "inactive tabpanel (1) has aria-hidden=true" ); - equal( headers.eq( 2 ).attr( "tabindex" ), -1, "inactive header (2) has tabindex=-1" ); - equal( headers.eq( 2 ).attr( "aria-selected" ), "false", "inactive tab (2) has aria-selected=false" ); - equal( headers.eq( 2 ).attr( "aria-expanded" ), "false", "inactive tab (2) has aria-expanded=false" ); - equal( headers.eq( 2 ).next().attr( "aria-hidden" ), "true", "inactive tabpanel (2) has aria-hidden=true" ); - - element.accordion( "option", "active", 1 ); - equal( headers.eq( 1 ).attr( "tabindex" ), 0, "active header has tabindex=0" ); - equal( headers.eq( 1 ).attr( "aria-selected" ), "true", "active tab (1) has aria-selected=true" ); - equal( headers.eq( 1 ).attr( "aria-expanded" ), "true", "active tab (1) has aria-expanded=true" ); - equal( headers.eq( 1 ).next().attr( "aria-hidden" ), "false", "active tabpanel (1) has aria-hidden=false" ); - equal( headers.eq( 0 ).attr( "tabindex" ), -1, "inactive header (0) has tabindex=-1" ); - equal( headers.eq( 0 ).attr( "aria-selected" ), "false", "inactive tab (0) has aria-selected=false" ); - equal( headers.eq( 0 ).attr( "aria-expanded" ), "false", "inactive tab (0) has aria-expanded=false" ); - equal( headers.eq( 0 ).next().attr( "aria-hidden" ), "true", "inactive tabpanel (0) has aria-hidden=true" ); - equal( headers.eq( 2 ).attr( "tabindex" ), -1, "inactive header (2) has tabindex=-1" ); - equal( headers.eq( 2 ).attr( "aria-selected" ), "false", "inactive tab (2) has aria-selected=false" ); - equal( headers.eq( 2 ).attr( "aria-expanded" ), "false", "inactive tab (2) has aria-expanded=false" ); - equal( headers.eq( 2 ).next().attr( "aria-hidden" ), "true", "inactive tabpanel (2) has aria-hidden=true" ); - -}); - -asyncTest( "keyboard support", function( assert ) { - expect( 13 ); - var element = $( "#list1" ).accordion(), - headers = element.find( ".ui-accordion-header" ), - anchor = headers.eq( 1 ).next().find( "a" ).eq( 0 ), - keyCode = $.ui.keyCode; - equal( headers.filter( ".ui-state-focus" ).length, 0, "no headers focused on init" ); - headers.eq( 0 ).simulate( "focus" ); - setTimeout( step1 ); - - function step1() { - assert.hasClasses( headers.eq( 0 ), "ui-state-focus", "first header has focus" ); - headers.eq( 0 ).simulate( "keydown", { keyCode: keyCode.DOWN } ); - setTimeout( step2 ); - } - - // Support: IE 11 with jQuery 1.7 - 1.8 only - // All of the setTimeouts() from keydowns aren't necessary with newer jQuery. - // Only the explicit focus simulations require them. - function step2() { - assert.hasClasses( headers.eq( 1 ), "ui-state-focus", "DOWN moves focus to next header" ); - headers.eq( 1 ).simulate( "keydown", { keyCode: keyCode.RIGHT } ); - setTimeout( step3 ); - } - - function step3() { - assert.hasClasses( headers.eq( 2 ), "ui-state-focus", "RIGHT moves focus to next header" ); - headers.eq( 2 ).simulate( "keydown", { keyCode: keyCode.DOWN } ); - setTimeout( step4 ); - } - - function step4() { - assert.hasClasses( headers.eq( 0 ), "ui-state-focus", "DOWN wraps focus to first header" ); - headers.eq( 0 ).simulate( "keydown", { keyCode: keyCode.UP } ); - setTimeout( step5 ); - } - - function step5() { - assert.hasClasses( headers.eq( 2 ), "ui-state-focus", "UP wraps focus to last header" ); - headers.eq( 2 ).simulate( "keydown", { keyCode: keyCode.LEFT } ); - setTimeout( step6 ); - } - - function step6() { - assert.hasClasses( headers.eq( 1 ), - "ui-state-focus", "LEFT moves focus to previous header" ); - headers.eq( 1 ).simulate( "keydown", { keyCode: keyCode.HOME } ); - setTimeout( step7 ); - } - - function step7() { - assert.hasClasses( headers.eq( 0 ), "ui-state-focus", "HOME moves focus to first header" ); - headers.eq( 0 ).simulate( "keydown", { keyCode: keyCode.END } ); - setTimeout( step8 ); - } - - function step8() { - assert.hasClasses( headers.eq( 2 ), "ui-state-focus", "END moves focus to last header" ); - headers.eq( 2 ).simulate( "keydown", { keyCode: keyCode.ENTER } ); - setTimeout( step9 ); - } - - function step9() { - equal( element.accordion( "option", "active" ) , 2, "ENTER activates panel" ); - headers.eq( 1 ).simulate( "keydown", { keyCode: keyCode.SPACE } ); - setTimeout( step10 ); - } - - function step10() { - equal( element.accordion( "option", "active" ), 1, "SPACE activates panel" ); - anchor.simulate( "focus" ); - setTimeout( step11 ); - } - - function step11() { - assert.lacksClasses( headers.eq( 1 ), "ui-state-focus", - "header loses focus when focusing inside the panel" ); - anchor.simulate( "keydown", { keyCode: keyCode.UP, ctrlKey: true } ); - setTimeout( step12 ); - } - - function step12() { - assert.hasClasses( headers.eq( 1 ), "ui-state-focus", "CTRL+UP moves focus to header" ); - start(); - } -}); - -} ); diff --git a/tests/unit/accordion/accordion_events.js b/tests/unit/accordion/accordion_events.js deleted file mode 100644 index ac05df30d..000000000 --- a/tests/unit/accordion/accordion_events.js +++ /dev/null @@ -1,168 +0,0 @@ -define( [ - "jquery", - "./accordion_test_helpers", - "ui/accordion" -], function( $, testHelper ) { - -var setupTeardown = testHelper.setupTeardown, - state = testHelper.state; - -module( "accordion: events", setupTeardown() ); - -test( "create", function() { - expect( 10 ); - - var element = $( "#list1" ), - headers = element.children( "h3" ), - contents = headers.next(); - - element.accordion({ - create: function( event, ui ) { - equal( ui.header.length, 1, "header length" ); - strictEqual( ui.header[ 0 ], headers[ 0 ], "header" ); - equal( ui.panel.length, 1, "panel length" ); - strictEqual( ui.panel[ 0 ], contents[ 0 ], "panel" ); - } - }); - element.accordion( "destroy" ); - - element.accordion({ - active: 2, - create: function( event, ui ) { - equal( ui.header.length, 1, "header length" ); - strictEqual( ui.header[ 0 ], headers[ 2 ], "header" ); - equal( ui.panel.length, 1, "panel length" ); - strictEqual( ui.panel[ 0 ], contents[ 2 ], "panel" ); - } - }); - element.accordion( "destroy" ); - - element.accordion({ - active: false, - collapsible: true, - create: function( event, ui ) { - equal( ui.header.length, 0, "header length" ); - equal( ui.panel.length, 0, "panel length" ); - } - }); - element.accordion( "destroy" ); -}); - -test( "beforeActivate", function() { - expect( 38 ); - var element = $( "#list1" ).accordion({ - active: false, - collapsible: true - }), - headers = element.find( ".ui-accordion-header" ), - content = element.find( ".ui-accordion-content" ); - - element.one( "accordionbeforeactivate", function( event, ui ) { - ok( !( "originalEvent" in event ) ); - equal( ui.oldHeader.length, 0 ); - equal( ui.oldPanel.length, 0 ); - equal( ui.newHeader.length, 1 ); - strictEqual( ui.newHeader[ 0 ], headers[ 0 ] ); - equal( ui.newPanel.length, 1 ); - strictEqual( ui.newPanel[ 0 ], content[ 0 ] ); - state( element, 0, 0, 0 ); - }); - element.accordion( "option", "active", 0 ); - state( element, 1, 0, 0 ); - - element.one( "accordionbeforeactivate", function( event, ui ) { - equal( event.originalEvent.type, "click" ); - equal( ui.oldHeader.length, 1 ); - strictEqual( ui.oldHeader[ 0 ], headers[ 0 ] ); - equal( ui.oldPanel.length, 1 ); - strictEqual( ui.oldPanel[ 0 ], content[ 0 ] ); - equal( ui.newHeader.length, 1 ); - strictEqual( ui.newHeader[ 0 ], headers[ 1 ] ); - equal( ui.newPanel.length, 1 ); - strictEqual( ui.newPanel[ 0 ], content[ 1 ] ); - state( element, 1, 0, 0 ); - }); - headers.eq( 1 ).click(); - state( element, 0, 1, 0 ); - - element.one( "accordionbeforeactivate", function( event, ui ) { - ok( !( "originalEvent" in event ) ); - equal( ui.oldHeader.length, 1 ); - strictEqual( ui.oldHeader[ 0 ], headers[ 1 ] ); - equal( ui.oldPanel.length, 1 ); - strictEqual( ui.oldPanel[ 0 ], content[ 1 ] ); - equal( ui.newHeader.length, 0 ); - equal( ui.newPanel.length, 0 ); - state( element, 0, 1, 0 ); - }); - element.accordion( "option", "active", false ); - state( element, 0, 0, 0 ); - - element.one( "accordionbeforeactivate", function( event, ui ) { - ok( !( "originalEvent" in event ) ); - equal( ui.oldHeader.length, 0 ); - equal( ui.oldPanel.length, 0 ); - equal( ui.newHeader.length, 1 ); - strictEqual( ui.newHeader[ 0 ], headers[ 2 ] ); - equal( ui.newPanel.length, 1 ); - strictEqual( ui.newPanel[ 0 ], content[ 2 ] ); - event.preventDefault(); - state( element, 0, 0, 0 ); - }); - element.accordion( "option", "active", 2 ); - state( element, 0, 0, 0 ); -}); - -test( "activate", function() { - expect( 21 ); - var element = $( "#list1" ).accordion({ - active: false, - collapsible: true - }), - headers = element.find( ".ui-accordion-header" ), - content = element.find( ".ui-accordion-content" ); - - element.one( "accordionactivate", function( event, ui ) { - equal( ui.oldHeader.length, 0 ); - equal( ui.oldPanel.length, 0 ); - equal( ui.newHeader.length, 1 ); - strictEqual( ui.newHeader[ 0 ], headers[ 0 ] ); - equal( ui.newPanel.length, 1 ); - strictEqual( ui.newPanel[ 0 ], content[ 0 ] ); - }); - element.accordion( "option", "active", 0 ); - - element.one( "accordionactivate", function( event, ui ) { - equal( ui.oldHeader.length, 1 ); - strictEqual( ui.oldHeader[ 0 ], headers[ 0 ] ); - equal( ui.oldPanel.length, 1 ); - strictEqual( ui.oldPanel[ 0 ], content[ 0 ] ); - equal( ui.newHeader.length, 1 ); - strictEqual( ui.newHeader[ 0 ], headers[ 1 ] ); - equal( ui.newPanel.length, 1 ); - strictEqual( ui.newPanel[ 0 ], content[ 1 ] ); - }); - headers.eq( 1 ).click(); - - element.one( "accordionactivate", function( event, ui ) { - equal( ui.oldHeader.length, 1 ); - strictEqual( ui.oldHeader[ 0 ], headers[ 1 ] ); - equal( ui.oldPanel.length, 1 ); - strictEqual( ui.oldPanel[ 0 ], content[ 1 ] ); - equal( ui.newHeader.length, 0 ); - equal( ui.newPanel.length, 0 ); - }); - element.accordion( "option", "active", false ); - - // prevent activation - element.one( "accordionbeforeactivate", function( event ) { - ok( true ); - event.preventDefault(); - }); - element.one( "accordionactivate", function() { - ok( false ); - }); - element.accordion( "option", "active", 1 ); -}); - -} ); diff --git a/tests/unit/accordion/accordion_methods.js b/tests/unit/accordion/accordion_methods.js deleted file mode 100644 index f33996c36..000000000 --- a/tests/unit/accordion/accordion_methods.js +++ /dev/null @@ -1,136 +0,0 @@ -define( [ - "jquery", - "./accordion_test_helpers", - "ui/accordion" -], function( $, testHelper ) { - -var equalHeight = testHelper.equalHeight, - setupTeardown = testHelper.setupTeardown, - state = testHelper.state; - -module( "accordion: methods", setupTeardown() ); - -test( "destroy", function( assert ) { - expect( 1 ); - assert.domEqual( "#list1", function() { - $( "#list1" ).accordion().accordion( "destroy" ); - }); -}); - -test( "enable/disable", function( assert ) { - expect( 7 ); - var element = $( "#list1" ).accordion(); - state( element, 1, 0, 0 ); - element.accordion( "disable" ); - - assert.hasClasses( element, "ui-state-disabled" ); - - equal( element.attr( "aria-disabled" ), "true", "element gets aria-disabled" ); - assert.hasClasses( element, "ui-accordion-disabled" ); - - // event does nothing - element.find( ".ui-accordion-header" ).eq( 1 ).trigger( "click" ); - state( element, 1, 0, 0 ); - // option still works - element.accordion( "option", "active", 1 ); - state( element, 0, 1, 0 ); - element.accordion( "enable" ); - element.accordion( "option", "active", 2 ); - state( element, 0, 0, 1 ); -}); - -test( "refresh", function() { - expect( 19 ); - var element = $( "#navigation" ) - .parent() - .height( 300 ) - .end() - .accordion({ - heightStyle: "fill" - }); - equalHeight( element, 255 ); - - element.parent().height( 500 ); - element.accordion( "refresh" ); - equalHeight( element, 455 ); - - element = $( "#list1" ); - element.accordion(); - state( element, 1, 0, 0 ); - - // disable panel via markup - element.find( "h3.bar" ).eq( 1 ).addClass( "ui-state-disabled" ); - element.accordion( "refresh" ); - state( element, 1, 0, 0 ); - - // don't add multiple icons - element.accordion( "refresh" ); - equal( element.find( ".ui-accordion-header-icon" ).length, 3 ); - - // add a panel - element - .append("

new 1

") - .append("
new 1
"); - element.accordion( "refresh" ); - state( element, 1, 0, 0, 0 ); - - // remove all tabs - element.find( "h3.bar, div.foo" ).remove(); - element.accordion( "refresh" ); - state( element ); - equal( element.accordion( "option", "active" ), false, "no active accordion panel" ); - - // add panels - element - .append("

new 2

") - .append("
new 2
") - .append("

new 3

") - .append("
new 3
") - .append("

new 4

") - .append("
new 4
") - .append("

new 5

") - .append("
new 5
"); - element.accordion( "refresh" ); - state( element, 1, 0, 0, 0 ); - - // activate third tab - element.accordion( "option", "active", 2 ); - state( element, 0, 0, 1, 0 ); - - // remove fourth panel, third panel should stay active - element.find( "h3.bar" ).eq( 3 ).remove(); - element.find( "div.foo" ).eq( 3 ).remove(); - element.accordion( "refresh" ); - state( element, 0, 0, 1 ); - - // remove third (active) panel, second panel should become active - element.find( "h3.bar" ).eq( 2 ).remove(); - element.find( "div.foo" ).eq( 2 ).remove(); - element.accordion( "refresh" ); - state( element, 0, 1 ); - - // remove first panel, previously active panel (now first) should stay active - element.find( "h3.bar" ).eq( 0 ).remove(); - element.find( "div.foo" ).eq( 0 ).remove(); - element.accordion( "refresh" ); - state( element, 1 ); - - // collapse all panels - element.accordion( "option", { - collapsible: true, - active: false - }); - state( element, 0 ); - element.accordion( "refresh" ); - state( element, 0 ); -}); - -test( "widget", function() { - expect( 2 ); - var element = $( "#list1" ).accordion(), - widgetElement = element.accordion( "widget" ); - equal( widgetElement.length, 1, "one element" ); - strictEqual( widgetElement[ 0 ], element[ 0 ], "same element" ); -}); - -} ); diff --git a/tests/unit/accordion/accordion_options.js b/tests/unit/accordion/accordion_options.js deleted file mode 100644 index d33241dac..000000000 --- a/tests/unit/accordion/accordion_options.js +++ /dev/null @@ -1,467 +0,0 @@ -define( [ - "jquery", - "./accordion_test_helpers", - "ui/accordion" -], function( $, testHelper ) { - -var equalHeight = testHelper.equalHeight, - setupTeardown = testHelper.setupTeardown, - state = testHelper.state; - -module( "accordion: options", setupTeardown() ); - -test( "{ active: default }", function() { - expect( 2 ); - var element = $( "#list1" ).accordion(); - equal( element.accordion( "option", "active" ), 0 ); - state( element, 1, 0, 0 ); -}); - -test( "{ active: null }", function() { - expect( 2 ); - var element = $( "#list1" ).accordion({ - active: null - }); - equal( element.accordion( "option", "active" ), 0 ); - state( element, 1, 0, 0 ); -}); - -test( "{ active: false }", function() { - expect( 7 ); - var element = $( "#list1" ).accordion({ - active: false, - collapsible: true - }); - state( element, 0, 0, 0 ); - equal( element.find( ".ui-accordion-header.ui-state-active" ).length, 0, "no headers selected" ); - equal( element.accordion( "option", "active" ), false ); - - element.accordion( "option", "collapsible", false ); - state( element, 1, 0, 0 ); - equal( element.accordion( "option", "active" ), 0 ); - - element.accordion( "destroy" ); - element.accordion({ - active: false - }); - state( element, 1, 0, 0 ); - strictEqual( element.accordion( "option", "active" ), 0 ); -}); - -test( "{ active: Number }", function() { - expect( 8 ); - var element = $( "#list1" ).accordion({ - active: 2 - }); - equal( element.accordion( "option", "active" ), 2 ); - state( element, 0, 0, 1 ); - - element.accordion( "option", "active", 0 ); - equal( element.accordion( "option", "active" ), 0 ); - state( element, 1, 0, 0 ); - - element.find( ".ui-accordion-header" ).eq( 1 ).click(); - equal( element.accordion( "option", "active" ), 1 ); - state( element, 0, 1, 0 ); - - element.accordion( "option", "active", 10 ); - equal( element.accordion( "option", "active" ), 1 ); - state( element, 0, 1, 0 ); -}); - -test( "{ active: -Number }", function() { - expect( 8 ); - var element = $( "#list1" ).accordion({ - active: -1 - }); - equal( element.accordion( "option", "active" ), 2 ); - state( element, 0, 0, 1 ); - - element.accordion( "option", "active", -2 ); - equal( element.accordion( "option", "active" ), 1 ); - state( element, 0, 1, 0 ); - - element.accordion( "option", "active", -10 ); - equal( element.accordion( "option", "active" ), 1 ); - state( element, 0, 1, 0 ); - - element.accordion( "option", "active", -3 ); - equal( element.accordion( "option", "active" ), 0 ); - state( element, 1, 0, 0 ); -}); - -test( "{ animate: false }", function() { - expect( 3 ); - var element = $( "#list1" ).accordion({ - animate: false - }), - panels = element.find( ".ui-accordion-content" ), - animate = $.fn.animate; - $.fn.animate = function() { - ok( false, ".animate() called" ); - }; - - ok( panels.eq( 0 ).is( ":visible" ), "first panel visible" ); - element.accordion( "option", "active", 1 ); - ok( panels.eq( 0 ).is( ":hidden" ), "first panel hidden" ); - ok( panels.eq( 1 ).is( ":visible" ), "second panel visible" ); - $.fn.animate = animate; -}); - -asyncTest( "{ animate: Number }", function() { - expect( 7 ); - var element = $( "#list1" ).accordion({ - animate: 100 - }), - panels = element.find( ".ui-accordion-content" ), - animate = $.fn.animate; - // called twice (both panels) - $.fn.animate = function( props, options ) { - equal( options.duration, 100, "correct duration" ); - equal( options.easing, undefined, "default easing" ); - animate.apply( this, arguments ); - }; - - ok( panels.eq( 0 ).is( ":visible" ), "first panel visible" ); - element.accordion( "option", "active", 1 ); - panels.promise().done(function() { - ok( panels.eq( 0 ).is( ":hidden" ), "first panel hidden" ); - ok( panels.eq( 1 ).is( ":visible" ), "second panel visible" ); - $.fn.animate = animate; - start(); - }); -}); - -asyncTest( "{ animate: String }", function() { - expect( 7 ); - var element = $( "#list1" ).accordion({ - animate: "linear" - }), - panels = element.find( ".ui-accordion-content" ), - animate = $.fn.animate; - // called twice (both panels) - $.fn.animate = function( props, options ) { - equal( options.duration, undefined, "default duration" ); - equal( options.easing, "linear", "correct easing" ); - animate.apply( this, arguments ); - }; - - ok( panels.eq( 0 ).is( ":visible" ), "first panel visible" ); - element.accordion( "option", "active", 1 ); - panels.promise().done(function() { - ok( panels.eq( 0 ).is( ":hidden" ), "first panel hidden" ); - ok( panels.eq( 1 ).is( ":visible" ), "second panel visible" ); - $.fn.animate = animate; - start(); - }); -}); - -asyncTest( "{ animate: {} }", function() { - expect( 7 ); - var element = $( "#list1" ).accordion({ - animate: {} - }), - panels = element.find( ".ui-accordion-content" ), - animate = $.fn.animate; - // called twice (both panels) - $.fn.animate = function( props, options ) { - equal( options.duration, undefined, "default duration" ); - equal( options.easing, undefined, "default easing" ); - animate.apply( this, arguments ); - }; - - ok( panels.eq( 0 ).is( ":visible" ), "first panel visible" ); - element.accordion( "option", "active", 1 ); - panels.promise().done(function() { - ok( panels.eq( 0 ).is( ":hidden" ), "first panel hidden" ); - ok( panels.eq( 1 ).is( ":visible" ), "second panel visible" ); - $.fn.animate = animate; - start(); - }); -}); - -asyncTest( "{ animate: { duration, easing } }", function() { - expect( 7 ); - var element = $( "#list1" ).accordion({ - animate: { duration: 100, easing: "linear" } - }), - panels = element.find( ".ui-accordion-content" ), - animate = $.fn.animate; - // called twice (both panels) - $.fn.animate = function( props, options ) { - equal( options.duration, 100, "correct duration" ); - equal( options.easing, "linear", "correct easing" ); - animate.apply( this, arguments ); - }; - - ok( panels.eq( 0 ).is( ":visible" ), "first panel visible" ); - element.accordion( "option", "active", 1 ); - panels.promise().done(function() { - ok( panels.eq( 0 ).is( ":hidden" ), "first panel hidden" ); - ok( panels.eq( 1 ).is( ":visible" ), "second panel visible" ); - $.fn.animate = animate; - start(); - }); -}); - -asyncTest( "{ animate: { duration, easing } }, animate down", function() { - expect( 7 ); - var element = $( "#list1" ).accordion({ - active: 1, - animate: { duration: 100, easing: "linear" } - }), - panels = element.find( ".ui-accordion-content" ), - animate = $.fn.animate; - // called twice (both panels) - $.fn.animate = function( props, options ) { - equal( options.duration, 100, "correct duration" ); - equal( options.easing, "linear", "correct easing" ); - animate.apply( this, arguments ); - }; - - ok( panels.eq( 1 ).is( ":visible" ), "first panel visible" ); - element.accordion( "option", "active", 0 ); - panels.promise().done(function() { - ok( panels.eq( 1 ).is( ":hidden" ), "first panel hidden" ); - ok( panels.eq( 0 ).is( ":visible" ), "second panel visible" ); - $.fn.animate = animate; - start(); - }); -}); - -asyncTest( "{ animate: { duration, easing, down } }, animate down", function() { - expect( 7 ); - var element = $( "#list1" ).accordion({ - active: 1, - animate: { - duration: 100, - easing: "linear", - down: { - easing: "swing" - } - } - }), - panels = element.find( ".ui-accordion-content" ), - animate = $.fn.animate; - // called twice (both panels) - $.fn.animate = function( props, options ) { - equal( options.duration, 100, "correct duration" ); - equal( options.easing, "swing", "correct easing" ); - animate.apply( this, arguments ); - }; - - ok( panels.eq( 1 ).is( ":visible" ), "first panel visible" ); - element.accordion( "option", "active", 0 ); - panels.promise().done(function() { - ok( panels.eq( 1 ).is( ":hidden" ), "first panel hidden" ); - ok( panels.eq( 0 ).is( ":visible" ), "second panel visible" ); - $.fn.animate = animate; - start(); - }); -}); - -test( "{ collapsible: false }", function() { - expect( 4 ); - var element = $( "#list1" ).accordion({ - active: 1 - }); - element.accordion( "option", "active", false ); - equal( element.accordion( "option", "active" ), 1 ); - state( element, 0, 1, 0 ); - - element.find( ".ui-accordion-header" ).eq( 1 ).click(); - equal( element.accordion( "option", "active" ), 1 ); - state( element, 0, 1, 0 ); -}); - -test( "{ collapsible: true }", function() { - expect( 6 ); - var element = $( "#list1" ).accordion({ - active: 1, - collapsible: true - }); - - element.accordion( "option", "active", false ); - equal( element.accordion( "option", "active" ), false ); - state( element, 0, 0, 0 ); - - element.accordion( "option", "active", 1 ); - equal( element.accordion( "option", "active" ), 1 ); - state( element, 0, 1, 0 ); - - element.find( ".ui-accordion-header" ).eq( 1 ).click(); - equal( element.accordion( "option", "active" ), false ); - state( element, 0, 0, 0 ); -}); - -test( "{ event: null }", function() { - expect( 5 ); - var element = $( "#list1" ).accordion({ - event: null - }); - state( element, 1, 0, 0 ); - - element.accordion( "option", "active", 1 ); - equal( element.accordion( "option", "active" ), 1 ); - state( element, 0, 1, 0 ); - - // ensure default click handler isn't bound - element.find( ".ui-accordion-header" ).eq( 2 ).click(); - equal( element.accordion( "option", "active" ), 1 ); - state( element, 0, 1, 0 ); -}); - -test( "{ event: custom }", function() { - expect( 11 ); - var element = $( "#list1" ).accordion({ - event: "custom1 custom2" - }); - state( element, 1, 0, 0 ); - - element.find( ".ui-accordion-header" ).eq( 1 ).trigger( "custom1" ); - equal( element.accordion( "option", "active" ), 1 ); - state( element, 0, 1, 0 ); - - // ensure default click handler isn't bound - element.find( ".ui-accordion-header" ).eq( 2 ).trigger( "click" ); - equal( element.accordion( "option", "active" ), 1 ); - state( element, 0, 1, 0 ); - - element.find( ".ui-accordion-header" ).eq( 2 ).trigger( "custom2" ); - equal( element.accordion( "option", "active" ), 2 ); - state( element, 0, 0, 1 ); - - element.accordion( "option", "event", "custom3" ); - - // ensure old event handlers are unbound - element.find( ".ui-accordion-header" ).eq( 1 ).trigger( "custom1" ); - element.find( ".ui-accordion-header" ).eq( 1 ).trigger( "custom2" ); - equal( element.accordion( "option", "active" ), 2 ); - state( element, 0, 0, 1 ); - - element.find( ".ui-accordion-header" ).eq( 1 ).trigger( "custom3" ); - equal( element.accordion( "option", "active" ), 1 ); - state( element, 0, 1, 0 ); -}); - -test( "{ header: default }", function() { - expect( 2 ); - // default: > li > :first-child,> :not(li):even - // > :not(li):even - state( $( "#list1" ).accordion(), 1, 0, 0); - // > li > :first-child - state( $( "#navigation" ).accordion(), 1, 0, 0); -}); - -test( "{ header: custom }", function( assert ) { - expect( 6 ); - var element = $( "#navigationWrapper" ).accordion({ - header: "h2" - }); - element.find( "h2" ).each(function() { - assert.hasClasses( this, "ui-accordion-header" ); - }); - equal( element.find( ".ui-accordion-header" ).length, 3 ); - state( element, 1, 0, 0 ); - element.accordion( "option", "active", 2 ); - state( element, 0, 0, 1 ); -}); - -test( "{ heightStyle: 'auto' }", function() { - expect( 3 ); - var element = $( "#navigation" ).accordion({ heightStyle: "auto" }); - equalHeight( element, 105 ); -}); - -test( "{ heightStyle: 'content' }", function() { - expect( 3 ); - var element = $( "#navigation" ).accordion({ heightStyle: "content" }), - sizes = element.find( ".ui-accordion-content" ).map(function() { - return $( this ).height(); - }).get(); - equal( sizes[ 0 ], 75 ); - equal( sizes[ 1 ], 105 ); - equal( sizes[ 2 ], 45 ); -}); - -test( "{ heightStyle: 'fill' }", function() { - expect( 3 ); - $( "#navigationWrapper" ).height( 500 ); - var element = $( "#navigation" ).accordion({ heightStyle: "fill" }); - equalHeight( element, 455 ); -}); - -test( "{ heightStyle: 'fill' } with sibling", function() { - expect( 3 ); - $( "#navigationWrapper" ).height( 500 ); - $( "

Lorem Ipsum

" ) - .css({ - height: 50, - marginTop: 20, - marginBottom: 30 - }) - .prependTo( "#navigationWrapper" ); - var element = $( "#navigation" ).accordion({ heightStyle: "fill" }); - equalHeight( element , 355 ); -}); - -test( "{ heightStyle: 'fill' } with multiple siblings", function() { - expect( 3 ); - $( "#navigationWrapper" ).height( 500 ); - $( "

Lorem Ipsum

" ) - .css({ - height: 50, - marginTop: 20, - marginBottom: 30 - }) - .prependTo( "#navigationWrapper" ); - $( "

Lorem Ipsum

" ) - .css({ - height: 50, - marginTop: 20, - marginBottom: 30, - position: "absolute" - }) - .prependTo( "#navigationWrapper" ); - $( "

Lorem Ipsum

" ) - .css({ - height: 25, - marginTop: 10, - marginBottom: 15 - }) - .prependTo( "#navigationWrapper" ); - var element = $( "#navigation" ).accordion({ heightStyle: "fill" }); - equalHeight( element, 305 ); -}); - -test( "{ icons: false }", function() { - expect( 8 ); - var element = $( "#list1" ); - function icons( on ) { - deepEqual( element.find( "span.ui-icon").length, on ? 3 : 0 ); - deepEqual( element.find( ".ui-accordion-header.ui-accordion-icons" ).length, on ? 3 : 0 ); - } - element.accordion(); - icons( true ); - element.accordion( "destroy" ).accordion({ - icons: false - }); - icons( false ); - element.accordion( "option", "icons", { header: "foo", activeHeader: "bar" } ); - icons( true ); - element.accordion( "option", "icons", false ); - icons( false ); -}); - -test( "{ icons: hash }", function( assert ) { - expect( 3 ); - var element = $( "#list1" ).accordion({ - icons: { activeHeader: "a1", header: "h1" } - }); - assert.hasClasses( element.find( ".ui-accordion-header.ui-state-active span.ui-icon" ), "a1" ); - element.accordion( "option", "icons", { activeHeader: "a2", header: "h2" } ); - assert.lacksClasses( element.find( ".ui-accordion-header.ui-state-active span.ui-icon" ), "a1"); - assert.hasClasses( element.find( ".ui-accordion-header.ui-state-active span.ui-icon" ), "a2" ); -}); - -} ); diff --git a/tests/unit/accordion/accordion_test_helpers.js b/tests/unit/accordion/accordion_test_helpers.js deleted file mode 100644 index 5eb3a4bc3..000000000 --- a/tests/unit/accordion/accordion_test_helpers.js +++ /dev/null @@ -1,35 +0,0 @@ -define( [ - "jquery", - "lib/helper", - "ui/accordion" -], function( $, helper ) { - -return $.extend( helper, { - equalHeight: function( accordion, height ) { - accordion.find( ".ui-accordion-content" ).each(function() { - equal( $( this ).outerHeight(), height ); - }); - }, - - setupTeardown: function() { - var animate = $.ui.accordion.prototype.options.animate; - return { - setup: function() { - $.ui.accordion.prototype.options.animate = false; - }, - teardown: function() { - $.ui.accordion.prototype.options.animate = animate; - } - }; - }, - - state: function( accordion ) { - var expected = $.makeArray( arguments ).slice( 1 ), - actual = accordion.find( ".ui-accordion-content" ).map(function() { - return $( this ).css( "display" ) === "none" ? 0 : 1; - }).get(); - QUnit.push( QUnit.equiv(actual, expected), actual, expected ); - } -} ); - -} ); diff --git a/tests/unit/accordion/common.js b/tests/unit/accordion/common.js new file mode 100644 index 000000000..8a859f0ca --- /dev/null +++ b/tests/unit/accordion/common.js @@ -0,0 +1,32 @@ +define( [ + "lib/common", + "ui/accordion" +], function( common ) { + +common.testWidget( "accordion", { + defaults: { + active: 0, + animate: {}, + classes: { + "ui-accordion-header": "ui-corner-top", + "ui-accordion-header-collapsed": "ui-corner-all", + "ui-accordion-content": "ui-corner-bottom" + }, + collapsible: false, + disabled: false, + event: "click", + header: "> li > :first-child, > :not(li):even", + heightStyle: "auto", + icons: { + "activeHeader": "ui-icon-triangle-1-s", + "header": "ui-icon-triangle-1-e" + }, + + // callbacks + activate: null, + beforeActivate: null, + create: null + } +}); + +} ); diff --git a/tests/unit/accordion/core.js b/tests/unit/accordion/core.js new file mode 100644 index 000000000..b1d45f77e --- /dev/null +++ b/tests/unit/accordion/core.js @@ -0,0 +1,207 @@ +define( [ + "jquery", + "./helper", + "ui/accordion" +], function( $, testHelper ) { + +var setupTeardown = testHelper.setupTeardown, + state = testHelper.state; + +module( "accordion: core", setupTeardown() ); + +$.each( { div: "#list1", ul: "#navigation", dl: "#accordion-dl" }, function( type, selector ) { + test( "markup structure: " + type, function( assert ) { + expect( 10 ); + var element = $( selector ).accordion(), + headers = element.find( ".ui-accordion-header" ), + content = headers.next(); + + assert.hasClasses( element, "ui-accordion ui-widget" ); + equal( headers.length, 3, ".ui-accordion-header elements exist, correct number" ); + assert.hasClasses( headers[ 0 ], + "ui-accordion-header ui-accordion-header-active ui-accordion-icons" ); + assert.hasClasses( headers[ 1 ], + "ui-accordion-header ui-accordion-header-collapsed ui-accordion-icons" ); + assert.hasClasses( headers[ 2 ], + "ui-accordion-header ui-accordion-header-collapsed ui-accordion-icons" ); + equal( content.length, 3, ".ui-accordion-content elements exist, correct number" ); + assert.hasClasses( content[ 0 ], + "ui-accordion-content ui-widget-content ui-accordion-content-active" ); + assert.hasClasses( content[ 1 ], "ui-accordion-content ui-widget-content" ); + assert.hasClasses( content[ 2 ], "ui-accordion-content ui-widget-content" ); + deepEqual( element.find( ".ui-accordion-header" ).next().get(), + element.find( ".ui-accordion-content" ).get(), + "content panels come immediately after headers" ); + }); +}); + +test( "handle click on header-descendant", function() { + expect( 1 ); + var element = $( "#navigation" ).accordion(); + $( "#navigation h2:eq(1) a" ).click(); + state( element, 0, 1, 0 ); +}); + +test( "accessibility", function () { + expect( 61 ); + var element = $( "#list1" ).accordion({ + active: 1, + collapsible: true + }), + headers = element.find( ".ui-accordion-header" ); + + equal( element.attr( "role" ), "tablist", "element role" ); + headers.each(function( i ) { + var header = headers.eq( i ), + panel = header.next(); + equal( header.attr( "role" ), "tab", "header " + i + " role" ); + equal( header.attr( "aria-controls" ), panel.attr( "id" ), "header " + i + " aria-controls" ); + equal( panel.attr( "role" ), "tabpanel", "panel " + i + " role" ); + equal( panel.attr( "aria-labelledby" ), header.attr( "id" ), "panel " + i + " aria-labelledby" ); + }); + + equal( headers.eq( 1 ).attr( "tabindex" ), 0, "active header has tabindex=0" ); + equal( headers.eq( 1 ).attr( "aria-selected" ), "true", "active tab (1) has aria-selected=true" ); + equal( headers.eq( 1 ).attr( "aria-expanded" ), "true", "active tab (1) has aria-expanded=true" ); + equal( headers.eq( 1 ).next().attr( "aria-hidden" ), "false", "active tabpanel (1) has aria-hidden=false" ); + equal( headers.eq( 0 ).attr( "tabindex" ), -1, "inactive header (0) has tabindex=-1" ); + equal( headers.eq( 0 ).attr( "aria-selected" ), "false", "inactive tab (0) has aria-selected=false" ); + equal( headers.eq( 0 ).attr( "aria-expanded" ), "false", "inactive tab (0) has aria-expanded=false" ); + equal( headers.eq( 0 ).next().attr( "aria-hidden" ), "true", "inactive tabpanel (0) has aria-hidden=true" ); + equal( headers.eq( 2 ).attr( "tabindex" ), -1, "inactive header (2) has tabindex=-1" ); + equal( headers.eq( 2 ).attr( "aria-selected" ), "false", "inactive tab (2) has aria-selected=false" ); + equal( headers.eq( 2 ).attr( "aria-expanded" ), "false", "inactive tab (2) has aria-expanded=false" ); + equal( headers.eq( 2 ).next().attr( "aria-hidden" ), "true", "inactive tabpanel (2) has aria-hidden=true" ); + + element.accordion( "option", "active", 0 ); + equal( headers.eq( 0 ).attr( "tabindex" ), 0, "active header (0) has tabindex=0" ); + equal( headers.eq( 0 ).attr( "aria-selected" ), "true", "active tab (0) has aria-selected=true" ); + equal( headers.eq( 0 ).attr( "aria-expanded" ), "true", "active tab (0) has aria-expanded=true" ); + equal( headers.eq( 0 ).next().attr( "aria-hidden" ), "false", "active tabpanel (0) has aria-hidden=false" ); + equal( headers.eq( 1 ).attr( "tabindex" ), -1, "inactive header (1) has tabindex=-1" ); + equal( headers.eq( 1 ).attr( "aria-selected" ), "false", "inactive tab (1) has aria-selected=false" ); + equal( headers.eq( 1 ).attr( "aria-expanded" ), "false", "inactive tab (1) has aria-expanded=false" ); + equal( headers.eq( 1 ).next().attr( "aria-hidden" ), "true", "inactive tabpanel (1) has aria-hidden=true" ); + equal( headers.eq( 2 ).attr( "tabindex" ), -1, "inactive header (2) has tabindex=-1" ); + equal( headers.eq( 2 ).attr( "aria-selected" ), "false", "inactive tab (2) has aria-selected=false" ); + equal( headers.eq( 2 ).attr( "aria-expanded" ), "false", "inactive tab (2) has aria-expanded=false" ); + equal( headers.eq( 2 ).next().attr( "aria-hidden" ), "true", "inactive tabpanel (2) has aria-hidden=true" ); + + element.accordion( "option", "active", false ); + equal( headers.eq( 0 ).attr( "tabindex" ), 0, "previously active header (0) has tabindex=0" ); + equal( headers.eq( 0 ).attr( "aria-selected" ), "false", "inactive tab (0) has aria-selected=false" ); + equal( headers.eq( 0 ).attr( "aria-expanded" ), "false", "inactive tab (0) has aria-expanded=false" ); + equal( headers.eq( 0 ).next().attr( "aria-hidden" ), "true", "inactive tabpanel (0) has aria-hidden=true" ); + equal( headers.eq( 1 ).attr( "tabindex" ), -1, "inactive header (1) has tabindex=-1" ); + equal( headers.eq( 1 ).attr( "aria-selected" ), "false", "inactive tab (1) has aria-selected=false" ); + equal( headers.eq( 1 ).attr( "aria-expanded" ), "false", "inactive tab (1) has aria-expanded=false" ); + equal( headers.eq( 1 ).next().attr( "aria-hidden" ), "true", "inactive tabpanel (1) has aria-hidden=true" ); + equal( headers.eq( 2 ).attr( "tabindex" ), -1, "inactive header (2) has tabindex=-1" ); + equal( headers.eq( 2 ).attr( "aria-selected" ), "false", "inactive tab (2) has aria-selected=false" ); + equal( headers.eq( 2 ).attr( "aria-expanded" ), "false", "inactive tab (2) has aria-expanded=false" ); + equal( headers.eq( 2 ).next().attr( "aria-hidden" ), "true", "inactive tabpanel (2) has aria-hidden=true" ); + + element.accordion( "option", "active", 1 ); + equal( headers.eq( 1 ).attr( "tabindex" ), 0, "active header has tabindex=0" ); + equal( headers.eq( 1 ).attr( "aria-selected" ), "true", "active tab (1) has aria-selected=true" ); + equal( headers.eq( 1 ).attr( "aria-expanded" ), "true", "active tab (1) has aria-expanded=true" ); + equal( headers.eq( 1 ).next().attr( "aria-hidden" ), "false", "active tabpanel (1) has aria-hidden=false" ); + equal( headers.eq( 0 ).attr( "tabindex" ), -1, "inactive header (0) has tabindex=-1" ); + equal( headers.eq( 0 ).attr( "aria-selected" ), "false", "inactive tab (0) has aria-selected=false" ); + equal( headers.eq( 0 ).attr( "aria-expanded" ), "false", "inactive tab (0) has aria-expanded=false" ); + equal( headers.eq( 0 ).next().attr( "aria-hidden" ), "true", "inactive tabpanel (0) has aria-hidden=true" ); + equal( headers.eq( 2 ).attr( "tabindex" ), -1, "inactive header (2) has tabindex=-1" ); + equal( headers.eq( 2 ).attr( "aria-selected" ), "false", "inactive tab (2) has aria-selected=false" ); + equal( headers.eq( 2 ).attr( "aria-expanded" ), "false", "inactive tab (2) has aria-expanded=false" ); + equal( headers.eq( 2 ).next().attr( "aria-hidden" ), "true", "inactive tabpanel (2) has aria-hidden=true" ); + +}); + +asyncTest( "keyboard support", function( assert ) { + expect( 13 ); + var element = $( "#list1" ).accordion(), + headers = element.find( ".ui-accordion-header" ), + anchor = headers.eq( 1 ).next().find( "a" ).eq( 0 ), + keyCode = $.ui.keyCode; + equal( headers.filter( ".ui-state-focus" ).length, 0, "no headers focused on init" ); + headers.eq( 0 ).simulate( "focus" ); + setTimeout( step1 ); + + function step1() { + assert.hasClasses( headers.eq( 0 ), "ui-state-focus", "first header has focus" ); + headers.eq( 0 ).simulate( "keydown", { keyCode: keyCode.DOWN } ); + setTimeout( step2 ); + } + + // Support: IE 11 with jQuery 1.7 - 1.8 only + // All of the setTimeouts() from keydowns aren't necessary with newer jQuery. + // Only the explicit focus simulations require them. + function step2() { + assert.hasClasses( headers.eq( 1 ), "ui-state-focus", "DOWN moves focus to next header" ); + headers.eq( 1 ).simulate( "keydown", { keyCode: keyCode.RIGHT } ); + setTimeout( step3 ); + } + + function step3() { + assert.hasClasses( headers.eq( 2 ), "ui-state-focus", "RIGHT moves focus to next header" ); + headers.eq( 2 ).simulate( "keydown", { keyCode: keyCode.DOWN } ); + setTimeout( step4 ); + } + + function step4() { + assert.hasClasses( headers.eq( 0 ), "ui-state-focus", "DOWN wraps focus to first header" ); + headers.eq( 0 ).simulate( "keydown", { keyCode: keyCode.UP } ); + setTimeout( step5 ); + } + + function step5() { + assert.hasClasses( headers.eq( 2 ), "ui-state-focus", "UP wraps focus to last header" ); + headers.eq( 2 ).simulate( "keydown", { keyCode: keyCode.LEFT } ); + setTimeout( step6 ); + } + + function step6() { + assert.hasClasses( headers.eq( 1 ), + "ui-state-focus", "LEFT moves focus to previous header" ); + headers.eq( 1 ).simulate( "keydown", { keyCode: keyCode.HOME } ); + setTimeout( step7 ); + } + + function step7() { + assert.hasClasses( headers.eq( 0 ), "ui-state-focus", "HOME moves focus to first header" ); + headers.eq( 0 ).simulate( "keydown", { keyCode: keyCode.END } ); + setTimeout( step8 ); + } + + function step8() { + assert.hasClasses( headers.eq( 2 ), "ui-state-focus", "END moves focus to last header" ); + headers.eq( 2 ).simulate( "keydown", { keyCode: keyCode.ENTER } ); + setTimeout( step9 ); + } + + function step9() { + equal( element.accordion( "option", "active" ) , 2, "ENTER activates panel" ); + headers.eq( 1 ).simulate( "keydown", { keyCode: keyCode.SPACE } ); + setTimeout( step10 ); + } + + function step10() { + equal( element.accordion( "option", "active" ), 1, "SPACE activates panel" ); + anchor.simulate( "focus" ); + setTimeout( step11 ); + } + + function step11() { + assert.lacksClasses( headers.eq( 1 ), "ui-state-focus", + "header loses focus when focusing inside the panel" ); + anchor.simulate( "keydown", { keyCode: keyCode.UP, ctrlKey: true } ); + setTimeout( step12 ); + } + + function step12() { + assert.hasClasses( headers.eq( 1 ), "ui-state-focus", "CTRL+UP moves focus to header" ); + start(); + } +}); + +} ); diff --git a/tests/unit/accordion/events.js b/tests/unit/accordion/events.js new file mode 100644 index 000000000..7f7390c83 --- /dev/null +++ b/tests/unit/accordion/events.js @@ -0,0 +1,168 @@ +define( [ + "jquery", + "./helper", + "ui/accordion" +], function( $, testHelper ) { + +var setupTeardown = testHelper.setupTeardown, + state = testHelper.state; + +module( "accordion: events", setupTeardown() ); + +test( "create", function() { + expect( 10 ); + + var element = $( "#list1" ), + headers = element.children( "h3" ), + contents = headers.next(); + + element.accordion({ + create: function( event, ui ) { + equal( ui.header.length, 1, "header length" ); + strictEqual( ui.header[ 0 ], headers[ 0 ], "header" ); + equal( ui.panel.length, 1, "panel length" ); + strictEqual( ui.panel[ 0 ], contents[ 0 ], "panel" ); + } + }); + element.accordion( "destroy" ); + + element.accordion({ + active: 2, + create: function( event, ui ) { + equal( ui.header.length, 1, "header length" ); + strictEqual( ui.header[ 0 ], headers[ 2 ], "header" ); + equal( ui.panel.length, 1, "panel length" ); + strictEqual( ui.panel[ 0 ], contents[ 2 ], "panel" ); + } + }); + element.accordion( "destroy" ); + + element.accordion({ + active: false, + collapsible: true, + create: function( event, ui ) { + equal( ui.header.length, 0, "header length" ); + equal( ui.panel.length, 0, "panel length" ); + } + }); + element.accordion( "destroy" ); +}); + +test( "beforeActivate", function() { + expect( 38 ); + var element = $( "#list1" ).accordion({ + active: false, + collapsible: true + }), + headers = element.find( ".ui-accordion-header" ), + content = element.find( ".ui-accordion-content" ); + + element.one( "accordionbeforeactivate", function( event, ui ) { + ok( !( "originalEvent" in event ) ); + equal( ui.oldHeader.length, 0 ); + equal( ui.oldPanel.length, 0 ); + equal( ui.newHeader.length, 1 ); + strictEqual( ui.newHeader[ 0 ], headers[ 0 ] ); + equal( ui.newPanel.length, 1 ); + strictEqual( ui.newPanel[ 0 ], content[ 0 ] ); + state( element, 0, 0, 0 ); + }); + element.accordion( "option", "active", 0 ); + state( element, 1, 0, 0 ); + + element.one( "accordionbeforeactivate", function( event, ui ) { + equal( event.originalEvent.type, "click" ); + equal( ui.oldHeader.length, 1 ); + strictEqual( ui.oldHeader[ 0 ], headers[ 0 ] ); + equal( ui.oldPanel.length, 1 ); + strictEqual( ui.oldPanel[ 0 ], content[ 0 ] ); + equal( ui.newHeader.length, 1 ); + strictEqual( ui.newHeader[ 0 ], headers[ 1 ] ); + equal( ui.newPanel.length, 1 ); + strictEqual( ui.newPanel[ 0 ], content[ 1 ] ); + state( element, 1, 0, 0 ); + }); + headers.eq( 1 ).click(); + state( element, 0, 1, 0 ); + + element.one( "accordionbeforeactivate", function( event, ui ) { + ok( !( "originalEvent" in event ) ); + equal( ui.oldHeader.length, 1 ); + strictEqual( ui.oldHeader[ 0 ], headers[ 1 ] ); + equal( ui.oldPanel.length, 1 ); + strictEqual( ui.oldPanel[ 0 ], content[ 1 ] ); + equal( ui.newHeader.length, 0 ); + equal( ui.newPanel.length, 0 ); + state( element, 0, 1, 0 ); + }); + element.accordion( "option", "active", false ); + state( element, 0, 0, 0 ); + + element.one( "accordionbeforeactivate", function( event, ui ) { + ok( !( "originalEvent" in event ) ); + equal( ui.oldHeader.length, 0 ); + equal( ui.oldPanel.length, 0 ); + equal( ui.newHeader.length, 1 ); + strictEqual( ui.newHeader[ 0 ], headers[ 2 ] ); + equal( ui.newPanel.length, 1 ); + strictEqual( ui.newPanel[ 0 ], content[ 2 ] ); + event.preventDefault(); + state( element, 0, 0, 0 ); + }); + element.accordion( "option", "active", 2 ); + state( element, 0, 0, 0 ); +}); + +test( "activate", function() { + expect( 21 ); + var element = $( "#list1" ).accordion({ + active: false, + collapsible: true + }), + headers = element.find( ".ui-accordion-header" ), + content = element.find( ".ui-accordion-content" ); + + element.one( "accordionactivate", function( event, ui ) { + equal( ui.oldHeader.length, 0 ); + equal( ui.oldPanel.length, 0 ); + equal( ui.newHeader.length, 1 ); + strictEqual( ui.newHeader[ 0 ], headers[ 0 ] ); + equal( ui.newPanel.length, 1 ); + strictEqual( ui.newPanel[ 0 ], content[ 0 ] ); + }); + element.accordion( "option", "active", 0 ); + + element.one( "accordionactivate", function( event, ui ) { + equal( ui.oldHeader.length, 1 ); + strictEqual( ui.oldHeader[ 0 ], headers[ 0 ] ); + equal( ui.oldPanel.length, 1 ); + strictEqual( ui.oldPanel[ 0 ], content[ 0 ] ); + equal( ui.newHeader.length, 1 ); + strictEqual( ui.newHeader[ 0 ], headers[ 1 ] ); + equal( ui.newPanel.length, 1 ); + strictEqual( ui.newPanel[ 0 ], content[ 1 ] ); + }); + headers.eq( 1 ).click(); + + element.one( "accordionactivate", function( event, ui ) { + equal( ui.oldHeader.length, 1 ); + strictEqual( ui.oldHeader[ 0 ], headers[ 1 ] ); + equal( ui.oldPanel.length, 1 ); + strictEqual( ui.oldPanel[ 0 ], content[ 1 ] ); + equal( ui.newHeader.length, 0 ); + equal( ui.newPanel.length, 0 ); + }); + element.accordion( "option", "active", false ); + + // prevent activation + element.one( "accordionbeforeactivate", function( event ) { + ok( true ); + event.preventDefault(); + }); + element.one( "accordionactivate", function() { + ok( false ); + }); + element.accordion( "option", "active", 1 ); +}); + +} ); diff --git a/tests/unit/accordion/helper.js b/tests/unit/accordion/helper.js new file mode 100644 index 000000000..5eb3a4bc3 --- /dev/null +++ b/tests/unit/accordion/helper.js @@ -0,0 +1,35 @@ +define( [ + "jquery", + "lib/helper", + "ui/accordion" +], function( $, helper ) { + +return $.extend( helper, { + equalHeight: function( accordion, height ) { + accordion.find( ".ui-accordion-content" ).each(function() { + equal( $( this ).outerHeight(), height ); + }); + }, + + setupTeardown: function() { + var animate = $.ui.accordion.prototype.options.animate; + return { + setup: function() { + $.ui.accordion.prototype.options.animate = false; + }, + teardown: function() { + $.ui.accordion.prototype.options.animate = animate; + } + }; + }, + + state: function( accordion ) { + var expected = $.makeArray( arguments ).slice( 1 ), + actual = accordion.find( ".ui-accordion-content" ).map(function() { + return $( this ).css( "display" ) === "none" ? 0 : 1; + }).get(); + QUnit.push( QUnit.equiv(actual, expected), actual, expected ); + } +} ); + +} ); diff --git a/tests/unit/accordion/methods.js b/tests/unit/accordion/methods.js new file mode 100644 index 000000000..efabfed10 --- /dev/null +++ b/tests/unit/accordion/methods.js @@ -0,0 +1,136 @@ +define( [ + "jquery", + "./helper", + "ui/accordion" +], function( $, testHelper ) { + +var equalHeight = testHelper.equalHeight, + setupTeardown = testHelper.setupTeardown, + state = testHelper.state; + +module( "accordion: methods", setupTeardown() ); + +test( "destroy", function( assert ) { + expect( 1 ); + assert.domEqual( "#list1", function() { + $( "#list1" ).accordion().accordion( "destroy" ); + }); +}); + +test( "enable/disable", function( assert ) { + expect( 7 ); + var element = $( "#list1" ).accordion(); + state( element, 1, 0, 0 ); + element.accordion( "disable" ); + + assert.hasClasses( element, "ui-state-disabled" ); + + equal( element.attr( "aria-disabled" ), "true", "element gets aria-disabled" ); + assert.hasClasses( element, "ui-accordion-disabled" ); + + // event does nothing + element.find( ".ui-accordion-header" ).eq( 1 ).trigger( "click" ); + state( element, 1, 0, 0 ); + // option still works + element.accordion( "option", "active", 1 ); + state( element, 0, 1, 0 ); + element.accordion( "enable" ); + element.accordion( "option", "active", 2 ); + state( element, 0, 0, 1 ); +}); + +test( "refresh", function() { + expect( 19 ); + var element = $( "#navigation" ) + .parent() + .height( 300 ) + .end() + .accordion({ + heightStyle: "fill" + }); + equalHeight( element, 255 ); + + element.parent().height( 500 ); + element.accordion( "refresh" ); + equalHeight( element, 455 ); + + element = $( "#list1" ); + element.accordion(); + state( element, 1, 0, 0 ); + + // disable panel via markup + element.find( "h3.bar" ).eq( 1 ).addClass( "ui-state-disabled" ); + element.accordion( "refresh" ); + state( element, 1, 0, 0 ); + + // don't add multiple icons + element.accordion( "refresh" ); + equal( element.find( ".ui-accordion-header-icon" ).length, 3 ); + + // add a panel + element + .append("

new 1

") + .append("
new 1
"); + element.accordion( "refresh" ); + state( element, 1, 0, 0, 0 ); + + // remove all tabs + element.find( "h3.bar, div.foo" ).remove(); + element.accordion( "refresh" ); + state( element ); + equal( element.accordion( "option", "active" ), false, "no active accordion panel" ); + + // add panels + element + .append("

new 2

") + .append("
new 2
") + .append("

new 3

") + .append("
new 3
") + .append("

new 4

") + .append("
new 4
") + .append("

new 5

") + .append("
new 5
"); + element.accordion( "refresh" ); + state( element, 1, 0, 0, 0 ); + + // activate third tab + element.accordion( "option", "active", 2 ); + state( element, 0, 0, 1, 0 ); + + // remove fourth panel, third panel should stay active + element.find( "h3.bar" ).eq( 3 ).remove(); + element.find( "div.foo" ).eq( 3 ).remove(); + element.accordion( "refresh" ); + state( element, 0, 0, 1 ); + + // remove third (active) panel, second panel should become active + element.find( "h3.bar" ).eq( 2 ).remove(); + element.find( "div.foo" ).eq( 2 ).remove(); + element.accordion( "refresh" ); + state( element, 0, 1 ); + + // remove first panel, previously active panel (now first) should stay active + element.find( "h3.bar" ).eq( 0 ).remove(); + element.find( "div.foo" ).eq( 0 ).remove(); + element.accordion( "refresh" ); + state( element, 1 ); + + // collapse all panels + element.accordion( "option", { + collapsible: true, + active: false + }); + state( element, 0 ); + element.accordion( "refresh" ); + state( element, 0 ); +}); + +test( "widget", function() { + expect( 2 ); + var element = $( "#list1" ).accordion(), + widgetElement = element.accordion( "widget" ); + equal( widgetElement.length, 1, "one element" ); + strictEqual( widgetElement[ 0 ], element[ 0 ], "same element" ); +}); + +} ); diff --git a/tests/unit/accordion/options.js b/tests/unit/accordion/options.js new file mode 100644 index 000000000..c95738c43 --- /dev/null +++ b/tests/unit/accordion/options.js @@ -0,0 +1,467 @@ +define( [ + "jquery", + "./helper", + "ui/accordion" +], function( $, testHelper ) { + +var equalHeight = testHelper.equalHeight, + setupTeardown = testHelper.setupTeardown, + state = testHelper.state; + +module( "accordion: options", setupTeardown() ); + +test( "{ active: default }", function() { + expect( 2 ); + var element = $( "#list1" ).accordion(); + equal( element.accordion( "option", "active" ), 0 ); + state( element, 1, 0, 0 ); +}); + +test( "{ active: null }", function() { + expect( 2 ); + var element = $( "#list1" ).accordion({ + active: null + }); + equal( element.accordion( "option", "active" ), 0 ); + state( element, 1, 0, 0 ); +}); + +test( "{ active: false }", function() { + expect( 7 ); + var element = $( "#list1" ).accordion({ + active: false, + collapsible: true + }); + state( element, 0, 0, 0 ); + equal( element.find( ".ui-accordion-header.ui-state-active" ).length, 0, "no headers selected" ); + equal( element.accordion( "option", "active" ), false ); + + element.accordion( "option", "collapsible", false ); + state( element, 1, 0, 0 ); + equal( element.accordion( "option", "active" ), 0 ); + + element.accordion( "destroy" ); + element.accordion({ + active: false + }); + state( element, 1, 0, 0 ); + strictEqual( element.accordion( "option", "active" ), 0 ); +}); + +test( "{ active: Number }", function() { + expect( 8 ); + var element = $( "#list1" ).accordion({ + active: 2 + }); + equal( element.accordion( "option", "active" ), 2 ); + state( element, 0, 0, 1 ); + + element.accordion( "option", "active", 0 ); + equal( element.accordion( "option", "active" ), 0 ); + state( element, 1, 0, 0 ); + + element.find( ".ui-accordion-header" ).eq( 1 ).click(); + equal( element.accordion( "option", "active" ), 1 ); + state( element, 0, 1, 0 ); + + element.accordion( "option", "active", 10 ); + equal( element.accordion( "option", "active" ), 1 ); + state( element, 0, 1, 0 ); +}); + +test( "{ active: -Number }", function() { + expect( 8 ); + var element = $( "#list1" ).accordion({ + active: -1 + }); + equal( element.accordion( "option", "active" ), 2 ); + state( element, 0, 0, 1 ); + + element.accordion( "option", "active", -2 ); + equal( element.accordion( "option", "active" ), 1 ); + state( element, 0, 1, 0 ); + + element.accordion( "option", "active", -10 ); + equal( element.accordion( "option", "active" ), 1 ); + state( element, 0, 1, 0 ); + + element.accordion( "option", "active", -3 ); + equal( element.accordion( "option", "active" ), 0 ); + state( element, 1, 0, 0 ); +}); + +test( "{ animate: false }", function() { + expect( 3 ); + var element = $( "#list1" ).accordion({ + animate: false + }), + panels = element.find( ".ui-accordion-content" ), + animate = $.fn.animate; + $.fn.animate = function() { + ok( false, ".animate() called" ); + }; + + ok( panels.eq( 0 ).is( ":visible" ), "first panel visible" ); + element.accordion( "option", "active", 1 ); + ok( panels.eq( 0 ).is( ":hidden" ), "first panel hidden" ); + ok( panels.eq( 1 ).is( ":visible" ), "second panel visible" ); + $.fn.animate = animate; +}); + +asyncTest( "{ animate: Number }", function() { + expect( 7 ); + var element = $( "#list1" ).accordion({ + animate: 100 + }), + panels = element.find( ".ui-accordion-content" ), + animate = $.fn.animate; + // called twice (both panels) + $.fn.animate = function( props, options ) { + equal( options.duration, 100, "correct duration" ); + equal( options.easing, undefined, "default easing" ); + animate.apply( this, arguments ); + }; + + ok( panels.eq( 0 ).is( ":visible" ), "first panel visible" ); + element.accordion( "option", "active", 1 ); + panels.promise().done(function() { + ok( panels.eq( 0 ).is( ":hidden" ), "first panel hidden" ); + ok( panels.eq( 1 ).is( ":visible" ), "second panel visible" ); + $.fn.animate = animate; + start(); + }); +}); + +asyncTest( "{ animate: String }", function() { + expect( 7 ); + var element = $( "#list1" ).accordion({ + animate: "linear" + }), + panels = element.find( ".ui-accordion-content" ), + animate = $.fn.animate; + // called twice (both panels) + $.fn.animate = function( props, options ) { + equal( options.duration, undefined, "default duration" ); + equal( options.easing, "linear", "correct easing" ); + animate.apply( this, arguments ); + }; + + ok( panels.eq( 0 ).is( ":visible" ), "first panel visible" ); + element.accordion( "option", "active", 1 ); + panels.promise().done(function() { + ok( panels.eq( 0 ).is( ":hidden" ), "first panel hidden" ); + ok( panels.eq( 1 ).is( ":visible" ), "second panel visible" ); + $.fn.animate = animate; + start(); + }); +}); + +asyncTest( "{ animate: {} }", function() { + expect( 7 ); + var element = $( "#list1" ).accordion({ + animate: {} + }), + panels = element.find( ".ui-accordion-content" ), + animate = $.fn.animate; + // called twice (both panels) + $.fn.animate = function( props, options ) { + equal( options.duration, undefined, "default duration" ); + equal( options.easing, undefined, "default easing" ); + animate.apply( this, arguments ); + }; + + ok( panels.eq( 0 ).is( ":visible" ), "first panel visible" ); + element.accordion( "option", "active", 1 ); + panels.promise().done(function() { + ok( panels.eq( 0 ).is( ":hidden" ), "first panel hidden" ); + ok( panels.eq( 1 ).is( ":visible" ), "second panel visible" ); + $.fn.animate = animate; + start(); + }); +}); + +asyncTest( "{ animate: { duration, easing } }", function() { + expect( 7 ); + var element = $( "#list1" ).accordion({ + animate: { duration: 100, easing: "linear" } + }), + panels = element.find( ".ui-accordion-content" ), + animate = $.fn.animate; + // called twice (both panels) + $.fn.animate = function( props, options ) { + equal( options.duration, 100, "correct duration" ); + equal( options.easing, "linear", "correct easing" ); + animate.apply( this, arguments ); + }; + + ok( panels.eq( 0 ).is( ":visible" ), "first panel visible" ); + element.accordion( "option", "active", 1 ); + panels.promise().done(function() { + ok( panels.eq( 0 ).is( ":hidden" ), "first panel hidden" ); + ok( panels.eq( 1 ).is( ":visible" ), "second panel visible" ); + $.fn.animate = animate; + start(); + }); +}); + +asyncTest( "{ animate: { duration, easing } }, animate down", function() { + expect( 7 ); + var element = $( "#list1" ).accordion({ + active: 1, + animate: { duration: 100, easing: "linear" } + }), + panels = element.find( ".ui-accordion-content" ), + animate = $.fn.animate; + // called twice (both panels) + $.fn.animate = function( props, options ) { + equal( options.duration, 100, "correct duration" ); + equal( options.easing, "linear", "correct easing" ); + animate.apply( this, arguments ); + }; + + ok( panels.eq( 1 ).is( ":visible" ), "first panel visible" ); + element.accordion( "option", "active", 0 ); + panels.promise().done(function() { + ok( panels.eq( 1 ).is( ":hidden" ), "first panel hidden" ); + ok( panels.eq( 0 ).is( ":visible" ), "second panel visible" ); + $.fn.animate = animate; + start(); + }); +}); + +asyncTest( "{ animate: { duration, easing, down } }, animate down", function() { + expect( 7 ); + var element = $( "#list1" ).accordion({ + active: 1, + animate: { + duration: 100, + easing: "linear", + down: { + easing: "swing" + } + } + }), + panels = element.find( ".ui-accordion-content" ), + animate = $.fn.animate; + // called twice (both panels) + $.fn.animate = function( props, options ) { + equal( options.duration, 100, "correct duration" ); + equal( options.easing, "swing", "correct easing" ); + animate.apply( this, arguments ); + }; + + ok( panels.eq( 1 ).is( ":visible" ), "first panel visible" ); + element.accordion( "option", "active", 0 ); + panels.promise().done(function() { + ok( panels.eq( 1 ).is( ":hidden" ), "first panel hidden" ); + ok( panels.eq( 0 ).is( ":visible" ), "second panel visible" ); + $.fn.animate = animate; + start(); + }); +}); + +test( "{ collapsible: false }", function() { + expect( 4 ); + var element = $( "#list1" ).accordion({ + active: 1 + }); + element.accordion( "option", "active", false ); + equal( element.accordion( "option", "active" ), 1 ); + state( element, 0, 1, 0 ); + + element.find( ".ui-accordion-header" ).eq( 1 ).click(); + equal( element.accordion( "option", "active" ), 1 ); + state( element, 0, 1, 0 ); +}); + +test( "{ collapsible: true }", function() { + expect( 6 ); + var element = $( "#list1" ).accordion({ + active: 1, + collapsible: true + }); + + element.accordion( "option", "active", false ); + equal( element.accordion( "option", "active" ), false ); + state( element, 0, 0, 0 ); + + element.accordion( "option", "active", 1 ); + equal( element.accordion( "option", "active" ), 1 ); + state( element, 0, 1, 0 ); + + element.find( ".ui-accordion-header" ).eq( 1 ).click(); + equal( element.accordion( "option", "active" ), false ); + state( element, 0, 0, 0 ); +}); + +test( "{ event: null }", function() { + expect( 5 ); + var element = $( "#list1" ).accordion({ + event: null + }); + state( element, 1, 0, 0 ); + + element.accordion( "option", "active", 1 ); + equal( element.accordion( "option", "active" ), 1 ); + state( element, 0, 1, 0 ); + + // ensure default click handler isn't bound + element.find( ".ui-accordion-header" ).eq( 2 ).click(); + equal( element.accordion( "option", "active" ), 1 ); + state( element, 0, 1, 0 ); +}); + +test( "{ event: custom }", function() { + expect( 11 ); + var element = $( "#list1" ).accordion({ + event: "custom1 custom2" + }); + state( element, 1, 0, 0 ); + + element.find( ".ui-accordion-header" ).eq( 1 ).trigger( "custom1" ); + equal( element.accordion( "option", "active" ), 1 ); + state( element, 0, 1, 0 ); + + // ensure default click handler isn't bound + element.find( ".ui-accordion-header" ).eq( 2 ).trigger( "click" ); + equal( element.accordion( "option", "active" ), 1 ); + state( element, 0, 1, 0 ); + + element.find( ".ui-accordion-header" ).eq( 2 ).trigger( "custom2" ); + equal( element.accordion( "option", "active" ), 2 ); + state( element, 0, 0, 1 ); + + element.accordion( "option", "event", "custom3" ); + + // ensure old event handlers are unbound + element.find( ".ui-accordion-header" ).eq( 1 ).trigger( "custom1" ); + element.find( ".ui-accordion-header" ).eq( 1 ).trigger( "custom2" ); + equal( element.accordion( "option", "active" ), 2 ); + state( element, 0, 0, 1 ); + + element.find( ".ui-accordion-header" ).eq( 1 ).trigger( "custom3" ); + equal( element.accordion( "option", "active" ), 1 ); + state( element, 0, 1, 0 ); +}); + +test( "{ header: default }", function() { + expect( 2 ); + // default: > li > :first-child,> :not(li):even + // > :not(li):even + state( $( "#list1" ).accordion(), 1, 0, 0); + // > li > :first-child + state( $( "#navigation" ).accordion(), 1, 0, 0); +}); + +test( "{ header: custom }", function( assert ) { + expect( 6 ); + var element = $( "#navigationWrapper" ).accordion({ + header: "h2" + }); + element.find( "h2" ).each(function() { + assert.hasClasses( this, "ui-accordion-header" ); + }); + equal( element.find( ".ui-accordion-header" ).length, 3 ); + state( element, 1, 0, 0 ); + element.accordion( "option", "active", 2 ); + state( element, 0, 0, 1 ); +}); + +test( "{ heightStyle: 'auto' }", function() { + expect( 3 ); + var element = $( "#navigation" ).accordion({ heightStyle: "auto" }); + equalHeight( element, 105 ); +}); + +test( "{ heightStyle: 'content' }", function() { + expect( 3 ); + var element = $( "#navigation" ).accordion({ heightStyle: "content" }), + sizes = element.find( ".ui-accordion-content" ).map(function() { + return $( this ).height(); + }).get(); + equal( sizes[ 0 ], 75 ); + equal( sizes[ 1 ], 105 ); + equal( sizes[ 2 ], 45 ); +}); + +test( "{ heightStyle: 'fill' }", function() { + expect( 3 ); + $( "#navigationWrapper" ).height( 500 ); + var element = $( "#navigation" ).accordion({ heightStyle: "fill" }); + equalHeight( element, 455 ); +}); + +test( "{ heightStyle: 'fill' } with sibling", function() { + expect( 3 ); + $( "#navigationWrapper" ).height( 500 ); + $( "

Lorem Ipsum

" ) + .css({ + height: 50, + marginTop: 20, + marginBottom: 30 + }) + .prependTo( "#navigationWrapper" ); + var element = $( "#navigation" ).accordion({ heightStyle: "fill" }); + equalHeight( element , 355 ); +}); + +test( "{ heightStyle: 'fill' } with multiple siblings", function() { + expect( 3 ); + $( "#navigationWrapper" ).height( 500 ); + $( "

Lorem Ipsum

" ) + .css({ + height: 50, + marginTop: 20, + marginBottom: 30 + }) + .prependTo( "#navigationWrapper" ); + $( "

Lorem Ipsum

" ) + .css({ + height: 50, + marginTop: 20, + marginBottom: 30, + position: "absolute" + }) + .prependTo( "#navigationWrapper" ); + $( "

Lorem Ipsum

" ) + .css({ + height: 25, + marginTop: 10, + marginBottom: 15 + }) + .prependTo( "#navigationWrapper" ); + var element = $( "#navigation" ).accordion({ heightStyle: "fill" }); + equalHeight( element, 305 ); +}); + +test( "{ icons: false }", function() { + expect( 8 ); + var element = $( "#list1" ); + function icons( on ) { + deepEqual( element.find( "span.ui-icon").length, on ? 3 : 0 ); + deepEqual( element.find( ".ui-accordion-header.ui-accordion-icons" ).length, on ? 3 : 0 ); + } + element.accordion(); + icons( true ); + element.accordion( "destroy" ).accordion({ + icons: false + }); + icons( false ); + element.accordion( "option", "icons", { header: "foo", activeHeader: "bar" } ); + icons( true ); + element.accordion( "option", "icons", false ); + icons( false ); +}); + +test( "{ icons: hash }", function( assert ) { + expect( 3 ); + var element = $( "#list1" ).accordion({ + icons: { activeHeader: "a1", header: "h1" } + }); + assert.hasClasses( element.find( ".ui-accordion-header.ui-state-active span.ui-icon" ), "a1" ); + element.accordion( "option", "icons", { activeHeader: "a2", header: "h2" } ); + assert.lacksClasses( element.find( ".ui-accordion-header.ui-state-active span.ui-icon" ), "a1"); + assert.hasClasses( element.find( ".ui-accordion-header.ui-state-active span.ui-icon" ), "a2" ); +}); + +} ); diff --git a/tests/unit/autocomplete/autocomplete_common.js b/tests/unit/autocomplete/autocomplete_common.js deleted file mode 100644 index 5ee7cdda0..000000000 --- a/tests/unit/autocomplete/autocomplete_common.js +++ /dev/null @@ -1,37 +0,0 @@ -define( [ - "lib/common", - "ui/autocomplete" -], function( common ) { - -common.testWidget( "autocomplete", { - defaults: { - appendTo: null, - autoFocus: false, - classes: {}, - delay: 300, - disabled: false, - messages: { - noResults: "No search results.", - results: $.ui.autocomplete.prototype.options.messages.results - }, - minLength: 1, - position: { - my: "left top", - at: "left bottom", - collision: "none" - }, - source: null, - - // callbacks - change: null, - close: null, - create: null, - focus: null, - open: null, - response: null, - search: null, - select: null - } -}); - -} ); diff --git a/tests/unit/autocomplete/autocomplete_core.js b/tests/unit/autocomplete/autocomplete_core.js deleted file mode 100644 index d25328dd5..000000000 --- a/tests/unit/autocomplete/autocomplete_core.js +++ /dev/null @@ -1,401 +0,0 @@ -define( [ - "jquery", - "ui/autocomplete" -], function( $ ) { - -module( "autocomplete: core" ); - -test( "markup structure", function( assert ) { - expect( 2 ); - var element = $( "#autocomplete" ).autocomplete(), - menu = element.autocomplete( "widget" ); - - assert.hasClasses( element, "ui-autocomplete-input" ); - assert.hasClasses( menu, "ui-autocomplete ui-widget ui-widget-content" ); -}); - -test( "prevent form submit on enter when menu is active", function() { - expect( 2 ); - var event, - element = $( "#autocomplete" ) - .autocomplete({ - source: [ "java", "javascript" ] - }) - .val( "ja" ) - .autocomplete( "search" ), - menu = element.autocomplete( "widget" ); - - event = $.Event( "keydown" ); - event.keyCode = $.ui.keyCode.DOWN; - element.trigger( event ); - equal( menu.find( ".ui-menu-item-wrapper.ui-state-active" ).length, 1, - "menu item is active" ); - - event = $.Event( "keydown" ); - event.keyCode = $.ui.keyCode.ENTER; - element.trigger( event ); - ok( event.isDefaultPrevented(), "default action is prevented" ); -}); - -test( "allow form submit on enter when menu is not active", function() { - expect( 1 ); - var event, - element = $( "#autocomplete" ) - .autocomplete({ - autoFocus: false, - source: [ "java", "javascript" ] - }) - .val( "ja" ) - .autocomplete( "search" ); - - event = $.Event( "keydown" ); - event.keyCode = $.ui.keyCode.ENTER; - element.trigger( event ); - ok( !event.isDefaultPrevented(), "default action is prevented" ); -}); - -(function() { - test( "up arrow invokes search - input", function() { - arrowsInvokeSearch( "#autocomplete", true, true ); - }); - - test( "down arrow invokes search - input", function() { - arrowsInvokeSearch( "#autocomplete", false, true ); - }); - - test( "up arrow invokes search - textarea", function() { - arrowsInvokeSearch( "#autocomplete-textarea", true, false ); - }); - - test( "down arrow invokes search - textarea", function() { - arrowsInvokeSearch( "#autocomplete-textarea", false, false ); - }); - - test( "up arrow invokes search - contenteditable", function() { - arrowsInvokeSearch( "#autocomplete-contenteditable", true, false ); - }); - - test( "down arrow invokes search - contenteditable", function() { - arrowsInvokeSearch( "#autocomplete-contenteditable", false, false ); - }); - - test( "up arrow moves focus - input", function() { - arrowsMoveFocus( "#autocomplete", true ); - }); - - test( "down arrow moves focus - input", function() { - arrowsMoveFocus( "#autocomplete", false ); - }); - - test( "up arrow moves focus - textarea", function() { - arrowsMoveFocus( "#autocomplete-textarea", true ); - }); - - test( "down arrow moves focus - textarea", function() { - arrowsMoveFocus( "#autocomplete-textarea", false ); - }); - - test( "up arrow moves focus - contenteditable", function() { - arrowsMoveFocus( "#autocomplete-contenteditable", true ); - }); - - test( "down arrow moves focus - contenteditable", function() { - arrowsMoveFocus( "#autocomplete-contenteditable", false ); - }); - - test( "up arrow moves cursor - input", function() { - arrowsNavigateElement( "#autocomplete", true, false ); - }); - - test( "down arrow moves cursor - input", function() { - arrowsNavigateElement( "#autocomplete", false, false ); - }); - - test( "up arrow moves cursor - textarea", function() { - arrowsNavigateElement( "#autocomplete-textarea", true, true ); - }); - - test( "down arrow moves cursor - textarea", function() { - arrowsNavigateElement( "#autocomplete-textarea", false, true ); - }); - - test( "up arrow moves cursor - contenteditable", function() { - arrowsNavigateElement( "#autocomplete-contenteditable", true, true ); - }); - - test( "down arrow moves cursor - contenteditable", function() { - arrowsNavigateElement( "#autocomplete-contenteditable", false, true ); - }); - - function arrowsInvokeSearch( id, isKeyUp, shouldMove ) { - expect( 1 ); - - var didMove = false, - element = $( id ).autocomplete({ - source: [ "a" ], - delay: 0, - minLength: 0 - }); - element.autocomplete( "instance" )._move = function() { - didMove = true; - }; - element.simulate( "keydown", { keyCode: ( isKeyUp ? $.ui.keyCode.UP : $.ui.keyCode.DOWN ) } ); - equal( didMove, shouldMove, "respond to arrow" ); - } - - function arrowsMoveFocus( id, isKeyUp ) { - expect( 1 ); - - var element = $( id ).autocomplete({ - source: [ "a" ], - delay: 0, - minLength: 0 - }); - element.autocomplete( "instance" )._move = function() { - ok( true, "repsond to arrow" ); - }; - element.autocomplete( "search" ); - element.simulate( "keydown", { keyCode: ( isKeyUp ? $.ui.keyCode.UP : $.ui.keyCode.DOWN ) } ); - } - - function arrowsNavigateElement( id, isKeyUp, shouldMove ) { - expect( 1 ); - - var didMove = false, - element = $( id ).autocomplete({ - source: [ "a" ], - delay: 0, - minLength: 0 - }); - element.bind( "keypress", function( e ) { - didMove = !e.isDefaultPrevented(); - }); - element.simulate( "keydown", { keyCode: ( isKeyUp ? $.ui.keyCode.UP : $.ui.keyCode.DOWN ) } ); - element.simulate( "keypress" ); - equal( didMove, shouldMove, "respond to arrow" ); - } -})(); - -asyncTest( "past end of menu in multiline autocomplete", function() { - expect( 2 ); - - var customVal = "custom value", - element = $( "#autocomplete-contenteditable" ).autocomplete({ - delay: 0, - source: [ "javascript" ], - focus: function( event, ui ) { - equal( ui.item.value, "javascript", "Item gained focus" ); - $( this ).text( customVal ); - event.preventDefault(); - } - }); - - element - .simulate( "focus" ) - .autocomplete( "search", "ja" ); - - setTimeout(function() { - element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); - element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); - equal( element.text(), customVal ); - start(); - }); -}); - -asyncTest( "ESCAPE in multiline autocomplete", function() { - expect( 2 ); - - var customVal = "custom value", - element = $( "#autocomplete-contenteditable" ).autocomplete({ - delay: 0, - source: [ "javascript" ], - focus: function( event, ui ) { - equal( ui.item.value, "javascript", "Item gained focus" ); - $( this ).text( customVal ); - event.preventDefault(); - } - }); - - element - .simulate( "focus" ) - .autocomplete( "search", "ja" ); - - setTimeout(function() { - element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); - element.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); - equal( element.text(), customVal ); - start(); - }); -}); - -asyncTest( "handle race condition", function() { - expect( 3 ); - var count = 0, - element = $( "#autocomplete" ).autocomplete({ - source: function( request, response ) { - count++; - if ( request.term.length === 1 ) { - equal( count, 1, "request with 1 character is first" ); - setTimeout(function() { - response([ "one" ]); - setTimeout( checkResults ); - }); - return; - } - equal( count, 2, "request with 2 characters is second" ); - response([ "two" ]); - } - }); - - element.autocomplete( "search", "a" ); - element.autocomplete( "search", "ab" ); - - function checkResults() { - equal( element.autocomplete( "widget" ).find( ".ui-menu-item" ).text(), "two", - "correct results displayed" ); - start(); - } -}); - -asyncTest( "simultaneous searches (#9334)", function() { - expect( 2 ); - var element = $( "#autocomplete" ).autocomplete({ - source: function( request, response ) { - setTimeout(function() { - response([ request.term ]); - }); - }, - response: function() { - ok( true, "response from first instance" ); - } - }), - element2 = $( "#autocomplete-textarea" ).autocomplete({ - source: function( request, response ) { - setTimeout(function() { - response([ request.term ]); - }); - }, - response: function() { - ok( true, "response from second instance" ); - start(); - } - }); - - element.autocomplete( "search", "test" ); - element2.autocomplete( "search", "test" ); -}); - -test( "ARIA", function() { - expect( 13 ); - var element = $( "#autocomplete" ).autocomplete({ - source: [ "java", "javascript" ] - }), - liveRegion = element.autocomplete( "instance" ).liveRegion; - - equal( liveRegion.children().length, 0, "Empty live region on create" ); - equal( liveRegion.attr( "aria-live" ), "assertive", - "Live region's aria-live attribute must be assertive" ); - equal( liveRegion.attr( "aria-relevant" ), "additions", - "Live region's aria-relevant attribute must be additions" ); - equal( liveRegion.attr( "role" ), "status", - "Live region's role attribute must be status" ); - - element.autocomplete( "search", "j" ); - equal( liveRegion.children().first().text(), - "2 results are available, use up and down arrow keys to navigate.", - "Live region for multiple values" ); - - element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); - equal( liveRegion.children().filter( ":visible" ).text(), "java", - "Live region changed on keydown to announce the highlighted value" ); - - element.one( "autocompletefocus", function( event ) { - event.preventDefault(); - }); - element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); - equal( liveRegion.children().filter( ":visible" ).text(), "javascript", - "Live region updated when default focus is prevented" ); - - element.autocomplete( "search", "javas" ); - equal( liveRegion.children().filter( ":visible" ).text(), - "1 result is available, use up and down arrow keys to navigate.", - "Live region for one value" ); - - element.autocomplete( "search", "z" ); - equal( liveRegion.children().filter( ":visible" ).text(), "No search results.", - "Live region for no values" ); - - equal( liveRegion.children().length, 5, - "Should be five children in the live region after the above" ); - equal( liveRegion.children().filter( ":visible" ).length, 1, - "Only one should be still visible" ); - ok( liveRegion.children().filter( ":visible" )[ 0 ] === liveRegion.children().last()[ 0 ], - "The last one should be the visible one" ); - - element.autocomplete( "destroy" ); - equal( liveRegion.parent().length, 0, - "The liveRegion should be detached after destroy" ); -}); - -test( "ARIA, aria-label announcement", function() { - expect( 1 ); - $.widget( "custom.catcomplete", $.ui.autocomplete, { - _renderMenu: function( ul, items ) { - var that = this; - $.each( items, function( index, item ) { - that._renderItemData( ul, item ) - .attr( "aria-label", item.category + " : " + item.label ); - }); - } - }); - var element = $( "#autocomplete" ).catcomplete({ - source: [ { label: "anders andersson", category: "People" } ] - }), - liveRegion = element.catcomplete( "instance" ).liveRegion; - element.catcomplete( "search", "a" ); - element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); - equal( liveRegion.children().filter( ":visible" ).text(), "People : anders andersson", - "Live region changed on keydown to announce the highlighted value's aria-label attribute" ); -}); - -test( "ARIA, init on detached input", function() { - expect( 1 ); - var element = $( "" ).autocomplete({ - source: [ "java", "javascript" ] - }), - liveRegion = element.autocomplete( "instance" ).liveRegion; - equal( liveRegion.parent().length, 1, "liveRegion must have a parent" ); -}); - -test( ".replaceWith() (#9172)", function() { - expect( 1 ); - - var element = $( "#autocomplete" ).autocomplete(), - replacement = "
test
", - parent = element.parent(); - element.replaceWith( replacement ); - equal( parent.html().toLowerCase(), replacement ); -}); - -asyncTest( "Search if the user retypes the same value (#7434)", function() { - expect( 3 ); - var element = $( "#autocomplete" ).autocomplete({ - source: [ "java", "javascript" ], - delay: 0 - }), - menu = element.autocomplete( "instance" ).menu.element; - - element.val( "j" ).simulate( "keydown" ); - setTimeout(function() { - ok( menu.is( ":visible" ), "menu displays initially" ); - element.trigger( "blur" ); - ok( !menu.is( ":visible" ), "menu hidden after blur" ); - element.val( "j" ).simulate( "keydown" ); - setTimeout(function() { - ok( menu.is( ":visible" ), "menu displays after typing the same value" ); - start(); - }); - }); -}); - -} ); diff --git a/tests/unit/autocomplete/autocomplete_events.js b/tests/unit/autocomplete/autocomplete_events.js deleted file mode 100644 index 606562aa9..000000000 --- a/tests/unit/autocomplete/autocomplete_events.js +++ /dev/null @@ -1,185 +0,0 @@ -define( [ - "jquery", - "ui/autocomplete" -], function( $ ) { - -module( "autocomplete: events" ); - -var data = [ "Clojure", "COBOL", "ColdFusion", "Java", "JavaScript", "Scala", "Scheme" ]; - -$.each([ - { - type: "input", - selector: "#autocomplete", - valueMethod: "val" - }, - { - type: "textarea", - selector: "#autocomplete-textarea", - valueMethod: "val" - }, - { - type: "contenteditable", - selector: "#autocomplete-contenteditable", - valueMethod: "text" - } -], function( i, settings ) { - asyncTest( "all events - " + settings.type, function() { - expect( 13 ); - var element = $( settings.selector ) - .autocomplete({ - autoFocus: false, - delay: 0, - source: data, - search: function( event ) { - equal( event.originalEvent.type, "keydown", "search originalEvent" ); - }, - response: function( event, ui ) { - deepEqual( ui.content, [ - { label: "Clojure", value: "Clojure" }, - { label: "Java", value: "Java" }, - { label: "JavaScript", value: "JavaScript" } - ], "response ui.content" ); - ui.content.splice( 0, 1 ); - }, - open: function() { - ok( menu.is( ":visible" ), "menu open on open" ); - }, - focus: function( event, ui ) { - equal( event.originalEvent.type, "menufocus", "focus originalEvent" ); - deepEqual( ui.item, { label: "Java", value: "Java" }, "focus ui.item" ); - }, - close: function( event ) { - equal( event.originalEvent.type, "menuselect", "close originalEvent" ); - ok( menu.is( ":hidden" ), "menu closed on close" ); - }, - select: function( event, ui ) { - equal( event.originalEvent.type, "menuselect", "select originalEvent" ); - deepEqual( ui.item, { label: "Java", value: "Java" }, "select ui.item" ); - }, - change: function( event, ui ) { - equal( event.originalEvent.type, "blur", "change originalEvent" ); - deepEqual( ui.item, { label: "Java", value: "Java" }, "change ui.item" ); - ok( menu.is( ":hidden" ), "menu closed on change" ); - start(); - } - }), - menu = element.autocomplete( "widget" ); - - element.simulate( "focus" )[ settings.valueMethod ]( "j" ).keydown(); - setTimeout(function() { - ok( menu.is( ":visible" ), "menu is visible after delay" ); - element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); - element.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - // blur must be async for IE to handle it properly - setTimeout(function() { - element.simulate( "blur" ); - }); - }); - }); -}); - -asyncTest( "change without selection", function() { - expect( 1 ); - var element = $( "#autocomplete" ).autocomplete({ - delay: 0, - source: data, - change: function( event, ui ) { - strictEqual( ui.item, null ); - start(); - } - }); - element.triggerHandler( "focus" ); - element.val( "ja" ).triggerHandler( "blur" ); -}); - -asyncTest( "cancel search", function() { - expect( 6 ); - var first = true, - element = $( "#autocomplete" ).autocomplete({ - delay: 0, - source: data, - search: function() { - if ( first ) { - equal( element.val(), "ja", "val on first search" ); - first = false; - return false; - } - equal( element.val(), "java", "val on second search" ); - }, - open: function() { - ok( true, "menu opened" ); - } - }), - menu = element.autocomplete( "widget" ); - element.val( "ja" ).keydown(); - setTimeout(function() { - ok( menu.is( ":hidden" ), "menu is hidden after first search" ); - element.val( "java" ).keydown(); - setTimeout(function() { - ok( menu.is( ":visible" ), "menu is visible after second search" ); - equal( menu.find( ".ui-menu-item" ).length, 2, "# of menu items" ); - start(); - }); - }); -}); - -asyncTest( "cancel focus", function() { - expect( 1 ); - var customVal = "custom value", - element = $( "#autocomplete" ).autocomplete({ - delay: 0, - source: data, - focus: function() { - $( this ).val( customVal ); - return false; - } - }); - element.val( "ja" ).keydown(); - setTimeout(function() { - element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); - equal( element.val(), customVal ); - start(); - }); -}); - -asyncTest( "cancel select", function() { - expect( 1 ); - var customVal = "custom value", - element = $( "#autocomplete" ).autocomplete({ - delay: 0, - source: data, - select: function() { - $( this ).val( customVal ); - return false; - } - }); - element.val( "ja" ).keydown(); - setTimeout(function() { - element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); - element.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - equal( element.val(), customVal ); - start(); - }); -}); - -asyncTest( "blur during remote search", function() { - expect( 1 ); - var ac = $( "#autocomplete" ).autocomplete({ - delay: 0, - source: function( request, response ) { - ok( true, "trigger request" ); - ac.simulate( "blur" ); - setTimeout(function() { - response([ "result" ]); - start(); - }, 25); - }, - open: function() { - ok( false, "opened after a blur" ); - } - }); - ac.val( "ro" ).keydown(); -}); - -} ); diff --git a/tests/unit/autocomplete/autocomplete_methods.js b/tests/unit/autocomplete/autocomplete_methods.js deleted file mode 100644 index 32080207a..000000000 --- a/tests/unit/autocomplete/autocomplete_methods.js +++ /dev/null @@ -1,48 +0,0 @@ -define( [ - "jquery", - "ui/autocomplete" -], function( $ ) { - -module( "autocomplete: methods" ); - -test( "destroy", function( assert ) { - expect( 1 ); - assert.domEqual( "#autocomplete", function() { - $( "#autocomplete" ).autocomplete().autocomplete( "destroy" ); - }); -}); - -test( "search, close", function() { - expect( 6 ); - var data = [ "c++", "java", "php", "coldfusion", "javascript", "asp", "ruby", "python", "c", "scala", "groovy", "haskell", "perl" ], - element = $( "#autocomplete" ).autocomplete({ - source: data, - minLength: 0 - }), - menu = element.autocomplete( "widget" ); - - ok( menu.is( ":hidden" ), "menu is hidden on init" ); - - element.autocomplete( "search" ); - ok( menu.is( ":visible" ), "menu is visible after search" ); - equal( menu.find( ".ui-menu-item" ).length, data.length, "all items for a blank search" ); - - element.val( "has" ).autocomplete( "search" ); - equal( menu.find( ".ui-menu-item" ).text(), "haskell", "only one item for set input value" ); - - element.autocomplete( "search", "ja" ); - equal( menu.find( ".ui-menu-item" ).length, 2, "only java and javascript for 'ja'" ); - - element.autocomplete( "close" ); - ok( menu.is( ":hidden" ), "menu is hidden after close" ); -}); - -test( "widget", function( assert ) { - expect( 2 ); - var element = $( "#autocomplete" ).autocomplete(), - widgetElement = element.autocomplete( "widget" ); - equal( widgetElement.length, 1, "one element" ); - assert.hasClasses( widgetElement, "ui-menu" ); -}); - -} ); diff --git a/tests/unit/autocomplete/autocomplete_options.js b/tests/unit/autocomplete/autocomplete_options.js deleted file mode 100644 index a07a8d636..000000000 --- a/tests/unit/autocomplete/autocomplete_options.js +++ /dev/null @@ -1,317 +0,0 @@ -define( [ - "jquery", - "ui/autocomplete" -], function( $ ) { - -module( "autocomplete: options" ); - -var data = [ "c++", "java", "php", "coldfusion", "javascript", "asp", "ruby", - "python", "c", "scala", "groovy", "haskell", "perl" ]; - -test( "appendTo: null", function() { - expect( 1 ); - var element = $( "#autocomplete" ).autocomplete(); - equal( element.autocomplete( "widget" ).parent()[ 0 ], document.body, - "defaults to body" ); - element.autocomplete( "destroy" ); -}); - -test( "appendTo: explicit", function() { - expect( 6 ); - var detached = $( "
" ), - element = $( "#autocomplete" ); - - element.autocomplete({ - appendTo: ".autocomplete-wrap" - }); - equal( element.autocomplete( "widget" ).parent()[ 0 ], - $( "#autocomplete-wrap1" )[ 0 ], "first found element" ); - equal( $( "#autocomplete-wrap2 .ui-autocomplete" ).length, 0, - "only appends to one element" ); - element.autocomplete( "destroy" ); - - element.autocomplete().autocomplete( "option", "appendTo", "#autocomplete-wrap1" ); - equal( element.autocomplete( "widget" ).parent()[ 0 ], - $( "#autocomplete-wrap1" )[ 0 ], "modified after init" ); - element.autocomplete( "destroy" ); - - element.autocomplete({ - appendTo: detached - }); - equal( element.autocomplete( "widget" ).parent()[ 0 ], detached[ 0 ], - "detached jQuery object" ); - element.autocomplete( "destroy" ); - - element.autocomplete({ - appendTo: detached[ 0 ] - }); - equal( element.autocomplete( "widget" ).parent()[ 0 ], detached[ 0 ], - "detached DOM element" ); - element.autocomplete( "destroy" ); - - element.autocomplete().autocomplete( "option", "appendTo", detached ); - equal( element.autocomplete( "widget" ).parent()[ 0 ], detached[ 0 ], - "detached DOM element via option()" ); - element.autocomplete( "destroy" ); -}); - -test( "appendTo: ui-front", function() { - expect( 2 ); - var element = $( "#autocomplete" ); - - $( "#autocomplete-wrap2" ).addClass( "ui-front" ); - element.autocomplete(); - equal( element.autocomplete( "widget" ).parent()[ 0 ], - $( "#autocomplete-wrap2" )[ 0 ], "null, inside .ui-front" ); - element.autocomplete( "destroy" ); - - element.autocomplete({ - appendTo: $() - }); - equal( element.autocomplete( "widget" ).parent()[ 0 ], - $( "#autocomplete-wrap2" )[ 0 ], "empty jQuery object, inside .ui-front" ); -}); - -function autoFocusTest( afValue, focusedLength ) { - var element = $( "#autocomplete" ).autocomplete({ - autoFocus: afValue, - delay: 0, - source: data, - open: function() { - equal( - element.autocomplete( "widget" ) - .find( ".ui-menu-item-wrapper.ui-state-active" ) - .length, - focusedLength, - "first item is " + (afValue ? "" : "not") + " auto focused" ); - start(); - } - }); - element.val( "ja" ).keydown(); - stop(); -} - -test( "autoFocus: false", function() { - expect( 1 ); - autoFocusTest( false, 0 ); -}); - -test( "autoFocus: true", function() { - expect( 1 ); - autoFocusTest( true, 1 ); -}); - -asyncTest( "delay", function() { - expect( 2 ); - var element = $( "#autocomplete" ).autocomplete({ - source: data, - delay: 25 - }), - menu = element.autocomplete( "widget" ); - element.val( "ja" ).keydown(); - - ok( menu.is( ":hidden" ), "menu is closed immediately after search" ); - - setTimeout(function() { - ok( menu.is( ":visible" ), "menu is open after delay" ); - start(); - }, 50 ); -}); - -asyncTest( "disabled", function( assert ) { - expect( 5 ); - var element = $( "#autocomplete" ).autocomplete({ - source: data, - delay: 0 - }), - menu = element.autocomplete( "disable" ).autocomplete( "widget" ); - element.val( "ja" ).keydown(); - - ok( menu.is( ":hidden" ) ); - - assert.lacksClasses( element, "ui-state-disabled" ); - assert.hasClasses( menu, "ui-autocomplete-disabled" ); - ok( !element.attr( "aria-disabled" ), "element doesn't get aria-disabled" ); - - setTimeout(function() { - ok( menu.is( ":hidden" ) ); - start(); - }); -}); - -test( "minLength", function() { - expect( 2 ); - var element = $( "#autocomplete" ).autocomplete({ - source: data - }), - menu = element.autocomplete( "widget" ); - element.autocomplete( "search", "" ); - ok( menu.is( ":hidden" ), "blank not enough for minLength: 1" ); - - element.autocomplete( "option", "minLength", 0 ); - element.autocomplete( "search", "" ); - ok( menu.is( ":visible" ), "blank enough for minLength: 0" ); -}); - -asyncTest( "minLength, exceed then drop below", function() { - expect( 4 ); - var element = $( "#autocomplete" ).autocomplete({ - minLength: 2, - source: function( req, res ) { - equal( req.term, "12", "correct search term" ); - setTimeout(function() { - res([ "item" ]); - }); - } - }), - menu = element.autocomplete( "widget" ); - - ok( menu.is( ":hidden" ), "menu is hidden before first search" ); - element.autocomplete( "search", "12" ); - - ok( menu.is( ":hidden" ), "menu is hidden before second search" ); - element.autocomplete( "search", "1" ); - - setTimeout(function() { - ok( menu.is( ":hidden" ), "menu is hidden after searches" ); - start(); - }); -}); - -test( "minLength, exceed then drop below then exceed", function() { - expect( 3 ); - var _res = [], - element = $( "#autocomplete" ).autocomplete({ - minLength: 2, - source: function( req, res ) { - _res.push( res ); - } - }), - menu = element.autocomplete( "widget" ); - - // trigger a valid search - ok( menu.is( ":hidden" ), "menu is hidden before first search" ); - element.autocomplete( "search", "12" ); - - // trigger a search below the minLength, to turn on cancelSearch flag - ok( menu.is( ":hidden" ), "menu is hidden before second search" ); - element.autocomplete( "search", "1" ); - - // trigger a valid search - element.autocomplete( "search", "13" ); - // react as if the first search was cancelled (default ajax behavior) - _res[ 0 ]([]); - // react to second search - _res[ 1 ]([ "13" ]); - - ok( menu.is( ":visible" ), "menu is visible after searches" ); -}); - -test( "source, local string array", function() { - expect( 1 ); - var element = $( "#autocomplete" ).autocomplete({ - source: data - }), - menu = element.autocomplete( "widget" ); - element.val( "ja" ).autocomplete( "search" ); - equal( menu.find( ".ui-menu-item" ).text(), "javajavascript" ); -}); - -function sourceTest( source, async ) { - var element = $( "#autocomplete" ).autocomplete({ - source: source - }), - menu = element.autocomplete( "widget" ); - function result() { - var items = menu.find( ".ui-menu-item" ); - equal( items.length, 3, "Should find three results." ); - deepEqual( items.eq( 0 ).data( "ui-autocomplete-item" ), { - label: "java", - value: "java" - }); - deepEqual( items.eq( 1 ).data( "ui-autocomplete-item" ), { - label: "javascript", - value: "javascript" - }); - deepEqual( items.eq( 2 ).data( "ui-autocomplete-item" ), { - label: "clojure", - value: "clojure" - }); - element.autocomplete( "destroy" ); - if ( async ) { - start(); - } - } - if ( async ) { - stop(); - $( document ).one( "ajaxStop", result ); - } - element.val( "j" ).autocomplete( "search" ); - if ( !async ) { - result(); - } -} - -test( "source, local object array, only labels", function() { - expect( 4 ); - sourceTest([ - { label: "java", value: null }, - { label: "php", value: null }, - { label: "coldfusion", value: "" }, - { label: "javascript", value: "" }, - { label: "clojure" } - ]); -}); - -test( "source, local object array, only values", function() { - expect( 4 ); - sourceTest([ - { value: "java", label: null }, - { value: "php", label: null }, - { value: "coldfusion", label: "" }, - { value: "javascript", label: "" }, - { value: "clojure" } - ]); -}); - -test( "source, url string with remote json string array", function() { - expect( 4 ); - sourceTest( "remote_string_array.txt", true ); -}); - -test( "source, url string with remote json object array, only value properties", function() { - expect( 4 ); - sourceTest( "remote_object_array_values.txt", true ); -}); - -test( "source, url string with remote json object array, only label properties", function() { - expect( 4 ); - sourceTest( "remote_object_array_labels.txt", true ); -}); - -test( "source, custom", function() { - expect( 5 ); - sourceTest(function( request, response ) { - equal( request.term, "j" ); - response([ - "java", - { label: "javascript", value: null }, - { value: "clojure", label: null } - ]); - }); -}); - -test( "source, update after init", function() { - expect( 2 ); - var element = $( "#autocomplete" ).autocomplete({ - source: [ "java", "javascript", "haskell" ] - }), - menu = element.autocomplete( "widget" ); - element.val( "ja" ).autocomplete( "search" ); - equal( menu.find( ".ui-menu-item" ).text(), "javajavascript" ); - element.autocomplete( "option", "source", [ "php", "asp" ] ); - element.val( "ph" ).autocomplete( "search" ); - equal( menu.find( ".ui-menu-item" ).text(), "php" ); -}); - -} ); diff --git a/tests/unit/autocomplete/common.js b/tests/unit/autocomplete/common.js new file mode 100644 index 000000000..5ee7cdda0 --- /dev/null +++ b/tests/unit/autocomplete/common.js @@ -0,0 +1,37 @@ +define( [ + "lib/common", + "ui/autocomplete" +], function( common ) { + +common.testWidget( "autocomplete", { + defaults: { + appendTo: null, + autoFocus: false, + classes: {}, + delay: 300, + disabled: false, + messages: { + noResults: "No search results.", + results: $.ui.autocomplete.prototype.options.messages.results + }, + minLength: 1, + position: { + my: "left top", + at: "left bottom", + collision: "none" + }, + source: null, + + // callbacks + change: null, + close: null, + create: null, + focus: null, + open: null, + response: null, + search: null, + select: null + } +}); + +} ); diff --git a/tests/unit/autocomplete/core.js b/tests/unit/autocomplete/core.js new file mode 100644 index 000000000..d25328dd5 --- /dev/null +++ b/tests/unit/autocomplete/core.js @@ -0,0 +1,401 @@ +define( [ + "jquery", + "ui/autocomplete" +], function( $ ) { + +module( "autocomplete: core" ); + +test( "markup structure", function( assert ) { + expect( 2 ); + var element = $( "#autocomplete" ).autocomplete(), + menu = element.autocomplete( "widget" ); + + assert.hasClasses( element, "ui-autocomplete-input" ); + assert.hasClasses( menu, "ui-autocomplete ui-widget ui-widget-content" ); +}); + +test( "prevent form submit on enter when menu is active", function() { + expect( 2 ); + var event, + element = $( "#autocomplete" ) + .autocomplete({ + source: [ "java", "javascript" ] + }) + .val( "ja" ) + .autocomplete( "search" ), + menu = element.autocomplete( "widget" ); + + event = $.Event( "keydown" ); + event.keyCode = $.ui.keyCode.DOWN; + element.trigger( event ); + equal( menu.find( ".ui-menu-item-wrapper.ui-state-active" ).length, 1, + "menu item is active" ); + + event = $.Event( "keydown" ); + event.keyCode = $.ui.keyCode.ENTER; + element.trigger( event ); + ok( event.isDefaultPrevented(), "default action is prevented" ); +}); + +test( "allow form submit on enter when menu is not active", function() { + expect( 1 ); + var event, + element = $( "#autocomplete" ) + .autocomplete({ + autoFocus: false, + source: [ "java", "javascript" ] + }) + .val( "ja" ) + .autocomplete( "search" ); + + event = $.Event( "keydown" ); + event.keyCode = $.ui.keyCode.ENTER; + element.trigger( event ); + ok( !event.isDefaultPrevented(), "default action is prevented" ); +}); + +(function() { + test( "up arrow invokes search - input", function() { + arrowsInvokeSearch( "#autocomplete", true, true ); + }); + + test( "down arrow invokes search - input", function() { + arrowsInvokeSearch( "#autocomplete", false, true ); + }); + + test( "up arrow invokes search - textarea", function() { + arrowsInvokeSearch( "#autocomplete-textarea", true, false ); + }); + + test( "down arrow invokes search - textarea", function() { + arrowsInvokeSearch( "#autocomplete-textarea", false, false ); + }); + + test( "up arrow invokes search - contenteditable", function() { + arrowsInvokeSearch( "#autocomplete-contenteditable", true, false ); + }); + + test( "down arrow invokes search - contenteditable", function() { + arrowsInvokeSearch( "#autocomplete-contenteditable", false, false ); + }); + + test( "up arrow moves focus - input", function() { + arrowsMoveFocus( "#autocomplete", true ); + }); + + test( "down arrow moves focus - input", function() { + arrowsMoveFocus( "#autocomplete", false ); + }); + + test( "up arrow moves focus - textarea", function() { + arrowsMoveFocus( "#autocomplete-textarea", true ); + }); + + test( "down arrow moves focus - textarea", function() { + arrowsMoveFocus( "#autocomplete-textarea", false ); + }); + + test( "up arrow moves focus - contenteditable", function() { + arrowsMoveFocus( "#autocomplete-contenteditable", true ); + }); + + test( "down arrow moves focus - contenteditable", function() { + arrowsMoveFocus( "#autocomplete-contenteditable", false ); + }); + + test( "up arrow moves cursor - input", function() { + arrowsNavigateElement( "#autocomplete", true, false ); + }); + + test( "down arrow moves cursor - input", function() { + arrowsNavigateElement( "#autocomplete", false, false ); + }); + + test( "up arrow moves cursor - textarea", function() { + arrowsNavigateElement( "#autocomplete-textarea", true, true ); + }); + + test( "down arrow moves cursor - textarea", function() { + arrowsNavigateElement( "#autocomplete-textarea", false, true ); + }); + + test( "up arrow moves cursor - contenteditable", function() { + arrowsNavigateElement( "#autocomplete-contenteditable", true, true ); + }); + + test( "down arrow moves cursor - contenteditable", function() { + arrowsNavigateElement( "#autocomplete-contenteditable", false, true ); + }); + + function arrowsInvokeSearch( id, isKeyUp, shouldMove ) { + expect( 1 ); + + var didMove = false, + element = $( id ).autocomplete({ + source: [ "a" ], + delay: 0, + minLength: 0 + }); + element.autocomplete( "instance" )._move = function() { + didMove = true; + }; + element.simulate( "keydown", { keyCode: ( isKeyUp ? $.ui.keyCode.UP : $.ui.keyCode.DOWN ) } ); + equal( didMove, shouldMove, "respond to arrow" ); + } + + function arrowsMoveFocus( id, isKeyUp ) { + expect( 1 ); + + var element = $( id ).autocomplete({ + source: [ "a" ], + delay: 0, + minLength: 0 + }); + element.autocomplete( "instance" )._move = function() { + ok( true, "repsond to arrow" ); + }; + element.autocomplete( "search" ); + element.simulate( "keydown", { keyCode: ( isKeyUp ? $.ui.keyCode.UP : $.ui.keyCode.DOWN ) } ); + } + + function arrowsNavigateElement( id, isKeyUp, shouldMove ) { + expect( 1 ); + + var didMove = false, + element = $( id ).autocomplete({ + source: [ "a" ], + delay: 0, + minLength: 0 + }); + element.bind( "keypress", function( e ) { + didMove = !e.isDefaultPrevented(); + }); + element.simulate( "keydown", { keyCode: ( isKeyUp ? $.ui.keyCode.UP : $.ui.keyCode.DOWN ) } ); + element.simulate( "keypress" ); + equal( didMove, shouldMove, "respond to arrow" ); + } +})(); + +asyncTest( "past end of menu in multiline autocomplete", function() { + expect( 2 ); + + var customVal = "custom value", + element = $( "#autocomplete-contenteditable" ).autocomplete({ + delay: 0, + source: [ "javascript" ], + focus: function( event, ui ) { + equal( ui.item.value, "javascript", "Item gained focus" ); + $( this ).text( customVal ); + event.preventDefault(); + } + }); + + element + .simulate( "focus" ) + .autocomplete( "search", "ja" ); + + setTimeout(function() { + element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + equal( element.text(), customVal ); + start(); + }); +}); + +asyncTest( "ESCAPE in multiline autocomplete", function() { + expect( 2 ); + + var customVal = "custom value", + element = $( "#autocomplete-contenteditable" ).autocomplete({ + delay: 0, + source: [ "javascript" ], + focus: function( event, ui ) { + equal( ui.item.value, "javascript", "Item gained focus" ); + $( this ).text( customVal ); + event.preventDefault(); + } + }); + + element + .simulate( "focus" ) + .autocomplete( "search", "ja" ); + + setTimeout(function() { + element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + element.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); + equal( element.text(), customVal ); + start(); + }); +}); + +asyncTest( "handle race condition", function() { + expect( 3 ); + var count = 0, + element = $( "#autocomplete" ).autocomplete({ + source: function( request, response ) { + count++; + if ( request.term.length === 1 ) { + equal( count, 1, "request with 1 character is first" ); + setTimeout(function() { + response([ "one" ]); + setTimeout( checkResults ); + }); + return; + } + equal( count, 2, "request with 2 characters is second" ); + response([ "two" ]); + } + }); + + element.autocomplete( "search", "a" ); + element.autocomplete( "search", "ab" ); + + function checkResults() { + equal( element.autocomplete( "widget" ).find( ".ui-menu-item" ).text(), "two", + "correct results displayed" ); + start(); + } +}); + +asyncTest( "simultaneous searches (#9334)", function() { + expect( 2 ); + var element = $( "#autocomplete" ).autocomplete({ + source: function( request, response ) { + setTimeout(function() { + response([ request.term ]); + }); + }, + response: function() { + ok( true, "response from first instance" ); + } + }), + element2 = $( "#autocomplete-textarea" ).autocomplete({ + source: function( request, response ) { + setTimeout(function() { + response([ request.term ]); + }); + }, + response: function() { + ok( true, "response from second instance" ); + start(); + } + }); + + element.autocomplete( "search", "test" ); + element2.autocomplete( "search", "test" ); +}); + +test( "ARIA", function() { + expect( 13 ); + var element = $( "#autocomplete" ).autocomplete({ + source: [ "java", "javascript" ] + }), + liveRegion = element.autocomplete( "instance" ).liveRegion; + + equal( liveRegion.children().length, 0, "Empty live region on create" ); + equal( liveRegion.attr( "aria-live" ), "assertive", + "Live region's aria-live attribute must be assertive" ); + equal( liveRegion.attr( "aria-relevant" ), "additions", + "Live region's aria-relevant attribute must be additions" ); + equal( liveRegion.attr( "role" ), "status", + "Live region's role attribute must be status" ); + + element.autocomplete( "search", "j" ); + equal( liveRegion.children().first().text(), + "2 results are available, use up and down arrow keys to navigate.", + "Live region for multiple values" ); + + element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + equal( liveRegion.children().filter( ":visible" ).text(), "java", + "Live region changed on keydown to announce the highlighted value" ); + + element.one( "autocompletefocus", function( event ) { + event.preventDefault(); + }); + element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + equal( liveRegion.children().filter( ":visible" ).text(), "javascript", + "Live region updated when default focus is prevented" ); + + element.autocomplete( "search", "javas" ); + equal( liveRegion.children().filter( ":visible" ).text(), + "1 result is available, use up and down arrow keys to navigate.", + "Live region for one value" ); + + element.autocomplete( "search", "z" ); + equal( liveRegion.children().filter( ":visible" ).text(), "No search results.", + "Live region for no values" ); + + equal( liveRegion.children().length, 5, + "Should be five children in the live region after the above" ); + equal( liveRegion.children().filter( ":visible" ).length, 1, + "Only one should be still visible" ); + ok( liveRegion.children().filter( ":visible" )[ 0 ] === liveRegion.children().last()[ 0 ], + "The last one should be the visible one" ); + + element.autocomplete( "destroy" ); + equal( liveRegion.parent().length, 0, + "The liveRegion should be detached after destroy" ); +}); + +test( "ARIA, aria-label announcement", function() { + expect( 1 ); + $.widget( "custom.catcomplete", $.ui.autocomplete, { + _renderMenu: function( ul, items ) { + var that = this; + $.each( items, function( index, item ) { + that._renderItemData( ul, item ) + .attr( "aria-label", item.category + " : " + item.label ); + }); + } + }); + var element = $( "#autocomplete" ).catcomplete({ + source: [ { label: "anders andersson", category: "People" } ] + }), + liveRegion = element.catcomplete( "instance" ).liveRegion; + element.catcomplete( "search", "a" ); + element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + equal( liveRegion.children().filter( ":visible" ).text(), "People : anders andersson", + "Live region changed on keydown to announce the highlighted value's aria-label attribute" ); +}); + +test( "ARIA, init on detached input", function() { + expect( 1 ); + var element = $( "" ).autocomplete({ + source: [ "java", "javascript" ] + }), + liveRegion = element.autocomplete( "instance" ).liveRegion; + equal( liveRegion.parent().length, 1, "liveRegion must have a parent" ); +}); + +test( ".replaceWith() (#9172)", function() { + expect( 1 ); + + var element = $( "#autocomplete" ).autocomplete(), + replacement = "
test
", + parent = element.parent(); + element.replaceWith( replacement ); + equal( parent.html().toLowerCase(), replacement ); +}); + +asyncTest( "Search if the user retypes the same value (#7434)", function() { + expect( 3 ); + var element = $( "#autocomplete" ).autocomplete({ + source: [ "java", "javascript" ], + delay: 0 + }), + menu = element.autocomplete( "instance" ).menu.element; + + element.val( "j" ).simulate( "keydown" ); + setTimeout(function() { + ok( menu.is( ":visible" ), "menu displays initially" ); + element.trigger( "blur" ); + ok( !menu.is( ":visible" ), "menu hidden after blur" ); + element.val( "j" ).simulate( "keydown" ); + setTimeout(function() { + ok( menu.is( ":visible" ), "menu displays after typing the same value" ); + start(); + }); + }); +}); + +} ); diff --git a/tests/unit/autocomplete/events.js b/tests/unit/autocomplete/events.js new file mode 100644 index 000000000..606562aa9 --- /dev/null +++ b/tests/unit/autocomplete/events.js @@ -0,0 +1,185 @@ +define( [ + "jquery", + "ui/autocomplete" +], function( $ ) { + +module( "autocomplete: events" ); + +var data = [ "Clojure", "COBOL", "ColdFusion", "Java", "JavaScript", "Scala", "Scheme" ]; + +$.each([ + { + type: "input", + selector: "#autocomplete", + valueMethod: "val" + }, + { + type: "textarea", + selector: "#autocomplete-textarea", + valueMethod: "val" + }, + { + type: "contenteditable", + selector: "#autocomplete-contenteditable", + valueMethod: "text" + } +], function( i, settings ) { + asyncTest( "all events - " + settings.type, function() { + expect( 13 ); + var element = $( settings.selector ) + .autocomplete({ + autoFocus: false, + delay: 0, + source: data, + search: function( event ) { + equal( event.originalEvent.type, "keydown", "search originalEvent" ); + }, + response: function( event, ui ) { + deepEqual( ui.content, [ + { label: "Clojure", value: "Clojure" }, + { label: "Java", value: "Java" }, + { label: "JavaScript", value: "JavaScript" } + ], "response ui.content" ); + ui.content.splice( 0, 1 ); + }, + open: function() { + ok( menu.is( ":visible" ), "menu open on open" ); + }, + focus: function( event, ui ) { + equal( event.originalEvent.type, "menufocus", "focus originalEvent" ); + deepEqual( ui.item, { label: "Java", value: "Java" }, "focus ui.item" ); + }, + close: function( event ) { + equal( event.originalEvent.type, "menuselect", "close originalEvent" ); + ok( menu.is( ":hidden" ), "menu closed on close" ); + }, + select: function( event, ui ) { + equal( event.originalEvent.type, "menuselect", "select originalEvent" ); + deepEqual( ui.item, { label: "Java", value: "Java" }, "select ui.item" ); + }, + change: function( event, ui ) { + equal( event.originalEvent.type, "blur", "change originalEvent" ); + deepEqual( ui.item, { label: "Java", value: "Java" }, "change ui.item" ); + ok( menu.is( ":hidden" ), "menu closed on change" ); + start(); + } + }), + menu = element.autocomplete( "widget" ); + + element.simulate( "focus" )[ settings.valueMethod ]( "j" ).keydown(); + setTimeout(function() { + ok( menu.is( ":visible" ), "menu is visible after delay" ); + element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + element.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + // blur must be async for IE to handle it properly + setTimeout(function() { + element.simulate( "blur" ); + }); + }); + }); +}); + +asyncTest( "change without selection", function() { + expect( 1 ); + var element = $( "#autocomplete" ).autocomplete({ + delay: 0, + source: data, + change: function( event, ui ) { + strictEqual( ui.item, null ); + start(); + } + }); + element.triggerHandler( "focus" ); + element.val( "ja" ).triggerHandler( "blur" ); +}); + +asyncTest( "cancel search", function() { + expect( 6 ); + var first = true, + element = $( "#autocomplete" ).autocomplete({ + delay: 0, + source: data, + search: function() { + if ( first ) { + equal( element.val(), "ja", "val on first search" ); + first = false; + return false; + } + equal( element.val(), "java", "val on second search" ); + }, + open: function() { + ok( true, "menu opened" ); + } + }), + menu = element.autocomplete( "widget" ); + element.val( "ja" ).keydown(); + setTimeout(function() { + ok( menu.is( ":hidden" ), "menu is hidden after first search" ); + element.val( "java" ).keydown(); + setTimeout(function() { + ok( menu.is( ":visible" ), "menu is visible after second search" ); + equal( menu.find( ".ui-menu-item" ).length, 2, "# of menu items" ); + start(); + }); + }); +}); + +asyncTest( "cancel focus", function() { + expect( 1 ); + var customVal = "custom value", + element = $( "#autocomplete" ).autocomplete({ + delay: 0, + source: data, + focus: function() { + $( this ).val( customVal ); + return false; + } + }); + element.val( "ja" ).keydown(); + setTimeout(function() { + element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + equal( element.val(), customVal ); + start(); + }); +}); + +asyncTest( "cancel select", function() { + expect( 1 ); + var customVal = "custom value", + element = $( "#autocomplete" ).autocomplete({ + delay: 0, + source: data, + select: function() { + $( this ).val( customVal ); + return false; + } + }); + element.val( "ja" ).keydown(); + setTimeout(function() { + element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + element.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + equal( element.val(), customVal ); + start(); + }); +}); + +asyncTest( "blur during remote search", function() { + expect( 1 ); + var ac = $( "#autocomplete" ).autocomplete({ + delay: 0, + source: function( request, response ) { + ok( true, "trigger request" ); + ac.simulate( "blur" ); + setTimeout(function() { + response([ "result" ]); + start(); + }, 25); + }, + open: function() { + ok( false, "opened after a blur" ); + } + }); + ac.val( "ro" ).keydown(); +}); + +} ); diff --git a/tests/unit/autocomplete/methods.js b/tests/unit/autocomplete/methods.js new file mode 100644 index 000000000..32080207a --- /dev/null +++ b/tests/unit/autocomplete/methods.js @@ -0,0 +1,48 @@ +define( [ + "jquery", + "ui/autocomplete" +], function( $ ) { + +module( "autocomplete: methods" ); + +test( "destroy", function( assert ) { + expect( 1 ); + assert.domEqual( "#autocomplete", function() { + $( "#autocomplete" ).autocomplete().autocomplete( "destroy" ); + }); +}); + +test( "search, close", function() { + expect( 6 ); + var data = [ "c++", "java", "php", "coldfusion", "javascript", "asp", "ruby", "python", "c", "scala", "groovy", "haskell", "perl" ], + element = $( "#autocomplete" ).autocomplete({ + source: data, + minLength: 0 + }), + menu = element.autocomplete( "widget" ); + + ok( menu.is( ":hidden" ), "menu is hidden on init" ); + + element.autocomplete( "search" ); + ok( menu.is( ":visible" ), "menu is visible after search" ); + equal( menu.find( ".ui-menu-item" ).length, data.length, "all items for a blank search" ); + + element.val( "has" ).autocomplete( "search" ); + equal( menu.find( ".ui-menu-item" ).text(), "haskell", "only one item for set input value" ); + + element.autocomplete( "search", "ja" ); + equal( menu.find( ".ui-menu-item" ).length, 2, "only java and javascript for 'ja'" ); + + element.autocomplete( "close" ); + ok( menu.is( ":hidden" ), "menu is hidden after close" ); +}); + +test( "widget", function( assert ) { + expect( 2 ); + var element = $( "#autocomplete" ).autocomplete(), + widgetElement = element.autocomplete( "widget" ); + equal( widgetElement.length, 1, "one element" ); + assert.hasClasses( widgetElement, "ui-menu" ); +}); + +} ); diff --git a/tests/unit/autocomplete/options.js b/tests/unit/autocomplete/options.js new file mode 100644 index 000000000..a07a8d636 --- /dev/null +++ b/tests/unit/autocomplete/options.js @@ -0,0 +1,317 @@ +define( [ + "jquery", + "ui/autocomplete" +], function( $ ) { + +module( "autocomplete: options" ); + +var data = [ "c++", "java", "php", "coldfusion", "javascript", "asp", "ruby", + "python", "c", "scala", "groovy", "haskell", "perl" ]; + +test( "appendTo: null", function() { + expect( 1 ); + var element = $( "#autocomplete" ).autocomplete(); + equal( element.autocomplete( "widget" ).parent()[ 0 ], document.body, + "defaults to body" ); + element.autocomplete( "destroy" ); +}); + +test( "appendTo: explicit", function() { + expect( 6 ); + var detached = $( "
" ), + element = $( "#autocomplete" ); + + element.autocomplete({ + appendTo: ".autocomplete-wrap" + }); + equal( element.autocomplete( "widget" ).parent()[ 0 ], + $( "#autocomplete-wrap1" )[ 0 ], "first found element" ); + equal( $( "#autocomplete-wrap2 .ui-autocomplete" ).length, 0, + "only appends to one element" ); + element.autocomplete( "destroy" ); + + element.autocomplete().autocomplete( "option", "appendTo", "#autocomplete-wrap1" ); + equal( element.autocomplete( "widget" ).parent()[ 0 ], + $( "#autocomplete-wrap1" )[ 0 ], "modified after init" ); + element.autocomplete( "destroy" ); + + element.autocomplete({ + appendTo: detached + }); + equal( element.autocomplete( "widget" ).parent()[ 0 ], detached[ 0 ], + "detached jQuery object" ); + element.autocomplete( "destroy" ); + + element.autocomplete({ + appendTo: detached[ 0 ] + }); + equal( element.autocomplete( "widget" ).parent()[ 0 ], detached[ 0 ], + "detached DOM element" ); + element.autocomplete( "destroy" ); + + element.autocomplete().autocomplete( "option", "appendTo", detached ); + equal( element.autocomplete( "widget" ).parent()[ 0 ], detached[ 0 ], + "detached DOM element via option()" ); + element.autocomplete( "destroy" ); +}); + +test( "appendTo: ui-front", function() { + expect( 2 ); + var element = $( "#autocomplete" ); + + $( "#autocomplete-wrap2" ).addClass( "ui-front" ); + element.autocomplete(); + equal( element.autocomplete( "widget" ).parent()[ 0 ], + $( "#autocomplete-wrap2" )[ 0 ], "null, inside .ui-front" ); + element.autocomplete( "destroy" ); + + element.autocomplete({ + appendTo: $() + }); + equal( element.autocomplete( "widget" ).parent()[ 0 ], + $( "#autocomplete-wrap2" )[ 0 ], "empty jQuery object, inside .ui-front" ); +}); + +function autoFocusTest( afValue, focusedLength ) { + var element = $( "#autocomplete" ).autocomplete({ + autoFocus: afValue, + delay: 0, + source: data, + open: function() { + equal( + element.autocomplete( "widget" ) + .find( ".ui-menu-item-wrapper.ui-state-active" ) + .length, + focusedLength, + "first item is " + (afValue ? "" : "not") + " auto focused" ); + start(); + } + }); + element.val( "ja" ).keydown(); + stop(); +} + +test( "autoFocus: false", function() { + expect( 1 ); + autoFocusTest( false, 0 ); +}); + +test( "autoFocus: true", function() { + expect( 1 ); + autoFocusTest( true, 1 ); +}); + +asyncTest( "delay", function() { + expect( 2 ); + var element = $( "#autocomplete" ).autocomplete({ + source: data, + delay: 25 + }), + menu = element.autocomplete( "widget" ); + element.val( "ja" ).keydown(); + + ok( menu.is( ":hidden" ), "menu is closed immediately after search" ); + + setTimeout(function() { + ok( menu.is( ":visible" ), "menu is open after delay" ); + start(); + }, 50 ); +}); + +asyncTest( "disabled", function( assert ) { + expect( 5 ); + var element = $( "#autocomplete" ).autocomplete({ + source: data, + delay: 0 + }), + menu = element.autocomplete( "disable" ).autocomplete( "widget" ); + element.val( "ja" ).keydown(); + + ok( menu.is( ":hidden" ) ); + + assert.lacksClasses( element, "ui-state-disabled" ); + assert.hasClasses( menu, "ui-autocomplete-disabled" ); + ok( !element.attr( "aria-disabled" ), "element doesn't get aria-disabled" ); + + setTimeout(function() { + ok( menu.is( ":hidden" ) ); + start(); + }); +}); + +test( "minLength", function() { + expect( 2 ); + var element = $( "#autocomplete" ).autocomplete({ + source: data + }), + menu = element.autocomplete( "widget" ); + element.autocomplete( "search", "" ); + ok( menu.is( ":hidden" ), "blank not enough for minLength: 1" ); + + element.autocomplete( "option", "minLength", 0 ); + element.autocomplete( "search", "" ); + ok( menu.is( ":visible" ), "blank enough for minLength: 0" ); +}); + +asyncTest( "minLength, exceed then drop below", function() { + expect( 4 ); + var element = $( "#autocomplete" ).autocomplete({ + minLength: 2, + source: function( req, res ) { + equal( req.term, "12", "correct search term" ); + setTimeout(function() { + res([ "item" ]); + }); + } + }), + menu = element.autocomplete( "widget" ); + + ok( menu.is( ":hidden" ), "menu is hidden before first search" ); + element.autocomplete( "search", "12" ); + + ok( menu.is( ":hidden" ), "menu is hidden before second search" ); + element.autocomplete( "search", "1" ); + + setTimeout(function() { + ok( menu.is( ":hidden" ), "menu is hidden after searches" ); + start(); + }); +}); + +test( "minLength, exceed then drop below then exceed", function() { + expect( 3 ); + var _res = [], + element = $( "#autocomplete" ).autocomplete({ + minLength: 2, + source: function( req, res ) { + _res.push( res ); + } + }), + menu = element.autocomplete( "widget" ); + + // trigger a valid search + ok( menu.is( ":hidden" ), "menu is hidden before first search" ); + element.autocomplete( "search", "12" ); + + // trigger a search below the minLength, to turn on cancelSearch flag + ok( menu.is( ":hidden" ), "menu is hidden before second search" ); + element.autocomplete( "search", "1" ); + + // trigger a valid search + element.autocomplete( "search", "13" ); + // react as if the first search was cancelled (default ajax behavior) + _res[ 0 ]([]); + // react to second search + _res[ 1 ]([ "13" ]); + + ok( menu.is( ":visible" ), "menu is visible after searches" ); +}); + +test( "source, local string array", function() { + expect( 1 ); + var element = $( "#autocomplete" ).autocomplete({ + source: data + }), + menu = element.autocomplete( "widget" ); + element.val( "ja" ).autocomplete( "search" ); + equal( menu.find( ".ui-menu-item" ).text(), "javajavascript" ); +}); + +function sourceTest( source, async ) { + var element = $( "#autocomplete" ).autocomplete({ + source: source + }), + menu = element.autocomplete( "widget" ); + function result() { + var items = menu.find( ".ui-menu-item" ); + equal( items.length, 3, "Should find three results." ); + deepEqual( items.eq( 0 ).data( "ui-autocomplete-item" ), { + label: "java", + value: "java" + }); + deepEqual( items.eq( 1 ).data( "ui-autocomplete-item" ), { + label: "javascript", + value: "javascript" + }); + deepEqual( items.eq( 2 ).data( "ui-autocomplete-item" ), { + label: "clojure", + value: "clojure" + }); + element.autocomplete( "destroy" ); + if ( async ) { + start(); + } + } + if ( async ) { + stop(); + $( document ).one( "ajaxStop", result ); + } + element.val( "j" ).autocomplete( "search" ); + if ( !async ) { + result(); + } +} + +test( "source, local object array, only labels", function() { + expect( 4 ); + sourceTest([ + { label: "java", value: null }, + { label: "php", value: null }, + { label: "coldfusion", value: "" }, + { label: "javascript", value: "" }, + { label: "clojure" } + ]); +}); + +test( "source, local object array, only values", function() { + expect( 4 ); + sourceTest([ + { value: "java", label: null }, + { value: "php", label: null }, + { value: "coldfusion", label: "" }, + { value: "javascript", label: "" }, + { value: "clojure" } + ]); +}); + +test( "source, url string with remote json string array", function() { + expect( 4 ); + sourceTest( "remote_string_array.txt", true ); +}); + +test( "source, url string with remote json object array, only value properties", function() { + expect( 4 ); + sourceTest( "remote_object_array_values.txt", true ); +}); + +test( "source, url string with remote json object array, only label properties", function() { + expect( 4 ); + sourceTest( "remote_object_array_labels.txt", true ); +}); + +test( "source, custom", function() { + expect( 5 ); + sourceTest(function( request, response ) { + equal( request.term, "j" ); + response([ + "java", + { label: "javascript", value: null }, + { value: "clojure", label: null } + ]); + }); +}); + +test( "source, update after init", function() { + expect( 2 ); + var element = $( "#autocomplete" ).autocomplete({ + source: [ "java", "javascript", "haskell" ] + }), + menu = element.autocomplete( "widget" ); + element.val( "ja" ).autocomplete( "search" ); + equal( menu.find( ".ui-menu-item" ).text(), "javajavascript" ); + element.autocomplete( "option", "source", [ "php", "asp" ] ); + element.val( "ph" ).autocomplete( "search" ); + equal( menu.find( ".ui-menu-item" ).text(), "php" ); +}); + +} ); diff --git a/tests/unit/button/button_common.js b/tests/unit/button/button_common.js deleted file mode 100644 index d376f4f05..000000000 --- a/tests/unit/button/button_common.js +++ /dev/null @@ -1,22 +0,0 @@ -define( [ - "lib/common", - "ui/button" -], function( common ) { - -common.testWidget( "button", { - defaults: { - classes: {}, - disabled: null, - icons: { - primary: null, - secondary: null - }, - label: null, - text: true, - - // callbacks - create: null - } -}); - -} ); diff --git a/tests/unit/button/button_core.js b/tests/unit/button/button_core.js deleted file mode 100644 index 4bc8d9fe5..000000000 --- a/tests/unit/button/button_core.js +++ /dev/null @@ -1,230 +0,0 @@ -define( [ - "jquery", - "ui/button" -], function( $ ) { - -module("button: core"); - -test("checkbox", function( assert ) { - expect( 4 ); - var input = $("#check"), - label = $("label[for=check]"); - ok( input.is(":visible") ); - ok( label.is(":not(.ui-button)") ); - input.button(); - assert.hasClasses( input, "ui-helper-hidden-accessible" ); - assert.hasClasses( label, "ui-button" ); -}); - -test("radios", function( assert ) { - expect( 8 ); - var inputs = $("#radio0 input"), - labels = $("#radio0 label"); - ok( inputs.is(":visible") ); - ok( labels.is(":not(.ui-button)") ); - inputs.button(); - inputs.each(function() { - assert.hasClasses( this, "ui-helper-hidden-accessible" ); - }); - labels.each(function() { - assert.hasClasses( this, "ui-button" ); - }); -}); - -test("radio groups", function( assert ) { - expect( 12 ); - - function assertClasses(noForm, form1, form2) { - assert.hasClasses( $("#radio0 .ui-button" + noForm ), "ui-state-active" ); - assert.hasClasses( $("#radio1 .ui-button" + form1 ), "ui-state-active" ); - assert.hasClasses( $("#radio2 .ui-button" + form2 ), "ui-state-active" ); - } - - $("input[type=radio]").button(); - assertClasses(":eq(0)", ":eq(1)", ":eq(2)"); - - // click outside of forms - $("#radio0 .ui-button:eq(1)").click(); - assertClasses(":eq(1)", ":eq(1)", ":eq(2)"); - - // click in first form - $("#radio1 .ui-button:eq(0)").click(); - assertClasses(":eq(1)", ":eq(0)", ":eq(2)"); - - // click in second form - $("#radio2 .ui-button:eq(0)").click(); - assertClasses(":eq(1)", ":eq(0)", ":eq(0)"); -}); - -test( "radio groups - ignore elements with same name", function() { - expect( 1 ); - var form = $( "form:first" ), - radios = form.find( "[type=radio]" ).button(), - checkbox = $( "", { - type: "checkbox", - name: radios.attr( "name" ) - }); - - form.append( checkbox ); - radios.button( "refresh" ); - ok( true, "no exception from accessing button instance of checkbox" ); -}); - -test("input type submit, don't create child elements", function() { - expect( 2 ); - var input = $("#submit"); - deepEqual( input.children().length, 0 ); - input.button(); - deepEqual( input.children().length, 0 ); -}); - -test("buttonset", function( assert ) { - expect( 6 ); - var set = $("#radio1").buttonset(); - assert.hasClasses( set, "ui-buttonset" ); - deepEqual( set.children(".ui-button").length, 3 ); - deepEqual( set.children("input[type=radio].ui-helper-hidden-accessible").length, 3 ); - ok( set.children("label:eq(0)").is(".ui-button.ui-corner-left:not(.ui-corner-all)") ); - ok( set.children("label:eq(1)").is(".ui-button:not(.ui-corner-all)") ); - ok( set.children("label:eq(2)").is(".ui-button.ui-corner-right:not(.ui-corner-all)") ); -}); - -test("buttonset (rtl)", function( assert ) { - expect( 6 ); - var set, - parent = $("#radio1").parent(); - // Set to rtl - parent.attr("dir", "rtl"); - - set = $("#radio1").buttonset(); - assert.hasClasses( set, "ui-buttonset" ); - deepEqual( set.children(".ui-button").length, 3 ); - deepEqual( set.children("input[type=radio].ui-helper-hidden-accessible").length, 3 ); - ok( set.children("label:eq(0)").is(".ui-button.ui-corner-right:not(.ui-corner-all)") ); - ok( set.children("label:eq(1)").is(".ui-button:not(.ui-corner-all)") ); - ok( set.children("label:eq(2)").is(".ui-button.ui-corner-left:not(.ui-corner-all)") ); -}); - -// TODO: simulated click events don't behave like real click events in IE -// remove this when simulate properly simulates this -// see http://yuilibrary.com/projects/yui2/ticket/2528826 fore more info -if ( !$.ui.ie || ( document.documentMode && document.documentMode > 8 ) ) { - asyncTest( "ensure checked and aria after single click on checkbox label button, see #5518", function( assert ) { - expect( 3 ); - - $("#check2").button().change( function() { - var lbl = $( this ).button("widget"); - ok( this.checked, "checked ok" ); - ok( lbl.attr("aria-pressed") === "true", "aria ok" ); - assert.hasClasses( lbl, "ui-state-active" ); - }); - - // support: Opera - // Opera doesn't trigger a change event when this is done synchronously. - // This seems to be a side effect of another test, but until that can be - // tracked down, this delay will have to do. - setTimeout(function() { - $("#check2").button("widget").simulate("click"); - start(); - }, 1 ); - }); -} - -test( "#7092 - button creation that requires a matching label does not find label in all cases", function( assert ) { - expect( 5 ); - var group = $( "" ); - group.find( "input[type=checkbox]" ).button(); - assert.hasClasses( group.find( "label" ), "ui-button" ); - - group = $( "" ); - group.filter( "input[type=checkbox]" ).button(); - assert.hasClasses( group.filter( "label" ), "ui-button" ); - - group = $( "" ); - group.find( "input[type=checkbox]" ).button(); - assert.hasClasses( group.filter( "label" ), "ui-button" ); - - group = $( "" ); - group.find( "input[type=checkbox]" ).button(); - assert.hasClasses( group.find( "label" ), "ui-button" ); - - group = $( "" ); - group.filter( "input[type=checkbox]" ).button(); - assert.hasClasses( group.find( "label" ), "ui-button" ); -}); - -test( "#5946 - buttonset should ignore buttons that are not :visible", function( assert ) { - expect( 2 ); - $( "#radio01" ).next().addBack().hide(); - var set = $( "#radio0" ).buttonset({ items: "input[type=radio]:visible" }); - ok( set.find( "label:eq(0)" ).is( ":not(.ui-button):not(.ui-corner-left)" ) ); - assert.hasClasses( set.find( "label:eq(1)" ), "ui-button ui-corner-left" ); -}); - -test( "#6262 - buttonset not applying ui-corner to invisible elements", function( assert ) { - expect( 3 ); - $( "#radio0" ).hide(); - var set = $( "#radio0" ).buttonset(); - assert.hasClasses( set.find( "label:eq(0)" ), "ui-button ui-corner-left" ); - assert.hasClasses( set.find( "label:eq(1)" ), "ui-button" ); - assert.hasClasses( set.find( "label:eq(2)" ), "ui-button ui-corner-right" ); - -}); - -asyncTest( "Resetting a button's form should refresh the visual state of the button widget to match.", function( assert ) { - expect( 2 ); - var form = $( "
" + - "" + - "" + - "
" ), - button = form.find( "button" ).button(), - checkbox = form.find( "input[type=checkbox]" ).button(); - - checkbox.prop( "checked", false ).button( "refresh" ); - assert.lacksClasses( checkbox.button( "widget" ), "ui-state-active" ); - - form.get( 0 ).reset(); - - // #9213: If a button has been removed, refresh should not be called on it when - // its corresponding form is reset. - button.remove(); - - setTimeout(function() { - assert.hasClasses( checkbox.button( "widget" ), "ui-state-active" ); - start(); - }, 1 ); -}); - -asyncTest( "#6711 Checkbox/Radiobutton do not Show Focused State when using Keyboard Navigation", function( assert ) { - expect( 2 ); - var check = $( "#check" ).button(), - label = $( "label[for='check']" ); - assert.lacksClasses( label, "ui-state-focus" ); - check.focus(); - setTimeout(function() { - assert.hasClasses( label, "ui-state-focus" ); - start(); - }); -}); - -test( "#7534 - Button label selector works for ids with \":\"", function( assert ) { - expect( 1 ); - var group = $( "" ); - group.find( "input" ).button(); - assert.hasClasses( group.find( "label" ), "ui-button" , "Found an id with a :" ); -}); - -asyncTest( "#9169 - Disabled button maintains ui-state-focus", function( assert ) { - expect( 2 ); - var element = $( "#button1" ).button(); - element[ 0 ].focus(); - setTimeout(function() { - assert.hasClasses( element, "ui-state-focus" ); - element.button( "disable" ); - assert.lacksClasses( element, "ui-state-focus", - "button does not have ui-state-focus when disabled" ); - start(); - }); -}); - -} ); diff --git a/tests/unit/button/button_events.js b/tests/unit/button/button_events.js deleted file mode 100644 index ec930077c..000000000 --- a/tests/unit/button/button_events.js +++ /dev/null @@ -1,36 +0,0 @@ -define( [ - "jquery", - "ui/button" -], function( $ ) { - -module("button: events"); - -test("buttonset works with single-quote named elements (#7505)", function() { - expect( 1 ); - $("#radio3").buttonset(); - $("#radio33").click( function(){ - ok( true, "button clicks work with single-quote named elements" ); - }).click(); -}); - -asyncTest( "when button loses focus, ensure active state is removed (#8559)", function( assert ) { - expect( 1 ); - - var element = $( "#button" ).button(); - - element.one( "keypress", function() { - element.one( "blur", function() { - assert.lacksClasses( element, "ui-state-active", "button loses active state appropriately" ); - start(); - }).blur(); - }); - - element.focus(); - setTimeout(function() { - element - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ) - .simulate( "keypress", { keyCode: $.ui.keyCode.ENTER } ); - }); -}); - -} ); diff --git a/tests/unit/button/button_methods.js b/tests/unit/button/button_methods.js deleted file mode 100644 index be36096b2..000000000 --- a/tests/unit/button/button_methods.js +++ /dev/null @@ -1,73 +0,0 @@ -define( [ - "jquery", - "ui/button" -], function( $ ) { - -module("button: methods"); - -test("destroy", function( assert ) { - expect( 1 ); - assert.domEqual( "#button", function() { - $( "#button" ).button().button( "destroy" ); - }); -}); - -test( "refresh: Ensure disabled state is preserved correctly.", function() { - expect( 8 ); - - var element = $( "" ); - element.button({ disabled: true }).button( "refresh" ); - ok( element.button( "option", "disabled" ), "Anchor button should remain disabled after refresh" ); //See #8237 - - element = $( "
" ); - element.button({ disabled: true }).button( "refresh" ); - ok( element.button( "option", "disabled" ), "
buttons should remain disabled after refresh" ); - - element = $( "" ); - element.button( { disabled: true} ).button( "refresh" ); - ok( element.button( "option", "disabled" ), "" ); - element.button( { disabled: true} ).prop( "disabled", false ).button( "refresh" ); - ok( !element.button( "option", "disabled" ), "Changing a " ), - $( "" ), - $( "
" ), - $( "" ), - $( "" ) - ]; - - $.each( elements, function() { - var element = $( this ).first().button(), - buttonElement = element.button( "widget" ), - elementType = element.prop( "nodeName" ).toLowerCase(); - - if ( element.is( "input" ) ) { - elementType += ":" + element.attr( "type" ); - } - - element.trigger( "mousedown" ); - assert.hasClasses( buttonElement, "ui-state-active", - "[" + elementType + "] has ui-state-active class after mousedown." ); - - element.button( "disable" ); - if ( element.is( "[type=checkbox], [type=radio]" ) ) { - assert.hasClasses( buttonElement, "ui-state-active", - "Disabled [" + elementType + "] has ui-state-active class." ); - } else { - assert.lacksClasses( buttonElement, "ui-state-active", - "Disabled [" + elementType + "] does not have ui-state-active class." ); - } - }); -}); - -test("text false without icon", function() { - expect( 1 ); - $("#button").button({ - text: false - }); - ok( $("#button").is(".ui-button-text-only:not(.ui-button-icon-only)") ); - - $("#button").button("destroy"); -}); - -test("text false with icon", function() { - expect( 1 ); - $("#button").button({ - text: false, - icons: { - primary: "iconclass" - } - }); - ok( $("#button").is(".ui-button-icon-only:not(.ui-button-text):has(span.ui-icon.iconclass)") ); - - $("#button").button("destroy"); -}); - -test("label, default", function() { - expect( 2 ); - $("#button").button(); - deepEqual( $("#button").text(), "Label" ); - deepEqual( $( "#button").button( "option", "label" ), "Label" ); - - $("#button").button("destroy"); -}); - -test("label", function() { - expect( 2 ); - $("#button").button({ - label: "xxx" - }); - deepEqual( $("#button").text(), "xxx" ); - deepEqual( $("#button").button( "option", "label" ), "xxx" ); - - $("#button").button("destroy"); -}); - -test("label default with input type submit", function() { - expect( 2 ); - deepEqual( $("#submit").button().val(), "Label" ); - deepEqual( $("#submit").button( "option", "label" ), "Label" ); -}); - -test("label with input type submit", function() { - expect( 2 ); - var label = $("#submit").button({ - label: "xxx" - }).val(); - deepEqual( label, "xxx" ); - deepEqual( $("#submit").button( "option", "label" ), "xxx" ); -}); - -test("icons", function() { - expect( 1 ); - $("#button").button({ - text: false, - icons: { - primary: "iconclass", - secondary: "iconclass2" - } - }); - ok( $("#button").is(":has(span.ui-icon.ui-button-icon-primary.iconclass):has(span.ui-icon.ui-button-icon-secondary.iconclass2)") ); - - $("#button").button("destroy"); -}); - -test( "#5295 - button does not remove hoverstate if disabled" , function( assert ) { - expect( 1 ); - var btn = $("#button").button(); - btn.hover( function() { - btn.button( "disable" ); - }); - btn.trigger( "mouseenter" ); - btn.trigger( "mouseleave" ); - assert.lacksClasses( btn, "ui-state-hover" ); -}); - -} ); diff --git a/tests/unit/button/common.js b/tests/unit/button/common.js new file mode 100644 index 000000000..d376f4f05 --- /dev/null +++ b/tests/unit/button/common.js @@ -0,0 +1,22 @@ +define( [ + "lib/common", + "ui/button" +], function( common ) { + +common.testWidget( "button", { + defaults: { + classes: {}, + disabled: null, + icons: { + primary: null, + secondary: null + }, + label: null, + text: true, + + // callbacks + create: null + } +}); + +} ); diff --git a/tests/unit/button/core.js b/tests/unit/button/core.js new file mode 100644 index 000000000..4bc8d9fe5 --- /dev/null +++ b/tests/unit/button/core.js @@ -0,0 +1,230 @@ +define( [ + "jquery", + "ui/button" +], function( $ ) { + +module("button: core"); + +test("checkbox", function( assert ) { + expect( 4 ); + var input = $("#check"), + label = $("label[for=check]"); + ok( input.is(":visible") ); + ok( label.is(":not(.ui-button)") ); + input.button(); + assert.hasClasses( input, "ui-helper-hidden-accessible" ); + assert.hasClasses( label, "ui-button" ); +}); + +test("radios", function( assert ) { + expect( 8 ); + var inputs = $("#radio0 input"), + labels = $("#radio0 label"); + ok( inputs.is(":visible") ); + ok( labels.is(":not(.ui-button)") ); + inputs.button(); + inputs.each(function() { + assert.hasClasses( this, "ui-helper-hidden-accessible" ); + }); + labels.each(function() { + assert.hasClasses( this, "ui-button" ); + }); +}); + +test("radio groups", function( assert ) { + expect( 12 ); + + function assertClasses(noForm, form1, form2) { + assert.hasClasses( $("#radio0 .ui-button" + noForm ), "ui-state-active" ); + assert.hasClasses( $("#radio1 .ui-button" + form1 ), "ui-state-active" ); + assert.hasClasses( $("#radio2 .ui-button" + form2 ), "ui-state-active" ); + } + + $("input[type=radio]").button(); + assertClasses(":eq(0)", ":eq(1)", ":eq(2)"); + + // click outside of forms + $("#radio0 .ui-button:eq(1)").click(); + assertClasses(":eq(1)", ":eq(1)", ":eq(2)"); + + // click in first form + $("#radio1 .ui-button:eq(0)").click(); + assertClasses(":eq(1)", ":eq(0)", ":eq(2)"); + + // click in second form + $("#radio2 .ui-button:eq(0)").click(); + assertClasses(":eq(1)", ":eq(0)", ":eq(0)"); +}); + +test( "radio groups - ignore elements with same name", function() { + expect( 1 ); + var form = $( "form:first" ), + radios = form.find( "[type=radio]" ).button(), + checkbox = $( "", { + type: "checkbox", + name: radios.attr( "name" ) + }); + + form.append( checkbox ); + radios.button( "refresh" ); + ok( true, "no exception from accessing button instance of checkbox" ); +}); + +test("input type submit, don't create child elements", function() { + expect( 2 ); + var input = $("#submit"); + deepEqual( input.children().length, 0 ); + input.button(); + deepEqual( input.children().length, 0 ); +}); + +test("buttonset", function( assert ) { + expect( 6 ); + var set = $("#radio1").buttonset(); + assert.hasClasses( set, "ui-buttonset" ); + deepEqual( set.children(".ui-button").length, 3 ); + deepEqual( set.children("input[type=radio].ui-helper-hidden-accessible").length, 3 ); + ok( set.children("label:eq(0)").is(".ui-button.ui-corner-left:not(.ui-corner-all)") ); + ok( set.children("label:eq(1)").is(".ui-button:not(.ui-corner-all)") ); + ok( set.children("label:eq(2)").is(".ui-button.ui-corner-right:not(.ui-corner-all)") ); +}); + +test("buttonset (rtl)", function( assert ) { + expect( 6 ); + var set, + parent = $("#radio1").parent(); + // Set to rtl + parent.attr("dir", "rtl"); + + set = $("#radio1").buttonset(); + assert.hasClasses( set, "ui-buttonset" ); + deepEqual( set.children(".ui-button").length, 3 ); + deepEqual( set.children("input[type=radio].ui-helper-hidden-accessible").length, 3 ); + ok( set.children("label:eq(0)").is(".ui-button.ui-corner-right:not(.ui-corner-all)") ); + ok( set.children("label:eq(1)").is(".ui-button:not(.ui-corner-all)") ); + ok( set.children("label:eq(2)").is(".ui-button.ui-corner-left:not(.ui-corner-all)") ); +}); + +// TODO: simulated click events don't behave like real click events in IE +// remove this when simulate properly simulates this +// see http://yuilibrary.com/projects/yui2/ticket/2528826 fore more info +if ( !$.ui.ie || ( document.documentMode && document.documentMode > 8 ) ) { + asyncTest( "ensure checked and aria after single click on checkbox label button, see #5518", function( assert ) { + expect( 3 ); + + $("#check2").button().change( function() { + var lbl = $( this ).button("widget"); + ok( this.checked, "checked ok" ); + ok( lbl.attr("aria-pressed") === "true", "aria ok" ); + assert.hasClasses( lbl, "ui-state-active" ); + }); + + // support: Opera + // Opera doesn't trigger a change event when this is done synchronously. + // This seems to be a side effect of another test, but until that can be + // tracked down, this delay will have to do. + setTimeout(function() { + $("#check2").button("widget").simulate("click"); + start(); + }, 1 ); + }); +} + +test( "#7092 - button creation that requires a matching label does not find label in all cases", function( assert ) { + expect( 5 ); + var group = $( "" ); + group.find( "input[type=checkbox]" ).button(); + assert.hasClasses( group.find( "label" ), "ui-button" ); + + group = $( "" ); + group.filter( "input[type=checkbox]" ).button(); + assert.hasClasses( group.filter( "label" ), "ui-button" ); + + group = $( "" ); + group.find( "input[type=checkbox]" ).button(); + assert.hasClasses( group.filter( "label" ), "ui-button" ); + + group = $( "" ); + group.find( "input[type=checkbox]" ).button(); + assert.hasClasses( group.find( "label" ), "ui-button" ); + + group = $( "" ); + group.filter( "input[type=checkbox]" ).button(); + assert.hasClasses( group.find( "label" ), "ui-button" ); +}); + +test( "#5946 - buttonset should ignore buttons that are not :visible", function( assert ) { + expect( 2 ); + $( "#radio01" ).next().addBack().hide(); + var set = $( "#radio0" ).buttonset({ items: "input[type=radio]:visible" }); + ok( set.find( "label:eq(0)" ).is( ":not(.ui-button):not(.ui-corner-left)" ) ); + assert.hasClasses( set.find( "label:eq(1)" ), "ui-button ui-corner-left" ); +}); + +test( "#6262 - buttonset not applying ui-corner to invisible elements", function( assert ) { + expect( 3 ); + $( "#radio0" ).hide(); + var set = $( "#radio0" ).buttonset(); + assert.hasClasses( set.find( "label:eq(0)" ), "ui-button ui-corner-left" ); + assert.hasClasses( set.find( "label:eq(1)" ), "ui-button" ); + assert.hasClasses( set.find( "label:eq(2)" ), "ui-button ui-corner-right" ); + +}); + +asyncTest( "Resetting a button's form should refresh the visual state of the button widget to match.", function( assert ) { + expect( 2 ); + var form = $( "
" + + "" + + "" + + "
" ), + button = form.find( "button" ).button(), + checkbox = form.find( "input[type=checkbox]" ).button(); + + checkbox.prop( "checked", false ).button( "refresh" ); + assert.lacksClasses( checkbox.button( "widget" ), "ui-state-active" ); + + form.get( 0 ).reset(); + + // #9213: If a button has been removed, refresh should not be called on it when + // its corresponding form is reset. + button.remove(); + + setTimeout(function() { + assert.hasClasses( checkbox.button( "widget" ), "ui-state-active" ); + start(); + }, 1 ); +}); + +asyncTest( "#6711 Checkbox/Radiobutton do not Show Focused State when using Keyboard Navigation", function( assert ) { + expect( 2 ); + var check = $( "#check" ).button(), + label = $( "label[for='check']" ); + assert.lacksClasses( label, "ui-state-focus" ); + check.focus(); + setTimeout(function() { + assert.hasClasses( label, "ui-state-focus" ); + start(); + }); +}); + +test( "#7534 - Button label selector works for ids with \":\"", function( assert ) { + expect( 1 ); + var group = $( "" ); + group.find( "input" ).button(); + assert.hasClasses( group.find( "label" ), "ui-button" , "Found an id with a :" ); +}); + +asyncTest( "#9169 - Disabled button maintains ui-state-focus", function( assert ) { + expect( 2 ); + var element = $( "#button1" ).button(); + element[ 0 ].focus(); + setTimeout(function() { + assert.hasClasses( element, "ui-state-focus" ); + element.button( "disable" ); + assert.lacksClasses( element, "ui-state-focus", + "button does not have ui-state-focus when disabled" ); + start(); + }); +}); + +} ); diff --git a/tests/unit/button/events.js b/tests/unit/button/events.js new file mode 100644 index 000000000..ec930077c --- /dev/null +++ b/tests/unit/button/events.js @@ -0,0 +1,36 @@ +define( [ + "jquery", + "ui/button" +], function( $ ) { + +module("button: events"); + +test("buttonset works with single-quote named elements (#7505)", function() { + expect( 1 ); + $("#radio3").buttonset(); + $("#radio33").click( function(){ + ok( true, "button clicks work with single-quote named elements" ); + }).click(); +}); + +asyncTest( "when button loses focus, ensure active state is removed (#8559)", function( assert ) { + expect( 1 ); + + var element = $( "#button" ).button(); + + element.one( "keypress", function() { + element.one( "blur", function() { + assert.lacksClasses( element, "ui-state-active", "button loses active state appropriately" ); + start(); + }).blur(); + }); + + element.focus(); + setTimeout(function() { + element + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ) + .simulate( "keypress", { keyCode: $.ui.keyCode.ENTER } ); + }); +}); + +} ); diff --git a/tests/unit/button/methods.js b/tests/unit/button/methods.js new file mode 100644 index 000000000..be36096b2 --- /dev/null +++ b/tests/unit/button/methods.js @@ -0,0 +1,73 @@ +define( [ + "jquery", + "ui/button" +], function( $ ) { + +module("button: methods"); + +test("destroy", function( assert ) { + expect( 1 ); + assert.domEqual( "#button", function() { + $( "#button" ).button().button( "destroy" ); + }); +}); + +test( "refresh: Ensure disabled state is preserved correctly.", function() { + expect( 8 ); + + var element = $( "" ); + element.button({ disabled: true }).button( "refresh" ); + ok( element.button( "option", "disabled" ), "Anchor button should remain disabled after refresh" ); //See #8237 + + element = $( "
" ); + element.button({ disabled: true }).button( "refresh" ); + ok( element.button( "option", "disabled" ), "
buttons should remain disabled after refresh" ); + + element = $( "" ); + element.button( { disabled: true} ).button( "refresh" ); + ok( element.button( "option", "disabled" ), "" ); + element.button( { disabled: true} ).prop( "disabled", false ).button( "refresh" ); + ok( !element.button( "option", "disabled" ), "Changing a " ), + $( "" ), + $( "
" ), + $( "" ), + $( "" ) + ]; + + $.each( elements, function() { + var element = $( this ).first().button(), + buttonElement = element.button( "widget" ), + elementType = element.prop( "nodeName" ).toLowerCase(); + + if ( element.is( "input" ) ) { + elementType += ":" + element.attr( "type" ); + } + + element.trigger( "mousedown" ); + assert.hasClasses( buttonElement, "ui-state-active", + "[" + elementType + "] has ui-state-active class after mousedown." ); + + element.button( "disable" ); + if ( element.is( "[type=checkbox], [type=radio]" ) ) { + assert.hasClasses( buttonElement, "ui-state-active", + "Disabled [" + elementType + "] has ui-state-active class." ); + } else { + assert.lacksClasses( buttonElement, "ui-state-active", + "Disabled [" + elementType + "] does not have ui-state-active class." ); + } + }); +}); + +test("text false without icon", function() { + expect( 1 ); + $("#button").button({ + text: false + }); + ok( $("#button").is(".ui-button-text-only:not(.ui-button-icon-only)") ); + + $("#button").button("destroy"); +}); + +test("text false with icon", function() { + expect( 1 ); + $("#button").button({ + text: false, + icons: { + primary: "iconclass" + } + }); + ok( $("#button").is(".ui-button-icon-only:not(.ui-button-text):has(span.ui-icon.iconclass)") ); + + $("#button").button("destroy"); +}); + +test("label, default", function() { + expect( 2 ); + $("#button").button(); + deepEqual( $("#button").text(), "Label" ); + deepEqual( $( "#button").button( "option", "label" ), "Label" ); + + $("#button").button("destroy"); +}); + +test("label", function() { + expect( 2 ); + $("#button").button({ + label: "xxx" + }); + deepEqual( $("#button").text(), "xxx" ); + deepEqual( $("#button").button( "option", "label" ), "xxx" ); + + $("#button").button("destroy"); +}); + +test("label default with input type submit", function() { + expect( 2 ); + deepEqual( $("#submit").button().val(), "Label" ); + deepEqual( $("#submit").button( "option", "label" ), "Label" ); +}); + +test("label with input type submit", function() { + expect( 2 ); + var label = $("#submit").button({ + label: "xxx" + }).val(); + deepEqual( label, "xxx" ); + deepEqual( $("#submit").button( "option", "label" ), "xxx" ); +}); + +test("icons", function() { + expect( 1 ); + $("#button").button({ + text: false, + icons: { + primary: "iconclass", + secondary: "iconclass2" + } + }); + ok( $("#button").is(":has(span.ui-icon.ui-button-icon-primary.iconclass):has(span.ui-icon.ui-button-icon-secondary.iconclass2)") ); + + $("#button").button("destroy"); +}); + +test( "#5295 - button does not remove hoverstate if disabled" , function( assert ) { + expect( 1 ); + var btn = $("#button").button(); + btn.hover( function() { + btn.button( "disable" ); + }); + btn.trigger( "mouseenter" ); + btn.trigger( "mouseleave" ); + assert.lacksClasses( btn, "ui-state-hover" ); +}); + +} ); diff --git a/tests/unit/datepicker/common.js b/tests/unit/datepicker/common.js new file mode 100644 index 000000000..1eecc85cb --- /dev/null +++ b/tests/unit/datepicker/common.js @@ -0,0 +1,7 @@ +/* +TestHelpers.commonWidgetTests( "datepicker", { + defaults: { + disabled: false + } +}); +*/ diff --git a/tests/unit/datepicker/core.js b/tests/unit/datepicker/core.js new file mode 100644 index 000000000..f6e0dd58f --- /dev/null +++ b/tests/unit/datepicker/core.js @@ -0,0 +1,530 @@ +define( [ + "jquery", + "lib/common", + "./helper", + "ui/datepicker", + "ui/i18n/datepicker-he" +], function( $, common, testHelper ) { + +module( "datepicker: core", { + setup: function() { + $( "body" ).focus(); + } +}); + +common.testJshint( "datepicker" ); + +test("initialization - Reinitialization after body had been emptied.", function() { + expect( 1 ); + var bodyContent = $("body").children(), inp = $("#inp"); + $("#inp").datepicker(); + $("body").empty().append(inp); + $("#inp").datepicker(); + ok( $("#"+$.datepicker._mainDivId).length===1, "Datepicker container added" ); + $("body").empty().append(bodyContent); // Returning to initial state for later tests +}); + +test( "widget method - empty collection", function() { + expect( 1 ); + $( "#nonExist" ).datepicker(); // should create nothing + ok( !$( "#ui-datepicker-div" ).length, "Non init on empty collection" ); +}); + +test("widget method", function() { + expect( 1 ); + var actual = $("#inp").datepicker().datepicker("widget")[0]; + deepEqual($("body > #ui-datepicker-div:last-child")[0], actual); +}); + +asyncTest( "baseStructure", function() { + expect( 58 ); + var header, title, table, thead, week, panel, inl, child, + inp = testHelper.initNewInput(), + dp = $( "#ui-datepicker-div" ); + + function step1() { + testHelper.onFocus( inp, function() { + ok( dp.is( ":visible" ), "Structure - datepicker visible" ); + ok( !dp.is( ".ui-datepicker-rtl" ), "Structure - not right-to-left" ); + ok( !dp.is( ".ui-datepicker-multi" ), "Structure - not multi-month" ); + equal( dp.children().length, 2, "Structure - child count" ); + + header = dp.children( ":first" ); + ok( header.is( "div.ui-datepicker-header" ), "Structure - header division" ); + equal( header.children().length, 3, "Structure - header child count" ); + ok( header.children( ":first" ).is( "a.ui-datepicker-prev" ) && header.children( ":first" ).html() !== "", "Structure - prev link" ); + ok( header.children( ":eq(1)" ).is( "a.ui-datepicker-next" ) && header.children( ":eq(1)" ).html() !== "", "Structure - next link" ); + + title = header.children( ":last" ); + ok( title.is( "div.ui-datepicker-title" ) && title.html() !== "","Structure - title division" ); + equal( title.children().length, 2, "Structure - title child count" ); + ok( title.children( ":first" ).is( "span.ui-datepicker-month" ) && title.children( ":first" ).text() !== "", "Structure - month text" ); + ok( title.children( ":last" ).is( "span.ui-datepicker-year" ) && title.children( ":last" ).text() !== "", "Structure - year text" ); + + table = dp.children( ":eq(1)" ); + ok( table.is( "table.ui-datepicker-calendar" ), "Structure - month table" ); + ok( table.children( ":first" ).is( "thead" ), "Structure - month table thead" ); + + thead = table.children( ":first" ).children( ":first" ); + ok( thead.is( "tr" ), "Structure - month table title row" ); + equal( thead.find( "th" ).length, 7, "Structure - month table title cells" ); + ok( table.children( ":eq(1)" ).is( "tbody" ), "Structure - month table body" ); + ok( table.children( ":eq(1)" ).children( "tr" ).length >= 4, "Structure - month table week count" ); + + week = table.children( ":eq(1)" ).children( ":first" ); + ok( week.is( "tr" ), "Structure - month table week row" ); + equal( week.children().length, 7, "Structure - week child count" ); + ok( week.children( ":first" ).is( "td.ui-datepicker-week-end" ), "Structure - month table first day cell" ); + ok( week.children( ":last" ).is( "td.ui-datepicker-week-end" ), "Structure - month table second day cell" ); + + inp.datepicker( "hide" ).datepicker( "destroy" ); + step2(); + }); + } + + function step2() { + // Editable month/year and button panel + inp = testHelper.initNewInput({ + changeMonth: true, + changeYear: true, + showButtonPanel: true + }); + testHelper.onFocus( inp, function() { + title = dp.find( "div.ui-datepicker-title" ); + ok( title.children( ":first" ).is( "select.ui-datepicker-month" ), "Structure - month selector" ); + ok( title.children( ":last" ).is( "select.ui-datepicker-year" ), "Structure - year selector" ); + + panel = dp.children( ":last" ); + ok( panel.is( "div.ui-datepicker-buttonpane" ), "Structure - button panel division" ); + equal( panel.children().length, 2, "Structure - button panel child count" ); + ok( panel.children( ":first" ).is( "button.ui-datepicker-current" ), "Structure - today button" ); + ok( panel.children( ":last" ).is( "button.ui-datepicker-close" ), "Structure - close button" ); + + inp.datepicker( "hide" ).datepicker( "destroy" ); + step3(); + }); + } + + function step3() { + // Multi-month 2 + inp = testHelper.initNewInput({ numberOfMonths: 2 }); + testHelper.onFocus( inp, function() { + ok( dp.is( ".ui-datepicker-multi" ), "Structure multi [2] - multi-month" ); + equal( dp.children().length, 3, "Structure multi [2] - child count" ); + + child = dp.children( ":first" ); + ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure multi [2] - first month division" ); + + child = dp.children( ":eq(1)" ); + ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-last" ), "Structure multi [2] - second month division" ); + + child = dp.children( ":eq(2)" ); + ok( child.is( "div.ui-datepicker-row-break" ), "Structure multi [2] - row break" ); + ok( dp.is( ".ui-datepicker-multi-2" ), "Structure multi [2] - multi-2" ); + + inp.datepicker( "hide" ).datepicker( "destroy" ); + step4(); + }); + } + + function step4() { + // Multi-month 3 + inp = testHelper.initNewInput({ numberOfMonths: 3 }); + testHelper.onFocus( inp, function() { + ok( dp.is( ".ui-datepicker-multi-3" ), "Structure multi [3] - multi-3" ); + ok( !dp.is( ".ui-datepicker-multi-2" ), "Structure multi [3] - Trac #6704" ); + + inp.datepicker( "hide" ).datepicker( "destroy" ); + step5(); + }); + } + + function step5() { + // Multi-month [2, 2] + inp = testHelper.initNewInput({ numberOfMonths: [ 2, 2 ] }); + testHelper.onFocus( inp, function() { + ok( dp.is( ".ui-datepicker-multi" ), "Structure multi - multi-month" ); + equal( dp.children().length, 6, "Structure multi [2,2] - child count" ); + + child = dp.children( ":first" ); + ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure multi [2,2] - first month division" ); + + child = dp.children( ":eq(1)" ); + ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-last" ), "Structure multi [2,2] - second month division" ); + + child = dp.children( ":eq(2)" ); + ok( child.is( "div.ui-datepicker-row-break" ), "Structure multi [2,2] - row break" ); + + child = dp.children( ":eq(3)" ); + ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure multi [2,2] - third month division" ); + + child = dp.children( ":eq(4)" ); + ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-last" ), "Structure multi [2,2] - fourth month division" ); + + child = dp.children( ":eq(5)" ); + ok( child.is( "div.ui-datepicker-row-break" ), "Structure multi [2,2] - row break" ); + + inp.datepicker( "hide" ).datepicker( "destroy" ); + + // Inline + inl = testHelper.init( "#inl" ); + dp = inl.children(); + + ok( dp.is( ".ui-datepicker-inline" ), "Structure inline - main div" ); + ok( !dp.is( ".ui-datepicker-rtl" ), "Structure inline - not right-to-left" ); + ok( !dp.is( ".ui-datepicker-multi" ), "Structure inline - not multi-month" ); + equal( dp.children().length, 2, "Structure inline - child count" ); + + header = dp.children( ":first" ); + ok( header.is( "div.ui-datepicker-header" ), "Structure inline - header division" ); + equal( header.children().length, 3, "Structure inline - header child count" ); + + table = dp.children( ":eq(1)" ); + ok( table.is( "table.ui-datepicker-calendar" ), "Structure inline - month table" ); + ok( table.children( ":first" ).is( "thead" ), "Structure inline - month table thead" ); + ok( table.children( ":eq(1)" ).is( "tbody" ), "Structure inline - month table body" ); + + inl.datepicker( "destroy" ); + + // Inline multi-month + inl = testHelper.init( "#inl", { numberOfMonths: 2 } ); + dp = inl.children(); + + ok( dp.is( ".ui-datepicker-inline" ) && dp.is( ".ui-datepicker-multi" ), "Structure inline multi - main div" ); + equal( dp.children().length, 3, "Structure inline multi - child count" ); + + child = dp.children( ":first" ); + ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure inline multi - first month division" ); + + child = dp.children( ":eq(1)" ); + ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-last" ), "Structure inline multi - second month division" ); + + child = dp.children( ":eq(2)" ); + ok( child.is( "div.ui-datepicker-row-break" ), "Structure inline multi - row break" ); + + inl.datepicker( "destroy" ); + start(); + }); + } + + step1(); +}); + +asyncTest( "customStructure", function() { + expect( 20 ); + var header, panel, title, thead, + inp = testHelper.initNewInput( $.datepicker.regional.he ), + dp = $( "#ui-datepicker-div" ); + + function step1() { + inp.datepicker( "option", "showButtonPanel", true ); + + testHelper.onFocus( inp, function() { + ok( dp.is( ".ui-datepicker-rtl" ), "Structure RTL - right-to-left" ); + + header = dp.children( ":first" ); + ok( header.is( "div.ui-datepicker-header" ), "Structure RTL - header division" ); + equal( header.children().length, 3, "Structure RTL - header child count" ); + ok( header.children( ":first" ).is( "a.ui-datepicker-next" ), "Structure RTL - prev link" ); + ok( header.children( ":eq(1)" ).is( "a.ui-datepicker-prev" ), "Structure RTL - next link" ); + + panel = dp.children( ":last" ); + ok( panel.is( "div.ui-datepicker-buttonpane" ), "Structure RTL - button division" ); + equal( panel.children().length, 2, "Structure RTL - button panel child count" ); + ok( panel.children( ":first" ).is( "button.ui-datepicker-close" ), "Structure RTL - close button" ); + ok( panel.children( ":last" ).is( "button.ui-datepicker-current" ), "Structure RTL - today button" ); + + inp.datepicker( "hide" ).datepicker( "destroy" ); + step2(); + }); + } + + // Hide prev/next + function step2() { + inp = testHelper.initNewInput({ + hideIfNoPrevNext: true, + minDate: new Date( 2008, 2 - 1, 4 ), + maxDate: new Date( 2008, 2 - 1, 14 ) + }); + inp.val( "02/10/2008" ); + + testHelper.onFocus( inp, function() { + header = dp.children( ":first" ); + ok( header.is( "div.ui-datepicker-header" ), "Structure hide prev/next - header division" ); + equal( header.children().length, 1, "Structure hide prev/next - links child count" ); + ok( header.children( ":first" ).is( "div.ui-datepicker-title" ), "Structure hide prev/next - title division" ); + + inp.datepicker( "hide" ).datepicker( "destroy" ); + step3(); + }); + } + + // Changeable Month with read-only year + function step3() { + inp = testHelper.initNewInput({ changeMonth: true }); + + testHelper.onFocus( inp, function() { + title = dp.children( ":first" ).children( ":last" ); + equal( title.children().length, 2, "Structure changeable month - title child count" ); + ok( title.children( ":first" ).is( "select.ui-datepicker-month" ), "Structure changeable month - month selector" ); + ok( title.children( ":last" ).is( "span.ui-datepicker-year" ), "Structure changeable month - read-only year" ); + + inp.datepicker( "hide" ).datepicker( "destroy" ); + step4(); + }); + } + + // Changeable year with read-only month + function step4() { + inp = testHelper.initNewInput({ changeYear: true }); + + testHelper.onFocus( inp, function() { + title = dp.children( ":first" ).children( ":last" ); + equal( title.children().length, 2, "Structure changeable year - title child count" ); + ok( title.children( ":first" ).is( "span.ui-datepicker-month" ), "Structure changeable year - read-only month" ); + ok( title.children( ":last" ).is( "select.ui-datepicker-year" ), "Structure changeable year - year selector" ); + + inp.datepicker( "hide" ).datepicker( "destroy" ); + step5(); + }); + } + + // Read-only first day of week + function step5() { + inp = testHelper.initNewInput({ changeFirstDay: false }); + + testHelper.onFocus( inp, function() { + thead = dp.find( ".ui-datepicker-calendar thead tr" ); + equal( thead.children().length, 7, "Structure read-only first day - thead child count" ); + equal( thead.find( "a" ).length, 0, "Structure read-only first day - thead links count" ); + + inp.datepicker( "hide" ).datepicker( "destroy" ); + start(); + }); + } + + // TODO: figure out why this setTimeout is needed in IE, + // it only is necessary when the previous baseStructure tests runs first + // Support: IE + setTimeout( step1 ); +}); + +test("keystrokes", function() { + expect( 26 ); + var inp = testHelper.init("#inp"), + date = new Date(); + inp.val("").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + testHelper.equalsDate(inp.datepicker("getDate"), date, "Keystroke enter"); + inp.val("02/04/2008").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 4), + "Keystroke enter - preset"); + inp.val("02/04/2008").datepicker("show"). + simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.HOME}). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + testHelper.equalsDate(inp.datepicker("getDate"), date, "Keystroke ctrl+home"); + inp.val("02/04/2008").datepicker("show"). + simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.END}); + ok(inp.datepicker("getDate") == null, "Keystroke ctrl+end"); + inp.val("").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.ESCAPE}); + ok(inp.datepicker("getDate") == null, "Keystroke esc"); + inp.val("02/04/2008").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.ESCAPE}); + testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 4), + "Keystroke esc - preset"); + inp.val("02/04/2008").datepicker("show"). + simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). + simulate("keydown", {keyCode: $.ui.keyCode.ESCAPE}); + testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 4), + "Keystroke esc - abandoned"); + // Moving by day or week + inp.val("").datepicker("show"). + simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.LEFT}). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + date.setDate(date.getDate() - 1); + testHelper.equalsDate(inp.datepicker("getDate"), date, "Keystroke ctrl+left"); + inp.val("").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.LEFT}). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + date.setDate(date.getDate() + 1); + testHelper.equalsDate(inp.datepicker("getDate"), date, "Keystroke left"); + inp.val("").datepicker("show"). + simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.RIGHT}). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + date.setDate(date.getDate() + 1); + testHelper.equalsDate(inp.datepicker("getDate"), date, "Keystroke ctrl+right"); + inp.val("").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.RIGHT}). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + date.setDate(date.getDate() - 1); + testHelper.equalsDate(inp.datepicker("getDate"), date, "Keystroke right"); + inp.val("").datepicker("show"). + simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.UP}). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + date.setDate(date.getDate() - 7); + testHelper.equalsDate(inp.datepicker("getDate"), date, "Keystroke ctrl+up"); + inp.val("").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.UP}). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + date.setDate(date.getDate() + 7); + testHelper.equalsDate(inp.datepicker("getDate"), date, "Keystroke up"); + inp.val("").datepicker("show"). + simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.DOWN}). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + date.setDate(date.getDate() + 7); + testHelper.equalsDate(inp.datepicker("getDate"), date, "Keystroke ctrl+down"); + inp.val("").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.DOWN}). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + date.setDate(date.getDate() - 7); + testHelper.equalsDate(inp.datepicker("getDate"), date, "Keystroke down"); + // Moving by month or year + inp.val("02/04/2008").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.PAGE_UP}). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 1 - 1, 4), + "Keystroke pgup"); + inp.val("02/04/2008").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 3 - 1, 4), + "Keystroke pgdn"); + inp.val("02/04/2008").datepicker("show"). + simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + testHelper.equalsDate(inp.datepicker("getDate"), new Date(2007, 2 - 1, 4), + "Keystroke ctrl+pgup"); + inp.val("02/04/2008").datepicker("show"). + simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + testHelper.equalsDate(inp.datepicker("getDate"), new Date(2009, 2 - 1, 4), + "Keystroke ctrl+pgdn"); + // Check for moving to short months + inp.val("03/31/2008").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.PAGE_UP}). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 29), + "Keystroke pgup - Feb"); + inp.val("01/30/2008").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 29), + "Keystroke pgdn - Feb"); + inp.val("02/29/2008").datepicker("show"). + simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + testHelper.equalsDate(inp.datepicker("getDate"), new Date(2007, 2 - 1, 28), + "Keystroke ctrl+pgup - Feb"); + inp.val("02/29/2008").datepicker("show"). + simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + testHelper.equalsDate(inp.datepicker("getDate"), new Date(2009, 2 - 1, 28), + "Keystroke ctrl+pgdn - Feb"); + // Goto current + inp.datepicker("option", {gotoCurrent: true}). + datepicker("hide").val("02/04/2008").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}). + simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.HOME}). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 4), + "Keystroke ctrl+home"); + // Change steps + inp.datepicker("option", {stepMonths: 2, gotoCurrent: false}). + datepicker("hide").val("02/04/2008").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.PAGE_UP}). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + testHelper.equalsDate(inp.datepicker("getDate"), new Date(2007, 12 - 1, 4), + "Keystroke pgup step 2"); + inp.val("02/04/2008").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 4 - 1, 4), + "Keystroke pgdn step 2"); +}); + +test("mouse", function() { + expect( 15 ); + var inl, + inp = testHelper.init("#inp"), + dp = $("#ui-datepicker-div"), + date = new Date(); + inp.val("").datepicker("show"); + $(".ui-datepicker-calendar tbody a:contains(10)", dp).simulate("click", {}); + date.setDate(10); + testHelper.equalsDate(inp.datepicker("getDate"), date, "Mouse click"); + inp.val("02/04/2008").datepicker("show"); + $(".ui-datepicker-calendar tbody a:contains(12)", dp).simulate("click", {}); + testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 12), + "Mouse click - preset"); + inp.val("02/04/2008").datepicker("show"); + inp.val("").datepicker("show"); + $("button.ui-datepicker-close", dp).simulate("click", {}); + ok(inp.datepicker("getDate") == null, "Mouse click - close"); + inp.val("02/04/2008").datepicker("show"); + $("button.ui-datepicker-close", dp).simulate("click", {}); + testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 4), + "Mouse click - close + preset"); + inp.val("02/04/2008").datepicker("show"); + $("a.ui-datepicker-prev", dp).simulate("click", {}); + $("button.ui-datepicker-close", dp).simulate("click", {}); + testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 4), + "Mouse click - abandoned"); + // Current/previous/next + inp.val("02/04/2008").datepicker("option", {showButtonPanel: true}).datepicker("show"); + $(".ui-datepicker-current", dp).simulate("click", {}); + $(".ui-datepicker-calendar tbody a:contains(14)", dp).simulate("click", {}); + date.setDate(14); + testHelper.equalsDate(inp.datepicker("getDate"), date, "Mouse click - current"); + inp.val("02/04/2008").datepicker("show"); + $(".ui-datepicker-prev", dp).simulate("click"); + $(".ui-datepicker-calendar tbody a:contains(16)", dp).simulate("click"); + testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 1 - 1, 16), + "Mouse click - previous"); + inp.val("02/04/2008").datepicker("show"); + $(".ui-datepicker-next", dp).simulate("click"); + $(".ui-datepicker-calendar tbody a:contains(18)", dp).simulate("click"); + testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 3 - 1, 18), + "Mouse click - next"); + // Previous/next with minimum/maximum + inp.datepicker("option", {minDate: new Date(2008, 2 - 1, 2), + maxDate: new Date(2008, 2 - 1, 26)}).val("02/04/2008").datepicker("show"); + $(".ui-datepicker-prev", dp).simulate("click"); + $(".ui-datepicker-calendar tbody a:contains(16)", dp).simulate("click"); + testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 16), + "Mouse click - previous + min/max"); + inp.val("02/04/2008").datepicker("show"); + $(".ui-datepicker-next", dp).simulate("click"); + $(".ui-datepicker-calendar tbody a:contains(18)", dp).simulate("click"); + testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 18), + "Mouse click - next + min/max"); + // Inline + inl = testHelper.init("#inl"); + dp = $(".ui-datepicker-inline", inl); + date = new Date(); + inl.datepicker("setDate", date); + $(".ui-datepicker-calendar tbody a:contains(10)", dp).simulate("click", {}); + date.setDate(10); + testHelper.equalsDate(inl.datepicker("getDate"), date, "Mouse click inline"); + inl.datepicker("option", {showButtonPanel: true}).datepicker("setDate", new Date(2008, 2 - 1, 4)); + $(".ui-datepicker-calendar tbody a:contains(12)", dp).simulate("click", {}); + testHelper.equalsDate(inl.datepicker("getDate"), new Date(2008, 2 - 1, 12), "Mouse click inline - preset"); + inl.datepicker("option", {showButtonPanel: true}); + $(".ui-datepicker-current", dp).simulate("click", {}); + $(".ui-datepicker-calendar tbody a:contains(14)", dp).simulate("click", {}); + date.setDate(14); + testHelper.equalsDate(inl.datepicker("getDate"), date, "Mouse click inline - current"); + inl.datepicker("setDate", new Date(2008, 2 - 1, 4)); + $(".ui-datepicker-prev", dp).simulate("click"); + $(".ui-datepicker-calendar tbody a:contains(16)", dp).simulate("click"); + testHelper.equalsDate(inl.datepicker("getDate"), new Date(2008, 1 - 1, 16), + "Mouse click inline - previous"); + inl.datepicker("setDate", new Date(2008, 2 - 1, 4)); + $(".ui-datepicker-next", dp).simulate("click"); + $(".ui-datepicker-calendar tbody a:contains(18)", dp).simulate("click"); + testHelper.equalsDate(inl.datepicker("getDate"), new Date(2008, 3 - 1, 18), + "Mouse click inline - next"); +}); + +} ); diff --git a/tests/unit/datepicker/datepicker_common.js b/tests/unit/datepicker/datepicker_common.js deleted file mode 100644 index 1eecc85cb..000000000 --- a/tests/unit/datepicker/datepicker_common.js +++ /dev/null @@ -1,7 +0,0 @@ -/* -TestHelpers.commonWidgetTests( "datepicker", { - defaults: { - disabled: false - } -}); -*/ diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js deleted file mode 100644 index a1e75848a..000000000 --- a/tests/unit/datepicker/datepicker_core.js +++ /dev/null @@ -1,530 +0,0 @@ -define( [ - "jquery", - "lib/common", - "./datepicker_test_helpers", - "ui/datepicker", - "ui/i18n/datepicker-he" -], function( $, common, testHelper ) { - -module( "datepicker: core", { - setup: function() { - $( "body" ).focus(); - } -}); - -common.testJshint( "datepicker" ); - -test("initialization - Reinitialization after body had been emptied.", function() { - expect( 1 ); - var bodyContent = $("body").children(), inp = $("#inp"); - $("#inp").datepicker(); - $("body").empty().append(inp); - $("#inp").datepicker(); - ok( $("#"+$.datepicker._mainDivId).length===1, "Datepicker container added" ); - $("body").empty().append(bodyContent); // Returning to initial state for later tests -}); - -test( "widget method - empty collection", function() { - expect( 1 ); - $( "#nonExist" ).datepicker(); // should create nothing - ok( !$( "#ui-datepicker-div" ).length, "Non init on empty collection" ); -}); - -test("widget method", function() { - expect( 1 ); - var actual = $("#inp").datepicker().datepicker("widget")[0]; - deepEqual($("body > #ui-datepicker-div:last-child")[0], actual); -}); - -asyncTest( "baseStructure", function() { - expect( 58 ); - var header, title, table, thead, week, panel, inl, child, - inp = testHelper.initNewInput(), - dp = $( "#ui-datepicker-div" ); - - function step1() { - testHelper.onFocus( inp, function() { - ok( dp.is( ":visible" ), "Structure - datepicker visible" ); - ok( !dp.is( ".ui-datepicker-rtl" ), "Structure - not right-to-left" ); - ok( !dp.is( ".ui-datepicker-multi" ), "Structure - not multi-month" ); - equal( dp.children().length, 2, "Structure - child count" ); - - header = dp.children( ":first" ); - ok( header.is( "div.ui-datepicker-header" ), "Structure - header division" ); - equal( header.children().length, 3, "Structure - header child count" ); - ok( header.children( ":first" ).is( "a.ui-datepicker-prev" ) && header.children( ":first" ).html() !== "", "Structure - prev link" ); - ok( header.children( ":eq(1)" ).is( "a.ui-datepicker-next" ) && header.children( ":eq(1)" ).html() !== "", "Structure - next link" ); - - title = header.children( ":last" ); - ok( title.is( "div.ui-datepicker-title" ) && title.html() !== "","Structure - title division" ); - equal( title.children().length, 2, "Structure - title child count" ); - ok( title.children( ":first" ).is( "span.ui-datepicker-month" ) && title.children( ":first" ).text() !== "", "Structure - month text" ); - ok( title.children( ":last" ).is( "span.ui-datepicker-year" ) && title.children( ":last" ).text() !== "", "Structure - year text" ); - - table = dp.children( ":eq(1)" ); - ok( table.is( "table.ui-datepicker-calendar" ), "Structure - month table" ); - ok( table.children( ":first" ).is( "thead" ), "Structure - month table thead" ); - - thead = table.children( ":first" ).children( ":first" ); - ok( thead.is( "tr" ), "Structure - month table title row" ); - equal( thead.find( "th" ).length, 7, "Structure - month table title cells" ); - ok( table.children( ":eq(1)" ).is( "tbody" ), "Structure - month table body" ); - ok( table.children( ":eq(1)" ).children( "tr" ).length >= 4, "Structure - month table week count" ); - - week = table.children( ":eq(1)" ).children( ":first" ); - ok( week.is( "tr" ), "Structure - month table week row" ); - equal( week.children().length, 7, "Structure - week child count" ); - ok( week.children( ":first" ).is( "td.ui-datepicker-week-end" ), "Structure - month table first day cell" ); - ok( week.children( ":last" ).is( "td.ui-datepicker-week-end" ), "Structure - month table second day cell" ); - - inp.datepicker( "hide" ).datepicker( "destroy" ); - step2(); - }); - } - - function step2() { - // Editable month/year and button panel - inp = testHelper.initNewInput({ - changeMonth: true, - changeYear: true, - showButtonPanel: true - }); - testHelper.onFocus( inp, function() { - title = dp.find( "div.ui-datepicker-title" ); - ok( title.children( ":first" ).is( "select.ui-datepicker-month" ), "Structure - month selector" ); - ok( title.children( ":last" ).is( "select.ui-datepicker-year" ), "Structure - year selector" ); - - panel = dp.children( ":last" ); - ok( panel.is( "div.ui-datepicker-buttonpane" ), "Structure - button panel division" ); - equal( panel.children().length, 2, "Structure - button panel child count" ); - ok( panel.children( ":first" ).is( "button.ui-datepicker-current" ), "Structure - today button" ); - ok( panel.children( ":last" ).is( "button.ui-datepicker-close" ), "Structure - close button" ); - - inp.datepicker( "hide" ).datepicker( "destroy" ); - step3(); - }); - } - - function step3() { - // Multi-month 2 - inp = testHelper.initNewInput({ numberOfMonths: 2 }); - testHelper.onFocus( inp, function() { - ok( dp.is( ".ui-datepicker-multi" ), "Structure multi [2] - multi-month" ); - equal( dp.children().length, 3, "Structure multi [2] - child count" ); - - child = dp.children( ":first" ); - ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure multi [2] - first month division" ); - - child = dp.children( ":eq(1)" ); - ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-last" ), "Structure multi [2] - second month division" ); - - child = dp.children( ":eq(2)" ); - ok( child.is( "div.ui-datepicker-row-break" ), "Structure multi [2] - row break" ); - ok( dp.is( ".ui-datepicker-multi-2" ), "Structure multi [2] - multi-2" ); - - inp.datepicker( "hide" ).datepicker( "destroy" ); - step4(); - }); - } - - function step4() { - // Multi-month 3 - inp = testHelper.initNewInput({ numberOfMonths: 3 }); - testHelper.onFocus( inp, function() { - ok( dp.is( ".ui-datepicker-multi-3" ), "Structure multi [3] - multi-3" ); - ok( !dp.is( ".ui-datepicker-multi-2" ), "Structure multi [3] - Trac #6704" ); - - inp.datepicker( "hide" ).datepicker( "destroy" ); - step5(); - }); - } - - function step5() { - // Multi-month [2, 2] - inp = testHelper.initNewInput({ numberOfMonths: [ 2, 2 ] }); - testHelper.onFocus( inp, function() { - ok( dp.is( ".ui-datepicker-multi" ), "Structure multi - multi-month" ); - equal( dp.children().length, 6, "Structure multi [2,2] - child count" ); - - child = dp.children( ":first" ); - ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure multi [2,2] - first month division" ); - - child = dp.children( ":eq(1)" ); - ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-last" ), "Structure multi [2,2] - second month division" ); - - child = dp.children( ":eq(2)" ); - ok( child.is( "div.ui-datepicker-row-break" ), "Structure multi [2,2] - row break" ); - - child = dp.children( ":eq(3)" ); - ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure multi [2,2] - third month division" ); - - child = dp.children( ":eq(4)" ); - ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-last" ), "Structure multi [2,2] - fourth month division" ); - - child = dp.children( ":eq(5)" ); - ok( child.is( "div.ui-datepicker-row-break" ), "Structure multi [2,2] - row break" ); - - inp.datepicker( "hide" ).datepicker( "destroy" ); - - // Inline - inl = testHelper.init( "#inl" ); - dp = inl.children(); - - ok( dp.is( ".ui-datepicker-inline" ), "Structure inline - main div" ); - ok( !dp.is( ".ui-datepicker-rtl" ), "Structure inline - not right-to-left" ); - ok( !dp.is( ".ui-datepicker-multi" ), "Structure inline - not multi-month" ); - equal( dp.children().length, 2, "Structure inline - child count" ); - - header = dp.children( ":first" ); - ok( header.is( "div.ui-datepicker-header" ), "Structure inline - header division" ); - equal( header.children().length, 3, "Structure inline - header child count" ); - - table = dp.children( ":eq(1)" ); - ok( table.is( "table.ui-datepicker-calendar" ), "Structure inline - month table" ); - ok( table.children( ":first" ).is( "thead" ), "Structure inline - month table thead" ); - ok( table.children( ":eq(1)" ).is( "tbody" ), "Structure inline - month table body" ); - - inl.datepicker( "destroy" ); - - // Inline multi-month - inl = testHelper.init( "#inl", { numberOfMonths: 2 } ); - dp = inl.children(); - - ok( dp.is( ".ui-datepicker-inline" ) && dp.is( ".ui-datepicker-multi" ), "Structure inline multi - main div" ); - equal( dp.children().length, 3, "Structure inline multi - child count" ); - - child = dp.children( ":first" ); - ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure inline multi - first month division" ); - - child = dp.children( ":eq(1)" ); - ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-last" ), "Structure inline multi - second month division" ); - - child = dp.children( ":eq(2)" ); - ok( child.is( "div.ui-datepicker-row-break" ), "Structure inline multi - row break" ); - - inl.datepicker( "destroy" ); - start(); - }); - } - - step1(); -}); - -asyncTest( "customStructure", function() { - expect( 20 ); - var header, panel, title, thead, - inp = testHelper.initNewInput( $.datepicker.regional.he ), - dp = $( "#ui-datepicker-div" ); - - function step1() { - inp.datepicker( "option", "showButtonPanel", true ); - - testHelper.onFocus( inp, function() { - ok( dp.is( ".ui-datepicker-rtl" ), "Structure RTL - right-to-left" ); - - header = dp.children( ":first" ); - ok( header.is( "div.ui-datepicker-header" ), "Structure RTL - header division" ); - equal( header.children().length, 3, "Structure RTL - header child count" ); - ok( header.children( ":first" ).is( "a.ui-datepicker-next" ), "Structure RTL - prev link" ); - ok( header.children( ":eq(1)" ).is( "a.ui-datepicker-prev" ), "Structure RTL - next link" ); - - panel = dp.children( ":last" ); - ok( panel.is( "div.ui-datepicker-buttonpane" ), "Structure RTL - button division" ); - equal( panel.children().length, 2, "Structure RTL - button panel child count" ); - ok( panel.children( ":first" ).is( "button.ui-datepicker-close" ), "Structure RTL - close button" ); - ok( panel.children( ":last" ).is( "button.ui-datepicker-current" ), "Structure RTL - today button" ); - - inp.datepicker( "hide" ).datepicker( "destroy" ); - step2(); - }); - } - - // Hide prev/next - function step2() { - inp = testHelper.initNewInput({ - hideIfNoPrevNext: true, - minDate: new Date( 2008, 2 - 1, 4 ), - maxDate: new Date( 2008, 2 - 1, 14 ) - }); - inp.val( "02/10/2008" ); - - testHelper.onFocus( inp, function() { - header = dp.children( ":first" ); - ok( header.is( "div.ui-datepicker-header" ), "Structure hide prev/next - header division" ); - equal( header.children().length, 1, "Structure hide prev/next - links child count" ); - ok( header.children( ":first" ).is( "div.ui-datepicker-title" ), "Structure hide prev/next - title division" ); - - inp.datepicker( "hide" ).datepicker( "destroy" ); - step3(); - }); - } - - // Changeable Month with read-only year - function step3() { - inp = testHelper.initNewInput({ changeMonth: true }); - - testHelper.onFocus( inp, function() { - title = dp.children( ":first" ).children( ":last" ); - equal( title.children().length, 2, "Structure changeable month - title child count" ); - ok( title.children( ":first" ).is( "select.ui-datepicker-month" ), "Structure changeable month - month selector" ); - ok( title.children( ":last" ).is( "span.ui-datepicker-year" ), "Structure changeable month - read-only year" ); - - inp.datepicker( "hide" ).datepicker( "destroy" ); - step4(); - }); - } - - // Changeable year with read-only month - function step4() { - inp = testHelper.initNewInput({ changeYear: true }); - - testHelper.onFocus( inp, function() { - title = dp.children( ":first" ).children( ":last" ); - equal( title.children().length, 2, "Structure changeable year - title child count" ); - ok( title.children( ":first" ).is( "span.ui-datepicker-month" ), "Structure changeable year - read-only month" ); - ok( title.children( ":last" ).is( "select.ui-datepicker-year" ), "Structure changeable year - year selector" ); - - inp.datepicker( "hide" ).datepicker( "destroy" ); - step5(); - }); - } - - // Read-only first day of week - function step5() { - inp = testHelper.initNewInput({ changeFirstDay: false }); - - testHelper.onFocus( inp, function() { - thead = dp.find( ".ui-datepicker-calendar thead tr" ); - equal( thead.children().length, 7, "Structure read-only first day - thead child count" ); - equal( thead.find( "a" ).length, 0, "Structure read-only first day - thead links count" ); - - inp.datepicker( "hide" ).datepicker( "destroy" ); - start(); - }); - } - - // TODO: figure out why this setTimeout is needed in IE, - // it only is necessary when the previous baseStructure tests runs first - // Support: IE - setTimeout( step1 ); -}); - -test("keystrokes", function() { - expect( 26 ); - var inp = testHelper.init("#inp"), - date = new Date(); - inp.val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - testHelper.equalsDate(inp.datepicker("getDate"), date, "Keystroke enter"); - inp.val("02/04/2008").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 4), - "Keystroke enter - preset"); - inp.val("02/04/2008").datepicker("show"). - simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.HOME}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - testHelper.equalsDate(inp.datepicker("getDate"), date, "Keystroke ctrl+home"); - inp.val("02/04/2008").datepicker("show"). - simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.END}); - ok(inp.datepicker("getDate") == null, "Keystroke ctrl+end"); - inp.val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ESCAPE}); - ok(inp.datepicker("getDate") == null, "Keystroke esc"); - inp.val("02/04/2008").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ESCAPE}); - testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 4), - "Keystroke esc - preset"); - inp.val("02/04/2008").datepicker("show"). - simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). - simulate("keydown", {keyCode: $.ui.keyCode.ESCAPE}); - testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 4), - "Keystroke esc - abandoned"); - // Moving by day or week - inp.val("").datepicker("show"). - simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.LEFT}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - date.setDate(date.getDate() - 1); - testHelper.equalsDate(inp.datepicker("getDate"), date, "Keystroke ctrl+left"); - inp.val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.LEFT}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - date.setDate(date.getDate() + 1); - testHelper.equalsDate(inp.datepicker("getDate"), date, "Keystroke left"); - inp.val("").datepicker("show"). - simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.RIGHT}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - date.setDate(date.getDate() + 1); - testHelper.equalsDate(inp.datepicker("getDate"), date, "Keystroke ctrl+right"); - inp.val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.RIGHT}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - date.setDate(date.getDate() - 1); - testHelper.equalsDate(inp.datepicker("getDate"), date, "Keystroke right"); - inp.val("").datepicker("show"). - simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.UP}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - date.setDate(date.getDate() - 7); - testHelper.equalsDate(inp.datepicker("getDate"), date, "Keystroke ctrl+up"); - inp.val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.UP}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - date.setDate(date.getDate() + 7); - testHelper.equalsDate(inp.datepicker("getDate"), date, "Keystroke up"); - inp.val("").datepicker("show"). - simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.DOWN}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - date.setDate(date.getDate() + 7); - testHelper.equalsDate(inp.datepicker("getDate"), date, "Keystroke ctrl+down"); - inp.val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.DOWN}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - date.setDate(date.getDate() - 7); - testHelper.equalsDate(inp.datepicker("getDate"), date, "Keystroke down"); - // Moving by month or year - inp.val("02/04/2008").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.PAGE_UP}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 1 - 1, 4), - "Keystroke pgup"); - inp.val("02/04/2008").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 3 - 1, 4), - "Keystroke pgdn"); - inp.val("02/04/2008").datepicker("show"). - simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - testHelper.equalsDate(inp.datepicker("getDate"), new Date(2007, 2 - 1, 4), - "Keystroke ctrl+pgup"); - inp.val("02/04/2008").datepicker("show"). - simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - testHelper.equalsDate(inp.datepicker("getDate"), new Date(2009, 2 - 1, 4), - "Keystroke ctrl+pgdn"); - // Check for moving to short months - inp.val("03/31/2008").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.PAGE_UP}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 29), - "Keystroke pgup - Feb"); - inp.val("01/30/2008").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 29), - "Keystroke pgdn - Feb"); - inp.val("02/29/2008").datepicker("show"). - simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - testHelper.equalsDate(inp.datepicker("getDate"), new Date(2007, 2 - 1, 28), - "Keystroke ctrl+pgup - Feb"); - inp.val("02/29/2008").datepicker("show"). - simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - testHelper.equalsDate(inp.datepicker("getDate"), new Date(2009, 2 - 1, 28), - "Keystroke ctrl+pgdn - Feb"); - // Goto current - inp.datepicker("option", {gotoCurrent: true}). - datepicker("hide").val("02/04/2008").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}). - simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.HOME}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 4), - "Keystroke ctrl+home"); - // Change steps - inp.datepicker("option", {stepMonths: 2, gotoCurrent: false}). - datepicker("hide").val("02/04/2008").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.PAGE_UP}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - testHelper.equalsDate(inp.datepicker("getDate"), new Date(2007, 12 - 1, 4), - "Keystroke pgup step 2"); - inp.val("02/04/2008").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 4 - 1, 4), - "Keystroke pgdn step 2"); -}); - -test("mouse", function() { - expect( 15 ); - var inl, - inp = testHelper.init("#inp"), - dp = $("#ui-datepicker-div"), - date = new Date(); - inp.val("").datepicker("show"); - $(".ui-datepicker-calendar tbody a:contains(10)", dp).simulate("click", {}); - date.setDate(10); - testHelper.equalsDate(inp.datepicker("getDate"), date, "Mouse click"); - inp.val("02/04/2008").datepicker("show"); - $(".ui-datepicker-calendar tbody a:contains(12)", dp).simulate("click", {}); - testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 12), - "Mouse click - preset"); - inp.val("02/04/2008").datepicker("show"); - inp.val("").datepicker("show"); - $("button.ui-datepicker-close", dp).simulate("click", {}); - ok(inp.datepicker("getDate") == null, "Mouse click - close"); - inp.val("02/04/2008").datepicker("show"); - $("button.ui-datepicker-close", dp).simulate("click", {}); - testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 4), - "Mouse click - close + preset"); - inp.val("02/04/2008").datepicker("show"); - $("a.ui-datepicker-prev", dp).simulate("click", {}); - $("button.ui-datepicker-close", dp).simulate("click", {}); - testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 4), - "Mouse click - abandoned"); - // Current/previous/next - inp.val("02/04/2008").datepicker("option", {showButtonPanel: true}).datepicker("show"); - $(".ui-datepicker-current", dp).simulate("click", {}); - $(".ui-datepicker-calendar tbody a:contains(14)", dp).simulate("click", {}); - date.setDate(14); - testHelper.equalsDate(inp.datepicker("getDate"), date, "Mouse click - current"); - inp.val("02/04/2008").datepicker("show"); - $(".ui-datepicker-prev", dp).simulate("click"); - $(".ui-datepicker-calendar tbody a:contains(16)", dp).simulate("click"); - testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 1 - 1, 16), - "Mouse click - previous"); - inp.val("02/04/2008").datepicker("show"); - $(".ui-datepicker-next", dp).simulate("click"); - $(".ui-datepicker-calendar tbody a:contains(18)", dp).simulate("click"); - testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 3 - 1, 18), - "Mouse click - next"); - // Previous/next with minimum/maximum - inp.datepicker("option", {minDate: new Date(2008, 2 - 1, 2), - maxDate: new Date(2008, 2 - 1, 26)}).val("02/04/2008").datepicker("show"); - $(".ui-datepicker-prev", dp).simulate("click"); - $(".ui-datepicker-calendar tbody a:contains(16)", dp).simulate("click"); - testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 16), - "Mouse click - previous + min/max"); - inp.val("02/04/2008").datepicker("show"); - $(".ui-datepicker-next", dp).simulate("click"); - $(".ui-datepicker-calendar tbody a:contains(18)", dp).simulate("click"); - testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 2 - 1, 18), - "Mouse click - next + min/max"); - // Inline - inl = testHelper.init("#inl"); - dp = $(".ui-datepicker-inline", inl); - date = new Date(); - inl.datepicker("setDate", date); - $(".ui-datepicker-calendar tbody a:contains(10)", dp).simulate("click", {}); - date.setDate(10); - testHelper.equalsDate(inl.datepicker("getDate"), date, "Mouse click inline"); - inl.datepicker("option", {showButtonPanel: true}).datepicker("setDate", new Date(2008, 2 - 1, 4)); - $(".ui-datepicker-calendar tbody a:contains(12)", dp).simulate("click", {}); - testHelper.equalsDate(inl.datepicker("getDate"), new Date(2008, 2 - 1, 12), "Mouse click inline - preset"); - inl.datepicker("option", {showButtonPanel: true}); - $(".ui-datepicker-current", dp).simulate("click", {}); - $(".ui-datepicker-calendar tbody a:contains(14)", dp).simulate("click", {}); - date.setDate(14); - testHelper.equalsDate(inl.datepicker("getDate"), date, "Mouse click inline - current"); - inl.datepicker("setDate", new Date(2008, 2 - 1, 4)); - $(".ui-datepicker-prev", dp).simulate("click"); - $(".ui-datepicker-calendar tbody a:contains(16)", dp).simulate("click"); - testHelper.equalsDate(inl.datepicker("getDate"), new Date(2008, 1 - 1, 16), - "Mouse click inline - previous"); - inl.datepicker("setDate", new Date(2008, 2 - 1, 4)); - $(".ui-datepicker-next", dp).simulate("click"); - $(".ui-datepicker-calendar tbody a:contains(18)", dp).simulate("click"); - testHelper.equalsDate(inl.datepicker("getDate"), new Date(2008, 3 - 1, 18), - "Mouse click inline - next"); -}); - -} ); diff --git a/tests/unit/datepicker/datepicker_events.js b/tests/unit/datepicker/datepicker_events.js deleted file mode 100644 index 04a4cbfe8..000000000 --- a/tests/unit/datepicker/datepicker_events.js +++ /dev/null @@ -1,154 +0,0 @@ -define( [ - "jquery", - "./datepicker_test_helpers", - "ui/datepicker" -], function( $, testHelper ) { - -module("datepicker: events"); - -var selectedThis = null, -selectedDate = null, -selectedInst = null; - -function callback(date, inst) { - selectedThis = this; - selectedDate = date; - selectedInst = inst; -} - -function callback2(year, month, inst) { - selectedThis = this; - selectedDate = year + "/" + month; - selectedInst = inst; -} - -test("events", function() { - expect( 26 ); - var dateStr, newMonthYear, inp2, - inp = testHelper.init("#inp", {onSelect: callback}), - date = new Date(); - // onSelect - inp.val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - equal(selectedThis, inp[0], "Callback selected this"); - equal(selectedInst, $.data(inp[0], testHelper.PROP_NAME), "Callback selected inst"); - equal(selectedDate, $.datepicker.formatDate("mm/dd/yy", date), - "Callback selected date"); - inp.val("").datepicker("show"). - simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.DOWN}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - date.setDate(date.getDate() + 7); - equal(selectedDate, $.datepicker.formatDate("mm/dd/yy", date), - "Callback selected date - ctrl+down"); - inp.val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ESCAPE}); - equal(selectedDate, $.datepicker.formatDate("mm/dd/yy", date), - "Callback selected date - esc"); - dateStr = "02/04/2008"; - inp.val(dateStr).datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - equal(dateStr, selectedDate, - "onSelect is called after enter keydown"); - // onChangeMonthYear - inp.datepicker("option", {onChangeMonthYear: callback2, onSelect: null}). - val("").datepicker("show"); - newMonthYear = function(date) { - return date.getFullYear() + "/" + (date.getMonth() + 1); - }; - date = new Date(); - date.setDate(1); - inp.simulate("keydown", {keyCode: $.ui.keyCode.PAGE_UP}); - date.setMonth(date.getMonth() - 1); - equal(selectedThis, inp[0], "Callback change month/year this"); - equal(selectedInst, $.data(inp[0], testHelper.PROP_NAME), "Callback change month/year inst"); - equal(selectedDate, newMonthYear(date), - "Callback change month/year date - pgup"); - inp.simulate("keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}); - date.setMonth(date.getMonth() + 1); - equal(selectedDate, newMonthYear(date), - "Callback change month/year date - pgdn"); - inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}); - date.setFullYear(date.getFullYear() - 1); - equal(selectedDate, newMonthYear(date), - "Callback change month/year date - ctrl+pgup"); - inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.HOME}); - date.setFullYear(date.getFullYear() + 1); - equal(selectedDate, newMonthYear(date), - "Callback change month/year date - ctrl+home"); - inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}); - date.setFullYear(date.getFullYear() + 1); - equal(selectedDate, newMonthYear(date), - "Callback change month/year date - ctrl+pgdn"); - inp.datepicker("setDate", new Date(2007, 1 - 1, 26)); - equal(selectedDate, "2007/1", "Callback change month/year date - setDate"); - selectedDate = null; - inp.datepicker("setDate", new Date(2007, 1 - 1, 12)); - ok(selectedDate == null, "Callback change month/year date - setDate no change"); - // onChangeMonthYear step by 2 - inp.datepicker("option", {stepMonths: 2}). - datepicker("hide").val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.PAGE_UP}); - date.setMonth(date.getMonth() - 14); - equal(selectedDate, newMonthYear(date), - "Callback change month/year by 2 date - pgup"); - inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}); - date.setMonth(date.getMonth() - 12); - equal(selectedDate, newMonthYear(date), - "Callback change month/year by 2 date - ctrl+pgup"); - inp.simulate("keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}); - date.setMonth(date.getMonth() + 2); - equal(selectedDate, newMonthYear(date), - "Callback change month/year by 2 date - pgdn"); - inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}); - date.setMonth(date.getMonth() + 12); - equal(selectedDate, newMonthYear(date), - "Callback change month/year by 2 date - ctrl+pgdn"); - // onClose - inp.datepicker("option", {onClose: callback, onChangeMonthYear: null, stepMonths: 1}). - val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ESCAPE}); - equal(selectedThis, inp[0], "Callback close this"); - equal(selectedInst, $.data(inp[0], testHelper.PROP_NAME), "Callback close inst"); - equal(selectedDate, "", "Callback close date - esc"); - inp.val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - equal(selectedDate, $.datepicker.formatDate("mm/dd/yy", new Date()), - "Callback close date - enter"); - inp.val("02/04/2008").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ESCAPE}); - equal(selectedDate, "02/04/2008", "Callback close date - preset"); - inp.val("02/04/2008").datepicker("show"). - simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.END}); - equal(selectedDate, "", "Callback close date - ctrl+end"); - - inp2 = testHelper.init("#inp2"); - inp2.datepicker().datepicker("option", {onClose: callback}).datepicker("show"); - inp.datepicker("show"); - equal(selectedThis, inp2[0], "Callback close this"); -}); - -test("beforeShowDay-getDate", function() { - expect( 3 ); - var inp = testHelper.init("#inp", {beforeShowDay: function() { inp.datepicker("getDate"); return [true, ""]; }}), - dp = $("#ui-datepicker-div"); - inp.val("01/01/2010").datepicker("show"); - // contains non-breaking space - equal($("div.ui-datepicker-title").text(), - // support: IE <9, jQuery <1.8 - // In IE7/8 with jQuery <1.8, encoded spaces behave in strange ways - $( "January 2010" ).text(), "Initial month"); - $("a.ui-datepicker-next", dp).click(); - $("a.ui-datepicker-next", dp).click(); - // contains non-breaking space - equal($("div.ui-datepicker-title").text(), - $( "March 2010" ).text(), "After next clicks"); - inp.datepicker("hide").datepicker("show"); - $("a.ui-datepicker-prev", dp).click(); - $("a.ui-datepicker-prev", dp).click(); - // contains non-breaking space - equal($("div.ui-datepicker-title").text(), - $( "November 2009" ).text(), "After prev clicks"); - inp.datepicker("hide"); -}); - -} ); diff --git a/tests/unit/datepicker/datepicker_methods.js b/tests/unit/datepicker/datepicker_methods.js deleted file mode 100644 index 3899779a9..000000000 --- a/tests/unit/datepicker/datepicker_methods.js +++ /dev/null @@ -1,126 +0,0 @@ -define( [ - "jquery", - "./datepicker_test_helpers", - "ui/datepicker" -], function( $, testHelper ) { - -module("datepicker: methods"); - -test("destroy", function() { - expect( 33 ); - var inl, - inp = testHelper.init("#inp"); - ok(inp.is(".hasDatepicker"), "Default - marker class set"); - ok($.data(inp[0], testHelper.PROP_NAME), "Default - instance present"); - ok(inp.next().is("#alt"), "Default - button absent"); - inp.datepicker("destroy"); - inp = $("#inp"); - ok(!inp.is(".hasDatepicker"), "Default - marker class cleared"); - ok(!$.data(inp[0], testHelper.PROP_NAME), "Default - instance absent"); - ok(inp.next().is("#alt"), "Default - button absent"); - // With button - inp= testHelper.init("#inp", {showOn: "both"}); - ok(inp.is(".hasDatepicker"), "Button - marker class set"); - ok($.data(inp[0], testHelper.PROP_NAME), "Button - instance present"); - ok(inp.next().text() === "...", "Button - button added"); - inp.datepicker("destroy"); - inp = $("#inp"); - ok(!inp.is(".hasDatepicker"), "Button - marker class cleared"); - ok(!$.data(inp[0], testHelper.PROP_NAME), "Button - instance absent"); - ok(inp.next().is("#alt"), "Button - button removed"); - // With append text - inp = testHelper.init("#inp", {appendText: "Testing"}); - ok(inp.is(".hasDatepicker"), "Append - marker class set"); - ok($.data(inp[0], testHelper.PROP_NAME), "Append - instance present"); - ok(inp.next().text() === "Testing", "Append - append text added"); - inp.datepicker("destroy"); - inp = $("#inp"); - ok(!inp.is(".hasDatepicker"), "Append - marker class cleared"); - ok(!$.data(inp[0], testHelper.PROP_NAME), "Append - instance absent"); - ok(inp.next().is("#alt"), "Append - append text removed"); - // With both - inp= testHelper.init("#inp", {showOn: "both", buttonImageOnly: true, - buttonImage: "images/calendar.gif", appendText: "Testing"}); - ok(inp.is(".hasDatepicker"), "Both - marker class set"); - ok($.data(inp[0], testHelper.PROP_NAME), "Both - instance present"); - ok(inp.next()[0].nodeName.toLowerCase() === "img", "Both - button added"); - ok(inp.next().next().text() === "Testing", "Both - append text added"); - inp.datepicker("destroy"); - inp = $("#inp"); - ok(!inp.is(".hasDatepicker"), "Both - marker class cleared"); - ok(!$.data(inp[0], testHelper.PROP_NAME), "Both - instance absent"); - ok(inp.next().is("#alt"), "Both - button and append text absent"); - // Inline - inl = testHelper.init("#inl"); - ok(inl.is(".hasDatepicker"), "Inline - marker class set"); - ok(inl.html() !== "", "Inline - datepicker present"); - ok($.data(inl[0], testHelper.PROP_NAME), "Inline - instance present"); - ok(inl.next().length === 0 || inl.next().is("p"), "Inline - button absent"); - inl.datepicker("destroy"); - inl = $("#inl"); - ok(!inl.is(".hasDatepicker"), "Inline - marker class cleared"); - ok(inl.html() === "", "Inline - datepicker absent"); - ok(!$.data(inl[0], testHelper.PROP_NAME), "Inline - instance absent"); - ok(inl.next().length === 0 || inl.next().is("p"), "Inline - button absent"); -}); - -test("enableDisable", function() { - expect( 33 ); - var inl, dp, - inp = testHelper.init("#inp"); - ok(!inp.datepicker("isDisabled"), "Enable/disable - initially marked as enabled"); - ok(!inp[0].disabled, "Enable/disable - field initially enabled"); - inp.datepicker("disable"); - ok(inp.datepicker("isDisabled"), "Enable/disable - now marked as disabled"); - ok(inp[0].disabled, "Enable/disable - field now disabled"); - inp.datepicker("enable"); - ok(!inp.datepicker("isDisabled"), "Enable/disable - now marked as enabled"); - ok(!inp[0].disabled, "Enable/disable - field now enabled"); - inp.datepicker("destroy"); - // With a button - inp = testHelper.init("#inp", {showOn: "button"}); - ok(!inp.datepicker("isDisabled"), "Enable/disable button - initially marked as enabled"); - ok(!inp[0].disabled, "Enable/disable button - field initially enabled"); - ok(!inp.next("button")[0].disabled, "Enable/disable button - button initially enabled"); - inp.datepicker("disable"); - ok(inp.datepicker("isDisabled"), "Enable/disable button - now marked as disabled"); - ok(inp[0].disabled, "Enable/disable button - field now disabled"); - ok(inp.next("button")[0].disabled, "Enable/disable button - button now disabled"); - inp.datepicker("enable"); - ok(!inp.datepicker("isDisabled"), "Enable/disable button - now marked as enabled"); - ok(!inp[0].disabled, "Enable/disable button - field now enabled"); - ok(!inp.next("button")[0].disabled, "Enable/disable button - button now enabled"); - inp.datepicker("destroy"); - // With an image button - inp = testHelper.init("#inp", {showOn: "button", buttonImageOnly: true, - buttonImage: "images/calendar.gif"}); - ok(!inp.datepicker("isDisabled"), "Enable/disable image - initially marked as enabled"); - ok(!inp[0].disabled, "Enable/disable image - field initially enabled"); - ok(parseFloat(inp.next("img").css("opacity")) === 1, "Enable/disable image - image initially enabled"); - inp.datepicker("disable"); - ok(inp.datepicker("isDisabled"), "Enable/disable image - now marked as disabled"); - ok(inp[0].disabled, "Enable/disable image - field now disabled"); - ok(parseFloat(inp.next("img").css("opacity")) !== 1, "Enable/disable image - image now disabled"); - inp.datepicker("enable"); - ok(!inp.datepicker("isDisabled"), "Enable/disable image - now marked as enabled"); - ok(!inp[0].disabled, "Enable/disable image - field now enabled"); - ok(parseFloat(inp.next("img").css("opacity")) === 1, "Enable/disable image - image now enabled"); - inp.datepicker("destroy"); - // Inline - inl = testHelper.init("#inl", {changeYear: true}); - dp = $(".ui-datepicker-inline", inl); - ok(!inl.datepicker("isDisabled"), "Enable/disable inline - initially marked as enabled"); - ok(!dp.children().is(".ui-state-disabled"), "Enable/disable inline - not visually disabled initially"); - ok(!dp.find("select").prop("disabled"), "Enable/disable inline - form element enabled initially"); - inl.datepicker("disable"); - ok(inl.datepicker("isDisabled"), "Enable/disable inline - now marked as disabled"); - ok(dp.children().is(".ui-state-disabled"), "Enable/disable inline - visually disabled"); - ok(dp.find("select").prop("disabled"), "Enable/disable inline - form element disabled"); - inl.datepicker("enable"); - ok(!inl.datepicker("isDisabled"), "Enable/disable inline - now marked as enabled"); - ok(!dp.children().is(".ui-state-disabled"), "Enable/disable inline - not visiually disabled"); - ok(!dp.find("select").prop("disabled"), "Enable/disable inline - form element enabled"); - inl.datepicker("destroy"); -}); - -} ); diff --git a/tests/unit/datepicker/datepicker_options.js b/tests/unit/datepicker/datepicker_options.js deleted file mode 100644 index ee4a3bae4..000000000 --- a/tests/unit/datepicker/datepicker_options.js +++ /dev/null @@ -1,1127 +0,0 @@ -define( [ - "jquery", - "./datepicker_test_helpers", - "ui/datepicker", - "ui/i18n/datepicker-fr", - "ui/i18n/datepicker-he", - "ui/i18n/datepicker-zh-CN" -], function( $, testHelper ) { - -module("datepicker: options"); - -test("setDefaults", function() { - expect( 3 ); - testHelper.init("#inp"); - equal($.datepicker._defaults.showOn, "focus", "Initial showOn"); - $.datepicker.setDefaults({showOn: "button"}); - equal($.datepicker._defaults.showOn, "button", "Change default showOn"); - $.datepicker.setDefaults({showOn: "focus"}); - equal($.datepicker._defaults.showOn, "focus", "Restore showOn"); -}); - -test("option", function() { - expect( 17 ); - var inp = testHelper.init("#inp"), - inst = $.data(inp[0], testHelper.PROP_NAME); - // Set option - equal(inst.settings.showOn, null, "Initial setting showOn"); - equal($.datepicker._get(inst, "showOn"), "focus", "Initial instance showOn"); - equal($.datepicker._defaults.showOn, "focus", "Initial default showOn"); - inp.datepicker("option", "showOn", "button"); - equal(inst.settings.showOn, "button", "Change setting showOn"); - equal($.datepicker._get(inst, "showOn"), "button", "Change instance showOn"); - equal($.datepicker._defaults.showOn, "focus", "Retain default showOn"); - inp.datepicker("option", {showOn: "both"}); - equal(inst.settings.showOn, "both", "Change setting showOn"); - equal($.datepicker._get(inst, "showOn"), "both", "Change instance showOn"); - equal($.datepicker._defaults.showOn, "focus", "Retain default showOn"); - inp.datepicker("option", "showOn", undefined); - equal(inst.settings.showOn, null, "Clear setting showOn"); - equal($.datepicker._get(inst, "showOn"), "focus", "Restore instance showOn"); - equal($.datepicker._defaults.showOn, "focus", "Retain default showOn"); - // Get option - inp = testHelper.init("#inp"); - equal(inp.datepicker("option", "showOn"), "focus", "Initial setting showOn"); - inp.datepicker("option", "showOn", "button"); - equal(inp.datepicker("option", "showOn"), "button", "Change instance showOn"); - inp.datepicker("option", "showOn", undefined); - equal(inp.datepicker("option", "showOn"), "focus", "Reset instance showOn"); - deepEqual(inp.datepicker("option", "all"), {showAnim: ""}, "Get instance settings"); - deepEqual(inp.datepicker("option", "defaults"), $.datepicker._defaults, - "Get default settings"); -}); - -test( "disabled", function() { - expect(8); - var inp = testHelper.init("#inp"); - ok(!inp.datepicker("isDisabled"), "Initially marked as enabled"); - ok(!inp[0].disabled, "Field initially enabled"); - inp.datepicker("option", "disabled", true); - ok(inp.datepicker("isDisabled"), "Marked as disabled"); - ok(inp[0].disabled, "Field now disabled"); - inp.datepicker("option", "disabled", false); - ok(!inp.datepicker("isDisabled"), "Marked as enabled"); - ok(!inp[0].disabled, "Field now enabled"); - inp.datepicker("destroy"); - - inp = testHelper.init("#inp", { disabled: true }); - ok(inp.datepicker("isDisabled"), "Initially marked as disabled"); - ok(inp[0].disabled, "Field initially disabled"); -}); - -test("change", function() { - expect( 12 ); - var inp = testHelper.init("#inp"), - inst = $.data(inp[0], testHelper.PROP_NAME); - equal(inst.settings.showOn, null, "Initial setting showOn"); - equal($.datepicker._get(inst, "showOn"), "focus", "Initial instance showOn"); - equal($.datepicker._defaults.showOn, "focus", "Initial default showOn"); - inp.datepicker("change", "showOn", "button"); - equal(inst.settings.showOn, "button", "Change setting showOn"); - equal($.datepicker._get(inst, "showOn"), "button", "Change instance showOn"); - equal($.datepicker._defaults.showOn, "focus", "Retain default showOn"); - inp.datepicker("change", {showOn: "both"}); - equal(inst.settings.showOn, "both", "Change setting showOn"); - equal($.datepicker._get(inst, "showOn"), "both", "Change instance showOn"); - equal($.datepicker._defaults.showOn, "focus", "Retain default showOn"); - inp.datepicker("change", "showOn", undefined); - equal(inst.settings.showOn, null, "Clear setting showOn"); - equal($.datepicker._get(inst, "showOn"), "focus", "Restore instance showOn"); - equal($.datepicker._defaults.showOn, "focus", "Retain default showOn"); -}); - -(function() { - var url = window.location.search; - url = decodeURIComponent( url.slice( url.indexOf( "swarmURL=" ) + 9 ) ); - - // TODO: This test occassionally fails in IE in TestSwarm - if ( $.ui.ie && url && url.indexOf( "http" ) === 0 ) { - return; - } - - asyncTest( "invocation", function() { - var button, image, - isOldIE = $.ui.ie && ( !document.documentMode || document.documentMode < 9 ), - body = $( "body" ); - - expect( isOldIE ? 25 : 29 ); - - function step0() { - var inp = testHelper.initNewInput(), - dp = $( "#ui-datepicker-div" ); - - button = inp.siblings( "button" ); - ok( button.length === 0, "Focus - button absent" ); - image = inp.siblings( "img" ); - ok( image.length === 0, "Focus - image absent" ); - - testHelper.onFocus( inp, function() { - ok( dp.is( ":visible" ), "Focus - rendered on focus" ); - inp.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); - ok( !dp.is( ":visible" ), "Focus - hidden on exit" ); - step1(); - }); - } - - function step1() { - - var inp = testHelper.initNewInput(), - dp = $( "#ui-datepicker-div" ); - - testHelper.onFocus( inp, function() { - ok( dp.is( ":visible" ), "Focus - rendered on focus" ); - body.simulate( "mousedown", {} ); - ok( !dp.is( ":visible" ), "Focus - hidden on external click" ); - inp.datepicker( "hide" ).datepicker( "destroy" ); - - step2(); - }); - } - - function step2() { - var inp = testHelper.initNewInput({ - showOn: "button", - buttonText: "Popup" - }), - dp = $( "#ui-datepicker-div" ); - - ok( !dp.is( ":visible" ), "Button - initially hidden" ); - button = inp.siblings( "button" ); - image = inp.siblings( "img" ); - ok( button.length === 1, "Button - button present" ); - ok( image.length === 0, "Button - image absent" ); - equal( button.text(), "Popup", "Button - button text" ); - - testHelper.onFocus( inp, function() { - ok( !dp.is( ":visible" ), "Button - not rendered on focus" ); - button.click(); - ok( dp.is( ":visible" ), "Button - rendered on button click" ); - button.click(); - ok( !dp.is( ":visible" ), "Button - hidden on second button click" ); - inp.datepicker( "hide" ).datepicker( "destroy" ); - - step3(); - }); - } - - function step3() { - var inp = testHelper.initNewInput({ - showOn: "button", - buttonImageOnly: true, - buttonImage: "images/calendar.gif", - buttonText: "Cal" - }), - dp = $( "#ui-datepicker-div" ); - - ok( !dp.is( ":visible" ), "Image button - initially hidden" ); - button = inp.siblings( "button" ); - ok( button.length === 0, "Image button - button absent" ); - image = inp.siblings( "img" ); - ok( image.length === 1, "Image button - image present" ); - ok( /images\/calendar\.gif$/.test( image.attr( "src" ) ), "Image button - image source" ); - equal( image.attr( "title" ), "Cal", "Image button - image text" ); - - testHelper.onFocus( inp, function() { - ok( !dp.is( ":visible" ), "Image button - not rendered on focus" ); - image.click(); - ok( dp.is( ":visible" ), "Image button - rendered on image click" ); - image.click(); - ok( !dp.is( ":visible" ), "Image button - hidden on second image click" ); - inp.datepicker( "hide" ).datepicker( "destroy" ); - - step4(); - }); - } - - function step4() { - var inp = testHelper.initNewInput({ - showOn: "both", - buttonImage: "images/calendar.gif" - }), - dp = $( "#ui-datepicker-div" ); - - ok( !dp.is( ":visible" ), "Both - initially hidden" ); - button = inp.siblings( "button" ); - ok( button.length === 1, "Both - button present" ); - image = inp.siblings( "img" ); - ok( image.length === 0, "Both - image absent" ); - image = button.children( "img" ); - ok( image.length === 1, "Both - button image present" ); - - // TODO: This test occasionally fails to focus in IE8 in BrowserStack - if ( !isOldIE ) { - testHelper.onFocus( inp, function() { - ok( dp.is( ":visible" ), "Both - rendered on focus" ); - body.simulate( "mousedown", {} ); - ok( !dp.is( ":visible" ), "Both - hidden on external click" ); - button.click(); - ok( dp.is( ":visible" ), "Both - rendered on button click" ); - button.click(); - ok( !dp.is( ":visible" ), "Both - hidden on second button click" ); - inp.datepicker( "hide" ).datepicker( "destroy" ); - - start(); - }); - } else { - start(); - } - } - - step0(); - }); -})(); - -test("otherMonths", function() { - expect( 8 ); - var inp = testHelper.init("#inp"), - pop = $("#ui-datepicker-div"); - inp.val("06/01/2009").datepicker("show"); - equal(pop.find("tbody").text(), - // support: IE <9, jQuery <1.8 - // In IE7/8 with jQuery <1.8, encoded spaces behave in strange ways - $( "\u00a0123456789101112131415161718192021222324252627282930\u00a0\u00a0\u00a0\u00a0" ).text(), - "Other months - none"); - ok(pop.find("td:last *").length === 0, "Other months - no content"); - inp.datepicker("hide").datepicker("option", "showOtherMonths", true).datepicker("show"); - equal(pop.find("tbody").text(), "311234567891011121314151617181920212223242526272829301234", - "Other months - show"); - ok(pop.find("td:last span").length === 1, "Other months - span content"); - inp.datepicker("hide").datepicker("option", "selectOtherMonths", true).datepicker("show"); - equal(pop.find("tbody").text(), "311234567891011121314151617181920212223242526272829301234", - "Other months - select"); - ok(pop.find("td:last a").length === 1, "Other months - link content"); - inp.datepicker("hide").datepicker("option", "showOtherMonths", false).datepicker("show"); - equal(pop.find("tbody").text(), - // support: IE <9, jQuery <1.8 - // In IE7/8 with jQuery <1.8, encoded spaces behave in strange ways - $( "\u00a0123456789101112131415161718192021222324252627282930\u00a0\u00a0\u00a0\u00a0" ).text(), - "Other months - none"); - ok(pop.find("td:last *").length === 0, "Other months - no content"); -}); - -test("defaultDate", function() { - expect( 16 ); - var inp = testHelper.init("#inp"), - date = new Date(); - inp.val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date null"); - - // Numeric values - inp.datepicker("option", {defaultDate: -2}). - datepicker("hide").val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - date.setDate(date.getDate() - 2); - testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date -2"); - - date = new Date(); - inp.datepicker("option", {defaultDate: 3}). - datepicker("hide").val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - date.setDate(date.getDate() + 3); - testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date 3"); - - date = new Date(); - inp.datepicker("option", {defaultDate: 1 / "a"}). - datepicker("hide").val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date NaN"); - - // String offset values - inp.datepicker("option", {defaultDate: "-1d"}). - datepicker("hide").val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - date.setDate(date.getDate() - 1); - testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date -1d"); - inp.datepicker("option", {defaultDate: "+3D"}). - datepicker("hide").val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - date.setDate(date.getDate() + 4); - testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date +3D"); - inp.datepicker("option", {defaultDate: " -2 w "}). - datepicker("hide").val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - date = new Date(); - date.setDate(date.getDate() - 14); - testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date -2 w"); - inp.datepicker("option", {defaultDate: "+1 W"}). - datepicker("hide").val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - date.setDate(date.getDate() + 21); - testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date +1 W"); - inp.datepicker("option", {defaultDate: " -1 m "}). - datepicker("hide").val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - date = testHelper.addMonths(new Date(), -1); - testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date -1 m"); - inp.datepicker("option", {defaultDate: "+2M"}). - datepicker("hide").val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - date = testHelper.addMonths(new Date(), 2); - testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date +2M"); - inp.datepicker("option", {defaultDate: "-2y"}). - datepicker("hide").val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - date = new Date(); - date.setFullYear(date.getFullYear() - 2); - testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date -2y"); - inp.datepicker("option", {defaultDate: "+1 Y "}). - datepicker("hide").val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - date.setFullYear(date.getFullYear() + 3); - testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date +1 Y"); - inp.datepicker("option", {defaultDate: "+1M +10d"}). - datepicker("hide").val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - date = testHelper.addMonths(new Date(), 1); - date.setDate(date.getDate() + 10); - testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date +1M +10d"); - // String date values - inp.datepicker("option", {defaultDate: "07/04/2007"}). - datepicker("hide").val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - date = new Date(2007, 7 - 1, 4); - testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date 07/04/2007"); - inp.datepicker("option", {dateFormat: "yy-mm-dd", defaultDate: "2007-04-02"}). - datepicker("hide").val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - date = new Date(2007, 4 - 1, 2); - testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date 2007-04-02"); - // Date value - date = new Date(2007, 1 - 1, 26); - inp.datepicker("option", {dateFormat: "mm/dd/yy", defaultDate: date}). - datepicker("hide").val("").datepicker("show"). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date 01/26/2007"); -}); - -test("miscellaneous", function() { - expect( 19 ); - var curYear, longNames, shortNames, date, - dp = $("#ui-datepicker-div"), - inp = testHelper.init("#inp"); - // Year range - function genRange(start, offset) { - var i = start, - range = ""; - for (; i < start + offset; i++) { - range += i; - } - return range; - } - curYear = new Date().getFullYear(); - inp.val("02/04/2008").datepicker("show"); - equal(dp.find(".ui-datepicker-year").text(), "2008", "Year range - read-only default"); - inp.datepicker("hide").datepicker("option", {changeYear: true}).datepicker("show"); - equal(dp.find(".ui-datepicker-year").text(), genRange(2008 - 10, 21), "Year range - changeable default"); - inp.datepicker("hide").datepicker("option", {yearRange: "c-6:c+2", changeYear: true}).datepicker("show"); - equal(dp.find(".ui-datepicker-year").text(), genRange(2008 - 6, 9), "Year range - c-6:c+2"); - inp.datepicker("hide").datepicker("option", {yearRange: "2000:2010", changeYear: true}).datepicker("show"); - equal(dp.find(".ui-datepicker-year").text(), genRange(2000, 11), "Year range - 2000:2010"); - inp.datepicker("hide").datepicker("option", {yearRange: "-5:+3", changeYear: true}).datepicker("show"); - equal(dp.find(".ui-datepicker-year").text(), genRange(curYear - 5, 9), "Year range - -5:+3"); - inp.datepicker("hide").datepicker("option", {yearRange: "2000:-5", changeYear: true}).datepicker("show"); - equal(dp.find(".ui-datepicker-year").text(), genRange(2000, curYear - 2004), "Year range - 2000:-5"); - inp.datepicker("hide").datepicker("option", {yearRange: "", changeYear: true}).datepicker("show"); - equal(dp.find(".ui-datepicker-year").text(), genRange(curYear, 1), "Year range - -6:+2"); - - // Navigation as date format - inp.datepicker("option", {showButtonPanel: true}); - equal(dp.find(".ui-datepicker-prev").text(), "Prev", "Navigation prev - default"); - equal(dp.find(".ui-datepicker-current").text(), "Today", "Navigation current - default"); - equal(dp.find(".ui-datepicker-next").text(), "Next", "Navigation next - default"); - inp.datepicker("hide").datepicker("option", {navigationAsDateFormat: true, prevText: "< M", currentText: "MM", nextText: "M >"}). - val("02/04/2008").datepicker("show"); - longNames = $.datepicker.regional[""].monthNames; - shortNames = $.datepicker.regional[""].monthNamesShort; - date = new Date(); - equal(dp.find(".ui-datepicker-prev").text(), "< " + shortNames[0], "Navigation prev - as date format"); - equal(dp.find(".ui-datepicker-current").text(), - longNames[date.getMonth()], "Navigation current - as date format"); - equal(dp.find(".ui-datepicker-next").text(), - shortNames[2] + " >", "Navigation next - as date format"); - inp.simulate("keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}); - equal(dp.find(".ui-datepicker-prev").text(), - "< " + shortNames[1], "Navigation prev - as date format + pgdn"); - equal(dp.find(".ui-datepicker-current").text(), - longNames[date.getMonth()], "Navigation current - as date format + pgdn"); - equal(dp.find(".ui-datepicker-next").text(), - shortNames[3] + " >", "Navigation next - as date format + pgdn"); - inp.datepicker("hide").datepicker("option", {gotoCurrent: true}). - val("02/04/2008").datepicker("show"); - equal(dp.find(".ui-datepicker-prev").text(), - "< " + shortNames[0], "Navigation prev - as date format + goto current"); - equal(dp.find(".ui-datepicker-current").text(), - longNames[1], "Navigation current - as date format + goto current"); - equal(dp.find(".ui-datepicker-next").text(), - shortNames[2] + " >", "Navigation next - as date format + goto current"); -}); - -test("minMax", function() { - expect( 23 ); - var date, - inp = testHelper.init("#inp"), - dp = $("#ui-datepicker-div"), - lastYear = new Date(2007, 6 - 1, 4), - nextYear = new Date(2009, 6 - 1, 4), - minDate = new Date(2008, 2 - 1, 29), - maxDate = new Date(2008, 12 - 1, 7); - inp.val("06/04/2008").datepicker("show"); - inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - testHelper.equalsDate(inp.datepicker("getDate"), lastYear, - "Min/max - null, null - ctrl+pgup"); - inp.val("06/04/2008").datepicker("show"); - inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - testHelper.equalsDate(inp.datepicker("getDate"), nextYear, - "Min/max - null, null - ctrl+pgdn"); - inp.datepicker("option", {minDate: minDate}). - datepicker("hide").val("06/04/2008").datepicker("show"); - inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - testHelper.equalsDate(inp.datepicker("getDate"), minDate, - "Min/max - 02/29/2008, null - ctrl+pgup"); - inp.val("06/04/2008").datepicker("show"); - inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - testHelper.equalsDate(inp.datepicker("getDate"), nextYear, - "Min/max - 02/29/2008, null - ctrl+pgdn"); - inp.datepicker("option", {maxDate: maxDate}). - datepicker("hide").val("06/04/2008").datepicker("show"); - inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - testHelper.equalsDate(inp.datepicker("getDate"), minDate, - "Min/max - 02/29/2008, 12/07/2008 - ctrl+pgup"); - inp.val("06/04/2008").datepicker("show"); - inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - testHelper.equalsDate(inp.datepicker("getDate"), maxDate, - "Min/max - 02/29/2008, 12/07/2008 - ctrl+pgdn"); - inp.datepicker("option", {minDate: null}). - datepicker("hide").val("06/04/2008").datepicker("show"); - inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - testHelper.equalsDate(inp.datepicker("getDate"), lastYear, - "Min/max - null, 12/07/2008 - ctrl+pgup"); - inp.val("06/04/2008").datepicker("show"); - inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - testHelper.equalsDate(inp.datepicker("getDate"), maxDate, - "Min/max - null, 12/07/2008 - ctrl+pgdn"); - // Relative dates - date = new Date(); - date.setDate(date.getDate() - 7); - inp.datepicker("option", {minDate: "-1w", maxDate: "+1 M +10 D "}). - datepicker("hide").val("").datepicker("show"); - inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - testHelper.equalsDate(inp.datepicker("getDate"), date, - "Min/max - -1w, +1 M +10 D - ctrl+pgup"); - date = testHelper.addMonths(new Date(), 1); - date.setDate(date.getDate() + 10); - inp.val("").datepicker("show"); - inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - testHelper.equalsDate(inp.datepicker("getDate"), date, - "Min/max - -1w, +1 M +10 D - ctrl+pgdn"); - // With existing date - inp = testHelper.init("#inp"); - inp.val("06/04/2008").datepicker("option", {minDate: minDate}); - testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 6 - 1, 4), "Min/max - setDate > min"); - inp.datepicker("option", {minDate: null}).val("01/04/2008").datepicker("option", {minDate: minDate}); - testHelper.equalsDate(inp.datepicker("getDate"), minDate, "Min/max - setDate < min"); - inp.datepicker("option", {minDate: null}).val("06/04/2008").datepicker("option", {maxDate: maxDate}); - testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 6 - 1, 4), "Min/max - setDate < max"); - inp.datepicker("option", {maxDate: null}).val("01/04/2009").datepicker("option", {maxDate: maxDate}); - testHelper.equalsDate(inp.datepicker("getDate"), maxDate, "Min/max - setDate > max"); - inp.datepicker("option", {maxDate: null}).val("01/04/2008").datepicker("option", {minDate: minDate, maxDate: maxDate}); - testHelper.equalsDate(inp.datepicker("getDate"), minDate, "Min/max - setDate < min"); - inp.datepicker("option", {maxDate: null}).val("06/04/2008").datepicker("option", {minDate: minDate, maxDate: maxDate}); - testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 6 - 1, 4), "Min/max - setDate > min, < max"); - inp.datepicker("option", {maxDate: null}).val("01/04/2009").datepicker("option", {minDate: minDate, maxDate: maxDate}); - testHelper.equalsDate(inp.datepicker("getDate"), maxDate, "Min/max - setDate > max"); - - inp.datepicker("option", {yearRange: "-0:+1"}).val("01/01/" + new Date().getFullYear()); - ok(dp.find(".ui-datepicker-prev").hasClass("ui-state-disabled"), "Year Range Test - previous button disabled at 1/1/minYear"); - inp.datepicker("setDate", "12/30/" + new Date().getFullYear()); - ok(dp.find(".ui-datepicker-next").hasClass("ui-state-disabled"), "Year Range Test - next button disabled at 12/30/maxYear"); - - inp.datepicker("option", { - minDate: new Date(1900, 0, 1), - maxDate: "-7Y", - yearRange: "1900:-7" - }).val( "" ); - ok(dp.find(".ui-datepicker-next").hasClass("ui-state-disabled"), "Year Range Test - relative - next button disabled"); - ok(!dp.find(".ui-datepicker-prev").hasClass("ui-state-disabled"), "Year Range Test - relative - prev button enabled"); - - inp.datepicker("option", { - minDate: new Date(1900, 0, 1), - maxDate: "1/25/2007", - yearRange: "1900:2007" - }).val( "" ); - ok(dp.find(".ui-datepicker-next").hasClass("ui-state-disabled"), "Year Range Test - absolute - next button disabled"); - ok(!dp.find(".ui-datepicker-prev").hasClass("ui-state-disabled"), "Year Range Test - absolute - prev button enabled"); -}); - -test("setDate", function() { - expect( 24 ); - var inl, alt, minDate, maxDate, dateAndTimeToSet, dateAndTimeClone, - inp = testHelper.init("#inp"), - date1 = new Date(2008, 6 - 1, 4), - date2 = new Date(); - ok(inp.datepicker("getDate") == null, "Set date - default"); - inp.datepicker("setDate", date1); - testHelper.equalsDate(inp.datepicker("getDate"), date1, "Set date - 2008-06-04"); - date1 = new Date(); - date1.setDate(date1.getDate() + 7); - inp.datepicker("setDate", +7); - testHelper.equalsDate(inp.datepicker("getDate"), date1, "Set date - +7"); - date2.setFullYear(date2.getFullYear() + 2); - inp.datepicker("setDate", "+2y"); - testHelper.equalsDate(inp.datepicker("getDate"), date2, "Set date - +2y"); - inp.datepicker("setDate", date1, date2); - testHelper.equalsDate(inp.datepicker("getDate"), date1, "Set date - two dates"); - inp.datepicker("setDate"); - ok(inp.datepicker("getDate") == null, "Set date - null"); - // Relative to current date - date1 = new Date(); - date1.setDate(date1.getDate() + 7); - inp.datepicker("setDate", "c +7"); - testHelper.equalsDate(inp.datepicker("getDate"), date1, "Set date - c +7"); - date1.setDate(date1.getDate() + 7); - inp.datepicker("setDate", "c+7"); - testHelper.equalsDate(inp.datepicker("getDate"), date1, "Set date - c+7"); - date1.setDate(date1.getDate() - 21); - inp.datepicker("setDate", "c -3 w"); - testHelper.equalsDate(inp.datepicker("getDate"), date1, "Set date - c -3 w"); - // Inline - inl = testHelper.init("#inl"); - date1 = new Date(2008, 6 - 1, 4); - date2 = new Date(); - testHelper.equalsDate(inl.datepicker("getDate"), date2, "Set date inline - default"); - inl.datepicker("setDate", date1); - testHelper.equalsDate(inl.datepicker("getDate"), date1, "Set date inline - 2008-06-04"); - date1 = new Date(); - date1.setDate(date1.getDate() + 7); - inl.datepicker("setDate", +7); - testHelper.equalsDate(inl.datepicker("getDate"), date1, "Set date inline - +7"); - date2.setFullYear(date2.getFullYear() + 2); - inl.datepicker("setDate", "+2y"); - testHelper.equalsDate(inl.datepicker("getDate"), date2, "Set date inline - +2y"); - inl.datepicker("setDate", date1, date2); - testHelper.equalsDate(inl.datepicker("getDate"), date1, "Set date inline - two dates"); - inl.datepicker("setDate"); - ok(inl.datepicker("getDate") == null, "Set date inline - null"); - // Alternate field - alt = $("#alt"); - inp.datepicker("option", {altField: "#alt", altFormat: "yy-mm-dd"}); - date1 = new Date(2008, 6 - 1, 4); - inp.datepicker("setDate", date1); - equal(inp.val(), "06/04/2008", "Set date alternate - 06/04/2008"); - equal(alt.val(), "2008-06-04", "Set date alternate - 2008-06-04"); - // With minimum/maximum - inp = testHelper.init("#inp"); - date1 = new Date(2008, 1 - 1, 4); - date2 = new Date(2008, 6 - 1, 4); - minDate = new Date(2008, 2 - 1, 29); - maxDate = new Date(2008, 3 - 1, 28); - inp.val("").datepicker("option", {minDate: minDate}).datepicker("setDate", date2); - testHelper.equalsDate(inp.datepicker("getDate"), date2, "Set date min/max - setDate > min"); - inp.datepicker("setDate", date1); - testHelper.equalsDate(inp.datepicker("getDate"), minDate, "Set date min/max - setDate < min"); - inp.val("").datepicker("option", {maxDate: maxDate, minDate: null}).datepicker("setDate", date1); - testHelper.equalsDate(inp.datepicker("getDate"), date1, "Set date min/max - setDate < max"); - inp.datepicker("setDate", date2); - testHelper.equalsDate(inp.datepicker("getDate"), maxDate, "Set date min/max - setDate > max"); - inp.val("").datepicker("option", {minDate: minDate}).datepicker("setDate", date1); - testHelper.equalsDate(inp.datepicker("getDate"), minDate, "Set date min/max - setDate < min"); - inp.datepicker("setDate", date2); - testHelper.equalsDate(inp.datepicker("getDate"), maxDate, "Set date min/max - setDate > max"); - dateAndTimeToSet = new Date(2008, 3 - 1, 28, 1, 11, 0); - dateAndTimeClone = new Date(2008, 3 - 1, 28, 1, 11, 0); - inp.datepicker("setDate", dateAndTimeToSet); - equal(dateAndTimeToSet.getTime(), dateAndTimeClone.getTime(), "Date object passed should not be changed by setDate"); -}); - -test("altField", function() { - expect( 10 ); - var inp = testHelper.init("#inp"), - alt = $("#alt"); - // No alternate field set - alt.val(""); - inp.val("06/04/2008").datepicker("show"); - inp.simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - equal(inp.val(), "06/04/2008", "Alt field - dp - enter"); - equal(alt.val(), "", "Alt field - alt not set"); - // Alternate field set - alt.val(""); - inp.datepicker("option", {altField: "#alt", altFormat: "yy-mm-dd"}). - val("06/04/2008").datepicker("show"); - inp.simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - equal(inp.val(), "06/04/2008", "Alt field - dp - enter"); - equal(alt.val(), "2008-06-04", "Alt field - alt - enter"); - // Move from initial date - alt.val(""); - inp.val("06/04/2008").datepicker("show"); - inp.simulate("keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}). - simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - equal(inp.val(), "07/04/2008", "Alt field - dp - pgdn"); - equal(alt.val(), "2008-07-04", "Alt field - alt - pgdn"); - // Alternate field set - closed - alt.val(""); - inp.val("06/04/2008").datepicker("show"); - inp.simulate("keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}). - simulate("keydown", {keyCode: $.ui.keyCode.ESCAPE}); - equal(inp.val(), "06/04/2008", "Alt field - dp - pgdn/esc"); - equal(alt.val(), "", "Alt field - alt - pgdn/esc"); - // Clear date and alternate - alt.val(""); - inp.val("06/04/2008").datepicker("show"); - inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.END}); - equal(inp.val(), "", "Alt field - dp - ctrl+end"); - equal(alt.val(), "", "Alt field - alt - ctrl+end"); -}); - -test("autoSize", function() { - expect( 15 ); - var inp = testHelper.init("#inp"); - equal(inp.prop("size"), 20, "Auto size - default"); - inp.datepicker("option", "autoSize", true); - equal(inp.prop("size"), 10, "Auto size - mm/dd/yy"); - inp.datepicker("option", "dateFormat", "m/d/yy"); - equal(inp.prop("size"), 10, "Auto size - m/d/yy"); - inp.datepicker("option", "dateFormat", "D M d yy"); - equal(inp.prop("size"), 15, "Auto size - D M d yy"); - inp.datepicker("option", "dateFormat", "DD, MM dd, yy"); - equal(inp.prop("size"), 29, "Auto size - DD, MM dd, yy"); - - // French - inp.datepicker("option", $.extend({autoSize: false}, $.datepicker.regional.fr)); - equal(inp.prop("size"), 29, "Auto size - fr - default"); - inp.datepicker("option", "autoSize", true); - equal(inp.prop("size"), 10, "Auto size - fr - dd/mm/yy"); - inp.datepicker("option", "dateFormat", "m/d/yy"); - equal(inp.prop("size"), 10, "Auto size - fr - m/d/yy"); - inp.datepicker("option", "dateFormat", "D M d yy"); - equal(inp.prop("size"), 18, "Auto size - fr - D M d yy"); - inp.datepicker("option", "dateFormat", "DD, MM dd, yy"); - equal(inp.prop("size"), 28, "Auto size - fr - DD, MM dd, yy"); - - // Hebrew - inp.datepicker("option", $.extend({autoSize: false}, $.datepicker.regional.he)); - equal(inp.prop("size"), 28, "Auto size - he - default"); - inp.datepicker("option", "autoSize", true); - equal(inp.prop("size"), 10, "Auto size - he - dd/mm/yy"); - inp.datepicker("option", "dateFormat", "m/d/yy"); - equal(inp.prop("size"), 10, "Auto size - he - m/d/yy"); - inp.datepicker("option", "dateFormat", "D M d yy"); - equal(inp.prop("size"), 16, "Auto size - he - D M d yy"); - inp.datepicker("option", "dateFormat", "DD, MM dd, yy"); - equal(inp.prop("size"), 23, "Auto size - he - DD, MM dd, yy"); -}); - -test("daylightSaving", function() { - expect( 25 ); - var inp = testHelper.init("#inp"), - dp = $("#ui-datepicker-div"); - ok(true, "Daylight saving - " + new Date()); - // Australia, Sydney - AM change, southern hemisphere - inp.val("04/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(6) a", dp).simulate("click"); - equal(inp.val(), "04/05/2008", "Daylight saving - Australia 04/05/2008"); - inp.val("04/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(7) a", dp).simulate("click"); - equal(inp.val(), "04/06/2008", "Daylight saving - Australia 04/06/2008"); - inp.val("04/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(8) a", dp).simulate("click"); - equal(inp.val(), "04/07/2008", "Daylight saving - Australia 04/07/2008"); - inp.val("10/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(6) a", dp).simulate("click"); - equal(inp.val(), "10/04/2008", "Daylight saving - Australia 10/04/2008"); - inp.val("10/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(7) a", dp).simulate("click"); - equal(inp.val(), "10/05/2008", "Daylight saving - Australia 10/05/2008"); - inp.val("10/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(8) a", dp).simulate("click"); - equal(inp.val(), "10/06/2008", "Daylight saving - Australia 10/06/2008"); - // Brasil, Brasilia - midnight change, southern hemisphere - inp.val("02/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(20) a", dp).simulate("click"); - equal(inp.val(), "02/16/2008", "Daylight saving - Brasil 02/16/2008"); - inp.val("02/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(21) a", dp).simulate("click"); - equal(inp.val(), "02/17/2008", "Daylight saving - Brasil 02/17/2008"); - inp.val("02/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(22) a", dp).simulate("click"); - equal(inp.val(), "02/18/2008", "Daylight saving - Brasil 02/18/2008"); - inp.val("10/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(13) a", dp).simulate("click"); - equal(inp.val(), "10/11/2008", "Daylight saving - Brasil 10/11/2008"); - inp.val("10/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(14) a", dp).simulate("click"); - equal(inp.val(), "10/12/2008", "Daylight saving - Brasil 10/12/2008"); - inp.val("10/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(15) a", dp).simulate("click"); - equal(inp.val(), "10/13/2008", "Daylight saving - Brasil 10/13/2008"); - // Lebanon, Beirut - midnight change, northern hemisphere - inp.val("03/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(34) a", dp).simulate("click"); - equal(inp.val(), "03/29/2008", "Daylight saving - Lebanon 03/29/2008"); - inp.val("03/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(35) a", dp).simulate("click"); - equal(inp.val(), "03/30/2008", "Daylight saving - Lebanon 03/30/2008"); - inp.val("03/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(36) a", dp).simulate("click"); - equal(inp.val(), "03/31/2008", "Daylight saving - Lebanon 03/31/2008"); - inp.val("10/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(27) a", dp).simulate("click"); - equal(inp.val(), "10/25/2008", "Daylight saving - Lebanon 10/25/2008"); - inp.val("10/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(28) a", dp).simulate("click"); - equal(inp.val(), "10/26/2008", "Daylight saving - Lebanon 10/26/2008"); - inp.val("10/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(29) a", dp).simulate("click"); - equal(inp.val(), "10/27/2008", "Daylight saving - Lebanon 10/27/2008"); - // US, Eastern - AM change, northern hemisphere - inp.val("03/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(13) a", dp).simulate("click"); - equal(inp.val(), "03/08/2008", "Daylight saving - US 03/08/2008"); - inp.val("03/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(14) a", dp).simulate("click"); - equal(inp.val(), "03/09/2008", "Daylight saving - US 03/09/2008"); - inp.val("03/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(15) a", dp).simulate("click"); - equal(inp.val(), "03/10/2008", "Daylight saving - US 03/10/2008"); - inp.val("11/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(6) a", dp).simulate("click"); - equal(inp.val(), "11/01/2008", "Daylight saving - US 11/01/2008"); - inp.val("11/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(7) a", dp).simulate("click"); - equal(inp.val(), "11/02/2008", "Daylight saving - US 11/02/2008"); - inp.val("11/01/2008").datepicker("show"); - $(".ui-datepicker-calendar td:eq(8) a", dp).simulate("click"); - equal(inp.val(), "11/03/2008", "Daylight saving - US 11/03/2008"); -}); - -var beforeShowThis = null, - beforeShowInput = null, - beforeShowInst = null, - beforeShowDayThis = null, - beforeShowDayOK = true; - -function beforeAll(input, inst) { - beforeShowThis = this; - beforeShowInput = input; - beforeShowInst = inst; - return {currentText: "Current"}; -} - -function beforeDay(date) { - beforeShowDayThis = this; - beforeShowDayOK &= (date > new Date(2008, 1 - 1, 26) && - date < new Date(2008, 3 - 1, 6)); - return [(date.getDate() % 2 === 0), (date.getDate() % 10 === 0 ? "day10" : ""), - (date.getDate() % 3 === 0 ? "Divisble by 3" : "")]; -} - -test("callbacks", function() { - expect( 13 ); - // Before show - var dp, day20, day21, - inp = testHelper.init("#inp", {beforeShow: beforeAll}), - inst = $.data(inp[0], "datepicker"); - equal($.datepicker._get(inst, "currentText"), "Today", "Before show - initial"); - inp.val("02/04/2008").datepicker("show"); - equal($.datepicker._get(inst, "currentText"), "Current", "Before show - changed"); - ok(beforeShowThis.id === inp[0].id, "Before show - this OK"); - ok(beforeShowInput.id === inp[0].id, "Before show - input OK"); - deepEqual(beforeShowInst, inst, "Before show - inst OK"); - inp.datepicker("hide").datepicker("destroy"); - // Before show day - inp = testHelper.init("#inp", {beforeShowDay: beforeDay}); - dp = $("#ui-datepicker-div"); - inp.val("02/04/2008").datepicker("show"); - ok(beforeShowDayThis.id === inp[0].id, "Before show day - this OK"); - ok(beforeShowDayOK, "Before show day - dates OK"); - day20 = dp.find(".ui-datepicker-calendar td:contains('20')"); - day21 = dp.find(".ui-datepicker-calendar td:contains('21')"); - ok(!day20.is(".ui-datepicker-unselectable"), "Before show day - unselectable 20"); - ok(day21.is(".ui-datepicker-unselectable"), "Before show day - unselectable 21"); - ok(day20.is(".day10"), "Before show day - CSS 20"); - ok(!day21.is(".day10"), "Before show day - CSS 21"); - ok(!day20.attr("title"), "Before show day - title 20"); - ok(day21.attr("title") === "Divisble by 3", "Before show day - title 21"); - inp.datepicker("hide").datepicker("destroy"); -}); - -test("beforeShowDay - tooltips with quotes", function() { - expect( 1 ); - var inp, dp; - inp = testHelper.init("#inp", { - beforeShowDay: function() { - return [ true, "", "'" ]; - } - }); - dp = $("#ui-datepicker-div"); - - inp.datepicker("show"); - equal( dp.find( ".ui-datepicker-calendar td:contains('9')").attr( "title" ), "'" ); - inp.datepicker("hide").datepicker("destroy"); -}); - -test("localisation", function() { - expect( 24 ); - var dp, month, day, date, - inp = testHelper.init("#inp", $.datepicker.regional.fr); - inp.datepicker("option", {dateFormat: "DD, d MM yy", showButtonPanel:true, changeMonth:true, changeYear:true}).val("").datepicker("show"); - dp = $("#ui-datepicker-div"); - equal($(".ui-datepicker-close", dp).text(), "Fermer", "Localisation - close"); - $(".ui-datepicker-close", dp).simulate("mouseover"); - equal($(".ui-datepicker-prev", dp).text(), "Précédent", "Localisation - previous"); - equal($(".ui-datepicker-current", dp).text(), "Aujourd'hui", "Localisation - current"); - equal($(".ui-datepicker-next", dp).text(), "Suivant", "Localisation - next"); - month = 0; - $(".ui-datepicker-month option", dp).each(function() { - equal($(this).text(), $.datepicker.regional.fr.monthNamesShort[month], - "Localisation - month " + month); - month++; - }); - day = 1; - $(".ui-datepicker-calendar th", dp).each(function() { - equal($(this).text(), $.datepicker.regional.fr.dayNamesMin[day], - "Localisation - day " + day); - day = (day + 1) % 7; - }); - inp.simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); - date = new Date(); - equal(inp.val(), $.datepicker.regional.fr.dayNames[date.getDay()] + ", " + - date.getDate() + " " + $.datepicker.regional.fr.monthNames[date.getMonth()] + - " " + date.getFullYear(), "Localisation - formatting"); -}); - -test("noWeekends", function() { - expect( 31 ); - var i, date; - for (i = 1; i <= 31; i++) { - date = new Date(2001, 1 - 1, i); - deepEqual($.datepicker.noWeekends(date), [(i + 1) % 7 >= 2, ""], - "No weekends " + date); - } -}); - -test("iso8601Week", function() { - expect( 12 ); - var date = new Date(2000, 12 - 1, 31); - equal($.datepicker.iso8601Week(date), 52, "ISO 8601 week " + date); - date = new Date(2001, 1 - 1, 1); - equal($.datepicker.iso8601Week(date), 1, "ISO 8601 week " + date); - date = new Date(2001, 1 - 1, 7); - equal($.datepicker.iso8601Week(date), 1, "ISO 8601 week " + date); - date = new Date(2001, 1 - 1, 8); - equal($.datepicker.iso8601Week(date), 2, "ISO 8601 week " + date); - date = new Date(2003, 12 - 1, 28); - equal($.datepicker.iso8601Week(date), 52, "ISO 8601 week " + date); - date = new Date(2003, 12 - 1, 29); - equal($.datepicker.iso8601Week(date), 1, "ISO 8601 week " + date); - date = new Date(2004, 1 - 1, 4); - equal($.datepicker.iso8601Week(date), 1, "ISO 8601 week " + date); - date = new Date(2004, 1 - 1, 5); - equal($.datepicker.iso8601Week(date), 2, "ISO 8601 week " + date); - date = new Date(2009, 12 - 1, 28); - equal($.datepicker.iso8601Week(date), 53, "ISO 8601 week " + date); - date = new Date(2010, 1 - 1, 3); - equal($.datepicker.iso8601Week(date), 53, "ISO 8601 week " + date); - date = new Date(2010, 1 - 1, 4); - equal($.datepicker.iso8601Week(date), 1, "ISO 8601 week " + date); - date = new Date(2010, 1 - 1, 10); - equal($.datepicker.iso8601Week(date), 1, "ISO 8601 week " + date); -}); - -test("parseDate", function() { - expect( 26 ); - testHelper.init("#inp"); - var currentYear, gmtDate, fr, settings, zh; - ok($.datepicker.parseDate("d m y", "") == null, "Parse date empty"); - testHelper.equalsDate($.datepicker.parseDate("d m y", "3 2 01"), - new Date(2001, 2 - 1, 3), "Parse date d m y"); - testHelper.equalsDate($.datepicker.parseDate("dd mm yy", "03 02 2001"), - new Date(2001, 2 - 1, 3), "Parse date dd mm yy"); - testHelper.equalsDate($.datepicker.parseDate("d m y", "13 12 01"), - new Date(2001, 12 - 1, 13), "Parse date d m y"); - testHelper.equalsDate($.datepicker.parseDate("dd mm yy", "13 12 2001"), - new Date(2001, 12 - 1, 13), "Parse date dd mm yy"); - testHelper.equalsDate($.datepicker.parseDate("y-o", "01-34"), - new Date(2001, 2 - 1, 3), "Parse date y-o"); - testHelper.equalsDate($.datepicker.parseDate("yy-oo", "2001-347"), - new Date(2001, 12 - 1, 13), "Parse date yy-oo"); - testHelper.equalsDate($.datepicker.parseDate("oo yy", "348 2004"), - new Date(2004, 12 - 1, 13), "Parse date oo yy"); - testHelper.equalsDate($.datepicker.parseDate("D d M y", "Sat 3 Feb 01"), - new Date(2001, 2 - 1, 3), "Parse date D d M y"); - testHelper.equalsDate($.datepicker.parseDate("d MM DD yy", "3 February Saturday 2001"), - new Date(2001, 2 - 1, 3), "Parse date dd MM DD yy"); - testHelper.equalsDate($.datepicker.parseDate("DD, MM d, yy", "Saturday, February 3, 2001"), - new Date(2001, 2 - 1, 3), "Parse date DD, MM d, yy"); - testHelper.equalsDate($.datepicker.parseDate("'day' d 'of' MM (''DD''), yy", - "day 3 of February ('Saturday'), 2001"), new Date(2001, 2 - 1, 3), - "Parse date 'day' d 'of' MM (''DD''), yy"); - currentYear = new Date().getFullYear(); - testHelper.equalsDate($.datepicker.parseDate("y-m-d", (currentYear - 2000) + "-02-03"), - new Date(currentYear, 2 - 1, 3), "Parse date y-m-d - default cutuff"); - testHelper.equalsDate($.datepicker.parseDate("y-m-d", (currentYear - 2000 + 10) + "-02-03"), - new Date(currentYear+10, 2 - 1, 3), "Parse date y-m-d - default cutuff"); - testHelper.equalsDate($.datepicker.parseDate("y-m-d", (currentYear - 2000 + 11) + "-02-03"), - new Date(currentYear-89, 2 - 1, 3), "Parse date y-m-d - default cutuff"); - testHelper.equalsDate($.datepicker.parseDate("y-m-d", "80-02-03", {shortYearCutoff: 80}), - new Date(2080, 2 - 1, 3), "Parse date y-m-d - cutoff 80"); - testHelper.equalsDate($.datepicker.parseDate("y-m-d", "81-02-03", {shortYearCutoff: 80}), - new Date(1981, 2 - 1, 3), "Parse date y-m-d - cutoff 80"); - testHelper.equalsDate($.datepicker.parseDate("y-m-d", (currentYear - 2000 + 60) + "-02-03", {shortYearCutoff: "+60"}), - new Date(currentYear + 60, 2 - 1, 3), "Parse date y-m-d - cutoff +60"); - testHelper.equalsDate($.datepicker.parseDate("y-m-d", (currentYear - 2000 + 61) + "-02-03", {shortYearCutoff: "+60"}), - new Date(currentYear - 39, 2 - 1, 3), "Parse date y-m-d - cutoff +60"); - gmtDate = new Date(2001, 2 - 1, 3); - gmtDate.setMinutes(gmtDate.getMinutes() - gmtDate.getTimezoneOffset()); - testHelper.equalsDate($.datepicker.parseDate("@", "981158400000"), gmtDate, "Parse date @"); - testHelper.equalsDate($.datepicker.parseDate("!", "631167552000000000"), gmtDate, "Parse date !"); - - fr = $.datepicker.regional.fr; - settings = {dayNamesShort: fr.dayNamesShort, dayNames: fr.dayNames, - monthNamesShort: fr.monthNamesShort, monthNames: fr.monthNames}; - testHelper.equalsDate($.datepicker.parseDate("D d M y", "Lun. 9 avr. 01", settings), - new Date(2001, 4 - 1, 9), "Parse date D M y with settings"); - testHelper.equalsDate($.datepicker.parseDate("d MM DD yy", "9 Avril Lundi 2001", settings), - new Date(2001, 4 - 1, 9), "Parse date d MM DD yy with settings"); - testHelper.equalsDate($.datepicker.parseDate("DD, MM d, yy", "Lundi, Avril 9, 2001", settings), - new Date(2001, 4 - 1, 9), "Parse date DD, MM d, yy with settings"); - testHelper.equalsDate($.datepicker.parseDate("'jour' d 'de' MM (''DD''), yy", "jour 9 de Avril ('Lundi'), 2001", settings), - new Date(2001, 4 - 1, 9), "Parse date 'jour' d 'de' MM (''DD''), yy with settings"); - - zh = $.datepicker.regional["zh-CN"]; - testHelper.equalsDate($.datepicker.parseDate("yy M d", "2011 十一月 22", zh), - new Date(2011, 11 - 1, 22), "Parse date yy M d with zh-CN"); -}); - -test("parseDateErrors", function() { - expect( 18 ); - testHelper.init("#inp"); - var fr, settings; - function expectError(expr, value, error) { - try { - expr(); - ok(false, "Parsed error " + value); - } - catch (e) { - equal(e, error, "Parsed error " + value); - } - } - expectError(function() { $.datepicker.parseDate(null, "Sat 2 01"); }, - "Sat 2 01", "Invalid arguments"); - expectError(function() { $.datepicker.parseDate("d m y", null); }, - "null", "Invalid arguments"); - expectError(function() { $.datepicker.parseDate("d m y", "Sat 2 01"); }, - "Sat 2 01 - d m y", "Missing number at position 0"); - expectError(function() { $.datepicker.parseDate("dd mm yy", "Sat 2 01"); }, - "Sat 2 01 - dd mm yy", "Missing number at position 0"); - expectError(function() { $.datepicker.parseDate("d m y", "3 Feb 01"); }, - "3 Feb 01 - d m y", "Missing number at position 2"); - expectError(function() { $.datepicker.parseDate("dd mm yy", "3 Feb 01"); }, - "3 Feb 01 - dd mm yy", "Missing number at position 2"); - expectError(function() { $.datepicker.parseDate("mm dd yy", "2 1 01"); }, - "2 1 01 - dd mm yy", "Missing number at position 4"); - expectError(function() { $.datepicker.parseDate("d m y", "3 2 AD01"); }, - "3 2 AD01 - d m y", "Missing number at position 4"); - expectError(function() { $.datepicker.parseDate("d m yy", "3 2 AD01"); }, - "3 2 AD01 - dd mm yy", "Missing number at position 4"); - expectError(function() { $.datepicker.parseDate("y-o", "01-D01"); }, - "2001-D01 - y-o", "Missing number at position 3"); - expectError(function() { $.datepicker.parseDate("yy-oo", "2001-D01"); }, - "2001-D01 - yy-oo", "Missing number at position 5"); - expectError(function() { $.datepicker.parseDate("D d M y", "D7 3 Feb 01"); }, - "D7 3 Feb 01 - D d M y", "Unknown name at position 0"); - expectError(function() { $.datepicker.parseDate("D d M y", "Sat 3 M2 01"); }, - "Sat 3 M2 01 - D d M y", "Unknown name at position 6"); - expectError(function() { $.datepicker.parseDate("DD, MM d, yy", "Saturday- Feb 3, 2001"); }, - "Saturday- Feb 3, 2001 - DD, MM d, yy", "Unexpected literal at position 8"); - expectError(function() { $.datepicker.parseDate("'day' d 'of' MM (''DD''), yy", - "day 3 of February (\"Saturday\"), 2001"); }, - "day 3 of Mon2 ('Day7'), 2001", "Unexpected literal at position 19"); - expectError(function() { $.datepicker.parseDate("d m y", "29 2 01"); }, - "29 2 01 - d m y", "Invalid date"); - fr = $.datepicker.regional.fr; - settings = {dayNamesShort: fr.dayNamesShort, dayNames: fr.dayNames, - monthNamesShort: fr.monthNamesShort, monthNames: fr.monthNames}; - expectError(function() { $.datepicker.parseDate("D d M y", "Mon 9 Avr 01", settings); }, - "Mon 9 Avr 01 - D d M y", "Unknown name at position 0"); - expectError(function() { $.datepicker.parseDate("D d M y", "Lun. 9 Apr 01", settings); }, - "Lun. 9 Apr 01 - D d M y", "Unknown name at position 7"); -}); - -test("Ticket #7244: date parser does not fail when too many numbers are passed into the date function", function() { - expect( 4 ); - var date; - try{ - date = $.datepicker.parseDate("dd/mm/yy", "18/04/19881"); - ok(false, "Did not properly detect an invalid date"); - }catch(e){ - ok("invalid date detected"); - } - - try { - date = $.datepicker.parseDate("dd/mm/yy", "18/04/1988 @ 2:43 pm"); - equal(date.getDate(), 18); - equal(date.getMonth(), 3); - equal(date.getFullYear(), 1988); - } catch(e) { - ok(false, "Did not properly parse date with extra text separated by whitespace"); - } -}); - -test("formatDate", function() { - expect( 16 ); - testHelper.init("#inp"); - var gmtDate, fr, settings; - equal($.datepicker.formatDate("d m y", new Date(2001, 2 - 1, 3)), - "3 2 01", "Format date d m y"); - equal($.datepicker.formatDate("dd mm yy", new Date(2001, 2 - 1, 3)), - "03 02 2001", "Format date dd mm yy"); - equal($.datepicker.formatDate("d m y", new Date(2001, 12 - 1, 13)), - "13 12 01", "Format date d m y"); - equal($.datepicker.formatDate("dd mm yy", new Date(2001, 12 - 1, 13)), - "13 12 2001", "Format date dd mm yy"); - equal($.datepicker.formatDate("yy-o", new Date(2001, 2 - 1, 3)), - "2001-34", "Format date yy-o"); - equal($.datepicker.formatDate("yy-oo", new Date(2001, 2 - 1, 3)), - "2001-034", "Format date yy-oo"); - equal($.datepicker.formatDate("D M y", new Date(2001, 2 - 1, 3)), - "Sat Feb 01", "Format date D M y"); - equal($.datepicker.formatDate("DD MM yy", new Date(2001, 2 - 1, 3)), - "Saturday February 2001", "Format date DD MM yy"); - equal($.datepicker.formatDate("DD, MM d, yy", new Date(2001, 2 - 1, 3)), - "Saturday, February 3, 2001", "Format date DD, MM d, yy"); - equal($.datepicker.formatDate("'day' d 'of' MM (''DD''), yy", - new Date(2001, 2 - 1, 3)), "day 3 of February ('Saturday'), 2001", - "Format date 'day' d 'of' MM ('DD'), yy"); - gmtDate = new Date(2001, 2 - 1, 3); - gmtDate.setMinutes(gmtDate.getMinutes() - gmtDate.getTimezoneOffset()); - equal($.datepicker.formatDate("@", gmtDate), "981158400000", "Format date @"); - equal($.datepicker.formatDate("!", gmtDate), "631167552000000000", "Format date !"); - fr = $.datepicker.regional.fr; - settings = {dayNamesShort: fr.dayNamesShort, dayNames: fr.dayNames, - monthNamesShort: fr.monthNamesShort, monthNames: fr.monthNames}; - equal($.datepicker.formatDate("D M y", new Date(2001, 4 - 1, 9), settings), - "lun. avr. 01", "Format date D M y with settings"); - equal($.datepicker.formatDate("DD MM yy", new Date(2001, 4 - 1, 9), settings), - "lundi avril 2001", "Format date DD MM yy with settings"); - equal($.datepicker.formatDate("DD, MM d, yy", new Date(2001, 4 - 1, 9), settings), - "lundi, avril 9, 2001", "Format date DD, MM d, yy with settings"); - equal($.datepicker.formatDate("'jour' d 'de' MM (''DD''), yy", - new Date(2001, 4 - 1, 9), settings), "jour 9 de avril ('lundi'), 2001", - "Format date 'jour' d 'de' MM (''DD''), yy with settings"); -}); - -// TODO: Fix this test so it isn't mysteriously flaky in Browserstack on certain OS/Browser combos -// test("Ticket 6827: formatDate day of year calculation is wrong during day lights savings time", function(){ -// expect( 1 ); -// var time = $.datepicker.formatDate("oo", new Date("2010/03/30 12:00:00 CDT")); -// equal(time, "089"); -// }); - -test( "Ticket 7602: Stop datepicker from appearing with beforeShow event handler", function() { - expect( 3 ); - - var inp, dp; - - inp = testHelper.init( "#inp", { - beforeShow: function() { - } - }); - dp = $( "#ui-datepicker-div" ); - inp.datepicker( "show" ); - equal( dp.css( "display" ), "block", "beforeShow returns nothing" ); - inp.datepicker( "hide" ).datepicker( "destroy" ); - - inp = testHelper.init( "#inp", { - beforeShow: function() { - return true; - } - }); - dp = $( "#ui-datepicker-div" ); - inp.datepicker( "show" ); - equal( dp.css( "display" ), "block", "beforeShow returns true" ); - inp.datepicker( "hide" ); - inp.datepicker( "destroy" ); - - inp = testHelper.init( "#inp", { - beforeShow: function() { - return false; - } - }); - dp = $( "#ui-datepicker-div" ); - inp.datepicker( "show" ); - equal( dp.css( "display" ), "none","beforeShow returns false" ); - inp.datepicker( "destroy" ); -}); - -} ); diff --git a/tests/unit/datepicker/datepicker_test_helpers.js b/tests/unit/datepicker/datepicker_test_helpers.js deleted file mode 100644 index 4cd9b48ff..000000000 --- a/tests/unit/datepicker/datepicker_test_helpers.js +++ /dev/null @@ -1,38 +0,0 @@ -define( [ - "jquery", - "lib/helper", - "ui/datepicker" -], function( $, helper ) { - -return $.extend( helper, { - addMonths: function(date, offset) { - var maxDay = 32 - new Date(date.getFullYear(), date.getMonth() + offset, 32).getDate(); - date.setDate(Math.min(date.getDate(), maxDay)); - date.setMonth(date.getMonth() + offset); - return date; - }, - - equalsDate: function(d1, d2, message) { - if (!d1 || !d2) { - ok(false, message + " - missing date"); - return; - } - d1 = new Date(d1.getFullYear(), d1.getMonth(), d1.getDate()); - d2 = new Date(d2.getFullYear(), d2.getMonth(), d2.getDate()); - equal(d1.toString(), d2.toString(), message); - }, - - init: function( id, options ) { - $.datepicker.setDefaults( $.datepicker.regional[ "" ] ); - return $( id ).datepicker( $.extend( { showAnim: "" }, options || {} ) ); - }, - - initNewInput: function( options ) { - var id = $( "" ).appendTo( "#qunit-fixture" ); - return this.init( id, options ); - }, - - PROP_NAME: "datepicker" -} ); - -} ); diff --git a/tests/unit/datepicker/events.js b/tests/unit/datepicker/events.js new file mode 100644 index 000000000..ea69c1aaa --- /dev/null +++ b/tests/unit/datepicker/events.js @@ -0,0 +1,154 @@ +define( [ + "jquery", + "./helper", + "ui/datepicker" +], function( $, testHelper ) { + +module("datepicker: events"); + +var selectedThis = null, +selectedDate = null, +selectedInst = null; + +function callback(date, inst) { + selectedThis = this; + selectedDate = date; + selectedInst = inst; +} + +function callback2(year, month, inst) { + selectedThis = this; + selectedDate = year + "/" + month; + selectedInst = inst; +} + +test("events", function() { + expect( 26 ); + var dateStr, newMonthYear, inp2, + inp = testHelper.init("#inp", {onSelect: callback}), + date = new Date(); + // onSelect + inp.val("").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + equal(selectedThis, inp[0], "Callback selected this"); + equal(selectedInst, $.data(inp[0], testHelper.PROP_NAME), "Callback selected inst"); + equal(selectedDate, $.datepicker.formatDate("mm/dd/yy", date), + "Callback selected date"); + inp.val("").datepicker("show"). + simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.DOWN}). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + date.setDate(date.getDate() + 7); + equal(selectedDate, $.datepicker.formatDate("mm/dd/yy", date), + "Callback selected date - ctrl+down"); + inp.val("").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.ESCAPE}); + equal(selectedDate, $.datepicker.formatDate("mm/dd/yy", date), + "Callback selected date - esc"); + dateStr = "02/04/2008"; + inp.val(dateStr).datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + equal(dateStr, selectedDate, + "onSelect is called after enter keydown"); + // onChangeMonthYear + inp.datepicker("option", {onChangeMonthYear: callback2, onSelect: null}). + val("").datepicker("show"); + newMonthYear = function(date) { + return date.getFullYear() + "/" + (date.getMonth() + 1); + }; + date = new Date(); + date.setDate(1); + inp.simulate("keydown", {keyCode: $.ui.keyCode.PAGE_UP}); + date.setMonth(date.getMonth() - 1); + equal(selectedThis, inp[0], "Callback change month/year this"); + equal(selectedInst, $.data(inp[0], testHelper.PROP_NAME), "Callback change month/year inst"); + equal(selectedDate, newMonthYear(date), + "Callback change month/year date - pgup"); + inp.simulate("keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}); + date.setMonth(date.getMonth() + 1); + equal(selectedDate, newMonthYear(date), + "Callback change month/year date - pgdn"); + inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}); + date.setFullYear(date.getFullYear() - 1); + equal(selectedDate, newMonthYear(date), + "Callback change month/year date - ctrl+pgup"); + inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.HOME}); + date.setFullYear(date.getFullYear() + 1); + equal(selectedDate, newMonthYear(date), + "Callback change month/year date - ctrl+home"); + inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}); + date.setFullYear(date.getFullYear() + 1); + equal(selectedDate, newMonthYear(date), + "Callback change month/year date - ctrl+pgdn"); + inp.datepicker("setDate", new Date(2007, 1 - 1, 26)); + equal(selectedDate, "2007/1", "Callback change month/year date - setDate"); + selectedDate = null; + inp.datepicker("setDate", new Date(2007, 1 - 1, 12)); + ok(selectedDate == null, "Callback change month/year date - setDate no change"); + // onChangeMonthYear step by 2 + inp.datepicker("option", {stepMonths: 2}). + datepicker("hide").val("").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.PAGE_UP}); + date.setMonth(date.getMonth() - 14); + equal(selectedDate, newMonthYear(date), + "Callback change month/year by 2 date - pgup"); + inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}); + date.setMonth(date.getMonth() - 12); + equal(selectedDate, newMonthYear(date), + "Callback change month/year by 2 date - ctrl+pgup"); + inp.simulate("keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}); + date.setMonth(date.getMonth() + 2); + equal(selectedDate, newMonthYear(date), + "Callback change month/year by 2 date - pgdn"); + inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}); + date.setMonth(date.getMonth() + 12); + equal(selectedDate, newMonthYear(date), + "Callback change month/year by 2 date - ctrl+pgdn"); + // onClose + inp.datepicker("option", {onClose: callback, onChangeMonthYear: null, stepMonths: 1}). + val("").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.ESCAPE}); + equal(selectedThis, inp[0], "Callback close this"); + equal(selectedInst, $.data(inp[0], testHelper.PROP_NAME), "Callback close inst"); + equal(selectedDate, "", "Callback close date - esc"); + inp.val("").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + equal(selectedDate, $.datepicker.formatDate("mm/dd/yy", new Date()), + "Callback close date - enter"); + inp.val("02/04/2008").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.ESCAPE}); + equal(selectedDate, "02/04/2008", "Callback close date - preset"); + inp.val("02/04/2008").datepicker("show"). + simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.END}); + equal(selectedDate, "", "Callback close date - ctrl+end"); + + inp2 = testHelper.init("#inp2"); + inp2.datepicker().datepicker("option", {onClose: callback}).datepicker("show"); + inp.datepicker("show"); + equal(selectedThis, inp2[0], "Callback close this"); +}); + +test("beforeShowDay-getDate", function() { + expect( 3 ); + var inp = testHelper.init("#inp", {beforeShowDay: function() { inp.datepicker("getDate"); return [true, ""]; }}), + dp = $("#ui-datepicker-div"); + inp.val("01/01/2010").datepicker("show"); + // contains non-breaking space + equal($("div.ui-datepicker-title").text(), + // support: IE <9, jQuery <1.8 + // In IE7/8 with jQuery <1.8, encoded spaces behave in strange ways + $( "January 2010" ).text(), "Initial month"); + $("a.ui-datepicker-next", dp).click(); + $("a.ui-datepicker-next", dp).click(); + // contains non-breaking space + equal($("div.ui-datepicker-title").text(), + $( "March 2010" ).text(), "After next clicks"); + inp.datepicker("hide").datepicker("show"); + $("a.ui-datepicker-prev", dp).click(); + $("a.ui-datepicker-prev", dp).click(); + // contains non-breaking space + equal($("div.ui-datepicker-title").text(), + $( "November 2009" ).text(), "After prev clicks"); + inp.datepicker("hide"); +}); + +} ); diff --git a/tests/unit/datepicker/helper.js b/tests/unit/datepicker/helper.js new file mode 100644 index 000000000..4cd9b48ff --- /dev/null +++ b/tests/unit/datepicker/helper.js @@ -0,0 +1,38 @@ +define( [ + "jquery", + "lib/helper", + "ui/datepicker" +], function( $, helper ) { + +return $.extend( helper, { + addMonths: function(date, offset) { + var maxDay = 32 - new Date(date.getFullYear(), date.getMonth() + offset, 32).getDate(); + date.setDate(Math.min(date.getDate(), maxDay)); + date.setMonth(date.getMonth() + offset); + return date; + }, + + equalsDate: function(d1, d2, message) { + if (!d1 || !d2) { + ok(false, message + " - missing date"); + return; + } + d1 = new Date(d1.getFullYear(), d1.getMonth(), d1.getDate()); + d2 = new Date(d2.getFullYear(), d2.getMonth(), d2.getDate()); + equal(d1.toString(), d2.toString(), message); + }, + + init: function( id, options ) { + $.datepicker.setDefaults( $.datepicker.regional[ "" ] ); + return $( id ).datepicker( $.extend( { showAnim: "" }, options || {} ) ); + }, + + initNewInput: function( options ) { + var id = $( "" ).appendTo( "#qunit-fixture" ); + return this.init( id, options ); + }, + + PROP_NAME: "datepicker" +} ); + +} ); diff --git a/tests/unit/datepicker/methods.js b/tests/unit/datepicker/methods.js new file mode 100644 index 000000000..14fefacc2 --- /dev/null +++ b/tests/unit/datepicker/methods.js @@ -0,0 +1,126 @@ +define( [ + "jquery", + "./helper", + "ui/datepicker" +], function( $, testHelper ) { + +module("datepicker: methods"); + +test("destroy", function() { + expect( 33 ); + var inl, + inp = testHelper.init("#inp"); + ok(inp.is(".hasDatepicker"), "Default - marker class set"); + ok($.data(inp[0], testHelper.PROP_NAME), "Default - instance present"); + ok(inp.next().is("#alt"), "Default - button absent"); + inp.datepicker("destroy"); + inp = $("#inp"); + ok(!inp.is(".hasDatepicker"), "Default - marker class cleared"); + ok(!$.data(inp[0], testHelper.PROP_NAME), "Default - instance absent"); + ok(inp.next().is("#alt"), "Default - button absent"); + // With button + inp= testHelper.init("#inp", {showOn: "both"}); + ok(inp.is(".hasDatepicker"), "Button - marker class set"); + ok($.data(inp[0], testHelper.PROP_NAME), "Button - instance present"); + ok(inp.next().text() === "...", "Button - button added"); + inp.datepicker("destroy"); + inp = $("#inp"); + ok(!inp.is(".hasDatepicker"), "Button - marker class cleared"); + ok(!$.data(inp[0], testHelper.PROP_NAME), "Button - instance absent"); + ok(inp.next().is("#alt"), "Button - button removed"); + // With append text + inp = testHelper.init("#inp", {appendText: "Testing"}); + ok(inp.is(".hasDatepicker"), "Append - marker class set"); + ok($.data(inp[0], testHelper.PROP_NAME), "Append - instance present"); + ok(inp.next().text() === "Testing", "Append - append text added"); + inp.datepicker("destroy"); + inp = $("#inp"); + ok(!inp.is(".hasDatepicker"), "Append - marker class cleared"); + ok(!$.data(inp[0], testHelper.PROP_NAME), "Append - instance absent"); + ok(inp.next().is("#alt"), "Append - append text removed"); + // With both + inp= testHelper.init("#inp", {showOn: "both", buttonImageOnly: true, + buttonImage: "images/calendar.gif", appendText: "Testing"}); + ok(inp.is(".hasDatepicker"), "Both - marker class set"); + ok($.data(inp[0], testHelper.PROP_NAME), "Both - instance present"); + ok(inp.next()[0].nodeName.toLowerCase() === "img", "Both - button added"); + ok(inp.next().next().text() === "Testing", "Both - append text added"); + inp.datepicker("destroy"); + inp = $("#inp"); + ok(!inp.is(".hasDatepicker"), "Both - marker class cleared"); + ok(!$.data(inp[0], testHelper.PROP_NAME), "Both - instance absent"); + ok(inp.next().is("#alt"), "Both - button and append text absent"); + // Inline + inl = testHelper.init("#inl"); + ok(inl.is(".hasDatepicker"), "Inline - marker class set"); + ok(inl.html() !== "", "Inline - datepicker present"); + ok($.data(inl[0], testHelper.PROP_NAME), "Inline - instance present"); + ok(inl.next().length === 0 || inl.next().is("p"), "Inline - button absent"); + inl.datepicker("destroy"); + inl = $("#inl"); + ok(!inl.is(".hasDatepicker"), "Inline - marker class cleared"); + ok(inl.html() === "", "Inline - datepicker absent"); + ok(!$.data(inl[0], testHelper.PROP_NAME), "Inline - instance absent"); + ok(inl.next().length === 0 || inl.next().is("p"), "Inline - button absent"); +}); + +test("enableDisable", function() { + expect( 33 ); + var inl, dp, + inp = testHelper.init("#inp"); + ok(!inp.datepicker("isDisabled"), "Enable/disable - initially marked as enabled"); + ok(!inp[0].disabled, "Enable/disable - field initially enabled"); + inp.datepicker("disable"); + ok(inp.datepicker("isDisabled"), "Enable/disable - now marked as disabled"); + ok(inp[0].disabled, "Enable/disable - field now disabled"); + inp.datepicker("enable"); + ok(!inp.datepicker("isDisabled"), "Enable/disable - now marked as enabled"); + ok(!inp[0].disabled, "Enable/disable - field now enabled"); + inp.datepicker("destroy"); + // With a button + inp = testHelper.init("#inp", {showOn: "button"}); + ok(!inp.datepicker("isDisabled"), "Enable/disable button - initially marked as enabled"); + ok(!inp[0].disabled, "Enable/disable button - field initially enabled"); + ok(!inp.next("button")[0].disabled, "Enable/disable button - button initially enabled"); + inp.datepicker("disable"); + ok(inp.datepicker("isDisabled"), "Enable/disable button - now marked as disabled"); + ok(inp[0].disabled, "Enable/disable button - field now disabled"); + ok(inp.next("button")[0].disabled, "Enable/disable button - button now disabled"); + inp.datepicker("enable"); + ok(!inp.datepicker("isDisabled"), "Enable/disable button - now marked as enabled"); + ok(!inp[0].disabled, "Enable/disable button - field now enabled"); + ok(!inp.next("button")[0].disabled, "Enable/disable button - button now enabled"); + inp.datepicker("destroy"); + // With an image button + inp = testHelper.init("#inp", {showOn: "button", buttonImageOnly: true, + buttonImage: "images/calendar.gif"}); + ok(!inp.datepicker("isDisabled"), "Enable/disable image - initially marked as enabled"); + ok(!inp[0].disabled, "Enable/disable image - field initially enabled"); + ok(parseFloat(inp.next("img").css("opacity")) === 1, "Enable/disable image - image initially enabled"); + inp.datepicker("disable"); + ok(inp.datepicker("isDisabled"), "Enable/disable image - now marked as disabled"); + ok(inp[0].disabled, "Enable/disable image - field now disabled"); + ok(parseFloat(inp.next("img").css("opacity")) !== 1, "Enable/disable image - image now disabled"); + inp.datepicker("enable"); + ok(!inp.datepicker("isDisabled"), "Enable/disable image - now marked as enabled"); + ok(!inp[0].disabled, "Enable/disable image - field now enabled"); + ok(parseFloat(inp.next("img").css("opacity")) === 1, "Enable/disable image - image now enabled"); + inp.datepicker("destroy"); + // Inline + inl = testHelper.init("#inl", {changeYear: true}); + dp = $(".ui-datepicker-inline", inl); + ok(!inl.datepicker("isDisabled"), "Enable/disable inline - initially marked as enabled"); + ok(!dp.children().is(".ui-state-disabled"), "Enable/disable inline - not visually disabled initially"); + ok(!dp.find("select").prop("disabled"), "Enable/disable inline - form element enabled initially"); + inl.datepicker("disable"); + ok(inl.datepicker("isDisabled"), "Enable/disable inline - now marked as disabled"); + ok(dp.children().is(".ui-state-disabled"), "Enable/disable inline - visually disabled"); + ok(dp.find("select").prop("disabled"), "Enable/disable inline - form element disabled"); + inl.datepicker("enable"); + ok(!inl.datepicker("isDisabled"), "Enable/disable inline - now marked as enabled"); + ok(!dp.children().is(".ui-state-disabled"), "Enable/disable inline - not visiually disabled"); + ok(!dp.find("select").prop("disabled"), "Enable/disable inline - form element enabled"); + inl.datepicker("destroy"); +}); + +} ); diff --git a/tests/unit/datepicker/options.js b/tests/unit/datepicker/options.js new file mode 100644 index 000000000..c8a30678b --- /dev/null +++ b/tests/unit/datepicker/options.js @@ -0,0 +1,1127 @@ +define( [ + "jquery", + "./helper", + "ui/datepicker", + "ui/i18n/datepicker-fr", + "ui/i18n/datepicker-he", + "ui/i18n/datepicker-zh-CN" +], function( $, testHelper ) { + +module("datepicker: options"); + +test("setDefaults", function() { + expect( 3 ); + testHelper.init("#inp"); + equal($.datepicker._defaults.showOn, "focus", "Initial showOn"); + $.datepicker.setDefaults({showOn: "button"}); + equal($.datepicker._defaults.showOn, "button", "Change default showOn"); + $.datepicker.setDefaults({showOn: "focus"}); + equal($.datepicker._defaults.showOn, "focus", "Restore showOn"); +}); + +test("option", function() { + expect( 17 ); + var inp = testHelper.init("#inp"), + inst = $.data(inp[0], testHelper.PROP_NAME); + // Set option + equal(inst.settings.showOn, null, "Initial setting showOn"); + equal($.datepicker._get(inst, "showOn"), "focus", "Initial instance showOn"); + equal($.datepicker._defaults.showOn, "focus", "Initial default showOn"); + inp.datepicker("option", "showOn", "button"); + equal(inst.settings.showOn, "button", "Change setting showOn"); + equal($.datepicker._get(inst, "showOn"), "button", "Change instance showOn"); + equal($.datepicker._defaults.showOn, "focus", "Retain default showOn"); + inp.datepicker("option", {showOn: "both"}); + equal(inst.settings.showOn, "both", "Change setting showOn"); + equal($.datepicker._get(inst, "showOn"), "both", "Change instance showOn"); + equal($.datepicker._defaults.showOn, "focus", "Retain default showOn"); + inp.datepicker("option", "showOn", undefined); + equal(inst.settings.showOn, null, "Clear setting showOn"); + equal($.datepicker._get(inst, "showOn"), "focus", "Restore instance showOn"); + equal($.datepicker._defaults.showOn, "focus", "Retain default showOn"); + // Get option + inp = testHelper.init("#inp"); + equal(inp.datepicker("option", "showOn"), "focus", "Initial setting showOn"); + inp.datepicker("option", "showOn", "button"); + equal(inp.datepicker("option", "showOn"), "button", "Change instance showOn"); + inp.datepicker("option", "showOn", undefined); + equal(inp.datepicker("option", "showOn"), "focus", "Reset instance showOn"); + deepEqual(inp.datepicker("option", "all"), {showAnim: ""}, "Get instance settings"); + deepEqual(inp.datepicker("option", "defaults"), $.datepicker._defaults, + "Get default settings"); +}); + +test( "disabled", function() { + expect(8); + var inp = testHelper.init("#inp"); + ok(!inp.datepicker("isDisabled"), "Initially marked as enabled"); + ok(!inp[0].disabled, "Field initially enabled"); + inp.datepicker("option", "disabled", true); + ok(inp.datepicker("isDisabled"), "Marked as disabled"); + ok(inp[0].disabled, "Field now disabled"); + inp.datepicker("option", "disabled", false); + ok(!inp.datepicker("isDisabled"), "Marked as enabled"); + ok(!inp[0].disabled, "Field now enabled"); + inp.datepicker("destroy"); + + inp = testHelper.init("#inp", { disabled: true }); + ok(inp.datepicker("isDisabled"), "Initially marked as disabled"); + ok(inp[0].disabled, "Field initially disabled"); +}); + +test("change", function() { + expect( 12 ); + var inp = testHelper.init("#inp"), + inst = $.data(inp[0], testHelper.PROP_NAME); + equal(inst.settings.showOn, null, "Initial setting showOn"); + equal($.datepicker._get(inst, "showOn"), "focus", "Initial instance showOn"); + equal($.datepicker._defaults.showOn, "focus", "Initial default showOn"); + inp.datepicker("change", "showOn", "button"); + equal(inst.settings.showOn, "button", "Change setting showOn"); + equal($.datepicker._get(inst, "showOn"), "button", "Change instance showOn"); + equal($.datepicker._defaults.showOn, "focus", "Retain default showOn"); + inp.datepicker("change", {showOn: "both"}); + equal(inst.settings.showOn, "both", "Change setting showOn"); + equal($.datepicker._get(inst, "showOn"), "both", "Change instance showOn"); + equal($.datepicker._defaults.showOn, "focus", "Retain default showOn"); + inp.datepicker("change", "showOn", undefined); + equal(inst.settings.showOn, null, "Clear setting showOn"); + equal($.datepicker._get(inst, "showOn"), "focus", "Restore instance showOn"); + equal($.datepicker._defaults.showOn, "focus", "Retain default showOn"); +}); + +(function() { + var url = window.location.search; + url = decodeURIComponent( url.slice( url.indexOf( "swarmURL=" ) + 9 ) ); + + // TODO: This test occassionally fails in IE in TestSwarm + if ( $.ui.ie && url && url.indexOf( "http" ) === 0 ) { + return; + } + + asyncTest( "invocation", function() { + var button, image, + isOldIE = $.ui.ie && ( !document.documentMode || document.documentMode < 9 ), + body = $( "body" ); + + expect( isOldIE ? 25 : 29 ); + + function step0() { + var inp = testHelper.initNewInput(), + dp = $( "#ui-datepicker-div" ); + + button = inp.siblings( "button" ); + ok( button.length === 0, "Focus - button absent" ); + image = inp.siblings( "img" ); + ok( image.length === 0, "Focus - image absent" ); + + testHelper.onFocus( inp, function() { + ok( dp.is( ":visible" ), "Focus - rendered on focus" ); + inp.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); + ok( !dp.is( ":visible" ), "Focus - hidden on exit" ); + step1(); + }); + } + + function step1() { + + var inp = testHelper.initNewInput(), + dp = $( "#ui-datepicker-div" ); + + testHelper.onFocus( inp, function() { + ok( dp.is( ":visible" ), "Focus - rendered on focus" ); + body.simulate( "mousedown", {} ); + ok( !dp.is( ":visible" ), "Focus - hidden on external click" ); + inp.datepicker( "hide" ).datepicker( "destroy" ); + + step2(); + }); + } + + function step2() { + var inp = testHelper.initNewInput({ + showOn: "button", + buttonText: "Popup" + }), + dp = $( "#ui-datepicker-div" ); + + ok( !dp.is( ":visible" ), "Button - initially hidden" ); + button = inp.siblings( "button" ); + image = inp.siblings( "img" ); + ok( button.length === 1, "Button - button present" ); + ok( image.length === 0, "Button - image absent" ); + equal( button.text(), "Popup", "Button - button text" ); + + testHelper.onFocus( inp, function() { + ok( !dp.is( ":visible" ), "Button - not rendered on focus" ); + button.click(); + ok( dp.is( ":visible" ), "Button - rendered on button click" ); + button.click(); + ok( !dp.is( ":visible" ), "Button - hidden on second button click" ); + inp.datepicker( "hide" ).datepicker( "destroy" ); + + step3(); + }); + } + + function step3() { + var inp = testHelper.initNewInput({ + showOn: "button", + buttonImageOnly: true, + buttonImage: "images/calendar.gif", + buttonText: "Cal" + }), + dp = $( "#ui-datepicker-div" ); + + ok( !dp.is( ":visible" ), "Image button - initially hidden" ); + button = inp.siblings( "button" ); + ok( button.length === 0, "Image button - button absent" ); + image = inp.siblings( "img" ); + ok( image.length === 1, "Image button - image present" ); + ok( /images\/calendar\.gif$/.test( image.attr( "src" ) ), "Image button - image source" ); + equal( image.attr( "title" ), "Cal", "Image button - image text" ); + + testHelper.onFocus( inp, function() { + ok( !dp.is( ":visible" ), "Image button - not rendered on focus" ); + image.click(); + ok( dp.is( ":visible" ), "Image button - rendered on image click" ); + image.click(); + ok( !dp.is( ":visible" ), "Image button - hidden on second image click" ); + inp.datepicker( "hide" ).datepicker( "destroy" ); + + step4(); + }); + } + + function step4() { + var inp = testHelper.initNewInput({ + showOn: "both", + buttonImage: "images/calendar.gif" + }), + dp = $( "#ui-datepicker-div" ); + + ok( !dp.is( ":visible" ), "Both - initially hidden" ); + button = inp.siblings( "button" ); + ok( button.length === 1, "Both - button present" ); + image = inp.siblings( "img" ); + ok( image.length === 0, "Both - image absent" ); + image = button.children( "img" ); + ok( image.length === 1, "Both - button image present" ); + + // TODO: This test occasionally fails to focus in IE8 in BrowserStack + if ( !isOldIE ) { + testHelper.onFocus( inp, function() { + ok( dp.is( ":visible" ), "Both - rendered on focus" ); + body.simulate( "mousedown", {} ); + ok( !dp.is( ":visible" ), "Both - hidden on external click" ); + button.click(); + ok( dp.is( ":visible" ), "Both - rendered on button click" ); + button.click(); + ok( !dp.is( ":visible" ), "Both - hidden on second button click" ); + inp.datepicker( "hide" ).datepicker( "destroy" ); + + start(); + }); + } else { + start(); + } + } + + step0(); + }); +})(); + +test("otherMonths", function() { + expect( 8 ); + var inp = testHelper.init("#inp"), + pop = $("#ui-datepicker-div"); + inp.val("06/01/2009").datepicker("show"); + equal(pop.find("tbody").text(), + // support: IE <9, jQuery <1.8 + // In IE7/8 with jQuery <1.8, encoded spaces behave in strange ways + $( "\u00a0123456789101112131415161718192021222324252627282930\u00a0\u00a0\u00a0\u00a0" ).text(), + "Other months - none"); + ok(pop.find("td:last *").length === 0, "Other months - no content"); + inp.datepicker("hide").datepicker("option", "showOtherMonths", true).datepicker("show"); + equal(pop.find("tbody").text(), "311234567891011121314151617181920212223242526272829301234", + "Other months - show"); + ok(pop.find("td:last span").length === 1, "Other months - span content"); + inp.datepicker("hide").datepicker("option", "selectOtherMonths", true).datepicker("show"); + equal(pop.find("tbody").text(), "311234567891011121314151617181920212223242526272829301234", + "Other months - select"); + ok(pop.find("td:last a").length === 1, "Other months - link content"); + inp.datepicker("hide").datepicker("option", "showOtherMonths", false).datepicker("show"); + equal(pop.find("tbody").text(), + // support: IE <9, jQuery <1.8 + // In IE7/8 with jQuery <1.8, encoded spaces behave in strange ways + $( "\u00a0123456789101112131415161718192021222324252627282930\u00a0\u00a0\u00a0\u00a0" ).text(), + "Other months - none"); + ok(pop.find("td:last *").length === 0, "Other months - no content"); +}); + +test("defaultDate", function() { + expect( 16 ); + var inp = testHelper.init("#inp"), + date = new Date(); + inp.val("").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date null"); + + // Numeric values + inp.datepicker("option", {defaultDate: -2}). + datepicker("hide").val("").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + date.setDate(date.getDate() - 2); + testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date -2"); + + date = new Date(); + inp.datepicker("option", {defaultDate: 3}). + datepicker("hide").val("").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + date.setDate(date.getDate() + 3); + testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date 3"); + + date = new Date(); + inp.datepicker("option", {defaultDate: 1 / "a"}). + datepicker("hide").val("").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date NaN"); + + // String offset values + inp.datepicker("option", {defaultDate: "-1d"}). + datepicker("hide").val("").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + date.setDate(date.getDate() - 1); + testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date -1d"); + inp.datepicker("option", {defaultDate: "+3D"}). + datepicker("hide").val("").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + date.setDate(date.getDate() + 4); + testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date +3D"); + inp.datepicker("option", {defaultDate: " -2 w "}). + datepicker("hide").val("").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + date = new Date(); + date.setDate(date.getDate() - 14); + testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date -2 w"); + inp.datepicker("option", {defaultDate: "+1 W"}). + datepicker("hide").val("").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + date.setDate(date.getDate() + 21); + testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date +1 W"); + inp.datepicker("option", {defaultDate: " -1 m "}). + datepicker("hide").val("").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + date = testHelper.addMonths(new Date(), -1); + testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date -1 m"); + inp.datepicker("option", {defaultDate: "+2M"}). + datepicker("hide").val("").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + date = testHelper.addMonths(new Date(), 2); + testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date +2M"); + inp.datepicker("option", {defaultDate: "-2y"}). + datepicker("hide").val("").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + date = new Date(); + date.setFullYear(date.getFullYear() - 2); + testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date -2y"); + inp.datepicker("option", {defaultDate: "+1 Y "}). + datepicker("hide").val("").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + date.setFullYear(date.getFullYear() + 3); + testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date +1 Y"); + inp.datepicker("option", {defaultDate: "+1M +10d"}). + datepicker("hide").val("").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + date = testHelper.addMonths(new Date(), 1); + date.setDate(date.getDate() + 10); + testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date +1M +10d"); + // String date values + inp.datepicker("option", {defaultDate: "07/04/2007"}). + datepicker("hide").val("").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + date = new Date(2007, 7 - 1, 4); + testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date 07/04/2007"); + inp.datepicker("option", {dateFormat: "yy-mm-dd", defaultDate: "2007-04-02"}). + datepicker("hide").val("").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + date = new Date(2007, 4 - 1, 2); + testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date 2007-04-02"); + // Date value + date = new Date(2007, 1 - 1, 26); + inp.datepicker("option", {dateFormat: "mm/dd/yy", defaultDate: date}). + datepicker("hide").val("").datepicker("show"). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + testHelper.equalsDate(inp.datepicker("getDate"), date, "Default date 01/26/2007"); +}); + +test("miscellaneous", function() { + expect( 19 ); + var curYear, longNames, shortNames, date, + dp = $("#ui-datepicker-div"), + inp = testHelper.init("#inp"); + // Year range + function genRange(start, offset) { + var i = start, + range = ""; + for (; i < start + offset; i++) { + range += i; + } + return range; + } + curYear = new Date().getFullYear(); + inp.val("02/04/2008").datepicker("show"); + equal(dp.find(".ui-datepicker-year").text(), "2008", "Year range - read-only default"); + inp.datepicker("hide").datepicker("option", {changeYear: true}).datepicker("show"); + equal(dp.find(".ui-datepicker-year").text(), genRange(2008 - 10, 21), "Year range - changeable default"); + inp.datepicker("hide").datepicker("option", {yearRange: "c-6:c+2", changeYear: true}).datepicker("show"); + equal(dp.find(".ui-datepicker-year").text(), genRange(2008 - 6, 9), "Year range - c-6:c+2"); + inp.datepicker("hide").datepicker("option", {yearRange: "2000:2010", changeYear: true}).datepicker("show"); + equal(dp.find(".ui-datepicker-year").text(), genRange(2000, 11), "Year range - 2000:2010"); + inp.datepicker("hide").datepicker("option", {yearRange: "-5:+3", changeYear: true}).datepicker("show"); + equal(dp.find(".ui-datepicker-year").text(), genRange(curYear - 5, 9), "Year range - -5:+3"); + inp.datepicker("hide").datepicker("option", {yearRange: "2000:-5", changeYear: true}).datepicker("show"); + equal(dp.find(".ui-datepicker-year").text(), genRange(2000, curYear - 2004), "Year range - 2000:-5"); + inp.datepicker("hide").datepicker("option", {yearRange: "", changeYear: true}).datepicker("show"); + equal(dp.find(".ui-datepicker-year").text(), genRange(curYear, 1), "Year range - -6:+2"); + + // Navigation as date format + inp.datepicker("option", {showButtonPanel: true}); + equal(dp.find(".ui-datepicker-prev").text(), "Prev", "Navigation prev - default"); + equal(dp.find(".ui-datepicker-current").text(), "Today", "Navigation current - default"); + equal(dp.find(".ui-datepicker-next").text(), "Next", "Navigation next - default"); + inp.datepicker("hide").datepicker("option", {navigationAsDateFormat: true, prevText: "< M", currentText: "MM", nextText: "M >"}). + val("02/04/2008").datepicker("show"); + longNames = $.datepicker.regional[""].monthNames; + shortNames = $.datepicker.regional[""].monthNamesShort; + date = new Date(); + equal(dp.find(".ui-datepicker-prev").text(), "< " + shortNames[0], "Navigation prev - as date format"); + equal(dp.find(".ui-datepicker-current").text(), + longNames[date.getMonth()], "Navigation current - as date format"); + equal(dp.find(".ui-datepicker-next").text(), + shortNames[2] + " >", "Navigation next - as date format"); + inp.simulate("keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}); + equal(dp.find(".ui-datepicker-prev").text(), + "< " + shortNames[1], "Navigation prev - as date format + pgdn"); + equal(dp.find(".ui-datepicker-current").text(), + longNames[date.getMonth()], "Navigation current - as date format + pgdn"); + equal(dp.find(".ui-datepicker-next").text(), + shortNames[3] + " >", "Navigation next - as date format + pgdn"); + inp.datepicker("hide").datepicker("option", {gotoCurrent: true}). + val("02/04/2008").datepicker("show"); + equal(dp.find(".ui-datepicker-prev").text(), + "< " + shortNames[0], "Navigation prev - as date format + goto current"); + equal(dp.find(".ui-datepicker-current").text(), + longNames[1], "Navigation current - as date format + goto current"); + equal(dp.find(".ui-datepicker-next").text(), + shortNames[2] + " >", "Navigation next - as date format + goto current"); +}); + +test("minMax", function() { + expect( 23 ); + var date, + inp = testHelper.init("#inp"), + dp = $("#ui-datepicker-div"), + lastYear = new Date(2007, 6 - 1, 4), + nextYear = new Date(2009, 6 - 1, 4), + minDate = new Date(2008, 2 - 1, 29), + maxDate = new Date(2008, 12 - 1, 7); + inp.val("06/04/2008").datepicker("show"); + inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + testHelper.equalsDate(inp.datepicker("getDate"), lastYear, + "Min/max - null, null - ctrl+pgup"); + inp.val("06/04/2008").datepicker("show"); + inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + testHelper.equalsDate(inp.datepicker("getDate"), nextYear, + "Min/max - null, null - ctrl+pgdn"); + inp.datepicker("option", {minDate: minDate}). + datepicker("hide").val("06/04/2008").datepicker("show"); + inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + testHelper.equalsDate(inp.datepicker("getDate"), minDate, + "Min/max - 02/29/2008, null - ctrl+pgup"); + inp.val("06/04/2008").datepicker("show"); + inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + testHelper.equalsDate(inp.datepicker("getDate"), nextYear, + "Min/max - 02/29/2008, null - ctrl+pgdn"); + inp.datepicker("option", {maxDate: maxDate}). + datepicker("hide").val("06/04/2008").datepicker("show"); + inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + testHelper.equalsDate(inp.datepicker("getDate"), minDate, + "Min/max - 02/29/2008, 12/07/2008 - ctrl+pgup"); + inp.val("06/04/2008").datepicker("show"); + inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + testHelper.equalsDate(inp.datepicker("getDate"), maxDate, + "Min/max - 02/29/2008, 12/07/2008 - ctrl+pgdn"); + inp.datepicker("option", {minDate: null}). + datepicker("hide").val("06/04/2008").datepicker("show"); + inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + testHelper.equalsDate(inp.datepicker("getDate"), lastYear, + "Min/max - null, 12/07/2008 - ctrl+pgup"); + inp.val("06/04/2008").datepicker("show"); + inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + testHelper.equalsDate(inp.datepicker("getDate"), maxDate, + "Min/max - null, 12/07/2008 - ctrl+pgdn"); + // Relative dates + date = new Date(); + date.setDate(date.getDate() - 7); + inp.datepicker("option", {minDate: "-1w", maxDate: "+1 M +10 D "}). + datepicker("hide").val("").datepicker("show"); + inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP}). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + testHelper.equalsDate(inp.datepicker("getDate"), date, + "Min/max - -1w, +1 M +10 D - ctrl+pgup"); + date = testHelper.addMonths(new Date(), 1); + date.setDate(date.getDate() + 10); + inp.val("").datepicker("show"); + inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN}). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + testHelper.equalsDate(inp.datepicker("getDate"), date, + "Min/max - -1w, +1 M +10 D - ctrl+pgdn"); + // With existing date + inp = testHelper.init("#inp"); + inp.val("06/04/2008").datepicker("option", {minDate: minDate}); + testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 6 - 1, 4), "Min/max - setDate > min"); + inp.datepicker("option", {minDate: null}).val("01/04/2008").datepicker("option", {minDate: minDate}); + testHelper.equalsDate(inp.datepicker("getDate"), minDate, "Min/max - setDate < min"); + inp.datepicker("option", {minDate: null}).val("06/04/2008").datepicker("option", {maxDate: maxDate}); + testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 6 - 1, 4), "Min/max - setDate < max"); + inp.datepicker("option", {maxDate: null}).val("01/04/2009").datepicker("option", {maxDate: maxDate}); + testHelper.equalsDate(inp.datepicker("getDate"), maxDate, "Min/max - setDate > max"); + inp.datepicker("option", {maxDate: null}).val("01/04/2008").datepicker("option", {minDate: minDate, maxDate: maxDate}); + testHelper.equalsDate(inp.datepicker("getDate"), minDate, "Min/max - setDate < min"); + inp.datepicker("option", {maxDate: null}).val("06/04/2008").datepicker("option", {minDate: minDate, maxDate: maxDate}); + testHelper.equalsDate(inp.datepicker("getDate"), new Date(2008, 6 - 1, 4), "Min/max - setDate > min, < max"); + inp.datepicker("option", {maxDate: null}).val("01/04/2009").datepicker("option", {minDate: minDate, maxDate: maxDate}); + testHelper.equalsDate(inp.datepicker("getDate"), maxDate, "Min/max - setDate > max"); + + inp.datepicker("option", {yearRange: "-0:+1"}).val("01/01/" + new Date().getFullYear()); + ok(dp.find(".ui-datepicker-prev").hasClass("ui-state-disabled"), "Year Range Test - previous button disabled at 1/1/minYear"); + inp.datepicker("setDate", "12/30/" + new Date().getFullYear()); + ok(dp.find(".ui-datepicker-next").hasClass("ui-state-disabled"), "Year Range Test - next button disabled at 12/30/maxYear"); + + inp.datepicker("option", { + minDate: new Date(1900, 0, 1), + maxDate: "-7Y", + yearRange: "1900:-7" + }).val( "" ); + ok(dp.find(".ui-datepicker-next").hasClass("ui-state-disabled"), "Year Range Test - relative - next button disabled"); + ok(!dp.find(".ui-datepicker-prev").hasClass("ui-state-disabled"), "Year Range Test - relative - prev button enabled"); + + inp.datepicker("option", { + minDate: new Date(1900, 0, 1), + maxDate: "1/25/2007", + yearRange: "1900:2007" + }).val( "" ); + ok(dp.find(".ui-datepicker-next").hasClass("ui-state-disabled"), "Year Range Test - absolute - next button disabled"); + ok(!dp.find(".ui-datepicker-prev").hasClass("ui-state-disabled"), "Year Range Test - absolute - prev button enabled"); +}); + +test("setDate", function() { + expect( 24 ); + var inl, alt, minDate, maxDate, dateAndTimeToSet, dateAndTimeClone, + inp = testHelper.init("#inp"), + date1 = new Date(2008, 6 - 1, 4), + date2 = new Date(); + ok(inp.datepicker("getDate") == null, "Set date - default"); + inp.datepicker("setDate", date1); + testHelper.equalsDate(inp.datepicker("getDate"), date1, "Set date - 2008-06-04"); + date1 = new Date(); + date1.setDate(date1.getDate() + 7); + inp.datepicker("setDate", +7); + testHelper.equalsDate(inp.datepicker("getDate"), date1, "Set date - +7"); + date2.setFullYear(date2.getFullYear() + 2); + inp.datepicker("setDate", "+2y"); + testHelper.equalsDate(inp.datepicker("getDate"), date2, "Set date - +2y"); + inp.datepicker("setDate", date1, date2); + testHelper.equalsDate(inp.datepicker("getDate"), date1, "Set date - two dates"); + inp.datepicker("setDate"); + ok(inp.datepicker("getDate") == null, "Set date - null"); + // Relative to current date + date1 = new Date(); + date1.setDate(date1.getDate() + 7); + inp.datepicker("setDate", "c +7"); + testHelper.equalsDate(inp.datepicker("getDate"), date1, "Set date - c +7"); + date1.setDate(date1.getDate() + 7); + inp.datepicker("setDate", "c+7"); + testHelper.equalsDate(inp.datepicker("getDate"), date1, "Set date - c+7"); + date1.setDate(date1.getDate() - 21); + inp.datepicker("setDate", "c -3 w"); + testHelper.equalsDate(inp.datepicker("getDate"), date1, "Set date - c -3 w"); + // Inline + inl = testHelper.init("#inl"); + date1 = new Date(2008, 6 - 1, 4); + date2 = new Date(); + testHelper.equalsDate(inl.datepicker("getDate"), date2, "Set date inline - default"); + inl.datepicker("setDate", date1); + testHelper.equalsDate(inl.datepicker("getDate"), date1, "Set date inline - 2008-06-04"); + date1 = new Date(); + date1.setDate(date1.getDate() + 7); + inl.datepicker("setDate", +7); + testHelper.equalsDate(inl.datepicker("getDate"), date1, "Set date inline - +7"); + date2.setFullYear(date2.getFullYear() + 2); + inl.datepicker("setDate", "+2y"); + testHelper.equalsDate(inl.datepicker("getDate"), date2, "Set date inline - +2y"); + inl.datepicker("setDate", date1, date2); + testHelper.equalsDate(inl.datepicker("getDate"), date1, "Set date inline - two dates"); + inl.datepicker("setDate"); + ok(inl.datepicker("getDate") == null, "Set date inline - null"); + // Alternate field + alt = $("#alt"); + inp.datepicker("option", {altField: "#alt", altFormat: "yy-mm-dd"}); + date1 = new Date(2008, 6 - 1, 4); + inp.datepicker("setDate", date1); + equal(inp.val(), "06/04/2008", "Set date alternate - 06/04/2008"); + equal(alt.val(), "2008-06-04", "Set date alternate - 2008-06-04"); + // With minimum/maximum + inp = testHelper.init("#inp"); + date1 = new Date(2008, 1 - 1, 4); + date2 = new Date(2008, 6 - 1, 4); + minDate = new Date(2008, 2 - 1, 29); + maxDate = new Date(2008, 3 - 1, 28); + inp.val("").datepicker("option", {minDate: minDate}).datepicker("setDate", date2); + testHelper.equalsDate(inp.datepicker("getDate"), date2, "Set date min/max - setDate > min"); + inp.datepicker("setDate", date1); + testHelper.equalsDate(inp.datepicker("getDate"), minDate, "Set date min/max - setDate < min"); + inp.val("").datepicker("option", {maxDate: maxDate, minDate: null}).datepicker("setDate", date1); + testHelper.equalsDate(inp.datepicker("getDate"), date1, "Set date min/max - setDate < max"); + inp.datepicker("setDate", date2); + testHelper.equalsDate(inp.datepicker("getDate"), maxDate, "Set date min/max - setDate > max"); + inp.val("").datepicker("option", {minDate: minDate}).datepicker("setDate", date1); + testHelper.equalsDate(inp.datepicker("getDate"), minDate, "Set date min/max - setDate < min"); + inp.datepicker("setDate", date2); + testHelper.equalsDate(inp.datepicker("getDate"), maxDate, "Set date min/max - setDate > max"); + dateAndTimeToSet = new Date(2008, 3 - 1, 28, 1, 11, 0); + dateAndTimeClone = new Date(2008, 3 - 1, 28, 1, 11, 0); + inp.datepicker("setDate", dateAndTimeToSet); + equal(dateAndTimeToSet.getTime(), dateAndTimeClone.getTime(), "Date object passed should not be changed by setDate"); +}); + +test("altField", function() { + expect( 10 ); + var inp = testHelper.init("#inp"), + alt = $("#alt"); + // No alternate field set + alt.val(""); + inp.val("06/04/2008").datepicker("show"); + inp.simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + equal(inp.val(), "06/04/2008", "Alt field - dp - enter"); + equal(alt.val(), "", "Alt field - alt not set"); + // Alternate field set + alt.val(""); + inp.datepicker("option", {altField: "#alt", altFormat: "yy-mm-dd"}). + val("06/04/2008").datepicker("show"); + inp.simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + equal(inp.val(), "06/04/2008", "Alt field - dp - enter"); + equal(alt.val(), "2008-06-04", "Alt field - alt - enter"); + // Move from initial date + alt.val(""); + inp.val("06/04/2008").datepicker("show"); + inp.simulate("keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}). + simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + equal(inp.val(), "07/04/2008", "Alt field - dp - pgdn"); + equal(alt.val(), "2008-07-04", "Alt field - alt - pgdn"); + // Alternate field set - closed + alt.val(""); + inp.val("06/04/2008").datepicker("show"); + inp.simulate("keydown", {keyCode: $.ui.keyCode.PAGE_DOWN}). + simulate("keydown", {keyCode: $.ui.keyCode.ESCAPE}); + equal(inp.val(), "06/04/2008", "Alt field - dp - pgdn/esc"); + equal(alt.val(), "", "Alt field - alt - pgdn/esc"); + // Clear date and alternate + alt.val(""); + inp.val("06/04/2008").datepicker("show"); + inp.simulate("keydown", {ctrlKey: true, keyCode: $.ui.keyCode.END}); + equal(inp.val(), "", "Alt field - dp - ctrl+end"); + equal(alt.val(), "", "Alt field - alt - ctrl+end"); +}); + +test("autoSize", function() { + expect( 15 ); + var inp = testHelper.init("#inp"); + equal(inp.prop("size"), 20, "Auto size - default"); + inp.datepicker("option", "autoSize", true); + equal(inp.prop("size"), 10, "Auto size - mm/dd/yy"); + inp.datepicker("option", "dateFormat", "m/d/yy"); + equal(inp.prop("size"), 10, "Auto size - m/d/yy"); + inp.datepicker("option", "dateFormat", "D M d yy"); + equal(inp.prop("size"), 15, "Auto size - D M d yy"); + inp.datepicker("option", "dateFormat", "DD, MM dd, yy"); + equal(inp.prop("size"), 29, "Auto size - DD, MM dd, yy"); + + // French + inp.datepicker("option", $.extend({autoSize: false}, $.datepicker.regional.fr)); + equal(inp.prop("size"), 29, "Auto size - fr - default"); + inp.datepicker("option", "autoSize", true); + equal(inp.prop("size"), 10, "Auto size - fr - dd/mm/yy"); + inp.datepicker("option", "dateFormat", "m/d/yy"); + equal(inp.prop("size"), 10, "Auto size - fr - m/d/yy"); + inp.datepicker("option", "dateFormat", "D M d yy"); + equal(inp.prop("size"), 18, "Auto size - fr - D M d yy"); + inp.datepicker("option", "dateFormat", "DD, MM dd, yy"); + equal(inp.prop("size"), 28, "Auto size - fr - DD, MM dd, yy"); + + // Hebrew + inp.datepicker("option", $.extend({autoSize: false}, $.datepicker.regional.he)); + equal(inp.prop("size"), 28, "Auto size - he - default"); + inp.datepicker("option", "autoSize", true); + equal(inp.prop("size"), 10, "Auto size - he - dd/mm/yy"); + inp.datepicker("option", "dateFormat", "m/d/yy"); + equal(inp.prop("size"), 10, "Auto size - he - m/d/yy"); + inp.datepicker("option", "dateFormat", "D M d yy"); + equal(inp.prop("size"), 16, "Auto size - he - D M d yy"); + inp.datepicker("option", "dateFormat", "DD, MM dd, yy"); + equal(inp.prop("size"), 23, "Auto size - he - DD, MM dd, yy"); +}); + +test("daylightSaving", function() { + expect( 25 ); + var inp = testHelper.init("#inp"), + dp = $("#ui-datepicker-div"); + ok(true, "Daylight saving - " + new Date()); + // Australia, Sydney - AM change, southern hemisphere + inp.val("04/01/2008").datepicker("show"); + $(".ui-datepicker-calendar td:eq(6) a", dp).simulate("click"); + equal(inp.val(), "04/05/2008", "Daylight saving - Australia 04/05/2008"); + inp.val("04/01/2008").datepicker("show"); + $(".ui-datepicker-calendar td:eq(7) a", dp).simulate("click"); + equal(inp.val(), "04/06/2008", "Daylight saving - Australia 04/06/2008"); + inp.val("04/01/2008").datepicker("show"); + $(".ui-datepicker-calendar td:eq(8) a", dp).simulate("click"); + equal(inp.val(), "04/07/2008", "Daylight saving - Australia 04/07/2008"); + inp.val("10/01/2008").datepicker("show"); + $(".ui-datepicker-calendar td:eq(6) a", dp).simulate("click"); + equal(inp.val(), "10/04/2008", "Daylight saving - Australia 10/04/2008"); + inp.val("10/01/2008").datepicker("show"); + $(".ui-datepicker-calendar td:eq(7) a", dp).simulate("click"); + equal(inp.val(), "10/05/2008", "Daylight saving - Australia 10/05/2008"); + inp.val("10/01/2008").datepicker("show"); + $(".ui-datepicker-calendar td:eq(8) a", dp).simulate("click"); + equal(inp.val(), "10/06/2008", "Daylight saving - Australia 10/06/2008"); + // Brasil, Brasilia - midnight change, southern hemisphere + inp.val("02/01/2008").datepicker("show"); + $(".ui-datepicker-calendar td:eq(20) a", dp).simulate("click"); + equal(inp.val(), "02/16/2008", "Daylight saving - Brasil 02/16/2008"); + inp.val("02/01/2008").datepicker("show"); + $(".ui-datepicker-calendar td:eq(21) a", dp).simulate("click"); + equal(inp.val(), "02/17/2008", "Daylight saving - Brasil 02/17/2008"); + inp.val("02/01/2008").datepicker("show"); + $(".ui-datepicker-calendar td:eq(22) a", dp).simulate("click"); + equal(inp.val(), "02/18/2008", "Daylight saving - Brasil 02/18/2008"); + inp.val("10/01/2008").datepicker("show"); + $(".ui-datepicker-calendar td:eq(13) a", dp).simulate("click"); + equal(inp.val(), "10/11/2008", "Daylight saving - Brasil 10/11/2008"); + inp.val("10/01/2008").datepicker("show"); + $(".ui-datepicker-calendar td:eq(14) a", dp).simulate("click"); + equal(inp.val(), "10/12/2008", "Daylight saving - Brasil 10/12/2008"); + inp.val("10/01/2008").datepicker("show"); + $(".ui-datepicker-calendar td:eq(15) a", dp).simulate("click"); + equal(inp.val(), "10/13/2008", "Daylight saving - Brasil 10/13/2008"); + // Lebanon, Beirut - midnight change, northern hemisphere + inp.val("03/01/2008").datepicker("show"); + $(".ui-datepicker-calendar td:eq(34) a", dp).simulate("click"); + equal(inp.val(), "03/29/2008", "Daylight saving - Lebanon 03/29/2008"); + inp.val("03/01/2008").datepicker("show"); + $(".ui-datepicker-calendar td:eq(35) a", dp).simulate("click"); + equal(inp.val(), "03/30/2008", "Daylight saving - Lebanon 03/30/2008"); + inp.val("03/01/2008").datepicker("show"); + $(".ui-datepicker-calendar td:eq(36) a", dp).simulate("click"); + equal(inp.val(), "03/31/2008", "Daylight saving - Lebanon 03/31/2008"); + inp.val("10/01/2008").datepicker("show"); + $(".ui-datepicker-calendar td:eq(27) a", dp).simulate("click"); + equal(inp.val(), "10/25/2008", "Daylight saving - Lebanon 10/25/2008"); + inp.val("10/01/2008").datepicker("show"); + $(".ui-datepicker-calendar td:eq(28) a", dp).simulate("click"); + equal(inp.val(), "10/26/2008", "Daylight saving - Lebanon 10/26/2008"); + inp.val("10/01/2008").datepicker("show"); + $(".ui-datepicker-calendar td:eq(29) a", dp).simulate("click"); + equal(inp.val(), "10/27/2008", "Daylight saving - Lebanon 10/27/2008"); + // US, Eastern - AM change, northern hemisphere + inp.val("03/01/2008").datepicker("show"); + $(".ui-datepicker-calendar td:eq(13) a", dp).simulate("click"); + equal(inp.val(), "03/08/2008", "Daylight saving - US 03/08/2008"); + inp.val("03/01/2008").datepicker("show"); + $(".ui-datepicker-calendar td:eq(14) a", dp).simulate("click"); + equal(inp.val(), "03/09/2008", "Daylight saving - US 03/09/2008"); + inp.val("03/01/2008").datepicker("show"); + $(".ui-datepicker-calendar td:eq(15) a", dp).simulate("click"); + equal(inp.val(), "03/10/2008", "Daylight saving - US 03/10/2008"); + inp.val("11/01/2008").datepicker("show"); + $(".ui-datepicker-calendar td:eq(6) a", dp).simulate("click"); + equal(inp.val(), "11/01/2008", "Daylight saving - US 11/01/2008"); + inp.val("11/01/2008").datepicker("show"); + $(".ui-datepicker-calendar td:eq(7) a", dp).simulate("click"); + equal(inp.val(), "11/02/2008", "Daylight saving - US 11/02/2008"); + inp.val("11/01/2008").datepicker("show"); + $(".ui-datepicker-calendar td:eq(8) a", dp).simulate("click"); + equal(inp.val(), "11/03/2008", "Daylight saving - US 11/03/2008"); +}); + +var beforeShowThis = null, + beforeShowInput = null, + beforeShowInst = null, + beforeShowDayThis = null, + beforeShowDayOK = true; + +function beforeAll(input, inst) { + beforeShowThis = this; + beforeShowInput = input; + beforeShowInst = inst; + return {currentText: "Current"}; +} + +function beforeDay(date) { + beforeShowDayThis = this; + beforeShowDayOK &= (date > new Date(2008, 1 - 1, 26) && + date < new Date(2008, 3 - 1, 6)); + return [(date.getDate() % 2 === 0), (date.getDate() % 10 === 0 ? "day10" : ""), + (date.getDate() % 3 === 0 ? "Divisble by 3" : "")]; +} + +test("callbacks", function() { + expect( 13 ); + // Before show + var dp, day20, day21, + inp = testHelper.init("#inp", {beforeShow: beforeAll}), + inst = $.data(inp[0], "datepicker"); + equal($.datepicker._get(inst, "currentText"), "Today", "Before show - initial"); + inp.val("02/04/2008").datepicker("show"); + equal($.datepicker._get(inst, "currentText"), "Current", "Before show - changed"); + ok(beforeShowThis.id === inp[0].id, "Before show - this OK"); + ok(beforeShowInput.id === inp[0].id, "Before show - input OK"); + deepEqual(beforeShowInst, inst, "Before show - inst OK"); + inp.datepicker("hide").datepicker("destroy"); + // Before show day + inp = testHelper.init("#inp", {beforeShowDay: beforeDay}); + dp = $("#ui-datepicker-div"); + inp.val("02/04/2008").datepicker("show"); + ok(beforeShowDayThis.id === inp[0].id, "Before show day - this OK"); + ok(beforeShowDayOK, "Before show day - dates OK"); + day20 = dp.find(".ui-datepicker-calendar td:contains('20')"); + day21 = dp.find(".ui-datepicker-calendar td:contains('21')"); + ok(!day20.is(".ui-datepicker-unselectable"), "Before show day - unselectable 20"); + ok(day21.is(".ui-datepicker-unselectable"), "Before show day - unselectable 21"); + ok(day20.is(".day10"), "Before show day - CSS 20"); + ok(!day21.is(".day10"), "Before show day - CSS 21"); + ok(!day20.attr("title"), "Before show day - title 20"); + ok(day21.attr("title") === "Divisble by 3", "Before show day - title 21"); + inp.datepicker("hide").datepicker("destroy"); +}); + +test("beforeShowDay - tooltips with quotes", function() { + expect( 1 ); + var inp, dp; + inp = testHelper.init("#inp", { + beforeShowDay: function() { + return [ true, "", "'" ]; + } + }); + dp = $("#ui-datepicker-div"); + + inp.datepicker("show"); + equal( dp.find( ".ui-datepicker-calendar td:contains('9')").attr( "title" ), "'" ); + inp.datepicker("hide").datepicker("destroy"); +}); + +test("localisation", function() { + expect( 24 ); + var dp, month, day, date, + inp = testHelper.init("#inp", $.datepicker.regional.fr); + inp.datepicker("option", {dateFormat: "DD, d MM yy", showButtonPanel:true, changeMonth:true, changeYear:true}).val("").datepicker("show"); + dp = $("#ui-datepicker-div"); + equal($(".ui-datepicker-close", dp).text(), "Fermer", "Localisation - close"); + $(".ui-datepicker-close", dp).simulate("mouseover"); + equal($(".ui-datepicker-prev", dp).text(), "Précédent", "Localisation - previous"); + equal($(".ui-datepicker-current", dp).text(), "Aujourd'hui", "Localisation - current"); + equal($(".ui-datepicker-next", dp).text(), "Suivant", "Localisation - next"); + month = 0; + $(".ui-datepicker-month option", dp).each(function() { + equal($(this).text(), $.datepicker.regional.fr.monthNamesShort[month], + "Localisation - month " + month); + month++; + }); + day = 1; + $(".ui-datepicker-calendar th", dp).each(function() { + equal($(this).text(), $.datepicker.regional.fr.dayNamesMin[day], + "Localisation - day " + day); + day = (day + 1) % 7; + }); + inp.simulate("keydown", {keyCode: $.ui.keyCode.ENTER}); + date = new Date(); + equal(inp.val(), $.datepicker.regional.fr.dayNames[date.getDay()] + ", " + + date.getDate() + " " + $.datepicker.regional.fr.monthNames[date.getMonth()] + + " " + date.getFullYear(), "Localisation - formatting"); +}); + +test("noWeekends", function() { + expect( 31 ); + var i, date; + for (i = 1; i <= 31; i++) { + date = new Date(2001, 1 - 1, i); + deepEqual($.datepicker.noWeekends(date), [(i + 1) % 7 >= 2, ""], + "No weekends " + date); + } +}); + +test("iso8601Week", function() { + expect( 12 ); + var date = new Date(2000, 12 - 1, 31); + equal($.datepicker.iso8601Week(date), 52, "ISO 8601 week " + date); + date = new Date(2001, 1 - 1, 1); + equal($.datepicker.iso8601Week(date), 1, "ISO 8601 week " + date); + date = new Date(2001, 1 - 1, 7); + equal($.datepicker.iso8601Week(date), 1, "ISO 8601 week " + date); + date = new Date(2001, 1 - 1, 8); + equal($.datepicker.iso8601Week(date), 2, "ISO 8601 week " + date); + date = new Date(2003, 12 - 1, 28); + equal($.datepicker.iso8601Week(date), 52, "ISO 8601 week " + date); + date = new Date(2003, 12 - 1, 29); + equal($.datepicker.iso8601Week(date), 1, "ISO 8601 week " + date); + date = new Date(2004, 1 - 1, 4); + equal($.datepicker.iso8601Week(date), 1, "ISO 8601 week " + date); + date = new Date(2004, 1 - 1, 5); + equal($.datepicker.iso8601Week(date), 2, "ISO 8601 week " + date); + date = new Date(2009, 12 - 1, 28); + equal($.datepicker.iso8601Week(date), 53, "ISO 8601 week " + date); + date = new Date(2010, 1 - 1, 3); + equal($.datepicker.iso8601Week(date), 53, "ISO 8601 week " + date); + date = new Date(2010, 1 - 1, 4); + equal($.datepicker.iso8601Week(date), 1, "ISO 8601 week " + date); + date = new Date(2010, 1 - 1, 10); + equal($.datepicker.iso8601Week(date), 1, "ISO 8601 week " + date); +}); + +test("parseDate", function() { + expect( 26 ); + testHelper.init("#inp"); + var currentYear, gmtDate, fr, settings, zh; + ok($.datepicker.parseDate("d m y", "") == null, "Parse date empty"); + testHelper.equalsDate($.datepicker.parseDate("d m y", "3 2 01"), + new Date(2001, 2 - 1, 3), "Parse date d m y"); + testHelper.equalsDate($.datepicker.parseDate("dd mm yy", "03 02 2001"), + new Date(2001, 2 - 1, 3), "Parse date dd mm yy"); + testHelper.equalsDate($.datepicker.parseDate("d m y", "13 12 01"), + new Date(2001, 12 - 1, 13), "Parse date d m y"); + testHelper.equalsDate($.datepicker.parseDate("dd mm yy", "13 12 2001"), + new Date(2001, 12 - 1, 13), "Parse date dd mm yy"); + testHelper.equalsDate($.datepicker.parseDate("y-o", "01-34"), + new Date(2001, 2 - 1, 3), "Parse date y-o"); + testHelper.equalsDate($.datepicker.parseDate("yy-oo", "2001-347"), + new Date(2001, 12 - 1, 13), "Parse date yy-oo"); + testHelper.equalsDate($.datepicker.parseDate("oo yy", "348 2004"), + new Date(2004, 12 - 1, 13), "Parse date oo yy"); + testHelper.equalsDate($.datepicker.parseDate("D d M y", "Sat 3 Feb 01"), + new Date(2001, 2 - 1, 3), "Parse date D d M y"); + testHelper.equalsDate($.datepicker.parseDate("d MM DD yy", "3 February Saturday 2001"), + new Date(2001, 2 - 1, 3), "Parse date dd MM DD yy"); + testHelper.equalsDate($.datepicker.parseDate("DD, MM d, yy", "Saturday, February 3, 2001"), + new Date(2001, 2 - 1, 3), "Parse date DD, MM d, yy"); + testHelper.equalsDate($.datepicker.parseDate("'day' d 'of' MM (''DD''), yy", + "day 3 of February ('Saturday'), 2001"), new Date(2001, 2 - 1, 3), + "Parse date 'day' d 'of' MM (''DD''), yy"); + currentYear = new Date().getFullYear(); + testHelper.equalsDate($.datepicker.parseDate("y-m-d", (currentYear - 2000) + "-02-03"), + new Date(currentYear, 2 - 1, 3), "Parse date y-m-d - default cutuff"); + testHelper.equalsDate($.datepicker.parseDate("y-m-d", (currentYear - 2000 + 10) + "-02-03"), + new Date(currentYear+10, 2 - 1, 3), "Parse date y-m-d - default cutuff"); + testHelper.equalsDate($.datepicker.parseDate("y-m-d", (currentYear - 2000 + 11) + "-02-03"), + new Date(currentYear-89, 2 - 1, 3), "Parse date y-m-d - default cutuff"); + testHelper.equalsDate($.datepicker.parseDate("y-m-d", "80-02-03", {shortYearCutoff: 80}), + new Date(2080, 2 - 1, 3), "Parse date y-m-d - cutoff 80"); + testHelper.equalsDate($.datepicker.parseDate("y-m-d", "81-02-03", {shortYearCutoff: 80}), + new Date(1981, 2 - 1, 3), "Parse date y-m-d - cutoff 80"); + testHelper.equalsDate($.datepicker.parseDate("y-m-d", (currentYear - 2000 + 60) + "-02-03", {shortYearCutoff: "+60"}), + new Date(currentYear + 60, 2 - 1, 3), "Parse date y-m-d - cutoff +60"); + testHelper.equalsDate($.datepicker.parseDate("y-m-d", (currentYear - 2000 + 61) + "-02-03", {shortYearCutoff: "+60"}), + new Date(currentYear - 39, 2 - 1, 3), "Parse date y-m-d - cutoff +60"); + gmtDate = new Date(2001, 2 - 1, 3); + gmtDate.setMinutes(gmtDate.getMinutes() - gmtDate.getTimezoneOffset()); + testHelper.equalsDate($.datepicker.parseDate("@", "981158400000"), gmtDate, "Parse date @"); + testHelper.equalsDate($.datepicker.parseDate("!", "631167552000000000"), gmtDate, "Parse date !"); + + fr = $.datepicker.regional.fr; + settings = {dayNamesShort: fr.dayNamesShort, dayNames: fr.dayNames, + monthNamesShort: fr.monthNamesShort, monthNames: fr.monthNames}; + testHelper.equalsDate($.datepicker.parseDate("D d M y", "Lun. 9 avr. 01", settings), + new Date(2001, 4 - 1, 9), "Parse date D M y with settings"); + testHelper.equalsDate($.datepicker.parseDate("d MM DD yy", "9 Avril Lundi 2001", settings), + new Date(2001, 4 - 1, 9), "Parse date d MM DD yy with settings"); + testHelper.equalsDate($.datepicker.parseDate("DD, MM d, yy", "Lundi, Avril 9, 2001", settings), + new Date(2001, 4 - 1, 9), "Parse date DD, MM d, yy with settings"); + testHelper.equalsDate($.datepicker.parseDate("'jour' d 'de' MM (''DD''), yy", "jour 9 de Avril ('Lundi'), 2001", settings), + new Date(2001, 4 - 1, 9), "Parse date 'jour' d 'de' MM (''DD''), yy with settings"); + + zh = $.datepicker.regional["zh-CN"]; + testHelper.equalsDate($.datepicker.parseDate("yy M d", "2011 十一月 22", zh), + new Date(2011, 11 - 1, 22), "Parse date yy M d with zh-CN"); +}); + +test("parseDateErrors", function() { + expect( 18 ); + testHelper.init("#inp"); + var fr, settings; + function expectError(expr, value, error) { + try { + expr(); + ok(false, "Parsed error " + value); + } + catch (e) { + equal(e, error, "Parsed error " + value); + } + } + expectError(function() { $.datepicker.parseDate(null, "Sat 2 01"); }, + "Sat 2 01", "Invalid arguments"); + expectError(function() { $.datepicker.parseDate("d m y", null); }, + "null", "Invalid arguments"); + expectError(function() { $.datepicker.parseDate("d m y", "Sat 2 01"); }, + "Sat 2 01 - d m y", "Missing number at position 0"); + expectError(function() { $.datepicker.parseDate("dd mm yy", "Sat 2 01"); }, + "Sat 2 01 - dd mm yy", "Missing number at position 0"); + expectError(function() { $.datepicker.parseDate("d m y", "3 Feb 01"); }, + "3 Feb 01 - d m y", "Missing number at position 2"); + expectError(function() { $.datepicker.parseDate("dd mm yy", "3 Feb 01"); }, + "3 Feb 01 - dd mm yy", "Missing number at position 2"); + expectError(function() { $.datepicker.parseDate("mm dd yy", "2 1 01"); }, + "2 1 01 - dd mm yy", "Missing number at position 4"); + expectError(function() { $.datepicker.parseDate("d m y", "3 2 AD01"); }, + "3 2 AD01 - d m y", "Missing number at position 4"); + expectError(function() { $.datepicker.parseDate("d m yy", "3 2 AD01"); }, + "3 2 AD01 - dd mm yy", "Missing number at position 4"); + expectError(function() { $.datepicker.parseDate("y-o", "01-D01"); }, + "2001-D01 - y-o", "Missing number at position 3"); + expectError(function() { $.datepicker.parseDate("yy-oo", "2001-D01"); }, + "2001-D01 - yy-oo", "Missing number at position 5"); + expectError(function() { $.datepicker.parseDate("D d M y", "D7 3 Feb 01"); }, + "D7 3 Feb 01 - D d M y", "Unknown name at position 0"); + expectError(function() { $.datepicker.parseDate("D d M y", "Sat 3 M2 01"); }, + "Sat 3 M2 01 - D d M y", "Unknown name at position 6"); + expectError(function() { $.datepicker.parseDate("DD, MM d, yy", "Saturday- Feb 3, 2001"); }, + "Saturday- Feb 3, 2001 - DD, MM d, yy", "Unexpected literal at position 8"); + expectError(function() { $.datepicker.parseDate("'day' d 'of' MM (''DD''), yy", + "day 3 of February (\"Saturday\"), 2001"); }, + "day 3 of Mon2 ('Day7'), 2001", "Unexpected literal at position 19"); + expectError(function() { $.datepicker.parseDate("d m y", "29 2 01"); }, + "29 2 01 - d m y", "Invalid date"); + fr = $.datepicker.regional.fr; + settings = {dayNamesShort: fr.dayNamesShort, dayNames: fr.dayNames, + monthNamesShort: fr.monthNamesShort, monthNames: fr.monthNames}; + expectError(function() { $.datepicker.parseDate("D d M y", "Mon 9 Avr 01", settings); }, + "Mon 9 Avr 01 - D d M y", "Unknown name at position 0"); + expectError(function() { $.datepicker.parseDate("D d M y", "Lun. 9 Apr 01", settings); }, + "Lun. 9 Apr 01 - D d M y", "Unknown name at position 7"); +}); + +test("Ticket #7244: date parser does not fail when too many numbers are passed into the date function", function() { + expect( 4 ); + var date; + try{ + date = $.datepicker.parseDate("dd/mm/yy", "18/04/19881"); + ok(false, "Did not properly detect an invalid date"); + }catch(e){ + ok("invalid date detected"); + } + + try { + date = $.datepicker.parseDate("dd/mm/yy", "18/04/1988 @ 2:43 pm"); + equal(date.getDate(), 18); + equal(date.getMonth(), 3); + equal(date.getFullYear(), 1988); + } catch(e) { + ok(false, "Did not properly parse date with extra text separated by whitespace"); + } +}); + +test("formatDate", function() { + expect( 16 ); + testHelper.init("#inp"); + var gmtDate, fr, settings; + equal($.datepicker.formatDate("d m y", new Date(2001, 2 - 1, 3)), + "3 2 01", "Format date d m y"); + equal($.datepicker.formatDate("dd mm yy", new Date(2001, 2 - 1, 3)), + "03 02 2001", "Format date dd mm yy"); + equal($.datepicker.formatDate("d m y", new Date(2001, 12 - 1, 13)), + "13 12 01", "Format date d m y"); + equal($.datepicker.formatDate("dd mm yy", new Date(2001, 12 - 1, 13)), + "13 12 2001", "Format date dd mm yy"); + equal($.datepicker.formatDate("yy-o", new Date(2001, 2 - 1, 3)), + "2001-34", "Format date yy-o"); + equal($.datepicker.formatDate("yy-oo", new Date(2001, 2 - 1, 3)), + "2001-034", "Format date yy-oo"); + equal($.datepicker.formatDate("D M y", new Date(2001, 2 - 1, 3)), + "Sat Feb 01", "Format date D M y"); + equal($.datepicker.formatDate("DD MM yy", new Date(2001, 2 - 1, 3)), + "Saturday February 2001", "Format date DD MM yy"); + equal($.datepicker.formatDate("DD, MM d, yy", new Date(2001, 2 - 1, 3)), + "Saturday, February 3, 2001", "Format date DD, MM d, yy"); + equal($.datepicker.formatDate("'day' d 'of' MM (''DD''), yy", + new Date(2001, 2 - 1, 3)), "day 3 of February ('Saturday'), 2001", + "Format date 'day' d 'of' MM ('DD'), yy"); + gmtDate = new Date(2001, 2 - 1, 3); + gmtDate.setMinutes(gmtDate.getMinutes() - gmtDate.getTimezoneOffset()); + equal($.datepicker.formatDate("@", gmtDate), "981158400000", "Format date @"); + equal($.datepicker.formatDate("!", gmtDate), "631167552000000000", "Format date !"); + fr = $.datepicker.regional.fr; + settings = {dayNamesShort: fr.dayNamesShort, dayNames: fr.dayNames, + monthNamesShort: fr.monthNamesShort, monthNames: fr.monthNames}; + equal($.datepicker.formatDate("D M y", new Date(2001, 4 - 1, 9), settings), + "lun. avr. 01", "Format date D M y with settings"); + equal($.datepicker.formatDate("DD MM yy", new Date(2001, 4 - 1, 9), settings), + "lundi avril 2001", "Format date DD MM yy with settings"); + equal($.datepicker.formatDate("DD, MM d, yy", new Date(2001, 4 - 1, 9), settings), + "lundi, avril 9, 2001", "Format date DD, MM d, yy with settings"); + equal($.datepicker.formatDate("'jour' d 'de' MM (''DD''), yy", + new Date(2001, 4 - 1, 9), settings), "jour 9 de avril ('lundi'), 2001", + "Format date 'jour' d 'de' MM (''DD''), yy with settings"); +}); + +// TODO: Fix this test so it isn't mysteriously flaky in Browserstack on certain OS/Browser combos +// test("Ticket 6827: formatDate day of year calculation is wrong during day lights savings time", function(){ +// expect( 1 ); +// var time = $.datepicker.formatDate("oo", new Date("2010/03/30 12:00:00 CDT")); +// equal(time, "089"); +// }); + +test( "Ticket 7602: Stop datepicker from appearing with beforeShow event handler", function() { + expect( 3 ); + + var inp, dp; + + inp = testHelper.init( "#inp", { + beforeShow: function() { + } + }); + dp = $( "#ui-datepicker-div" ); + inp.datepicker( "show" ); + equal( dp.css( "display" ), "block", "beforeShow returns nothing" ); + inp.datepicker( "hide" ).datepicker( "destroy" ); + + inp = testHelper.init( "#inp", { + beforeShow: function() { + return true; + } + }); + dp = $( "#ui-datepicker-div" ); + inp.datepicker( "show" ); + equal( dp.css( "display" ), "block", "beforeShow returns true" ); + inp.datepicker( "hide" ); + inp.datepicker( "destroy" ); + + inp = testHelper.init( "#inp", { + beforeShow: function() { + return false; + } + }); + dp = $( "#ui-datepicker-div" ); + inp.datepicker( "show" ); + equal( dp.css( "display" ), "none","beforeShow returns false" ); + inp.datepicker( "destroy" ); +}); + +} ); diff --git a/tests/unit/dialog/common-deprecated.js b/tests/unit/dialog/common-deprecated.js new file mode 100644 index 000000000..7b0091277 --- /dev/null +++ b/tests/unit/dialog/common-deprecated.js @@ -0,0 +1,54 @@ +define( [ + "lib/common", + "ui/dialog" +], function( common ) { + +common.testWidget( "dialog", { + defaults: { + appendTo: "body", + autoOpen: true, + buttons: [], + classes: { + "ui-dialog": "ui-corner-all", + "ui-dialog-titlebar": "ui-corner-all" + }, + closeOnEscape: true, + closeText: "Close", + dialogClass: "", + disabled: false, + draggable: true, + height: "auto", + hide: null, + maxHeight: null, + maxWidth: null, + minHeight: 150, + minWidth: 150, + modal: false, + position: { + my: "center", + at: "center", + of: window, + collision: "fit", + using: $.ui.dialog.prototype.options.position.using + }, + resizable: true, + show: null, + title: null, + width: 300, + + // callbacks + beforeClose: null, + close: null, + create: null, + drag: null, + dragStart: null, + dragStop: null, + focus: null, + open: null, + resize: null, + resizeStart: null, + resizeStop: null + } +}); + +} ); diff --git a/tests/unit/dialog/common.js b/tests/unit/dialog/common.js new file mode 100644 index 000000000..389b2ddff --- /dev/null +++ b/tests/unit/dialog/common.js @@ -0,0 +1,53 @@ +define( [ + "lib/common", + "ui/dialog" +], function( common ) { + +common.testWidget( "dialog", { + defaults: { + appendTo: "body", + autoOpen: true, + buttons: [], + classes: { + "ui-dialog": "ui-corner-all", + "ui-dialog-titlebar": "ui-corner-all" + }, + closeOnEscape: true, + closeText: "Close", + disabled: false, + draggable: true, + height: "auto", + hide: null, + maxHeight: null, + maxWidth: null, + minHeight: 150, + minWidth: 150, + modal: false, + position: { + my: "center", + at: "center", + of: window, + collision: "fit", + using: $.ui.dialog.prototype.options.position.using + }, + resizable: true, + show: null, + title: null, + width: 300, + + // callbacks + beforeClose: null, + close: null, + create: null, + drag: null, + dragStart: null, + dragStop: null, + focus: null, + open: null, + resize: null, + resizeStart: null, + resizeStop: null + } +}); + +} ); diff --git a/tests/unit/dialog/core.js b/tests/unit/dialog/core.js new file mode 100644 index 000000000..cb086ce8d --- /dev/null +++ b/tests/unit/dialog/core.js @@ -0,0 +1,308 @@ +define( [ + "jquery", + "ui/dialog" +], function( $ ) { + +// TODO add teardown callback to remove dialogs +module("dialog: core"); + +test( "markup structure", function( assert ) { + expect( 11 ); + + var element = $( "
" ).dialog({ + buttons: [ { + text: "Ok", + click: $.noop + } ] + }), + widget = element.dialog( "widget" ), + titlebar = widget.find( ".ui-dialog-titlebar" ), + title = titlebar.find( ".ui-dialog-title" ), + close = titlebar.find( ".ui-dialog-titlebar-close" ), + buttonpane = widget.find( ".ui-dialog-buttonpane" ), + buttonset = widget.find( ".ui-dialog-buttonset" ), + buttons = buttonset.find( ".ui-button" ); + + assert.hasClasses( widget, "ui-dialog ui-dialog-buttons ui-widget ui-widget-content" ); + assert.hasClasses( titlebar, "ui-dialog-titlebar ui-widget-header" ); + equal( titlebar.length, 1, "Dialog has exactly one titlebar" ); + assert.hasClasses( close, "ui-dialog-titlebar-close ui-widget" ); + equal( close.length, 1, "Titlebar has exactly one close button" ); + equal( title.length, 1, "Titlebar has exactly one title" ); + assert.hasClasses( element, "ui-dialog-content ui-widget-content" ); + assert.hasClasses( buttonpane, "ui-dialog-buttonpane ui-widget-content" ); + equal( buttonpane.length, 1, "Dialog has exactly one buttonpane" ); + equal( buttonset.length, 1, "Buttonpane has exactly one buttonset" ); + equal( buttons.length, 1, "Buttonset contains exactly 1 button when created with 1" ); + +}); + +test( "markup structure - no buttons", function( assert ) { + expect( 7 ); + + var element = $( "
" ).dialog(), + widget = element.dialog( "widget" ), + titlebar = widget.find( ".ui-dialog-titlebar" ), + title = titlebar.find( ".ui-dialog-title" ), + close = titlebar.find( ".ui-dialog-titlebar-close" ); + + assert.hasClasses( widget, "ui-dialog ui-widget ui-widget-content" ); + assert.hasClasses( titlebar, "ui-dialog-titlebar ui-widget-header" ); + equal( titlebar.length, 1, "Dialog has exactly one titlebar" ); + assert.hasClasses( close, "ui-dialog-titlebar-close ui-widget" ); + equal( close.length, 1, "Titlebar has exactly one close button" ); + equal( title.length, 1, "Titlebar has exactly one title" ); + assert.hasClasses( element, "ui-dialog-content ui-widget-content" ); +}); + +test("title id", function() { + expect(1); + + var titleId, + element = $("
").dialog(); + + titleId = element.dialog("widget").find(".ui-dialog-title").attr("id"); + ok( /ui-id-\d+$/.test( titleId ), "auto-numbered title id"); + element.remove(); +}); + +test( "ARIA", function() { + expect( 4 ); + + var element = $( "
" ).dialog(), + wrapper = element.dialog( "widget" ); + equal( wrapper.attr( "role" ), "dialog", "dialog role" ); + equal( wrapper.attr( "aria-labelledby" ), wrapper.find( ".ui-dialog-title" ).attr( "id" ) ); + equal( wrapper.attr( "aria-describedby" ), element.attr( "id" ), "aria-describedby added" ); + element.remove(); + + element = $("

descriotion

").dialog(); + equal( element.dialog( "widget" ).attr( "aria-describedby" ), null, "no aria-describedby added, as already present in markup" ); + element.remove(); +}); + +test("widget method", function() { + expect( 1 ); + var dialog = $("
").appendTo("#qunit-fixture").dialog(); + deepEqual(dialog.parent()[0], dialog.dialog("widget")[0]); + dialog.remove(); +}); + +asyncTest( "focus tabbable", function() { + expect( 8 ); + var element, + options = { + buttons: [{ + text: "Ok", + click: $.noop + }] + }; + + function checkFocus( markup, options, testFn, next ) { + + // Support: IE8 + // For some reason the focus doesn't get set properly if we don't + // focus the body first. + $( "body" ).focus(); + + element = $( markup ).dialog( options ); + setTimeout(function() { + testFn(function done() { + element.remove(); + setTimeout( next ); + }); + }); + } + + function step1() { + checkFocus( "
", options, function( done ) { + var input = element.find( "input:last" ).focus().blur(); + element.dialog( "instance" )._focusTabbable(); + setTimeout(function() { + equal( document.activeElement, input[ 0 ], + "1. an element that was focused previously." ); + done(); + }); + }, step2 ); + } + + function step2() { + checkFocus( "
", options, function( done ) { + equal( document.activeElement, element.find( "input" )[ 1 ], + "2. first element inside the dialog matching [autofocus]" ); + done(); + }, step3 ); + } + + function step3() { + checkFocus( "
", options, function( done ) { + equal( document.activeElement, element.find( "input" )[ 0 ], + "3. tabbable element inside the content element" ); + done(); + }, step4 ); + } + + function step4() { + checkFocus( "
text
", options, function( done ) { + equal( document.activeElement, + element.dialog( "widget" ).find( ".ui-dialog-buttonpane button" )[ 0 ], + "4. tabbable element inside the buttonpane" ); + done(); + }, step5 ); + } + + function step5() { + checkFocus( "
text
", {}, function( done ) { + equal( document.activeElement, + element.dialog( "widget" ).find( ".ui-dialog-titlebar .ui-dialog-titlebar-close" )[ 0 ], + "5. the close button" ); + done(); + }, step6 ); + } + + function step6() { + checkFocus( "
text
", { autoOpen: false }, function( done ) { + element.dialog( "widget" ).find( ".ui-dialog-titlebar-close" ).hide(); + element.dialog( "open" ); + setTimeout(function() { + equal( document.activeElement, element.parent()[ 0 ], "6. the dialog itself" ); + done(); + }); + }, step7 ); + } + + function step7() { + checkFocus( + "
", + { + open: function() { + var inputs = $( this ).find( "input" ); + inputs.last().keydown(function( event ) { + event.preventDefault(); + inputs.first().focus(); + }); + } + }, + function( done ) { + var inputs = element.find( "input" ); + equal( document.activeElement, inputs[ 1 ], "Focus starts on second input" ); + inputs.last().simulate( "keydown", { keyCode: $.ui.keyCode.TAB }); + setTimeout(function() { + equal( document.activeElement, inputs[ 0 ], + "Honor preventDefault, allowing custom focus management" ); + done(); + }, 50 ); + }, + start + ); + } + + step1(); +}); + +test( "#7960: resizable handles below modal overlays", function() { + expect( 1 ); + + var resizable = $( "
" ).resizable(), + dialog = $( "
" ).dialog({ modal: true }), + resizableZindex = parseInt( resizable.find( ".ui-resizable-handle" ).css( "zIndex" ), 10 ), + overlayZindex = parseInt( $( ".ui-widget-overlay" ).css( "zIndex" ), 10 ); + + ok( resizableZindex < overlayZindex, "Resizable handles have lower z-index than modal overlay" ); + dialog.dialog( "destroy" ); +}); + +asyncTest( "Prevent tabbing out of dialogs", function() { + expect( 3 ); + + var element = $( "
" ).dialog(), + inputs = element.find( "input" ); + + // Remove close button to test focus on just the two buttons + element.dialog( "widget" ).find( ".ui-button").remove(); + + function checkTab() { + equal( document.activeElement, inputs[ 0 ], "Tab key event moved focus within the modal" ); + + // check shift tab + $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.TAB, shiftKey: true }); + setTimeout( checkShiftTab ); + } + + function checkShiftTab() { + equal( document.activeElement, inputs[ 1 ], "Shift-Tab key event moved focus back to second input" ); + + element.remove(); + setTimeout( start ); + } + + inputs[ 1 ].focus(); + setTimeout(function() { + equal( document.activeElement, inputs[ 1 ], "Focus set on second input" ); + inputs.eq( 1 ).simulate( "keydown", { keyCode: $.ui.keyCode.TAB }); + + setTimeout( checkTab ); + }); +}); + +asyncTest( "#9048: multiple modal dialogs opened and closed in different order", function() { + expect( 1 ); + $( "#dialog1, #dialog2" ).dialog({ autoOpen: false, modal:true }); + $( "#dialog1" ).dialog( "open" ); + $( "#dialog2" ).dialog( "open" ); + $( "#dialog1" ).dialog( "close" ); + setTimeout(function() { + $( "#dialog2" ).dialog( "close" ); + $( "#favorite-animal" ).focus(); + ok( true, "event handlers cleaned up (no errors thrown)" ); + start(); + }); +}); + +asyncTest( "interaction between overlay and other dialogs", function() { + $.widget( "ui.testWidget", $.ui.dialog, { + options: { + modal: true, + autoOpen: false + } + }); + expect( 2 ); + var first = $( "
" ).dialog({ + modal: true + }), + firstInput = first.find( "input" ), + second = $( "
" ).testWidget(), + secondInput = second.find( "input" ); + + // Support: IE8 + // For some reason the focus doesn't get set properly if we don't + // focus the body first. + $( "body" ).focus(); + + // Wait for the modal to init + setTimeout(function() { + second.testWidget( "open" ); + + // Simulate user tabbing from address bar to an element outside the dialog + $( "#favorite-animal" ).focus(); + setTimeout(function() { + equal( document.activeElement, secondInput[ 0 ] ); + + // Last active dialog must receive focus + firstInput.focus(); + $( "#favorite-animal" ).focus(); + setTimeout(function() { + equal( document.activeElement, firstInput[ 0 ] ); + + // Cleanup + first.remove(); + second.remove(); + delete $.ui.testWidget; + delete $.fn.testWidget; + start(); + }); + }); + }); +}); + +} ); diff --git a/tests/unit/dialog/deprecated.html b/tests/unit/dialog/deprecated.html new file mode 100644 index 000000000..2d20b6291 --- /dev/null +++ b/tests/unit/dialog/deprecated.html @@ -0,0 +1,33 @@ + + + + + jQuery UI Dialog Test Suite + + + + + + +
+
+
+
+
+ +
...
+
+ Please share some personal information + + +
+
+

Some more (optional) information

+ +
+
+
+
+
+ + diff --git a/tests/unit/dialog/deprecated.js b/tests/unit/dialog/deprecated.js new file mode 100644 index 000000000..1f7087c57 --- /dev/null +++ b/tests/unit/dialog/deprecated.js @@ -0,0 +1,30 @@ +define( [ + "jquery", + "ui/dialog" +], function( $ ) { + +module( "dialog (deprecated): options" ); + +test( "dialogClass", function( assert ) { + expect( 5 ); + + var element = $( "
" ).dialog(), + widget = element.dialog( "widget" ); + assert.lacksClasses( widget, "foo", "dialogClass not specified. class not added" ); + element.remove(); + + element = $( "
" ).dialog({ dialogClass: "foo" }); + widget = element.dialog( "widget" ); + assert.hasClasses( widget, "foo", "dialogClass in init, foo class added" ); + element.dialog( "option", "dialogClass", "foobar" ); + assert.lacksClasses( widget, "foo", "dialogClass changed, previous one was removed" ); + assert.hasClasses( widget, "foobar", "dialogClass changed, new one was added" ); + element.remove(); + + element = $( "
" ).dialog({ dialogClass: "foo bar" }); + widget = element.dialog( "widget" ); + assert.hasClasses( widget, "foo bar", "dialogClass in init, two classes." ); + element.remove(); +}); + +} ); diff --git a/tests/unit/dialog/dialog_common.js b/tests/unit/dialog/dialog_common.js deleted file mode 100644 index 389b2ddff..000000000 --- a/tests/unit/dialog/dialog_common.js +++ /dev/null @@ -1,53 +0,0 @@ -define( [ - "lib/common", - "ui/dialog" -], function( common ) { - -common.testWidget( "dialog", { - defaults: { - appendTo: "body", - autoOpen: true, - buttons: [], - classes: { - "ui-dialog": "ui-corner-all", - "ui-dialog-titlebar": "ui-corner-all" - }, - closeOnEscape: true, - closeText: "Close", - disabled: false, - draggable: true, - height: "auto", - hide: null, - maxHeight: null, - maxWidth: null, - minHeight: 150, - minWidth: 150, - modal: false, - position: { - my: "center", - at: "center", - of: window, - collision: "fit", - using: $.ui.dialog.prototype.options.position.using - }, - resizable: true, - show: null, - title: null, - width: 300, - - // callbacks - beforeClose: null, - close: null, - create: null, - drag: null, - dragStart: null, - dragStop: null, - focus: null, - open: null, - resize: null, - resizeStart: null, - resizeStop: null - } -}); - -} ); diff --git a/tests/unit/dialog/dialog_common_deprecated.js b/tests/unit/dialog/dialog_common_deprecated.js deleted file mode 100644 index 7b0091277..000000000 --- a/tests/unit/dialog/dialog_common_deprecated.js +++ /dev/null @@ -1,54 +0,0 @@ -define( [ - "lib/common", - "ui/dialog" -], function( common ) { - -common.testWidget( "dialog", { - defaults: { - appendTo: "body", - autoOpen: true, - buttons: [], - classes: { - "ui-dialog": "ui-corner-all", - "ui-dialog-titlebar": "ui-corner-all" - }, - closeOnEscape: true, - closeText: "Close", - dialogClass: "", - disabled: false, - draggable: true, - height: "auto", - hide: null, - maxHeight: null, - maxWidth: null, - minHeight: 150, - minWidth: 150, - modal: false, - position: { - my: "center", - at: "center", - of: window, - collision: "fit", - using: $.ui.dialog.prototype.options.position.using - }, - resizable: true, - show: null, - title: null, - width: 300, - - // callbacks - beforeClose: null, - close: null, - create: null, - drag: null, - dragStart: null, - dragStop: null, - focus: null, - open: null, - resize: null, - resizeStart: null, - resizeStop: null - } -}); - -} ); diff --git a/tests/unit/dialog/dialog_core.js b/tests/unit/dialog/dialog_core.js deleted file mode 100644 index cb086ce8d..000000000 --- a/tests/unit/dialog/dialog_core.js +++ /dev/null @@ -1,308 +0,0 @@ -define( [ - "jquery", - "ui/dialog" -], function( $ ) { - -// TODO add teardown callback to remove dialogs -module("dialog: core"); - -test( "markup structure", function( assert ) { - expect( 11 ); - - var element = $( "
" ).dialog({ - buttons: [ { - text: "Ok", - click: $.noop - } ] - }), - widget = element.dialog( "widget" ), - titlebar = widget.find( ".ui-dialog-titlebar" ), - title = titlebar.find( ".ui-dialog-title" ), - close = titlebar.find( ".ui-dialog-titlebar-close" ), - buttonpane = widget.find( ".ui-dialog-buttonpane" ), - buttonset = widget.find( ".ui-dialog-buttonset" ), - buttons = buttonset.find( ".ui-button" ); - - assert.hasClasses( widget, "ui-dialog ui-dialog-buttons ui-widget ui-widget-content" ); - assert.hasClasses( titlebar, "ui-dialog-titlebar ui-widget-header" ); - equal( titlebar.length, 1, "Dialog has exactly one titlebar" ); - assert.hasClasses( close, "ui-dialog-titlebar-close ui-widget" ); - equal( close.length, 1, "Titlebar has exactly one close button" ); - equal( title.length, 1, "Titlebar has exactly one title" ); - assert.hasClasses( element, "ui-dialog-content ui-widget-content" ); - assert.hasClasses( buttonpane, "ui-dialog-buttonpane ui-widget-content" ); - equal( buttonpane.length, 1, "Dialog has exactly one buttonpane" ); - equal( buttonset.length, 1, "Buttonpane has exactly one buttonset" ); - equal( buttons.length, 1, "Buttonset contains exactly 1 button when created with 1" ); - -}); - -test( "markup structure - no buttons", function( assert ) { - expect( 7 ); - - var element = $( "
" ).dialog(), - widget = element.dialog( "widget" ), - titlebar = widget.find( ".ui-dialog-titlebar" ), - title = titlebar.find( ".ui-dialog-title" ), - close = titlebar.find( ".ui-dialog-titlebar-close" ); - - assert.hasClasses( widget, "ui-dialog ui-widget ui-widget-content" ); - assert.hasClasses( titlebar, "ui-dialog-titlebar ui-widget-header" ); - equal( titlebar.length, 1, "Dialog has exactly one titlebar" ); - assert.hasClasses( close, "ui-dialog-titlebar-close ui-widget" ); - equal( close.length, 1, "Titlebar has exactly one close button" ); - equal( title.length, 1, "Titlebar has exactly one title" ); - assert.hasClasses( element, "ui-dialog-content ui-widget-content" ); -}); - -test("title id", function() { - expect(1); - - var titleId, - element = $("
").dialog(); - - titleId = element.dialog("widget").find(".ui-dialog-title").attr("id"); - ok( /ui-id-\d+$/.test( titleId ), "auto-numbered title id"); - element.remove(); -}); - -test( "ARIA", function() { - expect( 4 ); - - var element = $( "
" ).dialog(), - wrapper = element.dialog( "widget" ); - equal( wrapper.attr( "role" ), "dialog", "dialog role" ); - equal( wrapper.attr( "aria-labelledby" ), wrapper.find( ".ui-dialog-title" ).attr( "id" ) ); - equal( wrapper.attr( "aria-describedby" ), element.attr( "id" ), "aria-describedby added" ); - element.remove(); - - element = $("

descriotion

").dialog(); - equal( element.dialog( "widget" ).attr( "aria-describedby" ), null, "no aria-describedby added, as already present in markup" ); - element.remove(); -}); - -test("widget method", function() { - expect( 1 ); - var dialog = $("
").appendTo("#qunit-fixture").dialog(); - deepEqual(dialog.parent()[0], dialog.dialog("widget")[0]); - dialog.remove(); -}); - -asyncTest( "focus tabbable", function() { - expect( 8 ); - var element, - options = { - buttons: [{ - text: "Ok", - click: $.noop - }] - }; - - function checkFocus( markup, options, testFn, next ) { - - // Support: IE8 - // For some reason the focus doesn't get set properly if we don't - // focus the body first. - $( "body" ).focus(); - - element = $( markup ).dialog( options ); - setTimeout(function() { - testFn(function done() { - element.remove(); - setTimeout( next ); - }); - }); - } - - function step1() { - checkFocus( "
", options, function( done ) { - var input = element.find( "input:last" ).focus().blur(); - element.dialog( "instance" )._focusTabbable(); - setTimeout(function() { - equal( document.activeElement, input[ 0 ], - "1. an element that was focused previously." ); - done(); - }); - }, step2 ); - } - - function step2() { - checkFocus( "
", options, function( done ) { - equal( document.activeElement, element.find( "input" )[ 1 ], - "2. first element inside the dialog matching [autofocus]" ); - done(); - }, step3 ); - } - - function step3() { - checkFocus( "
", options, function( done ) { - equal( document.activeElement, element.find( "input" )[ 0 ], - "3. tabbable element inside the content element" ); - done(); - }, step4 ); - } - - function step4() { - checkFocus( "
text
", options, function( done ) { - equal( document.activeElement, - element.dialog( "widget" ).find( ".ui-dialog-buttonpane button" )[ 0 ], - "4. tabbable element inside the buttonpane" ); - done(); - }, step5 ); - } - - function step5() { - checkFocus( "
text
", {}, function( done ) { - equal( document.activeElement, - element.dialog( "widget" ).find( ".ui-dialog-titlebar .ui-dialog-titlebar-close" )[ 0 ], - "5. the close button" ); - done(); - }, step6 ); - } - - function step6() { - checkFocus( "
text
", { autoOpen: false }, function( done ) { - element.dialog( "widget" ).find( ".ui-dialog-titlebar-close" ).hide(); - element.dialog( "open" ); - setTimeout(function() { - equal( document.activeElement, element.parent()[ 0 ], "6. the dialog itself" ); - done(); - }); - }, step7 ); - } - - function step7() { - checkFocus( - "
", - { - open: function() { - var inputs = $( this ).find( "input" ); - inputs.last().keydown(function( event ) { - event.preventDefault(); - inputs.first().focus(); - }); - } - }, - function( done ) { - var inputs = element.find( "input" ); - equal( document.activeElement, inputs[ 1 ], "Focus starts on second input" ); - inputs.last().simulate( "keydown", { keyCode: $.ui.keyCode.TAB }); - setTimeout(function() { - equal( document.activeElement, inputs[ 0 ], - "Honor preventDefault, allowing custom focus management" ); - done(); - }, 50 ); - }, - start - ); - } - - step1(); -}); - -test( "#7960: resizable handles below modal overlays", function() { - expect( 1 ); - - var resizable = $( "
" ).resizable(), - dialog = $( "
" ).dialog({ modal: true }), - resizableZindex = parseInt( resizable.find( ".ui-resizable-handle" ).css( "zIndex" ), 10 ), - overlayZindex = parseInt( $( ".ui-widget-overlay" ).css( "zIndex" ), 10 ); - - ok( resizableZindex < overlayZindex, "Resizable handles have lower z-index than modal overlay" ); - dialog.dialog( "destroy" ); -}); - -asyncTest( "Prevent tabbing out of dialogs", function() { - expect( 3 ); - - var element = $( "
" ).dialog(), - inputs = element.find( "input" ); - - // Remove close button to test focus on just the two buttons - element.dialog( "widget" ).find( ".ui-button").remove(); - - function checkTab() { - equal( document.activeElement, inputs[ 0 ], "Tab key event moved focus within the modal" ); - - // check shift tab - $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.TAB, shiftKey: true }); - setTimeout( checkShiftTab ); - } - - function checkShiftTab() { - equal( document.activeElement, inputs[ 1 ], "Shift-Tab key event moved focus back to second input" ); - - element.remove(); - setTimeout( start ); - } - - inputs[ 1 ].focus(); - setTimeout(function() { - equal( document.activeElement, inputs[ 1 ], "Focus set on second input" ); - inputs.eq( 1 ).simulate( "keydown", { keyCode: $.ui.keyCode.TAB }); - - setTimeout( checkTab ); - }); -}); - -asyncTest( "#9048: multiple modal dialogs opened and closed in different order", function() { - expect( 1 ); - $( "#dialog1, #dialog2" ).dialog({ autoOpen: false, modal:true }); - $( "#dialog1" ).dialog( "open" ); - $( "#dialog2" ).dialog( "open" ); - $( "#dialog1" ).dialog( "close" ); - setTimeout(function() { - $( "#dialog2" ).dialog( "close" ); - $( "#favorite-animal" ).focus(); - ok( true, "event handlers cleaned up (no errors thrown)" ); - start(); - }); -}); - -asyncTest( "interaction between overlay and other dialogs", function() { - $.widget( "ui.testWidget", $.ui.dialog, { - options: { - modal: true, - autoOpen: false - } - }); - expect( 2 ); - var first = $( "
" ).dialog({ - modal: true - }), - firstInput = first.find( "input" ), - second = $( "
" ).testWidget(), - secondInput = second.find( "input" ); - - // Support: IE8 - // For some reason the focus doesn't get set properly if we don't - // focus the body first. - $( "body" ).focus(); - - // Wait for the modal to init - setTimeout(function() { - second.testWidget( "open" ); - - // Simulate user tabbing from address bar to an element outside the dialog - $( "#favorite-animal" ).focus(); - setTimeout(function() { - equal( document.activeElement, secondInput[ 0 ] ); - - // Last active dialog must receive focus - firstInput.focus(); - $( "#favorite-animal" ).focus(); - setTimeout(function() { - equal( document.activeElement, firstInput[ 0 ] ); - - // Cleanup - first.remove(); - second.remove(); - delete $.ui.testWidget; - delete $.fn.testWidget; - start(); - }); - }); - }); -}); - -} ); diff --git a/tests/unit/dialog/dialog_deprecated.html b/tests/unit/dialog/dialog_deprecated.html deleted file mode 100644 index 2d20b6291..000000000 --- a/tests/unit/dialog/dialog_deprecated.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - jQuery UI Dialog Test Suite - - - - - - -
-
-
-
-
- -
...
-
- Please share some personal information - - -
-
-

Some more (optional) information

- -
-
-
-
-
- - diff --git a/tests/unit/dialog/dialog_deprecated.js b/tests/unit/dialog/dialog_deprecated.js deleted file mode 100644 index 1f7087c57..000000000 --- a/tests/unit/dialog/dialog_deprecated.js +++ /dev/null @@ -1,30 +0,0 @@ -define( [ - "jquery", - "ui/dialog" -], function( $ ) { - -module( "dialog (deprecated): options" ); - -test( "dialogClass", function( assert ) { - expect( 5 ); - - var element = $( "
" ).dialog(), - widget = element.dialog( "widget" ); - assert.lacksClasses( widget, "foo", "dialogClass not specified. class not added" ); - element.remove(); - - element = $( "
" ).dialog({ dialogClass: "foo" }); - widget = element.dialog( "widget" ); - assert.hasClasses( widget, "foo", "dialogClass in init, foo class added" ); - element.dialog( "option", "dialogClass", "foobar" ); - assert.lacksClasses( widget, "foo", "dialogClass changed, previous one was removed" ); - assert.hasClasses( widget, "foobar", "dialogClass changed, new one was added" ); - element.remove(); - - element = $( "
" ).dialog({ dialogClass: "foo bar" }); - widget = element.dialog( "widget" ); - assert.hasClasses( widget, "foo bar", "dialogClass in init, two classes." ); - element.remove(); -}); - -} ); diff --git a/tests/unit/dialog/dialog_events.js b/tests/unit/dialog/dialog_events.js deleted file mode 100644 index cc5bef8fa..000000000 --- a/tests/unit/dialog/dialog_events.js +++ /dev/null @@ -1,370 +0,0 @@ -define( [ - "jquery", - "./dialog_test_helpers", - "ui/dialog" -], function( $, testHelper ) { - -module("dialog: events"); - -test("open", function() { - expect(13); - - var element = $("
"); - element.dialog({ - open: function(ev, ui) { - ok(element.dialog( "instance" )._isOpen, "interal _isOpen flag is set"); - ok(true, "autoOpen: true fires open callback"); - equal(this, element[0], "context of callback"); - equal(ev.type, "dialogopen", "event type in callback"); - deepEqual(ui, {}, "ui hash in callback"); - } - }); - element.remove(); - - element = $("
"); - element.dialog({ - autoOpen: false, - open: function(ev, ui) { - ok(true, ".dialog('open') fires open callback"); - equal(this, element[0], "context of callback"); - equal(ev.type, "dialogopen", "event type in callback"); - deepEqual(ui, {}, "ui hash in callback"); - } - }).bind("dialogopen", function(ev, ui) { - ok(element.dialog( "instance" )._isOpen, "interal _isOpen flag is set"); - ok(true, "dialog('open') fires open event"); - equal(this, element[0], "context of event"); - deepEqual(ui, {}, "ui hash in event"); - }); - element.dialog("open"); - element.remove(); -}); - -test( "focus", function() { - expect( 5 ); - var element, other; - element = $("#dialog1").dialog({ - autoOpen: false - }); - other = $("#dialog2").dialog({ - autoOpen: false - }); - - element.one( "dialogopen", function() { - ok( true, "open, just once" ); - }); - element.one( "dialogfocus", function() { - ok( true, "focus on open" ); - }); - other.dialog( "open" ); - - element.one( "dialogfocus", function() { - ok( true, "when opening and already open and wasn't on top" ); - }); - other.dialog( "open" ); - element.dialog( "open" ); - - element.one( "dialogfocus", function() { - ok( true, "when calling moveToTop and wasn't on top" ); - }); - other.dialog( "moveToTop" ); - element.dialog( "moveToTop" ); - - element.bind( "dialogfocus", function() { - ok( true, "when mousedown anywhere on the dialog and it wasn't on top" ); - }); - other.dialog( "moveToTop" ); - element.trigger( "mousedown" ); - - // triggers just once when already on top - element.dialog( "open" ); - element.dialog( "moveToTop" ); - element.trigger( "mousedown" ); - - element.add( other ).remove(); -}); - -test("dragStart", function() { - expect(9); - - var handle, - element = $("
").dialog({ - dragStart: function(ev, ui) { - ok(true, "dragging fires dragStart callback"); - equal(this, element[0], "context of callback"); - equal(ev.type, "dialogdragstart", "event type in callback"); - ok(ui.position !== undefined, "ui.position in callback"); - ok(ui.offset !== undefined, "ui.offset in callback"); - } - }).bind("dialogdragstart", function(ev, ui) { - ok(true, "dragging fires dialogdragstart event"); - equal(this, element[0], "context of event"); - ok(ui.position !== undefined, "ui.position in callback"); - ok(ui.offset !== undefined, "ui.offset in callback"); - }); - - handle = $(".ui-dialog-titlebar", element.dialog("widget")); - testHelper.drag(element, handle, 50, 50); - element.remove(); -}); - -test("drag", function() { - expect(9); - var handle, - hasDragged = false, - element = $("
").dialog({ - drag: function(ev, ui) { - if (!hasDragged) { - ok(true, "dragging fires drag callback"); - equal(this, element[0], "context of callback"); - equal(ev.type, "dialogdrag", "event type in callback"); - ok(ui.position !== undefined, "ui.position in callback"); - ok(ui.offset !== undefined, "ui.offset in callback"); - - hasDragged = true; - } - } - }).one("dialogdrag", function(ev, ui) { - ok(true, "dragging fires dialogdrag event"); - equal(this, element[0], "context of event"); - ok(ui.position !== undefined, "ui.position in callback"); - ok(ui.offset !== undefined, "ui.offset in callback"); - }); - - handle = $(".ui-dialog-titlebar", element.dialog("widget")); - testHelper.drag(element, handle, 50, 50); - element.remove(); -}); - -test("dragStop", function() { - expect(9); - - var handle, - element = $("
").dialog({ - dragStop: function(ev, ui) { - ok(true, "dragging fires dragStop callback"); - equal(this, element[0], "context of callback"); - equal(ev.type, "dialogdragstop", "event type in callback"); - ok(ui.position !== undefined, "ui.position in callback"); - ok(ui.offset !== undefined, "ui.offset in callback"); - } - }).bind("dialogdragstop", function(ev, ui) { - ok(true, "dragging fires dialogdragstop event"); - equal(this, element[0], "context of event"); - ok(ui.position !== undefined, "ui.position in callback"); - ok(ui.offset !== undefined, "ui.offset in callback"); - }); - - handle = $(".ui-dialog-titlebar", element.dialog("widget")); - testHelper.drag(element, handle, 50, 50); - element.remove(); -}); - -test("resizeStart", function() { - expect(13); - - var handle, - element = $("
").dialog({ - resizeStart: function(ev, ui) { - ok(true, "resizing fires resizeStart callback"); - equal(this, element[0], "context of callback"); - equal(ev.type, "dialogresizestart", "event type in callback"); - ok(ui.originalPosition !== undefined, "ui.originalPosition in callback"); - ok(ui.originalSize !== undefined, "ui.originalSize in callback"); - ok(ui.position !== undefined, "ui.position in callback"); - ok(ui.size !== undefined, "ui.size in callback"); - } - }).bind("dialogresizestart", function(ev, ui) { - ok(true, "resizing fires dialogresizestart event"); - equal(this, element[0], "context of event"); - ok(ui.originalPosition !== undefined, "ui.originalPosition in callback"); - ok(ui.originalSize !== undefined, "ui.originalSize in callback"); - ok(ui.position !== undefined, "ui.position in callback"); - ok(ui.size !== undefined, "ui.size in callback"); - }); - - handle = $(".ui-resizable-se", element.dialog("widget")); - testHelper.drag(element, handle, 50, 50); - element.remove(); -}); - -test("resize", function() { - expect(13); - var handle, - hasResized = false, - element = $("
").dialog({ - resize: function(ev, ui) { - if (!hasResized) { - ok(true, "resizing fires resize callback"); - equal(this, element[0], "context of callback"); - equal(ev.type, "dialogresize", "event type in callback"); - ok(ui.originalPosition !== undefined, "ui.originalPosition in callback"); - ok(ui.originalSize !== undefined, "ui.originalSize in callback"); - ok(ui.position !== undefined, "ui.position in callback"); - ok(ui.size !== undefined, "ui.size in callback"); - - hasResized = true; - } - } - }).one("dialogresize", function(ev, ui) { - ok(true, "resizing fires dialogresize event"); - equal(this, element[0], "context of event"); - ok(ui.originalPosition !== undefined, "ui.originalPosition in callback"); - ok(ui.originalSize !== undefined, "ui.originalSize in callback"); - ok(ui.position !== undefined, "ui.position in callback"); - ok(ui.size !== undefined, "ui.size in callback"); - }); - - handle = $(".ui-resizable-se", element.dialog("widget")); - testHelper.drag(element, handle, 50, 50); - element.remove(); -}); - -test("resizeStop", function() { - expect(13); - - var handle, - element = $("
").dialog({ - resizeStop: function(ev, ui) { - ok(true, "resizing fires resizeStop callback"); - equal(this, element[0], "context of callback"); - equal(ev.type, "dialogresizestop", "event type in callback"); - ok(ui.originalPosition !== undefined, "ui.originalPosition in callback"); - ok(ui.originalSize !== undefined, "ui.originalSize in callback"); - ok(ui.position !== undefined, "ui.position in callback"); - ok(ui.size !== undefined, "ui.size in callback"); - } - }).bind("dialogresizestop", function(ev, ui) { - ok(true, "resizing fires dialogresizestop event"); - equal(this, element[0], "context of event"); - ok(ui.originalPosition !== undefined, "ui.originalPosition in callback"); - ok(ui.originalSize !== undefined, "ui.originalSize in callback"); - ok(ui.position !== undefined, "ui.position in callback"); - ok(ui.size !== undefined, "ui.size in callback"); - }); - - handle = $(".ui-resizable-se", element.dialog("widget")); - testHelper.drag(element, handle, 50, 50); - element.remove(); -}); - -asyncTest("close", function() { - expect(14); - - var element = $("
").dialog({ - close: function(ev, ui) { - ok(true, ".dialog('close') fires close callback"); - equal(this, element[0], "context of callback"); - equal(ev.type, "dialogclose", "event type in callback"); - deepEqual(ui, {}, "ui hash in callback"); - } - }).bind("dialogclose", function(ev, ui) { - ok(true, ".dialog('close') fires dialogclose event"); - equal(this, element[0], "context of event"); - deepEqual(ui, {}, "ui hash in event"); - }); - element.dialog("close"); - element.remove(); - - // Close event with an effect - element = $("
").dialog({ - hide: 10, - close: function(ev, ui) { - ok(true, ".dialog('close') fires close callback"); - equal(this, element[0], "context of callback"); - equal(ev.type, "dialogclose", "event type in callback"); - deepEqual(ui, {}, "ui hash in callback"); - start(); - } - }).bind("dialogclose", function(ev, ui) { - ok(true, ".dialog('close') fires dialogclose event"); - equal(this, element[0], "context of event"); - deepEqual(ui, {}, "ui hash in event"); - }); - element.dialog("close"); -}); - -test("beforeClose", function() { - expect(14); - - var element = $("
").dialog({ - beforeClose: function(ev, ui) { - ok(true, ".dialog('close') fires beforeClose callback"); - equal(this, element[0], "context of callback"); - equal(ev.type, "dialogbeforeclose", "event type in callback"); - deepEqual(ui, {}, "ui hash in callback"); - return false; - } - }); - - element.dialog("close"); - ok( element.dialog("widget").is(":visible"), "beforeClose callback should prevent dialog from closing"); - element.remove(); - - element = $("
").dialog(); - element.dialog("option", "beforeClose", function(ev, ui) { - ok(true, ".dialog('close') fires beforeClose callback"); - equal(this, element[0], "context of callback"); - equal(ev.type, "dialogbeforeclose", "event type in callback"); - deepEqual(ui, {}, "ui hash in callback"); - return false; - }); - element.dialog("close"); - - ok( element.dialog("widget").is(":visible"), "beforeClose callback should prevent dialog from closing"); - element.remove(); - - element = $("
").dialog().bind("dialogbeforeclose", function(ev, ui) { - ok(true, ".dialog('close') triggers dialogbeforeclose event"); - equal(this, element[0], "context of event"); - deepEqual(ui, {}, "ui hash in event"); - return false; - }); - element.dialog("close"); - ok( element.dialog("widget").is(":visible"), "dialogbeforeclose event should prevent dialog from closing"); - element.remove(); -}); - -// #8789 and #8838 -asyncTest("ensure dialog's container doesn't scroll on resize and focus", function() { - expect(2); - - var element = $("#dialog1").dialog(), - initialScroll = $(window).scrollTop(); - element.dialog("option", "height", 600); - equal($(window).scrollTop(), initialScroll, "scroll hasn't moved after height change"); - setTimeout( function(){ - $(".ui-dialog-titlebar-close").simulate("mousedown"); - equal($(window).scrollTop(), initialScroll, "scroll hasn't moved after focus moved to dialog"); - element.dialog("destroy"); - start(); - }); -}); - -test("#5184: isOpen in dialogclose event is true", function() { - expect( 3 ); - - var element = $( "
" ).dialog({ - close: function() { - ok( !element.dialog("isOpen"), "dialog is not open during close" ); - } - }); - ok( element.dialog("isOpen"), "dialog is open after init" ); - element.dialog( "close" ); - ok( !element.dialog("isOpen"), "dialog is not open after close" ); - element.remove(); -}); - -test("ensure dialog keeps focus when clicking modal overlay", function() { - expect( 2 ); - - var element = $( "
" ).dialog({ - modal: true - }); - equal( $( document.activeElement ).closest( ".ui-dialog" ).length, 1, "focus is in dialog" ); - $(".ui-widget-overlay").simulate("mousedown"); - equal( $( document.activeElement ).closest( ".ui-dialog" ).length, 1, "focus is still in dialog" ); - element.remove(); -}); - -} ); diff --git a/tests/unit/dialog/dialog_methods.js b/tests/unit/dialog/dialog_methods.js deleted file mode 100644 index 10b0fd7bb..000000000 --- a/tests/unit/dialog/dialog_methods.js +++ /dev/null @@ -1,267 +0,0 @@ -define( [ - "jquery", - "ui/dialog" -], function( $ ) { - -module("dialog: methods", { - teardown: function() { - $("body>.ui-dialog").remove(); - } -}); - -test("init", function() { - expect(6); - - $("
").appendTo("body").dialog().remove(); - ok(true, ".dialog() called on element"); - - $([]).dialog().remove(); - ok(true, ".dialog() called on empty collection"); - - $("
").dialog().remove(); - ok(true, ".dialog() called on disconnected DOMElement - never connected"); - - $("
").appendTo("body").remove().dialog().remove(); - ok(true, ".dialog() called on disconnected DOMElement - removed"); - - var element = $("
").dialog(); - element.dialog("option", "foo"); - element.remove(); - ok(true, "arbitrary option getter after init"); - - $("
").dialog().dialog("option", "foo", "bar").remove(); - ok(true, "arbitrary option setter after init"); -}); - -test("destroy", function( assert ) { - expect( 17 ); - - var element, element2; - - $( "#dialog1, #form-dialog" ).hide(); - assert.domEqual( "#dialog1", function() { - var dialog = $( "#dialog1" ).dialog().dialog( "destroy" ); - equal( dialog.parent()[ 0 ], $( "#qunit-fixture" )[ 0 ] ); - equal( dialog.index(), 0 ); - }); - assert.domEqual( "#form-dialog", function() { - var dialog = $( "#form-dialog" ).dialog().dialog( "destroy" ); - equal( dialog.parent()[ 0 ], $( "#qunit-fixture" )[ 0 ] ); - equal( dialog.index(), 2 ); - }); - - // Ensure dimensions are restored (#8119) - $( "#dialog1" ).show().css({ - width: "400px", - minHeight: "100px", - height: "200px" - }); - assert.domEqual( "#dialog1", function() { - $( "#dialog1" ).dialog().dialog( "destroy" ); - }); - - // Don't throw errors when destroying a never opened modal dialog (#9004) - $( "#dialog1" ).dialog({ autoOpen: false, modal: true }).dialog( "destroy" ); - equal( $( ".ui-widget-overlay" ).length, 0, "overlay does not exist" ); - equal( $( document ).data( "ui-dialog-overlays" ), undefined, "ui-dialog-overlays equals the number of open overlays"); - - element = $( "#dialog1" ).dialog({ modal: true }), - element2 = $( "#dialog2" ).dialog({ modal: true }); - equal( $( ".ui-widget-overlay" ).length, 2, "overlays created when dialogs are open" ); - equal( $( document ).data( "ui-dialog-overlays" ), 2, "ui-dialog-overlays equals the number of open overlays" ); - element.dialog( "close" ); - equal( $( ".ui-widget-overlay" ).length, 1, "overlay remains after closing one dialog" ); - equal( $( document ).data( "ui-dialog-overlays" ), 1, "ui-dialog-overlays equals the number of open overlays" ); - element.dialog( "destroy" ); - equal( $( ".ui-widget-overlay" ).length, 1, "overlay remains after destroying one dialog" ); - equal( $( document ).data( "ui-dialog-overlays" ), 1, "ui-dialog-overlays equals the number of open overlays" ); - element2.dialog( "destroy" ); - equal( $( ".ui-widget-overlay" ).length, 0, "overlays removed when all dialogs are destoryed" ); - equal( $( document ).data( "ui-dialog-overlays" ), undefined, "ui-dialog-overlays equals the number of open overlays" ); -}); - -asyncTest("#9000: Dialog leaves broken event handler after close/destroy in certain cases", function() { - expect( 1 ); - $( "#dialog1" ).dialog({ modal:true }).dialog( "close" ).dialog( "destroy" ); - setTimeout(function() { - $( "#favorite-animal" ).focus(); - ok( true, "close and destroy modal dialog before its really opened" ); - start(); - }); -}); - -test("#4980: Destroy should place element back in original DOM position", function(){ - expect( 2 ); - var container = $("
"), - modal = container.find("#modal"); - modal.dialog(); - ok(!$.contains(container[0], modal[0]), "dialog should move modal element to outside container element"); - modal.dialog("destroy"); - ok($.contains(container[0], modal[0]), "dialog(destroy) should place element back in original DOM position"); -}); - -test( "enable/disable disabled", function( assert ) { - expect( 3 ); - var element = $( "
" ).dialog(); - element.dialog( "disable" ); - equal(element.dialog( "option", "disabled" ), false, "disable method doesn't do anything" ); - assert.lacksClasses( element, "ui-dialog-disabled ui-state-disabled", "disable method doesn't add classes" ); - ok( !element.dialog( "widget" ).attr( "aria-disabled" ), "disable method doesn't add aria-disabled" ); -}); - -test("close", function() { - expect( 3 ); - - var element, - expected = $("
").dialog(), - actual = expected.dialog("close"); - equal(actual, expected, "close is chainable"); - - element = $("
").dialog(); - ok(element.dialog("widget").is(":visible") && !element.dialog("widget").is(":hidden"), "dialog visible before close method called"); - element.dialog("close"); - ok(element.dialog("widget").is(":hidden") && !element.dialog("widget").is(":visible"), "dialog hidden after close method called"); -}); - -test("isOpen", function() { - expect(4); - - var element = $("
").dialog(); - equal(element.dialog("isOpen"), true, "dialog is open after init"); - element.dialog("close"); - equal(element.dialog("isOpen"), false, "dialog is closed"); - element.remove(); - - element = $("
").dialog({autoOpen: false}); - equal(element.dialog("isOpen"), false, "dialog is closed after init"); - element.dialog("open"); - equal(element.dialog("isOpen"), true, "dialog is open"); - element.remove(); -}); - -test("moveToTop", function() { - expect( 5 ); - function order() { - var actual = $( ".ui-dialog" ).map(function() { - return +$( this ).css( "z-index" ); - }).get(); - deepEqual( actual, $.makeArray( arguments ) ); - } - var dialog1, dialog2, - focusOn = "dialog1"; - dialog1 = $( "#dialog1" ).dialog({ - focus: function() { - equal( focusOn, "dialog1" ); - } - }); - focusOn = "dialog2"; - dialog2 = $( "#dialog2" ).dialog({ - focus: function() { - equal( focusOn, "dialog2" ); - } - }); - order( 100, 101 ); - focusOn = "dialog1"; - dialog1.dialog( "moveToTop" ); - order( 102, 101 ); -}); - -test( "moveToTop: content scroll stays intact", function() { - expect( 2 ); - var otherDialog = $( "#dialog1" ).dialog(), - scrollDialog = $( "#form-dialog" ).dialog({ - height: 200 - }); - scrollDialog.scrollTop( 50 ); - equal( scrollDialog.scrollTop(), 50 ); - - otherDialog.dialog( "moveToTop" ); - equal( scrollDialog.scrollTop(), 50 ); -}); - -test("open", function() { - expect( 3 ); - var element, - expected = $("
").dialog(), - actual = expected.dialog("open"); - equal(actual, expected, "open is chainable"); - - element = $("
").dialog({ autoOpen: false }); - ok(element.dialog("widget").is(":hidden") && !element.dialog("widget").is(":visible"), "dialog hidden before open method called"); - element.dialog("open"); - ok(element.dialog("widget").is(":visible") && !element.dialog("widget").is(":hidden"), "dialog visible after open method called"); -}); - -// http://bugs.jqueryui.com/ticket/6137 -test("Ensure form elements don't reset when opening a dialog", function() { - expect(2); - - var d1 = $("
" + - "b
").appendTo( "body" ).dialog({autoOpen: false}); - - d1.find("#b").prop( "checked", true ); - equal(d1.find("input:checked").val(), "b", "checkbox b is checked"); - - d1.dialog("open"); - equal(d1.find("input:checked").val(), "b", "checkbox b is checked"); - - d1.remove(); -}); - -asyncTest( "#8958: dialog can be opened while opening", function() { - expect( 1 ); - - var element = $( "
" ).dialog({ - autoOpen: false, - modal: true, - open: function() { - equal( $( ".ui-widget-overlay" ).length, 1 ); - start(); - } - }); - - // Support: IE8 - // For some reason the #favorite-color input doesn't get focus if we don't - // focus the body first, causing the test to hang. - $( "body" ).focus(); - - $( "#favorite-animal" ) - // We focus the input to start the test. Once it receives focus, the - // dialog will open. Opening the dialog, will cause an element inside - // the dialog to gain focus, thus blurring the input. - .bind( "focus", function() { - element.dialog( "open" ); - }) - // When the input blurs, the dialog is in the process of opening. We - // try to open the dialog again, to make sure that dialogs properly - // handle a call to the open() method during the process of the dialog - // being opened. - .bind( "blur", function() { - element.dialog( "open" ); - }) - .focus(); -}); - -test("#5531: dialog width should be at least minWidth on creation", function () { - expect( 4 ); - var element = $("
").dialog({ - width: 200, - minWidth: 300 - }); - - equal(element.dialog("option", "width"), 300, "width is minWidth"); - element.dialog("option", "width", 200); - equal(element.dialog("option", "width"), 300, "width unchanged when set to < minWidth"); - element.dialog("option", "width", 320); - equal(element.dialog("option", "width"), 320, "width changed if set to > minWidth"); - element.remove(); - - element = $("
").dialog({ - minWidth: 300 - }); - ok(element.dialog("option", "width") >= 300, "width is at least 300"); - element.remove(); - -}); - -} ); diff --git a/tests/unit/dialog/dialog_options.js b/tests/unit/dialog/dialog_options.js deleted file mode 100644 index 1b9af7a09..000000000 --- a/tests/unit/dialog/dialog_options.js +++ /dev/null @@ -1,557 +0,0 @@ -define( [ - "jquery", - "./dialog_test_helpers", - "ui/dialog", - "ui/effect-blind", - "ui/effect-explode" -], function( $, testHelper ) { - -module("dialog: options"); - -test( "appendTo", function() { - expect( 16 ); - var detached = $( "
" ), - element = $( "#dialog1" ).dialog({ - modal: true - }); - equal( element.dialog( "widget" ).parent()[0], document.body, "defaults to body" ); - equal( $( ".ui-widget-overlay" ).parent()[0], document.body, "overlay defaults to body" ); - element.dialog( "destroy" ); - - element.dialog({ - appendTo: ".wrap", - modal: true - }); - equal( element.dialog( "widget" ).parent()[0], $( "#wrap1" )[0], "first found element" ); - equal( $( ".ui-widget-overlay" ).parent()[0], $( "#wrap1" )[0], "overlay first found element" ); - equal( $( "#wrap2 .ui-dialog" ).length, 0, "only appends to one element" ); - equal( $( "#wrap2 .ui-widget-overlay" ).length, 0, "overlay only appends to one element" ); - element.dialog( "destroy" ); - - element.dialog({ - appendTo: null, - modal: true - }); - equal( element.dialog( "widget" ).parent()[0], document.body, "null" ); - equal( $( ".ui-widget-overlay" ).parent()[0], document.body, "overlay null" ); - element.dialog( "destroy" ); - - element.dialog({ - autoOpen: false, - modal: true - }).dialog( "option", "appendTo", "#wrap1" ).dialog( "open" ); - equal( element.dialog( "widget" ).parent()[0], $( "#wrap1" )[0], "modified after init" ); - equal( $( ".ui-widget-overlay" ).parent()[0], $( "#wrap1" )[0], "overlay modified after init" ); - element.dialog( "destroy" ); - - element.dialog({ - appendTo: detached, - modal: true - }); - equal( element.dialog( "widget" ).parent()[0], detached[0], "detached jQuery object" ); - equal( detached.find( ".ui-widget-overlay" ).parent()[0], detached[0], "overlay detached jQuery object" ); - element.dialog( "destroy" ); - - element.dialog({ - appendTo: detached[0], - modal: true - }); - equal( element.dialog( "widget" ).parent()[0], detached[0], "detached DOM element" ); - equal( detached.find( ".ui-widget-overlay" ).parent()[0], detached[0], "overlay detached DOM element" ); - element.dialog( "destroy" ); - - element.dialog({ - autoOpen: false, - modal: true - }).dialog( "option", "appendTo", detached ); - equal( element.dialog( "widget" ).parent()[0], detached[0], "detached DOM element via option()" ); - equal( detached.find( ".ui-widget-overlay" ).length, 0, "overlay detached DOM element via option()" ); - element.dialog( "destroy" ); -}); - -test("autoOpen", function() { - expect(2); - - var element = $("
").dialog({ autoOpen: false }); - ok( !element.dialog("widget").is(":visible"), ".dialog({ autoOpen: false })"); - element.remove(); - - element = $("
").dialog({ autoOpen: true }); - ok( element.dialog("widget").is(":visible"), ".dialog({ autoOpen: true })"); - element.remove(); -}); - -test("buttons", function( assert ) { - expect(21); - - var btn, i, newButtons, - buttons = { - "Ok": function( ev ) { - ok(true, "button click fires callback"); - equal(this, element[0], "context of callback"); - equal(ev.target, btn[0], "event target"); - }, - "Cancel": function( ev ) { - ok(true, "button click fires callback"); - equal(this, element[0], "context of callback"); - equal(ev.target, btn[1], "event target"); - } - }, - element = $("
").dialog({ buttons: buttons }); - - btn = element.dialog( "widget" ).find( ".ui-dialog-buttonpane button" ); - equal(btn.length, 2, "number of buttons"); - - i = 0; - $.each(buttons, function( key ) { - equal(btn.eq(i).text(), key, "text of button " + (i+1)); - i++; - }); - - assert.hasClasses( btn.parent(), "ui-dialog-buttonset" ); - assert.hasClasses( element.parent(), "ui-dialog-buttons" ); - - btn.trigger("click"); - - newButtons = { - "Close": function( ev ) { - ok(true, "button click fires callback"); - equal(this, element[0], "context of callback"); - equal(ev.target, btn[0], "event target"); - } - }; - - deepEqual(element.dialog("option", "buttons"), buttons, ".dialog('option', 'buttons') getter"); - element.dialog("option", "buttons", newButtons); - deepEqual(element.dialog("option", "buttons"), newButtons, ".dialog('option', 'buttons', ...) setter"); - - btn = element.dialog( "widget" ).find( ".ui-dialog-buttonpane button" ); - equal(btn.length, 1, "number of buttons after setter"); - btn.trigger("click"); - - i = 0; - $.each(newButtons, function( key ) { - equal(btn.eq(i).text(), key, "text of button " + (i+1)); - i += 1; - }); - - element.dialog("option", "buttons", null); - btn = element.dialog( "widget" ).find( ".ui-dialog-buttonpane button" ); - equal(btn.length, 0, "all buttons have been removed"); - equal(element.find(".ui-dialog-buttonset").length, 0, "buttonset has been removed"); - assert.lacksClasses( element.parent(), "ui-dialog-buttons" ); - element.remove(); -}); - -test("buttons - advanced", function( assert ) { - expect( 7 ); - - var buttons, - element = $("
").dialog({ - buttons: [ - { - text: "a button", - "class": "additional-class", - id: "my-button-id", - click: function() { - equal(this, element[0], "correct context"); - }, - icons: { - primary: "ui-icon-cancel" - }, - showText: false - } - ] - }); - - buttons = element.dialog( "widget" ).find( ".ui-dialog-buttonpane button" ); - equal(buttons.length, 1, "correct number of buttons"); - equal(buttons.attr("id"), "my-button-id", "correct id"); - equal(buttons.text(), "a button", "correct label"); - assert.hasClasses( buttons, "additional-class" ); - deepEqual( buttons.button("option", "icons"), { primary: "ui-icon-cancel", secondary: null } ); - equal( buttons.button( "option", "text" ), false ); - buttons.click(); - - element.remove(); -}); - -test("#9043: buttons with Array.prototype modification", function() { - expect( 1 ); - Array.prototype.test = $.noop; - var element = $( "
" ).dialog(); - equal( element.dialog( "widget" ).find( ".ui-dialog-buttonpane" ).length, 0, - "no button pane" ); - element.remove(); - delete Array.prototype.test; -}); - -test("closeOnEscape", function() { - expect( 6 ); - var element = $("
").dialog({ closeOnEscape: false }); - ok(true, "closeOnEscape: false"); - ok(element.dialog("widget").is(":visible") && !element.dialog("widget").is(":hidden"), "dialog is open before ESC"); - element.simulate("keydown", { keyCode: $.ui.keyCode.ESCAPE }) - .simulate("keypress", { keyCode: $.ui.keyCode.ESCAPE }) - .simulate("keyup", { keyCode: $.ui.keyCode.ESCAPE }); - ok(element.dialog("widget").is(":visible") && !element.dialog("widget").is(":hidden"), "dialog is open after ESC"); - - element.remove(); - - element = $("
").dialog({ closeOnEscape: true }); - ok(true, "closeOnEscape: true"); - ok(element.dialog("widget").is(":visible") && !element.dialog("widget").is(":hidden"), "dialog is open before ESC"); - element.simulate("keydown", { keyCode: $.ui.keyCode.ESCAPE }) - .simulate("keypress", { keyCode: $.ui.keyCode.ESCAPE }) - .simulate("keyup", { keyCode: $.ui.keyCode.ESCAPE }); - ok(element.dialog("widget").is(":hidden") && !element.dialog("widget").is(":visible"), "dialog is closed after ESC"); -}); - -test("closeText", function() { - expect(3); - - var element = $("
").dialog(); - equal(element.dialog("widget").find(".ui-dialog-titlebar-close span").text(), "Close", - "default close text"); - element.remove(); - - element = $("
").dialog({ closeText: "foo" }); - equal(element.dialog("widget").find(".ui-dialog-titlebar-close span").text(), "foo", - "closeText on init"); - element.remove(); - - element = $("
").dialog().dialog("option", "closeText", "bar"); - equal(element.dialog("widget").find(".ui-dialog-titlebar-close span").text(), "bar", - "closeText via option method"); - element.remove(); -}); - -test("draggable", function() { - expect(4); - - var element = $("
").dialog({ draggable: false }); - - testHelper.testDrag(element, 50, -50, 0, 0); - element.dialog("option", "draggable", true); - testHelper.testDrag(element, 50, -50, 50, -50); - element.remove(); - - element = $("
").dialog({ draggable: true }); - testHelper.testDrag(element, 50, -50, 50, -50); - element.dialog("option", "draggable", false); - testHelper.testDrag(element, 50, -50, 0, 0); - element.remove(); -}); - -test("height", function() { - expect(4); - - var element = $("
").dialog(); - equal(element.dialog("widget").outerHeight(), 150, "default height"); - element.remove(); - - element = $("
").dialog({ height: 237 }); - equal(element.dialog("widget").outerHeight(), 237, "explicit height"); - element.remove(); - - element = $("
").dialog(); - element.dialog("option", "height", 238); - equal(element.dialog("widget").outerHeight(), 238, "explicit height set after init"); - element.remove(); - - element = $("
").css("padding", "20px") - .dialog({ height: 240 }); - equal(element.dialog("widget").outerHeight(), 240, "explicit height with padding"); - element.remove(); -}); - -test("maxHeight", function( assert ) { - expect(3); - - var element = $("
").dialog({ maxHeight: 200 }); - testHelper.drag(element, ".ui-resizable-s", 1000, 1000); - assert.close(element.dialog("widget").height(), 200, 1, "maxHeight"); - element.remove(); - - element = $("
").dialog({ maxHeight: 200 }); - testHelper.drag(element, ".ui-resizable-n", -1000, -1000); - assert.close(element.dialog("widget").height(), 200, 1, "maxHeight"); - element.remove(); - - element = $("
").dialog({ maxHeight: 200 }).dialog("option", "maxHeight", 300); - testHelper.drag(element, ".ui-resizable-s", 1000, 1000); - assert.close(element.dialog("widget").height(), 300, 1, "maxHeight"); - element.remove(); -}); - -test("maxWidth", function( assert ) { - expect(3); - - var element = $("
").dialog({ maxWidth: 200 }); - testHelper.drag(element, ".ui-resizable-e", 1000, 1000); - assert.close(element.dialog("widget").width(), 200, 1, "maxWidth"); - element.remove(); - - element = $("
").dialog({ maxWidth: 200 }); - testHelper.drag(element, ".ui-resizable-w", -1000, -1000); - assert.close(element.dialog("widget").width(), 200, 1, "maxWidth"); - element.remove(); - - element = $("
").dialog({ maxWidth: 200 }).dialog("option", "maxWidth", 300); - testHelper.drag(element, ".ui-resizable-w", -1000, -1000); - assert.close(element.dialog("widget").width(), 300, 1, "maxWidth"); - element.remove(); -}); - -test("minHeight", function( assert ) { - expect(3); - - var element = $("
").dialog({ minHeight: 10 }); - testHelper.drag(element, ".ui-resizable-s", -1000, -1000); - assert.close(element.dialog("widget").height(), 10, 1, "minHeight"); - element.remove(); - - element = $("
").dialog({ minHeight: 10 }); - testHelper.drag(element, ".ui-resizable-n", 1000, 1000); - assert.close(element.dialog("widget").height(), 10, 1, "minHeight"); - element.remove(); - - element = $("
").dialog({ minHeight: 10 }).dialog("option", "minHeight", 30); - testHelper.drag(element, ".ui-resizable-n", 1000, 1000); - assert.close(element.dialog("widget").height(), 30, 1, "minHeight"); - element.remove(); -}); - -test("minWidth", function( assert ) { - expect(3); - - var element = $("
").dialog({ minWidth: 10 }); - testHelper.drag(element, ".ui-resizable-e", -1000, -1000); - assert.close(element.dialog("widget").width(), 10, 1, "minWidth"); - element.remove(); - - element = $("
").dialog({ minWidth: 10 }); - testHelper.drag(element, ".ui-resizable-w", 1000, 1000); - assert.close(element.dialog("widget").width(), 10, 1, "minWidth"); - element.remove(); - - element = $("
").dialog({ minWidth: 30 }).dialog("option", "minWidth", 30); - testHelper.drag(element, ".ui-resizable-w", 1000, 1000); - assert.close(element.dialog("widget").width(), 30, 1, "minWidth"); - element.remove(); -}); - -test( "position, default center on window", function( assert ) { - expect( 2 ); - - // dialogs alter the window width and height in Firefox - // so we collect that information before creating the dialog - // Support: Firefox - var winWidth = $( window ).width(), - winHeight = $( window ).height(), - element = $("
").dialog(), - dialog = element.dialog("widget"), - offset = dialog.offset(); - assert.close( offset.left, Math.round( winWidth / 2 - dialog.outerWidth() / 2 ) + $( window ).scrollLeft(), 1, "dialog left position of center on window on initilization" ); - assert.close( offset.top, Math.round( winHeight / 2 - dialog.outerHeight() / 2 ) + $( window ).scrollTop(), 1, "dialog top position of center on window on initilization" ); - element.remove(); -}); - -test( "position, right bottom at right bottom via ui.position args", function( assert ) { - expect( 2 ); - - // dialogs alter the window width and height in Firefox - // so we collect that information before creating the dialog - // Support: Firefox - var winWidth = $( window ).width(), - winHeight = $( window ).height(), - element = $("
").dialog({ - position: { - my: "right bottom", - at: "right bottom" - } - }), - dialog = element.dialog("widget"), - offset = dialog.offset(); - - assert.close( offset.left, winWidth - dialog.outerWidth() + $( window ).scrollLeft(), 1, "dialog left position of right bottom at right bottom on initilization" ); - assert.close( offset.top, winHeight - dialog.outerHeight() + $( window ).scrollTop(), 1, "dialog top position of right bottom at right bottom on initilization" ); - element.remove(); -}); - -test( "position, at another element", function( assert ) { - expect( 4 ); - var parent = $("
").css({ - position: "absolute", - top: 400, - left: 600, - height: 10, - width: 10 - }).appendTo("body"), - - element = $("
").dialog({ - position: { - my: "left top", - at: "left top", - of: parent, - collision: "none" - } - }), - - dialog = element.dialog("widget"), - offset = dialog.offset(); - - assert.close( offset.left, 600, 1, "dialog left position at another element on initilization" ); - assert.close( offset.top, 400, 1, "dialog top position at another element on initilization" ); - - element.dialog("option", "position", { - my: "left top", - at: "right bottom", - of: parent, - collision: "none" - }); - - offset = dialog.offset(); - - assert.close( offset.left, 610, 1, "dialog left position at another element via setting option" ); - assert.close( offset.top, 410, 1, "dialog top position at another element via setting option" ); - - element.remove(); - parent.remove(); -}); - -test("resizable", function() { - expect(4); - - var element = $("
").dialog(); - testHelper.shouldResize(element, 50, 50, "[default]"); - element.dialog("option", "resizable", false); - testHelper.shouldResize(element, 0, 0, "disabled after init"); - element.remove(); - - element = $("
").dialog({ resizable: false }); - testHelper.shouldResize(element, 0, 0, "disabled in init options"); - element.dialog("option", "resizable", true); - testHelper.shouldResize(element, 50, 50, "enabled after init"); - element.remove(); -}); - -test( "title", function() { - expect( 11 ); - - function titleText() { - return element.dialog("widget").find( ".ui-dialog-title" ).html(); - } - - var element = $( "
" ).dialog(); - // some browsers return a non-breaking space and some return " " - // so we generate a non-breaking space for comparison - equal( titleText(), $( " " ).html(), "[default]" ); - equal( element.dialog( "option", "title" ), null, "option not changed" ); - element.remove(); - - element = $( "
" ).dialog(); - equal( titleText(), "foo", "title in element attribute" ); - equal( element.dialog( "option", "title"), "foo", "option updated from attribute" ); - element.remove(); - - element = $( "
" ).dialog({ title: "foo" }); - equal( titleText(), "foo", "title in init options" ); - equal( element.dialog("option", "title"), "foo", "opiton set from options hash" ); - element.remove(); - - element = $( "
" ).dialog({ title: "bar" }); - equal( titleText(), "bar", "title in init options should override title in element attribute" ); - equal( element.dialog("option", "title"), "bar", "opiton set from options hash" ); - element.remove(); - - element = $( "
" ).dialog().dialog( "option", "title", "foo" ); - equal( titleText(), "foo", "title after init" ); - element.remove(); - - // make sure attroperties are properly ignored - #5742 - .attr() might return a DOMElement - element = $( "
" ).dialog(); - // some browsers return a non-breaking space and some return " " - // so we get the text to normalize to the actual non-breaking space - equal( titleText(), $( " " ).html(), "[default]" ); - equal( element.dialog( "option", "title" ), null, "option not changed" ); - element.remove(); -}); - -test("width", function( assert ) { - expect(3); - - var element = $("
").dialog(); - assert.close(element.dialog("widget").width(), 300, 1, "default width"); - element.remove(); - - element = $("
").dialog({width: 437 }); - assert.close(element.dialog("widget").width(), 437, 1, "explicit width"); - element.dialog("option", "width", 438); - assert.close(element.dialog("widget").width(), 438, 1, "explicit width after init"); - element.remove(); -}); - -test("#4826: setting resizable false toggles resizable on dialog", function() { - expect(6); - var i, - element = $("
").dialog({ resizable: false }); - - testHelper.shouldResize(element, 0, 0, "[default]"); - for (i=0; i<2; i++) { - element.dialog("close").dialog("open"); - testHelper.shouldResize(element, 0, 0, "initialized with resizable false toggle ("+ (i+1) +")"); - } - element.remove(); - - element = $("
").dialog({ resizable: true }); - testHelper.shouldResize(element, 50, 50, "[default]"); - for (i=0; i<2; i++) { - element.dialog("close").dialog("option", "resizable", false).dialog("open"); - testHelper.shouldResize(element, 0, 0, "set option resizable false toggle ("+ (i+1) +")"); - } - element.remove(); - -}); - -asyncTest( "#8051 - 'Explode' dialog animation causes crash in IE 6, 7 and 8", function() { - expect( 1 ); - var element = $( "
" ).dialog({ - show: "explode", - focus: function() { - ok( true, "dialog opened with animation" ); - element.remove(); - start(); - } - }); -}); - -asyncTest( "#4421 - Focus lost from dialog which uses show-effect", function() { - expect( 1 ); - var element = $( "
" ).dialog({ - show: "blind", - focus: function() { - equal( element.dialog( "widget" ).find( document.activeElement ).length, 1, "dialog maintains focus" ); - element.remove(); - start(); - } - }); -}); - -asyncTest( "Open followed by close during show effect", function() { - expect( 1 ); - var element = $( "
" ).dialog({ - show: "blind", - close: function() { - ok( true, "dialog closed properly during animation" ); - element.remove(); - start(); - } - }); - - setTimeout( function() { - element.dialog("close"); - }, 100 ); -}); - -} ); diff --git a/tests/unit/dialog/dialog_test_helpers.js b/tests/unit/dialog/dialog_test_helpers.js deleted file mode 100644 index f84d1d624..000000000 --- a/tests/unit/dialog/dialog_test_helpers.js +++ /dev/null @@ -1,55 +0,0 @@ -define( [ - "jquery", - "lib/helper", - "ui/dialog" -], function( $, helper ) { - -return $.extend( helper, { - drag: function(element, handle, dx, dy) { - var d = element.dialog("widget"); - //this mouseover is to work around a limitation in resizable - //TODO: fix resizable so handle doesn't require mouseover in order to be used - $( handle, d ).simulate("mouseover").simulate( "drag", { - dx: dx, - dy: dy - }); - }, - testDrag: function(element, dx, dy, expectedDX, expectedDY, msg) { - var actualDX, actualDY, offsetAfter, - d = element.dialog("widget"), - handle = $(".ui-dialog-titlebar", d), - offsetBefore = d.offset(); - - this.drag(element, handle, dx, dy); - - offsetAfter = d.offset(); - - msg = msg ? msg + "." : ""; - - actualDX = offsetAfter.left - offsetBefore.left; - actualDY = offsetAfter.top - offsetBefore.top; - ok( expectedDX - actualDX <= 1 && expectedDY - actualDY <= 1, "dragged[" + expectedDX + ", " + expectedDY + "] " + msg); - }, - // TODO switch back to checking the size of the .ui-dialog element (var d) - // once we switch to using box-sizing: border-box (#9845) that should work fine - // using the element's dimensions to avoid subpixel errors - shouldResize: function(element, dw, dh, msg) { - var heightAfter, widthAfter, actual, expected, - d = element.dialog("widget"), - handle = $(".ui-resizable-se", d), - heightBefore = element.height(), - widthBefore = element.width(); - - this.drag(element, handle, 50, 50); - - heightAfter = element.height(); - widthAfter = element.width(); - - msg = msg ? msg + "." : ""; - actual = { width: widthAfter, height: heightAfter }, - expected = { width: widthBefore + dw, height: heightBefore + dh }; - deepEqual(actual, expected, "resized[" + 50 + ", " + 50 + "] " + msg); - } -} ); - -} ); diff --git a/tests/unit/dialog/events.js b/tests/unit/dialog/events.js new file mode 100644 index 000000000..5834b3481 --- /dev/null +++ b/tests/unit/dialog/events.js @@ -0,0 +1,370 @@ +define( [ + "jquery", + "./helper", + "ui/dialog" +], function( $, testHelper ) { + +module("dialog: events"); + +test("open", function() { + expect(13); + + var element = $("
"); + element.dialog({ + open: function(ev, ui) { + ok(element.dialog( "instance" )._isOpen, "interal _isOpen flag is set"); + ok(true, "autoOpen: true fires open callback"); + equal(this, element[0], "context of callback"); + equal(ev.type, "dialogopen", "event type in callback"); + deepEqual(ui, {}, "ui hash in callback"); + } + }); + element.remove(); + + element = $("
"); + element.dialog({ + autoOpen: false, + open: function(ev, ui) { + ok(true, ".dialog('open') fires open callback"); + equal(this, element[0], "context of callback"); + equal(ev.type, "dialogopen", "event type in callback"); + deepEqual(ui, {}, "ui hash in callback"); + } + }).bind("dialogopen", function(ev, ui) { + ok(element.dialog( "instance" )._isOpen, "interal _isOpen flag is set"); + ok(true, "dialog('open') fires open event"); + equal(this, element[0], "context of event"); + deepEqual(ui, {}, "ui hash in event"); + }); + element.dialog("open"); + element.remove(); +}); + +test( "focus", function() { + expect( 5 ); + var element, other; + element = $("#dialog1").dialog({ + autoOpen: false + }); + other = $("#dialog2").dialog({ + autoOpen: false + }); + + element.one( "dialogopen", function() { + ok( true, "open, just once" ); + }); + element.one( "dialogfocus", function() { + ok( true, "focus on open" ); + }); + other.dialog( "open" ); + + element.one( "dialogfocus", function() { + ok( true, "when opening and already open and wasn't on top" ); + }); + other.dialog( "open" ); + element.dialog( "open" ); + + element.one( "dialogfocus", function() { + ok( true, "when calling moveToTop and wasn't on top" ); + }); + other.dialog( "moveToTop" ); + element.dialog( "moveToTop" ); + + element.bind( "dialogfocus", function() { + ok( true, "when mousedown anywhere on the dialog and it wasn't on top" ); + }); + other.dialog( "moveToTop" ); + element.trigger( "mousedown" ); + + // triggers just once when already on top + element.dialog( "open" ); + element.dialog( "moveToTop" ); + element.trigger( "mousedown" ); + + element.add( other ).remove(); +}); + +test("dragStart", function() { + expect(9); + + var handle, + element = $("
").dialog({ + dragStart: function(ev, ui) { + ok(true, "dragging fires dragStart callback"); + equal(this, element[0], "context of callback"); + equal(ev.type, "dialogdragstart", "event type in callback"); + ok(ui.position !== undefined, "ui.position in callback"); + ok(ui.offset !== undefined, "ui.offset in callback"); + } + }).bind("dialogdragstart", function(ev, ui) { + ok(true, "dragging fires dialogdragstart event"); + equal(this, element[0], "context of event"); + ok(ui.position !== undefined, "ui.position in callback"); + ok(ui.offset !== undefined, "ui.offset in callback"); + }); + + handle = $(".ui-dialog-titlebar", element.dialog("widget")); + testHelper.drag(element, handle, 50, 50); + element.remove(); +}); + +test("drag", function() { + expect(9); + var handle, + hasDragged = false, + element = $("
").dialog({ + drag: function(ev, ui) { + if (!hasDragged) { + ok(true, "dragging fires drag callback"); + equal(this, element[0], "context of callback"); + equal(ev.type, "dialogdrag", "event type in callback"); + ok(ui.position !== undefined, "ui.position in callback"); + ok(ui.offset !== undefined, "ui.offset in callback"); + + hasDragged = true; + } + } + }).one("dialogdrag", function(ev, ui) { + ok(true, "dragging fires dialogdrag event"); + equal(this, element[0], "context of event"); + ok(ui.position !== undefined, "ui.position in callback"); + ok(ui.offset !== undefined, "ui.offset in callback"); + }); + + handle = $(".ui-dialog-titlebar", element.dialog("widget")); + testHelper.drag(element, handle, 50, 50); + element.remove(); +}); + +test("dragStop", function() { + expect(9); + + var handle, + element = $("
").dialog({ + dragStop: function(ev, ui) { + ok(true, "dragging fires dragStop callback"); + equal(this, element[0], "context of callback"); + equal(ev.type, "dialogdragstop", "event type in callback"); + ok(ui.position !== undefined, "ui.position in callback"); + ok(ui.offset !== undefined, "ui.offset in callback"); + } + }).bind("dialogdragstop", function(ev, ui) { + ok(true, "dragging fires dialogdragstop event"); + equal(this, element[0], "context of event"); + ok(ui.position !== undefined, "ui.position in callback"); + ok(ui.offset !== undefined, "ui.offset in callback"); + }); + + handle = $(".ui-dialog-titlebar", element.dialog("widget")); + testHelper.drag(element, handle, 50, 50); + element.remove(); +}); + +test("resizeStart", function() { + expect(13); + + var handle, + element = $("
").dialog({ + resizeStart: function(ev, ui) { + ok(true, "resizing fires resizeStart callback"); + equal(this, element[0], "context of callback"); + equal(ev.type, "dialogresizestart", "event type in callback"); + ok(ui.originalPosition !== undefined, "ui.originalPosition in callback"); + ok(ui.originalSize !== undefined, "ui.originalSize in callback"); + ok(ui.position !== undefined, "ui.position in callback"); + ok(ui.size !== undefined, "ui.size in callback"); + } + }).bind("dialogresizestart", function(ev, ui) { + ok(true, "resizing fires dialogresizestart event"); + equal(this, element[0], "context of event"); + ok(ui.originalPosition !== undefined, "ui.originalPosition in callback"); + ok(ui.originalSize !== undefined, "ui.originalSize in callback"); + ok(ui.position !== undefined, "ui.position in callback"); + ok(ui.size !== undefined, "ui.size in callback"); + }); + + handle = $(".ui-resizable-se", element.dialog("widget")); + testHelper.drag(element, handle, 50, 50); + element.remove(); +}); + +test("resize", function() { + expect(13); + var handle, + hasResized = false, + element = $("
").dialog({ + resize: function(ev, ui) { + if (!hasResized) { + ok(true, "resizing fires resize callback"); + equal(this, element[0], "context of callback"); + equal(ev.type, "dialogresize", "event type in callback"); + ok(ui.originalPosition !== undefined, "ui.originalPosition in callback"); + ok(ui.originalSize !== undefined, "ui.originalSize in callback"); + ok(ui.position !== undefined, "ui.position in callback"); + ok(ui.size !== undefined, "ui.size in callback"); + + hasResized = true; + } + } + }).one("dialogresize", function(ev, ui) { + ok(true, "resizing fires dialogresize event"); + equal(this, element[0], "context of event"); + ok(ui.originalPosition !== undefined, "ui.originalPosition in callback"); + ok(ui.originalSize !== undefined, "ui.originalSize in callback"); + ok(ui.position !== undefined, "ui.position in callback"); + ok(ui.size !== undefined, "ui.size in callback"); + }); + + handle = $(".ui-resizable-se", element.dialog("widget")); + testHelper.drag(element, handle, 50, 50); + element.remove(); +}); + +test("resizeStop", function() { + expect(13); + + var handle, + element = $("
").dialog({ + resizeStop: function(ev, ui) { + ok(true, "resizing fires resizeStop callback"); + equal(this, element[0], "context of callback"); + equal(ev.type, "dialogresizestop", "event type in callback"); + ok(ui.originalPosition !== undefined, "ui.originalPosition in callback"); + ok(ui.originalSize !== undefined, "ui.originalSize in callback"); + ok(ui.position !== undefined, "ui.position in callback"); + ok(ui.size !== undefined, "ui.size in callback"); + } + }).bind("dialogresizestop", function(ev, ui) { + ok(true, "resizing fires dialogresizestop event"); + equal(this, element[0], "context of event"); + ok(ui.originalPosition !== undefined, "ui.originalPosition in callback"); + ok(ui.originalSize !== undefined, "ui.originalSize in callback"); + ok(ui.position !== undefined, "ui.position in callback"); + ok(ui.size !== undefined, "ui.size in callback"); + }); + + handle = $(".ui-resizable-se", element.dialog("widget")); + testHelper.drag(element, handle, 50, 50); + element.remove(); +}); + +asyncTest("close", function() { + expect(14); + + var element = $("
").dialog({ + close: function(ev, ui) { + ok(true, ".dialog('close') fires close callback"); + equal(this, element[0], "context of callback"); + equal(ev.type, "dialogclose", "event type in callback"); + deepEqual(ui, {}, "ui hash in callback"); + } + }).bind("dialogclose", function(ev, ui) { + ok(true, ".dialog('close') fires dialogclose event"); + equal(this, element[0], "context of event"); + deepEqual(ui, {}, "ui hash in event"); + }); + element.dialog("close"); + element.remove(); + + // Close event with an effect + element = $("
").dialog({ + hide: 10, + close: function(ev, ui) { + ok(true, ".dialog('close') fires close callback"); + equal(this, element[0], "context of callback"); + equal(ev.type, "dialogclose", "event type in callback"); + deepEqual(ui, {}, "ui hash in callback"); + start(); + } + }).bind("dialogclose", function(ev, ui) { + ok(true, ".dialog('close') fires dialogclose event"); + equal(this, element[0], "context of event"); + deepEqual(ui, {}, "ui hash in event"); + }); + element.dialog("close"); +}); + +test("beforeClose", function() { + expect(14); + + var element = $("
").dialog({ + beforeClose: function(ev, ui) { + ok(true, ".dialog('close') fires beforeClose callback"); + equal(this, element[0], "context of callback"); + equal(ev.type, "dialogbeforeclose", "event type in callback"); + deepEqual(ui, {}, "ui hash in callback"); + return false; + } + }); + + element.dialog("close"); + ok( element.dialog("widget").is(":visible"), "beforeClose callback should prevent dialog from closing"); + element.remove(); + + element = $("
").dialog(); + element.dialog("option", "beforeClose", function(ev, ui) { + ok(true, ".dialog('close') fires beforeClose callback"); + equal(this, element[0], "context of callback"); + equal(ev.type, "dialogbeforeclose", "event type in callback"); + deepEqual(ui, {}, "ui hash in callback"); + return false; + }); + element.dialog("close"); + + ok( element.dialog("widget").is(":visible"), "beforeClose callback should prevent dialog from closing"); + element.remove(); + + element = $("
").dialog().bind("dialogbeforeclose", function(ev, ui) { + ok(true, ".dialog('close') triggers dialogbeforeclose event"); + equal(this, element[0], "context of event"); + deepEqual(ui, {}, "ui hash in event"); + return false; + }); + element.dialog("close"); + ok( element.dialog("widget").is(":visible"), "dialogbeforeclose event should prevent dialog from closing"); + element.remove(); +}); + +// #8789 and #8838 +asyncTest("ensure dialog's container doesn't scroll on resize and focus", function() { + expect(2); + + var element = $("#dialog1").dialog(), + initialScroll = $(window).scrollTop(); + element.dialog("option", "height", 600); + equal($(window).scrollTop(), initialScroll, "scroll hasn't moved after height change"); + setTimeout( function(){ + $(".ui-dialog-titlebar-close").simulate("mousedown"); + equal($(window).scrollTop(), initialScroll, "scroll hasn't moved after focus moved to dialog"); + element.dialog("destroy"); + start(); + }); +}); + +test("#5184: isOpen in dialogclose event is true", function() { + expect( 3 ); + + var element = $( "
" ).dialog({ + close: function() { + ok( !element.dialog("isOpen"), "dialog is not open during close" ); + } + }); + ok( element.dialog("isOpen"), "dialog is open after init" ); + element.dialog( "close" ); + ok( !element.dialog("isOpen"), "dialog is not open after close" ); + element.remove(); +}); + +test("ensure dialog keeps focus when clicking modal overlay", function() { + expect( 2 ); + + var element = $( "
" ).dialog({ + modal: true + }); + equal( $( document.activeElement ).closest( ".ui-dialog" ).length, 1, "focus is in dialog" ); + $(".ui-widget-overlay").simulate("mousedown"); + equal( $( document.activeElement ).closest( ".ui-dialog" ).length, 1, "focus is still in dialog" ); + element.remove(); +}); + +} ); diff --git a/tests/unit/dialog/helper.js b/tests/unit/dialog/helper.js new file mode 100644 index 000000000..f84d1d624 --- /dev/null +++ b/tests/unit/dialog/helper.js @@ -0,0 +1,55 @@ +define( [ + "jquery", + "lib/helper", + "ui/dialog" +], function( $, helper ) { + +return $.extend( helper, { + drag: function(element, handle, dx, dy) { + var d = element.dialog("widget"); + //this mouseover is to work around a limitation in resizable + //TODO: fix resizable so handle doesn't require mouseover in order to be used + $( handle, d ).simulate("mouseover").simulate( "drag", { + dx: dx, + dy: dy + }); + }, + testDrag: function(element, dx, dy, expectedDX, expectedDY, msg) { + var actualDX, actualDY, offsetAfter, + d = element.dialog("widget"), + handle = $(".ui-dialog-titlebar", d), + offsetBefore = d.offset(); + + this.drag(element, handle, dx, dy); + + offsetAfter = d.offset(); + + msg = msg ? msg + "." : ""; + + actualDX = offsetAfter.left - offsetBefore.left; + actualDY = offsetAfter.top - offsetBefore.top; + ok( expectedDX - actualDX <= 1 && expectedDY - actualDY <= 1, "dragged[" + expectedDX + ", " + expectedDY + "] " + msg); + }, + // TODO switch back to checking the size of the .ui-dialog element (var d) + // once we switch to using box-sizing: border-box (#9845) that should work fine + // using the element's dimensions to avoid subpixel errors + shouldResize: function(element, dw, dh, msg) { + var heightAfter, widthAfter, actual, expected, + d = element.dialog("widget"), + handle = $(".ui-resizable-se", d), + heightBefore = element.height(), + widthBefore = element.width(); + + this.drag(element, handle, 50, 50); + + heightAfter = element.height(); + widthAfter = element.width(); + + msg = msg ? msg + "." : ""; + actual = { width: widthAfter, height: heightAfter }, + expected = { width: widthBefore + dw, height: heightBefore + dh }; + deepEqual(actual, expected, "resized[" + 50 + ", " + 50 + "] " + msg); + } +} ); + +} ); diff --git a/tests/unit/dialog/methods.js b/tests/unit/dialog/methods.js new file mode 100644 index 000000000..10b0fd7bb --- /dev/null +++ b/tests/unit/dialog/methods.js @@ -0,0 +1,267 @@ +define( [ + "jquery", + "ui/dialog" +], function( $ ) { + +module("dialog: methods", { + teardown: function() { + $("body>.ui-dialog").remove(); + } +}); + +test("init", function() { + expect(6); + + $("
").appendTo("body").dialog().remove(); + ok(true, ".dialog() called on element"); + + $([]).dialog().remove(); + ok(true, ".dialog() called on empty collection"); + + $("
").dialog().remove(); + ok(true, ".dialog() called on disconnected DOMElement - never connected"); + + $("
").appendTo("body").remove().dialog().remove(); + ok(true, ".dialog() called on disconnected DOMElement - removed"); + + var element = $("
").dialog(); + element.dialog("option", "foo"); + element.remove(); + ok(true, "arbitrary option getter after init"); + + $("
").dialog().dialog("option", "foo", "bar").remove(); + ok(true, "arbitrary option setter after init"); +}); + +test("destroy", function( assert ) { + expect( 17 ); + + var element, element2; + + $( "#dialog1, #form-dialog" ).hide(); + assert.domEqual( "#dialog1", function() { + var dialog = $( "#dialog1" ).dialog().dialog( "destroy" ); + equal( dialog.parent()[ 0 ], $( "#qunit-fixture" )[ 0 ] ); + equal( dialog.index(), 0 ); + }); + assert.domEqual( "#form-dialog", function() { + var dialog = $( "#form-dialog" ).dialog().dialog( "destroy" ); + equal( dialog.parent()[ 0 ], $( "#qunit-fixture" )[ 0 ] ); + equal( dialog.index(), 2 ); + }); + + // Ensure dimensions are restored (#8119) + $( "#dialog1" ).show().css({ + width: "400px", + minHeight: "100px", + height: "200px" + }); + assert.domEqual( "#dialog1", function() { + $( "#dialog1" ).dialog().dialog( "destroy" ); + }); + + // Don't throw errors when destroying a never opened modal dialog (#9004) + $( "#dialog1" ).dialog({ autoOpen: false, modal: true }).dialog( "destroy" ); + equal( $( ".ui-widget-overlay" ).length, 0, "overlay does not exist" ); + equal( $( document ).data( "ui-dialog-overlays" ), undefined, "ui-dialog-overlays equals the number of open overlays"); + + element = $( "#dialog1" ).dialog({ modal: true }), + element2 = $( "#dialog2" ).dialog({ modal: true }); + equal( $( ".ui-widget-overlay" ).length, 2, "overlays created when dialogs are open" ); + equal( $( document ).data( "ui-dialog-overlays" ), 2, "ui-dialog-overlays equals the number of open overlays" ); + element.dialog( "close" ); + equal( $( ".ui-widget-overlay" ).length, 1, "overlay remains after closing one dialog" ); + equal( $( document ).data( "ui-dialog-overlays" ), 1, "ui-dialog-overlays equals the number of open overlays" ); + element.dialog( "destroy" ); + equal( $( ".ui-widget-overlay" ).length, 1, "overlay remains after destroying one dialog" ); + equal( $( document ).data( "ui-dialog-overlays" ), 1, "ui-dialog-overlays equals the number of open overlays" ); + element2.dialog( "destroy" ); + equal( $( ".ui-widget-overlay" ).length, 0, "overlays removed when all dialogs are destoryed" ); + equal( $( document ).data( "ui-dialog-overlays" ), undefined, "ui-dialog-overlays equals the number of open overlays" ); +}); + +asyncTest("#9000: Dialog leaves broken event handler after close/destroy in certain cases", function() { + expect( 1 ); + $( "#dialog1" ).dialog({ modal:true }).dialog( "close" ).dialog( "destroy" ); + setTimeout(function() { + $( "#favorite-animal" ).focus(); + ok( true, "close and destroy modal dialog before its really opened" ); + start(); + }); +}); + +test("#4980: Destroy should place element back in original DOM position", function(){ + expect( 2 ); + var container = $("
"), + modal = container.find("#modal"); + modal.dialog(); + ok(!$.contains(container[0], modal[0]), "dialog should move modal element to outside container element"); + modal.dialog("destroy"); + ok($.contains(container[0], modal[0]), "dialog(destroy) should place element back in original DOM position"); +}); + +test( "enable/disable disabled", function( assert ) { + expect( 3 ); + var element = $( "
" ).dialog(); + element.dialog( "disable" ); + equal(element.dialog( "option", "disabled" ), false, "disable method doesn't do anything" ); + assert.lacksClasses( element, "ui-dialog-disabled ui-state-disabled", "disable method doesn't add classes" ); + ok( !element.dialog( "widget" ).attr( "aria-disabled" ), "disable method doesn't add aria-disabled" ); +}); + +test("close", function() { + expect( 3 ); + + var element, + expected = $("
").dialog(), + actual = expected.dialog("close"); + equal(actual, expected, "close is chainable"); + + element = $("
").dialog(); + ok(element.dialog("widget").is(":visible") && !element.dialog("widget").is(":hidden"), "dialog visible before close method called"); + element.dialog("close"); + ok(element.dialog("widget").is(":hidden") && !element.dialog("widget").is(":visible"), "dialog hidden after close method called"); +}); + +test("isOpen", function() { + expect(4); + + var element = $("
").dialog(); + equal(element.dialog("isOpen"), true, "dialog is open after init"); + element.dialog("close"); + equal(element.dialog("isOpen"), false, "dialog is closed"); + element.remove(); + + element = $("
").dialog({autoOpen: false}); + equal(element.dialog("isOpen"), false, "dialog is closed after init"); + element.dialog("open"); + equal(element.dialog("isOpen"), true, "dialog is open"); + element.remove(); +}); + +test("moveToTop", function() { + expect( 5 ); + function order() { + var actual = $( ".ui-dialog" ).map(function() { + return +$( this ).css( "z-index" ); + }).get(); + deepEqual( actual, $.makeArray( arguments ) ); + } + var dialog1, dialog2, + focusOn = "dialog1"; + dialog1 = $( "#dialog1" ).dialog({ + focus: function() { + equal( focusOn, "dialog1" ); + } + }); + focusOn = "dialog2"; + dialog2 = $( "#dialog2" ).dialog({ + focus: function() { + equal( focusOn, "dialog2" ); + } + }); + order( 100, 101 ); + focusOn = "dialog1"; + dialog1.dialog( "moveToTop" ); + order( 102, 101 ); +}); + +test( "moveToTop: content scroll stays intact", function() { + expect( 2 ); + var otherDialog = $( "#dialog1" ).dialog(), + scrollDialog = $( "#form-dialog" ).dialog({ + height: 200 + }); + scrollDialog.scrollTop( 50 ); + equal( scrollDialog.scrollTop(), 50 ); + + otherDialog.dialog( "moveToTop" ); + equal( scrollDialog.scrollTop(), 50 ); +}); + +test("open", function() { + expect( 3 ); + var element, + expected = $("
").dialog(), + actual = expected.dialog("open"); + equal(actual, expected, "open is chainable"); + + element = $("
").dialog({ autoOpen: false }); + ok(element.dialog("widget").is(":hidden") && !element.dialog("widget").is(":visible"), "dialog hidden before open method called"); + element.dialog("open"); + ok(element.dialog("widget").is(":visible") && !element.dialog("widget").is(":hidden"), "dialog visible after open method called"); +}); + +// http://bugs.jqueryui.com/ticket/6137 +test("Ensure form elements don't reset when opening a dialog", function() { + expect(2); + + var d1 = $("
" + + "b
").appendTo( "body" ).dialog({autoOpen: false}); + + d1.find("#b").prop( "checked", true ); + equal(d1.find("input:checked").val(), "b", "checkbox b is checked"); + + d1.dialog("open"); + equal(d1.find("input:checked").val(), "b", "checkbox b is checked"); + + d1.remove(); +}); + +asyncTest( "#8958: dialog can be opened while opening", function() { + expect( 1 ); + + var element = $( "
" ).dialog({ + autoOpen: false, + modal: true, + open: function() { + equal( $( ".ui-widget-overlay" ).length, 1 ); + start(); + } + }); + + // Support: IE8 + // For some reason the #favorite-color input doesn't get focus if we don't + // focus the body first, causing the test to hang. + $( "body" ).focus(); + + $( "#favorite-animal" ) + // We focus the input to start the test. Once it receives focus, the + // dialog will open. Opening the dialog, will cause an element inside + // the dialog to gain focus, thus blurring the input. + .bind( "focus", function() { + element.dialog( "open" ); + }) + // When the input blurs, the dialog is in the process of opening. We + // try to open the dialog again, to make sure that dialogs properly + // handle a call to the open() method during the process of the dialog + // being opened. + .bind( "blur", function() { + element.dialog( "open" ); + }) + .focus(); +}); + +test("#5531: dialog width should be at least minWidth on creation", function () { + expect( 4 ); + var element = $("
").dialog({ + width: 200, + minWidth: 300 + }); + + equal(element.dialog("option", "width"), 300, "width is minWidth"); + element.dialog("option", "width", 200); + equal(element.dialog("option", "width"), 300, "width unchanged when set to < minWidth"); + element.dialog("option", "width", 320); + equal(element.dialog("option", "width"), 320, "width changed if set to > minWidth"); + element.remove(); + + element = $("
").dialog({ + minWidth: 300 + }); + ok(element.dialog("option", "width") >= 300, "width is at least 300"); + element.remove(); + +}); + +} ); diff --git a/tests/unit/dialog/options.js b/tests/unit/dialog/options.js new file mode 100644 index 000000000..c33a97c01 --- /dev/null +++ b/tests/unit/dialog/options.js @@ -0,0 +1,557 @@ +define( [ + "jquery", + "./helper", + "ui/dialog", + "ui/effect-blind", + "ui/effect-explode" +], function( $, testHelper ) { + +module("dialog: options"); + +test( "appendTo", function() { + expect( 16 ); + var detached = $( "
" ), + element = $( "#dialog1" ).dialog({ + modal: true + }); + equal( element.dialog( "widget" ).parent()[0], document.body, "defaults to body" ); + equal( $( ".ui-widget-overlay" ).parent()[0], document.body, "overlay defaults to body" ); + element.dialog( "destroy" ); + + element.dialog({ + appendTo: ".wrap", + modal: true + }); + equal( element.dialog( "widget" ).parent()[0], $( "#wrap1" )[0], "first found element" ); + equal( $( ".ui-widget-overlay" ).parent()[0], $( "#wrap1" )[0], "overlay first found element" ); + equal( $( "#wrap2 .ui-dialog" ).length, 0, "only appends to one element" ); + equal( $( "#wrap2 .ui-widget-overlay" ).length, 0, "overlay only appends to one element" ); + element.dialog( "destroy" ); + + element.dialog({ + appendTo: null, + modal: true + }); + equal( element.dialog( "widget" ).parent()[0], document.body, "null" ); + equal( $( ".ui-widget-overlay" ).parent()[0], document.body, "overlay null" ); + element.dialog( "destroy" ); + + element.dialog({ + autoOpen: false, + modal: true + }).dialog( "option", "appendTo", "#wrap1" ).dialog( "open" ); + equal( element.dialog( "widget" ).parent()[0], $( "#wrap1" )[0], "modified after init" ); + equal( $( ".ui-widget-overlay" ).parent()[0], $( "#wrap1" )[0], "overlay modified after init" ); + element.dialog( "destroy" ); + + element.dialog({ + appendTo: detached, + modal: true + }); + equal( element.dialog( "widget" ).parent()[0], detached[0], "detached jQuery object" ); + equal( detached.find( ".ui-widget-overlay" ).parent()[0], detached[0], "overlay detached jQuery object" ); + element.dialog( "destroy" ); + + element.dialog({ + appendTo: detached[0], + modal: true + }); + equal( element.dialog( "widget" ).parent()[0], detached[0], "detached DOM element" ); + equal( detached.find( ".ui-widget-overlay" ).parent()[0], detached[0], "overlay detached DOM element" ); + element.dialog( "destroy" ); + + element.dialog({ + autoOpen: false, + modal: true + }).dialog( "option", "appendTo", detached ); + equal( element.dialog( "widget" ).parent()[0], detached[0], "detached DOM element via option()" ); + equal( detached.find( ".ui-widget-overlay" ).length, 0, "overlay detached DOM element via option()" ); + element.dialog( "destroy" ); +}); + +test("autoOpen", function() { + expect(2); + + var element = $("
").dialog({ autoOpen: false }); + ok( !element.dialog("widget").is(":visible"), ".dialog({ autoOpen: false })"); + element.remove(); + + element = $("
").dialog({ autoOpen: true }); + ok( element.dialog("widget").is(":visible"), ".dialog({ autoOpen: true })"); + element.remove(); +}); + +test("buttons", function( assert ) { + expect(21); + + var btn, i, newButtons, + buttons = { + "Ok": function( ev ) { + ok(true, "button click fires callback"); + equal(this, element[0], "context of callback"); + equal(ev.target, btn[0], "event target"); + }, + "Cancel": function( ev ) { + ok(true, "button click fires callback"); + equal(this, element[0], "context of callback"); + equal(ev.target, btn[1], "event target"); + } + }, + element = $("
").dialog({ buttons: buttons }); + + btn = element.dialog( "widget" ).find( ".ui-dialog-buttonpane button" ); + equal(btn.length, 2, "number of buttons"); + + i = 0; + $.each(buttons, function( key ) { + equal(btn.eq(i).text(), key, "text of button " + (i+1)); + i++; + }); + + assert.hasClasses( btn.parent(), "ui-dialog-buttonset" ); + assert.hasClasses( element.parent(), "ui-dialog-buttons" ); + + btn.trigger("click"); + + newButtons = { + "Close": function( ev ) { + ok(true, "button click fires callback"); + equal(this, element[0], "context of callback"); + equal(ev.target, btn[0], "event target"); + } + }; + + deepEqual(element.dialog("option", "buttons"), buttons, ".dialog('option', 'buttons') getter"); + element.dialog("option", "buttons", newButtons); + deepEqual(element.dialog("option", "buttons"), newButtons, ".dialog('option', 'buttons', ...) setter"); + + btn = element.dialog( "widget" ).find( ".ui-dialog-buttonpane button" ); + equal(btn.length, 1, "number of buttons after setter"); + btn.trigger("click"); + + i = 0; + $.each(newButtons, function( key ) { + equal(btn.eq(i).text(), key, "text of button " + (i+1)); + i += 1; + }); + + element.dialog("option", "buttons", null); + btn = element.dialog( "widget" ).find( ".ui-dialog-buttonpane button" ); + equal(btn.length, 0, "all buttons have been removed"); + equal(element.find(".ui-dialog-buttonset").length, 0, "buttonset has been removed"); + assert.lacksClasses( element.parent(), "ui-dialog-buttons" ); + element.remove(); +}); + +test("buttons - advanced", function( assert ) { + expect( 7 ); + + var buttons, + element = $("
").dialog({ + buttons: [ + { + text: "a button", + "class": "additional-class", + id: "my-button-id", + click: function() { + equal(this, element[0], "correct context"); + }, + icons: { + primary: "ui-icon-cancel" + }, + showText: false + } + ] + }); + + buttons = element.dialog( "widget" ).find( ".ui-dialog-buttonpane button" ); + equal(buttons.length, 1, "correct number of buttons"); + equal(buttons.attr("id"), "my-button-id", "correct id"); + equal(buttons.text(), "a button", "correct label"); + assert.hasClasses( buttons, "additional-class" ); + deepEqual( buttons.button("option", "icons"), { primary: "ui-icon-cancel", secondary: null } ); + equal( buttons.button( "option", "text" ), false ); + buttons.click(); + + element.remove(); +}); + +test("#9043: buttons with Array.prototype modification", function() { + expect( 1 ); + Array.prototype.test = $.noop; + var element = $( "
" ).dialog(); + equal( element.dialog( "widget" ).find( ".ui-dialog-buttonpane" ).length, 0, + "no button pane" ); + element.remove(); + delete Array.prototype.test; +}); + +test("closeOnEscape", function() { + expect( 6 ); + var element = $("
").dialog({ closeOnEscape: false }); + ok(true, "closeOnEscape: false"); + ok(element.dialog("widget").is(":visible") && !element.dialog("widget").is(":hidden"), "dialog is open before ESC"); + element.simulate("keydown", { keyCode: $.ui.keyCode.ESCAPE }) + .simulate("keypress", { keyCode: $.ui.keyCode.ESCAPE }) + .simulate("keyup", { keyCode: $.ui.keyCode.ESCAPE }); + ok(element.dialog("widget").is(":visible") && !element.dialog("widget").is(":hidden"), "dialog is open after ESC"); + + element.remove(); + + element = $("
").dialog({ closeOnEscape: true }); + ok(true, "closeOnEscape: true"); + ok(element.dialog("widget").is(":visible") && !element.dialog("widget").is(":hidden"), "dialog is open before ESC"); + element.simulate("keydown", { keyCode: $.ui.keyCode.ESCAPE }) + .simulate("keypress", { keyCode: $.ui.keyCode.ESCAPE }) + .simulate("keyup", { keyCode: $.ui.keyCode.ESCAPE }); + ok(element.dialog("widget").is(":hidden") && !element.dialog("widget").is(":visible"), "dialog is closed after ESC"); +}); + +test("closeText", function() { + expect(3); + + var element = $("
").dialog(); + equal(element.dialog("widget").find(".ui-dialog-titlebar-close span").text(), "Close", + "default close text"); + element.remove(); + + element = $("
").dialog({ closeText: "foo" }); + equal(element.dialog("widget").find(".ui-dialog-titlebar-close span").text(), "foo", + "closeText on init"); + element.remove(); + + element = $("
").dialog().dialog("option", "closeText", "bar"); + equal(element.dialog("widget").find(".ui-dialog-titlebar-close span").text(), "bar", + "closeText via option method"); + element.remove(); +}); + +test("draggable", function() { + expect(4); + + var element = $("
").dialog({ draggable: false }); + + testHelper.testDrag(element, 50, -50, 0, 0); + element.dialog("option", "draggable", true); + testHelper.testDrag(element, 50, -50, 50, -50); + element.remove(); + + element = $("
").dialog({ draggable: true }); + testHelper.testDrag(element, 50, -50, 50, -50); + element.dialog("option", "draggable", false); + testHelper.testDrag(element, 50, -50, 0, 0); + element.remove(); +}); + +test("height", function() { + expect(4); + + var element = $("
").dialog(); + equal(element.dialog("widget").outerHeight(), 150, "default height"); + element.remove(); + + element = $("
").dialog({ height: 237 }); + equal(element.dialog("widget").outerHeight(), 237, "explicit height"); + element.remove(); + + element = $("
").dialog(); + element.dialog("option", "height", 238); + equal(element.dialog("widget").outerHeight(), 238, "explicit height set after init"); + element.remove(); + + element = $("
").css("padding", "20px") + .dialog({ height: 240 }); + equal(element.dialog("widget").outerHeight(), 240, "explicit height with padding"); + element.remove(); +}); + +test("maxHeight", function( assert ) { + expect(3); + + var element = $("
").dialog({ maxHeight: 200 }); + testHelper.drag(element, ".ui-resizable-s", 1000, 1000); + assert.close(element.dialog("widget").height(), 200, 1, "maxHeight"); + element.remove(); + + element = $("
").dialog({ maxHeight: 200 }); + testHelper.drag(element, ".ui-resizable-n", -1000, -1000); + assert.close(element.dialog("widget").height(), 200, 1, "maxHeight"); + element.remove(); + + element = $("
").dialog({ maxHeight: 200 }).dialog("option", "maxHeight", 300); + testHelper.drag(element, ".ui-resizable-s", 1000, 1000); + assert.close(element.dialog("widget").height(), 300, 1, "maxHeight"); + element.remove(); +}); + +test("maxWidth", function( assert ) { + expect(3); + + var element = $("
").dialog({ maxWidth: 200 }); + testHelper.drag(element, ".ui-resizable-e", 1000, 1000); + assert.close(element.dialog("widget").width(), 200, 1, "maxWidth"); + element.remove(); + + element = $("
").dialog({ maxWidth: 200 }); + testHelper.drag(element, ".ui-resizable-w", -1000, -1000); + assert.close(element.dialog("widget").width(), 200, 1, "maxWidth"); + element.remove(); + + element = $("
").dialog({ maxWidth: 200 }).dialog("option", "maxWidth", 300); + testHelper.drag(element, ".ui-resizable-w", -1000, -1000); + assert.close(element.dialog("widget").width(), 300, 1, "maxWidth"); + element.remove(); +}); + +test("minHeight", function( assert ) { + expect(3); + + var element = $("
").dialog({ minHeight: 10 }); + testHelper.drag(element, ".ui-resizable-s", -1000, -1000); + assert.close(element.dialog("widget").height(), 10, 1, "minHeight"); + element.remove(); + + element = $("
").dialog({ minHeight: 10 }); + testHelper.drag(element, ".ui-resizable-n", 1000, 1000); + assert.close(element.dialog("widget").height(), 10, 1, "minHeight"); + element.remove(); + + element = $("
").dialog({ minHeight: 10 }).dialog("option", "minHeight", 30); + testHelper.drag(element, ".ui-resizable-n", 1000, 1000); + assert.close(element.dialog("widget").height(), 30, 1, "minHeight"); + element.remove(); +}); + +test("minWidth", function( assert ) { + expect(3); + + var element = $("
").dialog({ minWidth: 10 }); + testHelper.drag(element, ".ui-resizable-e", -1000, -1000); + assert.close(element.dialog("widget").width(), 10, 1, "minWidth"); + element.remove(); + + element = $("
").dialog({ minWidth: 10 }); + testHelper.drag(element, ".ui-resizable-w", 1000, 1000); + assert.close(element.dialog("widget").width(), 10, 1, "minWidth"); + element.remove(); + + element = $("
").dialog({ minWidth: 30 }).dialog("option", "minWidth", 30); + testHelper.drag(element, ".ui-resizable-w", 1000, 1000); + assert.close(element.dialog("widget").width(), 30, 1, "minWidth"); + element.remove(); +}); + +test( "position, default center on window", function( assert ) { + expect( 2 ); + + // dialogs alter the window width and height in Firefox + // so we collect that information before creating the dialog + // Support: Firefox + var winWidth = $( window ).width(), + winHeight = $( window ).height(), + element = $("
").dialog(), + dialog = element.dialog("widget"), + offset = dialog.offset(); + assert.close( offset.left, Math.round( winWidth / 2 - dialog.outerWidth() / 2 ) + $( window ).scrollLeft(), 1, "dialog left position of center on window on initilization" ); + assert.close( offset.top, Math.round( winHeight / 2 - dialog.outerHeight() / 2 ) + $( window ).scrollTop(), 1, "dialog top position of center on window on initilization" ); + element.remove(); +}); + +test( "position, right bottom at right bottom via ui.position args", function( assert ) { + expect( 2 ); + + // dialogs alter the window width and height in Firefox + // so we collect that information before creating the dialog + // Support: Firefox + var winWidth = $( window ).width(), + winHeight = $( window ).height(), + element = $("
").dialog({ + position: { + my: "right bottom", + at: "right bottom" + } + }), + dialog = element.dialog("widget"), + offset = dialog.offset(); + + assert.close( offset.left, winWidth - dialog.outerWidth() + $( window ).scrollLeft(), 1, "dialog left position of right bottom at right bottom on initilization" ); + assert.close( offset.top, winHeight - dialog.outerHeight() + $( window ).scrollTop(), 1, "dialog top position of right bottom at right bottom on initilization" ); + element.remove(); +}); + +test( "position, at another element", function( assert ) { + expect( 4 ); + var parent = $("
").css({ + position: "absolute", + top: 400, + left: 600, + height: 10, + width: 10 + }).appendTo("body"), + + element = $("
").dialog({ + position: { + my: "left top", + at: "left top", + of: parent, + collision: "none" + } + }), + + dialog = element.dialog("widget"), + offset = dialog.offset(); + + assert.close( offset.left, 600, 1, "dialog left position at another element on initilization" ); + assert.close( offset.top, 400, 1, "dialog top position at another element on initilization" ); + + element.dialog("option", "position", { + my: "left top", + at: "right bottom", + of: parent, + collision: "none" + }); + + offset = dialog.offset(); + + assert.close( offset.left, 610, 1, "dialog left position at another element via setting option" ); + assert.close( offset.top, 410, 1, "dialog top position at another element via setting option" ); + + element.remove(); + parent.remove(); +}); + +test("resizable", function() { + expect(4); + + var element = $("
").dialog(); + testHelper.shouldResize(element, 50, 50, "[default]"); + element.dialog("option", "resizable", false); + testHelper.shouldResize(element, 0, 0, "disabled after init"); + element.remove(); + + element = $("
").dialog({ resizable: false }); + testHelper.shouldResize(element, 0, 0, "disabled in init options"); + element.dialog("option", "resizable", true); + testHelper.shouldResize(element, 50, 50, "enabled after init"); + element.remove(); +}); + +test( "title", function() { + expect( 11 ); + + function titleText() { + return element.dialog("widget").find( ".ui-dialog-title" ).html(); + } + + var element = $( "
" ).dialog(); + // some browsers return a non-breaking space and some return " " + // so we generate a non-breaking space for comparison + equal( titleText(), $( " " ).html(), "[default]" ); + equal( element.dialog( "option", "title" ), null, "option not changed" ); + element.remove(); + + element = $( "
" ).dialog(); + equal( titleText(), "foo", "title in element attribute" ); + equal( element.dialog( "option", "title"), "foo", "option updated from attribute" ); + element.remove(); + + element = $( "
" ).dialog({ title: "foo" }); + equal( titleText(), "foo", "title in init options" ); + equal( element.dialog("option", "title"), "foo", "opiton set from options hash" ); + element.remove(); + + element = $( "
" ).dialog({ title: "bar" }); + equal( titleText(), "bar", "title in init options should override title in element attribute" ); + equal( element.dialog("option", "title"), "bar", "opiton set from options hash" ); + element.remove(); + + element = $( "
" ).dialog().dialog( "option", "title", "foo" ); + equal( titleText(), "foo", "title after init" ); + element.remove(); + + // make sure attroperties are properly ignored - #5742 - .attr() might return a DOMElement + element = $( "
" ).dialog(); + // some browsers return a non-breaking space and some return " " + // so we get the text to normalize to the actual non-breaking space + equal( titleText(), $( " " ).html(), "[default]" ); + equal( element.dialog( "option", "title" ), null, "option not changed" ); + element.remove(); +}); + +test("width", function( assert ) { + expect(3); + + var element = $("
").dialog(); + assert.close(element.dialog("widget").width(), 300, 1, "default width"); + element.remove(); + + element = $("
").dialog({width: 437 }); + assert.close(element.dialog("widget").width(), 437, 1, "explicit width"); + element.dialog("option", "width", 438); + assert.close(element.dialog("widget").width(), 438, 1, "explicit width after init"); + element.remove(); +}); + +test("#4826: setting resizable false toggles resizable on dialog", function() { + expect(6); + var i, + element = $("
").dialog({ resizable: false }); + + testHelper.shouldResize(element, 0, 0, "[default]"); + for (i=0; i<2; i++) { + element.dialog("close").dialog("open"); + testHelper.shouldResize(element, 0, 0, "initialized with resizable false toggle ("+ (i+1) +")"); + } + element.remove(); + + element = $("
").dialog({ resizable: true }); + testHelper.shouldResize(element, 50, 50, "[default]"); + for (i=0; i<2; i++) { + element.dialog("close").dialog("option", "resizable", false).dialog("open"); + testHelper.shouldResize(element, 0, 0, "set option resizable false toggle ("+ (i+1) +")"); + } + element.remove(); + +}); + +asyncTest( "#8051 - 'Explode' dialog animation causes crash in IE 6, 7 and 8", function() { + expect( 1 ); + var element = $( "
" ).dialog({ + show: "explode", + focus: function() { + ok( true, "dialog opened with animation" ); + element.remove(); + start(); + } + }); +}); + +asyncTest( "#4421 - Focus lost from dialog which uses show-effect", function() { + expect( 1 ); + var element = $( "
" ).dialog({ + show: "blind", + focus: function() { + equal( element.dialog( "widget" ).find( document.activeElement ).length, 1, "dialog maintains focus" ); + element.remove(); + start(); + } + }); +}); + +asyncTest( "Open followed by close during show effect", function() { + expect( 1 ); + var element = $( "
" ).dialog({ + show: "blind", + close: function() { + ok( true, "dialog closed properly during animation" ); + element.remove(); + start(); + } + }); + + setTimeout( function() { + element.dialog("close"); + }, 100 ); +}); + +} ); diff --git a/tests/unit/draggable/common.js b/tests/unit/draggable/common.js new file mode 100644 index 000000000..7ae032c0f --- /dev/null +++ b/tests/unit/draggable/common.js @@ -0,0 +1,48 @@ +define( [ + "lib/common", + "ui/draggable" +], function( common ) { + +common.testWidget( "draggable", { + defaults: { + appendTo: "parent", + axis: false, + cancel: "input, textarea, button, select, option", + classes: {}, + connectToSortable: false, + containment: false, + cursor: "auto", + cursorAt: false, + disabled: false, + grid: false, + handle: false, + helper: "original", + opacity: false, + refreshPositions: false, + revert: false, + revertDuration: 500, + scroll: true, + scrollSensitivity: 20, + scrollSpeed: 20, + scope: "default", + snap: false, + snapMode: "both", + snapTolerance: 20, + stack: false, + zIndex: false, + + //todo: remove the following option checks when interactions are rewritten: + addClasses: true, + delay: 0, + distance: 1, + iframeFix: false, + + // callbacks + create: null, + drag: null, + start: null, + stop: null + } +}); + +} ); diff --git a/tests/unit/draggable/core.js b/tests/unit/draggable/core.js new file mode 100644 index 000000000..6e12b3521 --- /dev/null +++ b/tests/unit/draggable/core.js @@ -0,0 +1,346 @@ +define( [ + "jquery", + "./helper", + "ui/draggable", + "ui/droppable", + "ui/resizable" +], function( $, testHelper ) { + +module( "draggable: core" ); + +test( "element types", function( assert ) { + var typeNames = ( + "p,h1,h2,h3,h4,h5,h6,blockquote,ol,ul,dl,div,form" + + ",table,fieldset,address,ins,del,em,strong,q,cite,dfn,abbr" + + ",acronym,code,samp,kbd,var,img,hr" + + ",input,button,label,select,iframe" + ).split(","); + + expect( typeNames.length * 2 ); + + $.each( typeNames, function( i ) { + var offsetBefore, offsetAfter, + typeName = typeNames[ i ], + el = $( document.createElement( typeName ) ).appendTo("#qunit-fixture"); + + if ( typeName === "table" ) { + el.append("content"); + } + + el.draggable({ cancel: "" }); + offsetBefore = el.offset(); + el.simulate( "drag", { + dx: 50, + dy: 50 + }); + offsetAfter = el.offset(); + + // Support: FF, Chrome, and IE9, + // there are some rounding errors in so we can't say equal, we have to settle for close enough + assert.close( offsetBefore.left, offsetAfter.left - 50, 1, "dragged[50, 50] " + "<" + typeName + "> left" ); + assert.close( offsetBefore.top, offsetAfter.top - 50, 1, "dragged[50, 50] " + "<" + typeName + "> top" ); + el.draggable("destroy"); + el.remove(); + }); +}); + +test( "No options, relative", function() { + expect( 2 ); + testHelper.shouldMove( $( "#draggable1" ).draggable(), "no options, relative" ); +}); + +test( "No options, absolute", function() { + expect( 2 ); + testHelper.shouldMove( $( "#draggable2" ).draggable(), "no options, absolute" ); +}); + +test( "resizable handle with complex markup (#8756 / #8757)", function() { + expect( 2 ); + + $( "#draggable1" ) + .append( + $("
") + .addClass("ui-resizable-handle ui-resizable-w") + .append( $("
") ) + ); + + var handle = $(".ui-resizable-w div"), + target = $( "#draggable1" ).draggable().resizable({ handles: "all" }); + + // todo: fix resizable so it doesn't require a mouseover + handle.simulate("mouseover").simulate( "drag", { dx: -50 } ); + equal( target.width(), 250, "compare width" ); + + // todo: fix resizable so it doesn't require a mouseover + handle.simulate("mouseover").simulate( "drag", { dx: 50 } ); + equal( target.width(), 200, "compare width" ); +}); + +test( "#8269: Removing draggable element on drop", function() { + expect( 2 ); + + var element = $( "#draggable1" ).wrap( "
" ).draggable({ + stop: function() { + ok( true, "stop still called despite element being removed from DOM on drop" ); + } + }), + dropOffset = $( "#droppable" ).offset(); + + $( "#droppable" ).droppable({ + drop: function() { + $( "#wrapper" ).remove(); + ok( true, "element removed from DOM on drop" ); + } + }); + + // Support: Opera 12.10, Safari 5.1, jQuery <1.8 + if ( testHelper.unreliableContains ) { + ok( true, "Opera <12.14 and Safari <6.0 report wrong values for $.contains in jQuery < 1.8" ); + ok( true, "Opera <12.14 and Safari <6.0 report wrong values for $.contains in jQuery < 1.8" ); + } else { + element.simulate( "drag", { + handle: "corner", + x: dropOffset.left, + y: dropOffset.top + }); + } +}); + +// http://bugs.jqueryui.com/ticket/7778 +// drag element breaks in IE8 when its content is replaced onmousedown +test( "Stray mousemove after mousedown still drags", function() { + expect( 2 ); + + var element = $( "#draggable1" ).draggable({ scroll: false }); + + // In IE8, when content is placed under the mouse (e.g. when draggable content is replaced + // on mousedown), mousemove is triggered on those elements even though the mouse hasn't moved. + // Support: IE <9 + element.bind( "mousedown", function() { + $( document ).simulate( "mousemove", { button: -1 }); + }); + + testHelper.shouldMove( element, "element is draggable" ); +}); + +test( "#6258: not following mouse when scrolled and using overflow-y: scroll", function() { + expect( 2 ); + + var element = $( "#draggable1" ).draggable({ + stop: function( event, ui ) { + equal( ui.position.left, 1, "left position is correct despite overflow on HTML" ); + equal( ui.position.top, 1, "top position is correct despite overflow on HTML" ); + $( "html" ) + .css( "overflow-y", oldOverflowY ) + .css( "overflow-x", oldOverflowX ) + .scrollTop( 0 ) + .scrollLeft( 0 ); + } + }), + oldOverflowY = $( "html" ).css( "overflow-y" ), + oldOverflowX = $( "html" ).css( "overflow-x" ); + + testHelper.forceScrollableWindow(); + + $( "html" ) + .css( "overflow-y", "scroll" ) + .css( "overflow-x", "scroll" ) + .scrollTop( 300 ) + .scrollLeft( 300 ); + + element.simulate( "drag", { + dx: 1, + dy: 1, + moves: 1 + }); +}); + +test( "#9315: jumps down with offset of scrollbar", function() { + expect( 2 ); + + var element = $( "#draggable2" ).draggable({ + stop: function( event, ui ) { + equal( ui.position.left, 11, "left position is correct when position is absolute" ); + equal( ui.position.top, 11, "top position is correct when position is absolute" ); + $( "html" ).scrollTop( 0 ).scrollLeft( 0 ); + } + }); + + testHelper.forceScrollableWindow(); + + $( "html" ).scrollTop( 300 ).scrollLeft( 300 ); + + element.simulate( "drag", { + dx: 1, + dy: 1, + moves: 1 + }); +}); + +test( "scroll offset with fixed ancestors", function() { + expect( 2 ); + + var startValue = 300, + element = $( "#draggable1" ) + // http://bugs.jqueryui.com/ticket/5009 + // scroll not working with parent's position fixed + .wrap( "
" ) + // http://bugs.jqueryui.com/ticket/9612 + // abspos elements inside of fixed elements moving away from the mouse when scrolling + .wrap( "
" ) + .draggable({ + drag: function() { + startValue += 100; + $( document ).scrollTop( startValue ).scrollLeft( startValue ); + }, + stop: function( event, ui ) { + equal( ui.position.left, 10, "left position is correct when parent position is fixed" ); + equal( ui.position.top, 10, "top position is correct when parent position is fixed" ); + $( document ).scrollTop( 0 ).scrollLeft( 0 ); + } + }); + + testHelper.forceScrollableWindow(); + + $( "#wrapper" ).css( "position", "fixed" ); + $( "#wrapper2" ).css( "position", "absolute" ); + + element.simulate( "drag", { + dx: 10, + dy: 10, + moves: 3 + }); +}); + +$( [ "hidden", "auto", "scroll" ] ).each(function() { + var overflow = this; + + // http://bugs.jqueryui.com/ticket/9379 - position bug in scrollable div + // http://bugs.jqueryui.com/ticket/10147 - Wrong position in a parent with "overflow: hidden" + test( "position in scrollable parent with overflow: " + overflow, function() { + expect( 2 ); + + $( "#qunit-fixture" ).html( "
a
" ); + $( "#inner" ).css({ position: "absolute", width: "500px", height: "500px" }); + $( "#outer" ).css({ position: "absolute", width: "300px", height: "300px" }); + $( "#dragged" ).css({ width: "10px", height: "10px" }); + + var moves = 3, + startValue = 0, + dragDelta = 20, + delta = 100, + + // we scroll after each drag event, so subtract 1 from number of moves for expected + expected = delta + ( ( moves - 1 ) * dragDelta ), + element = $( "#dragged" ).draggable({ + drag: function() { + startValue += dragDelta; + $( "#outer" ).scrollTop( startValue ).scrollLeft( startValue ); + }, + stop: function( event, ui ) { + equal( ui.position.left, expected, "left position is correct when grandparent is scrolled" ); + equal( ui.position.top, expected, "top position is correct when grandparent is scrolled" ); + } + }); + + $( "#outer" ).css( "overflow", overflow ); + + element.simulate( "drag", { + dy: delta, + dx: delta, + moves: moves + }); + }); +}); + +test( "#5727: draggable from iframe", function() { + expect( 1 ); + + var iframeBody, draggable1, + iframe = $( "" ) - .append( "" ) + .append( "