提交新项目

This commit is contained in:
kongyuebin
2019-12-19 14:47:58 +08:00
parent 7ba20ac1b9
commit f29066a984
609 changed files with 238892 additions and 0 deletions

View File

@@ -0,0 +1,55 @@
Unit tests, written with [QUnit](http://docs.jquery.com/QUnit), are used to
expose bugs for squashing, prevent bugs from respawning, and suppress new
bugs when adding new features and making changes.
# Running the tests
The simplest way to run the tests is to open `tests/tests.html` in your browser.
The test suites will automatically run themselves and present their results.
To run the tests from the command line, download and install
[PhantomJS](http://phantomjs.org/), and run `run-qunit.js` with it:
$ cd tests/
$ phantomjs run-qunit.js tests.html
Failed tests and their failed assertions will be printed to the console. A
results summary will be printed at the end.
To generate coverage statistics, use [JSCoverage](http://siliconforks.com/jscoverage/)
to instrument the js files:
$ cd tests/
$ jscoverage ../js/ ../instrumented/
$ phantomjs run-qunit.js tests.html
Coverage percentage will be included in the output summary, and a highlighted
line-by-line html file will be generated.
# Shout-out
Thanks to Rod @ While One Fork for the
[CIS guide](http://whileonefork.blogspot.com/2011/10/integrating-javascript-tests-into-cli.html)
on putting the above together.
# Adding tests
Tests go in js files in the `tests/suites/` directory tree. QUnit organizes
tests into suites called "modules"; there is one module per js file. If the
tests you are adding do not fit into an existing module, create a new one at
`tests/suites/<new module>.js`, where `<new module>` is a broad yet
descriptive name for the suite. If tests have many year-specific cases (ie,
behave differently in leap years vs normal years, or have specific buggy
behavior in a certain year), create the module in a new directory,
`tests/suites/<new module>/<year>.js`, where `<new module>` is the decriptive
name and `<year>` is the four-digit year the tests pertain to.
In order for new tests to be run, they must be imported into `tests/tests.html`.
Find the script includes headed by the html comment `<!-- Test suites -->`, and
add a new one to the list which includes the new js files.
# Can I use this?
By all means, please do! Just note that I stopped working on this structure
once it fit my needs, there's no real support for it, and it may change in the
future. Otherwise, have at it.

View File

@@ -0,0 +1,26 @@
<!DOCTYPE html>
<html>
<head>
<style>
.code {
white-space: pre-wrap;
font-family: monospace;
width: 100%;
}
.miss {
background-color: #FF0000;
}
.hit, .undef {
background-color: #94FF7C;
}
</style>
</head>
<body>
COLORIZED_LINE_HTML
</body>
</html>

View File

@@ -0,0 +1,48 @@
(function(){
//we want this at global scope so outside callers can find it. In a more realistic implementation we
//should probably put it in a namespace.
window.getCoverageByLine = function(silent) {
var key = null;
var lines = null;
var source = null;
//look for code coverage data
if (typeof window._$jscoverage === 'object') {
for (key in _$jscoverage) {}
lines = _$jscoverage[key];
}
if (!lines && !silent) {
console.log('code coverage data is NOT available');
}
return { 'key': key, 'lines': lines };
};
QUnit.done = function(t) {
var cvgInfo = getCoverageByLine(true);
if (!!cvgInfo.key) {
var testableLines = 0;
var testedLines = 0;
var untestableLines = 0;
for (lineIdx in cvgInfo.lines) {
var cvg = cvgInfo.lines[lineIdx];
if (typeof cvg === 'number') {
testableLines += 1;
if (cvg > 0) {
testedLines += 1;
}
} else {
untestableLines += 1;
}
}
var coverage = '' + Math.floor(100 * testedLines / testableLines) + '%';
var result = document.getElementById('qunit-testresult');
if (result != null) {
result.innerHTML = result.innerHTML + ' ' + coverage + ' test coverage of ' + cvgInfo.key;
} else {
console.log('can\'t find test-result element to update');
}
}
};
}());

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,26 @@
;(function(){
window.patch_date = function patch(f){
var NativeDate = window.Date;
var date = function date(y,m,d,h,i,s,j){
switch(arguments.length){
case 0: return date.now ? new NativeDate(date.now) : new NativeDate();
case 1: return new NativeDate(y);
case 2: return new NativeDate(y,m);
case 3: return new NativeDate(y,m,d);
case 4: return new NativeDate(y,m,d,h);
case 5: return new NativeDate(y,m,d,h,i);
case 6: return new NativeDate(y,m,d,h,i,s);
case 7: return new NativeDate(y,m,d,h,i,s,j);
}
};
date.UTC = NativeDate.UTC;
return function(){
Array.prototype.push.call(arguments, date);
window.Date = date;
res = f.apply(this, arguments);
window.Date = NativeDate;
}
}
}());

View File

@@ -0,0 +1,29 @@
// Dummy logging calls (ie, if tests are run in IE)
window.console = window.console || {};
window.console.log = window.console.log || function(){};
window.console.debug = window.console.debug || function(){};
window.console.info = window.console.info || function(){};
window.console.warn = window.console.warn || function(){};
window.console.error = window.console.error || function(){};
(function() {
var modName, testName;
//arg: { name }
QUnit.testStart = function(t) {
modName = t.module;
testName = t.name;
};
//arg: { name, failed, passed, total }
QUnit.testDone = function(t) {
if (t.failed)
console.log('Test "' + t.module + ': ' + t.name + '" completed: ' + (0 === t.failed ? 'pass' : 'FAIL') + '\n')
};
//{ result, actual, expected, message }
QUnit.log = function(t) {
if (!t.result)
console.log('Test "' + modName + ': ' + testName + '" assertion failed. Expected <' + t.expected + '> Actual <' + t.actual + '>' + (t.message ? ': \'' + t.message + '\'' : ''));
};
}());

View File

@@ -0,0 +1,235 @@
/**
* QUnit v1.5.0 - A JavaScript Unit Testing Framework
*
* http://docs.jquery.com/QUnit
*
* Copyright (c) 2012 John Resig, Jörn Zaefferer
* Dual licensed under the MIT (MIT-LICENSE.txt)
* or GPL (GPL-LICENSE.txt) licenses.
*/
/** Font Family and Sizes */
#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
}
#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
#qunit-tests { font-size: smaller; }
/** Resets */
#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult {
margin: 0;
padding: 0;
}
/** Header */
#qunit-header {
padding: 0.5em 0 0.5em 1em;
color: #8699a4;
background-color: #0d3349;
font-size: 1.5em;
line-height: 1em;
font-weight: normal;
border-radius: 15px 15px 0 0;
-moz-border-radius: 15px 15px 0 0;
-webkit-border-top-right-radius: 15px;
-webkit-border-top-left-radius: 15px;
}
#qunit-header a {
text-decoration: none;
color: #c2ccd1;
}
#qunit-header a:hover,
#qunit-header a:focus {
color: #fff;
}
#qunit-header label {
display: inline-block;
}
#qunit-banner {
height: 5px;
}
#qunit-testrunner-toolbar {
padding: 0.5em 0 0.5em 2em;
color: #5E740B;
background-color: #eee;
}
#qunit-userAgent {
padding: 0.5em 0 0.5em 2.5em;
background-color: #2b81af;
color: #fff;
text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
}
/** Tests: Pass/Fail */
#qunit-tests {
list-style-position: inside;
}
#qunit-tests li {
padding: 0.4em 0.5em 0.4em 2.5em;
border-bottom: 1px solid #fff;
list-style-position: inside;
}
#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running {
display: none;
}
#qunit-tests li strong {
cursor: pointer;
}
#qunit-tests li a {
padding: 0.5em;
color: #c2ccd1;
text-decoration: none;
}
#qunit-tests li a:hover,
#qunit-tests li a:focus {
color: #000;
}
#qunit-tests ol {
margin-top: 0.5em;
padding: 0.5em;
background-color: #fff;
border-radius: 15px;
-moz-border-radius: 15px;
-webkit-border-radius: 15px;
box-shadow: inset 0px 2px 13px #999;
-moz-box-shadow: inset 0px 2px 13px #999;
-webkit-box-shadow: inset 0px 2px 13px #999;
}
#qunit-tests table {
border-collapse: collapse;
margin-top: .2em;
}
#qunit-tests th {
text-align: right;
vertical-align: top;
padding: 0 .5em 0 0;
}
#qunit-tests td {
vertical-align: top;
}
#qunit-tests pre {
margin: 0;
white-space: pre-wrap;
word-wrap: break-word;
}
#qunit-tests del {
background-color: #e0f2be;
color: #374e0c;
text-decoration: none;
}
#qunit-tests ins {
background-color: #ffcaca;
color: #500;
text-decoration: none;
}
/*** Test Counts */
#qunit-tests b.counts { color: black; }
#qunit-tests b.passed { color: #5E740B; }
#qunit-tests b.failed { color: #710909; }
#qunit-tests li li {
margin: 0.5em;
padding: 0.4em 0.5em 0.4em 0.5em;
background-color: #fff;
border-bottom: none;
list-style-position: inside;
}
/*** Passing Styles */
#qunit-tests li li.pass {
color: #5E740B;
background-color: #fff;
border-left: 26px solid #C6E746;
}
#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; }
#qunit-tests .pass .test-name { color: #366097; }
#qunit-tests .pass .test-actual,
#qunit-tests .pass .test-expected { color: #999999; }
#qunit-banner.qunit-pass { background-color: #C6E746; }
/*** Failing Styles */
#qunit-tests li li.fail {
color: #710909;
background-color: #fff;
border-left: 26px solid #EE5757;
white-space: pre;
}
#qunit-tests > li:last-child {
border-radius: 0 0 15px 15px;
-moz-border-radius: 0 0 15px 15px;
-webkit-border-bottom-right-radius: 15px;
-webkit-border-bottom-left-radius: 15px;
}
#qunit-tests .fail { color: #000000; background-color: #EE5757; }
#qunit-tests .fail .test-name,
#qunit-tests .fail .module-name { color: #000000; }
#qunit-tests .fail .test-actual { color: #EE5757; }
#qunit-tests .fail .test-expected { color: green; }
#qunit-banner.qunit-fail { background-color: #EE5757; }
/** Result */
#qunit-testresult {
padding: 0.5em 0.5em 0.5em 2.5em;
color: #2b81af;
background-color: #D2E0E6;
border-bottom: 1px solid white;
}
#qunit-testresult .module-name {
font-weight: bold;
}
/** Fixture */
#qunit-fixture {
position: absolute;
top: -10000px;
left: -10000px;
width: 1000px;
height: 1000px;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,21 @@
function UTCDate(){
return new Date(Date.UTC.apply(Date, arguments));
}
function format_date(date){
var y = date.getUTCFullYear(),
m = date.getUTCMonth() + 1,
d = date.getUTCDate(),
h = date.getUTCHours(),
i = date.getUTCMinutes(),
s = date.getUTCSeconds(),
l = date.getUTCMilliseconds();
function z(i){return (i <= 9 ? '0'+i : i);}
return y+'-'+z(m)+'-'+z(d)+' '+z(h)+':'+z(i)+':'+z(s)+'.'+z(l);
}
function datesEqual(actual, expected, message){
QUnit.push(QUnit.equiv(actual, expected), format_date(actual), format_date(expected), message);
}

View File

@@ -0,0 +1,157 @@
var system = require('system');
/**
* Wait until the test condition is true or a timeout occurs. Useful for waiting
* on a server response or for a ui change (fadeIn, etc.) to occur.
*
* @param testFx javascript condition that evaluates to a boolean,
* it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or
* as a callback function.
* @param onReady what to do when testFx condition is fulfilled,
* it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or
* as a callback function.
* @param timeOutMillis the max amount of time to wait. If not specified, 3 sec is used.
*/
function waitFor(testFx, onReady, timeOutMillis) {
var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 10001, //< Default Max Timout is 3s
start = new Date().getTime(),
condition = false,
interval = setInterval(function() {
if ( (new Date().getTime() - start < maxtimeOutMillis) && !condition ) {
// If not time-out yet and condition not yet fulfilled
condition = (typeof(testFx) === "string" ? eval(testFx) : testFx()); //< defensive code
} else {
if(!condition) {
// If condition still not fulfilled (timeout but condition is 'false')
console.log("'waitFor()' timeout");
phantom.exit(1);
} else {
// Condition fulfilled (timeout and/or condition is 'true')
//console.log("'waitFor()' finished in " + (new Date().getTime() - start) + "ms.");
typeof(onReady) === "string" ? eval(onReady) : onReady(); //< Do what it's supposed to do once the condition is fulfilled
clearInterval(interval); //< Stop this interval
}
}
}, 100); //< repeat check every 100ms
};
if (system.args.length !== 2) {
console.log('Usage: run-qunit.js URL');
phantom.exit(1);
}
var fs = require('fs');
var page = require('webpage').create();
// Route "console.log()" calls from within the Page context to the main Phantom context (i.e. current "this")
page.onConsoleMessage = function(msg) {
console.log(msg);
};
page.onError = function (msg, trace) {
console.log(msg);
trace.forEach(function(item) {
console.log(' ', item.file, ':', item.line);
})
}
var _openPath = phantom.args[0].replace(/^.*(\\|\/)/, '');
var openPath = _openPath;
var origdir = '../js/';
var basedir = '../instrumented/';
var coverageBase = fs.read('_coverage.html');
if (fs.exists(basedir)){
var script = /<script.*><\/script>/g,
src = /src=(["'])(.*?)\1/,
contents = fs.read(openPath),
_contents = contents,
srcs = [],
s;
while (script.exec(contents)){
s = src.exec(RegExp.lastMatch)[2];
if (s && s.indexOf(origdir) != -1)
_contents = _contents.replace(s, s.replace(origdir, basedir))
}
if (_contents != contents){
openPath += '.cov.html';
fs.write(openPath, _contents);
}
}
page.open(openPath, function(status){
if (status !== "success") {
console.log("Unable to access network");
phantom.exit(1);
} else {
// Inject instrumented sources if they exist
if (fs.exists(basedir))
for (var i=0; i<srcs.length; i++)
page.includeJs(srcs[i]);
waitFor(function(){
return page.evaluate(function(){
var el = document.getElementById('qunit-testresult');
if (el && el.innerText.match('completed')) {
return true;
}
return false;
});
}, function(){
// output colorized code coverage
// reach into page context and pull out coverage info. stringify to pass context boundaries.
var coverageInfo = JSON.parse(page.evaluate(function() { return JSON.stringify(getCoverageByLine()); }));
if (coverageInfo.key){
var lineCoverage = coverageInfo.lines;
var originalFile = origdir + fs.separator + coverageInfo.key;
var source = coverageInfo.source;
var fileLines = readFileLines(originalFile);
var colorized = '';
for (var idx=0; idx < lineCoverage.length; idx++) {
//+1: coverage lines count from 1.
var cvg = lineCoverage[idx + 1];
var hitmiss = '';
if (typeof cvg === 'number') {
hitmiss = ' ' + (cvg>0 ? 'hit' : 'miss');
} else {
hitmiss = ' ' + 'undef';
}
var htmlLine = fileLines[idx]
if (!source)
htmlLine = htmlLine.replace('<', '&lt;').replace('>', '&gt;');
colorized += '<div class="code' + hitmiss + '">' + htmlLine + '</div>\n';
};
colorized = coverageBase.replace('COLORIZED_LINE_HTML', colorized);
fs.write('coverage.html', colorized, 'w');
console.log('Coverage for ' + coverageInfo.key + ' in coverage.html');
}
if (_openPath != openPath)
fs.remove(openPath);
var failedNum = page.evaluate(function(){
var el = document.getElementById('qunit-testresult');
console.log(el.innerText);
try {
return el.getElementsByClassName('failed')[0].innerHTML;
} catch (e) { }
return 10000;
});
phantom.exit((parseInt(failedNum, 10) > 0) ? 1 : 0);
});
}
});
function readFileLines(filename) {
var stream = fs.open(filename, 'r');
var lines = [];
var line;
while (!stream.atEnd()) {
lines.push(stream.readLine());
}
stream.close();
return lines;
}

View File

@@ -0,0 +1,179 @@
module('Component', {
setup: function(){
this.component = $('<div class="input-group date" id="datetimepicker">'+
'<input size="16" type="text" value="12-02-2012" readonly>'+
'<span class="input-group-addon"><span class="glyphicon glyphicon-th"></span></span>'+
'</div>')
.appendTo('#qunit-fixture')
.datetimepicker({format: "dd-mm-yyyy", viewSelect: 2});
this.input = this.component.find('input');
this.addon = this.component.find('.input-group-addon');
this.dp = this.component.data('datetimepicker');
this.picker = this.dp.picker;
},
teardown: function(){
this.picker.remove();
}
});
test('Component gets date/viewDate from input value', function(){
datesEqual(this.dp.date, UTCDate(2012, 1, 12));
datesEqual(this.dp.viewDate, UTCDate(2012, 1, 12));
});
test('Activation by component', function(){
ok(!this.picker.is(':visible'));
this.addon.click();
ok(this.picker.is(':visible'));
});
test('simple keyboard nav test', function(){
var target;
// Keyboard nav only works with non-readonly inputs
this.input.removeAttr('readonly');
equal(this.dp.viewMode, 2);
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'February 2012', 'Title is "February 2012"');
datesEqual(this.dp.date, UTCDate(2012, 1, 12));
datesEqual(this.dp.viewDate, UTCDate(2012, 1, 12));
// Focus/open
this.addon.click();
// Navigation: -1 day, left arrow key
this.input.trigger({
type: 'keydown',
keyCode: 37
});
datesEqual(this.dp.viewDate, UTCDate(2012, 1, 11));
datesEqual(this.dp.date, UTCDate(2012, 1, 11));
// Month not changed
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'February 2012', 'Title is "February 2012"');
// Navigation: +1 month, shift + right arrow key
this.input.trigger({
type: 'keydown',
keyCode: 39,
shiftKey: true
});
datesEqual(this.dp.viewDate, UTCDate(2012, 2, 11));
datesEqual(this.dp.date, UTCDate(2012, 2, 11));
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'March 2012', 'Title is "March 2012"');
// Navigation: -1 year, ctrl + left arrow key
this.input.trigger({
type: 'keydown',
keyCode: 37,
ctrlKey: true
});
datesEqual(this.dp.viewDate, UTCDate(2011, 2, 11));
datesEqual(this.dp.date, UTCDate(2011, 2, 11));
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'March 2011', 'Title is "March 2011"');
});
test('setValue', function(){
this.dp.date = UTCDate(2012, 2, 13)
this.dp.setValue()
datesEqual(this.dp.date, UTCDate(2012, 2, 13));
equal(this.input.val(), '13-03-2012');
});
test('update', function(){
this.input.val('13-03-2012');
this.dp.update()
datesEqual(this.dp.date, UTCDate(2012, 2, 13));
});
test('Navigating to/from decade view', function(){
var target;
this.addon.click();
this.input.val('31-03-2012');
this.dp.update();
equal(this.dp.viewMode, 2);
target = this.picker.find('.datetimepicker-days thead th.switch');
ok(target.is(':visible'), 'View switcher is visible');
target.click();
ok(this.picker.find('.datetimepicker-months').is(':visible'), 'Month picker is visible');
equal(this.dp.viewMode, 3);
// Not modified when switching modes
datesEqual(this.dp.viewDate, UTCDate(2012, 2, 31));
datesEqual(this.dp.date, UTCDate(2012, 2, 31));
target = this.picker.find('.datetimepicker-months thead th.switch');
ok(target.is(':visible'), 'View switcher is visible');
target.click();
ok(this.picker.find('.datetimepicker-years').is(':visible'), 'Year picker is visible');
equal(this.dp.viewMode, 4);
// Not modified when switching modes
datesEqual(this.dp.viewDate, UTCDate(2012, 2, 31));
datesEqual(this.dp.date, UTCDate(2012, 2, 31));
// Change years to test internal state changes
target = this.picker.find('.datetimepicker-years tbody span:contains(2011)');
target.click();
equal(this.dp.viewMode, 3);
// Only viewDate modified
datesEqual(this.dp.viewDate, UTCDate(2011, 2, 1));
datesEqual(this.dp.date, UTCDate(2012, 2, 31));
target = this.picker.find('.datetimepicker-months tbody span:contains(Apr)');
target.click();
equal(this.dp.viewMode, 2);
// Only viewDate modified
datesEqual(this.dp.viewDate, UTCDate(2011, 3, 1));
datesEqual(this.dp.date, UTCDate(2012, 2, 31));
});
test('Selecting date resets viewDate and date', function(){
var target;
this.addon.click();
this.input.val('31-03-2012');
this.dp.update();
// Rendered correctly
equal(this.dp.viewMode, 2);
target = this.picker.find('.datetimepicker-days tbody td:first');
equal(target.text(), '26'); // Should be Feb 26
// Updated internally on click
target.click();
datesEqual(this.dp.viewDate, UTCDate(2012, 1, 26))
datesEqual(this.dp.date, UTCDate(2012, 1, 26))
// Re-rendered on click
target = this.picker.find('.datetimepicker-days tbody td:first');
equal(target.text(), '29'); // Should be Jan 29
});
test('Highlight in month', function() {
// custom setup for specifically bootstrap 2
var component = $('<div class="input-group date" id="datetimepicker">' +
'<input size="16" type="text" value="12-02-2012" readonly>' +
'<span class="input-group-addon"><span class="glyphicon glyphicon-th"></span></span>' +
'</div>')
.appendTo('#qunit-fixture')
.datetimepicker({format: "dd-mm-yyyy", bootcssVer: 2}),
addon = component.find('.input-group-addon'),
picker = component.data('datetimepicker').picker;
addon.click();
equal(picker.find('.datetimepicker-months .month.active').text(), 'Feb');
picker.remove();
// test bootstrap 3 as well
this.addon.click();
equal(this.picker.find('.datetimepicker-months .month.active').text(), 'Feb');
});

View File

@@ -0,0 +1,80 @@
module('Events', {
setup: function(){
this.input = $('<input type="text" value="31-03-2011">')
.appendTo('#qunit-fixture')
.datetimepicker({format: "dd-mm-yyyy"})
.focus(); // Activate for visibility checks
this.dp = this.input.data('datetimepicker')
this.picker = this.dp.picker;
},
teardown: function(){
this.picker.remove();
}
});
test('Selecting a year from decade view triggers pickYear', function(){
var target,
triggered = 0;
this.input.on('changeYear', function(){
triggered++;
});
equal(this.dp.viewMode, 2);
target = this.picker.find('.datetimepicker-days thead th.switch');
ok(target.is(':visible'), 'View switcher is visible');
target.click();
ok(this.picker.find('.datetimepicker-months').is(':visible'), 'Month picker is visible');
equal(this.dp.viewMode, 3);
// Not modified when switching modes
datesEqual(this.dp.viewDate, UTCDate(2011, 2, 31));
datesEqual(this.dp.date, UTCDate(2011, 2, 31));
target = this.picker.find('.datetimepicker-months thead th.switch');
ok(target.is(':visible'), 'View switcher is visible');
target.click();
ok(this.picker.find('.datetimepicker-years').is(':visible'), 'Year picker is visible');
equal(this.dp.viewMode, 4);
// Not modified when switching modes
datesEqual(this.dp.viewDate, UTCDate(2011, 2, 31));
datesEqual(this.dp.date, UTCDate(2011, 2, 31));
// Change years to test internal state changes
target = this.picker.find('.datetimepicker-years tbody span:contains(2010)');
target.click();
equal(this.dp.viewMode, 3);
// Only viewDate modified
datesEqual(this.dp.viewDate, UTCDate(2010, 2, 1));
datesEqual(this.dp.date, UTCDate(2011, 2, 31));
equal(triggered, 1);
});
test('Selecting a month from year view triggers pickMonth', function(){
var target,
triggered = 0;
this.input.on('changeMonth', function(){
triggered++;
});
equal(this.dp.viewMode, 2);
target = this.picker.find('.datetimepicker-days thead th.switch');
ok(target.is(':visible'), 'View switcher is visible');
target.click();
ok(this.picker.find('.datetimepicker-months').is(':visible'), 'Month picker is visible');
equal(this.dp.viewMode, 3);
// Not modified when switching modes
datesEqual(this.dp.viewDate, UTCDate(2011, 2, 31));
datesEqual(this.dp.date, UTCDate(2011, 2, 31));
target = this.picker.find('.datetimepicker-months tbody span:contains(Apr)');
target.click();
equal(this.dp.viewMode, 2);
// Only viewDate modified
datesEqual(this.dp.viewDate, UTCDate(2011, 3, 1));
datesEqual(this.dp.date, UTCDate(2011, 2, 31));
equal(triggered, 1);
});

View File

@@ -0,0 +1,256 @@
module('Formats', {
setup: function(){
this.input = $('<input type="text">').appendTo('#qunit-fixture');
this.date = UTCDate(2012, 2, 15, 0, 0, 0, 0); // March 15, 2012
},
teardown: function(){
this.input.data('datetimepicker').picker.remove();
}
});
test('d: Day of month, no leading zero.', function(){
this.input
.val('2012-03-05')
.datetimepicker({format: 'yyyy-mm-d'})
.datetimepicker('setValue');
equal(this.input.val().split('-')[2], '5');
});
test('dd: Day of month, leading zero.', function(){
this.input
.val('2012-03-5')
.datetimepicker({format: 'yyyy-mm-dd'})
.datetimepicker('setValue');
equal(this.input.val().split('-')[2], '05');
});
test('m: Month, no leading zero.', function(){
this.input
.val('2012-03-05')
.datetimepicker({format: 'yyyy-m-dd'})
.datetimepicker('setValue');
equal(this.input.val().split('-')[1], '3');
});
test('mm: Month, leading zero.', function(){
this.input
.val('2012-3-5')
.datetimepicker({format: 'yyyy-mm-dd'})
.datetimepicker('setValue');
equal(this.input.val().split('-')[1], '03');
});
test('M: Month shortname.', function(){
this.input
.val('2012-Mar-05')
.datetimepicker({format: 'yyyy-M-dd'})
.datetimepicker('setValue');
equal(this.input.val().split('-')[1], 'Mar');
});
test('MM: Month full name.', function(){
this.input
.val('2012-March-5')
.datetimepicker({format: 'yyyy-MM-dd'})
.datetimepicker('setValue');
equal(this.input.val().split('-')[1], 'March');
});
test('yy: Year, two-digit.', function(){
this.input
.val('2012-03-05')
.datetimepicker({format: 'yy-mm-dd'})
.datetimepicker('setValue');
equal(this.input.val().split('-')[0], '12');
});
test('yyyy: Year, four-digit.', function(){
this.input
.val('2012-03-5')
.datetimepicker({format: 'yyyy-mm-dd'})
.datetimepicker('setValue');
equal(this.input.val().split('-')[0], '2012');
});
test('H: 12 hour when language has meridiems', function(){
this.input
.val('2012-March-5 16:00:00')
.datetimepicker({format: 'yyyy-mm-dd H:ii p'})
.datetimepicker('setValue');
ok(this.input.val().match(/4:00 pm/));
});
test('H: 24 hour when language has no meridiems', function(){
$.fn.datetimepicker.dates['pt-BR'] = {
days: ["Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado", "Domingo"],
daysShort: ["Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb", "Dom"],
daysMin: ["Do", "Se", "Te", "Qu", "Qu", "Se", "Sa", "Do"],
months: ["Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"],
monthsShort: ["Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez"],
today: "Hoje",
suffix: [],
meridiem: []
};
this.input
.val('2012-March-5 16:00:00')
.datetimepicker({format: 'yyyy-mm-dd H:ii p', language: 'pt-BR'})
.datetimepicker('setValue');
ok(this.input.val().match(/16:00/));
});
test('dd-mm-yyyy: Regression: Prevent potential month overflow in small-to-large formats (Mar 31, 2012 -> Mar 01, 2012)', function(){
this.input
.val('31-03-2012')
.datetimepicker({format: 'dd-mm-yyyy'})
.datetimepicker('setValue');
equal(this.input.val(), '31-03-2012');
});
test('dd-mm-yyyy: Leap day', function(){
this.input
.val('29-02-2012')
.datetimepicker({format: 'dd-mm-yyyy'})
.datetimepicker('setValue');
equal(this.input.val(), '29-02-2012');
});
test('yyyy-mm-dd: Alternative format', function(){
this.input
.val('2012-02-12')
.datetimepicker({format: 'yyyy-mm-dd'})
.datetimepicker('setValue');
equal(this.input.val(), '2012-02-12');
});
test('yyyy-MM-dd: Regression: Infinite loop when numbers used for month', function(){
this.input
.val('2012-02-12')
.datetimepicker({format: 'yyyy-MM-dd'})
.datetimepicker('setValue');
equal(this.input.val(), '2012-February-12');
});
test('+1d: Tomorrow', patch_date(function(Date){
Date.now = UTCDate(2012, 2, 15);
this.input
.val('+1d')
.datetimepicker({format: 'dd-mm-yyyy'})
.datetimepicker('setValue');
equal(this.input.val(), '16-03-2012');
}));
test('-1d: Yesterday', patch_date(function(Date){
Date.now = UTCDate(2012, 2, 15);
this.input
.val('-1d')
.datetimepicker({format: 'dd-mm-yyyy'})
.datetimepicker('setValue');
equal(this.input.val(), '14-03-2012');
}));
test('+1w: Next week', patch_date(function(Date){
Date.now = UTCDate(2012, 2, 15);
this.input
.val('+1w')
.datetimepicker({format: 'dd-mm-yyyy'})
.datetimepicker('setValue');
equal(this.input.val(), '22-03-2012');
}));
test('-1w: Last week', patch_date(function(Date){
Date.now = UTCDate(2012, 2, 15);
this.input
.val('-1w')
.datetimepicker({format: 'dd-mm-yyyy'})
.datetimepicker('setValue');
equal(this.input.val(), '08-03-2012');
}));
test('+1m: Next month', patch_date(function(Date){
Date.now = UTCDate(2012, 2, 15);
this.input
.val('+1m')
.datetimepicker({format: 'dd-mm-yyyy'})
.datetimepicker('setValue');
equal(this.input.val(), '15-04-2012');
}));
test('-1m: Last month', patch_date(function(Date){
Date.now = UTCDate(2012, 2, 15);
this.input
.val('-1m')
.datetimepicker({format: 'dd-mm-yyyy'})
.datetimepicker('setValue');
equal(this.input.val(), '15-02-2012');
}));
test('+1y: Next year', patch_date(function(Date){
Date.now = UTCDate(2012, 2, 15);
this.input
.val('+1y')
.datetimepicker({format: 'dd-mm-yyyy'})
.datetimepicker('setValue');
equal(this.input.val(), '15-03-2013');
}));
test('-1y: Last year', patch_date(function(Date){
Date.now = UTCDate(2012, 2, 15);
this.input
.val('-1y')
.datetimepicker({format: 'dd-mm-yyyy'})
.datetimepicker('setValue');
equal(this.input.val(), '15-03-2011');
}));
test('-1y +2m: Multiformat', patch_date(function(Date){
Date.now = UTCDate(2012, 2, 15);
this.input
.val('-1y +2m')
.datetimepicker({format: 'dd-mm-yyyy'})
.datetimepicker('setValue');
equal(this.input.val(), '15-05-2011');
}));
test('Regression: End-of-month bug', patch_date(function(Date){
Date.now = UTCDate(2012, 4, 31);
this.input
.val('29-02-2012')
.datetimepicker({format: 'dd-mm-yyyy'})
.datetimepicker('setValue');
equal(this.input.val(), '29-02-2012');
}));
test('Invalid formats are force-parsed into a valid date on tab', patch_date(function(Date){
Date.now = UTCDate(2012, 4, 31);
this.input
.val('44-44-4444')
.datetimepicker({format: 'yyyy-MM-dd'})
.focus();
this.input.trigger({
type: 'keydown',
keyCode: 9
});
equal(this.input.val(), '56-September-30');
}));
test('Untrimmed datetime value', patch_date(function(Date){
this.input
.val('2012-03-05 ')
.datetimepicker({format: 'yyyy-mm-dd hh:ii'})
.datetimepicker('setValue');
equal(this.input.val(), '2012-03-05 00:00');
}));
test('With timezone option', patch_date(function(Date){
this.input
.val('2012-03-05')
.datetimepicker({format: 'yyyy-mm-dd hh:ii P Z'})
.datetimepicker('setValue');
equal(this.input.val(), '2012-03-05 00:00 AM UTC');
}));

View File

@@ -0,0 +1,28 @@
module('Inline', {
setup: function(){
this.component = $('<div data-date="12-02-2012"></div>')
.appendTo('#qunit-fixture')
.datetimepicker({format: "dd-mm-yyyy"});
this.dp = this.component.data('datetimepicker')
this.picker = this.dp.picker;
},
teardown: function(){
this.picker.remove();
}
});
test('Picker gets date/viewDate from data-date attr', function(){
datesEqual(this.dp.date, UTCDate(2012, 1, 12));
datesEqual(this.dp.viewDate, UTCDate(2012, 1, 12));
});
test('Visible after init', function(){
ok(this.picker.is(':visible'));
});
test('update', function(){
this.dp.update('13-03-2012')
datesEqual(this.dp.date, UTCDate(2012, 2, 13));
});

View File

@@ -0,0 +1,86 @@
module('Keyboard Navigation 2011', {
setup: function(){
/*
Tests start with picker on March 31, 2011. Fun facts:
* March 1, 2011 was on a Tuesday
* March 31, 2011 was on a Thursday
*/
this.input = $('<input type="text" value="31-03-2011">')
.appendTo('#qunit-fixture')
.datetimepicker({format: "dd-mm-yyyy"})
.focus(); // Activate for visibility checks
this.dp = this.input.data('datetimepicker')
this.picker = this.dp.picker;
},
teardown: function(){
this.picker.remove();
}
});
test('Regression: by week (up/down arrows); up from Mar 6, 2011 should go to Feb 27, 2011', function(){
var target;
this.input.val('06-03-2011').datetimepicker('update');
equal(this.dp.viewMode, 2);
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'March 2011', 'Title is "March 2011"');
datesEqual(this.dp.viewDate, UTCDate(2011, 2, 6));
datesEqual(this.dp.date, UTCDate(2011, 2, 6));
// Navigation: -1 week, up arrow key
this.input.trigger({
type: 'keydown',
keyCode: 38
});
datesEqual(this.dp.viewDate, UTCDate(2011, 1, 27));
datesEqual(this.dp.date, UTCDate(2011, 1, 27));
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'February 2011', 'Title is "February 2011"');
});
test('Regression: by day (left/right arrows); left from Mar 1, 2011 should go to Feb 28, 2011', function(){
var target;
this.input.val('01-03-2011').datetimepicker('update');
equal(this.dp.viewMode, 2);
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'March 2011', 'Title is "March 2011"');
datesEqual(this.dp.viewDate, UTCDate(2011, 2, 1));
datesEqual(this.dp.date, UTCDate(2011, 2, 1));
// Navigation: -1 day left arrow key
this.input.trigger({
type: 'keydown',
keyCode: 37
});
datesEqual(this.dp.viewDate, UTCDate(2011, 1, 28));
datesEqual(this.dp.date, UTCDate(2011, 1, 28));
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'February 2011', 'Title is "February 2011"');
});
test('Regression: by month (shift + left/right arrows); left from Mar 15, 2011 should go to Feb 15, 2011', function(){
var target;
this.input.val('15-03-2011').datetimepicker('update');
equal(this.dp.viewMode, 2);
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'March 2011', 'Title is "March 2011"');
datesEqual(this.dp.viewDate, UTCDate(2011, 2, 15));
datesEqual(this.dp.date, UTCDate(2011, 2, 15));
// Navigation: -1 month, shift + left arrow key
this.input.trigger({
type: 'keydown',
keyCode: 37,
shiftKey: true
});
datesEqual(this.dp.viewDate, UTCDate(2011, 1, 15));
datesEqual(this.dp.date, UTCDate(2011, 1, 15));
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'February 2011', 'Title is "February 2011"');
});

View File

@@ -0,0 +1,410 @@
module('Keyboard Navigation 2012', {
setup: function(){
/*
Tests start with picker on March 31, 2012. Fun facts:
* February 1, 2012 was on a Wednesday
* February 29, 2012 was on a Wednesday
* March 1, 2012 was on a Thursday
* March 31, 2012 was on a Saturday
*/
this.input = $('<input type="text" value="31-03-2012">')
.appendTo('#qunit-fixture')
.datetimepicker({format: "dd-mm-yyyy", minView: 2, autoclose: true})
.focus(); // Activate for visibility checks
this.dp = this.input.data('datetimepicker')
this.picker = this.dp.picker;
},
teardown: function(){
this.picker.remove();
}
});
test('by day (right/left arrows)', function(){
var target;
equal(this.dp.viewMode, 2);
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'March 2012', 'Title is "March 2012"');
// Navigation: -1 day, left arrow key
this.input.trigger({
type: 'keydown',
keyCode: 37
});
// Both updated on keyboard navigation
datesEqual(this.dp.viewDate, UTCDate(2012, 2, 30));
datesEqual(this.dp.date, UTCDate(2012, 2, 30));
// Month not changed
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'March 2012', 'Title is "March 2012"');
// Navigation: +1 day, right arrow key
for (var i=0; i<2; i++)
this.input.trigger({
type: 'keydown',
keyCode: 39
});
datesEqual(this.dp.viewDate, UTCDate(2012, 3, 1));
datesEqual(this.dp.date, UTCDate(2012, 3, 1));
// Month changed: April 1 (this is not a joke!)
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'April 2012', 'Title is "April 2012"');
});
test('by week (up/down arrows)', function(){
var target;
equal(this.dp.viewMode, 2);
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'March 2012', 'Title is "March 2012"');
// Navigation: -1 week, up arrow key
this.input.trigger({
type: 'keydown',
keyCode: 38
});
// Both updated on keyboard navigation
datesEqual(this.dp.viewDate, UTCDate(2012, 2, 24));
datesEqual(this.dp.date, UTCDate(2012, 2, 24));
// Month not changed
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'March 2012', 'Title is "March 2012"');
// Navigation: +1 week, down arrow key
for (var i=0; i<2; i++)
this.input.trigger({
type: 'keydown',
keyCode: 40
});
datesEqual(this.dp.viewDate, UTCDate(2012, 3, 7));
datesEqual(this.dp.date, UTCDate(2012, 3, 7));
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'April 2012', 'Title is "April 2012"');
});
test('by month, v1 (shift + left/right arrows)', function(){
var target;
equal(this.dp.viewMode, 2);
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'March 2012', 'Title is "March 2012"');
// Navigation: -1 month, shift + left arrow key
this.input.trigger({
type: 'keydown',
keyCode: 37,
shiftKey: true
});
// Both updated on keyboard navigation, w/ graceful date ends
datesEqual(this.dp.viewDate, UTCDate(2012, 1, 29));
datesEqual(this.dp.date, UTCDate(2012, 1, 29));
// Month not changed
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'February 2012', 'Title is "February 2012"');
// Navigation: +1 month, shift + right arrow key
for (var i=0; i<2; i++)
this.input.trigger({
type: 'keydown',
keyCode: 39,
shiftKey: true
});
datesEqual(this.dp.viewDate, UTCDate(2012, 3, 29));
datesEqual(this.dp.date, UTCDate(2012, 3, 29));
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'April 2012', 'Title is "April 2012"');
});
test('by month, v2 (shift + up/down arrows)', function(){
var target;
equal(this.dp.viewMode, 2);
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'March 2012', 'Title is "March 2012"');
// Navigation: -1 month, shift + up arrow key
this.input.trigger({
type: 'keydown',
keyCode: 38,
shiftKey: true
});
// Both updated on keyboard navigation, w/ graceful date ends
datesEqual(this.dp.viewDate, UTCDate(2012, 1, 29));
datesEqual(this.dp.date, UTCDate(2012, 1, 29));
// Month not changed
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'February 2012', 'Title is "February 2012"');
// Navigation: +1 month, shift + down arrow key
for (var i=0; i<2; i++)
this.input.trigger({
type: 'keydown',
keyCode: 40,
shiftKey: true
});
datesEqual(this.dp.viewDate, UTCDate(2012, 3, 29));
datesEqual(this.dp.date, UTCDate(2012, 3, 29));
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'April 2012', 'Title is "April 2012"');
});
test('by year, v1 (ctrl + left/right arrows)', function(){
var target;
equal(this.dp.viewMode, 2);
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'March 2012', 'Title is "March 2012"');
// Navigation: -1 year, ctrl + left arrow key
this.input.trigger({
type: 'keydown',
keyCode: 37,
ctrlKey: true
});
// Both updated on keyboard navigation
datesEqual(this.dp.viewDate, UTCDate(2011, 2, 31));
datesEqual(this.dp.date, UTCDate(2011, 2, 31));
// Month not changed
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'March 2011', 'Title is "March 2011"');
// Navigation: +1 year, ctrl + right arrow key
for (var i=0; i<2; i++)
this.input.trigger({
type: 'keydown',
keyCode: 39,
ctrlKey: true
});
datesEqual(this.dp.viewDate, UTCDate(2013, 2, 31));
datesEqual(this.dp.date, UTCDate(2013, 2, 31));
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'March 2013', 'Title is "March 2013"');
});
test('by year, v2 (ctrl + up/down arrows)', function(){
var target;
equal(this.dp.viewMode, 2);
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'March 2012', 'Title is "March 2012"');
// Navigation: -1 year, ctrl + up arrow key
this.input.trigger({
type: 'keydown',
keyCode: 38,
ctrlKey: true
});
// Both updated on keyboard navigation
datesEqual(this.dp.viewDate, UTCDate(2011, 2, 31));
datesEqual(this.dp.date, UTCDate(2011, 2, 31));
// Month not changed
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'March 2011', 'Title is "March 2011"');
// Navigation: +1 year, ctrl + down arrow key
for (var i=0; i<2; i++)
this.input.trigger({
type: 'keydown',
keyCode: 40,
ctrlKey: true
});
datesEqual(this.dp.viewDate, UTCDate(2013, 2, 31));
datesEqual(this.dp.date, UTCDate(2013, 2, 31));
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'March 2013', 'Title is "March 2013"');
});
test('by year, v3 (ctrl + shift + left/right arrows)', function(){
var target;
equal(this.dp.viewMode, 2);
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'March 2012', 'Title is "March 2012"');
// Navigation: -1 year, ctrl + left arrow key
this.input.trigger({
type: 'keydown',
keyCode: 37,
ctrlKey: true,
shiftKey: true
});
// Both updated on keyboard navigation
datesEqual(this.dp.viewDate, UTCDate(2011, 2, 31));
datesEqual(this.dp.date, UTCDate(2011, 2, 31));
// Month not changed
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'March 2011', 'Title is "March 2011"');
// Navigation: +1 year, ctrl + right arrow key
for (var i=0; i<2; i++)
this.input.trigger({
type: 'keydown',
keyCode: 39,
ctrlKey: true,
shiftKey: true
});
datesEqual(this.dp.viewDate, UTCDate(2013, 2, 31));
datesEqual(this.dp.date, UTCDate(2013, 2, 31));
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'March 2013', 'Title is "March 2013"');
});
test('by year, v4 (ctrl + shift + up/down arrows)', function(){
var target;
equal(this.dp.viewMode, 2);
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'March 2012', 'Title is "March 2012"');
// Navigation: -1 year, ctrl + up arrow key
this.input.trigger({
type: 'keydown',
keyCode: 38,
ctrlKey: true,
shiftKey: true
});
// Both updated on keyboard navigation
datesEqual(this.dp.viewDate, UTCDate(2011, 2, 31));
datesEqual(this.dp.date, UTCDate(2011, 2, 31));
// Month not changed
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'March 2011', 'Title is "March 2011"');
// Navigation: +1 year, ctrl + down arrow key
for (var i=0; i<2; i++)
this.input.trigger({
type: 'keydown',
keyCode: 40,
ctrlKey: true,
shiftKey: true
});
datesEqual(this.dp.viewDate, UTCDate(2013, 2, 31));
datesEqual(this.dp.date, UTCDate(2013, 2, 31));
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'March 2013', 'Title is "March 2013"');
});
test('by year, from leap day', function(){
var target;
equal(this.dp.viewMode, 2);
target = this.picker.find('.datetimepicker-days thead th.switch');
this.input.val('29-02-2012').datetimepicker('update');
datesEqual(this.dp.viewDate, UTCDate(2012, 1, 29));
datesEqual(this.dp.date, UTCDate(2012, 1, 29));
equal(target.text(), 'February 2012', 'Title is "February 2012"');
// Navigation: -1 year
this.input.trigger({
type: 'keydown',
keyCode: 37,
ctrlKey: true
});
// Both updated on keyboard navigation; graceful month-end
datesEqual(this.dp.viewDate, UTCDate(2011, 1, 28));
datesEqual(this.dp.date, UTCDate(2011, 1, 28));
// Month not changed
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'February 2011', 'Title is "February 2011"');
// Navigation: +1 year, back to leap year
this.input.trigger({
type: 'keydown',
keyCode: 39,
ctrlKey: true
});
// Both updated on keyboard navigation; graceful month-end
datesEqual(this.dp.viewDate, UTCDate(2012, 1, 28));
datesEqual(this.dp.date, UTCDate(2012, 1, 28));
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'February 2012', 'Title is "February 2012"');
// Navigation: +1 year
this.input.trigger({
type: 'keydown',
keyCode: 39,
ctrlKey: true
});
// Both updated on keyboard navigation; graceful month-end
datesEqual(this.dp.viewDate, UTCDate(2013, 1, 28));
datesEqual(this.dp.date, UTCDate(2013, 1, 28));
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'February 2013', 'Title is "February 2013"');
});
test('Selection (enter)', function(){
var target;
equal(this.dp.viewMode, 2);
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'March 2012', 'Title is "March 2012"');
// Navigation: -1 day, left arrow key
this.input.trigger({
type: 'keydown',
keyCode: 37
});
// Both updated on keyboard navigation
datesEqual(this.dp.viewDate, UTCDate(2012, 2, 30));
datesEqual(this.dp.date, UTCDate(2012, 2, 30));
// Month not changed
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'March 2012', 'Title is "March 2012"');
// Selection: Enter
this.input.trigger({
type: 'keydown',
keyCode: 13
});
// Both updated on keyboard navigation
datesEqual(this.dp.viewDate, UTCDate(2012, 2, 30));
datesEqual(this.dp.date, UTCDate(2012, 2, 30));
// Month not changed
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'March 2012', 'Title is "March 2012"');
ok(this.picker.is(':not(:visible)'), 'Picker is hidden');
});
test('Toggle hide/show (escape); navigation while hidden is suppressed', function(){
var target;
equal(this.dp.viewMode, 2);
target = this.picker.find('.datetimepicker-days thead th.switch');
equal(target.text(), 'March 2012', 'Title is "March 2012"');
ok(this.picker.is(':visible'), 'Picker is visible');
// Hide
this.input.trigger({
type: 'keydown',
keyCode: 27
});
ok(this.picker.is(':not(:visible)'), 'Picker is hidden');
datesEqual(this.dp.viewDate, UTCDate(2012, 2, 31));
datesEqual(this.dp.date, UTCDate(2012, 2, 31));
// left arrow key, *doesn't* navigate
this.input.trigger({
type: 'keydown',
keyCode: 37
});
datesEqual(this.dp.viewDate, UTCDate(2012, 2, 31));
datesEqual(this.dp.date, UTCDate(2012, 2, 31));
// Show
this.input.trigger({
type: 'keydown',
keyCode: 27
});
ok(this.picker.is(':visible'), 'Picker is visible');
datesEqual(this.dp.viewDate, UTCDate(2012, 2, 31));
datesEqual(this.dp.date, UTCDate(2012, 2, 31));
});

View File

@@ -0,0 +1,26 @@
module('Keyboard Navigation (All)', {
setup: function(){
this.input = $('<input type="text">')
.appendTo('#qunit-fixture')
.datetimepicker({format: "dd-mm-yyyy"})
.focus(); // Activate for visibility checks
this.dp = this.input.data('datetimepicker')
this.picker = this.dp.picker;
},
teardown: function(){
this.picker.remove();
}
});
test('TAB hides picker', function(){
var target;
ok(this.picker.is(':visible'), 'Picker is visible');
this.input.trigger({
type: 'keydown',
keyCode: 9
});
ok(this.picker.is(':not(:visible)'), 'Picker is hidden');
});

View File

@@ -0,0 +1,66 @@
module('Mouse Navigation 2011', {
setup: function(){
/*
Tests start with picker on March 31, 2011.
*/
this.input = $('<input type="text" value="31-03-2011">')
.appendTo('#qunit-fixture')
.datetimepicker({format: "dd-mm-yyyy", viewSelect: 2})
.focus(); // Activate for visibility checks
this.dp = this.input.data('datetimepicker')
this.picker = this.dp.picker;
},
teardown: function(){
this.picker.remove();
}
});
test('Selecting date from previous month while in January changes month and year displayed', function(){
var target;
this.input.val('01-01-2011');
this.dp.update();
datesEqual(this.dp.viewDate, UTCDate(2011, 0, 1))
datesEqual(this.dp.date, UTCDate(2011, 0, 1))
// Rendered correctly
equal(this.dp.viewMode, 2);
target = this.picker.find('.datetimepicker-days tbody td:first');
equal(target.text(), '26'); // Should be Dec 26
equal(this.picker.find('.datetimepicker-days thead th.switch').text(), 'January 2011');
// Updated internally on click
target.click();
equal(this.picker.find('.datetimepicker-days thead th.switch').text(), 'December 2010');
datesEqual(this.dp.viewDate, UTCDate(2010, 11, 26))
datesEqual(this.dp.date, UTCDate(2010, 11, 26))
// Re-rendered on click
target = this.picker.find('.datetimepicker-days tbody td:first');
equal(target.text(), '28'); // Should be Nov 28
});
test('Selecting date from next month while in December changes month and year displayed', function(){
var target;
this.input.val('01-12-2010');
this.dp.update();
datesEqual(this.dp.viewDate, UTCDate(2010, 11, 1))
datesEqual(this.dp.date, UTCDate(2010, 11, 1))
// Rendered correctly
equal(this.dp.viewMode, 2);
target = this.picker.find('.datetimepicker-days tbody td:last');
equal(target.text(), '8'); // Should be Jan 8
equal(this.picker.find('.datetimepicker-days thead th.switch').text(), 'December 2010');
// Updated internally on click
target.click();
equal(this.picker.find('.datetimepicker-days thead th.switch').text(), 'January 2011');
datesEqual(this.dp.viewDate, UTCDate(2011, 0, 8))
datesEqual(this.dp.date, UTCDate(2011, 0, 8))
// Re-rendered on click
target = this.picker.find('.datetimepicker-days tbody td:first');
equal(target.text(), '26'); // Should be Dec 26
});

View File

@@ -0,0 +1,295 @@
module('Mouse Navigation 2012', {
setup: function(){
/*
Tests start with picker on March 31, 2012. Fun facts:
* February 1, 2012 was on a Wednesday
* February 29, 2012 was on a Wednesday
* March 1, 2012 was on a Thursday
* March 31, 2012 was on a Saturday
*/
this.input = $('<input type="text" value="31-03-2012">')
.appendTo('#qunit-fixture')
.datetimepicker({format: "dd-mm-yyyy", viewSelect: 2})
.focus(); // Activate for visibility checks
this.dp = this.input.data('datetimepicker')
this.picker = this.dp.picker;
},
teardown: function(){
this.picker.remove();
}
});
test('Selecting date resets viewDate and date', function(){
var target;
// Rendered correctly
equal(this.dp.viewMode, 2);
target = this.picker.find('.datetimepicker-days tbody td:nth(7)');
equal(target.text(), '4'); // Should be Mar 4
// Updated internally on click
target.click();
datesEqual(this.dp.viewDate, UTCDate(2012, 2, 4))
datesEqual(this.dp.date, UTCDate(2012, 2, 4))
// Re-rendered on click
target = this.picker.find('.datetimepicker-days tbody td:first');
equal(target.text(), '26'); // Should be Feb 29
});
test('Navigating next/prev by month', function(){
var target;
equal(this.dp.viewMode, 2);
target = this.picker.find('.datetimepicker-days thead th.prev');
ok(target.is(':visible'), 'Month:prev nav is visible');
// Updated internally on click
target.click();
// Should handle month-length changes gracefully
datesEqual(this.dp.viewDate, UTCDate(2012, 1, 29));
datesEqual(this.dp.date, UTCDate(2012, 2, 31));
// Re-rendered on click
target = this.picker.find('.datetimepicker-days tbody td:first');
equal(target.text(), '29'); // Should be Jan 29
target = this.picker.find('.datetimepicker-days thead th.next');
ok(target.is(':visible'), 'Month:next nav is visible');
// Updated internally on click
target.click().click();
// Graceful moonth-end handling carries over
datesEqual(this.dp.viewDate, UTCDate(2012, 3, 29));
datesEqual(this.dp.date, UTCDate(2012, 2, 31));
// Re-rendered on click
target = this.picker.find('.datetimepicker-days tbody td:first');
equal(target.text(), '25'); // Should be Mar 25
// (includes "old" days at start of month, even if that's all the first week-row consists of)
});
test('Navigating to/from year view', function(){
var target;
equal(this.dp.viewMode, 2);
target = this.picker.find('.datetimepicker-days thead th.switch');
ok(target.is(':visible'), 'View switcher is visible');
target.click();
ok(this.picker.find('.datetimepicker-months').is(':visible'), 'Month picker is visible');
equal(this.dp.viewMode, 3);
// Not modified when switching modes
datesEqual(this.dp.viewDate, UTCDate(2012, 2, 31));
datesEqual(this.dp.date, UTCDate(2012, 2, 31));
// Change months to test internal state
target = this.picker.find('.datetimepicker-months tbody span:contains(Apr)');
target.click();
equal(this.dp.viewMode, 2);
// Only viewDate modified
datesEqual(this.dp.viewDate, UTCDate(2012, 3, 1)); // Apr 30
datesEqual(this.dp.date, UTCDate(2012, 2, 31));
});
test('Navigating to/from decade view', function(){
var target;
equal(this.dp.viewMode, 2);
target = this.picker.find('.datetimepicker-days thead th.switch');
ok(target.is(':visible'), 'View switcher is visible');
target.click();
ok(this.picker.find('.datetimepicker-months').is(':visible'), 'Month picker is visible');
equal(this.dp.viewMode, 3);
// Not modified when switching modes
datesEqual(this.dp.viewDate, UTCDate(2012, 2, 31));
datesEqual(this.dp.date, UTCDate(2012, 2, 31));
target = this.picker.find('.datetimepicker-months thead th.switch');
ok(target.is(':visible'), 'View switcher is visible');
target.click();
ok(this.picker.find('.datetimepicker-years').is(':visible'), 'Year picker is visible');
equal(this.dp.viewMode, 4);
// Not modified when switching modes
datesEqual(this.dp.viewDate, UTCDate(2012, 2, 31));
datesEqual(this.dp.date, UTCDate(2012, 2, 31));
// Change years to test internal state changes
target = this.picker.find('.datetimepicker-years tbody span:contains(2011)');
target.click();
equal(this.dp.viewMode, 3);
// Only viewDate modified
datesEqual(this.dp.viewDate, UTCDate(2011, 2, 1));
datesEqual(this.dp.date, UTCDate(2012, 2, 31));
target = this.picker.find('.datetimepicker-months tbody span:contains(Apr)');
target.click();
equal(this.dp.viewMode, 2);
// Only viewDate modified
datesEqual(this.dp.viewDate, UTCDate(2011, 3, 1));
datesEqual(this.dp.date, UTCDate(2012, 2, 31));
});
test('Navigating prev/next in year view', function(){
var target;
equal(this.dp.viewMode, 2);
target = this.picker.find('.datetimepicker-days thead th.switch');
ok(target.is(':visible'), 'View switcher is visible');
target.click();
ok(this.picker.find('.datetimepicker-months').is(':visible'), 'Month picker is visible');
equal(this.dp.viewMode, 3);
equal(this.picker.find('.datetimepicker-months thead th.switch').text(), '2012');
// Not modified when switching modes
datesEqual(this.dp.viewDate, UTCDate(2012, 2, 31));
datesEqual(this.dp.date, UTCDate(2012, 2, 31));
// Go to next year (2013)
target = this.picker.find('.datetimepicker-months thead th.next');
target.click();
equal(this.picker.find('.datetimepicker-months thead th.switch').text(), '2013');
// Only viewDate modified
datesEqual(this.dp.viewDate, UTCDate(2013, 2, 31));
datesEqual(this.dp.date, UTCDate(2012, 2, 31));
// Go to prev year (x2 == 2011)
target = this.picker.find('.datetimepicker-months thead th.prev');
target.click().click();
equal(this.picker.find('.datetimepicker-months thead th.switch').text(), '2011');
// Only viewDate modified
datesEqual(this.dp.viewDate, UTCDate(2011, 2, 31));
datesEqual(this.dp.date, UTCDate(2012, 2, 31));
});
test('Navigating prev/next in decade view', function(){
var target;
equal(this.dp.viewMode, 2);
target = this.picker.find('.datetimepicker-days thead th.switch');
ok(target.is(':visible'), 'View switcher is visible');
target.click();
ok(this.picker.find('.datetimepicker-months').is(':visible'), 'Month picker is visible');
equal(this.dp.viewMode, 3);
// Not modified when switching modes
datesEqual(this.dp.viewDate, UTCDate(2012, 2, 31));
datesEqual(this.dp.date, UTCDate(2012, 2, 31));
target = this.picker.find('.datetimepicker-months thead th.switch');
ok(target.is(':visible'), 'View switcher is visible');
target.click();
ok(this.picker.find('.datetimepicker-years').is(':visible'), 'Year picker is visible');
equal(this.dp.viewMode, 4);
equal(this.picker.find('.datetimepicker-years thead th.switch').text(), '2010-2019');
// Not modified when switching modes
datesEqual(this.dp.viewDate, UTCDate(2012, 2, 31));
datesEqual(this.dp.date, UTCDate(2012, 2, 31));
// Go to next decade (2020-29)
target = this.picker.find('.datetimepicker-years thead th.next');
target.click();
equal(this.picker.find('.datetimepicker-years thead th.switch').text(), '2020-2029');
// Only viewDate modified
datesEqual(this.dp.viewDate, UTCDate(2022, 2, 31));
datesEqual(this.dp.date, UTCDate(2012, 2, 31));
// Go to prev year (x2 == 2000-09)
target = this.picker.find('.datetimepicker-years thead th.prev');
target.click().click();
equal(this.picker.find('.datetimepicker-years thead th.switch').text(), '2000-2009');
// Only viewDate modified
datesEqual(this.dp.viewDate, UTCDate(2002, 2, 31));
datesEqual(this.dp.date, UTCDate(2012, 2, 31));
});
test('Selecting date from previous month resets viewDate and date, changing month displayed', function(){
var target;
// Rendered correctly
equal(this.dp.viewMode, 2);
target = this.picker.find('.datetimepicker-days tbody td:first');
equal(target.text(), '26'); // Should be Feb 26
equal(this.picker.find('.datetimepicker-days thead th.switch').text(), 'March 2012');
// Updated internally on click
target.click();
equal(this.picker.find('.datetimepicker-days thead th.switch').text(), 'February 2012');
datesEqual(this.dp.viewDate, UTCDate(2012, 1, 26))
datesEqual(this.dp.date, UTCDate(2012, 1, 26))
// Re-rendered on click
target = this.picker.find('.datetimepicker-days tbody td:first');
equal(target.text(), '29'); // Should be Jan 29
});
test('Selecting date from next month resets viewDate and date, changing month displayed', function(){
var target;
this.input.val('01-04-2012');
this.dp.update();
// Rendered correctly
equal(this.dp.viewMode, 2);
target = this.picker.find('.datetimepicker-days tbody td:last');
equal(target.text(), '5'); // Should be May 5
equal(this.picker.find('.datetimepicker-days thead th.switch').text(), 'April 2012');
// Updated internally on click
target.click();
equal(this.picker.find('.datetimepicker-days thead th.switch').text(), 'May 2012');
datesEqual(this.dp.viewDate, UTCDate(2012, 4, 5))
datesEqual(this.dp.date, UTCDate(2012, 4, 5))
// Re-rendered on click
target = this.picker.find('.datetimepicker-days tbody td:first');
equal(target.text(), '29'); // Should be Apr 29
});
test('Selecting date from next month when the current month has 31 days resets viewDate and date, changing month displayed to the following month', function(){
var target;
// use Date AND Time mode
this.dp.viewSelect = 0;
this.input.val('2012-01-31');
this.dp.update();
equal(this.picker.find('.datetimepicker-days tbody td.day.active').text(), '31');
// Rendered correctly
equal(this.dp.viewMode, 2);
target = this.picker.find('.datetimepicker-days tbody td:last');
equal(target.text(), '4');
equal(this.picker.find('.datetimepicker-days thead th.switch').text(), 'January 2012');
// Updated internally on click
target.click();
equal(this.picker.find('.datetimepicker-days thead th.switch').text(), 'February 2012');
datesEqual(this.dp.viewDate, UTCDate(2012, 1, 4));
});
test('Selecting date from previous month when the current month has 31 days resets viewDate and date, changing month displayed to the preceding month', function(){
var target;
// use Date AND Time mode
this.dp.viewSelect = 0;
this.input.val('2012-03-31');
this.dp.update();
equal(this.picker.find('.datetimepicker-days tbody td.day.active').text(), '31');
// Rendered correctly
equal(this.dp.viewMode, 2);
target = this.picker.find('.datetimepicker-days tbody td.old:last');
equal(target.text(), '29');
equal(this.picker.find('.datetimepicker-days thead th.switch').text(), 'March 2012');
// Updated internally on click
target.click();
equal(this.picker.find('.datetimepicker-days thead th.switch').text(), 'February 2012');
datesEqual(this.dp.viewDate, UTCDate(2012, 1, 29));
});

View File

@@ -0,0 +1,33 @@
module('Mouse Navigation (All)', {
setup: function(){
this.input = $('<input type="text">')
.appendTo('#qunit-fixture')
.datetimepicker({format: "dd-mm-yyyy"})
.focus(); // Activate for visibility checks
this.dp = this.input.data('datetimepicker')
this.picker = this.dp.picker;
},
teardown: function(){
this.picker.remove();
}
});
test('Clicking datetimepicker does not hide datetimepicker', function(){
ok(this.picker.is(':visible'), 'Picker is visible');
this.picker.trigger('mousedown');
ok(this.picker.is(':visible'), 'Picker is still visible');
});
test('Clicking outside datetimepicker hides datetimepicker', function(){
var $otherelement = $('<div />');
$('body').append($otherelement);
ok(this.picker.is(':visible'), 'Picker is visible');
this.input.trigger('click');
ok(this.picker.is(':visible'), 'Picker is still visible');
$otherelement.trigger('mousedown');
ok(this.picker.is(':not(:visible)'), 'Picker is hidden');
$otherelement.remove();
});

View File

@@ -0,0 +1,396 @@
module('Options', {
setup: function(){},
teardown: function(){
return
$('#qunit-fixture *').each(function(){
var t = $(this);
if ('datetimepicker' in t.data())
t.data('datetimepicker').picker.remove();
});
}
});
test('Autoclose', function(){
var input = $('<input />')
.appendTo('#qunit-fixture')
.val('2012-03-05')
.datetimepicker({
format: 'yyyy-mm-dd',
autoclose: true,
minView: 2,
viewSelect: 2
}),
dp = input.data('datetimepicker'),
picker = dp.picker,
target;
input.focus();
ok(picker.is(':visible'), 'Picker is visible');
target = picker.find('.datetimepicker-days tbody td:nth(7)');
equal(target.text(), '4'); // Mar 4
target.click();
ok(picker.is(':not(:visible)'), 'Picker is hidden');
datesEqual(dp.date, UTCDate(2012, 2, 4));
datesEqual(dp.viewDate, UTCDate(2012, 2, 4));
});
test('Startview: year view (integer)', function(){
var input = $('<input />')
.appendTo('#qunit-fixture')
.val('2012-03-05')
.datetimepicker({
format: 'yyyy-mm-dd',
startView: 3,
viewSelect: 2
}),
dp = input.data('datetimepicker'),
picker = dp.picker,
target;
input.focus();
ok(picker.find('.datetimepicker-days').is(':not(:visible)'), 'Days view hidden');
ok(picker.find('.datetimepicker-months').is(':visible'), 'Months view visible');
ok(picker.find('.datetimepicker-years').is(':not(:visible)'), 'Years view hidden');
});
test('Startview: year view (string)', function(){
var input = $('<input />')
.appendTo('#qunit-fixture')
.val('2012-03-05')
.datetimepicker({
format: 'yyyy-mm-dd',
startView: 'year',
viewSelect: 2
}),
dp = input.data('datetimepicker'),
picker = dp.picker,
target;
input.focus();
ok(picker.find('.datetimepicker-days').is(':not(:visible)'), 'Days view hidden');
ok(picker.find('.datetimepicker-months').is(':visible'), 'Months view visible');
ok(picker.find('.datetimepicker-years').is(':not(:visible)'), 'Years view hidden');
});
test('Startview: decade view (integer)', function(){
var input = $('<input />')
.appendTo('#qunit-fixture')
.val('2012-03-05')
.datetimepicker({
format: 'yyyy-mm-dd',
startView: 4
}),
dp = input.data('datetimepicker'),
picker = dp.picker,
target;
input.focus();
ok(picker.find('.datetimepicker-days').is(':not(:visible)'), 'Days view hidden');
ok(picker.find('.datetimepicker-months').is(':not(:visible)'), 'Months view hidden');
ok(picker.find('.datetimepicker-years').is(':visible'), 'Years view visible');
});
test('Startview: decade view (string)', function(){
var input = $('<input />')
.appendTo('#qunit-fixture')
.val('2012-03-05')
.datetimepicker({
format: 'yyyy-mm-dd',
startView: 'decade'
}),
dp = input.data('datetimepicker'),
picker = dp.picker,
target;
input.focus();
ok(picker.find('.datetimepicker-days').is(':not(:visible)'), 'Days view hidden');
ok(picker.find('.datetimepicker-months').is(':not(:visible)'), 'Months view hidden');
ok(picker.find('.datetimepicker-years').is(':visible'), 'Years view visible');
});
test('Today Button: today button not default', function(){
var input = $('<input />')
.appendTo('#qunit-fixture')
.val('2012-03-05')
.datetimepicker({
format: 'yyyy-mm-dd'
}),
dp = input.data('datetimepicker'),
picker = dp.picker,
target;
input.focus();
ok(picker.find('.datetimepicker-days').is(':visible'), 'Days view visible');
ok(picker.find('.datetimepicker-days tfoot .today').is(':not(:visible)'), 'Today button not visible');
});
test('Today Button: today visibility when enabled', function(){
var input = $('<input />')
.appendTo('#qunit-fixture')
.val('2012-03-05')
.datetimepicker({
format: 'yyyy-mm-dd',
todayBtn: true
}),
dp = input.data('datetimepicker'),
picker = dp.picker,
target;
input.focus();
ok(picker.find('.datetimepicker-days').is(':visible'), 'Days view visible');
ok(picker.find('.datetimepicker-days tfoot .today').is(':visible'), 'Today button visible');
picker.find('.datetimepicker-days thead th.switch').click();
ok(picker.find('.datetimepicker-months').is(':visible'), 'Months view visible');
ok(picker.find('.datetimepicker-months tfoot .today').is(':visible'), 'Today button visible');
picker.find('.datetimepicker-months thead th.switch').click();
ok(picker.find('.datetimepicker-years').is(':visible'), 'Years view visible');
ok(picker.find('.datetimepicker-years tfoot .today').is(':visible'), 'Today button visible');
});
test('Today Button: data-api', function(){
var input = $('<input data-date-today-btn="true" />')
.appendTo('#qunit-fixture')
.val('2012-03-05')
.datetimepicker({
format: 'yyyy-mm-dd'
}),
dp = input.data('datetimepicker'),
picker = dp.picker,
target;
input.focus();
ok(picker.find('.datetimepicker-days').is(':visible'), 'Days view visible');
ok(picker.find('.datetimepicker-days tfoot .today').is(':visible'), 'Today button visible');
});
test('Today Button: moves to today\'s date', function(){
var input = $('<input />')
.appendTo('#qunit-fixture')
.val('2012-03-05')
.datetimepicker({
format: 'yyyy-mm-dd',
todayBtn: true
}),
dp = input.data('datetimepicker'),
picker = dp.picker,
target;
input.focus();
ok(picker.find('.datetimepicker-days').is(':visible'), 'Days view visible');
ok(picker.find('.datetimepicker-days tfoot .today').is(':visible'), 'Today button visible');
target = picker.find('.datetimepicker-days tfoot .today');
target.click();
var d = new Date(),
today = UTCDate(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds());
datesEqual(dp.viewDate, today);
//datesEqual(dp.date, UTCDate(2012, 2, 5));
});
test('Today Button: "linked" selects today\'s date', function(){
var input = $('<input />')
.appendTo('#qunit-fixture')
.val('2012-03-05')
.datetimepicker({
format: 'yyyy-mm-dd',
todayBtn: "linked"
}),
dp = input.data('datetimepicker'),
picker = dp.picker,
target;
input.focus();
ok(picker.find('.datetimepicker-days').is(':visible'), 'Days view visible');
ok(picker.find('.datetimepicker-days tfoot .today').is(':visible'), 'Today button visible');
target = picker.find('.datetimepicker-days tfoot .today');
target.click();
var d = new Date(),
today = UTCDate(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds());
datesEqual(dp.viewDate, today);
datesEqual(dp.date, today);
});
test('Today Highlight: today\'s date is not highlighted by default', patch_date(function(Date){
Date.now = UTCDate(2012, 2, 15);
var input = $('<input />')
.appendTo('#qunit-fixture')
.val('2012-03-05')
.datetimepicker({
format: 'yyyy-mm-dd'
}),
dp = input.data('datetimepicker'),
picker = dp.picker,
target;
input.focus();
ok(picker.find('.datetimepicker-days').is(':visible'), 'Days view visible');
equal(picker.find('.datetimepicker-days thead .switch').text(), 'March 2012', 'Title is "March 2012"');
target = picker.find('.datetimepicker-days tbody td:contains(15)');
ok(!target.hasClass('today'), 'Today is not marked with "today" class');
target = picker.find('.datetimepicker-days tbody td:contains(14)');
ok(!target.hasClass('today'), 'Yesterday is not marked with "today" class');
target = picker.find('.datetimepicker-days tbody td:contains(16)');
ok(!target.hasClass('today'), 'Tomorrow is not marked with "today" class');
}));
test('Today Highlight: today\'s date is highlighted when not active', patch_date(function(Date){
Date.now = new Date(2012, 2, 15);
var input = $('<input />')
.appendTo('#qunit-fixture')
.val('2012-03-05')
.datetimepicker({
format: 'yyyy-mm-dd',
todayHighlight: true
}),
dp = input.data('datetimepicker'),
picker = dp.picker,
target;
input.focus();
ok(picker.find('.datetimepicker-days').is(':visible'), 'Days view visible');
equal(picker.find('.datetimepicker-days thead .switch').text(), 'March 2012', 'Title is "March 2012"');
target = picker.find('.datetimepicker-days tbody td:contains(15)');
ok(target.hasClass('today'), 'Today is marked with "today" class');
target = picker.find('.datetimepicker-days tbody td:contains(14)');
ok(!target.hasClass('today'), 'Yesterday is not marked with "today" class');
target = picker.find('.datetimepicker-days tbody td:contains(16)');
ok(!target.hasClass('today'), 'Tomorrow is not marked with "today" class');
}));
test('DaysOfWeekDisabled', function(){
var input = $('<input />')
.appendTo('#qunit-fixture')
.val('2012-10-26')
.datetimepicker({
format: 'yyyy-mm-dd',
daysOfWeekDisabled: '1,5'
}),
dp = input.data('datetimepicker'),
picker = dp.picker,
target;
input.focus();
target = picker.find('.datetimepicker-days tbody td:nth(22)');
ok(target.hasClass('disabled'), 'Day of week is disabled');
target = picker.find('.datetimepicker-days tbody td:nth(24)');
ok(!target.hasClass('disabled'), 'Day of week is enabled');
target = picker.find('.datetimepicker-days tbody td:nth(26)');
ok(target.hasClass('disabled'), 'Day of week is disabled');
});
test('startDate: Custom value', function(){
var input = $('<input />')
.appendTo('#qunit-fixture')
.val('2013-01-25')
.datetimepicker({
format: 'yyyy-mm-dd',
startView: 2,
startDate: "2013-01-24 15:30",
viewSelect: 2
}),
dp = input.data('datetimepicker'),
picker = dp.picker,
target;
input.focus();
ok(picker.find('.datetimepicker-days tbody tr:nth(3) td:nth(2)').hasClass('disabled'), 'The previous day is disabled');
target = picker.find('.datetimepicker-days tbody tr:nth(3) td:nth(4)')
ok(!target.hasClass('disabled'), 'The starting day is enabled');
target.click()
ok(picker.find('.datetimepicker-hours tbody span:nth(14)').hasClass('disabled'), 'The previous hour is disabled');
target = picker.find('.datetimepicker-hours tbody span:nth(15)')
ok(!target.hasClass('disabled'), 'The starting hour is enabled');
target.click()
ok(picker.find('.datetimepicker-minutes tbody span:nth(5)').hasClass('disabled'), 'The previous minute is disabled');
ok(!picker.find('.datetimepicker-minutes tbody span:nth(6)').hasClass('disabled'), 'The starting minute is enabled');
});
test('startDate: Custom value', function(){
var input = $('<input />')
.appendTo('#qunit-fixture')
.val('2013-01-25')
.datetimepicker({
format: 'yyyy-mm-dd',
startView: 2,
startDate: "2013-01-24 15:30",
viewSelect: 2
}),
dp = input.data('datetimepicker'),
picker = dp.picker,
target;
input.focus();
ok(picker.find('.datetimepicker-days tbody tr:nth(3) td:nth(3)').hasClass('disabled'), 'The previous day is disabled');
target = picker.find('.datetimepicker-days tbody tr:nth(3) td:nth(4)')
ok(!target.hasClass('disabled'), 'The starting day is enabled');
target.click()
ok(picker.find('.datetimepicker-hours tbody span:nth(14)').hasClass('disabled'), 'The previous hour is disabled');
target = picker.find('.datetimepicker-hours tbody span:nth(15)')
ok(!target.hasClass('disabled'), 'The starting hour is enabled');
target.click()
ok(picker.find('.datetimepicker-minutes tbody span:nth(5)').hasClass('disabled'), 'The previous minute is disabled');
ok(!picker.find('.datetimepicker-minutes tbody span:nth(6)').hasClass('disabled'), 'The starting minute is enabled');
});
test('endDate: Custom value', function(){
var input = $('<input />')
.appendTo('#qunit-fixture')
.val('2013-01-25')
.datetimepicker({
format: 'yyyy-mm-dd',
startView: 2,
endDate: "2013-01-24 15:30",
viewSelect: 2
}),
dp = input.data('datetimepicker'),
picker = dp.picker,
target;
input.focus();
ok(picker.find('.datetimepicker-days tbody tr:nth(3) td:nth(5)').hasClass('disabled'), 'The next day is disabled');
target = picker.find('.datetimepicker-days tbody tr:nth(3) td:nth(4)')
ok(!target.hasClass('disabled'), 'The last day is enabled');
target.click()
ok(picker.find('.datetimepicker-hours tbody span:nth(16)').hasClass('disabled'), 'The next hour is disabled');
target = picker.find('.datetimepicker-hours tbody span:nth(15)')
ok(!target.hasClass('disabled'), 'The last hour is enabled');
target.click()
ok(picker.find('.datetimepicker-minutes tbody span:nth(7)').hasClass('disabled'), 'The next minute is disabled');
ok(!picker.find('.datetimepicker-minutes tbody span:nth(6)').hasClass('disabled'), 'The last minute is enabled');
});
test('zIndex: set in options', function(){
var zIndex = 77;
var input = $('<input />')
.appendTo('#qunit-fixture')
.val('2013-01-25')
.datetimepicker({
format: 'yyyy-mm-dd',
startView: 2,
endDate: "2013-01-24 15:30",
viewSelect: 2,
zIndex: zIndex
}),
dp = input.data('datetimepicker'),
picker = dp.picker;
ok(parseInt(picker.css('z-index'), 10) == zIndex, 'has a value defined in the options');
});

View File

@@ -0,0 +1,46 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="assets/qunit.css" />
<script src="assets/qunit.js"></script>
<script src="assets/qunit-logging.js"></script> <!-- console.log for test failures -->
<script src="assets/coverage.js"></script>
<script src="assets/jquery-1.7.1.min.js"></script>
<script src="../js/bootstrap-datetimepicker.js"></script>
<style>
.datetimepicker {
/* Appended to body, abs-pos off the page */
position: absolute;
display: none;
top: -9999em;
left: -9999em;
}
</style>
<!-- Utilities -->
<script src="assets/utils.js"></script>
<script src="assets/mock.js"></script>
<!-- Test suites -->
<script src="suites/formats.js"></script>
<script src="suites/mouse_navigation/all.js"></script>
<script src="suites/mouse_navigation/2012.js"></script>
<script src="suites/mouse_navigation/2011.js"></script>
<script src="suites/keyboard_navigation/all.js"></script>
<script src="suites/keyboard_navigation/2012.js"></script>
<script src="suites/keyboard_navigation/2011.js"></script>
<script src="suites/component.js"></script>
<script src="suites/events.js"></script>
<script src="suites/options.js"></script>
<script src="suites/inline.js"></script>
</head>
<body>
<h1 id="qunit-header">bootstrap-datetimepicker</h1>
<h2 id="qunit-banner"></h2>
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
<div id="qunit-fixture"></div>
</body>
</html>

View File

@@ -0,0 +1,46 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="assets/qunit.css" />
<script src="assets/qunit.js"></script>
<script src="assets/qunit-logging.js"></script> <!-- console.log for test failures -->
<script src="assets/coverage.js"></script>
<script src="assets/jquery-1.7.1.min.js"></script>
<script src="../js/bootstrap-datetimepicker.min.js"></script>
<style>
.datetimepicker {
/* Appended to body, abs-pos off the page */
position: absolute;
display: none;
top: -9999em;
left: -9999em;
}
</style>
<!-- Utilities -->
<script src="assets/utils.js"></script>
<script src="assets/mock.js"></script>
<!-- Test suites -->
<script src="suites/formats.js"></script>
<script src="suites/mouse_navigation/all.js"></script>
<script src="suites/mouse_navigation/2012.js"></script>
<script src="suites/mouse_navigation/2011.js"></script>
<script src="suites/keyboard_navigation/all.js"></script>
<script src="suites/keyboard_navigation/2012.js"></script>
<script src="suites/keyboard_navigation/2011.js"></script>
<script src="suites/component.js"></script>
<script src="suites/events.js"></script>
<script src="suites/options.js"></script>
<script src="suites/inline.js"></script>
</head>
<body>
<h1 id="qunit-header">bootstrap-datetimepicker</h1>
<h2 id="qunit-banner"></h2>
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
<div id="qunit-fixture"></div>
</body>
</html>