aboutsummaryrefslogtreecommitdiffstats
path: root/tests/unit
diff options
context:
space:
mode:
authorRichard Worth <rdworth@gmail.com>2009-01-07 03:31:15 +0000
committerRichard Worth <rdworth@gmail.com>2009-01-07 03:31:15 +0000
commitb792bd46ec9b1b55bf2289faedd4ab3614c9319a (patch)
tree4b1736c703d392ec07fd4a5ae3390151470ae933 /tests/unit
parent4707debd645e63ea22d7a076e97a34eb3d310ebc (diff)
downloadjquery-ui-b792bd46ec9b1b55bf2289faedd4ab3614c9319a.tar.gz
jquery-ui-b792bd46ec9b1b55bf2289faedd4ab3614c9319a.zip
restructured unit tests folder
Diffstat (limited to 'tests/unit')
-rw-r--r--tests/unit/accordion/accordion.html96
-rw-r--r--tests/unit/accordion/accordion.js150
-rw-r--r--tests/unit/all/all.html226
-rw-r--r--tests/unit/all/all_2.html82
-rw-r--r--tests/unit/core/core.html63
-rw-r--r--tests/unit/core/core.js78
-rw-r--r--tests/unit/datepicker/datepicker.html30
-rw-r--r--tests/unit/datepicker/datepicker.js1387
-rw-r--r--tests/unit/dialog/dialog.html26
-rw-r--r--tests/unit/dialog/dialog.js723
-rw-r--r--tests/unit/draggable/draggable.html28
-rw-r--r--tests/unit/draggable/draggable.js787
-rw-r--r--tests/unit/droppable/droppable.html27
-rw-r--r--tests/unit/droppable/droppable.js223
-rw-r--r--tests/unit/progressbar/progressbar.html24
-rw-r--r--tests/unit/progressbar/progressbar.js68
-rw-r--r--tests/unit/resizable/images/test.jpgbin0 -> 915 bytes
-rw-r--r--tests/unit/resizable/resizable.html25
-rw-r--r--tests/unit/resizable/resizable.js416
-rw-r--r--tests/unit/selectable/selectable.html30
-rw-r--r--tests/unit/selectable/selectable.js196
-rw-r--r--tests/unit/slider/slider.html27
-rw-r--r--tests/unit/slider/slider.js396
-rw-r--r--tests/unit/sortable/sortable.html30
-rw-r--r--tests/unit/sortable/sortable.js148
-rw-r--r--tests/unit/tabs/tabs.html44
-rw-r--r--tests/unit/tabs/tabs.js243
-rw-r--r--tests/unit/testsuite.css4
-rw-r--r--tests/unit/testsuite.js10
29 files changed, 5587 insertions, 0 deletions
diff --git a/tests/unit/accordion/accordion.html b/tests/unit/accordion/accordion.html
new file mode 100644
index 000000000..51553d330
--- /dev/null
+++ b/tests/unit/accordion/accordion.html
@@ -0,0 +1,96 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <title>jQuery UI Accordion Test Suite</title>
+
+ <script type="text/javascript" src="../../../jquery-1.3pre.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.core.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.accordion.js"></script>
+
+ <link type="text/css" href="../testsuite.css" rel="stylesheet" />
+ <script type="text/javascript" src="../testsuite.js"></script>
+ <script type="text/javascript" src="../../../external/qunit/testrunner.js"></script>
+ <script type="text/javascript" src="../../../external/simulate/jquery.simulate.js"></script>
+
+ <script type="text/javascript" src="accordion.js"></script>
+</head>
+<body>
+
+<div id="main">
+
+ <div id="list1">
+ <div>
+ <a>There is one obvious advantage:</a>
+ <div>
+ <p>
+ You've seen it coming!
+ <br/>
+ Buy now and get nothing for free!
+ <br/>
+ Well, at least no free beer. Perhaps a bear, if you can afford it.
+ </p>
+ </div>
+ </div>
+ <div>
+ <a>Now that you've got...</a>
+ <div>
+ <p>
+ your bear, you have to admit it!
+ <br/>
+ No, we aren't selling bears.
+ </p>
+ <p>
+ We could talk about renting one.
+ </p>
+ </div>
+ </div>
+ <div>
+ <a>Rent one bear, ...</a>
+ <div>
+ <p>
+ get two for three beer.
+ </p>
+ <p>
+ And now, for something completely different.
+ </p>
+ </div>
+ </div>
+ </div>
+
+ <ul id="navigation">
+ <li>
+ <a href="?p=1.1.1">Guitar</a>
+ <ul>
+ <li><a href="?p=1.1.1.1">Electric</a></li>
+ <li><a href="?p=1.1.1.2">Acoustic</a></li>
+ <li><a href="?p=1.1.1.3">Amps</a></li>
+ <li><a href="?p=1.1.1.4">Effects</a></li>
+ <li><a href="?p=1.1.1.5">Accessories</a></li>
+ </ul>
+ </li>
+ <li>
+ <a href="?p=1.1.2"><span>Bass</span></a>
+ <ul>
+ <li><a href="?p=1.1.2.1">Electric</a></li>
+ <li><a href="?p=1.1.2.2">Acoustic</a></li>
+ <li><a href="?p=1.1.2.3">Amps</a></li>
+ <li><a href="?p=1.1.2.4">Effects</a></li>
+ <li><a href="?p=1.1.2.5">Accessories</a></li>
+ <li><a href="?p=1.1.2.5">Accessories</a></li>
+ <li><a href="?p=1.1.2.5">Accessories</a></li>
+ </ul>
+ </li>
+ <li>
+ <a href="?p=1.1.3">Drums</a>
+ <ul>
+ <li><a href="?p=1.1.3.2">Acoustic Drums</a></li>
+ <li><a href="?p=1.1.3.3">Electronic Drums</a></li>
+ <li><a href="?p=1.1.3.6">Accessories</a></li>
+ </ul>
+ </li>
+ </ul>
+
+</div>
+
+</body>
+</html>
diff --git a/tests/unit/accordion/accordion.js b/tests/unit/accordion/accordion.js
new file mode 100644
index 000000000..d9f8c4b64
--- /dev/null
+++ b/tests/unit/accordion/accordion.js
@@ -0,0 +1,150 @@
+/*
+ * accordion unit tests
+ */
+(function($) {
+
+module("accordion");
+
+jQuery.ui.accordion.defaults.animated = false;
+
+function state(accordion) {
+ var args = $.makeArray(arguments).slice(1);
+ $.each(args, function(i, n) {
+ equals(accordion.find(".ui-accordion-content").parent().eq(i).is(":visible"), n);
+ });
+}
+
+$.fn.triggerEvent = function(type, target) {
+ return this.triggerHandler(type, [jQuery.event.fix({ type: type, target: target })]);
+}
+
+test("basics", function() {
+ state($('#list1').accordion(), 1, 0, 0);
+});
+
+test("autoheight", function() {
+ $('#navigation').accordion({ autoHeight: false });
+ equals( 90, $('#navigation div:first').height() );
+ equals( 126, $('#navigation div:eq(1)').height() );
+ equals( 54, $('#navigation div:last').height() );
+ $('#navigation').accordion("destroy").accordion({ autoHeight: true });
+ equals( 126, $('#navigation div:first').height() );
+ equals( 126, $('#navigation div:eq(1)').height() );
+ equals( 126, $('#navigation div:last').height() );
+});
+
+test("activate, numeric", function() {
+ var ac = $('#list1').accordion({ active: 1 });
+ state(ac, 0, 1, 0);
+ ac.accordion("activate", 2);
+ state(ac, 0, 0, 1);
+ ac.accordion("activate", 0);
+ state(ac, 1, 0, 0);
+ ac.accordion("activate", 1);
+ state(ac, 0, 1, 0);
+ ac.accordion("activate", 2);
+ state(ac, 0, 0, 1);
+ ac.accordion("activate", -1);
+ state(ac, 0, 0, 1);
+});
+
+test("activate, boolean and numeric, alwaysOpen:false", function() {
+ var ac = $('#list1').accordion({alwaysOpen: false}).accordion("activate", 2);
+ state(ac, 0, 0, 1);
+ ok("x", "----");
+ ac.accordion("activate", 0);
+ state(ac, 1, 0, 0);
+ ok("x", "----");
+ ac.accordion("activate", -1);
+ state(ac, 0, 0, 0);
+});
+
+test("activate, boolean, alwaysOpen:true", function() {
+ var ac = $('#list1').accordion().accordion("activate", 2);
+ state(ac, 0, 0, 1);
+ ac.accordion("activate", -1);
+ state(ac, 0, 0, 1);
+});
+
+test("activate, string expression", function() {
+ var ac = $('#list1').accordion({ active: "a:last" });
+ state(ac, 0, 0, 1);
+ ac.accordion("activate", ":first");
+ state(ac, 1, 0, 0);
+ ac.accordion("activate", ":eq(1)");
+ state(ac, 0, 1, 0);
+ ac.accordion("activate", ":last");
+ state(ac, 0, 0, 1);
+});
+
+test("activate, jQuery or DOM element", function() {
+ var ac = $('#list1').accordion({ active: $("#list1 a:last") });
+ state(ac, 0, 0, 1);
+ ac.accordion("activate", $("#list1 a:first"));
+ state(ac, 1, 0, 0);
+ ac.accordion("activate", $("#list1 a")[1]);
+ state(ac, 0, 1, 0);
+});
+
+function state2(accordion) {
+ var args = $.makeArray(arguments).slice(1);
+ $.each(args, function(i, n) {
+ equals(accordion.find("div").eq(i).is(":visible"), n);
+ });
+}
+
+test("handle click on header-descendant", function() {
+ var ac = $('#navigation').accordion({ autoHeight: false })
+ ac.triggerEvent("click", $('#navigation span:contains(Bass)')[0]);
+ state2(ac, 0, 1, 0);
+});
+
+test("active:false", function() {
+ $("#list1").accordion({
+ active: false,
+ alwaysOpen: false
+ });
+ equals( $("#list1 a.selected").size(), 0, "no headers selected" );
+});
+
+test("accordionchange event, open closed and close again", function() {
+ expect(8);
+ $("#list1").accordion({
+ active: false,
+ alwaysOpen: false
+ })
+ .one("accordionchange", function(event, ui) {
+ equals( ui.oldHeader.size(), 0 )
+ equals( ui.oldContent.size(), 0 )
+ equals( ui.newHeader.size(), 1 )
+ equals( ui.newContent.size(), 1 )
+ })
+ .accordion("activate", 0)
+ .one("accordionchange", function(event, ui) {
+ equals( ui.oldHeader.size(), 1 )
+ equals( ui.oldContent.size(), 1 )
+ equals( ui.newHeader.size(), 0 )
+ equals( ui.newContent.size(), 0 )
+ })
+ .accordion("activate", 0);
+});
+
+test("accessibility", function () {
+ expect(9);
+ var ac = $('#list1').accordion().accordion("activate", 1);
+ var headers = $(".ui-accordion-header");
+
+ equals( headers.eq(1).attr("tabindex"), "0", "active header should have tabindex=0");
+ equals( headers.eq(0).attr("tabindex"), "-1", "inactive header should have tabindex=-1");
+ equals( ac.attr("role"), "tablist", "main role");
+ equals( headers.attr("role"), "tab", "tab roles");
+ equals( headers.next().attr("role"), "tabpanel", "tabpanel roles");
+ equals( headers.eq(1).attr("aria-expanded"), "true", "active tab has aria-expanded");
+ equals( headers.eq(0).attr("aria-expanded"), "false", "inactive tab has aria-expanded");
+ ac.accordion("activate", 0);
+ equals( headers.eq(0).attr("aria-expanded"), "true", "newly active tab has aria-expanded");
+ equals( headers.eq(1).attr("aria-expanded"), "false", "newly inactive tab has aria-expanded");
+});
+
+
+})(jQuery);
diff --git a/tests/unit/all/all.html b/tests/unit/all/all.html
new file mode 100644
index 000000000..358cc3e52
--- /dev/null
+++ b/tests/unit/all/all.html
@@ -0,0 +1,226 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <title>jQuery UI All Tests</title>
+ <link rel="stylesheet" href="../testsuite.css" type="text/css">
+
+ <script type="text/javascript" src="../../../jquery-1.3pre.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.core.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.accordion.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.datepicker.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.dialog.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.draggable.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.droppable.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.progressbar.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.resizable.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.selectable.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.slider.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.sortable.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.tabs.js"></script>
+
+ <script type="text/javascript" src="../../../external/qunit/testrunner.js"></script>
+ <script type="text/javascript" src="../../../external/simulate/jquery.simulate.js"></script>
+ <script type="text/javascript" src="../../../external/cookie/jquery.cookie.js"></script>
+
+ <script type="text/javascript" src="../accordion/accordion.js"></script>
+ <script type="text/javascript" src="../datepicker/datepicker.js"></script>
+ <script type="text/javascript" src="../dialog/dialog.js"></script>
+ <script type="text/javascript" src="../draggable/draggable.js"></script>
+ <script type="text/javascript" src="../droppable/droppable.js"></script>
+ <script type="text/javascript" src="../progressbar/progressbar.js"></script>
+ <script type="text/javascript" src="../resizable/resizable.js"></script>
+ <script type="text/javascript" src="../selectable/selectable.js"></script>
+ <script type="text/javascript" src="../slider/slider.js"></script>
+ <script type="text/javascript" src="../sortable/sortable.js"></script>
+ <script type="text/javascript" src="../tabs/tabs.js"></script>
+
+ <style type="text/css">
+ @import "../../../themes/base/ui.datepicker.css";
+ .xerror, .error, .ui-tabs-hide {
+ display: none;
+ }
+ </style>
+
+</head>
+<body>
+ <h1>jQuery UI All Tests</h1>
+ <h2 id="banner"></h2>
+ <h2 id="userAgent"></h2>
+
+ <h4>Run individual testsuites or doubleclick a test below</h4>
+ <ul>
+ <li><a href="accordion.html">Accordion</a></li>
+ <li><a href="datepicker.html">Datepicker</a></li>
+ <li><a href="dialog.html">Dialog</a></li>
+ <li><a href="draggable.html">Draggable</a></li>
+ <li><a href="resizable.html">Resizable</a></li>
+ <li><a href="selectable.html">Selectable</a></li>
+ <li><a href="slider.html">Slider</a></li>
+ <li><a href="sortable.html">Sortable</a></li>
+ <li><a href="tabs.html">Tabs</a></li>
+ </ul>
+
+ <ol id="tests"></ol>
+
+ <div id="main" style="position:absolute;top:-2000000px;">
+
+ <p><input type="text" id="dp1"/><input type="text" id="rem"/></p>
+
+ <div id="draggable1" style="background: green; width: 200px; height: 100px;">Relative</div>
+ <div id="draggable2" style="background: green; width: 200px; height: 100px; position: absolute; top: 10px; left: 10px;"><span>Absolute</span></div>
+
+ <div id="slider1"></div>
+ <div id="slider3" style="position: relative; margin: 40px; width: 217px; height: 28px;">
+ <div class="ui-slider-handle" style="position: absolute; height: 21px; left: 0px; bottom: 0px; width: 17px;"></div>
+ </div>
+
+ <div id="list1">
+ <a>There is one obvious advantage:</a>
+ <div>
+ <p>
+ You've seen it coming!<br/>
+ Buy now and get nothing for free!<br/>
+ Well, at least no free beer. Perhaps a bear, if you can afford it.
+ </p>
+ </div>
+ <a>Now that you've got...</a>
+ <div>
+ <p>
+ your bear, you have to admit it!<br/>
+ No, we aren't selling bears.
+ </p>
+ <p>
+ We could talk about renting one.
+ </p>
+ </div>
+ <a>Rent one bear, ...</a>
+ <div>
+ <p>
+ get two for three beer.
+ </p>
+ <p>
+ And now, for something completely different.
+ </p>
+ </div>
+ </div>
+
+ <ul id="navigation">
+ <li>
+ <a class="head" href="?p=1.1.1">Guitar</a>
+ <ul>
+ <li><a href="?p=1.1.1.1">Electric</a></li>
+ <li><a href="?p=1.1.1.2">Acoustic</a></li>
+ <li><a href="?p=1.1.1.3">Amps</a></li>
+ <li><a href="?p=1.1.1.4">Effects</a></li>
+ <li><a href="?p=1.1.1.5">Accessories</a></li>
+ </ul>
+ </li>
+ <li>
+ <a class="head" href="?p=1.1.2"><span>Bass</span></a>
+ <ul>
+ <li><a href="?p=1.1.2.1">Electric</a></li>
+ <li><a href="?p=1.1.2.2">Acoustic</a></li>
+ <li><a href="?p=1.1.2.3">Amps</a></li>
+ <li><a href="?p=1.1.2.4">Effects</a></li>
+ <li><a href="?p=1.1.2.5">Accessories</a></li>
+ <li><a href="?p=1.1.2.5">Accessories</a></li>
+ <li><a href="?p=1.1.2.5">Accessories</a></li>
+ </ul>
+ </li>
+ <li>
+ <a class="head" href="?p=1.1.3">Drums</a>
+ <ul>
+ <li><a href="?p=1.1.3.2">Acoustic Drums</a></li>
+ <li><a href="?p=1.1.3.3">Electronic Drums</a></li>
+ <li><a href="?p=1.1.3.6">Accessories</a></li>
+ </ul>
+ </li>
+ </ul>
+ <dl id="list2">
+ <dt class="red">Red</dt>
+ <dd>
+ Fancy stuff about red thingies.
+ </dd>
+ <dt class="green selected">Green</dt>
+ <dd>
+ Green! Green! Green!
+ </dd>
+ <dt class="blue">Blue</dt>
+ <dd>
+ Cool kids are blue.
+ </dd>
+ </dl>
+
+ <div id="list3">
+ <div>
+ <div class="title">Tennis</div>
+ <div>
+ One ball, two players. Lots of fun.
+ </div>
+ </div>
+ <div>
+ <div class="title">Soccer</div>
+ <div>
+ One ball, 22 players. Lots of fun.
+ </div>
+ </div>
+ <div>
+ <div class="title">Baseball</div>
+ <div>
+ Well, one ball, some guys running around, some guys hitting others with a stick.<br/>
+ Sounds like fun, doesn't it?
+ </div>
+ <div>
+ Well, apart from the running part.
+ </div>
+ </div>
+ </div>
+
+ <div id="resizable1" style="background: green; width: 100px; height: 100px;">I'm a resizable.</div>
+ <img src="images/test.jpg" id="resizable2" style="width: 100px; height: 100px;"/>
+
+
+ <ul id="selectable1">
+ <li>Item 1</li>
+ <li>Item 2</li>
+ <li class="special">Item 3</li>
+ <li>Item 4</li>
+ <li>Item 5</li>
+ </ul>
+
+ <ul id="sortable">
+ <li>Item 1</li>
+ <li>Item 2</li>
+ <li>Item 3</li>
+ <li>Item 4</li>
+ <li>Item 5</li>
+ </ul>
+
+ <p><input type="text" id="inp"/><input type="text" id="alt"/><div id="inl"></div></p>
+
+ <input type="text" id="spin" />
+
+ <div id="progressbar"></div>
+
+ <div id="tabs1">
+ <ul>
+ <li><a href="#fragment-1">1</a></li>
+ <li><a href="#fragment-2">2</a></li>
+ <li><a href="#fragment-3">3</a></li>
+ </ul>
+ <div id="fragment-1"></div>
+ <div id="fragment-2"></div>
+ <div id="fragment-3"></div>
+ </div>
+ <div id="tabs2">
+ <ul>
+ <li><a href="#colon:test">1</a></li>
+ <li><a href="#inline-style">2</a></li>
+ </ul>
+ <div id="colon:test"></div>
+ <div style="height: 300px;" id="inline-style"></div>
+ </div>
+
+</div>
+ </body>
+</html> \ No newline at end of file
diff --git a/tests/unit/all/all_2.html b/tests/unit/all/all_2.html
new file mode 100644
index 000000000..0645acb83
--- /dev/null
+++ b/tests/unit/all/all_2.html
@@ -0,0 +1,82 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <title>jQuery UI All Tests</title>
+ <link rel="stylesheet" href="../testsuite.css" type="text/css">
+
+ <script type="text/javascript" src="../../../jquery-1.3pre.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.core.js"></script>
+
+ <script type="text/javascript">
+ var components = ["accordion","datepicker","dialog","draggable","progressbar","resizable","selectable","slider","sortable","tabs"];
+
+ $(function() {
+
+ var $list = $("#individual_list"),
+ $main = $("#main");
+
+ $.each(components, function(i, val){
+ $list.append('<li><a href="../' + val + '/' + val + '.html">' + val + '</a></li>');
+ $('<div class="component_panel" id="' + val + '">').appendTo($main);
+ $('#' + val).load(val + '.html #main *');
+ });
+
+ loadScripts();
+
+ function loadScripts() {
+ if ( $("div.component_panel").length == components.length ) {
+ $.each(components, function(i, val){
+ $('head').append('<script type="text/javascript" src="' + val + '.js"></scr'+'ipt>');
+ });
+ } else {
+ setTimeout(loadScripts, 10);
+ }
+ }
+
+
+ });
+
+
+ </script>
+
+ <script type="text/javascript" src="../../../ui/ui.accordion.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.datepicker.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.dialog.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.draggable.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.droppable.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.progressbar.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.resizable.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.selectable.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.slider.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.sortable.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.tabs.js"></script>
+
+ <script type="text/javascript" src="../../../external/qunit/testrunner.js"></script>
+ <script type="text/javascript" src="../../../external/simulate/jquery.simulate.js"></script>
+ <script type="text/javascript" src="../../../cookie/jquery.cookie.js"></script>
+
+ <style type="text/css">
+ @import "../../../themes/base/ui.datepicker.css";
+ .xerror, .error, .ui-tabs-hide {
+ display: none;
+ }
+ </style>
+
+</head>
+<body>
+ <h1>jQuery UI All Tests</h1>
+ <h2 id="banner"></h2>
+ <h2 id="userAgent"></h2>
+
+ <h4>Run individual testsuites or doubleclick a test below</h4>
+ <ul id="individual_list">
+ </ul>
+
+ <ol id="tests"></ol>
+
+ <div id="main" style="position:absolute; top:-2000000px;">
+
+ </div>
+
+ </body>
+</html> \ No newline at end of file
diff --git a/tests/unit/core/core.html b/tests/unit/core/core.html
new file mode 100644
index 000000000..c8d88c88a
--- /dev/null
+++ b/tests/unit/core/core.html
@@ -0,0 +1,63 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <title>jQuery UI Core Test Suite</title>
+
+ <script type="text/javascript" src="../../../jquery-1.3pre.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.core.js"></script>
+
+ <link type="text/css" href="../testsuite.css" rel="stylesheet" />
+ <script type="text/javascript" src="../testsuite.js"></script>
+ <script type="text/javascript" src="../../../external/qunit/testrunner.js"></script>
+ <script type="text/javascript" src="../../../external/simulate/jquery.simulate.js"></script>
+
+ <script type="text/javascript" src="core.js"></script>
+</head>
+<body>
+
+<div id="main">
+ <div id="wrap1">
+ <input id="input1-1" />
+ <input type="text" id="input1-2" />
+ <input type="checkbox" id="input1-3" />
+ <input type="radio" id="input1-4" />
+ <input type="button" id="input1-5" />
+ <input type="hidden" id="input1-6" />
+ <select id="input1-7"></select>
+ <textarea id="input1-8"></textarea>
+ <a href="#" id="anchor1-1">anchor</a>
+ <a id="anchor1-2">anchor</a>
+ </div>
+ <div id="wrap2">
+ <input id="input2-1" disabled="disabled" />
+ <input type="text" id="input2-2" disabled="disabled" />
+ <input type="checkbox" id="input2-3" disabled="disabled" />
+ <input type="radio" id="input2-4" disabled="disabled" />
+ <input type="button" id="input2-5" disabled="disabled" />
+ <input type="hidden" id="input2-6" disabled="disabled" />
+ <select id="input2-7" disabled="disabled"></select>
+ <textarea id="input2-8" disabled="disabled"></textarea>
+ </div>
+ <div id="wrap3">
+ <div id="wrap3-1" style="display: none;">
+ <input id="input3-1" />
+ <a href="#" id="anchor3-1">anchor</a>
+ </div>
+ <div id="wrap3-2" style="visibility: hidden;">
+ <input id="input3-2" />
+ <a href="#" id="anchor3-2">anchor</a>
+ </div>
+ <input id="input3-3" style="display: none;">
+ <input id="input3-4" style="visibility: hidden;">
+ </div>
+ <div id="wrap4">
+ <input id="input4-1" tabindex="0" />
+ <input id="input4-2" tabindex="10" />
+ <input id="input4-3" tabindex="-1" />
+ <input id="input4-4" tabindex="-50" />
+ </div>
+ <div id="aria"></div>
+</div>
+
+</body>
+</html>
diff --git a/tests/unit/core/core.js b/tests/unit/core/core.js
new file mode 100644
index 000000000..4be475486
--- /dev/null
+++ b/tests/unit/core/core.js
@@ -0,0 +1,78 @@
+/*
+ * core unit tests
+ */
+(function($) {
+
+module("selectors");
+
+test("tabbable - enabled elements", function() {
+ expect(10);
+
+ ok( $('#input1-1').is(':tabbable'), 'input, no type');
+ ok( $('#input1-2').is(':tabbable'), 'input, type text');
+ ok( $('#input1-3').is(':tabbable'), 'input, type checkbox');
+ ok( $('#input1-4').is(':tabbable'), 'input, type radio');
+ ok( $('#input1-5').is(':tabbable'), 'input, type button');
+ ok(!$('#input1-6').is(':tabbable'), 'input, type hidden');
+ ok( $('#input1-7').is(':tabbable'), 'select');
+ ok( $('#input1-8').is(':tabbable'), 'textarea');
+ ok( $('#anchor1-1').is(':tabbable'), 'anchor with href');
+ ok(!$('#anchor1-2').is(':tabbable'), 'anchor without href');
+});
+
+test("tabbable - disabled elements", function() {
+ expect(8);
+
+ ok(!$('#input2-1').is(':tabbable'), 'input, no type');
+ ok(!$('#input2-2').is(':tabbable'), 'input, type text');
+ ok(!$('#input2-3').is(':tabbable'), 'input, type checkbox');
+ ok(!$('#input2-4').is(':tabbable'), 'input, type radio');
+ ok(!$('#input2-5').is(':tabbable'), 'input, type button');
+ ok(!$('#input2-6').is(':tabbable'), 'input, type hidden');
+ ok(!$('#input2-7').is(':tabbable'), 'select');
+ ok(!$('#input2-8').is(':tabbable'), 'textarea');
+});
+
+test("tabbable - hidden styles", function() {
+ expect(6);
+
+ ok(!$('#input3-1').is(':tabbable'), 'input, hidden wrapper - display: none');
+ ok(!$('#anchor3-1').is(':tabbable'), 'anchor, hidden wrapper - display: none');
+ ok(!$('#input3-2').is(':tabbable'), 'input, hidden wrapper - visibility: hidden');
+ ok(!$('#anchor3-2').is(':tabbable'), 'anchor, hidden wrapper - visibility: hidden');
+ ok(!$('#input3-3').is(':tabbable'), 'input, display: none');
+ ok(!$('#input3-4').is(':tabbable'), 'input, visibility: hidden');
+});
+
+test("tabbable - tabindex", function() {
+ expect(4);
+
+ ok( $('#input4-1').is(':tabbable'), 'input, tabindex 0');
+ ok( $('#input4-2').is(':tabbable'), 'input, tabindex 10');
+ ok(!$('#input4-3').is(':tabbable'), 'input, tabindex -1');
+ ok(!$('#input4-4').is(':tabbable'), 'input, tabindex -50');
+});
+
+module('jQuery extensions');
+
+test("attr - aria", function() {
+ expect(6);
+
+ var el = $('#aria');
+
+ ok(!el.attr('role'), 'role is empty via attr');
+ equals(el.attr('role', 'tablist').attr('role'), 'tablist', 'role is tablist');
+
+ equals(el.attr('aria-expanded'), undefined, 'aria expanded is undefined');
+
+ el.attr('aria-expanded', true);
+ equals(el.attr('aria-expanded'), 'true', 'aria expanded is true');
+
+ el.removeAttr('aria-expanded');
+ equals(el.attr('aria-expanded'), undefined, 'aria expanded is undefined after removing');
+
+ el.attr('aria-expanded', false);
+ equals(el.attr('aria-expanded'), 'false', 'aria expanded is false');
+});
+
+})(jQuery);
diff --git a/tests/unit/datepicker/datepicker.html b/tests/unit/datepicker/datepicker.html
new file mode 100644
index 000000000..a17b08e90
--- /dev/null
+++ b/tests/unit/datepicker/datepicker.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <title>jQuery UI Datepicker Test Suite</title>
+
+ <script type="text/javascript" src="../../../jquery-1.3pre.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.core.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.datepicker.js"></script>
+ <script type="text/javascript" src="../../../ui/i18n/ui.datepicker-fr.js"></script>
+ <script type="text/javascript" src="../../../ui/i18n/ui.datepicker-he.js"></script>
+
+ <link type="text/css" href="../testsuite.css" rel="stylesheet" />
+ <script type="text/javascript" src="../testsuite.js"></script>
+ <script type="text/javascript" src="../../../external/qunit/testrunner.js"></script>
+ <script type="text/javascript" src="../../../external/simulate/jquery.simulate.js"></script>
+
+ <style type="text/css">
+ @import "../../../themes/base/ui.datepicker.css";
+ </style>
+
+ <script type="text/javascript" src="datepicker.js"></script>
+</head>
+<body>
+
+<div id="main">
+ <p><input type="text" id="inp"/><input type="text" id="alt"/><div id="inl"></div></p>
+</div>
+
+</body>
+</html>
diff --git a/tests/unit/datepicker/datepicker.js b/tests/unit/datepicker/datepicker.js
new file mode 100644
index 000000000..dadb5a997
--- /dev/null
+++ b/tests/unit/datepicker/datepicker.js
@@ -0,0 +1,1387 @@
+/*
+ * datepicker unit tests
+ */
+(function($) {
+
+module('datepicker');
+
+function equalsDate(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());
+ equals(d1.toString(), d2.toString(), message);
+}
+
+function equalsDateArray(a1, a2, message) {
+ if (!a1 || !a2) {
+ ok(false, message + ' - missing dates');
+ return;
+ }
+ a1[0] = (a1[0] ? new Date(a1[0].getFullYear(), a1[0].getMonth(), a1[0].getDate()) : '');
+ a1[1] = (a1[1] ? new Date(a1[1].getFullYear(), a1[1].getMonth(), a1[1].getDate()) : '');
+ a2[0] = (a2[0] ? new Date(a2[0].getFullYear(), a2[0].getMonth(), a2[0].getDate()) : '');
+ a2[1] = (a2[1] ? new Date(a2[1].getFullYear(), a2[1].getMonth(), a2[1].getDate()) : '');
+ same(a1, a2, message);
+}
+
+function init(id, options) {
+ $.datepicker.setDefaults($.datepicker.regional['']);
+ var inp = $(id);
+ inp.datepicker($.extend({duration: ''}, options || {}));
+ return inp;
+}
+
+var PROP_NAME = 'datepicker';
+
+test('setDefaults', function() {
+ var inp = init('#inp');
+ var dp = $('#ui-datepicker-div');
+ ok(!dp.is(':visible'), 'Initially invisible');
+ ok(inp.is('.hasDatepicker'), 'Marker class set');
+ ok($($.datepicker.dpDiv).html() == '', 'Content empty');
+ inp.datepicker('show');
+ ok($($.datepicker.dpDiv).html() != '', 'Content present');
+ inp.datepicker('hide');
+ equals($.datepicker._defaults.showOn, 'focus', 'Initial showOn');
+ $.datepicker.setDefaults({showOn: 'button'});
+ equals($.datepicker._defaults.showOn, 'button', 'Change default showOn');
+ $.datepicker.setDefaults({showOn: 'focus'});
+ equals($.datepicker._defaults.showOn, 'focus', 'Restore showOn');
+});
+
+test('destroy', function() {
+ var inp = init('#inp');
+ ok(inp.is('.hasDatepicker'), 'Default - marker class set');
+ ok($.data(inp[0], 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], PROP_NAME), 'Default - instance absent');
+ ok(inp.next().is('#alt'), 'Default - button absent');
+ // With button
+ inp= init('#inp', {showOn: 'both'});
+ ok(inp.is('.hasDatepicker'), 'Button - marker class set');
+ ok($.data(inp[0], 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], PROP_NAME), 'Button - instance absent');
+ ok(inp.next().is('#alt'), 'Button - button removed');
+ // With append text
+ inp = init('#inp', {appendText: 'Testing'});
+ ok(inp.is('.hasDatepicker'), 'Append - marker class set');
+ ok($.data(inp[0], 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], PROP_NAME), 'Append - instance absent');
+ ok(inp.next().is('#alt'), 'Append - append text removed');
+ // With both
+ inp= init('#inp', {showOn: 'both', buttonImageOnly: true,
+ buttonImage: 'img/calendar.gif', appendText: 'Testing'});
+ ok(inp.is('.hasDatepicker'), 'Both - marker class set');
+ ok($.data(inp[0], 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], PROP_NAME), 'Both - instance absent');
+ ok(inp.next().is('#alt'), 'Both - button and append text absent');
+ // Inline
+ var inl = init('#inl');
+ ok(inl.is('.hasDatepicker'), 'Inline - marker class set');
+ ok(inl.html() != '', 'Inline - datepicker present');
+ ok($.data(inl[0], 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], PROP_NAME), 'Inline - instance absent');
+ ok(inl.next().length == 0 || inl.next().is('p'), 'Inline - button absent');
+});
+
+test('option', function() {
+ var inp = init('#inp');
+ var inst = $.data(inp[0], PROP_NAME);
+ equals(inst.settings.showOn, null, 'Initial setting showOn');
+ equals($.datepicker._get(inst, 'showOn'), 'focus', 'Initial instance showOn');
+ equals($.datepicker._defaults.showOn, 'focus', 'Initial default showOn');
+ inp.datepicker('option', 'showOn', 'button');
+ equals(inst.settings.showOn, 'button', 'Change setting showOn');
+ equals($.datepicker._get(inst, 'showOn'), 'button', 'Change instance showOn');
+ equals($.datepicker._defaults.showOn, 'focus', 'Retain default showOn');
+ inp.datepicker('option', {showOn: 'both'});
+ equals(inst.settings.showOn, 'both', 'Change setting showOn');
+ equals($.datepicker._get(inst, 'showOn'), 'both', 'Change instance showOn');
+ equals($.datepicker._defaults.showOn, 'focus', 'Retain default showOn');
+ inp.datepicker('option', 'showOn', undefined);
+ equals(inst.settings.showOn, null, 'Clear setting showOn');
+ equals($.datepicker._get(inst, 'showOn'), 'focus', 'Restore instance showOn');
+ equals($.datepicker._defaults.showOn, 'focus', 'Retain default showOn');
+});
+
+test('change', function() {
+ var inp = init('#inp');
+ var inst = $.data(inp[0], PROP_NAME);
+ equals(inst.settings.showOn, null, 'Initial setting showOn');
+ equals($.datepicker._get(inst, 'showOn'), 'focus', 'Initial instance showOn');
+ equals($.datepicker._defaults.showOn, 'focus', 'Initial default showOn');
+ inp.datepicker('change', 'showOn', 'button');
+ equals(inst.settings.showOn, 'button', 'Change setting showOn');
+ equals($.datepicker._get(inst, 'showOn'), 'button', 'Change instance showOn');
+ equals($.datepicker._defaults.showOn, 'focus', 'Retain default showOn');
+ inp.datepicker('change', {showOn: 'both'});
+ equals(inst.settings.showOn, 'both', 'Change setting showOn');
+ equals($.datepicker._get(inst, 'showOn'), 'both', 'Change instance showOn');
+ equals($.datepicker._defaults.showOn, 'focus', 'Retain default showOn');
+ inp.datepicker('change', 'showOn', undefined);
+ equals(inst.settings.showOn, null, 'Clear setting showOn');
+ equals($.datepicker._get(inst, 'showOn'), 'focus', 'Restore instance showOn');
+ equals($.datepicker._defaults.showOn, 'focus', 'Retain default showOn');
+});
+
+test('invocation', function() {
+ var inp = init('#inp');
+ var dp = $('#ui-datepicker-div');
+ var body = $('body');
+ // On focus
+ var button = inp.siblings('button');
+ ok(button.length == 0, 'Focus - button absent');
+ var image = inp.siblings('img');
+ ok(image.length == 0, 'Focus - image absent');
+ inp.focus();
+ ok(dp.is(':visible'), 'Focus - rendered on focus');
+ inp.simulate('keydown', {keyCode: $.simulate.VK_ESC});
+ ok(!dp.is(':visible'), 'Focus - hidden on exit');
+ inp.focus();
+ 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');
+ // On button
+ inp = init('#inp', {showOn: 'button', buttonText: 'Popup'});
+ 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');
+ equals(button.text(), 'Popup', 'Button - button text');
+ inp.focus();
+ 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');
+ // On image button
+ inp = init('#inp', {showOn: 'button', buttonImageOnly: true,
+ buttonImage: 'img/calendar.gif', buttonText: 'Cal'});
+ 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');
+ equals(image.attr('src'), 'img/calendar.gif', 'Image button - image source');
+ equals(image.attr('title'), 'Cal', 'Image button - image text');
+ inp.focus();
+ 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');
+ // On both
+ inp = init('#inp', {showOn: 'both', buttonImage: 'img/calendar.gif'});
+ 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');
+ inp.focus();
+ 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');
+});
+
+test('baseStructure', function() {
+ var dp = $('#ui-datepicker-div');
+ var inp = init('#inp');
+ inp.focus();
+ var iframe = ($.browser.msie && parseInt($.browser.version) < 7);
+ 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');
+ equals(dp.children().length, 2 + (iframe ? 1 : 0), 'Structure - child count');
+
+ var header = dp.children(':first');
+ ok(header.is('div.ui-datepicker-header'), 'Structure - header division');
+ equals(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');
+
+ var title = header.children(':last');
+ ok(title.is('div.ui-datepicker-title') && title.html() != '','Structure - title division');
+ equals(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')
+
+ var 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');
+ var thead = table.children(':first').children(':first');
+ ok(thead.is('tr'), 'Structure - month table title row');
+ equals(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');
+ var week = table.children(':eq(1)').children(':first');
+ ok(week.is('tr'), 'Structure - month table week row');
+ equals(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');
+ ok(dp.children('iframe').length == (iframe ? 1 : 0), 'Structure - iframe');
+ inp.datepicker('hide').datepicker('destroy');
+
+ // Editable month/year and button panel
+ inp = init('#inp', {changeMonth: true, changeYear: true, showButtonPanel: true});
+ inp.focus();
+
+ var 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');
+
+ var panel = dp.children(':last');
+ ok(panel.is('div.ui-datepicker-buttonpane'), 'Structure - button panel division');
+ equals(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');
+
+ // Multi-month 2
+ inp = init('#inp', {numberOfMonths: 2});
+ inp.focus();
+ ok(dp.is('.ui-datepicker-multi'), 'Structure multi [2] - multi-month');
+ equals(dp.children().length, 2 + (iframe ? 1 : 0), 'Structure multi [2] - child count');
+ month = dp.children(':first');
+ ok(month.is('div.ui-datepicker-group') && month.is('div.ui-datepicker-group-first'), 'Structure multi [2] - first month division');
+ month = dp.children(':eq(1)');
+ ok(month.is('div.ui-datepicker-group') && month.is('div.ui-datepicker-group-last'), 'Structure multi [2] - second month division');
+ inp.datepicker('hide').datepicker('destroy');
+
+ // Multi-month [2, 2]
+ inp = init('#inp', {numberOfMonths: [2, 2]});
+ inp.focus();
+ ok(dp.is('.ui-datepicker-multi'), 'Structure multi - multi-month');
+ equals(dp.children().length, 4 + (iframe ? 1 : 0), 'Structure multi [2,2] - child count');
+ month = dp.children(':first');
+ ok(month.is('div.ui-datepicker-group') && month.is('div.ui-datepicker-group-first'), 'Structure multi [2,2] - first month division');
+ month = dp.children(':eq(1)');
+ ok(month.is('div.ui-datepicker-group') && month.is('div.ui-datepicker-group-last'), 'Structure multi [2,2] - second month division');
+ month = dp.children(':eq(2)');
+ ok(month.is('div.ui-datepicker-group') && month.is('div.ui-datepicker-group-first'), 'Structure multi [2,2] - third month division');
+ month = dp.children(':eq(3)');
+ ok(month.is('div.ui-datepicker-group') && month.is('div.ui-datepicker-group-last'), 'Structure multi [2,2] - fourth month division');
+ inp.datepicker('hide').datepicker('destroy');
+
+ // Inline
+ var inl = 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');
+ equals(dp.children().length, 2, 'Structure inline - child count');
+ var header = dp.children(':first');
+ ok(header.is('div.ui-datepicker-header'), 'Structure inline - header division');
+ equals(header.children().length, 3, 'Structure inline - header child count');
+ var table = month.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 = init('#inl', {numberOfMonths: 2});
+ dp = inl.children();
+ ok(dp.is('.ui-datepicker-inline') && dp.is('.ui-datepicker-multi'), 'Structure inline multi - main div');
+ equals(dp.children().length, 2 + (iframe ? 1 : 0), 'Structure multi - child count');
+ month = dp.children(':first');
+ ok(month.is('div.ui-datepicker-group') && month.is('div.ui-datepicker-group-first'), 'Structure multi - first month division');
+ month = dp.children(':eq(1)');
+ ok(month.is('div.ui-datepicker-group') && month.is('div.ui-datepicker-group-last'), 'Structure multi - second month division');
+ inl.datepicker('destroy');
+});
+
+test('customStructure', function() {
+ var dp = $('#ui-datepicker-div');
+ // Check right-to-left localisation
+ var inp = init('#inp', $.datepicker.regional['he']);
+ inp.data('showButtonPanel.datepicker',true);
+ inp.focus();
+ var iframe = ($.browser.msie && parseInt($.browser.version) < 7);
+ ok(dp.is('.ui-datepicker-rtl'), 'Structure RTL - right-to-left');
+ var header = dp.children(':first');
+ ok(header.is('div.ui-datepicker-header'), 'Structure RTL - header division');
+ equals(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');
+ var panel = dp.children(':last');
+ ok(panel.is('div.ui-datepicker-buttonpane'), 'Structure RTL - button division');
+ equals(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');
+
+ // Hide prev/next
+ inp = init('#inp', {hideIfNoPrevNext: true, minDate: new Date(2008, 2 - 1, 4), maxDate: new Date(2008, 2 - 1, 14)});
+ inp.val('02/10/2008').focus();
+ var header = dp.children(':first');
+ ok(header.is('div.ui-datepicker-header'), 'Structure hide prev/next - header division');
+ equals(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');
+
+ // Changeable Month with read-only year
+ inp = init('#inp', {changeMonth: true});
+ inp.focus();
+ var title = dp.children(':first').children(':last');
+ equals(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');
+
+ // Changeable year with read-only month
+ inp = init('#inp', {changeYear: true});
+ inp.focus();
+ var title = dp.children(':first').children(':last');
+ equals(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');
+
+ // Read-only first day of week
+ inp = init('#inp', {changeFirstDay: false});
+ inp.focus();
+ var thead = dp.find('.ui-datepicker-calendar thead tr');
+ equals(thead.children().length, 7, 'Structure read-only first day - thead child count');
+ equals(thead.find('a').length, 0, 'Structure read-only first day - thead links count');
+ inp.datepicker('hide').datepicker('destroy');
+});
+
+test('enableDisable', function() {
+ var inp = 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 = 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 = init('#inp', {showOn: 'button', buttonImageOnly: true,
+ buttonImage: 'img/calendar.gif'});
+ ok(!inp.datepicker('isDisabled'), 'Enable/disable image - initially marked as enabled');
+ ok(!inp[0].disabled, 'Enable/disable image - field initially enabled');
+ ok(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(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(inp.next('img').css('opacity') == 1, 'Enable/disable image - image now enabled');
+ inp.datepicker('destroy');
+ // Inline
+ var inl = init('#inl');
+ var 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');
+ 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');
+ 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');
+ inl.datepicker('destroy');
+});
+
+test('keystrokes', function() {
+ var inp = init('#inp');
+ var date = new Date();
+ inp.val('').datepicker('show').
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ equalsDate(inp.datepicker('getDate'), date, 'Keystroke enter');
+ inp.val('02/04/2008').datepicker('show').
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ 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: $.simulate.VK_HOME}).
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ equalsDate(inp.datepicker('getDate'), date, 'Keystroke ctrl+home');
+ inp.val('02/04/2008').datepicker('show').
+ simulate('keydown', {ctrlKey: true, keyCode: $.simulate.VK_END});
+ ok(inp.datepicker('getDate') == null, 'Keystroke ctrl+end');
+ inp.val('').datepicker('show').
+ simulate('keydown', {keyCode: $.simulate.VK_ESC});
+ ok(inp.datepicker('getDate') == null, 'Keystroke esc');
+ inp.val('02/04/2008').datepicker('show').
+ simulate('keydown', {keyCode: $.simulate.VK_ESC});
+ 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: $.simulate.VK_PGUP}).
+ simulate('keydown', {keyCode: $.simulate.VK_ESC});
+ 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: $.simulate.VK_LEFT}).
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ date.setDate(date.getDate() - 1);
+ equalsDate(inp.datepicker('getDate'), date, 'Keystroke ctrl+left');
+ inp.val('').datepicker('show').
+ simulate('keydown', {keyCode: $.simulate.VK_LEFT}).
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ date.setDate(date.getDate() + 1);
+ equalsDate(inp.datepicker('getDate'), date, 'Keystroke left');
+ inp.val('').datepicker('show').
+ simulate('keydown', {ctrlKey: true, keyCode: $.simulate.VK_RIGHT}).
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ date.setDate(date.getDate() + 1);
+ equalsDate(inp.datepicker('getDate'), date, 'Keystroke ctrl+right');
+ inp.val('').datepicker('show').
+ simulate('keydown', {keyCode: $.simulate.VK_RIGHT}).
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ date.setDate(date.getDate() - 1);
+ equalsDate(inp.datepicker('getDate'), date, 'Keystroke right');
+ inp.val('').datepicker('show').
+ simulate('keydown', {ctrlKey: true, keyCode: $.simulate.VK_UP}).
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ date.setDate(date.getDate() - 7);
+ equalsDate(inp.datepicker('getDate'), date, 'Keystroke ctrl+up');
+ inp.val('').datepicker('show').
+ simulate('keydown', {keyCode: $.simulate.VK_UP}).
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ date.setDate(date.getDate() + 7);
+ equalsDate(inp.datepicker('getDate'), date, 'Keystroke up');
+ inp.val('').datepicker('show').
+ simulate('keydown', {ctrlKey: true, keyCode: $.simulate.VK_DOWN}).
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ date.setDate(date.getDate() + 7);
+ equalsDate(inp.datepicker('getDate'), date, 'Keystroke ctrl+down');
+ inp.val('').datepicker('show').
+ simulate('keydown', {keyCode: $.simulate.VK_DOWN}).
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ date.setDate(date.getDate() - 7);
+ equalsDate(inp.datepicker('getDate'), date, 'Keystroke down');
+ // Moving by month or year
+ inp.val('02/04/2008').datepicker('show').
+ simulate('keydown', {keyCode: $.simulate.VK_PGUP}).
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ equalsDate(inp.datepicker('getDate'), new Date(2008, 1 - 1, 4),
+ 'Keystroke pgup');
+ inp.val('02/04/2008').datepicker('show').
+ simulate('keydown', {keyCode: $.simulate.VK_PGDN}).
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ equalsDate(inp.datepicker('getDate'), new Date(2008, 3 - 1, 4),
+ 'Keystroke pgdn');
+ inp.val('02/04/2008').datepicker('show').
+ simulate('keydown', {ctrlKey: true, keyCode: $.simulate.VK_PGUP}).
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ 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: $.simulate.VK_PGDN}).
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ 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: $.simulate.VK_PGUP}).
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ equalsDate(inp.datepicker('getDate'), new Date(2008, 2 - 1, 29),
+ 'Keystroke pgup - Feb');
+ inp.val('01/30/2008').datepicker('show').
+ simulate('keydown', {keyCode: $.simulate.VK_PGDN}).
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ 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: $.simulate.VK_PGUP}).
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ 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: $.simulate.VK_PGDN}).
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ 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: $.simulate.VK_PGDN}).
+ simulate('keydown', {ctrlKey: true, keyCode: $.simulate.VK_HOME}).
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ 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: $.simulate.VK_PGUP}).
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ equalsDate(inp.datepicker('getDate'), new Date(2007, 12 - 1, 4),
+ 'Keystroke pgup step 2');
+ inp.val('02/04/2008').datepicker('show').
+ simulate('keydown', {keyCode: $.simulate.VK_PGDN}).
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ equalsDate(inp.datepicker('getDate'), new Date(2008, 4 - 1, 4),
+ 'Keystroke pgdn step 2');
+});
+
+test('mouse', function() {
+ var inp = init('#inp');
+ var dp = $('#ui-datepicker-div');
+ var date = new Date();
+ inp.val('').datepicker('show');
+ $('.ui-datepicker-calendar tbody a:contains(10)', dp).simulate('click', {});
+ date.setDate(10);
+ equalsDate(inp.datepicker('getDate'), date, 'Mouse click');
+ inp.val('02/04/2008').datepicker('show');
+ $('.ui-datepicker-calendar tbody a:contains(12)', dp).simulate('click', {});
+ 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', {});
+ 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', {});
+ 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);
+ 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');
+ 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');
+ 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');
+ 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');
+ equalsDate(inp.datepicker('getDate'), new Date(2008, 2 - 1, 18),
+ 'Mouse click - next + min/max');
+ // Inline
+ var inl = init('#inl');
+ var dp = $('.ui-datepicker-inline', inl);
+ var date = new Date();
+ inl.datepicker('setDate', date);
+ $('.ui-datepicker-calendar tbody a:contains(10)', dp).simulate('click', {});
+ date.setDate(10);
+ 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', {});
+ 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);
+ 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');
+ 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');
+ equalsDate(inl.datepicker('getDate'), new Date(2008, 3 - 1, 18),
+ 'Mouse click inline - next');
+});
+
+test('defaultDate', function() {
+ var inp = init('#inp');
+ var date = new Date();
+ inp.val('').datepicker('show').
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ equalsDate(inp.datepicker('getDate'), date, 'Default date null');
+ // numeric values
+ inp.datepicker('option', {defaultDate: -2}).
+ datepicker('hide').val('').datepicker('show').
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ date.setDate(date.getDate() - 2);
+ equalsDate(inp.datepicker('getDate'), date, 'Default date -2');
+ inp.datepicker('option', {defaultDate: 3}).
+ datepicker('hide').val('').datepicker('show').
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ date.setDate(date.getDate() + 5);
+ equalsDate(inp.datepicker('getDate'), date, 'Default date 3');
+ inp.datepicker('option', {defaultDate: 1 / 0}).
+ datepicker('hide').val('').datepicker('show').
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ date.setDate(date.getDate() - 3);
+ equalsDate(inp.datepicker('getDate'), date, 'Default date Infinity');
+ inp.datepicker('option', {defaultDate: 1 / 'a'}).
+ datepicker('hide').val('').datepicker('show').
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ equalsDate(inp.datepicker('getDate'), date, 'Default date NaN');
+ // string values
+ inp.datepicker('option', {defaultDate: '-1d'}).
+ datepicker('hide').val('').datepicker('show').
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ date.setDate(date.getDate() - 1);
+ equalsDate(inp.datepicker('getDate'), date, 'Default date -1d');
+ inp.datepicker('option', {defaultDate: '+3D'}).
+ datepicker('hide').val('').datepicker('show').
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ date.setDate(date.getDate() + 4);
+ equalsDate(inp.datepicker('getDate'), date, 'Default date +3D');
+ inp.datepicker('option', {defaultDate: ' -2 w '}).
+ datepicker('hide').val('').datepicker('show').
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ date = new Date();
+ date.setDate(date.getDate() - 14);
+ equalsDate(inp.datepicker('getDate'), date, 'Default date -2 w');
+ inp.datepicker('option', {defaultDate: '+1 W'}).
+ datepicker('hide').val('').datepicker('show').
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ date.setDate(date.getDate() + 21);
+ equalsDate(inp.datepicker('getDate'), date, 'Default date +1 W');
+ inp.datepicker('option', {defaultDate: ' -1 m '}).
+ datepicker('hide').val('').datepicker('show').
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ date = new Date();
+ date.setMonth(date.getMonth() - 1);
+ equalsDate(inp.datepicker('getDate'), date, 'Default date -1 m');
+ inp.datepicker('option', {defaultDate: '+2M'}).
+ datepicker('hide').val('').datepicker('show').
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ date.setMonth(date.getMonth() + 3);
+ equalsDate(inp.datepicker('getDate'), date, 'Default date +2M');
+ inp.datepicker('option', {defaultDate: '-2y'}).
+ datepicker('hide').val('').datepicker('show').
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ date = new Date();
+ date.setFullYear(date.getFullYear() - 2);
+ equalsDate(inp.datepicker('getDate'), date, 'Default date -2y');
+ inp.datepicker('option', {defaultDate: '+1 Y '}).
+ datepicker('hide').val('').datepicker('show').
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ date.setFullYear(date.getFullYear() + 3);
+ equalsDate(inp.datepicker('getDate'), date, 'Default date +1 Y');
+ inp.datepicker('option', {defaultDate: '+1M +10d'}).
+ datepicker('hide').val('').datepicker('show').
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ date = new Date();
+ date.setMonth(date.getMonth() + 1);
+ date.setDate(date.getDate() + 10);
+ equalsDate(inp.datepicker('getDate'), date, 'Default date +1M +10d');
+ date = new Date(2007, 1 - 1, 26);
+ inp.datepicker('option', {defaultDate: date}).
+ datepicker('hide').val('').datepicker('show').
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ equalsDate(inp.datepicker('getDate'), date, 'Default date 01/26/2007');
+});
+
+test('miscellaneous', function() {
+ var dp = $('#ui-datepicker-div');
+ var inp = init('#inp');
+ // Year range
+ var genRange = function(start, offset) {
+ var range = '';
+ for (var i = start; i < start + offset; i++) {
+ range += i;
+ }
+ return range;
+ };
+ inp.val('02/04/2008').datepicker('show');
+ equals(dp.find('.ui-datepicker-year').text(), '2008', 'Year range - read-only default');
+ inp.datepicker('hide').datepicker('option', {changeYear: true}).datepicker('show');
+ equals(dp.find('.ui-datepicker-year').text(), genRange(new Date().getFullYear() - 10, 21), 'Year range - changeable default');
+ inp.datepicker('hide').datepicker('option', {yearRange: '-6:+2', changeYear: true}).datepicker('show');
+ equals(dp.find('.ui-datepicker-year').text(), genRange(new Date().getFullYear() - 6, 9), 'Year range - -6:+2');
+ inp.datepicker('hide').datepicker('option', {yearRange: '2000:2010', changeYear: true}).datepicker('show');
+ equals(dp.find('.ui-datepicker-year').text(), genRange(2000, 11), 'Year range - 2000:2010');
+
+ // Navigation as date format
+ inp.datepicker('option', {showButtonPanel: true});
+ equals(dp.find('.ui-datepicker-prev').text(), 'Prev', 'Navigation prev - default');
+ equals(dp.find('.ui-datepicker-current').text(), 'Today', 'Navigation current - default');
+ equals(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');
+ var longNames = $.datepicker.regional[''].monthNames;
+ var shortNames = $.datepicker.regional[''].monthNamesShort;
+ var date = new Date();
+ equals(dp.find('.ui-datepicker-prev').text(), '< ' + shortNames[0], 'Navigation prev - as date format');
+ equals(dp.find('.ui-datepicker-current').text(),
+ longNames[date.getMonth()], 'Navigation current - as date format');
+ equals(dp.find('.ui-datepicker-next').text(),
+ shortNames[2] + ' >', 'Navigation next - as date format');
+ inp.simulate('keydown', {keyCode: $.simulate.VK_PGDN});
+ equals(dp.find('.ui-datepicker-prev').text(),
+ '< ' + shortNames[1], 'Navigation prev - as date format + pgdn');
+ equals(dp.find('.ui-datepicker-current').text(),
+ longNames[date.getMonth()], 'Navigation current - as date format + pgdn');
+ equals(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');
+ equals(dp.find('.ui-datepicker-prev').text(),
+ '< ' + shortNames[0], 'Navigation prev - as date format + goto current');
+ equals(dp.find('.ui-datepicker-current').text(),
+ longNames[1], 'Navigation current - as date format + goto current');
+ equals(dp.find('.ui-datepicker-next').text(),
+ shortNames[2] + ' >', 'Navigation next - as date format + goto current');
+});
+
+test('minMax', function() {
+ var inp = init('#inp');
+ var lastYear = new Date(2007, 6 - 1, 4);
+ var nextYear = new Date(2009, 6 - 1, 4);
+ var minDate = new Date(2008, 2 - 1, 29);
+ var maxDate = new Date(2008, 12 - 1, 7);
+ inp.val('06/04/2008').datepicker('show');
+ inp.simulate('keydown', {ctrlKey: true, keyCode: $.simulate.VK_PGUP}).
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ equalsDate(inp.datepicker('getDate'), lastYear,
+ 'Min/max - null, null - ctrl+pgup');
+ inp.val('06/04/2008').datepicker('show');
+ inp.simulate('keydown', {ctrlKey: true, keyCode: $.simulate.VK_PGDN}).
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ 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: $.simulate.VK_PGUP}).
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ 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: $.simulate.VK_PGDN}).
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ 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: $.simulate.VK_PGUP}).
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ 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: $.simulate.VK_PGDN}).
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ 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: $.simulate.VK_PGUP}).
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ 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: $.simulate.VK_PGDN}).
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ equalsDate(inp.datepicker('getDate'), maxDate,
+ 'Min/max - null, 12/07/2008 - ctrl+pgdn');
+ // Relative dates
+ var 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: $.simulate.VK_PGUP}).
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ equalsDate(inp.datepicker('getDate'), date,
+ 'Min/max - -1w, +1 M +10 D - ctrl+pgup');
+ date = new Date();
+ date.setMonth(date.getMonth() + 1);
+ date.setDate(date.getDate() + 10);
+ inp.val('').datepicker('show');
+ inp.simulate('keydown', {ctrlKey: true, keyCode: $.simulate.VK_PGDN}).
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ equalsDate(inp.datepicker('getDate'), date,
+ 'Min/max - -1w, +1 M +10 D - ctrl+pgdn');
+});
+
+test('setDate', function() {
+ var inp = init('#inp');
+ var date1 = new Date(2008, 6 - 1, 4);
+ var date2 = new Date();
+ ok(inp.datepicker('getDate') == null, 'Set date - default');
+ inp.datepicker('setDate', date1);
+ equalsDate(inp.datepicker('getDate'), date1, 'Set date - 2008-06-04');
+ date1 = new Date();
+ date1.setDate(date1.getDate() + 7);
+ inp.datepicker('setDate', +7);
+ equalsDate(inp.datepicker('getDate'), date1, 'Set date - +7');
+ date2.setFullYear(date2.getFullYear() + 2);
+ inp.datepicker('setDate', '+2y');
+ equalsDate(inp.datepicker('getDate'), date2, 'Set date - +2y');
+ inp.datepicker('setDate', date1, date2);
+ equalsDate(inp.datepicker('getDate'), date1, 'Set date - two dates');
+ inp.datepicker('setDate');
+ ok(inp.datepicker('getDate') == null, 'Set date - null');
+ // Inline
+ var inl = init('#inl');
+ date1 = new Date(2008, 6 - 1, 4);
+ date2 = new Date();
+ equalsDate(inl.datepicker('getDate'), date2, 'Set date inline - default');
+ inl.datepicker('setDate', date1);
+ equalsDate(inl.datepicker('getDate'), date1, 'Set date inline - 2008-06-04');
+ date1 = new Date();
+ date1.setDate(date1.getDate() + 7);
+ inl.datepicker('setDate', +7);
+ equalsDate(inl.datepicker('getDate'), date1, 'Set date inline - +7');
+ date2.setFullYear(date2.getFullYear() + 2);
+ inl.datepicker('setDate', '+2y');
+ equalsDate(inl.datepicker('getDate'), date2, 'Set date inline - +2y');
+ inl.datepicker('setDate', date1, date2);
+ equalsDate(inl.datepicker('getDate'), date1, 'Set date inline - two dates');
+ inl.datepicker('setDate');
+ ok(inl.datepicker('getDate') == null, 'Set date inline - null');
+ // Alternate field
+ var alt = $('#alt');
+ inp.datepicker('option', {altField: '#alt', altFormat: 'yy-mm-dd'});
+ date1 = new Date(2008, 6 - 1, 4);
+ inp.datepicker('setDate', date1);
+ equals(inp.val(), '06/04/2008', 'Set date alternate - 06/04/2008');
+ equals(alt.val(), '2008-06-04', 'Set date alternate - 2008-06-04');
+});
+
+test('altField', function() {
+ var inp = init('#inp');
+ var alt = $('#alt');
+ // No alternate field set
+ alt.val('');
+ inp.val('06/04/2008').datepicker('show');
+ inp.simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ equals(inp.val(), '06/04/2008', 'Alt field - dp - enter');
+ equals(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: $.simulate.VK_ENTER});
+ equals(inp.val(), '06/04/2008', 'Alt field - dp - enter');
+ equals(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: $.simulate.VK_PGDN}).
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ equals(inp.val(), '07/04/2008', 'Alt field - dp - pgdn');
+ equals(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: $.simulate.VK_PGDN}).
+ simulate('keydown', {keyCode: $.simulate.VK_ESC});
+ equals(inp.val(), '06/04/2008', 'Alt field - dp - pgdn/esc');
+ equals(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: $.simulate.VK_END});
+ equals(inp.val(), '', 'Alt field - dp - ctrl+end');
+ equals(alt.val(), '', 'Alt field - alt - ctrl+end');
+});
+
+test('daylightSaving', function() {
+ var inp = init('#inp');
+ var 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');
+ equals(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');
+ equals(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');
+ equals(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');
+ equals(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');
+ equals(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');
+ equals(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');
+ equals(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');
+ equals(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');
+ equals(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');
+ equals(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');
+ equals(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');
+ equals(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');
+ equals(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');
+ equals(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');
+ equals(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');
+ equals(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');
+ equals(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');
+ equals(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');
+ equals(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');
+ equals(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');
+ equals(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');
+ equals(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');
+ equals(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');
+ equals(inp.val(), '11/03/2008', 'Daylight saving - US 11/03/2008');
+});
+
+var beforeShowThis = null;
+var beforeShowInput = null;
+var beforeShowInst = null;
+
+function beforeAll(input, inst) {
+ beforeShowThis = this;
+ beforeShowInput = input;
+ beforeShowInst = inst;
+ return {currentText: 'Current'};
+}
+
+var beforeShowDayThis = null;
+var beforeShowDayOK = true;
+
+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' : '')];
+}
+
+function calcWeek(date) {
+ var doy = date.getDate() + 6;
+ for (var m = date.getMonth() - 1; m >= 0; m--)
+ doy += $.datepicker._getDaysInMonth(date.getFullYear(), m);
+ // Simple count from 01/01 starting at week 1
+ return Math.floor(doy / 7);
+}
+
+test('callbacks', function() {
+ // Before show
+ var inp = init('#inp', {beforeShow: beforeAll});
+ var inst = $.data(inp[0], 'datepicker');
+ equals($.datepicker._get(inst, 'currentText'), 'Today', 'Before show - initial');
+ inp.val('02/04/2008').datepicker('show');
+ equals($.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');
+ isObj(beforeShowInst, inst, 'Before show - inst OK');
+ inp.datepicker('hide').datepicker('destroy');
+ // Before show day
+ inp = init('#inp', {beforeShowDay: beforeDay});
+ var 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');
+ var day20 = dp.find('.ui-datepicker-calendar td:contains("20")');
+ var 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');
+});
+
+var selectedThis = null;
+var selectedDate = null;
+var 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() {
+ var inp = init('#inp', {onSelect: callback});
+ var date = new Date();
+ // onSelect
+ inp.val('').datepicker('show').
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ equals(selectedThis, inp[0], 'Callback selected this');
+ equals(selectedInst, $.data(inp[0], PROP_NAME), 'Callback selected inst');
+ equals(selectedDate, $.datepicker.formatDate('mm/dd/yy', date),
+ 'Callback selected date');
+ inp.val('').datepicker('show').
+ simulate('keydown', {ctrlKey: true, keyCode: $.simulate.VK_DOWN}).
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ date.setDate(date.getDate() + 7);
+ equals(selectedDate, $.datepicker.formatDate('mm/dd/yy', date),
+ 'Callback selected date - ctrl+down');
+ inp.val('').datepicker('show').
+ simulate('keydown', {keyCode: $.simulate.VK_ESC});
+ equals(selectedDate, $.datepicker.formatDate('mm/dd/yy', date),
+ 'Callback selected date - esc');
+ // onChangeMonthYear
+ inp.datepicker('option', {onChangeMonthYear: callback2, onSelect: null}).
+ val('').datepicker('show');
+ var newMonthYear = function(date) {
+ return date.getFullYear() + '/' + (date.getMonth() + 1);
+ };
+ date = new Date();
+ date.setDate(1);
+ inp.simulate('keydown', {keyCode: $.simulate.VK_PGUP});
+ date.setMonth(date.getMonth() - 1);
+ equals(selectedThis, inp[0], 'Callback change month/year this');
+ equals(selectedInst, $.data(inp[0], PROP_NAME), 'Callback change month/year inst');
+ equals(selectedDate, newMonthYear(date),
+ 'Callback change month/year date - pgup');
+ inp.simulate('keydown', {keyCode: $.simulate.VK_PGDN});
+ date.setMonth(date.getMonth() + 1);
+ equals(selectedDate, newMonthYear(date),
+ 'Callback change month/year date - pgdn');
+ inp.simulate('keydown', {ctrlKey: true, keyCode: $.simulate.VK_PGUP});
+ date.setFullYear(date.getFullYear() - 1);
+ equals(selectedDate, newMonthYear(date),
+ 'Callback change month/year date - ctrl+pgup');
+ inp.simulate('keydown', {ctrlKey: true, keyCode: $.simulate.VK_HOME});
+ date.setFullYear(date.getFullYear() + 1);
+ equals(selectedDate, newMonthYear(date),
+ 'Callback change month/year date - ctrl+home');
+ inp.simulate('keydown', {ctrlKey: true, keyCode: $.simulate.VK_PGDN});
+ date.setFullYear(date.getFullYear() + 1);
+ equals(selectedDate, newMonthYear(date),
+ 'Callback change month/year date - ctrl+pgdn');
+ inp.datepicker('setDate', new Date(2007, 1 - 1, 26));
+ equals(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: $.simulate.VK_PGUP});
+ date.setMonth(date.getMonth() - 14);
+ equals(selectedDate, newMonthYear(date),
+ 'Callback change month/year by 2 date - pgup');
+ inp.simulate('keydown', {ctrlKey: true, keyCode: $.simulate.VK_PGUP});
+ date.setMonth(date.getMonth() - 12);
+ equals(selectedDate, newMonthYear(date),
+ 'Callback change month/year by 2 date - ctrl+pgup');
+ inp.simulate('keydown', {keyCode: $.simulate.VK_PGDN});
+ date.setMonth(date.getMonth() + 2);
+ equals(selectedDate, newMonthYear(date),
+ 'Callback change month/year by 2 date - pgdn');
+ inp.simulate('keydown', {ctrlKey: true, keyCode: $.simulate.VK_PGDN});
+ date.setMonth(date.getMonth() + 12);
+ equals(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: $.simulate.VK_ESC});
+ equals(selectedThis, inp[0], 'Callback close this');
+ equals(selectedInst, $.data(inp[0], PROP_NAME), 'Callback close inst');
+ equals(selectedDate, '', 'Callback close date - esc');
+ inp.val('').datepicker('show').
+ simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ equals(selectedDate, $.datepicker.formatDate('mm/dd/yy', new Date()),
+ 'Callback close date - enter');
+ inp.val('02/04/2008').datepicker('show').
+ simulate('keydown', {keyCode: $.simulate.VK_ESC});
+ equals(selectedDate, '02/04/2008', 'Callback close date - preset');
+ inp.val('02/04/2008').datepicker('show').
+ simulate('keydown', {ctrlKey: true, keyCode: $.simulate.VK_END});
+ equals(selectedDate, '', 'Callback close date - ctrl+end');
+});
+
+test('localisation', function() {
+ var inp = init('#inp', $.datepicker.regional['fr']);
+ inp.datepicker('option', {dateFormat: 'DD, d MM yy', showButtonPanel:true, changeMonth:true, changeYear:true}).val('').datepicker('show');
+ var dp = $('#ui-datepicker-div');
+ equals($('.ui-datepicker-close', dp).text(), 'Fermer', 'Localisation - close');
+ $('.ui-datepicker-close', dp).simulate('mouseover');
+ equals($('.ui-datepicker-prev', dp).text(), '<Préc', 'Localisation - previous');
+ equals($('.ui-datepicker-current', dp).text(), 'Courant', 'Localisation - current');
+ equals($('.ui-datepicker-next', dp).text(), 'Suiv>', 'Localisation - next');
+ var month = 0;
+ $('.ui-datepicker-month option', dp).each(function() {
+ equals($(this).text(), $.datepicker.regional['fr'].monthNamesShort[month],
+ 'Localisation - month ' + month);
+ month++;
+ });
+ var day = 1;
+ $('.ui-datepicker-calendar th', dp).each(function() {
+ equals($(this).text(), $.datepicker.regional['fr'].dayNamesMin[day],
+ 'Localisation - day ' + day);
+ day = (day + 1) % 7;
+ });
+ inp.simulate('keydown', {keyCode: $.simulate.VK_ENTER});
+ var date = new Date();
+ equals(inp.val(), $.datepicker.regional['fr'].dayNames[date.getDay()] + ', ' +
+ date.getDate() + ' ' + $.datepicker.regional['fr'].monthNames[date.getMonth()] +
+ ' ' + date.getFullYear(), 'Localisation - formatting');
+});
+
+test('noWeekends', function() {
+ for (var i = 1; i <= 31; i++) {
+ var date = new Date(2001, 1 - 1, i);
+ isSet($.datepicker.noWeekends(date), [(i + 1) % 7 >= 2, ''],
+ 'No weekends ' + date);
+ }
+});
+
+test('iso8601Week', function() {
+ var date = new Date(2000, 12 - 1, 31);
+ equals($.datepicker.iso8601Week(date), 52, 'ISO 8601 week ' + date);
+ date = new Date(2001, 1 - 1, 1);
+ equals($.datepicker.iso8601Week(date), 1, 'ISO 8601 week ' + date);
+ date = new Date(2001, 1 - 1, 7);
+ equals($.datepicker.iso8601Week(date), 1, 'ISO 8601 week ' + date);
+ date = new Date(2001, 1 - 1, 8);
+ equals($.datepicker.iso8601Week(date), 2, 'ISO 8601 week ' + date);
+ date = new Date(2003, 12 - 1, 28);
+ equals($.datepicker.iso8601Week(date), 52, 'ISO 8601 week ' + date);
+ date = new Date(2003, 12 - 1, 29);
+ equals($.datepicker.iso8601Week(date), 1, 'ISO 8601 week ' + date);
+ date = new Date(2004, 1 - 1, 4);
+ equals($.datepicker.iso8601Week(date), 1, 'ISO 8601 week ' + date);
+ date = new Date(2004, 1 - 1, 5);
+ equals($.datepicker.iso8601Week(date), 2, 'ISO 8601 week ' + date);
+ date = new Date(2009, 12 - 1, 28);
+ equals($.datepicker.iso8601Week(date), 53, 'ISO 8601 week ' + date);
+ date = new Date(2010, 1 - 1, 3);
+ equals($.datepicker.iso8601Week(date), 53, 'ISO 8601 week ' + date);
+ date = new Date(2010, 1 - 1, 4);
+ equals($.datepicker.iso8601Week(date), 1, 'ISO 8601 week ' + date);
+ date = new Date(2010, 1 - 1, 10);
+ equals($.datepicker.iso8601Week(date), 1, 'ISO 8601 week ' + date);
+});
+
+test('parseDate', function() {
+ init('#inp');
+ ok($.datepicker.parseDate('d m y', '') == null, 'Parse date empty');
+ equalsDate($.datepicker.parseDate('d m y', '3 2 01'),
+ new Date(2001, 2 - 1, 3), 'Parse date d m y');
+ equalsDate($.datepicker.parseDate('dd mm yy', '03 02 2001'),
+ new Date(2001, 2 - 1, 3), 'Parse date dd mm yy');
+ equalsDate($.datepicker.parseDate('d m y', '13 12 01'),
+ new Date(2001, 12 - 1, 13), 'Parse date d m y');
+ equalsDate($.datepicker.parseDate('dd mm yy', '13 12 2001'),
+ new Date(2001, 12 - 1, 13), 'Parse date dd mm yy');
+ equalsDate($.datepicker.parseDate('y-o', '2001-34'),
+ new Date(2001, 2 - 1, 3), 'Parse date y-o');
+ equalsDate($.datepicker.parseDate('yy-oo', '2001-347'),
+ new Date(2001, 12 - 1, 13), 'Parse date yy oo');
+ equalsDate($.datepicker.parseDate('oo yy', '348 2004'),
+ new Date(2004, 12 - 1, 13), 'Parse date oo-yy');
+ equalsDate($.datepicker.parseDate('D d M y', 'Sat 3 Feb 01'),
+ new Date(2001, 2 - 1, 3), 'Parse date D d M y');
+ equalsDate($.datepicker.parseDate('d MM DD yy', '3 February Saturday 2001'),
+ new Date(2001, 2 - 1, 3), 'Parse date dd MM DD yy');
+ equalsDate($.datepicker.parseDate('DD, MM d, yy', 'Saturday, February 3, 2001'),
+ new Date(2001, 2 - 1, 3), 'Parse date DD, MM d, yy');
+ 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');
+ equalsDate($.datepicker.parseDate('y-m-d', '01-02-03'),
+ new Date(2001, 2 - 1, 3), 'Parse date y-m-d - default cutoff');
+ equalsDate($.datepicker.parseDate('y-m-d', '51-02-03'),
+ new Date(1951, 2 - 1, 3), 'Parse date y-m-d - default cutoff');
+ equalsDate($.datepicker.parseDate('y-m-d', '51-02-03', {shortYearCutoff: 80}),
+ new Date(2051, 2 - 1, 3), 'Parse date y-m-d - cutoff 80');
+ equalsDate($.datepicker.parseDate('y-m-d', '51-02-03', {shortYearCutoff: '+60'}),
+ new Date(2051, 2 - 1, 3), 'Parse date y-m-d - cutoff +60');
+ var fr = $.datepicker.regional['fr'];
+ var settings = {dayNamesShort: fr.dayNamesShort, dayNames: fr.dayNames,
+ monthNamesShort: fr.monthNamesShort, monthNames: fr.monthNames};
+ 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');
+ 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');
+ 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');
+ 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');
+});
+
+test('parseDateErrors', function() {
+ init('#inp');
+ var expectError = function(expr, value, error) {
+ try {
+ expr();
+ ok(false, 'Parsed error ' + value);
+ }
+ catch (e) {
+ equals(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('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', '2001-D01'); },
+ '2001-D01 - y-o', 'Missing number at position 5');
+ 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');
+ var fr = $.datepicker.regional['fr'];
+ var 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 6');
+});
+
+test('formatDate', function() {
+ init('#inp');
+ equals($.datepicker.formatDate('d m y', new Date(2001, 2 - 1, 3)),
+ '3 2 01', 'Format date d m y');
+ equals($.datepicker.formatDate('dd mm yy', new Date(2001, 2 - 1, 3)),
+ '03 02 2001', 'Format date dd mm yy');
+ equals($.datepicker.formatDate('d m y', new Date(2001, 12 - 1, 13)),
+ '13 12 01', 'Format date d m y');
+ equals($.datepicker.formatDate('dd mm yy', new Date(2001, 12 - 1, 13)),
+ '13 12 2001', 'Format date dd mm yy');
+ equals($.datepicker.formatDate('yy-o', new Date(2001, 2 - 1, 3)),
+ '2001-34', 'Format date yy-o');
+ equals($.datepicker.formatDate('yy-oo', new Date(2001, 2 - 1, 3)),
+ '2001-034', 'Format date yy-oo');
+ equals($.datepicker.formatDate('D M y', new Date(2001, 2 - 1, 3)),
+ 'Sat Feb 01', 'Format date D M y');
+ equals($.datepicker.formatDate('DD MM yy', new Date(2001, 2 - 1, 3)),
+ 'Saturday February 2001', 'Format date DD MM yy');
+ equals($.datepicker.formatDate('DD, MM d, yy', new Date(2001, 2 - 1, 3)),
+ 'Saturday, February 3, 2001', 'Format date DD, MM d, yy');
+ equals($.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');
+ var fr = $.datepicker.regional['fr'];
+ var settings = {dayNamesShort: fr.dayNamesShort, dayNames: fr.dayNames,
+ monthNamesShort: fr.monthNamesShort, monthNames: fr.monthNames};
+ equals($.datepicker.formatDate('D M y', new Date(2001, 4 - 1, 9), settings),
+ 'Lun Avr 01', 'Format date D M y with settings');
+ equals($.datepicker.formatDate('DD MM yy', new Date(2001, 4 - 1, 9), settings),
+ 'Lundi Avril 2001', 'Format date DD MM yy with settings');
+ equals($.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');
+ equals($.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');
+});
+
+})(jQuery);
diff --git a/tests/unit/dialog/dialog.html b/tests/unit/dialog/dialog.html
new file mode 100644
index 000000000..184430ec7
--- /dev/null
+++ b/tests/unit/dialog/dialog.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <title>jQuery UI Dialog Test Suite</title>
+
+ <script type="text/javascript" src="../../../jquery-1.3pre.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.core.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.dialog.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.draggable.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.resizable.js"></script>
+
+ <link type="text/css" href="../testsuite.css" rel="stylesheet" />
+ <script type="text/javascript" src="../testsuite.js"></script>
+ <script type="text/javascript" src="../../../external/qunit/testrunner.js"></script>
+ <script type="text/javascript" src="../../../external/simulate/jquery.simulate.js"></script>
+
+ <script type="text/javascript" src="dialog.js"></script>
+</head>
+<body>
+
+<div id="main">
+ <div id="dialog1">Dialog Content</div>
+</div>
+
+</body>
+</html>
diff --git a/tests/unit/dialog/dialog.js b/tests/unit/dialog/dialog.js
new file mode 100644
index 000000000..ff537174b
--- /dev/null
+++ b/tests/unit/dialog/dialog.js
@@ -0,0 +1,723 @@
+/*
+ * dialog unit tests
+ */
+(function($) {
+//
+// Dialog Test Helper Functions
+//
+
+var defaults = {
+ autoOpen: true,
+ buttons: {},
+ closeOnEscape: true,
+ closeText: 'close',
+ disabled: false,
+ dialogClass: undefined,
+ draggable: true,
+ height: 'auto',
+ maxHeight: undefined,
+ maxWidth: undefined,
+ minHeight: 150,
+ minWidth: 150,
+ modal: false,
+ overlay: {},
+ position: 'center',
+ resizable: true,
+ stack: true,
+ title: '',
+ width: 300
+};
+
+var el,
+ offsetBefore, offsetAfter,
+ heightBefore, heightAfter,
+ widthBefore, widthAfter,
+ dragged;
+
+function dlg() {
+ return el.data("dialog").element.parents(".ui-dialog:first");
+}
+
+function isOpen(why) {
+ ok(dlg().is(":visible"), why);
+}
+
+function isNotOpen(why) {
+ ok(!dlg().is(":visible"), why);
+}
+
+function drag(handle, dx, dy) {
+ var d = dlg();
+ offsetBefore = d.offset();
+ heightBefore = d.height();
+ widthBefore = d.width();
+ //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");
+ $(handle, d).simulate("drag", {
+ dx: dx || 0,
+ dy: dy || 0
+ });
+ dragged = { dx: dx, dy: dy };
+ offsetAfter = d.offset();
+ heightAfter = d.height();
+ widthAfter = d.width();
+}
+
+function moved(dx, dy, msg) {
+ msg = msg ? msg + "." : "";
+ var actual = { left: offsetAfter.left, top: offsetAfter.top };
+ var expected = { left: offsetBefore.left + dx, top: offsetBefore.top + dy };
+ same(actual, expected, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ' + msg);
+}
+
+function shouldmove(why) {
+ var handle = $(".ui-dialog-titlebar", dlg());
+ drag(handle, 50, 50);
+ moved(50, 50, why);
+}
+
+function shouldnotmove(why) {
+ var handle = $(".ui-dialog-titlebar", dlg());
+ drag(handle, 50, 50);
+ moved(0, 0, why);
+}
+
+function resized(dw, dh, msg) {
+ msg = msg ? msg + "." : "";
+ var actual = { width: widthAfter, height: heightAfter };
+ var expected = { width: widthBefore + dw, height: heightBefore + dh };
+ same(actual, expected, 'resized[' + dragged.dx + ', ' + dragged.dy + '] ' + msg);
+}
+
+function shouldresize(why) {
+ var handle = $(".ui-resizable-se", dlg());
+ drag(handle, 50, 50);
+ resized(50, 50, why);
+}
+
+function shouldnotresize(why) {
+ var handle = $(".ui-resizable-se", dlg());
+ drag(handle, 50, 50);
+ resized(0, 0, why);
+}
+
+function broder(el, side){
+ return parseInt(el.css('border-' + side + '-width'), 10);
+}
+
+function margin(el, side) {
+ return parseInt(el.css('margin-' + side), 10);
+}
+
+// Dialog Tests
+module("dialog");
+
+test("init", function() {
+ expect(7);
+
+ $("<div></div>").appendTo('body').dialog().remove();
+ ok(true, '.dialog() called on element');
+
+ $([]).dialog().remove();
+ ok(true, '.dialog() called on empty collection');
+
+ $('<div></div>').dialog().remove();
+ ok(true, '.dialog() called on disconnected DOMElement - never connected');
+
+ $('<div></div>').appendTo('body').remove().dialog().remove();
+ ok(true, '.dialog() called on disconnected DOMElement - removed');
+
+ $('<div></div>').dialog().dialog("foo").remove();
+ ok(true, 'arbitrary method called after init');
+
+ el = $('<div></div>').dialog();
+ var foo = el.data("foo.dialog");
+ el.remove();
+ ok(true, 'arbitrary option getter after init');
+
+ $('<div></div>').dialog().data("foo.dialog", "bar").remove();
+ ok(true, 'arbitrary option setter after init');
+});
+
+test("destroy", function() {
+ expect(6);
+
+ $("<div></div>").appendTo('body').dialog().dialog("destroy").remove();
+ ok(true, '.dialog("destroy") called on element');
+
+ $([]).dialog().dialog("destroy").remove();
+ ok(true, '.dialog("destroy") called on empty collection');
+
+ $('<div></div>').dialog().dialog("destroy").remove();
+ ok(true, '.dialog("destroy") called on disconnected DOMElement');
+
+ $('<div></div>').dialog().dialog("destroy").dialog("foo").remove();
+ ok(true, 'arbitrary method called after destroy');
+
+ el = $('<div></div>').dialog();
+ var foo = el.dialog("destroy").data("foo.dialog");
+ el.remove();
+ ok(true, 'arbitrary option getter after destroy');
+
+ $('<div></div>').dialog().dialog("destroy").data("foo.dialog", "bar").remove();
+ ok(true, 'arbitrary option setter after destroy');
+});
+
+/*
+//This one takes a while to run
+
+test("element types", function() {
+ 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,object,hr'
+ + ',input,button,label,select,iframe').split(',');
+
+ $.each(typeNames, function(i) {
+ var typeName = typeNames[i];
+ el = $(document.createElement(typeName)).appendTo('body');
+ (typeName == 'table' && el.append("<tr><td>content</td></tr>"));
+ el.dialog();
+ ok(true, '$("&lt;' + typeName + '/&gt").dialog()');
+ el.dialog("destroy");
+ el.remove();
+ });
+});
+
+*/
+
+test("defaults", function() {
+ el = $('<div></div>').dialog();
+ $.each(defaults, function(key, val) {
+ var actual = el.data(key + ".dialog"), expected = val;
+ same(actual, expected, key);
+ });
+ el.remove();
+});
+
+test("title id", function() {
+ expect(3);
+
+ var titleId;
+
+ // reset the uuid so we know what values to expect
+ $.ui.dialog.uuid = 0;
+
+ el = $('<div></div>').dialog();
+ titleId = dlg().find('.ui-dialog-title').attr('id');
+ equals(titleId, 'ui-dialog-title-1', 'auto-numbered title id');
+ el.remove();
+
+ el = $('<div></div>').dialog();
+ titleId = dlg().find('.ui-dialog-title').attr('id');
+ equals(titleId, 'ui-dialog-title-2', 'auto-numbered title id');
+ el.remove();
+
+ el = $('<div id="foo"/>').dialog();
+ titleId = dlg().find('.ui-dialog-title').attr('id');
+ equals(titleId, 'ui-dialog-title-foo', 'carried over title id');
+ el.remove();
+});
+
+test("ARIA", function() {
+ expect(4);
+
+ el = $('<div></div>').dialog();
+
+ equals(dlg().attr('role'), 'dialog', 'dialog role');
+
+ var labelledBy = dlg().attr('aria-labelledby');
+ ok(labelledBy.length > 0, 'has aria-labelledby attribute');
+ equals(dlg().find('.ui-dialog-title').attr('id'), labelledBy,
+ 'proper aria-labelledby attribute');
+
+ equals(dlg().find('.ui-dialog-titlebar-close').attr('role'), 'button',
+ 'close link role');
+
+ el.remove();
+});
+
+module("dialog: Options");
+
+test("autoOpen", function() {
+ expect(2);
+
+ el = $('<div></div>').dialog({ autoOpen: false });
+ isNotOpen('.dialog({ autoOpen: false })');
+ el.remove();
+
+ el = $('<div></div>').dialog({ autoOpen: true });
+ isOpen('.dialog({ autoOpen: true })');
+ el.remove();
+});
+
+test("buttons", function() {
+ expect(17);
+
+ var buttons = {
+ "Ok": function(ev, ui) {
+ ok(true, "button click fires callback");
+ equals(this, el[0], "context of callback");
+ equals(ev.target, btn[0], "event target");
+ },
+ "Cancel": function(ev, ui) {
+ ok(true, "button click fires callback");
+ equals(this, el[0], "context of callback");
+ equals(ev.target, btn[1], "event target");
+ }
+ };
+
+ el = $('<div></div>').dialog({ buttons: buttons });
+ var btn = $("button", dlg());
+ equals(btn.length, 2, "number of buttons");
+
+ var i = 0;
+ $.each(buttons, function(key, val) {
+ equals(btn.eq(i).text(), key, "text of button " + (i+1));
+ i++;
+ });
+
+ ok(btn.parent().hasClass('ui-dialog-buttonpane'), "buttons in container");
+ btn.trigger("click");
+
+ var newButtons = {
+ "Close": function(ev, ui) {
+ ok(true, "button click fires callback");
+ equals(this, el[0], "context of callback");
+ equals(ev.target, btn[0], "event target");
+ }
+ };
+
+ equals(el.data("buttons.dialog"), buttons, '.data("buttons.dialog") getter');
+ el.data("buttons.dialog", newButtons);
+ equals(el.data("buttons.dialog"), newButtons, '.data("buttons.dialog", ...) setter');
+
+ btn = $("button", dlg());
+ equals(btn.length, 1, "number of buttons after setter");
+ btn.trigger('click');
+
+ i = 0;
+ $.each(newButtons, function(key, val) {
+ equals(btn.eq(i).text(), key, "text of button " + (i+1));
+ i += 1;
+ });
+
+ el.remove();
+});
+
+test("closeOnEscape", function() {
+ ok(false, 'missing test');
+});
+
+test("closeText", function() {
+ expect(3);
+
+ el = $('<div></div>').dialog();
+ equals(dlg().find('.ui-dialog-titlebar-close span').text(), 'close',
+ 'default close text');
+ el.remove();
+
+ el = $('<div></div>').dialog({ closeText: "foo" });
+ equals(dlg().find('.ui-dialog-titlebar-close span').text(), 'foo',
+ 'closeText on init');
+ el.remove();
+
+ el = $('<div></div>').dialog().dialog('option', 'closeText', 'bar');
+ equals(dlg().find('.ui-dialog-titlebar-close span').text(), 'bar',
+ 'closeText via option method');
+ el.remove();
+});
+
+test("dialogClass", function() {
+ expect(4);
+
+ el = $('<div></div>').dialog();
+ equals(dlg().is(".foo"), false, 'dialogClass not specified. foo class added');
+ el.remove();
+
+ el = $('<div></div>').dialog({ dialogClass: "foo" });
+ equals(dlg().is(".foo"), true, 'dialogClass in init. foo class added');
+ el.remove();
+
+ el = $('<div></div>').dialog({ dialogClass: "foo bar" });
+ equals(dlg().is(".foo"), true, 'dialogClass in init, two classes. foo class added');
+ equals(dlg().is(".bar"), true, 'dialogClass in init, two classes. bar class added');
+ el.remove();
+});
+
+test("draggable", function() {
+ expect(4);
+
+ el = $('<div></div>').dialog({ draggable: false });
+ shouldnotmove();
+ el.data('draggable.dialog', true);
+ shouldmove();
+ el.remove();
+
+ el = $('<div></div>').dialog({ draggable: true });
+ shouldmove();
+ el.data('draggable.dialog', false);
+ shouldnotmove();
+ el.remove();
+});
+
+test("height", function() {
+ expect(3);
+
+ el = $('<div></div>').dialog();
+ equals(dlg().height(), defaults.minHeight, "default height");
+ el.remove();
+
+ el = $('<div></div>').dialog({ height: 437 });
+ equals(dlg().height(), 437, "explicit height");
+ el.remove();
+
+ el = $('<div></div>').dialog();
+ el.data('height.dialog', 438);
+ equals(dlg().height(), 438, "explicit height set after init");
+ el.remove();
+});
+
+test("maxHeight", function() {
+ expect(3);
+
+ el = $('<div></div>').dialog({ maxHeight: 400 });
+ drag('.ui-resizable-s', 1000, 1000);
+ equals(heightAfter, 400, "maxHeight");
+ el.remove();
+
+ el = $('<div></div>').dialog({ maxHeight: 400 });
+ drag('.ui-resizable-n', -1000, -1000);
+ equals(heightAfter, 400, "maxHeight");
+ el.remove();
+
+ el = $('<div></div>').dialog({ maxHeight: 400 }).data('maxHeight.dialog', 600);
+ drag('.ui-resizable-n', -1000, -1000);
+ equals(heightAfter, 600, "maxHeight");
+ el.remove();
+});
+
+test("maxWidth", function() {
+ expect(3);
+
+ el = $('<div></div>').dialog({ maxWidth: 400 });
+ drag('.ui-resizable-e', 1000, 1000);
+ equals(widthAfter, 400, "maxWidth");
+ el.remove();
+
+ el = $('<div></div>').dialog({ maxWidth: 400 });
+ drag('.ui-resizable-w', -1000, -1000);
+ equals(widthAfter, 400, "maxWidth");
+ el.remove();
+
+ el = $('<div></div>').dialog({ maxWidth: 400 }).data('maxWidth.dialog', 600);
+ drag('.ui-resizable-w', -1000, -1000);
+ equals(widthAfter, 600, "maxWidth");
+ el.remove();
+});
+
+test("minHeight", function() {
+ expect(3);
+
+ el = $('<div></div>').dialog({ minHeight: 10 });
+ drag('.ui-resizable-s', -1000, -1000);
+ equals(heightAfter, 10, "minHeight");
+ el.remove();
+
+ el = $('<div></div>').dialog({ minHeight: 10 });
+ drag('.ui-resizable-n', 1000, 1000);
+ equals(heightAfter, 10, "minHeight");
+ el.remove();
+
+ el = $('<div></div>').dialog({ minHeight: 10 }).data('minHeight.dialog', 30);
+ drag('.ui-resizable-n', 1000, 1000);
+ equals(heightAfter, 30, "minHeight");
+ el.remove();
+});
+
+test("minWidth", function() {
+ expect(3);
+
+ el = $('<div></div>').dialog({ minWidth: 10 });
+ drag('.ui-resizable-e', -1000, -1000);
+ equals(widthAfter, 10, "minWidth");
+ el.remove();
+
+ el = $('<div></div>').dialog({ minWidth: 10 });
+ drag('.ui-resizable-w', 1000, 1000);
+ equals(widthAfter, 10, "minWidth");
+ el.remove();
+
+ el = $('<div></div>').dialog({ minWidth: 30 }).data('minWidth.dialog', 30);
+ drag('.ui-resizable-w', 1000, 1000);
+ equals(widthAfter, 30, "minWidth");
+ el.remove();
+});
+
+test("modal", function() {
+ ok(false, "missing test");
+});
+
+test("overlay", function() {
+ ok(false, "missing test");
+});
+
+test("position", function() {
+ ok(false, "missing test");
+});
+
+test("resizable", function() {
+ expect(4);
+
+ el = $('<div></div>').dialog();
+ shouldresize("[default]");
+ el.data('resizable.dialog', false);
+ shouldnotresize('disabled after init');
+ el.remove();
+
+ el = $('<div></div>').dialog({ resizable: false });
+ shouldnotresize("disabled in init options");
+ el.data('resizable.dialog', true);
+ shouldresize('enabled after init');
+ el.remove();
+});
+
+test("stack", function() {
+ ok(false, "missing test");
+});
+
+test("title", function() {
+ expect(5);
+
+ function titleText() {
+ return dlg().find(".ui-dialog-title").html();
+ }
+
+ el = $('<div></div>').dialog();
+ equals(titleText(), "&nbsp;", "[default]");
+ el.remove();
+
+ el = $('<div title="foo"/>').dialog();
+ equals(titleText(), "foo", "title in element attribute");
+ el.remove();
+
+ el = $('<div></div>').dialog({ title: 'foo' });
+ equals(titleText(), "foo", "title in init options");
+ el.remove();
+
+ el = $('<div title="foo"/>').dialog({ title: 'bar' });
+ equals(titleText(), "bar", "title in init options should override title in element attribute");
+ el.remove();
+
+ el = $('<div></div>').dialog().data('title.dialog', 'foo');
+ equals(titleText(), 'foo', 'title after init');
+ el.remove();
+});
+
+test("width", function() {
+ expect(3);
+
+ el = $('<div></div>').dialog();
+ equals(dlg().width(), defaults.width, "default width");
+ el.remove();
+
+ el = $('<div></div>').dialog({width: 437 });
+ equals(dlg().width(), 437, "explicit width");
+ el.data('width.dialog', 438);
+ equals(dlg().width(), 438, 'explicit width after init');
+ el.remove();
+});
+
+module("dialog: Methods");
+
+test("isOpen", function() {
+ expect(4);
+
+ el = $('<div></div>').dialog();
+ equals(el.dialog('isOpen'), true, "dialog is open after init");
+ el.dialog('close');
+ equals(el.dialog('isOpen'), false, "dialog is closed");
+ el.remove();
+
+ el = $('<div></div>').dialog({autoOpen: false});
+ equals(el.dialog('isOpen'), false, "dialog is closed after init");
+ el.dialog('open');
+ equals(el.dialog('isOpen'), true, "dialog is open");
+ el.remove();
+});
+
+module("dialog: Callbacks");
+
+test("open", function() {
+ expect(6);
+
+ el = $("<div></div>");
+ el.dialog({
+ open: function(ev, ui) {
+ ok(true, 'autoOpen: true fires open callback');
+ equals(this, el[0], "context of callback");
+ }
+ });
+ el.remove();
+
+ el = $("<div></div>");
+ el.dialog({
+ autoOpen: false,
+ open: function(ev, ui) {
+ ok(true, '.dialog("open") fires open callback');
+ equals(this, el[0], "context of callback");
+ }
+ });
+ el.dialog("open");
+ el.remove();
+
+ el = $('<div></div>').dialog({
+ autoOpen: false
+ });
+ el.bind('dialogopen', function(ev, ui) {
+ ok(true, 'dialog("open") fires open event');
+ equals(this, el[0], 'context of event');
+ });
+ el.dialog('open');
+ el.remove();
+});
+
+test("dragStart", function() {
+ expect(2);
+
+ el = $("<div></div>");
+ el.dialog({
+ dragStart: function(ev, ui) {
+ ok(true, 'dragging fires dragStart callback');
+ equals(this, el[0], "context of callback");
+ }
+ });
+ var handle = $(".ui-dialog-titlebar", dlg());
+ drag(handle, 50, 50);
+ el.remove();
+});
+
+test("drag", function() {
+ var fired = false;
+
+ el = $("<div></div>");
+ el.dialog({
+ drag: function(ev, ui) {
+ fired = true;
+ equals(this, el[0], "context of callback");
+ }
+ });
+ var handle = $(".ui-dialog-titlebar", dlg());
+ drag(handle, 50, 50);
+ ok(fired, "drag fired");
+ el.remove();
+});
+
+test("dragStop", function() {
+ expect(2);
+
+ el = $("<div></div>");
+ el.dialog({
+ dragStop: function(ev, ui) {
+ ok(true, 'dragging fires dragStop callback');
+ equals(this, el[0], "context of callback");
+ }
+ });
+ var handle = $(".ui-dialog-titlebar", dlg());
+ drag(handle, 50, 50);
+ el.remove();
+});
+
+test("resizeStart", function() {
+ expect(2);
+
+ el = $("<div></div>");
+ el.dialog({
+ resizeStart: function(ev, ui) {
+ ok(true, 'resizing fires resizeStart callback');
+ equals(this, el[0], "context of callback");
+ }
+ });
+ var handle = $(".ui-resizable-se", dlg());
+ drag(handle, 50, 50);
+ el.remove();
+});
+
+test("resize", function() {
+ var fired = false;
+
+ el = $("<div></div>");
+ el.dialog({
+ resize: function(ev, ui) {
+ fired = true;
+ equals(this, el[0], "context of callback");
+ }
+ });
+ var handle = $(".ui-resizable-se", dlg());
+ drag(handle, 50, 50);
+ ok(fired, "resize fired");
+ el.remove();
+});
+
+test("resizeStop", function() {
+ expect(2);
+
+ el = $("<div></div>");
+ el.dialog({
+ resizeStop: function(ev, ui) {
+ ok(true, 'resizing fires resizeStop callback');
+ equals(this, el[0], "context of callback");
+ }
+ });
+ var handle = $(".ui-resizable-se", dlg());
+ drag(handle, 50, 50);
+ el.remove();
+});
+
+test("close", function() {
+ expect(4);
+
+ el = $('<div></div>').dialog({
+ close: function(ev, ui) {
+ ok(true, '.dialog("close") fires close callback');
+ equals(this, el[0], "context of callback");
+ }
+ });
+ el.dialog("close");
+ el.remove();
+
+ el = $('<div></div>').dialog().bind('dialogclose', function(ev, ui) {
+ ok(true, '.dialog("close") fires dialogclose event');
+ equals(this, el[0], 'context of event');
+ });
+ el.dialog('close');
+ el.remove();
+});
+
+test("beforeclose", function() {
+ expect(6);
+
+ el = $('<div></div>').dialog({
+ beforeclose: function(ev, ui) {
+ ok(true, '.dialog("close") fires beforeclose callback');
+ equals(this, el[0], "context of callback");
+ return false;
+ }
+ });
+ el.dialog('close');
+ isOpen('beforeclose callback should prevent dialog from closing');
+ el.remove();
+
+ el = $('<div></div>').dialog().bind('dialogbeforeclose', function(ev, ui) {
+ ok(true, '.dialog("close") triggers dialogbeforeclose event');
+ equals(this, el[0], "context of event");
+ return false;
+ });
+ el.dialog('close');
+ isOpen('dialogbeforeclose event should prevent dialog from closing');
+ el.remove();
+});
+
+module("dialog: Tickets");
+
+})(jQuery);
diff --git a/tests/unit/draggable/draggable.html b/tests/unit/draggable/draggable.html
new file mode 100644
index 000000000..2d129c9d6
--- /dev/null
+++ b/tests/unit/draggable/draggable.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <title>jQuery UI Draggable Test Suite</title>
+
+ <script type="text/javascript" src="../../../jquery-1.3pre.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.core.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.draggable.js"></script>
+
+ <link type="text/css" href="../testsuite.css" rel="stylesheet" />
+ <script type="text/javascript" src="../testsuite.js"></script>
+ <script type="text/javascript" src="../../../external/qunit/testrunner.js"></script>
+ <script type="text/javascript" src="../../../external/simulate/jquery.simulate.js"></script>
+
+ <script type="text/javascript" src="draggable.js"></script>
+</head>
+<body>
+
+<div id="main">
+ <div id="draggable1" style="background: green; width: 200px; height: 100px;">Relative</div>
+ <div id="draggable2" style="background: green; width: 200px; height: 100px; position: absolute; top: 10px; left: 10px;"><span>Absolute</span></div>
+ <div style='width: 1px; height: 1000px;'></div>
+</div>
+
+<div style="width: 1px; height: 2000px;"></div>
+
+</body>
+</html>
diff --git a/tests/unit/draggable/draggable.js b/tests/unit/draggable/draggable.js
new file mode 100644
index 000000000..d5ef7fda9
--- /dev/null
+++ b/tests/unit/draggable/draggable.js
@@ -0,0 +1,787 @@
+/*
+ * draggable unit tests
+ */
+(function($) {
+//
+// Draggable Test Helper Functions
+//
+
+var defaults = {
+ appendTo: "parent",
+ axis: false,
+ cancel: ":input",
+ connectToSortable: false,
+ containment: false,
+ cursor: "default",
+ cursorAt: null,
+ delay: 0,
+ disabled: false,
+ distance: 1,
+ grid: false,
+ handle: false,
+ helper: "original",
+ iframeFix: false,
+ opacity: 1.0,
+ refreshPositions: false,
+ revert: false,
+ revertDuration: 500,
+ scroll: true,
+ scrollSensitivity: 20,
+ scrollSpeed: 20,
+ scope: "default",
+ snap: false,
+ snapMode: "both",
+ snapTolerance: 20,
+ stack: false,
+ zIndex: null
+};
+
+var el, offsetBefore, offsetAfter, dragged;
+
+var drag = function(handle, dx, dy) {
+ var element = el.data("draggable").element;
+ offsetBefore = el.offset();
+ $(handle).simulate("drag", {
+ dx: dx || 0,
+ dy: dy || 0
+ });
+ dragged = { dx: dx, dy: dy };
+ offsetAfter = el.offset();
+}
+
+var moved = function (dx, dy, msg) {
+ msg = msg ? msg + "." : "";
+ var actual = { left: offsetAfter.left, top: offsetAfter.top };
+ var expected = { left: offsetBefore.left + dx, top: offsetBefore.top + dy };
+ same(actual, expected, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ' + msg);
+}
+
+function shouldmove(why) {
+ drag(el, 50, 50);
+ moved(50, 50, why);
+}
+
+function shouldnotmove(why) {
+ drag(el, 50, 50);
+ moved(0, 0, why);
+}
+
+var border = function(el, side) { return parseInt(el.css('border-' + side + '-width')); }
+
+var margin = function(el, side) { return parseInt(el.css('margin-' + side)); }
+
+// Draggable Tests
+module("draggable");
+
+test("init", function() {
+ expect(6);
+
+ $("<div></div>").appendTo('body').draggable().remove();
+ ok(true, '.draggable() called on element');
+
+ $([]).draggable();
+ ok(true, '.draggable() called on empty collection');
+
+ $("<div></div>").draggable();
+ ok(true, '.draggable() called on disconnected DOMElement');
+
+ $("<div></div>").draggable().draggable("foo");
+ ok(true, 'arbitrary method called after init');
+
+ $("<div></div>").draggable().data("foo.draggable");
+ ok(true, 'arbitrary option getter after init');
+
+ $("<div></div>").draggable().data("foo.draggable", "bar");
+ ok(true, 'arbitrary option setter after init');
+});
+
+test("destroy", function() {
+ expect(6);
+
+ $("<div></div>").appendTo('body').draggable().draggable("destroy").remove();
+ ok(true, '.draggable("destroy") called on element');
+
+ $([]).draggable().draggable("destroy");
+ ok(true, '.draggable("destroy") called on empty collection');
+
+ $("<div></div>").draggable().draggable("destroy");
+ ok(true, '.draggable("destroy") called on disconnected DOMElement');
+
+ $("<div></div>").draggable().draggable("destroy").draggable("foo");
+ ok(true, 'arbitrary method called after destroy');
+
+ $("<div></div>").draggable().draggable("destroy").data("foo.draggable");
+ ok(true, 'arbitrary option getter after destroy');
+
+ $("<div></div>").draggable().draggable("destroy").data("foo.draggable", "bar");
+ ok(true, 'arbitrary option setter after destroy');
+});
+
+test("enable", function() {
+ expect(6);
+ el = $("#draggable2").draggable({ disabled: true });
+ shouldnotmove('.draggable({ disabled: true })');
+ el.draggable("enable");
+ shouldmove('.draggable("enable")');
+ equals(el.data("disabled.draggable"), false, "disabled.draggable getter");
+
+ el.draggable("destroy");
+ el.draggable({ disabled: true });
+ shouldnotmove('.draggable({ disabled: true })');
+ el.data("disabled.draggable", false);
+ equals(el.data("disabled.draggable"), false, "disabled.draggable setter");
+ shouldmove('.data("disabled.draggable", false)');
+});
+
+test("disable", function() {
+ expect(6);
+ el = $("#draggable2").draggable({ disabled: false });
+ shouldmove('.draggable({ disabled: false })');
+ el.draggable("disable");
+ shouldnotmove('.draggable("disable")');
+ equals(el.data("disabled.draggable"), true, "disabled.draggable getter");
+
+ el.draggable("destroy");
+
+ el.draggable({ disabled: false });
+ shouldmove('.draggable({ disabled: false })');
+ el.data("disabled.draggable", true);
+ equals(el.data("disabled.draggable"), true, "disabled.draggable setter");
+ shouldnotmove('.data("disabled.draggable", true)');
+});
+
+test("element types", function() {
+ 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,object,hr'
+ + ',input,button,label,select,iframe').split(',');
+
+ $.each(typeNames, function(i) {
+ var typeName = typeNames[i];
+ el = $(document.createElement(typeName)).appendTo('body');
+ (typeName == 'table' && el.append("<tr><td>content</td></tr>"));
+ el.draggable({ cancel: '' });
+ drag(el, 50, 50);
+ moved(50, 50, "&lt;" + typeName + "&gt;");
+ el.draggable("destroy");
+ el.remove();
+ });
+});
+
+test("defaults", function() {
+ el = $('<div></div>').draggable();
+ $.each(defaults, function(key, val) {
+ var actual = el.data(key + ".draggable"), expected = val;
+ same(actual, expected, key);
+ });
+ el.remove();
+});
+
+test("No options, relative", function() {
+ el = $("#draggable1").draggable();
+ drag(el, 50, 50);
+ moved(50, 50);
+});
+
+test("No options, absolute", function() {
+ el = $("#draggable2").draggable();
+ drag(el, 50, 50);
+ moved(50, 50);
+});
+
+module("draggable: Options");
+
+test("{ axis: false }, default", function() {
+ el = $("#draggable2").draggable({ axis: false });
+ drag(el, 50, 50);
+ moved(50, 50);
+});
+
+test("{ axis: 'x' }", function() {
+ el = $("#draggable2").draggable({ axis: "x" });
+ drag(el, 50, 50);
+ moved(50, 0);
+});
+
+test("{ axis: 'y' }", function() {
+ el = $("#draggable2").draggable({ axis: "y" });
+ drag(el, 50, 50);
+ moved(0, 50);
+});
+
+test("{ axis: ? }, unexpected", function() {
+ var unexpected = {
+ "true": true,
+ "{}": {},
+ "[]": [],
+ "null": null,
+ "undefined": undefined,
+ "function() {}": function() {}
+ };
+ $.each(unexpected, function(key, val) {
+ el = $("#draggable2").draggable({ axis: val });
+ drag(el, 50, 50);
+ moved(50, 50, "axis: " + key);
+ el.draggable("destroy");
+ })
+});
+
+test("{ cancel: 'span' }", function() {
+ el = $("#draggable2").draggable();
+ drag("#draggable2 span", 50, 50);
+ moved(50, 50);
+
+ el.draggable("destroy");
+
+ el = $("#draggable2").draggable({ cancel: 'span' });
+ drag("#draggable2 span", 50, 50);
+ moved(0, 0);
+});
+
+test("{ cancel: ? }, unexpected", function() {
+ var unexpected = {
+ "true": true,
+ "false": false,
+ "{}": {},
+ "[]": [],
+ "null": null,
+ "undefined": undefined,
+ "function() {return '';}": function() {return '';},
+ "function() {return true;}": function() {return true;},
+ "function() {return false;}": function() {return false;}
+ };
+ $.each(unexpected, function(key, val) {
+ el = $("#draggable2").draggable({ cancel: val });
+ drag(el, 50, 50);
+ var expected = [50, 50];
+ moved(expected[0], expected[1], "cancel: " + key);
+ el.draggable("destroy");
+ })
+});
+
+test("{ containment: 'parent' }, relative", function() {
+ el = $("#draggable1").draggable({ containment: 'parent' });
+ var p = el.parent(), po = p.offset();
+ drag(el, -100, -100);
+ var expected = {
+ left: po.left + border(p, 'left') + margin(el, 'left'),
+ top: po.top + border(p, 'top') + margin(el, 'top')
+ }
+ same(offsetAfter, expected, 'compare offset to parent');
+});
+
+test("{ containment: 'parent' }, absolute", function() {
+ el = $("#draggable2").draggable({ containment: 'parent' });
+ var p = el.parent(), po = p.offset();
+ drag(el, -100, -100);
+ var expected = {
+ left: po.left + border(p, 'left') + margin(el, 'left'),
+ top: po.top + border(p, 'top') + margin(el, 'top')
+ }
+ same(offsetAfter, expected, 'compare offset to parent');
+});
+
+test("{ cursor: 'move' }", function() {
+
+ function getCursor() { return $("body").css("cursor"); }
+
+ expect(2);
+
+ var expected = "move", actual, before, after;
+
+ el = $("#draggable2").draggable({
+ cursor: expected,
+ start: function(event, ui) {
+ actual = getCursor();
+ }
+ });
+
+ before = getCursor();
+ drag("#draggable2", -1, -1);
+ after = getCursor();
+
+ equals(actual, expected, "start callback: cursor '" + expected + "'");
+ equals(after, before, "after drag: cursor restored");
+
+});
+
+test("{ cursorAt: { left: -5, top: -5 } }", function() {
+
+ expect(4);
+
+ var dx = -3, dy = -3;
+ var ox = 5, oy = 5;
+ var cax = -5, cay = -5;
+
+ var actual = null;
+ $("#draggable2").draggable({
+ cursorAt: { left: cax, top: cay },
+ drag: function(event, ui) {
+ actual = ui.absolutePosition;
+ }
+ });
+ var el = $("#draggable2").data("draggable").element;
+
+ var before = el.offset();
+ var pos = { clientX: before.left + ox, clientY: before.top + oy };
+ $("#draggable2").simulate("mousedown", pos);
+ pos = { clientX: pos.clientX + dx, clientY: pos.clientY + dy };
+ $(document).simulate("mousemove", pos);
+ $(document).simulate("mousemove", pos);
+ $("#draggable2").simulate("mouseup", pos);
+ var expected = {
+ left: before.left + ox - cax + dx,
+ top: before.top + oy - cay + dy
+ };
+
+ equals(actual.left, expected.left, "Absolute: -1px left");
+ equals(actual.top, expected.top, "Absolute: -1px top");
+
+ var actual = null;
+ $("#draggable1").draggable({
+ cursorAt: { left: cax, top: cay },
+ drag: function(event, ui) {
+ actual = ui.absolutePosition;
+ }
+ });
+ var el = $("#draggable2").data("draggable").element;
+
+ var before = el.offset();
+ var pos = { clientX: before.left + ox, clientY: before.top + oy };
+ $("#draggable2").simulate("mousedown", pos);
+ pos = { clientX: pos.clientX + dx, clientY: pos.clientY + dy };
+ $(document).simulate("mousemove", pos);
+ $(document).simulate("mousemove", pos);
+ $("#draggable2").simulate("mouseup", pos);
+ var expected = {
+ left: before.left + ox - cax + dx,
+ top: before.top + oy - cay + dy
+ };
+
+ equals(actual.left, expected.left, "Relative: -1px left");
+ equals(actual.top, expected.top, "Relative: -1px top");
+
+});
+
+test("{ distance: 10 }", function() {
+
+ el = $("#draggable2").draggable({ distance: 10 });
+ drag(el, -9, -9);
+ moved(0, 0, 'distance not met');
+
+ drag(el, -10, -10);
+ moved(-10, -10, 'distance met');
+
+ drag(el, 9, 9);
+ moved(0, 0, 'distance not met');
+
+});
+
+test("{ grid: [50, 50] }, relative", function() {
+ el = $("#draggable1").draggable({ grid: [50, 50] });
+ drag(el, 24, 24);
+ moved(0, 0);
+ drag(el, 26, 25);
+ moved(50, 50);
+});
+
+test("{ grid: [50, 50] }, absolute", function() {
+ el = $("#draggable2").draggable({ grid: [50, 50] });
+ drag(el, 24, 24);
+ moved(0, 0);
+ drag(el, 26, 25);
+ moved(50, 50);
+});
+
+test("{ handle: 'span' }", function() {
+ el = $("#draggable2").draggable({ handle: 'span' });
+
+ drag("#draggable2 span", 50, 50);
+ moved(50, 50, "drag span");
+
+ drag("#draggable2", 50, 50);
+ moved(0, 0, "drag element");
+});
+
+test("{ helper: 'clone' }, relative", function() {
+ el = $("#draggable1").draggable({ helper: "clone" });
+ drag(el, 50, 50);
+ moved(0, 0);
+});
+
+test("{ helper: 'clone' }, absolute", function() {
+ el = $("#draggable2").draggable({ helper: "clone" });
+ drag(el, 50, 50);
+ moved(0, 0);
+});
+
+test("{ opacity: 0.5 }", function() {
+
+ expect(1);
+
+ var opacity = null;
+ el = $("#draggable2").draggable({
+ opacity: 0.5,
+ start: function(event, ui) {
+ opacity = $(this).css("opacity");
+ }
+ });
+
+ drag("#draggable2", -1, -1);
+
+ equals(opacity, 0.5, "start callback: opacity is");
+
+});
+
+test("{ zIndex: 10 }", function() {
+
+ expect(1);
+
+ var expected = 10, actual;
+
+ var zIndex = null;
+ el = $("#draggable2").draggable({
+ zIndex: expected,
+ start: function(event, ui) {
+ actual = $(this).css("zIndex");
+ }
+ });
+
+ drag("#draggable2", -1, -1);
+
+ equals(actual, expected, "start callback: zIndex is");
+
+});
+
+module("draggable: Callbacks");
+
+test("callbacks occurance count", function() {
+
+ expect(3);
+
+ var start = 0, stop = 0, dragc = 0;
+ el = $("#draggable2").draggable({
+ start: function() { start++; },
+ drag: function() { dragc++; },
+ stop: function() { stop++; }
+ });
+
+ drag(el, 10, 10);
+
+ equals(start, 1, "start callback should happen exactly once");
+ equals(dragc, 3, "drag callback should happen exactly once per mousemove");
+ equals(stop, 1, "stop callback should happen exactly once");
+
+});
+
+module("draggable: Scroll offsets");
+
+
+function testScroll(position) {
+ $("#main").css('position', position);
+ drag(el, 50, 50);
+ moved(50, 50, position+' parent');
+
+}
+
+function setScroll(what) {
+ if(what) {
+ $(document).scrollTop(100); $(document).scrollLeft(100);
+ } else {
+ $("#main")[0].scrollTop = 100; $("#main")[0].scrollLeft = 100;
+ }
+}
+
+function restoreScroll(what) {
+ if(what) {
+ $(document).scrollTop(0); $(document).scrollLeft(0);
+ } else {
+ $("#main")[0].scrollTop = 0; $("#main")[0].scrollLeft = 0;
+ }
+}
+
+test("{ helper: 'original' }, relative, with scroll offset on parent", function() {
+
+ el = $("#draggable1").draggable({ helper: "original" });
+
+ setScroll();
+ testScroll('relative');
+
+ setScroll();
+ testScroll('static');
+
+ setScroll();
+ testScroll('absolute');
+
+ restoreScroll();
+
+});
+
+test("{ helper: 'original' }, relative, with scroll offset on root", function() {
+
+ el = $("#draggable1").draggable({ helper: "original" });
+
+ setScroll('root');
+ testScroll('relative');
+
+ setScroll('root');
+ testScroll('static');
+
+ setScroll('root');
+ testScroll('absolute');
+
+ restoreScroll('root');
+
+});
+
+test("{ helper: 'original' }, relative, with scroll offset on root and parent", function() {
+
+ el = $("#draggable1").draggable({ helper: "original" });
+
+ setScroll();
+ setScroll('root');
+ testScroll('relative');
+
+ setScroll();
+ setScroll('root');
+ testScroll('static');
+
+ setScroll();
+ setScroll('root');
+ testScroll('absolute');
+
+ restoreScroll();
+ restoreScroll('root');
+
+});
+
+test("{ helper: 'original' }, absolute, with scroll offset on parent", function() {
+
+ el = $("#draggable1").css({ position: 'absolute', top: 0, left: 0 }).draggable({ helper: "original" });
+
+ setScroll();
+ testScroll('relative');
+
+ setScroll();
+ testScroll('static');
+
+ setScroll();
+ testScroll('absolute');
+
+ restoreScroll();
+
+});
+
+test("{ helper: 'original' }, absolute, with scroll offset on root", function() {
+
+ el = $("#draggable1").css({ position: 'absolute', top: 0, left: 0 }).draggable({ helper: "original" });
+
+ setScroll('root');
+ testScroll('relative');
+
+ setScroll('root');
+ testScroll('static');
+
+ setScroll('root');
+ testScroll('absolute');
+
+ restoreScroll('root');
+
+});
+
+test("{ helper: 'original' }, absolute, with scroll offset on root and parent", function() {
+
+ el = $("#draggable1").css({ position: 'absolute', top: 0, left: 0 }).draggable({ helper: "original" });
+
+ setScroll();
+ setScroll('root');
+ testScroll('relative');
+
+ setScroll();
+ setScroll('root');
+ testScroll('static');
+
+ setScroll();
+ setScroll('root');
+ testScroll('absolute');
+
+ restoreScroll();
+ restoreScroll('root');
+
+});
+
+//Fixed not for IE < 7
+if(!($.browser.msie && $.browser.version < 7)) {
+
+ test("{ helper: 'original' }, fixed, with scroll offset on parent", function() {
+
+ el = $("#draggable1").css({ position: 'fixed', top: 0, left: 0 }).draggable({ helper: "original" });
+
+ setScroll();
+ testScroll('relative');
+
+ setScroll();
+ testScroll('static');
+
+ setScroll();
+ testScroll('absolute');
+
+ restoreScroll();
+
+ });
+
+ test("{ helper: 'original' }, fixed, with scroll offset on root", function() {
+
+ el = $("#draggable1").css({ position: 'fixed', top: 0, left: 0 }).draggable({ helper: "original" });
+
+ setScroll('root');
+ testScroll('relative');
+
+ setScroll('root');
+ testScroll('static');
+
+ setScroll('root');
+ testScroll('absolute');
+
+ restoreScroll('root');
+
+ });
+
+ test("{ helper: 'original' }, fixed, with scroll offset on root and parent", function() {
+
+ el = $("#draggable1").css({ position: 'fixed', top: 0, left: 0 }).draggable({ helper: "original" });
+
+ setScroll();
+ setScroll('root');
+ testScroll('relative');
+
+ setScroll();
+ setScroll('root');
+ testScroll('static');
+
+ setScroll();
+ setScroll('root');
+ testScroll('absolute');
+
+ restoreScroll();
+ restoreScroll('root');
+
+ });
+
+}
+
+
+
+test("{ helper: 'clone' }, absolute", function() {
+
+ var helperOffset = null;
+ var origOffset = $("#draggable1").offset();
+
+ el = $("#draggable1").draggable({ helper: "clone", drag: function(event, ui) {
+ helperOffset = ui.helper.offset();
+ } });
+
+ drag(el, 1, 1);
+ same({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ');
+
+});
+
+test("{ helper: 'clone' }, absolute with scroll offset on parent", function() {
+
+ setScroll();
+ var helperOffset = null;
+ var origOffset = null;
+
+ el = $("#draggable1").draggable({ helper: "clone", drag: function(event, ui) {
+ helperOffset = ui.helper.offset();
+ } });
+
+ $("#main").css('position', 'relative');
+ origOffset = $("#draggable1").offset();
+ drag(el, 1, 1);
+ same({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ');
+
+ $("#main").css('position', 'static');
+ origOffset = $("#draggable1").offset();
+ drag(el, 1, 1);
+ same({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ');
+
+ $("#main").css('position', 'absolute');
+ origOffset = $("#draggable1").offset();
+ drag(el, 1, 1);
+ same({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ');
+
+ restoreScroll();
+
+});
+
+test("{ helper: 'clone' }, absolute with scroll offset on root", function() {
+
+ setScroll('root');
+ var helperOffset = null;
+ var origOffset = null;
+
+ el = $("#draggable1").draggable({ helper: "clone", drag: function(event, ui) {
+ helperOffset = ui.helper.offset();
+ } });
+
+ $("#main").css('position', 'relative');
+ origOffset = $("#draggable1").offset();
+ drag(el, 1, 1);
+ same({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ');
+
+ $("#main").css('position', 'static');
+ origOffset = $("#draggable1").offset();
+ drag(el, 1, 1);
+ same({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ');
+
+ $("#main").css('position', 'absolute');
+ origOffset = $("#draggable1").offset();
+ drag(el, 1, 1);
+ same({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ');
+
+ restoreScroll('root');
+
+});
+
+test("{ helper: 'clone' }, absolute with scroll offset on root and parent", function() {
+
+ setScroll('root');
+ setScroll();
+ var helperOffset = null;
+ var origOffset = null;
+
+ el = $("#draggable1").draggable({ helper: "clone", drag: function(event, ui) {
+ helperOffset = ui.helper.offset();
+ } });
+
+ $("#main").css('position', 'relative');
+ origOffset = $("#draggable1").offset()
+ drag(el, 1, 1);
+ same({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ');
+
+ $("#main").css('position', 'static');
+ origOffset = $("#draggable1").offset()
+ drag(el, 1, 1);
+ same({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ');
+
+ $("#main").css('position', 'absolute');
+ origOffset = $("#draggable1").offset()
+ drag(el, 1, 1);
+ same({ top: helperOffset.top-1, left: helperOffset.left-1 }, origOffset, 'dragged[' + dragged.dx + ', ' + dragged.dy + '] ');
+
+ restoreScroll('root');
+ restoreScroll();
+
+});
+
+module("draggable: behaviour");
+
+test("Events should not be executed on the element if drag is initiated", function() {
+ //TODO: Implement missing test
+});
+
+
+module("draggable: Tickets");
+
+})(jQuery);
diff --git a/tests/unit/droppable/droppable.html b/tests/unit/droppable/droppable.html
new file mode 100644
index 000000000..3881adf1d
--- /dev/null
+++ b/tests/unit/droppable/droppable.html
@@ -0,0 +1,27 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <title>jQuery UI Droppable Test Suite</title>
+
+ <script type="text/javascript" src="../../../jquery-1.3pre.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.core.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.draggable.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.droppable.js"></script>
+
+ <link type="text/css" href="../testsuite.css" rel="stylesheet" />
+ <script type="text/javascript" src="../testsuite.js"></script>
+ <script type="text/javascript" src="../../../external/qunit/testrunner.js"></script>
+ <script type="text/javascript" src="../../../external/simulate/jquery.simulate.js"></script>
+
+ <script type="text/javascript" src="droppable.js"></script>
+</head>
+<body>
+
+<div id="main">
+ <div id="draggable1" style="width: 25px; height: 25px;">Draggable</div>
+ <div id="droppable1" style="width: 100px; height: 100px;">Droppable</div>
+ <div style='width:1000px;height:1000px;'>&nbsp;</div>
+</div>
+
+</body>
+</html>
diff --git a/tests/unit/droppable/droppable.js b/tests/unit/droppable/droppable.js
new file mode 100644
index 000000000..31915defc
--- /dev/null
+++ b/tests/unit/droppable/droppable.js
@@ -0,0 +1,223 @@
+/*
+ * droppable unit tests
+ */
+(function($) {
+//
+// Droppable Test Helper Functions
+//
+
+var defaults = {
+ accept: '*',
+ activeClass: null,
+ cssNamespace: "ui",
+ disabled: false,
+ greedy: false,
+ hoverClass: null,
+ scope: "default",
+ tolerance: "intersect"
+};
+
+var el, drg;
+
+function shouldBeDroppable() {
+ ok(false, "missing test - should be droppable");
+}
+
+function shouldNotBeDroppable() {
+ ok(false, "missing test - should not be droppable");
+}
+
+// Droppable Tests
+module("droppable");
+
+test("init", function() {
+ expect(6);
+
+ $("<div></div>").appendTo('body').droppable().remove();
+ ok(true, '.droppable() called on element');
+
+ $([]).droppable();
+ ok(true, '.droppable() called on empty collection');
+
+ $("<div></div>").droppable();
+ ok(true, '.droppable() called on disconnected DOMElement');
+
+ $("<div></div>").droppable().droppable("foo");
+ ok(true, 'arbitrary method called after init');
+
+ $("<div></div>").droppable().data("foo.droppable");
+ ok(true, 'arbitrary option getter after init');
+
+ $("<div></div>").droppable().data("foo.droppable", "bar");
+ ok(true, 'arbitrary option setter after init');
+});
+
+test("destroy", function() {
+ expect(6);
+
+ $("<div></div>").appendTo('body').droppable().droppable("destroy").remove();
+ ok(true, '.droppable("destroy") called on element');
+
+ $([]).droppable().droppable("destroy");
+ ok(true, '.droppable("destroy") called on empty collection');
+
+ $("<div></div>").droppable().droppable("destroy");
+ ok(true, '.droppable("destroy") called on disconnected DOMElement');
+
+ $("<div></div>").droppable().droppable("destroy").droppable("foo");
+ ok(true, 'arbitrary method called after destroy');
+
+ $("<div></div>").droppable().droppable("destroy").data("foo.droppable");
+ ok(true, 'arbitrary option getter after destroy');
+
+ $("<div></div>").droppable().droppable("destroy").data("foo.droppable", "bar");
+ ok(true, 'arbitrary option setter after destroy');
+});
+
+test("enable", function() {
+ expect(6);
+ el = $("#droppable1").droppable({ disabled: true });
+ shouldNotBeDroppable();
+ el.droppable("enable");
+ shouldBeDroppable();
+ equals(el.data("disabled.droppable"), false, "disabled.droppable getter");
+ el.droppable("destroy");
+ el.droppable({ disabled: true });
+ shouldNotBeDroppable();
+ el.data("disabled.droppable", false);
+ equals(el.data("disabled.droppable"), false, "disabled.droppable setter");
+ shouldBeDroppable();
+});
+
+test("disable", function() {
+ expect(6);
+ el = $("#droppable1").droppable({ disabled: false });
+ shouldBeDroppable();
+ el.droppable("disable");
+ shouldNotBeDroppable();
+ equals(el.data("disabled.droppable"), true, "disabled.droppable getter");
+ el.droppable("destroy");
+ el.droppable({ disabled: false });
+ shouldBeDroppable();
+ el.data("disabled.droppable", true);
+ equals(el.data("disabled.droppable"), true, "disabled.droppable setter");
+ shouldNotBeDroppable();
+});
+
+test("element types", function() {
+ 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,object,hr'
+ + ',input,button,label,select,iframe').split(',');
+
+ $.each(typeNames, function(i) {
+ var typeName = typeNames[i];
+ el = $(document.createElement(typeName)).appendTo('body');
+ (typeName == 'table' && el.append("<tr><td>content</td></tr>"));
+ el.droppable();
+ shouldBeDroppable();
+ el.droppable("destroy");
+ el.remove();
+ });
+});
+
+test("defaults", function() {
+ el = $("<div></div>").droppable();
+ $.each(defaults, function(key, val) {
+ var actual = el.data(key + ".droppable"), expected = val;
+ same(actual, expected, key);
+ });
+ el.remove();
+});
+
+test("option setting", function() {
+ // The plugin shouldn't modify an option value set by the user
+ $.each(defaults, function(key, val) {
+ el = $("<div></div>").droppable();
+ el.data(key + ".droppable", val);
+ var actual = el.data(key + ".droppable"), expected = val;
+ same(actual, expected, key);
+ el.remove();
+ });
+});
+
+module("droppable: Options");
+
+test("accept, selector", function() {
+ ok(false, "missing test");
+});
+
+test("accept, fn", function() {
+ ok(false, "missing test");
+});
+
+test("activeClass", function() {
+ ok(false, "missing test");
+});
+
+test("cssNamespace", function() {
+ //cssNamespace should be appended with '-droppable' and added as className
+ el = $("<div></div>").droppable({ cssNamespace: "ui" });
+ equals(el[0].className, "ui-droppable");
+ el.droppable("destroy");
+
+ //no className should be added if cssNamepsace is null
+ el = $("<div></div>").droppable({ cssNamespace: null });
+ equals(el[0].className, "");
+ el.droppable("destroy");
+});
+
+test("greedy", function() {
+ ok(false, "missing test");
+});
+
+test("hoverClass", function() {
+ ok(false, "missing test");
+});
+
+test("scope", function() {
+ ok(false, "missing test");
+});
+
+test("tolerance, fit", function() {
+ ok(false, "missing test");
+});
+
+test("tolerance, intersect", function() {
+ ok(false, "missing test");
+});
+
+test("tolerance, pointer", function() {
+ ok(false, "missing test");
+});
+
+test("tolerance, touch", function() {
+ ok(false, "missing test");
+});
+
+module("droppable: Callbacks");
+
+test("activate", function() {
+ ok(false, "missing test");
+});
+
+test("deactivate", function() {
+ ok(false, "missing test");
+});
+
+test("over", function() {
+ ok(false, "missing test");
+});
+
+test("out", function() {
+ ok(false, "missing test");
+});
+
+test("drop", function() {
+ ok(false, "missing test");
+});
+
+module("droppable: Tickets");
+
+
+})(jQuery);
diff --git a/tests/unit/progressbar/progressbar.html b/tests/unit/progressbar/progressbar.html
new file mode 100644
index 000000000..c6d9becfb
--- /dev/null
+++ b/tests/unit/progressbar/progressbar.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <title>jQuery UI Progressbar Test Suite</title>
+
+ <script type="text/javascript" src="../../../jquery-1.3pre.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.core.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.progressbar.js"></script>
+
+ <link type="text/css" href="../testsuite.css" rel="stylesheet" />
+ <script type="text/javascript" src="../testsuite.js"></script>
+ <script type="text/javascript" src="../../../external/qunit/testrunner.js"></script>
+ <script type="text/javascript" src="../../../external/simulate/jquery.simulate.js"></script>
+
+ <script type="text/javascript" src="progressbar.js"></script>
+</head>
+<body>
+
+<div id="main">
+ <div id="progressbar"></div>
+</div>
+
+</body>
+</html>
diff --git a/tests/unit/progressbar/progressbar.js b/tests/unit/progressbar/progressbar.js
new file mode 100644
index 000000000..087106510
--- /dev/null
+++ b/tests/unit/progressbar/progressbar.js
@@ -0,0 +1,68 @@
+/*
+ * progressbar unit tests
+ */
+(function($) {
+//
+// Progressbar Test Helper Functions
+//
+
+var defaults = {
+ disabled: false,
+ value: 0
+};
+
+var el;
+
+// Progressbar Tests
+module("progressbar");
+
+test("init", function() {
+ expect(1);
+
+ $("<div></div>").appendTo('body').progressbar().remove();
+ ok(true, '.progressbar() called on element');
+
+});
+
+test("destroy", function() {
+ expect(1);
+
+ $("<div></div>").appendTo('body').progressbar().progressbar("destroy").remove();
+ ok(true, '.progressbar("destroy") called on element');
+
+});
+
+test("defaults", function() {
+ el = $('<div></div>').progressbar();
+ $.each(defaults, function(key, val) {
+ var actual = el.data(key + ".progressbar"), expected = val;
+ same(actual, expected, key);
+ });
+ el.remove();
+});
+
+test("set defaults on init", function() {
+ el = $("#progressbar").progressbar({
+ value: 50
+ });
+
+ equals(el.progressbar("option", "value"), 50, "value");
+});
+
+test("accessibility", function() {
+ expect(7);
+ el = $("#progressbar").progressbar();
+
+ equals(el.attr("role"), "progressbar", "aria role");
+ equals(el.attr("aria-valuemin"), 0, "aria-valuemin");
+ equals(el.attr("aria-valuemax"), 100, "aria-valuemax");
+ equals(el.attr("aria-valuenow"), 0, "aria-valuenow initially");
+ el.progressbar("value", 77);
+ equals(el.attr("aria-valuenow"), 77, "aria-valuenow");
+ el.progressbar("disable");
+ equals(el.attr("aria-disabled"), "true", "aria-disabled");
+ el.progressbar("enable");
+ equals(el.attr("aria-disabled"), "false", "enabled");
+});
+
+})(jQuery);
diff --git a/tests/unit/resizable/images/test.jpg b/tests/unit/resizable/images/test.jpg
new file mode 100644
index 000000000..7d8ec0996
--- /dev/null
+++ b/tests/unit/resizable/images/test.jpg
Binary files differ
diff --git a/tests/unit/resizable/resizable.html b/tests/unit/resizable/resizable.html
new file mode 100644
index 000000000..5d2889884
--- /dev/null
+++ b/tests/unit/resizable/resizable.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <title>jQuery UI Resizable Test Suite</title>
+
+ <script type="text/javascript" src="../../../jquery-1.3pre.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.core.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.resizable.js"></script>
+
+ <link type="text/css" href="../testsuite.css" rel="stylesheet" />
+ <script type="text/javascript" src="../testsuite.js"></script>
+ <script type="text/javascript" src="../../../external/qunit/testrunner.js"></script>
+ <script type="text/javascript" src="../../../external/simulate/jquery.simulate.js"></script>
+
+ <script type="text/javascript" src="resizable.js"></script>
+</head>
+<body>
+
+<div id="main">
+ <div id="resizable1" style="background: green; width: 100px; height: 100px;">I'm a resizable.</div>
+ <img src="images/test.jpg" id="resizable2" style="width: 100px; height: 100px;"/>
+</div>
+
+</body>
+</html>
diff --git a/tests/unit/resizable/resizable.js b/tests/unit/resizable/resizable.js
new file mode 100644
index 000000000..98a69de5b
--- /dev/null
+++ b/tests/unit/resizable/resizable.js
@@ -0,0 +1,416 @@
+/*
+ * resizable tests
+ */
+(function($) {
+//
+// Resizable Test Helper Functions
+//
+
+var defaults = {
+ animate: false,
+ animateDuration: 'slow',
+ animateEasing: 'swing',
+ alsoResize: false,
+ aspectRatio: false,
+ autoHide: false,
+ cancel: ':input',
+ containment: false,
+ delay: 0,
+ disabled: false,
+ disableSelection: true,
+ distance: 1,
+ ghost: false,
+ grid: false,
+ handles: '???',
+ helper: null,
+ knobHandles: false,
+ maxHeight: null,
+ maxWidth: null,
+ minHeight: 10,
+ minWidth: 10,
+ preserveCursor: true,
+ preventDefault: true,
+ proportionallyResize: false,
+ transparent: false
+};
+
+var drag = function(el, dx, dy, complete) {
+
+ // speed = sync -> Drag syncrhonously.
+ // speed = fast|slow -> Drag asyncrhonously - animated.
+
+ //this mouseover is to work around a limitation in resizable
+ //TODO: fix resizable so handle doesn't require mouseover in order to be used
+ $(el).simulate("mouseover");
+
+ return $(el).simulate("drag", {
+ dx: dx||0, dy: dy||0, speed: 'sync', complete: complete
+ });
+};
+
+// Resizable Tests
+module("resizable");
+
+test("init", function() {
+ expect(6);
+
+ $("<div></div>").appendTo('body').resizable().remove();
+ ok(true, '.resizable() called on element');
+
+ $([]).resizable().remove();
+ ok(true, '.resizable() called on empty collection');
+
+ $('<div></div>').resizable().remove();
+ ok(true, '.resizable() called on disconnected DOMElement');
+
+ $('<div></div>').resizable().resizable("foo").remove();
+ ok(true, 'arbitrary method called after init');
+
+ el = $('<div></div>').resizable()
+ var foo = el.data("foo.resizable");
+ el.remove();
+ ok(true, 'arbitrary option getter after init');
+
+ $('<div></div>').resizable().data("foo.resizable", "bar").remove();
+ ok(true, 'arbitrary option setter after init');
+});
+
+test("destroy", function() {
+ expect(6);
+
+ $("<div></div>").appendTo('body').resizable().resizable("destroy").remove();
+ ok(true, '.resizable("destroy") called on element');
+
+ $([]).resizable().resizable("destroy").remove();
+ ok(true, '.resizable("destroy") called on empty collection');
+
+ $('<div></div>').resizable().resizable("destroy").remove();
+ ok(true, '.resizable("destroy") called on disconnected DOMElement');
+
+ $('<div></div>').resizable().resizable("destroy").resizable("foo").remove();
+ ok(true, 'arbitrary method called after destroy');
+
+ el = $('<div></div>').resizable();
+ var foo = el.resizable("destroy").data("foo.resizable");
+ el.remove();
+ ok(true, 'arbitrary option getter after destroy');
+
+ $('<div></div>').resizable().resizable("destroy").data("foo.resizable", "bar").remove();
+ ok(true, 'arbitrary option setter after destroy');
+});
+
+test("element types", function() {
+ 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,object,hr'
+ + ',input,button,label,select,iframe').split(',');
+
+ $.each(typeNames, function(i) {
+ var typeName = typeNames[i];
+ el = $(document.createElement(typeName)).appendTo('body');
+ (typeName == 'table' && el.append("<tr><td>content</td></tr>"));
+ el.resizable();
+ ok(true, '$("&lt;' + typeName + '/&gt").resizable()');
+ el.resizable("destroy");
+ el.remove();
+ });
+});
+
+test("defaults", function() {
+ el = $('<div></div>').resizable();
+ $.each(defaults, function(key, val) {
+ var actual = el.data(key + ".resizable"), expected = val;
+ same(actual, expected, key);
+ });
+ el.remove();
+});
+
+test("n", function() {
+ expect(2);
+
+ var handle = '.ui-resizable-n', target = $('#resizable1').resizable({ handles: 'all' });
+
+ drag(handle, 0, -50);
+ equals( target.height(), 150, "compare height" );
+
+ drag(handle, 0, 50);
+ equals( target.height(), 100, "compare height" );
+});
+
+test("s", function() {
+ expect(2);
+
+ var handle = '.ui-resizable-s', target = $('#resizable1').resizable({ handles: 'all' });
+
+ drag(handle, 0, 50);
+ equals( target.height(), 150, "compare height" );
+
+ drag(handle, 0, -50);
+ equals( target.height(), 100, "compare height" );
+});
+
+test("e", function() {
+ expect(2);
+
+ var handle = '.ui-resizable-e', target = $('#resizable1').resizable({ handles: 'all' });
+
+ drag(handle, 50);
+ equals( target.width(), 150, "compare width");
+
+ drag(handle, -50);
+ equals( target.width(), 100, "compare width" );
+});
+
+test("w", function() {
+ expect(2);
+
+ var handle = '.ui-resizable-w', target = $('#resizable1').resizable({ handles: 'all' });
+
+ drag(handle, -50);
+ equals( target.width(), 150, "compare width" );
+
+ drag(handle, 50);
+ equals( target.width(), 100, "compare width" );
+});
+
+test("ne", function() {
+ expect(4);
+
+ var handle = '.ui-resizable-ne', target = $('#resizable1').css({ overflow: 'hidden' }).resizable({ handles: 'all' });
+
+ drag(handle, -50, -50);
+ equals( target.width(), 50, "compare width" );
+ equals( target.height(), 150, "compare height" );
+
+ drag(handle, 50, 50);
+ equals( target.width(), 100, "compare width" );
+ equals( target.height(), 100, "compare height" );
+});
+
+test("se", function() {
+ expect(4);
+
+ var handle = '.ui-resizable-se', target = $('#resizable1').resizable({ handles: 'all' });
+
+ drag(handle, 50, 50);
+ equals( target.width(), 150, "compare width" );
+ equals( target.height(), 150, "compare height" );
+
+ drag(handle, -50, -50);
+ equals( target.width(), 100, "compare width" );
+ equals( target.height(), 100, "compare height" );
+});
+
+test("sw", function() {
+ expect(4);
+
+ var handle = '.ui-resizable-sw', target = $('#resizable1').resizable({ handles: 'all' });
+
+ drag(handle, -50, -50);
+ equals( target.width(), 150, "compare width" );
+ equals( target.height(), 50, "compare height" );
+
+ drag(handle, 50, 50);
+ equals( target.width(), 100, "compare width" );
+ equals( target.height(), 100, "compare height" );
+});
+
+test("nw", function() {
+ expect(4);
+
+ var handle = '.ui-resizable-nw', target = $('#resizable1').resizable({ handles: 'all' });
+
+ drag(handle, -50, -50);
+ equals( target.width(), 150, "compare width" );
+ equals( target.height(), 150, "compare height" );
+
+ drag(handle, 50, 50);
+ equals( target.width(), 100, "compare width" );
+ equals( target.height(), 100, "compare height" );
+});
+
+module("resizable: Options");
+
+test("aspectRatio: 'preserve' (e)", function() {
+ expect(4);
+
+ var handle = '.ui-resizable-e', target = $('#resizable1').resizable({ aspectRatio: 'preserve', handles: 'all', minWidth: 70, minHeight: 50, maxWidth: 150, maxHeight: 130 });
+
+ drag(handle, 80);
+ equals( target.width(), 130, "compare maxWidth");
+ equals( target.height(), 130, "compare maxHeight");
+
+ drag(handle, -130);
+ equals( target.width(), 70, "compare minWidth");
+ equals( target.height(), 70, "compare minHeight");
+});
+
+test("aspectRatio: 'preserve' (w)", function() {
+ expect(4);
+
+ var handle = '.ui-resizable-w', target = $('#resizable1').resizable({ aspectRatio: 'preserve', handles: 'all', minWidth: 70, minHeight: 50, maxWidth: 150, maxHeight: 130 });
+
+ drag(handle, -80);
+ equals( target.width(), 130, "compare maxWidth");
+ equals( target.height(), 130, "compare maxHeight");
+
+ drag(handle, 130);
+ equals( target.width(), 70, "compare minWidth");
+ equals( target.height(), 70, "compare minHeight");
+});
+
+test("aspectRatio: 'preserve' (n)", function() {
+ expect(4);
+
+ var handle = '.ui-resizable-n', target = $('#resizable1').resizable({ aspectRatio: 'preserve', handles: 'all', minWidth: 70, minHeight: 50, maxWidth: 150, maxHeight: 130 });
+
+ drag(handle, 0, -80);
+ equals( target.width(), 130, "compare maxWidth");
+ equals( target.height(), 130, "compare maxHeight");
+
+ drag(handle, 0, 80);
+ equals( target.width(), 70, "compare minWidth");
+ equals( target.height(), 70, "compare minHeight");
+});
+
+test("aspectRatio: 'preserve' (s)", function() {
+ expect(4);
+
+ var handle = '.ui-resizable-s', target = $('#resizable1').resizable({ aspectRatio: 'preserve', handles: 'all', minWidth: 70, minHeight: 50, maxWidth: 150, maxHeight: 130 });
+
+ drag(handle, 0, 80);
+ equals( target.width(), 130, "compare maxWidth");
+ equals( target.height(), 130, "compare maxHeight");
+
+ drag(handle, 0, -80);
+ equals( target.width(), 70, "compare minWidth");
+ equals( target.height(), 70, "compare minHeight");
+});
+
+test("aspectRatio: 'preserve' (se)", function() {
+ expect(4);
+
+ var handle = '.ui-resizable-se', target = $('#resizable1').resizable({ aspectRatio: 'preserve', handles: 'all', minWidth: 70, minHeight: 50, maxWidth: 150, maxHeight: 130 });
+
+ drag(handle, 80, 80);
+ equals( target.width(), 130, "compare maxWidth");
+ equals( target.height(), 130, "compare maxHeight");
+
+ drag(handle, -80, -80);
+ equals( target.width(), 70, "compare minWidth");
+ equals( target.height(), 70, "compare minHeight");
+});
+
+test("aspectRatio: 'preserve' (sw)", function() {
+ expect(4);
+
+ var handle = '.ui-resizable-sw', target = $('#resizable1').resizable({ aspectRatio: 'preserve', handles: 'all', minWidth: 70, minHeight: 50, maxWidth: 150, maxHeight: 130 });
+
+ drag(handle, -80, 80);
+ equals( target.width(), 130, "compare maxWidth");
+ equals( target.height(), 130, "compare maxHeight");
+
+ drag(handle, 80, -80);
+ equals( target.width(), 70, "compare minWidth");
+ equals( target.height(), 70, "compare minHeight");
+});
+
+test("aspectRatio: 'preserve' (ne)", function() {
+ expect(4);
+
+ var handle = '.ui-resizable-ne', target = $('#resizable1').resizable({ aspectRatio: 'preserve', handles: 'all', minWidth: 70, minHeight: 50, maxWidth: 150, maxHeight: 130 });
+
+ drag(handle, 80, -80);
+ equals( target.width(), 130, "compare maxWidth");
+ equals( target.height(), 130, "compare maxHeight");
+
+ drag(handle, -80, 80);
+ equals( target.width(), 70, "compare minWidth");
+ equals( target.height(), 70, "compare minHeight");
+});
+
+test("grid", function() {
+ expect(4);
+
+ var handle = '.ui-resizable-se', target = $('#resizable1').resizable({ handles: 'all', grid: [0, 20] });
+
+ drag(handle, 3, 9);
+ equals( target.width(), 103, "compare width");
+ equals( target.height(), 100, "compare height");
+
+ drag(handle, 15, 11);
+ equals( target.width(), 118, "compare width");
+ equals( target.height(), 120, "compare height");
+});
+
+test("grid (wrapped)", function() {
+ expect(4);
+
+ var handle = '.ui-resizable-se', target = $('#resizable2').resizable({ handles: 'all', grid: [0, 20] });
+
+ drag(handle, 3, 9);
+ equals( target.width(), 103, "compare width");
+ equals( target.height(), 100, "compare height");
+
+ drag(handle, 15, 11);
+ equals( target.width(), 118, "compare width");
+ equals( target.height(), 120, "compare height");
+});
+
+test("ui-resizable-se { handles: 'all', minWidth: 60, minHeight: 60, maxWidth: 100, maxHeight: 100 }", function() {
+ expect(4);
+
+ var handle = '.ui-resizable-se', target = $('#resizable1').resizable({ handles: 'all', minWidth: 60, minHeight: 60, maxWidth: 100, maxHeight: 100 });
+
+ drag(handle, -50, -50);
+ equals( target.width(), 60, "compare minWidth" );
+ equals( target.height(), 60, "compare minHeight" );
+
+ drag(handle, 70, 70);
+ equals( target.width(), 100, "compare maxWidth" );
+ equals( target.height(), 100, "compare maxHeight" );
+});
+
+test("ui-resizable-sw { handles: 'all', minWidth: 60, minHeight: 60, maxWidth: 100, maxHeight: 100 }", function() {
+ expect(4);
+
+ var handle = '.ui-resizable-sw', target = $('#resizable1').resizable({ handles: 'all', minWidth: 60, minHeight: 60, maxWidth: 100, maxHeight: 100 });
+
+ drag(handle, 50, -50);
+ equals( target.width(), 60, "compare minWidth" );
+ equals( target.height(), 60, "compare minHeight" );
+
+ drag(handle, -70, 70);
+ equals( target.width(), 100, "compare maxWidth" );
+ equals( target.height(), 100, "compare maxHeight" );
+});
+
+test("ui-resizable-ne { handles: 'all', minWidth: 60, minHeight: 60, maxWidth: 100, maxHeight: 100 }", function() {
+ expect(4);
+
+ var handle = '.ui-resizable-ne', target = $('#resizable1').resizable({ handles: 'all', minWidth: 60, minHeight: 60, maxWidth: 100, maxHeight: 100 });
+
+ drag(handle, -50, 50);
+ equals( target.width(), 60, "compare minWidth" );
+ equals( target.height(), 60, "compare minHeight" );
+
+ drag(handle, 70, -70);
+ equals( target.width(), 100, "compare maxWidth" );
+ equals( target.height(), 100, "compare maxHeight" );
+});
+
+test("ui-resizable-nw { handles: 'all', minWidth: 60, minHeight: 60, maxWidth: 100, maxHeight: 100 }", function() {
+ expect(4);
+
+ var handle = '.ui-resizable-nw', target = $('#resizable1').resizable({ handles: 'all', minWidth: 60, minHeight: 60, maxWidth: 100, maxHeight: 100 });
+
+ drag(handle, 70, 70);
+ equals( target.width(), 60, "compare minWidth" );
+ equals( target.height(), 60, "compare minHeight" );
+
+ drag(handle, -70, -70);
+ equals( target.width(), 100, "compare maxWidth" );
+ equals( target.height(), 100, "compare maxHeight" );
+});
+
+})(jQuery);
diff --git a/tests/unit/selectable/selectable.html b/tests/unit/selectable/selectable.html
new file mode 100644
index 000000000..e35d28ad1
--- /dev/null
+++ b/tests/unit/selectable/selectable.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <title>jQuery UI Selectable Test Suite</title>
+
+ <script type="text/javascript" src="../../../jquery-1.3pre.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.core.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.selectable.js"></script>
+
+ <link type="text/css" href="../testsuite.css" rel="stylesheet" />
+ <script type="text/javascript" src="../testsuite.js"></script>
+ <script type="text/javascript" src="../../../external/qunit/testrunner.js"></script>
+ <script type="text/javascript" src="../../../external/simulate/jquery.simulate.js"></script>
+
+ <script type="text/javascript" src="selectable.js"></script>
+</head>
+<body>
+
+<div id="main">
+ <ul id="selectable1">
+ <li>Item 1</li>
+ <li>Item 2</li>
+ <li class="special">Item 3</li>
+ <li>Item 4</li>
+ <li>Item 5</li>
+ </ul>
+</div>
+
+</body>
+</html>
diff --git a/tests/unit/selectable/selectable.js b/tests/unit/selectable/selectable.js
new file mode 100644
index 000000000..df23626ca
--- /dev/null
+++ b/tests/unit/selectable/selectable.js
@@ -0,0 +1,196 @@
+/*
+ * selectable unit tests
+ */
+(function($) {
+//
+// Selectable Test Helper Functions
+//
+
+var defaults = {
+ autoRefresh: true,
+ disabled: false,
+ filter: '*'
+};
+
+var el;
+
+var drag = function(dx, dy) {
+ var off = el.offset(), pos = { clientX: off.left, clientY: off.top };
+ el.simulate("mousedown", pos);
+ $(document).simulate("mousemove", pos);
+ pos.clientX += dx;
+ pos.clientY += dy;
+ $(document).simulate("mousemove", pos);
+ $(document).simulate("mouseup", pos);
+}
+
+var border = function(el, side) { return parseInt(el.css('border-' + side + '-width')); }
+
+var margin = function(el, side) { return parseInt(el.css('margin-' + side)); }
+
+// Selectable Tests
+module("selectable");
+
+test("init", function() {
+ expect(6);
+
+ $("<div></div>").appendTo('body').selectable().remove();
+ ok(true, '.selectable() called on element');
+
+ $([]).selectable().remove();
+ ok(true, '.selectable() called on empty collection');
+
+ $("<div></div>").selectable().remove();
+ ok(true, '.selectable() called on disconnected DOMElement');
+
+ $("<div></div>").selectable().selectable("foo").remove();
+ ok(true, 'arbitrary method called after init');
+
+ el = $("<div></div>").selectable()
+ var foo = el.data("foo.selectable");
+ el.remove();
+ ok(true, 'arbitrary option getter after init');
+
+ $("<div></div>").selectable().data("foo.selectable", "bar").remove();
+ ok(true, 'arbitrary option setter after init');
+});
+
+test("destroy", function() {
+ expect(6);
+
+ $("<div></div>").appendTo('body').selectable().selectable("destroy").remove();
+ ok(true, '.selectable("destroy") called on element');
+
+ $([]).selectable().selectable("destroy").remove();
+ ok(true, '.selectable("destroy") called on empty collection');
+
+ $("<div></div>").selectable().selectable("destroy").remove();
+ ok(true, '.selectable("destroy") called on disconnected DOMElement');
+
+ $("<div></div>").selectable().selectable("destroy").selectable("foo").remove();
+ ok(true, 'arbitrary method called after destroy');
+
+ el = $("<div></div>").selectable();
+ var foo = el.selectable("destroy").data("foo.selectable");
+ el.remove();
+ ok(true, 'arbitrary option getter after destroy');
+
+ $("<div></div>").selectable().selectable("destroy").data("foo.selectable", "bar").remove();
+ ok(true, 'arbitrary option setter after destroy');
+});
+
+test("defaults", function() {
+ el = $('<div></div>').selectable();
+ $.each(defaults, function(key, val) {
+ var actual = el.data(key + ".selectable"), expected = val;
+ same(actual, expected, key);
+ });
+ el.remove();
+});
+
+module("selectable: Options");
+
+test("autoRefresh", function() {
+ expect(3);
+ el = $("#selectable1");
+ var actual, sel = $("*", el), selected = function() { actual += 1 };
+
+ actual = 0;
+ el = $("#selectable1").selectable({ autoRefresh: false, selected: selected });
+ sel.hide();
+ drag(1000, 1000);
+ equals(actual, sel.length);
+ el.selectable("destroy");
+
+ actual = 0;
+ sel.show();
+ el = $("#selectable1").selectable({ autoRefresh: true, selected: selected });
+ sel.hide();
+ drag(1000, 1000);
+ equals(actual, 0);
+ sel.show();
+ drag(1000, 1000);
+ equals(actual, sel.length);
+ el.selectable("destroy");
+ sel.show();
+});
+
+test("filter", function() {
+ expect(2);
+ el = $("#selectable1");
+ var actual, sel = $("*", el), selected = function() { actual += 1 };
+
+ actual = 0;
+ el = $("#selectable1").selectable({ filter: '.special', selected: selected });
+ drag(1000, 1000);
+ ok(sel.length != 1, "this test assumes more than 1 selectee");
+ equals(actual, 1);
+ el.selectable("destroy");
+});
+
+module("selectable: Methods");
+
+test("disable", function() {
+ expect(2);
+ var fired = false;
+
+ el = $("#selectable1");
+ el.selectable({
+ disabled: false,
+ start: function() { fired = true; }
+ });
+ el.simulate("drag", 20, 20);
+ equals(fired, true, "start fired");
+ el.selectable("disable");
+ fired = false;
+ el.simulate("drag", 20, 20);
+ equals(fired, false, "start fired");
+ el.selectable("destroy");
+});
+
+test("enable", function() {
+ expect(2);
+ var fired = false;
+
+ el = $("#selectable1");
+ el.selectable({
+ disabled: true,
+ start: function() { fired = true; }
+ });
+ el.simulate("drag", 20, 20);
+ equals(fired, false, "start fired");
+ el.selectable("enable");
+ el.simulate("drag", 20, 20);
+ equals(fired, true, "start fired");
+ el.selectable("destroy");
+});
+
+module("selectable: Callbacks");
+
+test("start", function() {
+ expect(2);
+ el = $("#selectable1");
+ el.selectable({
+ start: function(ev, ui) {
+ ok(true, "drag fired start callback");
+ equals(this, el[0], "context of callback");
+ }
+ });
+ el.simulate("drag", 20, 20);
+});
+
+test("stop", function() {
+ expect(2);
+ el = $("#selectable1");
+ el.selectable({
+ start: function(ev, ui) {
+ ok(true, "drag fired stop callback");
+ equals(this, el[0], "context of callback");
+ }
+ });
+ el.simulate("drag", 20, 20);
+});
+
+module("selectable: Tickets");
+
+})(jQuery);
diff --git a/tests/unit/slider/slider.html b/tests/unit/slider/slider.html
new file mode 100644
index 000000000..c4a30168a
--- /dev/null
+++ b/tests/unit/slider/slider.html
@@ -0,0 +1,27 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <title>jQuery UI Slider Test Suite</title>
+
+ <script type="text/javascript" src="../../../jquery-1.3pre.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.core.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.slider.js"></script>
+
+ <link type="text/css" href="../testsuite.css" rel="stylesheet" />
+ <script type="text/javascript" src="../testsuite.js"></script>
+ <script type="text/javascript" src="../../../external/qunit/testrunner.js"></script>
+ <script type="text/javascript" src="../../../external/simulate/jquery.simulate.js"></script>
+
+ <script type="text/javascript" src="slider.js"></script>
+</head>
+<body>
+
+<div id="main">
+ <div id="slider1"></div>
+ <div id="slider3" style="position: relative; margin: 40px; width: 217px; height: 28px;">
+ <div class="ui-slider-handle" style="position: absolute; height: 21px; left: 0px; bottom: 0px; width: 17px;"></div>
+ </div>
+</div>
+
+</body>
+</html>
diff --git a/tests/unit/slider/slider.js b/tests/unit/slider/slider.js
new file mode 100644
index 000000000..34d29b4fd
--- /dev/null
+++ b/tests/unit/slider/slider.js
@@ -0,0 +1,396 @@
+/*
+ * slider unit tests
+ */
+(function($) {
+//
+// Slider Test Helper Functions
+//
+
+var defaults = {
+ max: 100,
+ min: 0,
+ orientation: 'horizontal',
+ step: 1,
+ value: 0
+};
+
+var el, options;
+
+function handle() {
+ return el.find(".ui-slider-handle");
+}
+
+// Slider Tests
+module("slider");
+
+test("init", function() {
+ expect(6);
+
+ $("<div></div>").appendTo('body').slider().remove();
+ ok(true, '.slider() called on element');
+
+ $([]).slider().remove();
+ ok(true, '.slider() called on empty collection');
+
+ $('<div></div>').slider().remove();
+ ok(true, '.slider() called on disconnected DOMElement');
+
+ $('<div></div>').slider().slider("foo").remove();
+ ok(true, 'arbitrary method called after init');
+
+ el = $('<div></div>').slider();
+ var foo = el.data("foo.slider");
+ el.remove();
+ ok(true, 'arbitrary option getter after init');
+
+ $('<div></div>').slider().data("foo.slider", "bar").remove();
+ ok(true, 'arbitrary option setter after init');
+});
+
+test("destroy", function() {
+ expect(8);
+
+ $("<div></div>").appendTo('body').slider().slider("destroy").remove();
+ ok(true, '.slider("destroy") called on element');
+
+ $([]).slider().slider("destroy").remove();
+ ok(true, '.slider("destroy") called on empty collection');
+
+ $('<div></div>').appendTo('body').remove().slider().slider("destroy").remove();
+ ok(true, '.slider("destroy") called on disconnected DOMElement');
+
+ $('<div></div>').slider().slider("destroy").slider("foo").remove();
+ ok(true, 'arbitrary method called after destroy');
+
+ el = $('<div></div>').slider();
+ var foo = el.slider("destroy").data("foo.slider");
+ el.remove();
+ ok(true, 'arbitrary option getter (.data) after destroy');
+
+ el = $('<div></div>').slider();
+ var foo = el.slider("destroy").slider("option", "foo");
+ el.remove();
+ ok(true, 'arbitrary option getter (.slider option method) after destroy');
+
+ $('<div></div>').slider().slider("destroy").data("foo.slider", "bar").remove();
+ ok(true, 'arbitrary option setter (.data) after destroy');
+
+ $('<div></div>').slider().slider("destroy").slider("options", "foo", "bar").remove();
+ ok(true, 'arbitrary option setter (.slider option method) after destroy');
+});
+
+test("defaults", function() {
+ el = $('<div></div>').slider();
+ $.each(defaults, function(key, val) {
+ var actual = el.data(key + ".slider"), expected = val;
+ same(actual, expected, key);
+ });
+ el.remove();
+});
+
+module("slider");
+
+test("keydown HOME on handle sets value to min", function() {
+ el = $('<div></div>');
+ options = {
+ max: 5,
+ min: -5,
+ orientation: 'horizontal',
+ step: 1
+ };
+ el.slider(options);
+
+ el.slider("value", 0);
+
+ handle().simulate("keydown", { keyCode: $.ui.keyCode.HOME });
+ equals(el.slider("value"), options.min);
+
+ el.slider('destroy');
+
+ el = $('<div></div>');
+ options = {
+ max: 5,
+ min: -5,
+ orientation: 'vertical',
+ step: 1
+ };
+ el.slider(options);
+
+ el.slider("value", 0);
+
+ handle().simulate("keydown", { keyCode: $.ui.keyCode.HOME });
+ equals(el.slider("value"), options.min);
+
+ el.slider('destroy');
+});
+
+test("keydown END on handle sets value to max", function() {
+ el = $('<div></div>');
+ options = {
+ max: 5,
+ min: -5,
+ orientation: 'horizontal',
+ step: 1
+ };
+ el.slider(options);
+
+ el.slider("value", 0);
+
+ handle().simulate("keydown", { keyCode: $.ui.keyCode.END });
+ equals(el.slider("value"), options.max);
+
+ el.slider('destroy');
+
+ el = $('<div></div>');
+ options = {
+ max: 5,
+ min: -5,
+ orientation: 'vertical',
+ step: 1
+ };
+ el.slider(options);
+
+ el.slider("value", 0);
+
+ handle().simulate("keydown", { keyCode: $.ui.keyCode.END });
+ equals(el.slider("value"), options.max);
+
+ el.slider('destroy');
+});
+
+test("keydown UP on handle increases value by step, not greater than max", function() {
+ el = $('<div></div>');
+ options = {
+ max: 5,
+ min: -5,
+ orientation: 'horizontal',
+ step: 1
+ };
+ el.slider(options);
+
+ el.slider("value", options.max - options.step);
+
+ handle().simulate("keydown", { keyCode: $.ui.keyCode.UP });
+ equals(el.slider("value"), options.max);
+
+ handle().simulate("keydown", { keyCode: $.ui.keyCode.UP });
+ equals(el.slider("value"), options.max);
+
+ el.slider("destroy");
+
+ el = $('<div></div>');
+ options = {
+ max: 5,
+ min: -5,
+ orientation: 'vertical',
+ step: 1
+ };
+ el.slider(options);
+
+ el.slider("value", options.max - options.step);
+
+ handle().simulate("keydown", { keyCode: $.ui.keyCode.UP });
+ equals(el.slider("value"), options.max);
+
+ handle().simulate("keydown", { keyCode: $.ui.keyCode.UP });
+ equals(el.slider("value"), options.max);
+
+ el.slider("destroy");
+});
+
+test("keydown RIGHT on handle increases value by step, not greater than max", function() {
+ el = $('<div></div>');
+ options = {
+ max: 5,
+ min: -5,
+ orientation: 'horizontal',
+ step: 1
+ };
+ el.slider(options);
+
+ el.slider("value", options.max - options.step);
+
+ handle().simulate("keydown", { keyCode: $.ui.keyCode.RIGHT });
+ equals(el.slider("value"), options.max);
+
+ handle().simulate("keydown", { keyCode: $.ui.keyCode.RIGHT });
+ equals(el.slider("value"), options.max);
+
+ el.slider("destroy");
+
+ el = $('<div></div>');
+ options = {
+ max: 5,
+ min: -5,
+ orientation: 'vertical',
+ step: 1
+ };
+ el.slider(options);
+
+ el.slider("value", options.max - options.step);
+
+ handle().simulate("keydown", { keyCode: $.ui.keyCode.RIGHT });
+ equals(el.slider("value"), options.max);
+
+ handle().simulate("keydown", { keyCode: $.ui.keyCode.RIGHT });
+ equals(el.slider("value"), options.max);
+
+ el.slider("destroy");
+});
+
+test("keydown DOWN on handle decreases value by step, not less than min", function() {
+ el = $('<div></div>');
+ options = {
+ max: 5,
+ min: -5,
+ orientation: 'horizontal',
+ step: 1
+ };
+ el.slider(options);
+
+ el.slider("value", options.min + options.step);
+
+ handle().simulate("keydown", { keyCode: $.ui.keyCode.DOWN });
+ equals(el.slider("value"), options.min);
+
+ handle().simulate("keydown", { keyCode: $.ui.keyCode.DOWN });
+ equals(el.slider("value"), options.min);
+
+ el.slider("destroy");
+
+ el = $('<div></div>');
+ options = {
+ max: 5,
+ min: -5,
+ orientation: 'vertical',
+ step: 1
+ };
+ el.slider(options);
+
+ el.slider("value", options.min + options.step);
+
+ handle().simulate("keydown", { keyCode: $.ui.keyCode.DOWN });
+ equals(el.slider("value"), options.min);
+
+ handle().simulate("keydown", { keyCode: $.ui.keyCode.DOWN });
+ equals(el.slider("value"), options.min);
+
+ el.slider("destroy");
+});
+
+test("keydown LEFT on handle decreases value by step, not less than min", function() {
+ el = $('<div></div>');
+ options = {
+ max: 5,
+ min: -5,
+ orientation: 'horizontal',
+ step: 1
+ };
+ el.slider(options);
+
+ el.slider("value", options.min + options.step);
+
+ handle().simulate("keydown", { keyCode: $.ui.keyCode.LEFT });
+ equals(el.slider("value"), options.min);
+
+ handle().simulate("keydown", { keyCode: $.ui.keyCode.LEFT });
+ equals(el.slider("value"), options.min);
+
+ el.slider("destroy");
+
+ el = $('<div></div>');
+ options = {
+ max: 5,
+ min: -5,
+ orientation: 'vertical',
+ step: 1
+ };
+ el.slider(options);
+
+ el.slider("value", options.min + options.step);
+
+ handle().simulate("keydown", { keyCode: $.ui.keyCode.LEFT });
+ equals(el.slider("value"), options.min);
+
+ handle().simulate("keydown", { keyCode: $.ui.keyCode.LEFT });
+ equals(el.slider("value"), options.min);
+
+ el.slider("destroy");
+});
+
+module("slider: Options");
+
+test("orientation", function() {
+ el = $('<div></div>');
+
+ options = {
+ max: 2,
+ min: -2,
+ orientation: 'vertical',
+ value: 1
+ };
+
+ var percentVal = (options.value - options.min) / (options.max - options.min) * 100;
+
+ el.slider(options).slider("option", "orientation", "horizontal");
+ ok(el.is('.ui-slider-horizontal'), "horizontal slider has class .ui-slider-horizontal");
+ ok(!el.is('.ui-slider-vertical'), "horizontal slider does not have class .ui-slider-vertical");
+ equals(handle().css('left'), percentVal + '%', "horizontal slider handle is positioned with left: %");
+
+ el.slider('destroy');
+
+ options = {
+ max: 2,
+ min: -2,
+ orientation: 'horizontal',
+ value: -1
+ };
+
+ var percentVal = (options.value - options.min) / (options.max - options.min) * 100;
+
+ el.slider(options).slider("option", "orientation", "vertical");
+ ok(el.is('.ui-slider-vertical'), "vertical slider has class .ui-slider-vertical");
+ ok(!el.is('.ui-slider-horizontal'), "vertical slider does not have class .ui-slider-horizontal");
+ equals(handle().css('bottom'), percentVal + '%', "vertical slider handle is positioned with bottom: %");
+
+ el.slider('destroy');
+
+});
+
+test("max", function() {
+ el = $('<div></div>');
+
+ options = {
+ max: 37,
+ min: 6,
+ orientation: 'horizontal',
+ step: 1,
+ value: 50
+ };
+
+ el.slider(options);
+ ok(el.slider("option", "value") == options.value, "value option is not contained by max");
+ ok(el.slider("value") == options.max, "value method is contained by max");
+ el.slider('destroy');
+
+});
+
+test("min", function() {
+ el = $('<div></div>');
+
+ options = {
+ max: 37,
+ min: 6,
+ orientation: 'vertical',
+ step: 1,
+ value: 2
+ };
+
+ el.slider(options);
+ ok(el.slider("option", "value") == options.value, "value option is not contained by min");
+ ok(el.slider("value") == options.min, "value method is contained by min");
+ el.slider('destroy');
+
+});
+
+})(jQuery);
diff --git a/tests/unit/sortable/sortable.html b/tests/unit/sortable/sortable.html
new file mode 100644
index 000000000..5c45144bc
--- /dev/null
+++ b/tests/unit/sortable/sortable.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <title>jQuery UI Sortable Test Suite</title>
+
+ <script type="text/javascript" src="../../../jquery-1.3pre.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.core.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.sortable.js"></script>
+
+ <link type="text/css" href="../testsuite.css" rel="stylesheet" />
+ <script type="text/javascript" src="../testsuite.js"></script>
+ <script type="text/javascript" src="../../../external/qunit/testrunner.js"></script>
+ <script type="text/javascript" src="../../../external/simulate/jquery.simulate.js"></script>
+
+ <script type="text/javascript" src="sortable.js"></script>
+</head>
+<body>
+
+<div id="main">
+ <ul id="sortable">
+ <li>Item 1</li>
+ <li>Item 2</li>
+ <li>Item 3</li>
+ <li>Item 4</li>
+ <li>Item 5</li>
+ </ul>
+</div>
+
+</body>
+</html>
diff --git a/tests/unit/sortable/sortable.js b/tests/unit/sortable/sortable.js
new file mode 100644
index 000000000..c913ed86d
--- /dev/null
+++ b/tests/unit/sortable/sortable.js
@@ -0,0 +1,148 @@
+/*
+ * sortable unit tests
+ */
+(function($) {
+//
+// Sortable Test Helper Functions
+//
+
+var defaults = {
+ appendTo: "parent",
+ cancel: ":input",
+ delay: 0,
+ disabled: false,
+ distance: 1,
+ dropOnEmpty: true,
+ helper: "original",
+ items: "> *",
+ scroll: true,
+ scrollSensitivity: 20,
+ scrollSpeed: 20,
+ tolerance: "guess",
+ zIndex: 1000
+};
+
+var el, offsetBefore, offsetAfter, dragged;
+
+var drag = function(handle, dx, dy) {
+ offsetBefore = $(handle).offset();
+ $(handle).simulate("drag", {
+ dx: dx || 0,
+ dy: dy || 0
+ });
+ dragged = { dx: dx, dy: dy };
+ offsetAfter = $(handle).offset();
+}
+
+var sort = function(handle, dx, dy, index, msg) {
+ drag(handle, dx, dy);
+ equals($(handle).parent().children().index(handle), index, msg);
+}
+
+var border = function(el, side) { return parseInt(el.css('border-' + side + '-width')); }
+var margin = function(el, side) { return parseInt(el.css('margin-' + side)); }
+
+// Sortable Tests
+module("sortable");
+
+test("init", function() {
+ expect(6);
+
+ $("<div></div>").appendTo('body').sortable().remove();
+ ok(true, '.sortable() called on element');
+
+ $([]).sortable();
+ ok(true, '.sortable() called on empty collection');
+
+ $("<div></div>").sortable();
+ ok(true, '.sortable() called on disconnected DOMElement');
+
+ $("<div></div>").sortable().sortable("foo");
+ ok(true, 'arbitrary method called after init');
+
+ $("<div></div>").sortable().data("foo.sortable");
+ ok(true, 'arbitrary option getter after init');
+
+ $("<div></div>").sortable().data("foo.sortable", "bar");
+ ok(true, 'arbitrary option setter after init');
+});
+
+test("destroy", function() {
+ expect(6);
+
+ $("<div></div>").appendTo('body').sortable().sortable("destroy").remove();
+ ok(true, '.sortable("destroy") called on element');
+
+ $([]).sortable().sortable("destroy");
+ ok(true, '.sortable("destroy") called on empty collection');
+
+ $("<div></div>").sortable().sortable("destroy");
+ ok(true, '.sortable("destroy") called on disconnected DOMElement');
+
+ $("<div></div>").sortable().sortable("destroy").sortable("foo");
+ ok(true, 'arbitrary method called after destroy');
+
+ $("<div></div>").sortable().sortable("destroy").data("foo.sortable");
+ ok(true, 'arbitrary option getter after destroy');
+
+ $("<div></div>").sortable().sortable("destroy").data("foo.sortable", "bar");
+ ok(true, 'arbitrary option setter after destroy');
+});
+
+test("enable", function() {
+ expect(4);
+ el = $("#sortable").sortable({ disabled: true });
+
+ sort($("li", el)[0], 0, 40, 0, '.sortable({ disabled: true })');
+
+ el.sortable("enable");
+ equals(el.data("disabled.sortable"), false, "disabled.sortable getter");
+
+ el.sortable("destroy");
+ el.sortable({ disabled: true });
+ el.data("disabled.sortable", false);
+ equals(el.data("disabled.sortable"), false, "disabled.sortable setter");
+
+ sort($("li", el)[0], 0, 40, 2, '.data("disabled.sortable", false)');
+});
+
+test("disable", function() {
+ expect(5);
+ el = $("#sortable").sortable({ disabled: false });
+ sort($("li", el)[0], 0, 40, 2, '.sortable({ disabled: false })');
+
+ el.sortable("disable");
+ sort($("li", el)[0], 0, 40, 0, 'disabled.sortable getter');
+
+ el.sortable("destroy");
+
+ el.sortable({ disabled: false });
+ sort($("li", el)[0], 0, 40, 2, '.sortable({ disabled: false })');
+ el.data("disabled.sortable", true);
+ equals(el.data("disabled.sortable"), true, "disabled.sortable setter");
+ sort($("li", el)[0], 0, 40, 0, '.data("disabled.sortable", true)');
+});
+
+test("defaults", function() {
+ el = $('<div></div>').sortable();
+ $.each(defaults, function(key, val) {
+ var actual = el.data(key + ".sortable"), expected = val;
+ same(actual, expected, key);
+ });
+ el.remove();
+});
+
+test("#3019: Stop fires too early", function() {
+
+ var helper = null;
+ el = $("#sortable").sortable({ stop: function(event, ui) {
+ helper = ui.helper;
+ }});
+
+ sort($("li", el)[0], 0, 40, 2, 'Dragging the sortable');
+ equals(helper, null, "helper should be false");
+
+});
+
+
+})(jQuery);
diff --git a/tests/unit/tabs/tabs.html b/tests/unit/tabs/tabs.html
new file mode 100644
index 000000000..57ddb6680
--- /dev/null
+++ b/tests/unit/tabs/tabs.html
@@ -0,0 +1,44 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <title>jQuery UI Tabs Test Suite</title>
+
+ <script type="text/javascript" src="../../../jquery-1.3pre.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.core.js"></script>
+ <script type="text/javascript" src="../../../ui/ui.tabs.js"></script>
+
+ <link type="text/css" href="../testsuite.css" rel="stylesheet" />
+ <script type="text/javascript" src="../testsuite.js"></script>
+ <script type="text/javascript" src="../../../external/qunit/testrunner.js"></script>
+ <script type="text/javascript" src="../../../external/simulate/jquery.simulate.js"></script>
+ <script type="text/javascript" src="../../../external/cookie/jquery.cookie.js"></script>
+
+ <script type="text/javascript" src="tabs.js"></script>
+</head>
+<body>
+
+ <div id="main">
+
+ <div id="tabs1">
+ <ul>
+ <li><a href="#fragment-1">1</a></li>
+ <li><a href="#fragment-2">2</a></li>
+ <li><a href="#fragment-3">3</a></li>
+ </ul>
+ <div id="fragment-1"></div>
+ <div id="fragment-2"></div>
+ <div id="fragment-3"></div>
+ </div>
+ <div id="tabs2">
+ <ul>
+ <li><a href="#colon:test">1</a></li>
+ <li><a href="#inline-style">2</a></li>
+ </ul>
+ <div id="colon:test"></div>
+ <div style="height: 300px;" id="inline-style"></div>
+ </div>
+
+ </div>
+
+</body>
+</html>
diff --git a/tests/unit/tabs/tabs.js b/tests/unit/tabs/tabs.js
new file mode 100644
index 000000000..41d59f060
--- /dev/null
+++ b/tests/unit/tabs/tabs.js
@@ -0,0 +1,243 @@
+/*
+ * tabs unit tests
+ */
+(function($) {
+//
+// Tabs Test Helper Functions
+//
+
+var defaults = {
+ ajaxOptions: null,
+ cache: false,
+ cookie: null,
+ deselectable: false,
+ deselectableClass: 'ui-tabs-deselectable',
+ disabled: [],
+ disabledClass: 'ui-state-disabled',
+ event: 'click',
+ fx: null,
+ hideClass: 'ui-tabs-hide',
+ idPrefix: 'ui-tabs-',
+ loadingClass: 'ui-tabs-loading',
+ navClass: 'ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all',
+ panelClass: 'ui-tabs-panel ui-widget-content ui-corner-bottom',
+ panelTemplate: '<div></div>',
+ selectedClass: 'ui-tabs-selected ui-state-active',
+ spinner: 'Loading&#8230;',
+ tabTemplate: '<li><a href="#{href}"><span>#{label}</span></a></li>'
+};
+
+var el;
+
+// need to wait a bit for the pseudo animation...
+function defer(defered, ms) {
+ var queue = defer.queue || (defer.queue = []);
+ if (!queue.length) stop();
+ queue.push(defered);
+ setTimeout(function() {
+ queue.shift()();
+ if (!queue.length) start();
+ }, ms || 100);
+}
+
+module('tabs');
+
+ test('init', function() {
+ expect(9);
+
+ var el = $('#tabs1').tabs(); // new markup requires to tabify wrapper again...
+ ok(true, '.tabs() called on element');
+
+ el.tabs('destroy').tabs({ selected: 1 });
+
+ ok( el.is('.ui-tabs.ui-widget.ui-widget-content.ui-corner-all'), 'attach classes to container');
+ ok( $('ul', el).is('.ui-tabs-nav.ui-helper-reset.ui-helper-clearfix.ui-widget-header.ui-corner-all'), 'attach classes to list' );
+ ok( $('div:eq(0)', el).is('.ui-tabs-panel.ui-widget-content.ui-corner-bottom'), 'attach classes to panel' );
+ ok( $('li:eq(0)', el).is('.ui-state-default.ui-corner-top'), 'attach classes to inactive li');
+ ok( $('li:eq(1)', el).is('.ui-tabs-selected.ui-state-active.ui-corner-top'), 'attach classes to active li');
+ equals( el.data('selected.tabs'), 1, 'selected.tabs set' );
+ equals( $('li', el).index( $('li.ui-tabs-selected', el) ), 1, 'second tab active');
+ equals( $('div', el).index( $('div.ui-tabs-hide', '#tabs1') ), 0, 'first panel should be hidden' );
+
+ });
+
+ test('destroy', function() {
+ expect(0);
+
+ });
+
+ test("defaults", function() {
+ el = $('#tabs1 > ul').tabs();
+ $.each(defaults, function(key, val) {
+ var actual = el.data(key + '.tabs'), expected = val;
+ same(actual, expected, key);
+ });
+ el.tabs('destroy');
+ });
+
+ test('add', function() {
+ expect(0);
+
+ });
+
+ test('remove', function() {
+ expect(4);
+
+ var el = $('#tabs1 > ul').tabs();
+ el.tabs('remove', 0);
+ equals(el.tabs('length'), 2, 'remove tab');
+ equals($('li a[href$="fragment-1"]', el).length, 0, 'remove associated list item');
+ equals($('#fragment-1').length, 0, 'remove associated panel');
+
+ // TODO delete tab -> focus tab to right
+ // TODO delete last tab -> focus tab to left
+
+ el = $('#tabs2 > ul').tabs({ selected: 1 });
+ el.tabs('remove', 1);
+ equals(el.data('selected.tabs'), 0, 'update selected property');
+
+ });
+
+ test('enable', function() {
+ expect(0);
+
+ });
+
+ test('disable', function() {
+ expect(0);
+
+ });
+
+ test('select', function() {
+ expect(0);
+
+ });
+
+ test('load', function() {
+ expect(0);
+
+ });
+
+ test('url', function() {
+ expect(0);
+
+ });
+
+
+module('tabs: Options');
+
+ test('select: null', function() {
+ expect(3);
+
+ var el = $('#tabs1 > ul');
+
+ el.tabs({ selected: null });
+ equals( el.data('selected.tabs'), null, 'option set' );
+ equals( $('li.ui-tabs-selected', el).length, 0, 'all tabs should be deselected' );
+ equals( $('div.ui-tabs-hide', '#tabs1').length, 3, 'all panels should be hidden' );
+
+ // TODO select == null with cookie
+ // TODO select == null with select method
+
+ });
+
+ test('deselectable: true', function() {
+ expect(7);
+
+ var el = $('#tabs1 > ul');
+
+ el.tabs({ deselectable: true });
+ equals( el.data('deselectable.tabs'), true, 'option set' );
+ equals( $('li.ui-tabs-deselectable', el).length, 1, 'class "ui-tabs-deselectable" attached once');
+ equals( $('li', el).index( $('li.ui-tabs-deselectable', el) ), 0, 'class "ui-tabs-deselectable" attached to first tab');
+
+ el.tabs('select', 1);
+ equals( $('li.ui-tabs-deselectable', el).length, 1, 'class "ui-tabs-deselectable" attached once');
+ equals( $('li', el).index( $('li.ui-tabs-deselectable', el) ), 1, 'class "ui-tabs-deselectable" attached to second tab');
+
+ el.tabs('select', 1);
+ equals( $('li.ui-tabs-deselectable', el).length, 0, 'class "ui-tabs-deselectable" not attached');
+ defer(function() {
+ equals( $('div.ui-tabs-hide', '#tabs1').length, 3, 'all panels should be hidden' );
+ });
+
+ });
+
+ test('cookie', function() {
+ expect(5);
+
+ var el = $('#tabs1 > ul');
+ var cookieName = 'ui-tabs-' + $.data(el[0]);
+ $.cookie(cookieName, null); // blank state
+ var cookie = function() {
+ return parseInt($.cookie(cookieName), 10);
+ };
+
+ el.tabs({ cookie: {} });
+ equals(cookie(), 0, 'initial cookie value, no cookie given');
+
+ el.tabs('destroy');
+ el.tabs({ selected: 1, cookie: {} });
+ equals(cookie(), 1, 'initial cookie value, given selected');
+
+ el.tabs('select', 2);
+ equals(cookie(), 2, 'cookie value after tabs select');
+
+ el.tabs('destroy');
+ $.cookie(cookieName, 1);
+ el.tabs({ cookie: {} });
+ equals(cookie(), 1, 'initial cookie value, from existing cookie');
+
+ el.tabs('destroy');
+ ok($.cookie(cookieName) === null, 'erase cookie after destroy');
+
+ });
+
+
+module('tabs: Tickets');
+
+ test('id containing colon, #????', function() {
+ expect(4);
+
+ var el = $('#tabs2 > ul').tabs();
+ ok( $('div.ui-tabs-panel:eq(0)', '#tabs2').is(':visible'), 'first panel should be visible' );
+ ok( $('div.ui-tabs-panel:eq(1)', '#tabs2').is(':hidden'), 'second panel should be hidden' );
+
+ el.tabs('select', 1).tabs('select', 0);
+ defer(function() {
+ ok( $('div.ui-tabs-panel:eq(0)', '#tabs2').is(':visible'), 'first panel should be visible' );
+ ok( $('div.ui-tabs-panel:eq(1)', '#tabs2').is(':hidden'), 'second panel should be hidden' );
+ });
+
+ });
+
+ test('panel containing inline style, #????', function() {
+ expect(3);
+
+ var inlineStyle = function(property) {
+ return $('#inline-style')[0].style[property];
+ };
+ var expected = inlineStyle('height');
+
+ var el = $('#tabs2 > ul').tabs();
+ equals(inlineStyle('height'), expected, 'init should not remove inline style');
+
+ el.tabs('select', 1);
+ defer(function() {
+ equals(inlineStyle('height'), expected, 'show tab should not remove inline style');
+
+ el.tabs('select', 0);
+ defer(function() {
+ equals(inlineStyle('height'), expected, 'hide tab should not remove inline style');
+ });
+
+ });
+
+ });
+
+// test('', function() {
+// expect(0);
+//
+// });
+
+})(jQuery);
diff --git a/tests/unit/testsuite.css b/tests/unit/testsuite.css
new file mode 100644
index 000000000..f1961ff47
--- /dev/null
+++ b/tests/unit/testsuite.css
@@ -0,0 +1,4 @@
+@import url("../../external/qunit/testsuite.css");
+html { border: 0; }
+.xerror, .error, .ui-tabs-hide { display: none }
+#main { position: absolute; top: -10000px; left: -10000px; }
diff --git a/tests/unit/testsuite.js b/tests/unit/testsuite.js
new file mode 100644
index 000000000..2ad60cbab
--- /dev/null
+++ b/tests/unit/testsuite.js
@@ -0,0 +1,10 @@
+$(function() {
+
+$('body').prepend(
+ '<h1 id="header">' + document.title + '</h1>' +
+ '<h2 id="banner"></h2>' +
+ '<h2 id="userAgent"></h2>' +
+ '<ol id="tests"></ol>'
+);
+
+});