mirror of
https://github.com/Hopiu/jquery-mobile.git
synced 2026-05-17 19:11:06 +00:00
Merge remote branch 'origin/master'
This commit is contained in:
commit
ecf3e8a1f9
17 changed files with 1123 additions and 1018 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -5,3 +5,4 @@
|
||||||
.DS_Store
|
.DS_Store
|
||||||
cache/
|
cache/
|
||||||
combined/
|
combined/
|
||||||
|
combine/
|
||||||
|
|
|
||||||
79
external/qunit.css
vendored
79
external/qunit.css
vendored
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
/** Resets */
|
/** Resets */
|
||||||
|
|
||||||
#qunit-tests, #qunit-tests li ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult {
|
#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
@ -21,10 +21,13 @@
|
||||||
#qunit-header {
|
#qunit-header {
|
||||||
padding: 0.5em 0 0.5em 1em;
|
padding: 0.5em 0 0.5em 1em;
|
||||||
|
|
||||||
color: #fff;
|
color: #8699a4;
|
||||||
text-shadow: rgba(0, 0, 0, 0.5) 4px 4px 1px;
|
|
||||||
background-color: #0d3349;
|
background-color: #0d3349;
|
||||||
|
|
||||||
|
font-size: 1.5em;
|
||||||
|
line-height: 1em;
|
||||||
|
font-weight: normal;
|
||||||
|
|
||||||
border-radius: 15px 15px 0 0;
|
border-radius: 15px 15px 0 0;
|
||||||
-moz-border-radius: 15px 15px 0 0;
|
-moz-border-radius: 15px 15px 0 0;
|
||||||
-webkit-border-top-right-radius: 15px;
|
-webkit-border-top-right-radius: 15px;
|
||||||
|
|
@ -33,7 +36,12 @@
|
||||||
|
|
||||||
#qunit-header a {
|
#qunit-header a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: white;
|
color: #c2ccd1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#qunit-header a:hover,
|
||||||
|
#qunit-header a:focus {
|
||||||
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
#qunit-banner {
|
#qunit-banner {
|
||||||
|
|
@ -68,7 +76,7 @@
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
#qunit-tests li ol {
|
#qunit-tests ol {
|
||||||
margin-top: 0.5em;
|
margin-top: 0.5em;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
|
|
||||||
|
|
@ -83,6 +91,45 @@
|
||||||
-webkit-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 {
|
#qunit-tests li li {
|
||||||
margin: 0.5em;
|
margin: 0.5em;
|
||||||
padding: 0.4em 0.5em 0.4em 0.5em;
|
padding: 0.4em 0.5em 0.4em 0.5em;
|
||||||
|
|
@ -99,13 +146,11 @@
|
||||||
border-left: 26px solid #C6E746;
|
border-left: 26px solid #C6E746;
|
||||||
}
|
}
|
||||||
|
|
||||||
#qunit-tests li.pass { color: #528CE0; background-color: #D2E0E6; }
|
#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; }
|
||||||
#qunit-tests li.pass span.test-name { color: #366097; }
|
#qunit-tests .pass .test-name { color: #366097; }
|
||||||
|
|
||||||
#qunit-tests li li.pass span.test-actual,
|
#qunit-tests .pass .test-actual,
|
||||||
#qunit-tests li li.pass span.test-expected { color: #999999; }
|
#qunit-tests .pass .test-expected { color: #999999; }
|
||||||
|
|
||||||
strong b.pass { color: #5E740B; }
|
|
||||||
|
|
||||||
#qunit-banner.qunit-pass { background-color: #C6E746; }
|
#qunit-banner.qunit-pass { background-color: #C6E746; }
|
||||||
|
|
||||||
|
|
@ -117,14 +162,12 @@ strong b.pass { color: #5E740B; }
|
||||||
border-left: 26px solid #EE5757;
|
border-left: 26px solid #EE5757;
|
||||||
}
|
}
|
||||||
|
|
||||||
#qunit-tests li.fail { color: #000000; background-color: #EE5757; }
|
#qunit-tests .fail { color: #000000; background-color: #EE5757; }
|
||||||
#qunit-tests li.fail span.test-name,
|
#qunit-tests .fail .test-name,
|
||||||
#qunit-tests li.fail span.module-name { color: #000000; }
|
#qunit-tests .fail .module-name { color: #000000; }
|
||||||
|
|
||||||
#qunit-tests li li.fail span.test-actual { color: #EE5757; }
|
#qunit-tests .fail .test-actual { color: #EE5757; }
|
||||||
#qunit-tests li li.fail span.test-expected { color: green; }
|
#qunit-tests .fail .test-expected { color: green; }
|
||||||
|
|
||||||
strong b.fail { color: #710909; }
|
|
||||||
|
|
||||||
#qunit-banner.qunit-fail,
|
#qunit-banner.qunit-fail,
|
||||||
#qunit-testrunner-toolbar { background-color: #EE5757; }
|
#qunit-testrunner-toolbar { background-color: #EE5757; }
|
||||||
|
|
|
||||||
608
external/qunit.js
vendored
608
external/qunit.js
vendored
|
|
@ -10,23 +10,234 @@
|
||||||
|
|
||||||
(function(window) {
|
(function(window) {
|
||||||
|
|
||||||
|
var defined = {
|
||||||
|
setTimeout: typeof window.setTimeout !== "undefined",
|
||||||
|
sessionStorage: (function() {
|
||||||
|
try {
|
||||||
|
return !!sessionStorage.getItem;
|
||||||
|
} catch(e){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
}
|
||||||
|
|
||||||
|
var testId = 0;
|
||||||
|
|
||||||
|
var Test = function(name, testName, expected, testEnvironmentArg, async, callback) {
|
||||||
|
this.name = name;
|
||||||
|
this.testName = testName;
|
||||||
|
this.expected = expected;
|
||||||
|
this.testEnvironmentArg = testEnvironmentArg;
|
||||||
|
this.async = async;
|
||||||
|
this.callback = callback;
|
||||||
|
this.assertions = [];
|
||||||
|
};
|
||||||
|
Test.prototype = {
|
||||||
|
init: function() {
|
||||||
|
var tests = id("qunit-tests");
|
||||||
|
if (tests) {
|
||||||
|
var b = document.createElement("strong");
|
||||||
|
b.innerHTML = "Running " + this.name;
|
||||||
|
var li = document.createElement("li");
|
||||||
|
li.appendChild( b );
|
||||||
|
li.id = this.id = "test-output" + testId++;
|
||||||
|
tests.appendChild( li );
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setup: function() {
|
||||||
|
if (this.module != config.previousModule) {
|
||||||
|
if ( this.previousModule ) {
|
||||||
|
QUnit.moduleDone( this.module, config.moduleStats.bad, config.moduleStats.all );
|
||||||
|
}
|
||||||
|
config.previousModule = this.module;
|
||||||
|
config.moduleStats = { all: 0, bad: 0 };
|
||||||
|
QUnit.moduleStart( this.module, this.moduleTestEnvironment );
|
||||||
|
}
|
||||||
|
|
||||||
|
config.current = this;
|
||||||
|
this.testEnvironment = extend({
|
||||||
|
setup: function() {},
|
||||||
|
teardown: function() {}
|
||||||
|
}, this.moduleTestEnvironment);
|
||||||
|
if (this.testEnvironmentArg) {
|
||||||
|
extend(this.testEnvironment, this.testEnvironmentArg);
|
||||||
|
}
|
||||||
|
|
||||||
|
QUnit.testStart( this.testName, this.testEnvironment );
|
||||||
|
|
||||||
|
// allow utility functions to access the current test environment
|
||||||
|
// TODO why??
|
||||||
|
QUnit.current_testEnvironment = this.testEnvironment;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if ( !config.pollution ) {
|
||||||
|
saveGlobal();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.testEnvironment.setup.call(this.testEnvironment);
|
||||||
|
} catch(e) {
|
||||||
|
// TODO use testName instead of name for no-markup message?
|
||||||
|
QUnit.ok( false, "Setup failed on " + this.name + ": " + e.message );
|
||||||
|
}
|
||||||
|
},
|
||||||
|
run: function() {
|
||||||
|
if ( this.async ) {
|
||||||
|
QUnit.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.callback.call(this.testEnvironment);
|
||||||
|
} catch(e) {
|
||||||
|
// TODO use testName instead of name for no-markup message?
|
||||||
|
fail("Test " + this.name + " died, exception and test follows", e, this.callback);
|
||||||
|
QUnit.ok( false, "Died on test #" + (this.assertions.length + 1) + ": " + e.message + " - " + QUnit.jsDump.parse(e) );
|
||||||
|
// else next test will carry the responsibility
|
||||||
|
saveGlobal();
|
||||||
|
|
||||||
|
// Restart the tests if they're blocking
|
||||||
|
if ( config.blocking ) {
|
||||||
|
start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
teardown: function() {
|
||||||
|
try {
|
||||||
|
checkPollution();
|
||||||
|
this.testEnvironment.teardown.call(this.testEnvironment);
|
||||||
|
} catch(e) {
|
||||||
|
// TODO use testName instead of name for no-markup message?
|
||||||
|
QUnit.ok( false, "Teardown failed on " + this.name + ": " + e.message );
|
||||||
|
}
|
||||||
|
},
|
||||||
|
finish: function() {
|
||||||
|
if ( this.expected && this.expected != this.assertions.length ) {
|
||||||
|
QUnit.ok( false, "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run" );
|
||||||
|
}
|
||||||
|
|
||||||
|
var good = 0, bad = 0,
|
||||||
|
tests = id("qunit-tests");
|
||||||
|
|
||||||
|
config.stats.all += this.assertions.length;
|
||||||
|
config.moduleStats.all += this.assertions.length;
|
||||||
|
|
||||||
|
if ( tests ) {
|
||||||
|
var ol = document.createElement("ol");
|
||||||
|
|
||||||
|
for ( var i = 0; i < this.assertions.length; i++ ) {
|
||||||
|
var assertion = this.assertions[i];
|
||||||
|
|
||||||
|
var li = document.createElement("li");
|
||||||
|
li.className = assertion.result ? "pass" : "fail";
|
||||||
|
li.innerHTML = assertion.message || (assertion.result ? "okay" : "failed");
|
||||||
|
ol.appendChild( li );
|
||||||
|
|
||||||
|
if ( assertion.result ) {
|
||||||
|
good++;
|
||||||
|
} else {
|
||||||
|
bad++;
|
||||||
|
config.stats.bad++;
|
||||||
|
config.moduleStats.bad++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// store result when possible
|
||||||
|
defined.sessionStorage && sessionStorage.setItem("qunit-" + this.testName, bad);
|
||||||
|
|
||||||
|
if (bad == 0) {
|
||||||
|
ol.style.display = "none";
|
||||||
|
}
|
||||||
|
|
||||||
|
var b = document.createElement("strong");
|
||||||
|
b.innerHTML = this.name + " <b class='counts'>(<b class='failed'>" + bad + "</b>, <b class='passed'>" + good + "</b>, " + this.assertions.length + ")</b>";
|
||||||
|
|
||||||
|
addEvent(b, "click", function() {
|
||||||
|
var next = b.nextSibling, display = next.style.display;
|
||||||
|
next.style.display = display === "none" ? "block" : "none";
|
||||||
|
});
|
||||||
|
|
||||||
|
addEvent(b, "dblclick", function(e) {
|
||||||
|
var target = e && e.target ? e.target : window.event.srcElement;
|
||||||
|
if ( target.nodeName.toLowerCase() == "span" || target.nodeName.toLowerCase() == "b" ) {
|
||||||
|
target = target.parentNode;
|
||||||
|
}
|
||||||
|
if ( window.location && target.nodeName.toLowerCase() === "strong" ) {
|
||||||
|
window.location.search = "?" + encodeURIComponent(getText([target]).replace(/\(.+\)$/, "").replace(/(^\s*|\s*$)/g, ""));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var li = id(this.id);
|
||||||
|
li.className = bad ? "fail" : "pass";
|
||||||
|
li.style.display = resultDisplayStyle(!bad);
|
||||||
|
li.removeChild( li.firstChild );
|
||||||
|
li.appendChild( b );
|
||||||
|
li.appendChild( ol );
|
||||||
|
|
||||||
|
if ( bad ) {
|
||||||
|
var toolbar = id("qunit-testrunner-toolbar");
|
||||||
|
if ( toolbar ) {
|
||||||
|
toolbar.style.display = "block";
|
||||||
|
id("qunit-filter-pass").disabled = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
for ( var i = 0; i < this.assertions.length; i++ ) {
|
||||||
|
if ( !this.assertions[i].result ) {
|
||||||
|
bad++;
|
||||||
|
config.stats.bad++;
|
||||||
|
config.moduleStats.bad++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
QUnit.reset();
|
||||||
|
} catch(e) {
|
||||||
|
// TODO use testName instead of name for no-markup message?
|
||||||
|
fail("reset() failed, following Test " + this.name + ", exception and reset fn follows", e, QUnit.reset);
|
||||||
|
}
|
||||||
|
|
||||||
|
QUnit.testDone( this.testName, bad, this.assertions.length );
|
||||||
|
},
|
||||||
|
|
||||||
|
queue: function() {
|
||||||
|
var test = this;
|
||||||
|
synchronize(function() {
|
||||||
|
test.init();
|
||||||
|
});
|
||||||
|
function run() {
|
||||||
|
// each of these can by async
|
||||||
|
synchronize(function() {
|
||||||
|
test.setup();
|
||||||
|
});
|
||||||
|
synchronize(function() {
|
||||||
|
test.run();
|
||||||
|
});
|
||||||
|
synchronize(function() {
|
||||||
|
test.teardown();
|
||||||
|
});
|
||||||
|
synchronize(function() {
|
||||||
|
test.finish();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// defer when previous test run passed, if storage is available
|
||||||
|
var bad = defined.sessionStorage && +sessionStorage.getItem("qunit-" + this.testName);
|
||||||
|
if (bad) {
|
||||||
|
run();
|
||||||
|
} else {
|
||||||
|
synchronize(run);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
var QUnit = {
|
var QUnit = {
|
||||||
|
|
||||||
// call on start of module test to prepend name to all tests
|
// call on start of module test to prepend name to all tests
|
||||||
module: function(name, testEnvironment) {
|
module: function(name, testEnvironment) {
|
||||||
|
config.previousModule = config.currentModule;
|
||||||
config.currentModule = name;
|
config.currentModule = name;
|
||||||
|
config.currentModuleTestEnviroment = testEnvironment;
|
||||||
synchronize(function() {
|
|
||||||
if ( config.currentModule ) {
|
|
||||||
QUnit.moduleDone( config.currentModule, config.moduleStats.bad, config.moduleStats.all );
|
|
||||||
}
|
|
||||||
|
|
||||||
config.currentModule = name;
|
|
||||||
config.moduleTestEnvironment = testEnvironment;
|
|
||||||
config.moduleStats = { all: 0, bad: 0 };
|
|
||||||
|
|
||||||
QUnit.moduleStart( name, testEnvironment );
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
asyncTest: function(testName, expected, callback) {
|
asyncTest: function(testName, expected, callback) {
|
||||||
|
|
@ -39,7 +250,7 @@ var QUnit = {
|
||||||
},
|
},
|
||||||
|
|
||||||
test: function(testName, expected, callback, async) {
|
test: function(testName, expected, callback, async) {
|
||||||
var name = '<span class="test-name">' + testName + '</span>', testEnvironment, testEnvironmentArg;
|
var name = '<span class="test-name">' + testName + '</span>', testEnvironmentArg;
|
||||||
|
|
||||||
if ( arguments.length === 2 ) {
|
if ( arguments.length === 2 ) {
|
||||||
callback = expected;
|
callback = expected;
|
||||||
|
|
@ -59,173 +270,18 @@ var QUnit = {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronize(function() {
|
var test = new Test(name, testName, expected, testEnvironmentArg, async, callback);
|
||||||
|
test.previousModule = config.previousModule;
|
||||||
testEnvironment = extend({
|
test.module = config.currentModule;
|
||||||
setup: function() {},
|
test.moduleTestEnvironment = config.currentModuleTestEnviroment;
|
||||||
teardown: function() {}
|
test.queue();
|
||||||
}, config.moduleTestEnvironment);
|
|
||||||
if (testEnvironmentArg) {
|
|
||||||
extend(testEnvironment,testEnvironmentArg);
|
|
||||||
}
|
|
||||||
|
|
||||||
QUnit.testStart( testName, testEnvironment );
|
|
||||||
|
|
||||||
// allow utility functions to access the current test environment
|
|
||||||
QUnit.current_testEnvironment = testEnvironment;
|
|
||||||
|
|
||||||
config.assertions = [];
|
|
||||||
config.expected = expected;
|
|
||||||
|
|
||||||
var tests = id("qunit-tests");
|
|
||||||
if (tests) {
|
|
||||||
var b = document.createElement("strong");
|
|
||||||
b.innerHTML = "Running " + name;
|
|
||||||
var li = document.createElement("li");
|
|
||||||
li.appendChild( b );
|
|
||||||
li.id = "current-test-output";
|
|
||||||
tests.appendChild( li )
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
if ( !config.pollution ) {
|
|
||||||
saveGlobal();
|
|
||||||
}
|
|
||||||
|
|
||||||
testEnvironment.setup.call(testEnvironment);
|
|
||||||
} catch(e) {
|
|
||||||
QUnit.ok( false, "Setup failed on " + name + ": " + e.message );
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
synchronize(function() {
|
|
||||||
if ( async ) {
|
|
||||||
QUnit.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
callback.call(testEnvironment);
|
|
||||||
} catch(e) {
|
|
||||||
fail("Test " + name + " died, exception and test follows", e, callback);
|
|
||||||
QUnit.ok( false, "Died on test #" + (config.assertions.length + 1) + ": " + e.message );
|
|
||||||
// else next test will carry the responsibility
|
|
||||||
saveGlobal();
|
|
||||||
|
|
||||||
// Restart the tests if they're blocking
|
|
||||||
if ( config.blocking ) {
|
|
||||||
start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
synchronize(function() {
|
|
||||||
try {
|
|
||||||
checkPollution();
|
|
||||||
testEnvironment.teardown.call(testEnvironment);
|
|
||||||
} catch(e) {
|
|
||||||
QUnit.ok( false, "Teardown failed on " + name + ": " + e.message );
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
synchronize(function() {
|
|
||||||
try {
|
|
||||||
QUnit.reset();
|
|
||||||
} catch(e) {
|
|
||||||
fail("reset() failed, following Test " + name + ", exception and reset fn follows", e, reset);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( config.expected && config.expected != config.assertions.length ) {
|
|
||||||
QUnit.ok( false, "Expected " + config.expected + " assertions, but " + config.assertions.length + " were run" );
|
|
||||||
}
|
|
||||||
|
|
||||||
var good = 0, bad = 0,
|
|
||||||
tests = id("qunit-tests");
|
|
||||||
|
|
||||||
config.stats.all += config.assertions.length;
|
|
||||||
config.moduleStats.all += config.assertions.length;
|
|
||||||
|
|
||||||
if ( tests ) {
|
|
||||||
var ol = document.createElement("ol");
|
|
||||||
|
|
||||||
for ( var i = 0; i < config.assertions.length; i++ ) {
|
|
||||||
var assertion = config.assertions[i];
|
|
||||||
|
|
||||||
var li = document.createElement("li");
|
|
||||||
li.className = assertion.result ? "pass" : "fail";
|
|
||||||
li.innerHTML = assertion.message || "(no message)";
|
|
||||||
ol.appendChild( li );
|
|
||||||
|
|
||||||
if ( assertion.result ) {
|
|
||||||
good++;
|
|
||||||
} else {
|
|
||||||
bad++;
|
|
||||||
config.stats.bad++;
|
|
||||||
config.moduleStats.bad++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (bad == 0) {
|
|
||||||
ol.style.display = "none";
|
|
||||||
}
|
|
||||||
|
|
||||||
var b = document.createElement("strong");
|
|
||||||
b.innerHTML = name + " <b style='color:black;'>(<b class='fail'>" + bad + "</b>, <b class='pass'>" + good + "</b>, " + config.assertions.length + ")</b>";
|
|
||||||
|
|
||||||
addEvent(b, "click", function() {
|
|
||||||
var next = b.nextSibling, display = next.style.display;
|
|
||||||
next.style.display = display === "none" ? "block" : "none";
|
|
||||||
});
|
|
||||||
|
|
||||||
addEvent(b, "dblclick", function(e) {
|
|
||||||
var target = e && e.target ? e.target : window.event.srcElement;
|
|
||||||
if ( target.nodeName.toLowerCase() == "span" || target.nodeName.toLowerCase() == "b" ) {
|
|
||||||
target = target.parentNode;
|
|
||||||
}
|
|
||||||
if ( window.location && target.nodeName.toLowerCase() === "strong" ) {
|
|
||||||
window.location.search = "?" + encodeURIComponent(getText([target]).replace(/\(.+\)$/, "").replace(/(^\s*|\s*$)/g, ""));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var li = id("current-test-output");
|
|
||||||
li.id = "";
|
|
||||||
li.className = bad ? "fail" : "pass";
|
|
||||||
li.removeChild( li.firstChild );
|
|
||||||
li.appendChild( b );
|
|
||||||
li.appendChild( ol );
|
|
||||||
|
|
||||||
if ( bad ) {
|
|
||||||
var toolbar = id("qunit-testrunner-toolbar");
|
|
||||||
if ( toolbar ) {
|
|
||||||
toolbar.style.display = "block";
|
|
||||||
id("qunit-filter-pass").disabled = null;
|
|
||||||
id("qunit-filter-missing").disabled = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
for ( var i = 0; i < config.assertions.length; i++ ) {
|
|
||||||
if ( !config.assertions[i].result ) {
|
|
||||||
bad++;
|
|
||||||
config.stats.bad++;
|
|
||||||
config.moduleStats.bad++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QUnit.testDone( testName, bad, config.assertions.length );
|
|
||||||
|
|
||||||
if ( !window.setTimeout && !config.queue.length ) {
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
synchronize( done );
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through.
|
* Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through.
|
||||||
*/
|
*/
|
||||||
expect: function(asserts) {
|
expect: function(asserts) {
|
||||||
config.expected = asserts;
|
config.current.expected = asserts;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -233,11 +289,15 @@ var QUnit = {
|
||||||
* @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" );
|
* @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" );
|
||||||
*/
|
*/
|
||||||
ok: function(a, msg) {
|
ok: function(a, msg) {
|
||||||
|
a = !!a;
|
||||||
|
var details = {
|
||||||
|
result: a,
|
||||||
|
message: msg
|
||||||
|
};
|
||||||
msg = escapeHtml(msg);
|
msg = escapeHtml(msg);
|
||||||
QUnit.log(a, msg);
|
QUnit.log(a, msg, details);
|
||||||
|
config.current.assertions.push({
|
||||||
config.assertions.push({
|
result: a,
|
||||||
result: !!a,
|
|
||||||
message: msg
|
message: msg
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
@ -255,42 +315,42 @@ var QUnit = {
|
||||||
* @param String message (optional)
|
* @param String message (optional)
|
||||||
*/
|
*/
|
||||||
equal: function(actual, expected, message) {
|
equal: function(actual, expected, message) {
|
||||||
push(expected == actual, actual, expected, message);
|
QUnit.push(expected == actual, actual, expected, message);
|
||||||
},
|
},
|
||||||
|
|
||||||
notEqual: function(actual, expected, message) {
|
notEqual: function(actual, expected, message) {
|
||||||
push(expected != actual, actual, expected, message);
|
QUnit.push(expected != actual, actual, expected, message);
|
||||||
},
|
},
|
||||||
|
|
||||||
deepEqual: function(actual, expected, message) {
|
deepEqual: function(actual, expected, message) {
|
||||||
push(QUnit.equiv(actual, expected), actual, expected, message);
|
QUnit.push(QUnit.equiv(actual, expected), actual, expected, message);
|
||||||
},
|
},
|
||||||
|
|
||||||
notDeepEqual: function(actual, expected, message) {
|
notDeepEqual: function(actual, expected, message) {
|
||||||
push(!QUnit.equiv(actual, expected), actual, expected, message);
|
QUnit.push(!QUnit.equiv(actual, expected), actual, expected, message);
|
||||||
},
|
},
|
||||||
|
|
||||||
strictEqual: function(actual, expected, message) {
|
strictEqual: function(actual, expected, message) {
|
||||||
push(expected === actual, actual, expected, message);
|
QUnit.push(expected === actual, actual, expected, message);
|
||||||
},
|
},
|
||||||
|
|
||||||
notStrictEqual: function(actual, expected, message) {
|
notStrictEqual: function(actual, expected, message) {
|
||||||
push(expected !== actual, actual, expected, message);
|
QUnit.push(expected !== actual, actual, expected, message);
|
||||||
},
|
},
|
||||||
|
|
||||||
raises: function(fn, message) {
|
raises: function(fn, message) {
|
||||||
try {
|
try {
|
||||||
fn();
|
fn();
|
||||||
ok( false, message );
|
QUnit.ok( false, message );
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
ok( true, message );
|
QUnit.ok( true, message );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
start: function() {
|
start: function() {
|
||||||
// A slight delay, to avoid any current callbacks
|
// A slight delay, to avoid any current callbacks
|
||||||
if ( window.setTimeout ) {
|
if ( defined.setTimeout ) {
|
||||||
window.setTimeout(function() {
|
window.setTimeout(function() {
|
||||||
if ( config.timeout ) {
|
if ( config.timeout ) {
|
||||||
clearTimeout(config.timeout);
|
clearTimeout(config.timeout);
|
||||||
|
|
@ -308,7 +368,7 @@ var QUnit = {
|
||||||
stop: function(timeout) {
|
stop: function(timeout) {
|
||||||
config.blocking = true;
|
config.blocking = true;
|
||||||
|
|
||||||
if ( timeout && window.setTimeout ) {
|
if ( timeout && defined.setTimeout ) {
|
||||||
config.timeout = window.setTimeout(function() {
|
config.timeout = window.setTimeout(function() {
|
||||||
QUnit.ok( false, "Test timed out" );
|
QUnit.ok( false, "Test timed out" );
|
||||||
QUnit.start();
|
QUnit.start();
|
||||||
|
|
@ -379,7 +439,6 @@ extend(QUnit, {
|
||||||
blocking: false,
|
blocking: false,
|
||||||
autostart: true,
|
autostart: true,
|
||||||
autorun: false,
|
autorun: false,
|
||||||
assertions: [],
|
|
||||||
filters: [],
|
filters: [],
|
||||||
queue: []
|
queue: []
|
||||||
});
|
});
|
||||||
|
|
@ -403,10 +462,17 @@ extend(QUnit, {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets the test setup. Useful for tests that modify the DOM.
|
* Resets the test setup. Useful for tests that modify the DOM.
|
||||||
|
*
|
||||||
|
* If jQuery is available, uses jQuery's html(), otherwise just innerHTML.
|
||||||
*/
|
*/
|
||||||
reset: function() {
|
reset: function() {
|
||||||
if ( window.jQuery ) {
|
if ( window.jQuery ) {
|
||||||
jQuery("#main, #qunit-fixture").html( config.fixture );
|
jQuery( "#main, #qunit-fixture" ).html( config.fixture );
|
||||||
|
} else {
|
||||||
|
var main = id( 'main' ) || id( 'qunit-fixture' );
|
||||||
|
if ( main ) {
|
||||||
|
main.innerHTML = config.fixture;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -469,6 +535,40 @@ extend(QUnit, {
|
||||||
return undefined;
|
return undefined;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
push: function(result, actual, expected, message) {
|
||||||
|
var details = {
|
||||||
|
result: result,
|
||||||
|
message: message,
|
||||||
|
actual: actual,
|
||||||
|
expected: expected
|
||||||
|
};
|
||||||
|
|
||||||
|
message = escapeHtml(message) || (result ? "okay" : "failed");
|
||||||
|
message = '<span class="test-message">' + message + "</span>";
|
||||||
|
expected = escapeHtml(QUnit.jsDump.parse(expected));
|
||||||
|
actual = escapeHtml(QUnit.jsDump.parse(actual));
|
||||||
|
var output = message + '<table><tr class="test-expected"><th>Expected: </th><td><pre>' + expected + '</pre></td></tr>';
|
||||||
|
if (actual != expected) {
|
||||||
|
output += '<tr class="test-actual"><th>Result: </th><td><pre>' + actual + '</pre></td></tr>';
|
||||||
|
output += '<tr class="test-diff"><th>Diff: </th><td><pre>' + QUnit.diff(expected, actual) +'</pre></td></tr>';
|
||||||
|
}
|
||||||
|
if (!result) {
|
||||||
|
var source = sourceFromStacktrace();
|
||||||
|
if (source) {
|
||||||
|
details.source = source;
|
||||||
|
output += '<tr class="test-source"><th>Source: </th><td><pre>' + source +'</pre></td></tr>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
output += "</table>";
|
||||||
|
|
||||||
|
QUnit.log(result, message, details);
|
||||||
|
|
||||||
|
config.current.assertions.push({
|
||||||
|
result: !!result,
|
||||||
|
message: output
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
// Logging callbacks
|
// Logging callbacks
|
||||||
begin: function() {},
|
begin: function() {},
|
||||||
done: function(failures, total) {},
|
done: function(failures, total) {},
|
||||||
|
|
@ -499,7 +599,16 @@ addEvent(window, "load", function() {
|
||||||
}
|
}
|
||||||
var banner = id("qunit-header");
|
var banner = id("qunit-header");
|
||||||
if ( banner ) {
|
if ( banner ) {
|
||||||
banner.innerHTML = '<a href="' + location.href + '">' + banner.innerHTML + '</a>';
|
var paramsIndex = location.href.lastIndexOf(location.search);
|
||||||
|
if ( paramsIndex > -1 ) {
|
||||||
|
var mainPageLocation = location.href.slice(0, paramsIndex);
|
||||||
|
if ( mainPageLocation == location.href ) {
|
||||||
|
banner.innerHTML = '<a href=""> ' + banner.innerHTML + '</a> ';
|
||||||
|
} else {
|
||||||
|
var testName = decodeURIComponent(location.search.slice(1));
|
||||||
|
banner.innerHTML = '<a href="' + mainPageLocation + '">' + banner.innerHTML + '</a> › <a href="">' + testName + '</a>';
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var toolbar = id("qunit-testrunner-toolbar");
|
var toolbar = id("qunit-testrunner-toolbar");
|
||||||
|
|
@ -524,25 +633,6 @@ addEvent(window, "load", function() {
|
||||||
label.setAttribute("for", "qunit-filter-pass");
|
label.setAttribute("for", "qunit-filter-pass");
|
||||||
label.innerHTML = "Hide passed tests";
|
label.innerHTML = "Hide passed tests";
|
||||||
toolbar.appendChild( label );
|
toolbar.appendChild( label );
|
||||||
|
|
||||||
var missing = document.createElement("input");
|
|
||||||
missing.type = "checkbox";
|
|
||||||
missing.id = "qunit-filter-missing";
|
|
||||||
missing.disabled = true;
|
|
||||||
addEvent( missing, "click", function() {
|
|
||||||
var li = document.getElementsByTagName("li");
|
|
||||||
for ( var i = 0; i < li.length; i++ ) {
|
|
||||||
if ( li[i].className.indexOf("fail") > -1 && li[i].innerHTML.indexOf('missing test - untested code is broken code') > - 1 ) {
|
|
||||||
li[i].parentNode.parentNode.style.display = missing.checked ? "none" : "block";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
toolbar.appendChild( missing );
|
|
||||||
|
|
||||||
label = document.createElement("label");
|
|
||||||
label.setAttribute("for", "qunit-filter-missing");
|
|
||||||
label.innerHTML = "Hide missing tests (untested code is broken code)";
|
|
||||||
toolbar.appendChild( label );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var main = id('main') || id('qunit-fixture');
|
var main = id('main') || id('qunit-fixture');
|
||||||
|
|
@ -556,23 +646,6 @@ addEvent(window, "load", function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
function done() {
|
function done() {
|
||||||
if ( config.doneTimer && window.clearTimeout ) {
|
|
||||||
window.clearTimeout( config.doneTimer );
|
|
||||||
config.doneTimer = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( config.queue.length ) {
|
|
||||||
config.doneTimer = window.setTimeout(function(){
|
|
||||||
if ( !config.queue.length ) {
|
|
||||||
done();
|
|
||||||
} else {
|
|
||||||
synchronize( done );
|
|
||||||
}
|
|
||||||
}, 13);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
config.autorun = true;
|
config.autorun = true;
|
||||||
|
|
||||||
// Log the last module results
|
// Log the last module results
|
||||||
|
|
@ -634,8 +707,31 @@ function validTest( name ) {
|
||||||
return run;
|
return run;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// so far supports only Firefox, Chrome and Opera (buggy)
|
||||||
|
// could be extended in the future to use something like https://github.com/csnover/TraceKit
|
||||||
|
function sourceFromStacktrace() {
|
||||||
|
try {
|
||||||
|
throw new Error();
|
||||||
|
} catch ( e ) {
|
||||||
|
if (e.stacktrace) {
|
||||||
|
// Opera
|
||||||
|
return e.stacktrace.split("\n")[6];
|
||||||
|
} else if (e.stack) {
|
||||||
|
// Firefox, Chrome
|
||||||
|
return e.stack.split("\n")[4];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function resultDisplayStyle(passed) {
|
||||||
|
return passed && id("qunit-filter-pass") && id("qunit-filter-pass").checked ? 'none' : '';
|
||||||
|
}
|
||||||
|
|
||||||
function escapeHtml(s) {
|
function escapeHtml(s) {
|
||||||
s = s === null ? "" : s + "";
|
if (!s) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
s = s + "";
|
||||||
return s.replace(/[\&"<>\\]/g, function(s) {
|
return s.replace(/[\&"<>\\]/g, function(s) {
|
||||||
switch(s) {
|
switch(s) {
|
||||||
case "&": return "&";
|
case "&": return "&";
|
||||||
|
|
@ -648,24 +744,6 @@ function escapeHtml(s) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function push(result, actual, expected, message) {
|
|
||||||
message = escapeHtml(message) || (result ? "okay" : "failed");
|
|
||||||
message = '<span class="test-message">' + message + "</span>";
|
|
||||||
expected = escapeHtml(QUnit.jsDump.parse(expected));
|
|
||||||
actual = escapeHtml(QUnit.jsDump.parse(actual));
|
|
||||||
var output = message + ', expected: <span class="test-expected">' + expected + '</span>';
|
|
||||||
if (actual != expected) {
|
|
||||||
output += ' result: <span class="test-actual">' + actual + '</span>, diff: ' + QUnit.diff(expected, actual);
|
|
||||||
}
|
|
||||||
|
|
||||||
// can't use ok, as that would double-escape messages
|
|
||||||
QUnit.log(result, output);
|
|
||||||
config.assertions.push({
|
|
||||||
result: !!result,
|
|
||||||
message: output
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function synchronize( callback ) {
|
function synchronize( callback ) {
|
||||||
config.queue.push( callback );
|
config.queue.push( callback );
|
||||||
|
|
||||||
|
|
@ -680,12 +758,14 @@ function process() {
|
||||||
while ( config.queue.length && !config.blocking ) {
|
while ( config.queue.length && !config.blocking ) {
|
||||||
if ( config.updateRate <= 0 || (((new Date()).getTime() - start) < config.updateRate) ) {
|
if ( config.updateRate <= 0 || (((new Date()).getTime() - start) < config.updateRate) ) {
|
||||||
config.queue.shift()();
|
config.queue.shift()();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
setTimeout( process, 13 );
|
window.setTimeout( process, 13 );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!config.blocking && !config.queue.length) {
|
||||||
|
done();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveGlobal() {
|
function saveGlobal() {
|
||||||
|
|
@ -705,13 +785,13 @@ function checkPollution( name ) {
|
||||||
var newGlobals = diff( old, config.pollution );
|
var newGlobals = diff( old, config.pollution );
|
||||||
if ( newGlobals.length > 0 ) {
|
if ( newGlobals.length > 0 ) {
|
||||||
ok( false, "Introduced global variable(s): " + newGlobals.join(", ") );
|
ok( false, "Introduced global variable(s): " + newGlobals.join(", ") );
|
||||||
config.expected++;
|
config.current.expected++;
|
||||||
}
|
}
|
||||||
|
|
||||||
var deletedGlobals = diff( config.pollution, old );
|
var deletedGlobals = diff( config.pollution, old );
|
||||||
if ( deletedGlobals.length > 0 ) {
|
if ( deletedGlobals.length > 0 ) {
|
||||||
ok( false, "Deleted global variable(s): " + deletedGlobals.join(", ") );
|
ok( false, "Deleted global variable(s): " + deletedGlobals.join(", ") );
|
||||||
config.expected++;
|
config.current.expected++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -988,7 +1068,7 @@ QUnit.jsDump = (function() {
|
||||||
type = "date";
|
type = "date";
|
||||||
} else if (QUnit.is("Function", obj)) {
|
} else if (QUnit.is("Function", obj)) {
|
||||||
type = "function";
|
type = "function";
|
||||||
} else if (obj.setInterval && obj.document && !obj.nodeType) {
|
} else if (typeof obj.setInterval !== undefined && typeof obj.document !== "undefined" && typeof obj.nodeType === "undefined") {
|
||||||
type = "window";
|
type = "window";
|
||||||
} else if (obj.nodeType === 9) {
|
} else if (obj.nodeType === 9) {
|
||||||
type = "document";
|
type = "document";
|
||||||
|
|
@ -1042,31 +1122,31 @@ QUnit.jsDump = (function() {
|
||||||
ret += ' ' + name;
|
ret += ' ' + name;
|
||||||
ret += '(';
|
ret += '(';
|
||||||
|
|
||||||
ret = [ ret, this.parse( fn, 'functionArgs' ), '){'].join('');
|
ret = [ ret, QUnit.jsDump.parse( fn, 'functionArgs' ), '){'].join('');
|
||||||
return join( ret, this.parse(fn,'functionCode'), '}' );
|
return join( ret, QUnit.jsDump.parse(fn,'functionCode'), '}' );
|
||||||
},
|
},
|
||||||
array: array,
|
array: array,
|
||||||
nodelist: array,
|
nodelist: array,
|
||||||
arguments: array,
|
arguments: array,
|
||||||
object:function( map ) {
|
object:function( map ) {
|
||||||
var ret = [ ];
|
var ret = [ ];
|
||||||
this.up();
|
QUnit.jsDump.up();
|
||||||
for ( var key in map )
|
for ( var key in map )
|
||||||
ret.push( this.parse(key,'key') + ': ' + this.parse(map[key]) );
|
ret.push( QUnit.jsDump.parse(key,'key') + ': ' + QUnit.jsDump.parse(map[key]) );
|
||||||
this.down();
|
QUnit.jsDump.down();
|
||||||
return join( '{', ret, '}' );
|
return join( '{', ret, '}' );
|
||||||
},
|
},
|
||||||
node:function( node ) {
|
node:function( node ) {
|
||||||
var open = this.HTML ? '<' : '<',
|
var open = QUnit.jsDump.HTML ? '<' : '<',
|
||||||
close = this.HTML ? '>' : '>';
|
close = QUnit.jsDump.HTML ? '>' : '>';
|
||||||
|
|
||||||
var tag = node.nodeName.toLowerCase(),
|
var tag = node.nodeName.toLowerCase(),
|
||||||
ret = open + tag;
|
ret = open + tag;
|
||||||
|
|
||||||
for ( var a in this.DOMAttrs ) {
|
for ( var a in QUnit.jsDump.DOMAttrs ) {
|
||||||
var val = node[this.DOMAttrs[a]];
|
var val = node[QUnit.jsDump.DOMAttrs[a]];
|
||||||
if ( val )
|
if ( val )
|
||||||
ret += ' ' + a + '=' + this.parse( val, 'attribute' );
|
ret += ' ' + a + '=' + QUnit.jsDump.parse( val, 'attribute' );
|
||||||
}
|
}
|
||||||
return ret + close + open + '/' + tag + close;
|
return ret + close + open + '/' + tag + close;
|
||||||
},
|
},
|
||||||
|
|
@ -1094,8 +1174,8 @@ QUnit.jsDump = (function() {
|
||||||
'class':'className'
|
'class':'className'
|
||||||
},
|
},
|
||||||
HTML:false,//if true, entities are escaped ( <, >, \t, space and \n )
|
HTML:false,//if true, entities are escaped ( <, >, \t, space and \n )
|
||||||
indentChar:' ',//indentation unit
|
indentChar:' ',//indentation unit
|
||||||
multiline:false //if true, items in a collection, are separated by a \n, else just a space.
|
multiline:true //if true, items in a collection, are separated by a \n, else just a space.
|
||||||
};
|
};
|
||||||
|
|
||||||
return jsDump;
|
return jsDump;
|
||||||
|
|
@ -1255,7 +1335,7 @@ QUnit.diff = (function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
})(this);
|
})(this);
|
||||||
|
|
|
||||||
|
|
@ -2,150 +2,148 @@
|
||||||
* mobile core unit tests
|
* mobile core unit tests
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function( $ ) {
|
var libName = "jquery.mobile.core.js",
|
||||||
var libName = "jquery.mobile.core.js",
|
setGradeA = function(value) { $.support.mediaquery = value; },
|
||||||
setGradeA = function(value) { $.support.mediaquery = value; },
|
extendFn = $.extend;
|
||||||
extendFn = $.extend;
|
|
||||||
|
|
||||||
module(libName, {
|
module(libName, {
|
||||||
setup: function(){
|
setup: function(){
|
||||||
// NOTE reset for gradeA tests
|
// NOTE reset for gradeA tests
|
||||||
$('html').removeClass('ui-mobile');
|
$('html').removeClass('ui-mobile');
|
||||||
|
|
||||||
// NOTE reset for pageLoading tests
|
// NOTE reset for pageLoading tests
|
||||||
$('.ui-loader').remove();
|
$('.ui-loader').remove();
|
||||||
},
|
},
|
||||||
teardown: function(){
|
teardown: function(){
|
||||||
$.extend = extendFn;
|
$.extend = extendFn;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$.testHelper.excludeFileProtocol(function(){
|
||||||
|
test( "grade A browser support media queries", function(){
|
||||||
|
setGradeA(false);
|
||||||
|
$.testHelper.reloadLib(libName);
|
||||||
|
ok(!$.mobile.gradeA());
|
||||||
|
|
||||||
|
setGradeA(true);
|
||||||
|
$.testHelper.reloadLib(libName);
|
||||||
|
ok($.mobile.gradeA());
|
||||||
});
|
});
|
||||||
|
|
||||||
$.testHelper.excludeFileProtocol(function(){
|
test( "loading the core library triggers mobilinit on the document", function(){
|
||||||
test( "grade A browser support media queries", function(){
|
expect( 1 );
|
||||||
setGradeA(false);
|
|
||||||
$.testHelper.reloadLib(libName);
|
|
||||||
ok(!$.mobile.gradeA());
|
|
||||||
|
|
||||||
setGradeA(true);
|
$(window.document).bind('mobileinit', function(event){
|
||||||
$.testHelper.reloadLib(libName);
|
ok(true);
|
||||||
ok($.mobile.gradeA());
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test( "loading the core library triggers mobilinit on the document", function(){
|
$.testHelper.reloadLib(libName);
|
||||||
expect( 1 );
|
|
||||||
|
|
||||||
$(window.document).bind('mobileinit', function(event){
|
|
||||||
ok(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
$.testHelper.reloadLib(libName);
|
|
||||||
});
|
|
||||||
|
|
||||||
test( "enhancments are skipped when the browser is not grade A", function(){
|
|
||||||
setGradeA(false);
|
|
||||||
$.testHelper.reloadLib(libName);
|
|
||||||
|
|
||||||
//NOTE easiest way to check for enhancements, not the most obvious
|
|
||||||
ok(!$("html").hasClass("ui-mobile"));
|
|
||||||
});
|
|
||||||
|
|
||||||
test( "enhancments are added when the browser is grade A", function(){
|
|
||||||
setGradeA(true);
|
|
||||||
$.testHelper.reloadLib(libName);
|
|
||||||
|
|
||||||
ok($("html").hasClass("ui-mobile"));
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
//TODO lots of duplication
|
|
||||||
test( "pageLoading doesn't add the dialog to the page when loading message is false", function(){
|
|
||||||
$.testHelper.alterExtend({loadingMessage: false});
|
|
||||||
$.testHelper.reloadLib(libName);
|
|
||||||
$.mobile.pageLoading(false);
|
|
||||||
ok(!$(".ui-loader").length);
|
|
||||||
});
|
|
||||||
|
|
||||||
test( "pageLoading doesn't add the dialog to the page when done is passed as true", function(){
|
|
||||||
$.testHelper.alterExtend({loadingMessage: true});
|
|
||||||
$.testHelper.reloadLib(libName);
|
|
||||||
|
|
||||||
// TODO add post reload callback
|
|
||||||
$('.ui-loader').remove();
|
|
||||||
|
|
||||||
$.mobile.pageLoading(true);
|
|
||||||
ok(!$(".ui-loader").length);
|
|
||||||
});
|
|
||||||
|
|
||||||
test( "pageLoading adds the dialog to the page when done is true", function(){
|
|
||||||
$.testHelper.alterExtend({loadingMessage: true});
|
|
||||||
$.testHelper.reloadLib(libName);
|
|
||||||
$.mobile.pageLoading(false);
|
|
||||||
ok($(".ui-loader").length);
|
|
||||||
});
|
|
||||||
|
|
||||||
var metaViewportSelector = "head meta[name=viewport]",
|
|
||||||
setViewPortContent = function(value){
|
|
||||||
$(metaViewportSelector).remove();
|
|
||||||
$.testHelper.alterExtend({metaViewportContent: value});
|
|
||||||
$.testHelper.reloadLib(libName);
|
|
||||||
};
|
|
||||||
|
|
||||||
test( "meta view port element is added to head when defined on mobile", function(){
|
|
||||||
setViewPortContent("width=device-width");
|
|
||||||
same($(metaViewportSelector).length, 1);
|
|
||||||
});
|
|
||||||
|
|
||||||
test( "meta view port element not added to head when not defined on mobile", function(){
|
|
||||||
setViewPortContent(false);
|
|
||||||
same($(metaViewportSelector).length, 0);
|
|
||||||
});
|
|
||||||
|
|
||||||
var findFirstPage = function() {
|
|
||||||
return $("[data-role='page']").first();
|
|
||||||
};
|
|
||||||
|
|
||||||
test( "active page and start page should be set to the fist page in the selected set", function(){
|
|
||||||
var firstPage = findFirstPage();
|
|
||||||
$.testHelper.reloadLib(libName);
|
|
||||||
|
|
||||||
same($.mobile.startPage, firstPage);
|
|
||||||
same($.mobile.activePage, firstPage);
|
|
||||||
});
|
|
||||||
|
|
||||||
test( "mobile viewport class is defined on the first page's parent", function(){
|
|
||||||
var firstPage = findFirstPage();
|
|
||||||
$.testHelper.reloadLib(libName);
|
|
||||||
|
|
||||||
ok(firstPage.parent().hasClass('ui-mobile-viewport'));
|
|
||||||
});
|
|
||||||
|
|
||||||
test( "mobile page container is the first page's parent", function(){
|
|
||||||
var firstPage = findFirstPage();
|
|
||||||
$.testHelper.reloadLib(libName);
|
|
||||||
|
|
||||||
same($.mobile.pageContainer, firstPage.parent());
|
|
||||||
});
|
|
||||||
|
|
||||||
test( "page loading is called on document ready", function(){
|
|
||||||
expect( 2 );
|
|
||||||
|
|
||||||
$.testHelper.alterExtend({ pageLoading: function(){
|
|
||||||
ok("called");
|
|
||||||
}});
|
|
||||||
|
|
||||||
$.testHelper.reloadLib(libName);
|
|
||||||
});
|
|
||||||
|
|
||||||
test( "hashchange triggered on document ready with single argument: true", function(){
|
|
||||||
expect( 2 );
|
|
||||||
|
|
||||||
$(window).bind("hashchange", function(ev, arg){
|
|
||||||
same(arg, true);
|
|
||||||
});
|
|
||||||
|
|
||||||
$.testHelper.reloadLib(libName);
|
|
||||||
});
|
|
||||||
|
|
||||||
//TODO test that silentScroll is called on window load
|
|
||||||
});
|
});
|
||||||
})(jQuery);
|
|
||||||
|
test( "enhancments are skipped when the browser is not grade A", function(){
|
||||||
|
setGradeA(false);
|
||||||
|
$.testHelper.reloadLib(libName);
|
||||||
|
|
||||||
|
//NOTE easiest way to check for enhancements, not the most obvious
|
||||||
|
ok(!$("html").hasClass("ui-mobile"));
|
||||||
|
});
|
||||||
|
|
||||||
|
test( "enhancments are added when the browser is grade A", function(){
|
||||||
|
setGradeA(true);
|
||||||
|
$.testHelper.reloadLib(libName);
|
||||||
|
|
||||||
|
ok($("html").hasClass("ui-mobile"));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
//TODO lots of duplication
|
||||||
|
test( "pageLoading doesn't add the dialog to the page when loading message is false", function(){
|
||||||
|
$.testHelper.alterExtend({loadingMessage: false});
|
||||||
|
$.testHelper.reloadLib(libName);
|
||||||
|
$.mobile.pageLoading(false);
|
||||||
|
ok(!$(".ui-loader").length);
|
||||||
|
});
|
||||||
|
|
||||||
|
test( "pageLoading doesn't add the dialog to the page when done is passed as true", function(){
|
||||||
|
$.testHelper.alterExtend({loadingMessage: true});
|
||||||
|
$.testHelper.reloadLib(libName);
|
||||||
|
|
||||||
|
// TODO add post reload callback
|
||||||
|
$('.ui-loader').remove();
|
||||||
|
|
||||||
|
$.mobile.pageLoading(true);
|
||||||
|
ok(!$(".ui-loader").length);
|
||||||
|
});
|
||||||
|
|
||||||
|
test( "pageLoading adds the dialog to the page when done is true", function(){
|
||||||
|
$.testHelper.alterExtend({loadingMessage: true});
|
||||||
|
$.testHelper.reloadLib(libName);
|
||||||
|
$.mobile.pageLoading(false);
|
||||||
|
ok($(".ui-loader").length);
|
||||||
|
});
|
||||||
|
|
||||||
|
var metaViewportSelector = "head meta[name=viewport]",
|
||||||
|
setViewPortContent = function(value){
|
||||||
|
$(metaViewportSelector).remove();
|
||||||
|
$.testHelper.alterExtend({metaViewportContent: value});
|
||||||
|
$.testHelper.reloadLib(libName);
|
||||||
|
};
|
||||||
|
|
||||||
|
test( "meta view port element is added to head when defined on mobile", function(){
|
||||||
|
setViewPortContent("width=device-width");
|
||||||
|
same($(metaViewportSelector).length, 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test( "meta view port element not added to head when not defined on mobile", function(){
|
||||||
|
setViewPortContent(false);
|
||||||
|
same($(metaViewportSelector).length, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
var findFirstPage = function() {
|
||||||
|
return $("[data-role='page']").first();
|
||||||
|
};
|
||||||
|
|
||||||
|
test( "active page and start page should be set to the fist page in the selected set", function(){
|
||||||
|
var firstPage = findFirstPage();
|
||||||
|
$.testHelper.reloadLib(libName);
|
||||||
|
|
||||||
|
same($.mobile.startPage, firstPage);
|
||||||
|
same($.mobile.activePage, firstPage);
|
||||||
|
});
|
||||||
|
|
||||||
|
test( "mobile viewport class is defined on the first page's parent", function(){
|
||||||
|
var firstPage = findFirstPage();
|
||||||
|
$.testHelper.reloadLib(libName);
|
||||||
|
|
||||||
|
ok(firstPage.parent().hasClass('ui-mobile-viewport'));
|
||||||
|
});
|
||||||
|
|
||||||
|
test( "mobile page container is the first page's parent", function(){
|
||||||
|
var firstPage = findFirstPage();
|
||||||
|
$.testHelper.reloadLib(libName);
|
||||||
|
|
||||||
|
same($.mobile.pageContainer, firstPage.parent());
|
||||||
|
});
|
||||||
|
|
||||||
|
test( "page loading is called on document ready", function(){
|
||||||
|
expect( 2 );
|
||||||
|
|
||||||
|
$.testHelper.alterExtend({ pageLoading: function(){
|
||||||
|
ok("called");
|
||||||
|
}});
|
||||||
|
|
||||||
|
$.testHelper.reloadLib(libName);
|
||||||
|
});
|
||||||
|
|
||||||
|
test( "hashchange triggered on document ready with single argument: true", function(){
|
||||||
|
expect( 2 );
|
||||||
|
|
||||||
|
$(window).bind("hashchange", function(ev, arg){
|
||||||
|
same(arg, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
$.testHelper.reloadLib(libName);
|
||||||
|
});
|
||||||
|
|
||||||
|
//TODO test that silentScroll is called on window load
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -2,73 +2,71 @@
|
||||||
* mobile core unit tests
|
* mobile core unit tests
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function( $ ) {
|
var libName = "jquery.mobile.core.js",
|
||||||
var libName = "jquery.mobile.core.js",
|
scrollTimeout = 20, // TODO expose timing as an attribute
|
||||||
scrollTimeout = 20, // TODO expose timing as an attribute
|
scrollStartEnabledTimeout = 150;
|
||||||
scrollStartEnabledTimeout = 150;
|
|
||||||
|
|
||||||
module(libName, {
|
module(libName, {
|
||||||
setup: function(){
|
setup: function(){
|
||||||
$("<div id='scroll-testing' style='height: 1000px'></div>").appendTo("body");
|
$("<div id='scroll-testing' style='height: 1000px'></div>").appendTo("body");
|
||||||
},
|
},
|
||||||
|
|
||||||
teardown: function(){
|
teardown: function(){
|
||||||
$("#scroll-testing").remove();
|
$("#scroll-testing").remove();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var scrollUp = function( pos ){
|
var scrollUp = function( pos ){
|
||||||
$(window).scrollTop(1000);
|
$(window).scrollTop(1000);
|
||||||
ok($(window).scrollTop() > 0);
|
ok($(window).scrollTop() > 0);
|
||||||
|
|
||||||
if(pos) {
|
if(pos) {
|
||||||
$.mobile.silentScroll(pos);
|
$.mobile.silentScroll(pos);
|
||||||
} else {
|
} else {
|
||||||
$.mobile.silentScroll();
|
$.mobile.silentScroll();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
test( "silent scroll scrolls the page to the top by default", function(){
|
test( "silent scroll scrolls the page to the top by default", function(){
|
||||||
scrollUp();
|
scrollUp();
|
||||||
|
|
||||||
stop();
|
stop();
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
same($(window).scrollTop(), 0);
|
same($(window).scrollTop(), 0);
|
||||||
start();
|
start();
|
||||||
}, scrollTimeout);
|
}, scrollTimeout);
|
||||||
});
|
});
|
||||||
|
|
||||||
test( "silent scroll scrolls the page to the passed y position", function(){
|
test( "silent scroll scrolls the page to the passed y position", function(){
|
||||||
var pos = 10;
|
var pos = 10;
|
||||||
scrollUp(pos);
|
scrollUp(pos);
|
||||||
|
|
||||||
stop();
|
stop();
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
same($(window).scrollTop(), pos);
|
same($(window).scrollTop(), pos);
|
||||||
start();
|
start();
|
||||||
}, scrollTimeout);
|
}, scrollTimeout);
|
||||||
});
|
});
|
||||||
|
|
||||||
// NOTE may be brittle depending on timing
|
// NOTE may be brittle depending on timing
|
||||||
test( "silent scroll takes at least 20 ms to scroll to the top", function(){
|
test( "silent scroll takes at least 20 ms to scroll to the top", function(){
|
||||||
scrollUp();
|
scrollUp();
|
||||||
|
|
||||||
stop();
|
stop();
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
ok($(window).scrollTop() != 0);
|
ok($(window).scrollTop() != 0);
|
||||||
start();
|
start();
|
||||||
}, scrollTimeout - 1);
|
}, scrollTimeout - 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test( "scrolling marks scrollstart as disabled for 150 ms", function(){
|
test( "scrolling marks scrollstart as disabled for 150 ms", function(){
|
||||||
$.event.special.scrollstart.enabled = true;
|
$.event.special.scrollstart.enabled = true;
|
||||||
scrollUp();
|
scrollUp();
|
||||||
ok(!$.event.special.scrollstart.enabled);
|
ok(!$.event.special.scrollstart.enabled);
|
||||||
|
|
||||||
stop();
|
stop();
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
ok($.event.special.scrollstart.enabled);
|
ok($.event.special.scrollstart.enabled);
|
||||||
start();
|
start();
|
||||||
}, scrollStartEnabledTimeout);
|
}, scrollStartEnabledTimeout);
|
||||||
});
|
});
|
||||||
})(jQuery);
|
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@
|
||||||
<ol id="qunit-tests">
|
<ol id="qunit-tests">
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<div id="main" style="position: absolute; top: -10000px; left: -10000px;">
|
<div id="qunit-fixture">
|
||||||
<div data-role="page">
|
<div data-role="page">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -2,350 +2,348 @@
|
||||||
* mobile event unit tests
|
* mobile event unit tests
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function( $ ) {
|
var libName = "jquery.mobile.event.js",
|
||||||
var libName = "jquery.mobile.event.js",
|
absFn = Math.abs,
|
||||||
absFn = Math.abs,
|
originalEventFn = $.Event.prototype.originalEvent,
|
||||||
originalEventFn = $.Event.prototype.originalEvent,
|
preventDefaultFn = $.Event.prototype.preventDefault,
|
||||||
preventDefaultFn = $.Event.prototype.preventDefault,
|
events = ("touchstart touchmove touchend orientationchange tap taphold " +
|
||||||
events = ("touchstart touchmove touchend orientationchange tap taphold " +
|
"swipe swipeleft swiperight scrollstart scrollstop").split( " " );
|
||||||
"swipe swipeleft swiperight scrollstart scrollstop").split( " " );
|
|
||||||
|
|
||||||
module(libName, {
|
module(libName, {
|
||||||
teardown: function(){
|
teardown: function(){
|
||||||
$.each(events, function(i, name){
|
|
||||||
$("#main").unbind(name);
|
|
||||||
});
|
|
||||||
|
|
||||||
$($.event.special.scrollstart).unbind("scrollstart");
|
|
||||||
$($.event.special.tap).unbind("tap");
|
|
||||||
$($.event.special.tap).unbind("taphold");
|
|
||||||
$($.event.special.swipe).unbind("swipe");
|
|
||||||
|
|
||||||
//NOTE unmock
|
|
||||||
Math.abs = absFn;
|
|
||||||
$.Event.prototype.originalEvent = originalEventFn;
|
|
||||||
$.Event.prototype.preventDefault = preventDefaultFn;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$.testHelper.excludeFileProtocol(function(){
|
|
||||||
test( "new events defined on the jquery object", function(){
|
|
||||||
$.each(events, function( i, name ) {
|
|
||||||
delete $.fn[name];
|
|
||||||
same($.fn[name], undefined);
|
|
||||||
});
|
|
||||||
|
|
||||||
$.testHelper.reloadLib(libName);
|
|
||||||
|
|
||||||
$.each($.fn.clone(events), function( i, name ) {
|
|
||||||
ok($.fn[name] !== undefined, name + "is not undefined");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test( "defined event functions bind a closure when passed", function(){
|
|
||||||
expect( 1 );
|
|
||||||
|
|
||||||
$('#main')[events[0]](function(){
|
|
||||||
ok(true, "event fired");
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#main').trigger(events[0]);
|
|
||||||
});
|
|
||||||
|
|
||||||
test( "defined event functions trigger the event with no arguments", function(){
|
|
||||||
expect( 1 );
|
|
||||||
|
|
||||||
$('#main')[events[0]](function(){
|
|
||||||
ok(true, "event fired");
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#main')[events[0]]();
|
|
||||||
});
|
|
||||||
|
|
||||||
test( "defining event functions sets the attrFn to true", function(){
|
|
||||||
$.each(events, function(i, name){
|
$.each(events, function(i, name){
|
||||||
ok($.attrFn[name], "attribute function is true");
|
$("#qunit-fixture").unbind(name);
|
||||||
|
});
|
||||||
|
|
||||||
|
$($.event.special.scrollstart).unbind("scrollstart");
|
||||||
|
$($.event.special.tap).unbind("tap");
|
||||||
|
$($.event.special.tap).unbind("taphold");
|
||||||
|
$($.event.special.swipe).unbind("swipe");
|
||||||
|
|
||||||
|
//NOTE unmock
|
||||||
|
Math.abs = absFn;
|
||||||
|
$.Event.prototype.originalEvent = originalEventFn;
|
||||||
|
$.Event.prototype.preventDefault = preventDefaultFn;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$.testHelper.excludeFileProtocol(function(){
|
||||||
|
test( "new events defined on the jquery object", function(){
|
||||||
|
$.each(events, function( i, name ) {
|
||||||
|
delete $.fn[name];
|
||||||
|
same($.fn[name], undefined);
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
test( "scrollstart enabled defaults to true", function(){
|
|
||||||
$.event.special.scrollstart.enabled = false;
|
|
||||||
$.testHelper.reloadLib(libName);
|
$.testHelper.reloadLib(libName);
|
||||||
ok($.event.special.scrollstart.enabled, "scrollstart enabled");
|
|
||||||
|
$.each($.fn.clone(events), function( i, name ) {
|
||||||
|
ok($.fn[name] !== undefined, name + "is not undefined");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test( "defined event functions bind a closure when passed", function(){
|
||||||
|
expect( 1 );
|
||||||
|
|
||||||
|
$('#qunit-fixture')[events[0]](function(){
|
||||||
|
ok(true, "event fired");
|
||||||
});
|
});
|
||||||
|
|
||||||
test( "scrollstart setup binds a function that returns when its disabled", function(){
|
$('#qunit-fixture').trigger(events[0]);
|
||||||
expect( 1 );
|
});
|
||||||
$.event.special.scrollstart.enabled = false;
|
|
||||||
|
|
||||||
$($.event.special.scrollstart).bind("scrollstart", function(){
|
test( "defined event functions trigger the event with no arguments", function(){
|
||||||
ok(false, "scrollstart fired");
|
expect( 1 );
|
||||||
});
|
|
||||||
|
|
||||||
$($.event.special.scrollstart).bind("touchmove", function(){
|
$('#qunit-fixture')[events[0]](function(){
|
||||||
ok(true, "touchmove fired");
|
ok(true, "event fired");
|
||||||
});
|
|
||||||
|
|
||||||
$($.event.special.scrollstart).trigger("touchmove");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test( "scrollstart setup binds a function that triggers scroll start when enabled", function(){
|
$('#qunit-fixture')[events[0]]();
|
||||||
$.event.special.scrollstart.enabled = true;
|
});
|
||||||
|
|
||||||
$($.event.special.scrollstart).bind("scrollstart", function(){
|
test( "defining event functions sets the attrFn to true", function(){
|
||||||
ok(true, "scrollstart fired");
|
$.each(events, function(i, name){
|
||||||
});
|
ok($.attrFn[name], "attribute function is true");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
$($.event.special.scrollstart).trigger("touchmove");
|
test( "scrollstart enabled defaults to true", function(){
|
||||||
|
$.event.special.scrollstart.enabled = false;
|
||||||
|
$.testHelper.reloadLib(libName);
|
||||||
|
ok($.event.special.scrollstart.enabled, "scrollstart enabled");
|
||||||
|
});
|
||||||
|
|
||||||
|
test( "scrollstart setup binds a function that returns when its disabled", function(){
|
||||||
|
expect( 1 );
|
||||||
|
$.event.special.scrollstart.enabled = false;
|
||||||
|
|
||||||
|
$($.event.special.scrollstart).bind("scrollstart", function(){
|
||||||
|
ok(false, "scrollstart fired");
|
||||||
});
|
});
|
||||||
|
|
||||||
test( "scrollstart setup binds a function that triggers scroll stop after 50 ms", function(){
|
$($.event.special.scrollstart).bind("touchmove", function(){
|
||||||
var triggered = false;
|
ok(true, "touchmove fired");
|
||||||
$.event.special.scrollstart.enabled = true;
|
|
||||||
|
|
||||||
$($.event.special.scrollstart).bind("scrollstop", function(){
|
|
||||||
triggered = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
ok(!triggered, "not triggered");
|
|
||||||
|
|
||||||
$($.event.special.scrollstart).trigger("touchmove");
|
|
||||||
|
|
||||||
stop();
|
|
||||||
setTimeout(function(){
|
|
||||||
ok(triggered, "triggered");
|
|
||||||
start();
|
|
||||||
}, 50);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var forceTouchSupport = function(){
|
$($.event.special.scrollstart).trigger("touchmove");
|
||||||
$.support.touch = true;
|
});
|
||||||
$.testHelper.reloadLib(libName);
|
|
||||||
|
test( "scrollstart setup binds a function that triggers scroll start when enabled", function(){
|
||||||
|
$.event.special.scrollstart.enabled = true;
|
||||||
|
|
||||||
|
$($.event.special.scrollstart).bind("scrollstart", function(){
|
||||||
|
ok(true, "scrollstart fired");
|
||||||
|
});
|
||||||
|
|
||||||
|
$($.event.special.scrollstart).trigger("touchmove");
|
||||||
|
});
|
||||||
|
|
||||||
|
test( "scrollstart setup binds a function that triggers scroll stop after 50 ms", function(){
|
||||||
|
var triggered = false;
|
||||||
|
$.event.special.scrollstart.enabled = true;
|
||||||
|
|
||||||
|
$($.event.special.scrollstart).bind("scrollstop", function(){
|
||||||
|
triggered = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
ok(!triggered, "not triggered");
|
||||||
|
|
||||||
|
$($.event.special.scrollstart).trigger("touchmove");
|
||||||
|
|
||||||
|
stop();
|
||||||
|
setTimeout(function(){
|
||||||
|
ok(triggered, "triggered");
|
||||||
|
start();
|
||||||
|
}, 50);
|
||||||
|
});
|
||||||
|
|
||||||
|
var forceTouchSupport = function(){
|
||||||
|
$.support.touch = true;
|
||||||
|
$.testHelper.reloadLib(libName);
|
||||||
|
};
|
||||||
|
|
||||||
|
test( "long press fires tap hold after 750 ms", function(){
|
||||||
|
var taphold = false;
|
||||||
|
|
||||||
|
forceTouchSupport();
|
||||||
|
|
||||||
|
$($.event.special.tap).bind("taphold", function(){
|
||||||
|
taphold = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
$($.event.special.tap).trigger("touchstart");
|
||||||
|
|
||||||
|
stop();
|
||||||
|
setTimeout(function(){
|
||||||
|
ok(taphold);
|
||||||
|
start();
|
||||||
|
}, 751);
|
||||||
|
});
|
||||||
|
|
||||||
|
//NOTE used to simulate movement when checked
|
||||||
|
//TODO find a better way ...
|
||||||
|
var mockAbs = function(value){
|
||||||
|
Math.abs = function(){
|
||||||
|
return value;
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
|
||||||
test( "long press fires tap hold after 750 ms", function(){
|
test( "touchmove prevents taphold", function(){
|
||||||
var taphold = false;
|
var taphold = false;
|
||||||
|
|
||||||
forceTouchSupport();
|
forceTouchSupport();
|
||||||
|
mockAbs(100);
|
||||||
|
|
||||||
$($.event.special.tap).bind("taphold", function(){
|
//NOTE record taphold event
|
||||||
taphold = true;
|
stop();
|
||||||
});
|
$($.event.special.tap).bind("taphold", function(){
|
||||||
|
taphold = true;
|
||||||
$($.event.special.tap).trigger("touchstart");
|
|
||||||
|
|
||||||
stop();
|
|
||||||
setTimeout(function(){
|
|
||||||
ok(taphold);
|
|
||||||
start();
|
|
||||||
}, 751);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//NOTE used to simulate movement when checked
|
//NOTE start the touch events
|
||||||
//TODO find a better way ...
|
$($.event.special.tap).trigger("touchstart");
|
||||||
var mockAbs = function(value){
|
|
||||||
Math.abs = function(){
|
|
||||||
return value;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
test( "touchmove prevents taphold", function(){
|
//NOTE fire touchmove to push back taphold
|
||||||
var taphold = false;
|
setTimeout(function(){
|
||||||
|
|
||||||
forceTouchSupport();
|
|
||||||
mockAbs(100);
|
|
||||||
|
|
||||||
//NOTE record taphold event
|
|
||||||
stop();
|
|
||||||
$($.event.special.tap).bind("taphold", function(){
|
|
||||||
taphold = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
//NOTE start the touch events
|
|
||||||
$($.event.special.tap).trigger("touchstart");
|
|
||||||
|
|
||||||
//NOTE fire touchmove to push back taphold
|
|
||||||
setTimeout(function(){
|
|
||||||
$($.event.special.tap).trigger("touchmove");
|
|
||||||
}, 100);
|
|
||||||
|
|
||||||
//NOTE verify that the taphold hasn't been fired
|
|
||||||
// with the normal timing
|
|
||||||
setTimeout(function(){
|
|
||||||
ok(!taphold, "taphold not fired");
|
|
||||||
start();
|
|
||||||
}, 751);
|
|
||||||
});
|
|
||||||
|
|
||||||
test( "tap event fired without movement", function(){
|
|
||||||
var tap = false;
|
|
||||||
|
|
||||||
forceTouchSupport();
|
|
||||||
|
|
||||||
//NOTE record the tap event
|
|
||||||
$($.event.special.tap).bind("tap", function(){
|
|
||||||
start();
|
|
||||||
tap = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
stop();
|
|
||||||
$($.event.special.tap).trigger("touchstart");
|
|
||||||
$($.event.special.tap).trigger("touchend");
|
|
||||||
|
|
||||||
ok(tap, "tapped");
|
|
||||||
});
|
|
||||||
|
|
||||||
test( "tap event not fired when there is movement", function(){
|
|
||||||
var tap = false;
|
|
||||||
forceTouchSupport();
|
|
||||||
|
|
||||||
//NOTE record tap event
|
|
||||||
$($.event.special.tap).bind("tap", function(){
|
|
||||||
tap = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
//NOTE make sure movement is recorded
|
|
||||||
mockAbs(100);
|
|
||||||
|
|
||||||
//NOTE start and move right away
|
|
||||||
$($.event.special.tap).trigger("touchstart");
|
|
||||||
$($.event.special.tap).trigger("touchmove");
|
$($.event.special.tap).trigger("touchmove");
|
||||||
|
}, 100);
|
||||||
|
|
||||||
//NOTE end touch sequence after 20 ms
|
//NOTE verify that the taphold hasn't been fired
|
||||||
stop();
|
// with the normal timing
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
$($.event.special.tap).trigger("touchend");
|
ok(!taphold, "taphold not fired");
|
||||||
start();
|
start();
|
||||||
}, 20);
|
}, 751);
|
||||||
|
});
|
||||||
|
|
||||||
ok(!tap, "not tapped");
|
test( "tap event fired without movement", function(){
|
||||||
|
var tap = false;
|
||||||
|
|
||||||
|
forceTouchSupport();
|
||||||
|
|
||||||
|
//NOTE record the tap event
|
||||||
|
$($.event.special.tap).bind("tap", function(){
|
||||||
|
start();
|
||||||
|
tap = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
var swipeTimedTest = function(opts){
|
stop();
|
||||||
var swipe = false;
|
$($.event.special.tap).trigger("touchstart");
|
||||||
|
$($.event.special.tap).trigger("touchend");
|
||||||
|
|
||||||
forceTouchSupport();
|
ok(tap, "tapped");
|
||||||
|
});
|
||||||
|
|
||||||
$($.event.special.swipe).bind('swipe', function(){
|
test( "tap event not fired when there is movement", function(){
|
||||||
swipe = true;
|
var tap = false;
|
||||||
start();
|
forceTouchSupport();
|
||||||
});
|
|
||||||
|
|
||||||
//NOTE bypass the trigger source check
|
//NOTE record tap event
|
||||||
$.Event.prototype.originalEvent = {
|
$($.event.special.tap).bind("tap", function(){
|
||||||
touches: false
|
tap = true;
|
||||||
};
|
});
|
||||||
|
|
||||||
$($.event.special.swipe).trigger("touchstart");
|
//NOTE make sure movement is recorded
|
||||||
|
mockAbs(100);
|
||||||
|
|
||||||
//NOTE make sure the coordinates are calculated within range
|
//NOTE start and move right away
|
||||||
// to be registered as a swipe
|
$($.event.special.tap).trigger("touchstart");
|
||||||
mockAbs(opts.coordChange);
|
$($.event.special.tap).trigger("touchmove");
|
||||||
|
|
||||||
setTimeout(function(){
|
//NOTE end touch sequence after 20 ms
|
||||||
$($.event.special.swipe).trigger("touchmove");
|
stop();
|
||||||
$($.event.special.swipe).trigger("touchend");
|
setTimeout(function(){
|
||||||
}, opts.timeout);
|
$($.event.special.tap).trigger("touchend");
|
||||||
|
start();
|
||||||
|
}, 20);
|
||||||
|
|
||||||
stop();
|
ok(!tap, "not tapped");
|
||||||
setTimeout(function(){
|
});
|
||||||
same(swipe, opts.expected, "swipe expected");
|
|
||||||
|
|
||||||
//NOTE the start in the event closure won't be fired, fire it here
|
var swipeTimedTest = function(opts){
|
||||||
if(!opts.expected) { start(); }
|
var swipe = false;
|
||||||
}, opts.timeout + 10);
|
|
||||||
|
forceTouchSupport();
|
||||||
|
|
||||||
|
$($.event.special.swipe).bind('swipe', function(){
|
||||||
|
swipe = true;
|
||||||
|
start();
|
||||||
|
});
|
||||||
|
|
||||||
|
//NOTE bypass the trigger source check
|
||||||
|
$.Event.prototype.originalEvent = {
|
||||||
|
touches: false
|
||||||
};
|
};
|
||||||
|
|
||||||
test( "swipe fired when coordinate change in less than a second", function(){
|
$($.event.special.swipe).trigger("touchstart");
|
||||||
swipeTimedTest({ timeout: 10, coordChange: 35, expected: true });
|
|
||||||
});
|
|
||||||
|
|
||||||
test( "swipe not fired when coordinate change takes more than a second", function(){
|
//NOTE make sure the coordinates are calculated within range
|
||||||
swipeTimedTest({ timeout: 1000, coordChange: 35, expected: false });
|
// to be registered as a swipe
|
||||||
});
|
mockAbs(opts.coordChange);
|
||||||
|
|
||||||
test( "swipe not fired when coordinate change <= 30", function(){
|
setTimeout(function(){
|
||||||
swipeTimedTest({ timeout: 1000, coordChange: 30, expected: false });
|
|
||||||
});
|
|
||||||
|
|
||||||
test( "swipe not fired when coordinate change >= 75", function(){
|
|
||||||
swipeTimedTest({ timeout: 1000, coordChange: 75, expected: false });
|
|
||||||
});
|
|
||||||
|
|
||||||
test( "scrolling prevented when coordinate change > 10", function(){
|
|
||||||
expect( 1 );
|
|
||||||
|
|
||||||
//NOTE bypass the trigger source check
|
|
||||||
$.Event.prototype.originalEvent = {
|
|
||||||
touches: false
|
|
||||||
};
|
|
||||||
|
|
||||||
$.Event.prototype.preventDefault = function(){
|
|
||||||
ok(true, "prevent default called");
|
|
||||||
};
|
|
||||||
|
|
||||||
mockAbs(11);
|
|
||||||
|
|
||||||
$($.event.special.swipe).trigger("touchstart");
|
|
||||||
$($.event.special.swipe).trigger("touchmove");
|
$($.event.special.swipe).trigger("touchmove");
|
||||||
});
|
|
||||||
|
|
||||||
test( "move handler returns when touchstart has been fired since touchstop", function(){
|
|
||||||
expect( 1 );
|
|
||||||
|
|
||||||
$.Event.prototype.originalEvent = {
|
|
||||||
touches: false
|
|
||||||
};
|
|
||||||
|
|
||||||
$($.event.special.swipe).trigger("touchstart");
|
|
||||||
$($.event.special.swipe).trigger("touchend");
|
$($.event.special.swipe).trigger("touchend");
|
||||||
|
}, opts.timeout);
|
||||||
|
|
||||||
$($.event.special.swipe).bind("touchmove", function(){
|
stop();
|
||||||
ok(true, "touchmove bound functions are fired");
|
setTimeout(function(){
|
||||||
});
|
same(swipe, opts.expected, "swipe expected");
|
||||||
|
|
||||||
Math.abs = function(){
|
//NOTE the start in the event closure won't be fired, fire it here
|
||||||
ok(false, "shouldn't compare coordinates");
|
if(!opts.expected) { start(); }
|
||||||
};
|
}, opts.timeout + 10);
|
||||||
|
};
|
||||||
|
|
||||||
$($.event.special.swipe).trigger("touchmove");
|
test( "swipe fired when coordinate change in less than a second", function(){
|
||||||
});
|
swipeTimedTest({ timeout: 10, coordChange: 35, expected: true });
|
||||||
|
});
|
||||||
|
|
||||||
var nativeSupportTest = function(opts){
|
test( "swipe not fired when coordinate change takes more than a second", function(){
|
||||||
$.support.orientation = opts.orientationSupport;
|
swipeTimedTest({ timeout: 1000, coordChange: 35, expected: false });
|
||||||
same($.event.special.orientationchange[opts.method](), opts.returnValue);
|
});
|
||||||
|
|
||||||
|
test( "swipe not fired when coordinate change <= 30", function(){
|
||||||
|
swipeTimedTest({ timeout: 1000, coordChange: 30, expected: false });
|
||||||
|
});
|
||||||
|
|
||||||
|
test( "swipe not fired when coordinate change >= 75", function(){
|
||||||
|
swipeTimedTest({ timeout: 1000, coordChange: 75, expected: false });
|
||||||
|
});
|
||||||
|
|
||||||
|
test( "scrolling prevented when coordinate change > 10", function(){
|
||||||
|
expect( 1 );
|
||||||
|
|
||||||
|
//NOTE bypass the trigger source check
|
||||||
|
$.Event.prototype.originalEvent = {
|
||||||
|
touches: false
|
||||||
};
|
};
|
||||||
|
|
||||||
test( "orientation change setup should do nothing when natively supported", function(){
|
$.Event.prototype.preventDefault = function(){
|
||||||
nativeSupportTest({
|
ok(true, "prevent default called");
|
||||||
method: 'setup',
|
};
|
||||||
orientationSupport: true,
|
|
||||||
returnValue: false
|
mockAbs(11);
|
||||||
});
|
|
||||||
|
$($.event.special.swipe).trigger("touchstart");
|
||||||
|
$($.event.special.swipe).trigger("touchmove");
|
||||||
|
});
|
||||||
|
|
||||||
|
test( "move handler returns when touchstart has been fired since touchstop", function(){
|
||||||
|
expect( 1 );
|
||||||
|
|
||||||
|
$.Event.prototype.originalEvent = {
|
||||||
|
touches: false
|
||||||
|
};
|
||||||
|
|
||||||
|
$($.event.special.swipe).trigger("touchstart");
|
||||||
|
$($.event.special.swipe).trigger("touchend");
|
||||||
|
|
||||||
|
$($.event.special.swipe).bind("touchmove", function(){
|
||||||
|
ok(true, "touchmove bound functions are fired");
|
||||||
});
|
});
|
||||||
|
|
||||||
test( "orientation change setup should bind resize when not supported natively", function(){
|
Math.abs = function(){
|
||||||
nativeSupportTest({
|
ok(false, "shouldn't compare coordinates");
|
||||||
method: 'setup',
|
};
|
||||||
orientationSupport: false,
|
|
||||||
returnValue: undefined //NOTE result of bind function call
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test( "orientation change teardown should do nothing when natively supported", function(){
|
$($.event.special.swipe).trigger("touchmove");
|
||||||
nativeSupportTest({
|
});
|
||||||
method: 'teardown',
|
|
||||||
orientationSupport: true,
|
|
||||||
returnValue: false
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test( "orientation change teardown should unbind resize when not supported natively", function(){
|
var nativeSupportTest = function(opts){
|
||||||
nativeSupportTest({
|
$.support.orientation = opts.orientationSupport;
|
||||||
method: 'teardown',
|
same($.event.special.orientationchange[opts.method](), opts.returnValue);
|
||||||
orientationSupport: false,
|
};
|
||||||
returnValue: undefined //NOTE result of unbind function call
|
|
||||||
});
|
test( "orientation change setup should do nothing when natively supported", function(){
|
||||||
|
nativeSupportTest({
|
||||||
|
method: 'setup',
|
||||||
|
orientationSupport: true,
|
||||||
|
returnValue: false
|
||||||
});
|
});
|
||||||
})(jQuery);
|
});
|
||||||
|
|
||||||
|
test( "orientation change setup should bind resize when not supported natively", function(){
|
||||||
|
nativeSupportTest({
|
||||||
|
method: 'setup',
|
||||||
|
orientationSupport: false,
|
||||||
|
returnValue: undefined //NOTE result of bind function call
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test( "orientation change teardown should do nothing when natively supported", function(){
|
||||||
|
nativeSupportTest({
|
||||||
|
method: 'teardown',
|
||||||
|
orientationSupport: true,
|
||||||
|
returnValue: false
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test( "orientation change teardown should unbind resize when not supported natively", function(){
|
||||||
|
nativeSupportTest({
|
||||||
|
method: 'teardown',
|
||||||
|
orientationSupport: false,
|
||||||
|
returnValue: undefined //NOTE result of unbind function call
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,7 @@
|
||||||
<ol id="qunit-tests">
|
<ol id="qunit-tests">
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<div id="main" style="position: absolute; top: -10000px; left: -10000px;">
|
<div id="qunit-fixture"></div>
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,7 @@
|
||||||
<ol id="qunit-tests">
|
<ol id="qunit-tests">
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<div id="main" style="position: absolute; top: -10000px; left: -10000px;">
|
<div id="qunit-fixture"></div>
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -2,96 +2,94 @@
|
||||||
* mobile media unit tests
|
* mobile media unit tests
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function( $ ) {
|
var cssFn = $.fn.css,
|
||||||
var cssFn = $.fn.css,
|
widthFn = $.fn.width;
|
||||||
widthFn = $.fn.width;
|
|
||||||
|
|
||||||
// make sure original definitions are reset
|
// make sure original definitions are reset
|
||||||
module('jquery.mobile.media.js', {
|
module('jquery.mobile.media.js', {
|
||||||
teardown: function(){
|
teardown: function(){
|
||||||
$.fn.css = cssFn;
|
$.fn.css = cssFn;
|
||||||
$.fn.width = widthFn;
|
$.fn.width = widthFn;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test( "media query check returns true when the position is absolute", function(){
|
||||||
|
$.fn.css = function(){ return "absolute"; };
|
||||||
|
same($.mobile.media("screen 1"), true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test( "media query check returns false when the position is not absolute", function(){
|
||||||
|
$.fn.css = function(){ return "not absolute"; };
|
||||||
|
same($.mobile.media("screen 2"), false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test( "media query check is cached", function(){
|
||||||
|
$.fn.css = function(){ return "absolute"; };
|
||||||
|
same($.mobile.media("screen 3"), true);
|
||||||
|
|
||||||
|
$.fn.css = function(){ return "not absolute"; };
|
||||||
|
same($.mobile.media("screen 3"), true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test( "window widths smaller than the break points set max-width classes", function(){
|
||||||
|
$.fn.width = function(){ return 120; };
|
||||||
|
|
||||||
|
$.mobile.addResolutionBreakpoints([125]);
|
||||||
|
ok($("html").hasClass("max-width-125px"));
|
||||||
|
});
|
||||||
|
|
||||||
|
test( "window widths larger than the break points set min-width classes", function(){
|
||||||
|
$.fn.width = function(){ return 1900; };
|
||||||
|
|
||||||
|
$.mobile.addResolutionBreakpoints([125]);
|
||||||
|
ok($("html").hasClass("min-width-125px"));
|
||||||
|
});
|
||||||
|
|
||||||
|
test( "many break points result in many class additions", function(){
|
||||||
|
$.fn.width = function(){ return 1900; };
|
||||||
|
$.mobile.addResolutionBreakpoints([1, 2]);
|
||||||
|
|
||||||
|
ok($("html").hasClass("min-width-1px"));
|
||||||
|
ok($("html").hasClass("min-width-2px"));
|
||||||
|
});
|
||||||
|
|
||||||
|
test( "adds all classes for default res breakpoints", function(){
|
||||||
|
expect( 4 );
|
||||||
|
$.fn.width = function(){ return 1900; };
|
||||||
|
$.mobile.addResolutionBreakpoints([]);
|
||||||
|
|
||||||
|
// TODO should expose the defaults to prevent brittle tests
|
||||||
|
$.each([320, 480, 768, 1024], function(i, element){
|
||||||
|
ok($("html").hasClass("min-width-" + element + "px"));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test( "triggering mobile init triggers orientationchange.htmlclass", function(){
|
||||||
|
expect( 1 );
|
||||||
|
|
||||||
|
$(window).bind("orientationchange.htmlclass", function(event){
|
||||||
|
ok(event);
|
||||||
});
|
});
|
||||||
|
|
||||||
test( "media query check returns true when the position is absolute", function(){
|
$(document).trigger("mobileinit.htmlclass");
|
||||||
$.fn.css = function(){ return "absolute"; };
|
});
|
||||||
same($.mobile.media("screen 1"), true);
|
|
||||||
});
|
|
||||||
|
|
||||||
test( "media query check returns false when the position is not absolute", function(){
|
test( "binds remove of portrait and landscape classes resize/orientation fired", function(){
|
||||||
$.fn.css = function(){ return "not absolute"; };
|
$.Event.prototype.orientation = true;
|
||||||
same($.mobile.media("screen 2"), false);
|
|
||||||
});
|
|
||||||
|
|
||||||
test( "media query check is cached", function(){
|
$("html").addClass("portrait landscape");
|
||||||
$.fn.css = function(){ return "absolute"; };
|
$(window).trigger("resize.htmlclass");
|
||||||
same($.mobile.media("screen 3"), true);
|
ok(!$("html").hasClass("portrait landscape"));
|
||||||
|
|
||||||
$.fn.css = function(){ return "not absolute"; };
|
$("html").addClass("portrait landscape");
|
||||||
same($.mobile.media("screen 3"), true);
|
$(window).trigger("resize.htmlclass");
|
||||||
});
|
ok(!$("html").hasClass("portrait landscape"));
|
||||||
|
});
|
||||||
|
|
||||||
test( "window widths smaller than the break points set max-width classes", function(){
|
test( "sets break point class additions on resize/orientation change", function(){
|
||||||
$.fn.width = function(){ return 120; };
|
$.fn.width = function(){ return 1900; };
|
||||||
|
|
||||||
$.mobile.addResolutionBreakpoints([125]);
|
$("html").removeClass("min-width-320px");
|
||||||
ok($("html").hasClass("max-width-125px"));
|
$(window).trigger("resize.htmlclass");
|
||||||
});
|
ok($("html").hasClass("min-width-320px"));
|
||||||
|
});
|
||||||
test( "window widths larger than the break points set min-width classes", function(){
|
|
||||||
$.fn.width = function(){ return 1900; };
|
|
||||||
|
|
||||||
$.mobile.addResolutionBreakpoints([125]);
|
|
||||||
ok($("html").hasClass("min-width-125px"));
|
|
||||||
});
|
|
||||||
|
|
||||||
test( "many break points result in many class additions", function(){
|
|
||||||
$.fn.width = function(){ return 1900; };
|
|
||||||
$.mobile.addResolutionBreakpoints([1, 2]);
|
|
||||||
|
|
||||||
ok($("html").hasClass("min-width-1px"));
|
|
||||||
ok($("html").hasClass("min-width-2px"));
|
|
||||||
});
|
|
||||||
|
|
||||||
test( "adds all classes for default res breakpoints", function(){
|
|
||||||
expect( 4 );
|
|
||||||
$.fn.width = function(){ return 1900; };
|
|
||||||
$.mobile.addResolutionBreakpoints([]);
|
|
||||||
|
|
||||||
// TODO should expose the defaults to prevent brittle tests
|
|
||||||
$.each([320, 480, 768, 1024], function(i, element){
|
|
||||||
ok($("html").hasClass("min-width-" + element + "px"));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test( "triggering mobile init triggers orientationchange.htmlclass", function(){
|
|
||||||
expect( 1 );
|
|
||||||
|
|
||||||
$(window).bind("orientationchange.htmlclass", function(event){
|
|
||||||
ok(event);
|
|
||||||
});
|
|
||||||
|
|
||||||
$(document).trigger("mobileinit.htmlclass");
|
|
||||||
});
|
|
||||||
|
|
||||||
test( "binds remove of portrait and landscape classes resize/orientation fired", function(){
|
|
||||||
$.Event.prototype.orientation = true;
|
|
||||||
|
|
||||||
$("html").addClass("portrait landscape");
|
|
||||||
$(window).trigger("resize.htmlclass");
|
|
||||||
ok(!$("html").hasClass("portrait landscape"));
|
|
||||||
|
|
||||||
$("html").addClass("portrait landscape");
|
|
||||||
$(window).trigger("resize.htmlclass");
|
|
||||||
ok(!$("html").hasClass("portrait landscape"));
|
|
||||||
});
|
|
||||||
|
|
||||||
test( "sets break point class additions on resize/orientation change", function(){
|
|
||||||
$.fn.width = function(){ return 1900; };
|
|
||||||
|
|
||||||
$("html").removeClass("min-width-320px");
|
|
||||||
$(window).trigger("resize.htmlclass");
|
|
||||||
ok($("html").hasClass("min-width-320px"));
|
|
||||||
});
|
|
||||||
})(jQuery);
|
|
||||||
|
|
|
||||||
|
|
@ -1,48 +1,46 @@
|
||||||
/*
|
/*
|
||||||
* mobile navigation unit tests
|
* mobile navigation unit tests
|
||||||
*/
|
*/
|
||||||
(function( $ ) {
|
var perspective = "ui-mobile-viewport-perspective",
|
||||||
var perspective = "ui-mobile-viewport-perspective",
|
transitioning = "ui-mobile-viewport-transitioning",
|
||||||
transitioning = "ui-mobile-viewport-transitioning",
|
animationCompleteFn = $.fn.animationComplete,
|
||||||
animationCompleteFn = $.fn.animationComplete,
|
|
||||||
|
|
||||||
removeClasses = function(){
|
removeClasses = function(){
|
||||||
$("body").removeClass([perspective, transitioning].join(" "));
|
$("body").removeClass([perspective, transitioning].join(" "));
|
||||||
};
|
};
|
||||||
|
|
||||||
module('jquery.mobile.navigation.js', {
|
module('jquery.mobile.navigation.js', {
|
||||||
teardown: function(){
|
teardown: function(){
|
||||||
// unmock animation complete
|
// unmock animation complete
|
||||||
$.fn.animationComplete = animationCompleteFn;
|
$.fn.animationComplete = animationCompleteFn;
|
||||||
|
|
||||||
removeClasses();
|
removeClasses();
|
||||||
}});
|
}});
|
||||||
|
|
||||||
test( "changePage applys perspective class to mobile viewport for flip", function(){
|
test( "changePage applys perspective class to mobile viewport for flip", function(){
|
||||||
//stub to prevent class removal
|
//stub to prevent class removal
|
||||||
$.fn.animationComplete = function(){};
|
$.fn.animationComplete = function(){};
|
||||||
|
|
||||||
$("#foo > a").click();
|
$("#foo > a").click();
|
||||||
|
|
||||||
ok($("body").hasClass(perspective), "has perspective class");
|
ok($("body").hasClass(perspective), "has perspective class");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
test( "changePage applys does not apply perspective class to mobile viewport for transitions other than flip", function(){
|
test( "changePage applys does not apply perspective class to mobile viewport for transitions other than flip", function(){
|
||||||
//stub to prevent class removal
|
//stub to prevent class removal
|
||||||
$.fn.animationComplete = function(){};
|
$.fn.animationComplete = function(){};
|
||||||
|
|
||||||
$("#bar > a").click();
|
$("#bar > a").click();
|
||||||
|
|
||||||
ok(!$("body").hasClass(perspective), "doesn't have perspective class");
|
ok(!$("body").hasClass(perspective), "doesn't have perspective class");
|
||||||
});
|
});
|
||||||
|
|
||||||
test( "changePage applys transition class to mobile viewport for default transition", function(){
|
test( "changePage applys transition class to mobile viewport for default transition", function(){
|
||||||
//stub to prevent class removal
|
//stub to prevent class removal
|
||||||
$.fn.animationComplete = function(){};
|
$.fn.animationComplete = function(){};
|
||||||
|
|
||||||
$("#baz > a").click();
|
$("#baz > a").click();
|
||||||
|
|
||||||
ok($("body").hasClass(transitioning), "has transitioning class");
|
ok($("body").hasClass(transitioning), "has transitioning class");
|
||||||
});
|
});
|
||||||
})(jQuery);
|
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@
|
||||||
<ol id="qunit-tests">
|
<ol id="qunit-tests">
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<div id="main" style="position: absolute; top: -10000px; left: -10000px;">
|
<div id="qunit-fixture">
|
||||||
<div data-role="page">
|
<div data-role="page">
|
||||||
<div data-role="header">
|
<div data-role="header">
|
||||||
<div>
|
<div>
|
||||||
|
|
|
||||||
|
|
@ -1,31 +1,29 @@
|
||||||
/*
|
/*
|
||||||
* mobile page unit tests
|
* mobile page unit tests
|
||||||
*/
|
*/
|
||||||
(function( $ ) {
|
module('jquery.mobile.page.js');
|
||||||
module('jquery.mobile.page.js');
|
|
||||||
|
|
||||||
test( "nested header anchors aren't altered", function(){
|
test( "nested header anchors aren't altered", function(){
|
||||||
ok(!$('.ui-header > div > a').hasClass('ui-btn'));
|
ok(!$('.ui-header > div > a').hasClass('ui-btn'));
|
||||||
});
|
});
|
||||||
|
|
||||||
test( "nested footer anchors aren't altered", function(){
|
test( "nested footer anchors aren't altered", function(){
|
||||||
ok(!$('.ui-footer > div > a').hasClass('ui-btn'));
|
ok(!$('.ui-footer > div > a').hasClass('ui-btn'));
|
||||||
});
|
});
|
||||||
|
|
||||||
test( "nested bar anchors aren't styled", function(){
|
test( "nested bar anchors aren't styled", function(){
|
||||||
ok(!$('.ui-bar > div > a').hasClass('ui-btn'));
|
ok(!$('.ui-bar > div > a').hasClass('ui-btn'));
|
||||||
});
|
});
|
||||||
|
|
||||||
test( "unnested footer anchors are styled", function(){
|
test( "unnested footer anchors are styled", function(){
|
||||||
ok($('.ui-footer > a').hasClass('ui-btn'));
|
ok($('.ui-footer > a').hasClass('ui-btn'));
|
||||||
});
|
});
|
||||||
|
|
||||||
test( "unnested footer anchors are styled", function(){
|
test( "unnested footer anchors are styled", function(){
|
||||||
ok($('.ui-footer > a').hasClass('ui-btn'));
|
ok($('.ui-footer > a').hasClass('ui-btn'));
|
||||||
});
|
});
|
||||||
|
|
||||||
test( "unnested bar anchors are styled", function(){
|
test( "unnested bar anchors are styled", function(){
|
||||||
ok($('.ui-bar > a').hasClass('ui-btn'));
|
ok($('.ui-bar > a').hasClass('ui-btn'));
|
||||||
});
|
});
|
||||||
|
|
||||||
})(jQuery);
|
|
||||||
|
|
@ -24,8 +24,7 @@
|
||||||
<ol id="qunit-tests">
|
<ol id="qunit-tests">
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<div id="main" style="position: absolute; top: -10000px; left: -10000px;">
|
<div id="qunit-fixture"></div>
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -2,76 +2,74 @@
|
||||||
* mobile support unit tests
|
* mobile support unit tests
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function( $ ) {
|
$.testHelper.excludeFileProtocol(function(){
|
||||||
$.testHelper.excludeFileProtocol(function(){
|
var prependToFn = $.fn.prependTo,
|
||||||
var prependToFn = $.fn.prependTo,
|
libName = "jquery.mobile.support.js";
|
||||||
libName = "jquery.mobile.support.js";
|
|
||||||
|
|
||||||
module(libName, {
|
module(libName, {
|
||||||
teardown: function(){
|
teardown: function(){
|
||||||
//NOTE undo any mocking
|
//NOTE undo any mocking
|
||||||
$.fn.prependTo = prependToFn;
|
$.fn.prependTo = prependToFn;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
// NOTE following two tests have debatable value as they only
|
|
||||||
// prevent property name changes and improper attribute checks
|
|
||||||
test( "detects functionality from basic affirmative properties and attributes", function(){
|
|
||||||
// TODO expose properties for less brittle tests
|
|
||||||
$.extend(window, {
|
|
||||||
WebKitTransitionEvent: true,
|
|
||||||
orientation: true
|
|
||||||
});
|
|
||||||
|
|
||||||
document.ontouchend = true;
|
|
||||||
|
|
||||||
history.pushState = function(){};
|
|
||||||
$.mobile.media = function(){ return true; };
|
|
||||||
|
|
||||||
$.testHelper.reloadLib(libName);
|
|
||||||
|
|
||||||
ok($.support.orientation);
|
|
||||||
ok($.support.touch);
|
|
||||||
ok($.support.cssTransitions);
|
|
||||||
ok($.support.pushState);
|
|
||||||
ok($.support.mediaquery);
|
|
||||||
});
|
|
||||||
|
|
||||||
test( "detects functionality from basic negative properties and attributes (where possible)", function(){
|
|
||||||
delete window["orientation"];
|
|
||||||
delete document["ontouchend"];
|
|
||||||
|
|
||||||
$.testHelper.reloadLib(libName);
|
|
||||||
|
|
||||||
ok(!$.support.orientation);
|
|
||||||
ok(!$.support.touch);
|
|
||||||
});
|
|
||||||
|
|
||||||
// NOTE mocks prependTo to simulate base href updates or lack thereof
|
|
||||||
var mockBaseCheck = function( url ){
|
|
||||||
var prependToFn = $.fn.prependTo;
|
|
||||||
|
|
||||||
$.fn.prependTo = function( selector ){
|
|
||||||
var result = prependToFn.call(this, selector);
|
|
||||||
if(this[0].href && this[0].href.indexOf("testurl") != -1)
|
|
||||||
result = [{href: url}];
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
test( "detects dynamic base tag when new base element added and base href updates", function(){
|
|
||||||
mockBaseCheck(location.protocol + '//' + location.host + location.pathname + "ui-dir/");
|
|
||||||
$.testHelper.reloadLib(libName);
|
|
||||||
ok($.support.dynamicBaseTag);
|
|
||||||
});
|
|
||||||
|
|
||||||
test( "detects no dynamic base tag when new base element added and base href unchanged", function(){
|
|
||||||
mockBaseCheck('testurl');
|
|
||||||
$.testHelper.reloadLib(libName);
|
|
||||||
ok(!$.support.dynamicBaseTag);
|
|
||||||
});
|
|
||||||
|
|
||||||
//TODO propExists testing, refactor propExists into mockable method
|
|
||||||
//TODO scrollTop testing, refactor scrollTop logic into mockable method
|
|
||||||
});
|
});
|
||||||
})(jQuery);
|
|
||||||
|
// NOTE following two tests have debatable value as they only
|
||||||
|
// prevent property name changes and improper attribute checks
|
||||||
|
test( "detects functionality from basic affirmative properties and attributes", function(){
|
||||||
|
// TODO expose properties for less brittle tests
|
||||||
|
$.extend(window, {
|
||||||
|
WebKitTransitionEvent: true,
|
||||||
|
orientation: true
|
||||||
|
});
|
||||||
|
|
||||||
|
document.ontouchend = true;
|
||||||
|
|
||||||
|
history.pushState = function(){};
|
||||||
|
$.mobile.media = function(){ return true; };
|
||||||
|
|
||||||
|
$.testHelper.reloadLib(libName);
|
||||||
|
|
||||||
|
ok($.support.orientation);
|
||||||
|
ok($.support.touch);
|
||||||
|
ok($.support.cssTransitions);
|
||||||
|
ok($.support.pushState);
|
||||||
|
ok($.support.mediaquery);
|
||||||
|
});
|
||||||
|
|
||||||
|
test( "detects functionality from basic negative properties and attributes (where possible)", function(){
|
||||||
|
delete window["orientation"];
|
||||||
|
delete document["ontouchend"];
|
||||||
|
|
||||||
|
$.testHelper.reloadLib(libName);
|
||||||
|
|
||||||
|
ok(!$.support.orientation);
|
||||||
|
ok(!$.support.touch);
|
||||||
|
});
|
||||||
|
|
||||||
|
// NOTE mocks prependTo to simulate base href updates or lack thereof
|
||||||
|
var mockBaseCheck = function( url ){
|
||||||
|
var prependToFn = $.fn.prependTo;
|
||||||
|
|
||||||
|
$.fn.prependTo = function( selector ){
|
||||||
|
var result = prependToFn.call(this, selector);
|
||||||
|
if(this[0].href && this[0].href.indexOf("testurl") != -1)
|
||||||
|
result = [{href: url}];
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
test( "detects dynamic base tag when new base element added and base href updates", function(){
|
||||||
|
mockBaseCheck(location.protocol + '//' + location.host + location.pathname + "ui-dir/");
|
||||||
|
$.testHelper.reloadLib(libName);
|
||||||
|
ok($.support.dynamicBaseTag);
|
||||||
|
});
|
||||||
|
|
||||||
|
test( "detects no dynamic base tag when new base element added and base href unchanged", function(){
|
||||||
|
mockBaseCheck('testurl');
|
||||||
|
$.testHelper.reloadLib(libName);
|
||||||
|
ok(!$.support.dynamicBaseTag);
|
||||||
|
});
|
||||||
|
|
||||||
|
//TODO propExists testing, refactor propExists into mockable method
|
||||||
|
//TODO scrollTop testing, refactor scrollTop logic into mockable method
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
<ol id="qunit-tests">
|
<ol id="qunit-tests">
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<div id="main" style="position: absolute; top: -10000px; left: -10000px;">
|
<div id="qunit-fixture">
|
||||||
|
|
||||||
<div id="widget-wrapper">
|
<div id="widget-wrapper">
|
||||||
<div id="widget">
|
<div id="widget">
|
||||||
|
|
|
||||||
|
|
@ -2,33 +2,31 @@
|
||||||
* mobile widget unit tests
|
* mobile widget unit tests
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function( $ ) {
|
module('jquery.mobile.widget.js');
|
||||||
module('jquery.mobile.widget.js');
|
|
||||||
|
|
||||||
test( "getting data from creation options", function(){
|
test( "getting data from creation options", function(){
|
||||||
var expected = "bizzle";
|
var expected = "bizzle";
|
||||||
|
|
||||||
$.mobile.widget.prototype.options = { "fooBar" : true };
|
$.mobile.widget.prototype.options = { "fooBar" : true };
|
||||||
$.mobile.widget.prototype.element = $("<div data-foo-bar=" + expected + ">");
|
$.mobile.widget.prototype.element = $("<div data-foo-bar=" + expected + ">");
|
||||||
same($.mobile.widget.prototype._getCreateOptions()["fooBar"],
|
same($.mobile.widget.prototype._getCreateOptions()["fooBar"],
|
||||||
expected);
|
expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
test( "getting no data when the options are empty", function(){
|
test( "getting no data when the options are empty", function(){
|
||||||
var expected = {};
|
var expected = {};
|
||||||
|
|
||||||
$.mobile.widget.prototype.options = {};
|
$.mobile.widget.prototype.options = {};
|
||||||
$.mobile.widget.prototype.element = $("<div data-foo-bar=" + expected + ">");
|
$.mobile.widget.prototype.element = $("<div data-foo-bar=" + expected + ">");
|
||||||
same($.mobile.widget.prototype._getCreateOptions(),
|
same($.mobile.widget.prototype._getCreateOptions(),
|
||||||
expected);
|
expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
test( "getting no data when the element has none", function(){
|
test( "getting no data when the element has none", function(){
|
||||||
var expected = {};
|
var expected = {};
|
||||||
|
|
||||||
$.mobile.widget.prototype.options = { "fooBar" : true };
|
$.mobile.widget.prototype.options = { "fooBar" : true };
|
||||||
$.mobile.widget.prototype.element = $("<div>");
|
$.mobile.widget.prototype.element = $("<div>");
|
||||||
same($.mobile.widget.prototype._getCreateOptions(),
|
same($.mobile.widget.prototype._getCreateOptions(),
|
||||||
expected);
|
expected);
|
||||||
});
|
});
|
||||||
})(jQuery);
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue