diff options
Diffstat (limited to 'wqflask/wqflask/static/new/packages/ValidationPlugin/test')
19 files changed, 6274 insertions, 0 deletions
diff --git a/wqflask/wqflask/static/new/packages/ValidationPlugin/test/events.html b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/events.html new file mode 100644 index 00000000..eba81b00 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/events.html @@ -0,0 +1,71 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /> +<title>Test for jQuery validate() plugin</title> + +<link rel="stylesheet" type="text/css" media="screen" href="css/screen.css" /> +<script src="../lib/jquery.js" type="text/javascript"></script> +<script src="firebug/firebug.js" type="text/javascript"></script> + +<script type="text/javascript"> +$().ready(function() { + var handler = { + focusin: function() { + $(this).addClass("focus"); + }, + focusout: function() { + $(this).removeClass("focus"); + } + } + $("#commentForm").delegate("focusin focusout", ":text, textarea", function(event) { + /* + this.addClass("focus").one("blur", function() { + $(this).removeClass("focus"); + }); + */ + handler[event.type].call(this, arguments); + }); + $("#remove").click(function() { + $("#commentForm").unbind("focusin"); + }) +}); +</script> + +<style type="text/css"> +#commentForm { width: 500px; } +#commentForm label { width: 250px; display: block; float: left; } +#commentForm label.error, #commentForm input.submit { margin-left: 253px; } +.focus { background-color: red; } +</style> + +</head> +<body> +<form class="cmxform" id="commentForm" method="get" action=""> + <fieldset> + <legend>A simple comment form with submit validation and default messages</legend> + <p> + <label for="cname">Name (required, at least 2 characters)</label> + <input id="cname" name="name" class="some other styles {required:true,minLength:2}" /> + <p> + <label for="cemail">E-Mail (required)</label> + <input id="cemail" name="email" class="{required:true,email:true}" /> + </p> + <p> + <label for="curl">URL (optional)</label> + <input id="curl" name="url" class="{url:true}" value="" /> + </p> + <p> + <label for="ccomment">Your comment (required)</label> + <textarea id="ccomment" name="comment" class="{required:true}"></textarea> + </p> + <p> + <input class="submit" type="submit" value="Submit"/> + </p> + </fieldset> +</form> + +<button id="remove">Remove focus handler</button> + +</body> +</html> diff --git a/wqflask/wqflask/static/new/packages/ValidationPlugin/test/firebug/errorIcon.png b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/firebug/errorIcon.png Binary files differnew file mode 100644 index 00000000..2d75261b --- /dev/null +++ b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/firebug/errorIcon.png diff --git a/wqflask/wqflask/static/new/packages/ValidationPlugin/test/firebug/firebug.css b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/firebug/firebug.css new file mode 100644 index 00000000..1f041c4d --- /dev/null +++ b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/firebug/firebug.css @@ -0,0 +1,209 @@ + +html, body { + margin: 0; + background: #FFFFFF; + font-family: Lucida Grande, Tahoma, sans-serif; + font-size: 11px; + overflow: hidden; +} + +a { + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +.toolbar { + height: 14px; + border-top: 1px solid ThreeDHighlight; + border-bottom: 1px solid ThreeDShadow; + padding: 2px 6px; + background: ThreeDFace; +} + +.toolbarRight { + position: absolute; + top: 4px; + right: 6px; +} + +#log { + overflow: auto; + position: absolute; + left: 0; + width: 100%; +} + +#commandLine { + position: absolute; + bottom: 0; + left: 0; + width: 100%; + height: 18px; + border: none; + border-top: 1px solid ThreeDShadow; +} + +/************************************************************************************************/ + +.logRow { + position: relative; + border-bottom: 1px solid #D7D7D7; + padding: 2px 4px 1px 6px; + background-color: #FFFFFF; +} + +.logRow-command { + font-family: Monaco, monospace; + color: blue; +} + +.objectBox-null { + padding: 0 2px; + border: 1px solid #666666; + background-color: #888888; + color: #FFFFFF; +} + +.objectBox-string { + font-family: Monaco, monospace; + color: red; + white-space: pre; +} + +.objectBox-number { + color: #000088; +} + +.objectBox-function { + font-family: Monaco, monospace; + color: DarkGreen; +} + +.objectBox-object { + color: DarkGreen; + font-weight: bold; +} + +/************************************************************************************************/ + +.logRow-info, +.logRow-error, +.logRow-warning { + background: #FFFFFF no-repeat 2px 2px; + padding-left: 20px; + padding-bottom: 3px; +} + +.logRow-info { + background-image: url(infoIcon.png); +} + +.logRow-warning { + background-color: cyan; + background-image: url(warningIcon.png); +} + +.logRow-error { + background-color: LightYellow; + background-image: url(errorIcon.png); +} + +.errorMessage { + vertical-align: top; + color: #FF0000; +} + +.objectBox-sourceLink { + position: absolute; + right: 4px; + top: 2px; + padding-left: 8px; + font-family: Lucida Grande, sans-serif; + font-weight: bold; + color: #0000FF; +} + +/************************************************************************************************/ + +.logRow-group { + background: #EEEEEE; + border-bottom: none; +} + +.logGroup { + background: #EEEEEE; +} + +.logGroupBox { + margin-left: 24px; + border-top: 1px solid #D7D7D7; + border-left: 1px solid #D7D7D7; +} + +/************************************************************************************************/ + +.selectorTag, +.selectorId, +.selectorClass { + font-family: Monaco, monospace; + font-weight: normal; +} + +.selectorTag { + color: #0000FF; +} + +.selectorId { + color: DarkBlue; +} + +.selectorClass { + color: red; +} + +/************************************************************************************************/ + +.objectBox-element { + font-family: Monaco, monospace; + color: #000088; +} + +.nodeChildren { + margin-left: 16px; +} + +.nodeTag { + color: blue; +} + +.nodeValue { + color: #FF0000; + font-weight: normal; +} + +.nodeText, +.nodeComment { + margin: 0 2px; + vertical-align: top; +} + +.nodeText { + color: #333333; +} + +.nodeComment { + color: DarkGreen; +} + +/************************************************************************************************/ + +.propertyNameCell { + vertical-align: top; +} + +.propertyName { + font-weight: bold; +} diff --git a/wqflask/wqflask/static/new/packages/ValidationPlugin/test/firebug/firebug.html b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/firebug/firebug.html new file mode 100644 index 00000000..861e6393 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/firebug/firebug.html @@ -0,0 +1,23 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml"> + +<head> + <title>Firebug</title> + <link rel="stylesheet" type="text/css" href="firebug.css"> +</head> + +<body> + <div id="toolbar" class="toolbar"> + <a href="#" onclick="parent.console.clear()">Clear</a> + <span class="toolbarRight"> + <a href="#" onclick="parent.console.close()">Close</a> + </span> + </div> + <div id="log"></div> + <input type="text" id="commandLine"> + + <script>parent.onFirebugReady(document);</script> +</body> +</html> diff --git a/wqflask/wqflask/static/new/packages/ValidationPlugin/test/firebug/firebug.js b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/firebug/firebug.js new file mode 100644 index 00000000..eb853b82 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/firebug/firebug.js @@ -0,0 +1,672 @@ + +if (!("console" in window) || !("firebug" in console)) { +(function() +{ + window.console = + { + log: function() + { + logFormatted(arguments, ""); + }, + + debug: function() + { + logFormatted(arguments, "debug"); + }, + + info: function() + { + logFormatted(arguments, "info"); + }, + + warn: function() + { + logFormatted(arguments, "warning"); + }, + + error: function() + { + logFormatted(arguments, "error"); + }, + + assert: function(truth, message) + { + if (!truth) + { + var args = []; + for (var i = 1; i < arguments.length; ++i) + args.push(arguments[i]); + + logFormatted(args.length ? args : ["Assertion Failure"], "error"); + throw message ? message : "Assertion Failure"; + } + }, + + dir: function(object) + { + var html = []; + + var pairs = []; + for (var name in object) + { + try + { + pairs.push([name, object[name]]); + } + catch (exc) + { + } + } + + pairs.sort(function(a, b) { return a[0] < b[0] ? -1 : 1; }); + + html.push('<table>'); + for (var i = 0; i < pairs.length; ++i) + { + var name = pairs[i][0], value = pairs[i][1]; + + html.push('<tr>', + '<td class="propertyNameCell"><span class="propertyName">', + escapeHTML(name), '</span></td>', '<td><span class="propertyValue">'); + appendObject(value, html); + html.push('</span></td></tr>'); + } + html.push('</table>'); + + logRow(html, "dir"); + }, + + dirxml: function(node) + { + var html = []; + + appendNode(node, html); + logRow(html, "dirxml"); + }, + + group: function() + { + logRow(arguments, "group", pushGroup); + }, + + groupEnd: function() + { + logRow(arguments, "", popGroup); + }, + + time: function(name) + { + timeMap[name] = (new Date()).getTime(); + }, + + timeEnd: function(name) + { + if (name in timeMap) + { + var delta = (new Date()).getTime() - timeMap[name]; + logFormatted([name+ ":", delta+"ms"]); + delete timeMap[name]; + } + }, + + count: function() + { + this.warn(["count() not supported."]); + }, + + trace: function() + { + this.warn(["trace() not supported."]); + }, + + profile: function() + { + this.warn(["profile() not supported."]); + }, + + profileEnd: function() + { + }, + + clear: function() + { + consoleBody.innerHTML = ""; + }, + + open: function() + { + toggleConsole(true); + }, + + close: function() + { + if (frameVisible) + toggleConsole(); + } + }; + + // ******************************************************************************************** + + var consoleFrame = null; + var consoleBody = null; + var commandLine = null; + + var frameVisible = false; + var messageQueue = []; + var groupStack = []; + var timeMap = {}; + + var clPrefix = ">>> "; + + var isFirefox = navigator.userAgent.indexOf("Firefox") != -1; + var isIE = navigator.userAgent.indexOf("MSIE") != -1; + var isOpera = navigator.userAgent.indexOf("Opera") != -1; + var isSafari = navigator.userAgent.indexOf("AppleWebKit") != -1; + + // ******************************************************************************************** + + function toggleConsole(forceOpen) + { + frameVisible = forceOpen || !frameVisible; + if (consoleFrame) + consoleFrame.style.visibility = frameVisible ? "visible" : "hidden"; + else + waitForBody(); + } + + function focusCommandLine() + { + toggleConsole(true); + if (commandLine) + commandLine.focus(); + } + + function waitForBody() + { + if (document.body) + createFrame(); + else + setTimeout(waitForBody, 200); + } + + function createFrame() + { + if (consoleFrame) + return; + + window.onFirebugReady = function(doc) + { + window.onFirebugReady = null; + + var toolbar = doc.getElementById("toolbar"); + toolbar.onmousedown = onSplitterMouseDown; + + commandLine = doc.getElementById("commandLine"); + addEvent(commandLine, "keydown", onCommandLineKeyDown); + + addEvent(doc, isIE || isSafari ? "keydown" : "keypress", onKeyDown); + + consoleBody = doc.getElementById("log"); + layout(); + flush(); + } + + var baseURL = getFirebugURL(); + + consoleFrame = document.createElement("iframe"); + consoleFrame.setAttribute("src", baseURL+"/firebug.html"); + consoleFrame.setAttribute("frameBorder", "0"); + consoleFrame.style.visibility = (frameVisible ? "visible" : "hidden"); + consoleFrame.style.zIndex = "2147483647"; + consoleFrame.style.position = "fixed"; + consoleFrame.style.width = "100%"; + consoleFrame.style.left = "0"; + consoleFrame.style.bottom = "0"; + consoleFrame.style.height = "200px"; + document.body.appendChild(consoleFrame); + } + + function getFirebugURL() + { + var scripts = document.getElementsByTagName("script"); + for (var i = 0; i < scripts.length; ++i) + { + if (scripts[i].src.indexOf("firebug.js") != -1) + { + var lastSlash = scripts[i].src.lastIndexOf("/"); + return scripts[i].src.substr(0, lastSlash); + } + } + } + + function evalCommandLine() + { + var text = commandLine.value; + commandLine.value = ""; + + logRow([clPrefix, text], "command"); + + var value; + try + { + value = eval(text); + } + catch (exc) + { + } + + console.log(value); + } + + function layout() + { + var toolbar = consoleBody.ownerDocument.getElementById("toolbar"); + var height = consoleFrame.offsetHeight - (toolbar.offsetHeight + commandLine.offsetHeight); + consoleBody.style.top = toolbar.offsetHeight + "px"; + consoleBody.style.height = height + "px"; + + commandLine.style.top = (consoleFrame.offsetHeight - commandLine.offsetHeight) + "px"; + } + + function logRow(message, className, handler) + { + if (consoleBody) + writeMessage(message, className, handler); + else + { + messageQueue.push([message, className, handler]); + waitForBody(); + } + } + + function flush() + { + var queue = messageQueue; + messageQueue = []; + + for (var i = 0; i < queue.length; ++i) + writeMessage(queue[i][0], queue[i][1], queue[i][2]); + } + + function writeMessage(message, className, handler) + { + var isScrolledToBottom = + consoleBody.scrollTop + consoleBody.offsetHeight >= consoleBody.scrollHeight; + + if (!handler) + handler = writeRow; + + handler(message, className); + + if (isScrolledToBottom) + consoleBody.scrollTop = consoleBody.scrollHeight - consoleBody.offsetHeight; + } + + function appendRow(row) + { + var container = groupStack.length ? groupStack[groupStack.length-1] : consoleBody; + container.appendChild(row); + } + + function writeRow(message, className) + { + var row = consoleBody.ownerDocument.createElement("div"); + row.className = "logRow" + (className ? " logRow-"+className : ""); + row.innerHTML = message.join(""); + appendRow(row); + } + + function pushGroup(message, className) + { + logFormatted(message, className); + + var groupRow = consoleBody.ownerDocument.createElement("div"); + groupRow.className = "logGroup"; + var groupRowBox = consoleBody.ownerDocument.createElement("div"); + groupRowBox.className = "logGroupBox"; + groupRow.appendChild(groupRowBox); + appendRow(groupRowBox); + groupStack.push(groupRowBox); + } + + function popGroup() + { + groupStack.pop(); + } + + // ******************************************************************************************** + + function logFormatted(objects, className) + { + var html = []; + + var format = objects[0]; + var objIndex = 0; + + if (typeof(format) != "string") + { + format = ""; + objIndex = -1; + } + + var parts = parseFormat(format); + for (var i = 0; i < parts.length; ++i) + { + var part = parts[i]; + if (part && typeof(part) == "object") + { + var object = objects[++objIndex]; + part.appender(object, html); + } + else + appendText(part, html); + } + + for (var i = objIndex+1; i < objects.length; ++i) + { + appendText(" ", html); + + var object = objects[i]; + if (typeof(object) == "string") + appendText(object, html); + else + appendObject(object, html); + } + + logRow(html, className); + } + + function parseFormat(format) + { + var parts = []; + + var reg = /((^%|[^\\]%)(\d+)?(\.)([a-zA-Z]))|((^%|[^\\]%)([a-zA-Z]))/; + var appenderMap = {s: appendText, d: appendInteger, i: appendInteger, f: appendFloat}; + + for (var m = reg.exec(format); m; m = reg.exec(format)) + { + var type = m[8] ? m[8] : m[5]; + var appender = type in appenderMap ? appenderMap[type] : appendObject; + var precision = m[3] ? parseInt(m[3]) : (m[4] == "." ? -1 : 0); + + parts.push(format.substr(0, m[0][0] == "%" ? m.index : m.index+1)); + parts.push({appender: appender, precision: precision}); + + format = format.substr(m.index+m[0].length); + } + + parts.push(format); + + return parts; + } + + function escapeHTML(value) + { + function replaceChars(ch) + { + switch (ch) + { + case "<": + return "<"; + case ">": + return ">"; + case "&": + return "&"; + case "'": + return "'"; + case '"': + return """; + } + return "?"; + }; + return String(value).replace(/[<>&"']/g, replaceChars); + } + + function objectToString(object) + { + try + { + return object+""; + } + catch (exc) + { + return null; + } + } + + // ******************************************************************************************** + + function appendText(object, html) + { + html.push(escapeHTML(objectToString(object))); + } + + function appendNull(object, html) + { + html.push('<span class="objectBox-null">', escapeHTML(objectToString(object)), '</span>'); + } + + function appendString(object, html) + { + html.push('<span class="objectBox-string">"', escapeHTML(objectToString(object)), + '"</span>'); + } + + function appendInteger(object, html) + { + html.push('<span class="objectBox-number">', escapeHTML(objectToString(object)), '</span>'); + } + + function appendFloat(object, html) + { + html.push('<span class="objectBox-number">', escapeHTML(objectToString(object)), '</span>'); + } + + function appendFunction(object, html) + { + var reName = /function ?(.*?)\(/; + var m = reName.exec(objectToString(object)); + var name = m ? m[1] : "function"; + html.push('<span class="objectBox-function">', escapeHTML(name), '()</span>'); + } + + function appendObject(object, html) + { + try + { + if (object == undefined) + appendNull("undefined", html); + else if (object == null) + appendNull("null", html); + else if (typeof object == "string") + appendString(object, html); + else if (typeof object == "number") + appendInteger(object, html); + else if (typeof object == "function") + appendFunction(object, html); + else if (object.nodeType == 1) + appendSelector(object, html); + else if (typeof object == "object") + appendObjectFormatted(object, html); + else + appendText(object, html); + } + catch (exc) + { + } + } + + function appendObjectFormatted(object, html) + { + var text = objectToString(object); + var reObject = /\[object (.*?)\]/; + + var m = reObject.exec(text); + html.push('<span class="objectBox-object">', m ? m[1] : text, '</span>') + } + + function appendSelector(object, html) + { + html.push('<span class="objectBox-selector">'); + + html.push('<span class="selectorTag">', escapeHTML(object.nodeName.toLowerCase()), '</span>'); + if (object.id) + html.push('<span class="selectorId">#', escapeHTML(object.id), '</span>'); + if (object.className) + html.push('<span class="selectorClass">.', escapeHTML(object.className), '</span>'); + + html.push('</span>'); + } + + function appendNode(node, html) + { + if (node.nodeType == 1) + { + html.push( + '<div class="objectBox-element">', + '<<span class="nodeTag">', node.nodeName.toLowerCase(), '</span>'); + + for (var i = 0; i < node.attributes.length; ++i) + { + var attr = node.attributes[i]; + if (!attr.specified) + continue; + + html.push(' <span class="nodeName">', attr.nodeName.toLowerCase(), + '</span>="<span class="nodeValue">', escapeHTML(attr.nodeValue), + '</span>"') + } + + if (node.firstChild) + { + html.push('></div><div class="nodeChildren">'); + + for (var child = node.firstChild; child; child = child.nextSibling) + appendNode(child, html); + + html.push('</div><div class="objectBox-element"></<span class="nodeTag">', + node.nodeName.toLowerCase(), '></span></div>'); + } + else + html.push('/></div>'); + } + else if (node.nodeType == 3) + { + html.push('<div class="nodeText">', escapeHTML(node.nodeValue), + '</div>'); + } + } + + // ******************************************************************************************** + + function addEvent(object, name, handler) + { + if (document.all) + object.attachEvent("on"+name, handler); + else + object.addEventListener(name, handler, false); + } + + function removeEvent(object, name, handler) + { + if (document.all) + object.detachEvent("on"+name, handler); + else + object.removeEventListener(name, handler, false); + } + + function cancelEvent(event) + { + if (document.all) + event.cancelBubble = true; + else + event.stopPropagation(); + } + + function onError(msg, href, lineNo) + { + var html = []; + + var lastSlash = href.lastIndexOf("/"); + var fileName = lastSlash == -1 ? href : href.substr(lastSlash+1); + + html.push( + '<span class="errorMessage">', msg, '</span>', + '<div class="objectBox-sourceLink">', fileName, ' (line ', lineNo, ')</div>' + ); + + logRow(html, "error"); + }; + + function onKeyDown(event) + { + if (event.keyCode == 123) + toggleConsole(); + else if ((event.keyCode == 108 || event.keyCode == 76) && event.shiftKey + && (event.metaKey || event.ctrlKey)) + focusCommandLine(); + else + return; + + cancelEvent(event); + } + + function onSplitterMouseDown(event) + { + if (isSafari || isOpera) + return; + + addEvent(document, "mousemove", onSplitterMouseMove); + addEvent(document, "mouseup", onSplitterMouseUp); + + for (var i = 0; i < frames.length; ++i) + { + addEvent(frames[i].document, "mousemove", onSplitterMouseMove); + addEvent(frames[i].document, "mouseup", onSplitterMouseUp); + } + } + + function onSplitterMouseMove(event) + { + var win = document.all + ? event.srcElement.ownerDocument.parentWindow + : event.target.ownerDocument.defaultView; + + var clientY = event.clientY; + if (win != win.parent) + clientY += win.frameElement ? win.frameElement.offsetTop : 0; + + var height = consoleFrame.offsetTop + consoleFrame.clientHeight; + var y = height - clientY; + + consoleFrame.style.height = y + "px"; + layout(); + } + + function onSplitterMouseUp(event) + { + removeEvent(document, "mousemove", onSplitterMouseMove); + removeEvent(document, "mouseup", onSplitterMouseUp); + + for (var i = 0; i < frames.length; ++i) + { + removeEvent(frames[i].document, "mousemove", onSplitterMouseMove); + removeEvent(frames[i].document, "mouseup", onSplitterMouseUp); + } + } + + function onCommandLineKeyDown(event) + { + if (event.keyCode == 13) + evalCommandLine(); + else if (event.keyCode == 27) + commandLine.value = ""; + } + + window.onerror = onError; + addEvent(document, isIE || isSafari ? "keydown" : "keypress", onKeyDown); + + if (document.documentElement.getAttribute("debug") == "true") + toggleConsole(true); +})(); +} diff --git a/wqflask/wqflask/static/new/packages/ValidationPlugin/test/firebug/firebugx.js b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/firebug/firebugx.js new file mode 100644 index 00000000..5a467fc1 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/firebug/firebugx.js @@ -0,0 +1,10 @@ + +if (!("console" in window) || !("firebug" in console)) +{ + var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", + "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"]; + + window.console = {}; + for (var i = 0; i < names.length; ++i) + window.console[names[i]] = function() {} +}
\ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/ValidationPlugin/test/firebug/infoIcon.png b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/firebug/infoIcon.png Binary files differnew file mode 100644 index 00000000..da1e5334 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/firebug/infoIcon.png diff --git a/wqflask/wqflask/static/new/packages/ValidationPlugin/test/firebug/warningIcon.png b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/firebug/warningIcon.png Binary files differnew file mode 100644 index 00000000..de51084e --- /dev/null +++ b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/firebug/warningIcon.png diff --git a/wqflask/wqflask/static/new/packages/ValidationPlugin/test/index.html b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/index.html new file mode 100644 index 00000000..c2e8ef2b --- /dev/null +++ b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/index.html @@ -0,0 +1,300 @@ +<!DOCTYPE html> +<html id="html"> +<head> + <title>jQuery - Validation Test Suite</title> + <link rel="Stylesheet" media="screen" href="qunit/qunit.css" /> + <script type="text/javascript" src="jquery.js"></script> + <script type="text/javascript" src="../lib/jquery.form.js"></script> + <script type="text/javascript" src="qunit/qunit.js"></script> + <script type="text/javascript" src="../lib/jquery.metadata.js"></script> + <script type="text/javascript" src="../lib/jquery.mockjax.js"></script> + <script type="text/javascript" src="../jquery.validate.js"></script> + <script type="text/javascript" src="../additional-methods.js"></script> + <script type="text/javascript" src="test.js"></script> + <script type="text/javascript" src="rules.js"></script> + <script type="text/javascript" src="messages.js"></script> + <script type="text/javascript" src="methods.js"></script> +</head> +<body id="body"> + <h1 id="qunit-header"> + <a href="http://bassistance.de/jquery-plugins/jquery-plugin-validation/">jQuery Validation Plugin</a> Test Suite + <a href="?jquery=1.3.2">jQuery 1.3.2</a> + <a href="?jquery=1.4.2">jQuery 1.4.2</a> + <a href="?jquery=1.4.4">jQuery 1.4.4</a> + <a href="?jquery=1.5.2">jQuery 1.5.2</a> + <a href="?jquery=1.6.1">jQuery 1.6.1</a> + <a href="?jquery=1.7.2">jQuery 1.7.2</a> + <a href="?jquery=git">jQuery Latest (git)</a> + </h1> + <div> + </div> + <h2 id="qunit-banner"></h2> + <div id="qunit-testrunner-toolbar"></div> + <h2 id="qunit-userAgent"></h2> + <ol id="qunit-tests"></ol> + + <!-- Test HTML --> + <div id="other" style="display:none;"> + <input type="password" name="pw1" id="pw1" value="engfeh" /> + <input type="password" name="pw2" id="pw2" value="" /> + </div> + <div id="qunit-fixture"> + <p id="firstp">See <a id="simon1" href="http://simon.incutio.com/archive/2003/03/25/#getElementsBySelector" rel="bookmark">this blog entry</a> for more information.</p> + <p id="ap"> + Here are some links in a normal paragraph: <a id="google" href="http://www.google.com/" title="Google!">Google</a>, + <a id="groups" href="http://groups.google.com/">Google Groups</a>. + This link has <code><a href="#" id="anchor1">class="blog"</a></code>: + <a href="http://diveintomark.org/" class="blog" hreflang="en" id="mark">diveintomark</a> + + </p> + <div id="foo"> + <p id="sndp">Everything inside the red border is inside a div with <code>id="foo"</code>.</p> + <p lang="en" id="en">This is a normal link: <a id="yahoo" href="http://www.yahoo.com/" class="blogTest">Yahoo</a></p> + <p id="sap">This link has <code><a href="#2" id="anchor2">class="blog"</a></code>: <a href="http://simon.incutio.com/" class="blog link" id="simon">Simon Willison's Weblog</a></p> + + </div> + <p id="first">Try them out:</p> + <ul id="firstUL"></ul> + <ol id="empty"></ol> + + <form id="testForm1"> + <input type="text" class="{required:true,minlength:2}" title="buga" name="firstname" id="firstname" /> + <label id="errorFirstname" for="firstname" class="error">error for firstname</label> + <input type="text" class="{required:true}" title="buga" name="lastname" id="lastname" /> + <input type="text" class="{required:true}" title="something" name="something" id="something" value="something" /> + </form> + + <form id="testForm1clean"> + <input title="buga" name="firstname" id="firstnamec" /> + <label id="errorFirstname" for="firstname" class="error">error for firstname</label> + <input title="buga" name="lastname" id="lastnamec" /> + <input name="username" id="usernamec" /> + </form> + + <form id="userForm"> + <input type="text" class="{required:true}" name="username" id="username" /> + <input type="submit" name="submitButton" value="submitButtonValue" /> + </form> + + <form id="signupForm" action="form.php"> + <input id="user" name="user" title="Please enter your username (at least 3 characters)" class="{required:true,minlength:3}" /> + <input type="password" name="password" id="password" class="{required:true,minlength:5}" /> + </form> + + <form id="testForm2"> + <input class="{required:true}" type="radio" name="agree" id="agb" /> + <label for="agree" id="agreeLabel" class="xerror">error for agb</label> + </form> + + <form id="testForm3"> + <select class="{required:true}" name="meal" id="meal" > + <option value="">Please select...</option> + <option value="1">Food</option> + <option value="2">Milk</option> + </select> + </form> + <div class="error" id="errorContainer"> + <ul> + <li class="error" id="errorWrapper"> + <label for="meal" id="mealLabel" class="error">error for meal</label> + </li> + </ul> + </div> + + <form id="testForm4"> + <input class="{foo:true}" name="f1" id="f1" /> + <input class="{bar:true}" name="f2" id="f2" /> + </form> + + <form id="testForm5"> + <input class="{equalTo:'#x2'}" value="x" name="x1" id="x1" /> + <input class="{equalTo:'#x1'}" value="y" name="x2" id="x2" /> + </form> + + <form id="testForm6"> + <input class="{required:true,minlength:2}" type="checkbox" name="check" id="form6check1" /> + <input type="checkbox" name="check" id="form6check2" /> + </form> + + <form id="testForm7"> + <select class="{required:true,minlength:2}" name="selectf7" id="selectf7" multiple="multiple"> + <option id="optionxa" value="0">0</option> + <option id="optionxb" value="1">1</option> + <option id="optionxc" value="2">2</option> + <option id="optionxd" value="3">3</option> + </select> + </form> + + <form id="dateRangeForm"> + <input id="fromDate" name="fromDate" class="requiredDateRange" value="x" /> + <input id="toDate" name="toDate" class="requiredDateRange" value="y" /> + <span class="errorContainer"></span> + </form> + + <form id="testForm8"> + <input id="form8input" class="{required:true,number:true,rangelength:[2,8]}" name="abc" /> + <input type="radio" name="radio1"/> + </form> + + <form id="testForm9"> + <input id="testEmail9" class="{required:true,email:true,messages:{required:'required',email:'email'}}" /> + </form> + + <form id="testForm10"> + <input type="radio" name="testForm10Radio" value="1" id="testForm10Radio1" /> + <input type="radio" name="testForm10Radio" value="2" id="testForm10Radio2" /> + </form> + + <form id="testForm11"> + <!-- HTML5 --> + <input required type="text" name="testForm11Text" id="testForm11text1" /> + </form> + + <form id="testForm12"> + <!-- empty "type" attribute --> + <input name="testForm12text" id="testForm12text" class="{required:true}" /> + </form> + + <form id="dataMessages"> + <input name="dataMessagesName" id="dataMessagesName" class="required" data-msg-required="You must enter a value here" /> + </form> + + <div id="simplecontainer"> + <h3></h3> + </div> + + <div id="container"></div> + + <ol id="labelcontainer"></ol> + + <form id="elementsOrder"> + <select class="required" name="order1" id="order1"><option value="">none</option></select> + <input class="required" name="order2" id="order2"/> + <input class="required" name="order3" type="checkbox" id="order3"/> + <input class="required" name="order4" id="order4"/> + <input class="required" name="order5" type="radio" id="order5"/> + <input class="required" name="order6" id="order6"/> + <ul id="orderContainer"> + </ul> + </form> + + <form id="form" action="formaction"> + <input type="text" name="action" value="Test" id="text1"/> + <input type="text" name="text2" value=" " id="text1b"/> + <input type="text" name="text2" value="T " id="text1c"/> + <input type="text" name="text2" value="T" id="text2"/> + <input type="text" name="text2" value="TestTestTest" id="text3"/> + + <input type="text" name="action" value="0" id="value1"/> + <input type="text" name="text2" value="10" id="value2"/> + <input type="text" name="text2" value="1000" id="value3"/> + + <input type="radio" name="radio1" id="radio1"/> + <input type="radio" name="radio1" id="radio1a"/> + <input type="radio" name="radio2" id="radio2" checked="checked"/> + <input type="radio" name="radio" id="radio3"/> + <input type="radio" name="radio" id="radio4" checked="checked"/> + + <input type="checkbox" name="check" id="check1" checked="checked"/> + <input type="checkbox" name="check" id="check1b" /> + + <input type="checkbox" name="check2" id="check2"/> + + <input type="checkbox" name="check3" id="check3" checked="checked"/> + <input type="checkbox" name="check3" checked="checked"/> + <input type="checkbox" name="check3" checked="checked"/> + <input type="checkbox" name="check3" checked="checked"/> + <input type="checkbox" name="check3" checked="checked"/> + + <input type="hidden" name="hidden" id="hidden1"/> + <input type="text" style="display:none;" name="foo[bar]" id="hidden2"/> + + <input type="text" readonly="readonly" id="name" name="name" value="name" /> + + <button name="button">Button</button> + + <textarea id="area1" name="area1">foobar</textarea> + + + <textarea id="area2" name="area2"></textarea> + + <select name="select1" id="select1"> + <option id="option1a" value="">Nothing</option> + <option id="option1b" value="1">1</option> + <option id="option1c" value="2">2</option> + <option id="option1d" value="3">3</option> + </select> + <select name="select2" id="select2"> + <option id="option2a" value="">Nothing</option> + <option id="option2b" value="1">1</option> + <option id="option2c" value="2">2</option> + <option id="option2d" selected="selected" value="3">3</option> + </select> + <select name="select3" id="select3" multiple="multiple"> + <option id="option3a" value="">Nothing</option> + <option id="option3b" selected="selected" value="1">1</option> + <option id="option3c" selected="selected" value="2">2</option> + <option id="option3d" value="3">3</option> + </select> + <select name="select4" id="select4" multiple="multiple"> + <option id="option4a" selected="selected" value="1">1</option> + <option id="option4b" selected="selected" value="2">2</option> + <option id="option4c" selected="selected" value="3">3</option> + <option id="option4d" selected="selected" value="4">4</option> + <option id="option4e" selected="selected" value="5">5</option> + </select> + <select name="select5" id="select5" multiple="multiple"> + <option id="option5a" value="0">0</option> + <option id="option5b" value="1">1</option> + <option id="option5c" value="2">2</option> + <option id="option5d" value="3">3</option> + </select> + </form> + + <form id="v2"> + <input id="v2-i1" name="v2-i1" class="required" /> + <input id="v2-i2" name="v2-i2" class="required email" /> + <input id="v2-i3" name="v2-i3" class="url" /> + <input id="v2-i4" name="v2-i4" class="required" minlength="2" /> + <input id="v2-i5" name="v2-i5" class="required" minlength="2" maxlength="5" customMethod1="123" /> + <input id="v2-i6" name="v2-i6" class="required customMethod2 {maxlength: 5}" minlength="2" /> + <input id="v2-i7" name="v2-i7" /> + </form> + + <form id="checkables"> + <input type="checkbox" id="checkable1" name="checkablesgroup" class="required" /> + <input type="checkbox" id="checkable2" name="checkablesgroup" /> + <input type="checkbox" id="checkable3" name="checkablesgroup" /> + </form> + + + <form id="subformRequired"> + <div class="billingAddressControl"> + <input type="checkbox" id="bill_to_co" name="bill_to_co" class="toggleCheck" checked="checked" style="width: auto;" tabindex="1" /> + <label for="bill_to_co" style="cursor:pointer">Same as Company Address</label> + </div> + <div id="subform"> + <input maxlength="40" class="billingRequired" name="bill_first_name" size="20" type="text" tabindex="2" value="" /> + </div> + <input id="co_name" class="required" maxlength="40" name="co_name" size="20" type="text" tabindex="1" value="" /> + </form> + + <form id="withTitle"> + <input class="required" name="hastitle" type="text" title="fromtitle" /> + </form> + + <form id="ccform" method="get" action=""> + <input id="cardnumber" name="cardnumber" /> + </form> + + <form id="productInfo"> + <input class="productInfo" name="partnumber"> + <input class="productInfo" name="description"> + <input class="productInfo" name="color"> + <input class="productInfo" type="checkbox" name="discount" /> + </form> + + </div> + +</body> +</html> diff --git a/wqflask/wqflask/static/new/packages/ValidationPlugin/test/jquery.js b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/jquery.js new file mode 100644 index 00000000..100c4465 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/jquery.js @@ -0,0 +1,25 @@ +(function() { + +var parts = document.location.search.slice( 1 ).split( "&" ), + length = parts.length, + i = 0, + current, + version = "1.3.2", + file = "http://code.jquery.com/jquery-git.js"; + +for ( ; i < length; i++ ) { + current = parts[ i ].split( "=" ); + if ( current[ 0 ] === "jquery" ) { + version = current[ 1 ]; + break; + } +} + +if (version != "git") { + file = "../lib/jquery-" + version + ".js"; +} + + +document.write( "<script src='" + file + "'></script>" ); + +})(); diff --git a/wqflask/wqflask/static/new/packages/ValidationPlugin/test/large.html b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/large.html new file mode 100644 index 00000000..9e8a0e85 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/large.html @@ -0,0 +1,188 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /> +<title>Test for jQuery validate() plugin</title> + +<link rel="stylesheet" type="text/css" media="screen" href="css/screen.css" /> +<script src="../lib/jquery.js" type="text/javascript"></script> +<script src="../lib/jquery.metadata.js" type="text/javascript"></script> +<script src="../lib/jquery.ajaxQueue.js" type="text/javascript"></script> +<script src="../jquery.validate.js" type="text/javascript"></script> + +<script type="text/javascript"> +$().ready(function() { + $("#commentForm").validate(); +}); +</script> + +<style type="text/css"> +#commentForm { width: 500px; } +#commentForm label { width: 250px; display: block; float: left; } +#commentForm label.error, #commentForm input.submit { margin-left: 253px; } +.focus { background-color: red; } +</style> + +</head> +<body> +<form class="cmxform" id="commentForm" method="get" action=""> + <fieldset> + <legend>A simple comment form with submit validation and default messages</legend> + <p> + <label for="cname-x0">Name (required, at least 2 characters)</label> + <input id="cname-x0" name="name-x0" class="some other styles {required:true,minLength:2}" /> + <p> + <label for="cemail-x0">E-Mail (required)</label> + <input id="cemail-x0" name="email-x0" class="{required:true,email:true}" /> + </p> + <p> + <label for="curl-x0">URL (optional)</label> + <input id="curl-x0" name="url-x0" class="{url:true}" value="" /> + </p> + <p> + <label for="ccomment-x0">Your comment (required)</label> + <textarea id="ccomment-x0" name="comment-x0" class="{required:true}"></textarea> + </p> + <p> + <label for="cname-x1">Name (required, at least 2 characters)</label> + <input class="some other styles {required:true,minLength:2}" name="name-x1" id="cname-x1"/> + </p><p> + <label for="cemail-x1">E-Mail (required)</label> + <input class="{required:true,email:true}" name="email-x1" id="cemail-x1"/> + </p> + <p> + <label for="curl-x1">URL (optional)</label> + <input value="" class="{url:true}" name="url-x1" id="curl-x1"/> + </p> + <p> + <label for="ccomment-x1">Your comment (required)</label> + <textarea class="{required:true}" name="comment-x1" id="ccomment-x1"></textarea> + </p> + <p> + <label for="cname-x2">Name (required, at least 2 characters)</label> + <input class="some other styles {required:true,minLength:2}" name="name-x2" id="cname-x2"/> + </p><p> + <label for="cemail-x2">E-Mail (required)</label> + <input class="{required:true,email:true}" name="email-x2" id="cemail-x2"/> + </p> + <p> + <label for="curl-x2">URL (optional)</label> + <input value="" class="{url:true}" name="url-x2" id="curl-x2"/> + </p> + <p> + <label for="ccomment-x2">Your comment (required)</label> + <textarea class="{required:true}" name="comment-x2" id="ccomment-x2"></textarea> + </p> + <p> + <label for="cname-x3">Name (required, at least 2 characters)</label> + <input class="some other styles {required:true,minLength:2}" name="name-x3" id="cname-x3"/> + </p><p> + <label for="cemail-x3">E-Mail (required)</label> + <input class="{required:true,email:true}" name="email-x3" id="cemail-x3"/> + </p> + <p> + <label for="curl-x3">URL (optional)</label> + <input value="" class="{url:true}" name="url-x3" id="curl-x3"/> + </p> + <p> + <label for="ccomment-x3">Your comment (required)</label> + <textarea class="{required:true}" name="comment-x3" id="ccomment-x3"></textarea> + </p> + <p> + <label for="cname-x4">Name (required, at least 2 characters)</label> + <input class="some other styles {required:true,minLength:2}" name="name-x4" id="cname-x4"/> + </p><p> + <label for="cemail-x4">E-Mail (required)</label> + <input class="{required:true,email:true}" name="email-x4" id="cemail-x4"/> + </p> + <p> + <label for="curl-x4">URL (optional)</label> + <input value="" class="{url:true}" name="url-x4" id="curl-x4"/> + </p> + <p> + <label for="ccomment-x4">Your comment (required)</label> + <textarea class="{required:true}" name="comment-x4" id="ccomment-x4"></textarea> + </p> + <p> + <label for="cname-x5">Name (required, at least 2 characters)</label> + <input class="some other styles {required:true,minLength:2}" name="name-x5" id="cname-x5"/> + </p><p> + <label for="cemail-x5">E-Mail (required)</label> + <input class="{required:true,email:true}" name="email-x5" id="cemail-x5"/> + </p> + <p> + <label for="curl-x5">URL (optional)</label> + <input value="" class="{url:true}" name="url-x5" id="curl-x5"/> + </p> + <p> + <label for="ccomment-x5">Your comment (required)</label> + <textarea class="{required:true}" name="comment-x5" id="ccomment-x5"></textarea> + </p> + <p> + <label for="cname-x6">Name (required, at least 2 characters)</label> + <input class="some other styles {required:true,minLength:2}" name="name-x6" id="cname-x6"/> + </p><p> + <label for="cemail-x6">E-Mail (required)</label> + <input class="{required:true,email:true}" name="email-x6" id="cemail-x6"/> + </p> + <p> + <label for="curl-x6">URL (optional)</label> + <input value="" class="{url:true}" name="url-x6" id="curl-x6"/> + </p> + <p> + <label for="ccomment-x6">Your comment (required)</label> + <textarea class="{required:true}" name="comment-x6" id="ccomment-x6"></textarea> + </p> + <p> + <label for="cname-x7">Name (required, at least 2 characters)</label> + <input class="some other styles {required:true,minLength:2}" name="name-x7" id="cname-x7"/> + </p><p> + <label for="cemail-x7">E-Mail (required)</label> + <input class="{required:true,email:true}" name="email-x7" id="cemail-x7"/> + </p> + <p> + <label for="curl-x7">URL (optional)</label> + <input value="" class="{url:true}" name="url-x7" id="curl-x7"/> + </p> + <p> + <label for="ccomment-x7">Your comment (required)</label> + <textarea class="{required:true}" name="comment-x7" id="ccomment-x7"></textarea> + </p> + <p> + <label for="cname-x8">Name (required, at least 2 characters)</label> + <input class="some other styles {required:true,minLength:2}" name="name-x8" id="cname-x8"/> + </p><p> + <label for="cemail-x8">E-Mail (required)</label> + <input class="{required:true,email:true}" name="email-x8" id="cemail-x8"/> + </p> + <p> + <label for="curl-x8">URL (optional)</label> + <input value="" class="{url:true}" name="url-x8" id="curl-x8"/> + </p> + <p> + <label for="ccomment-x8">Your comment (required)</label> + <textarea class="{required:true}" name="comment-x8" id="ccomment-x8"></textarea> + </p> + <p> + <label for="cname-x9">Name (required, at least 2 characters)</label> + <input class="some other styles {required:true,minLength:2}" name="name-x9" id="cname-x9"/> + </p><p> + <label for="cemail-x9">E-Mail (required)</label> + <input class="{required:true,email:true}" name="email-x9" id="cemail-x9"/> + </p> + <p> + <label for="curl-x9">URL (optional)</label> + <input value="" class="{url:true}" name="url-x9" id="curl-x9"/> + </p> + <p> + <label for="ccomment-x9">Your comment (required)</label> + <textarea class="{required:true}" name="comment-x9" id="ccomment-x9"></textarea> + </p> + <p> + <input class="submit" type="submit" value="Submit"/> + </p> + </fieldset> +</form> + +</body> +</html> diff --git a/wqflask/wqflask/static/new/packages/ValidationPlugin/test/messages.js b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/messages.js new file mode 100644 index 00000000..5f6277af --- /dev/null +++ b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/messages.js @@ -0,0 +1,62 @@ +module("messages"); + +test("predefined message not overwritten by addMethod(a, b, undefined)", function() { + var message = "my custom message"; + $.validator.messages.custom = message; + $.validator.addMethod("custom", function() {}); + deepEqual(message, $.validator.messages.custom); + delete $.validator.messages.custom; + delete $.validator.methods.custom; +}); + +test("group error messages", function() { + $.validator.addClassRules({ + requiredDateRange: {required:true, date:true, dateRange:true} + }); + $.validator.addMethod("dateRange", function() { + return new Date($("#fromDate").val()) < new Date($("#toDate").val()); + }, "Please specify a correct date range."); + var form = $("#dateRangeForm"); + form.validate({ + groups: { + dateRange: "fromDate toDate" + }, + errorPlacement: function(error) { + form.find(".errorContainer").append(error); + } + }); + ok( !form.valid() ); + equal( 1, form.find(".errorContainer *").length ); + equal( "Please enter a valid date.", form.find(".errorContainer label.error").text() ); + + $("#fromDate").val("12/03/2006"); + $("#toDate").val("12/01/2006"); + ok( !form.valid() ); + equal( "Please specify a correct date range.", form.find(".errorContainer label.error").text() ); + + $("#toDate").val("12/04/2006"); + ok( form.valid() ); + ok( form.find(".errorContainer label.error").is(":hidden") ); +}); + +test("read messages from metadata", function() { + var form = $("#testForm9") + form.validate(); + var e = $("#testEmail9") + e.valid(); + equal( form.find("label").text(), "required" ); + e.val("bla").valid(); + equal( form.find("label").text(), "email" ); +}); + + +test("read messages from metadata, with meta option specified, but no metadata in there", function() { + var form = $("#testForm1clean") + form.validate({ + meta: "validate", + rules: { + firstname: "required" + } + }); + ok(!form.valid(), "not valid"); +}); diff --git a/wqflask/wqflask/static/new/packages/ValidationPlugin/test/methods.js b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/methods.js new file mode 100644 index 00000000..61643c99 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/methods.js @@ -0,0 +1,757 @@ +(function($) { + +function methodTest( methodName ) { + var v = jQuery("#form").validate(); + var method = $.validator.methods[methodName]; + var element = $("#firstname")[0]; + return function(value, param) { + element.value = value; + return method.call( v, value, element, param ); + }; +} + +module("methods"); + +test("default messages", function() { + var m = $.validator.methods; + $.each(m, function(key) { + ok( jQuery.validator.messages[key], key + " has a default message." ); + }); +}); + +test("digit", function() { + var method = methodTest("digits"); + ok( method( "123" ), "Valid digits" ); + ok(!method( "123.000" ), "Invalid digits" ); + ok(!method( "123.000,00" ), "Invalid digits" ); + ok(!method( "123.0.0,0" ), "Invalid digits" ); + ok(!method( "x123" ), "Invalid digits" ); + ok(!method( "100.100,0,0" ), "Invalid digits" ); +}); + +test("url", function() { + var method = methodTest("url"); + ok( method( "http://bassistance.de/jquery/plugin.php?bla=blu" ), "Valid url" ); + ok( method( "https://bassistance.de/jquery/plugin.php?bla=blu" ), "Valid url" ); + ok( method( "ftp://bassistance.de/jquery/plugin.php?bla=blu" ), "Valid url" ); + ok( method( "http://www.føtex.dk/" ), "Valid url, danish unicode characters" ); + ok( method( "http://bösendorfer.de/" ), "Valid url, german unicode characters" ); + ok( method( "http://192.168.8.5" ), "Valid IP Address" ) + ok(!method( "http://192.168.8." ), "Invalid IP Address" ) + ok(!method( "http://bassistance" ), "Invalid url" ); // valid + ok(!method( "http://bassistance." ), "Invalid url" ); // valid + ok(!method( "http://bassistance,de" ), "Invalid url" ); + ok(!method( "http://bassistance;de" ), "Invalid url" ); + ok(!method( "http://.bassistancede" ), "Invalid url" ); + ok(!method( "bassistance.de" ), "Invalid url" ); +}); + +test("url2 (tld optional)", function() { + var method = methodTest("url2"); + ok( method( "http://bassistance.de/jquery/plugin.php?bla=blu" ), "Valid url" ); + ok( method( "https://bassistance.de/jquery/plugin.php?bla=blu" ), "Valid url" ); + ok( method( "ftp://bassistance.de/jquery/plugin.php?bla=blu" ), "Valid url" ); + ok( method( "http://www.føtex.dk/" ), "Valid url, danish unicode characters" ); + ok( method( "http://bösendorfer.de/" ), "Valid url, german unicode characters" ); + ok( method( "http://192.168.8.5" ), "Valid IP Address" ) + ok(!method( "http://192.168.8." ), "Invalid IP Address" ) + ok( method( "http://bassistance" ), "Invalid url" ); + ok( method( "http://bassistance." ), "Invalid url" ); + ok(!method( "http://bassistance,de" ), "Invalid url" ); + ok(!method( "http://bassistance;de" ), "Invalid url" ); + ok(!method( "http://.bassistancede" ), "Invalid url" ); + ok(!method( "bassistance.de" ), "Invalid url" ); +}); + +test("email", function() { + var method = methodTest("email"); + ok( method( "name@domain.tld" ), "Valid email" ); + ok( method( "name@domain.tl" ), "Valid email" ); + ok( method( "bart+bart@tokbox.com" ), "Valid email" ); + ok( method( "bart+bart@tokbox.travel" ), "Valid email" ); + ok( method( "n@d.tld" ), "Valid email" ); + ok( method( "ole@føtex.dk"), "Valid email" ); + ok( method( "jörn@bassistance.de"), "Valid email" ); + ok( method( "bla.blu@g.mail.com"), "Valid email" ); + ok( method( "\"Scott Gonzalez\"@example.com" ), "Valid email" ); + ok( method( "\"Scott González\"@example.com" ), "Valid email" ); + ok( method( "\"name.\"@domain.tld" ), "Valid email" ); // valid without top label + ok( method( "\"name,\"@domain.tld" ), "Valid email" ); // valid without top label + ok( method( "\"name;\"@domain.tld" ), "Valid email" ); // valid without top label + ok(!method( "name" ), "Invalid email" ); + ok(!method( "name@" ), "Invalid email" ); + ok(!method( "name@domain" ), "Invalid email" ); + ok(!method( "name.@domain.tld" ), "Invalid email" ); + ok(!method( "name,@domain.tld" ), "Invalid email" ); + ok(!method( "name;@domain.tld" ), "Invalid email" ); + ok(!method( "name;@domain.tld." ), "Invalid email" ); +}); + +test("email2 (tld optional)", function() { + var method = methodTest("email2"); + ok( method( "name@domain.tld" ), "Valid email" ); + ok( method( "name@domain.tl" ), "Valid email" ); + ok( method( "bart+bart@tokbox.com" ), "Valid email" ); + ok( method( "bart+bart@tokbox.travel" ), "Valid email" ); + ok( method( "n@d.tld" ), "Valid email" ); + ok( method( "ole@føtex.dk"), "Valid email" ); + ok( method( "jörn@bassistance.de"), "Valid email" ); + ok( method( "bla.blu@g.mail.com"), "Valid email" ); + ok( method( "\"Scott Gonzalez\"@example.com" ), "Valid email" ); + ok( method( "\"Scott González\"@example.com" ), "Valid email" ); + ok( method( "\"name.\"@domain.tld" ), "Valid email" ); // valid without top label + ok( method( "\"name,\"@domain.tld" ), "Valid email" ); // valid without top label + ok( method( "\"name;\"@domain.tld" ), "Valid email" ); // valid without top label + ok(!method( "name" ), "Invalid email" ); + ok(!method( "name@" ), "Invalid email" ); + ok( method( "name@domain" ), "Invalid email" ); + ok(!method( "name.@domain.tld" ), "Invalid email" ); + ok(!method( "name,@domain.tld" ), "Invalid email" ); + ok(!method( "name;@domain.tld" ), "Invalid email" ); +}); + +test("number", function() { + var method = methodTest("number"); + ok( method( "123" ), "Valid number" ); + ok( method( "-123" ), "Valid number" ); + ok( method( "123,000" ), "Valid number" ); + ok( method( "-123,000" ), "Valid number" ); + ok( method( "123,000.00" ), "Valid number" ); + ok( method( "-123,000.00" ), "Valid number" ); + ok(!method( "123.000,00" ), "Invalid number" ); + ok(!method( "123.0.0,0" ), "Invalid number" ); + ok(!method( "x123" ), "Invalid number" ); + ok(!method( "100.100,0,0" ), "Invalid number" ); + + ok( method( "" ), "Blank is valid" ); + ok( method( "123" ), "Valid decimal" ); + ok( method( "123000" ), "Valid decimal" ); + ok( method( "123000.12" ), "Valid decimal" ); + ok( method( "-123000.12" ), "Valid decimal" ); + ok( method( "123.000" ), "Valid decimal" ); + ok( method( "123,000.00" ), "Valid decimal" ); + ok( method( "-123,000.00" ), "Valid decimal" ); + ok( method( ".100" ), "Valid decimal" ); + ok(!method( "1230,000.00" ), "Invalid decimal" ); + ok(!method( "123.0.0,0" ), "Invalid decimal" ); + ok(!method( "x123" ), "Invalid decimal" ); + ok(!method( "100.100,0,0" ), "Invalid decimal" ); +}); + +/* disabled for now, need to figure out how to test localized methods +test("numberDE", function() { + var method = methodTest("numberDE"); + ok( method( "123" ), "Valid numberDE" ); + ok( method( "-123" ), "Valid numberDE" ); + ok( method( "123.000" ), "Valid numberDE" ); + ok( method( "-123.000" ), "Valid numberDE" ); + ok( method( "123.000,00" ), "Valid numberDE" ); + ok( method( "-123.000,00" ), "Valid numberDE" ); + ok(!method( "123,000.00" ), "Invalid numberDE" ); + ok(!method( "123,0,0.0" ), "Invalid numberDE" ); + ok(!method( "x123" ), "Invalid numberDE" ); + ok(!method( "100,100.0.0" ), "Invalid numberDE" ); + + ok( method( "" ), "Blank is valid" ); + ok( method( "123" ), "Valid decimalDE" ); + ok( method( "123000" ), "Valid decimalDE" ); + ok( method( "123000,12" ), "Valid decimalDE" ); + ok( method( "-123000,12" ), "Valid decimalDE" ); + ok( method( "123.000" ), "Valid decimalDE" ); + ok( method( "123.000,00" ), "Valid decimalDE" ); + ok( method( "-123.000,00" ), "Valid decimalDE" ) + ok(!method( "123.0.0,0" ), "Invalid decimalDE" ); + ok(!method( "x123" ), "Invalid decimalDE" ); + ok(!method( "100,100.0.0" ), "Invalid decimalDE" ); +}); +*/ + +test("date", function() { + var method = methodTest("date"); + ok( method( "06/06/1990" ), "Valid date" ); + ok( method( "6/6/06" ), "Valid date" ); + ok(!method( "1990x-06-06" ), "Invalid date" ); +}); + +test("dateISO", function() { + var method = methodTest("dateISO"); + ok( method( "1990-06-06" ), "Valid date" ); + ok( method( "1990/06/06" ), "Valid date" ); + ok( method( "1990-6-6" ), "Valid date" ); + ok( method( "1990/6/6" ), "Valid date" ); + ok(!method( "1990-106-06" ), "Invalid date" ); + ok(!method( "190-06-06" ), "Invalid date" ); +}); + +/* disabled for now, need to figure out how to test localized methods +test("dateDE", function() { + var method = methodTest("dateDE"); + ok( method( "03.06.1984" ), "Valid dateDE" ); + ok( method( "3.6.84" ), "Valid dateDE" ); + ok(!method( "6-6-06" ), "Invalid dateDE" ); + ok(!method( "1990-06-06" ), "Invalid dateDE" ); + ok(!method( "06/06/1990" ), "Invalid dateDE" ); + ok(!method( "6/6/06" ), "Invalid dateDE" ); +}); +*/ + +test("required", function() { + var v = jQuery("#form").validate(), + method = $.validator.methods.required, + e = $('#text1, #text1b, #hidden2, #select1, #select2'); + ok( method.call( v, e[0].value, e[0]), "Valid text input" ); + ok(!method.call( v, e[1].value, e[1]), "Invalid text input" ); + ok(!method.call( v, e[1].value, e[2]), "Invalid text input" ); + + ok(!method.call( v, e[2].value, e[3]), "Invalid select" ); + ok( method.call( v, e[3].value, e[4]), "Valid select" ); + + e = $('#area1, #area2, #pw1, #pw2'); + ok( method.call( v, e[0].value, e[0]), "Valid textarea" ); + ok(!method.call( v, e[1].value, e[1]), "Invalid textarea" ); + ok( method.call( v, e[2].value, e[2]), "Valid password input" ); + ok(!method.call( v, e[3].value, e[3]), "Invalid password input" ); + + e = $('#radio1, #radio2, #radio3'); + ok(!method.call( v, e[0].value, e[0]), "Invalid radio" ); + ok( method.call( v, e[1].value, e[1]), "Valid radio" ); + ok( method.call( v, e[2].value, e[2]), "Valid radio" ); + + e = $('#check1, #check2'); + ok( method.call( v, e[0].value, e[0]), "Valid checkbox" ); + ok(!method.call( v, e[1].value, e[1]), "Invalid checkbox" ); + + e = $('#select1, #select2, #select3, #select4'); + ok(!method.call( v, e[0].value, e[0]), "Invalid select" ); + ok( method.call( v, e[1].value, e[1]), "Valid select" ); + ok( method.call( v, e[2].value, e[2]), "Valid select" ); + ok( method.call( v, e[3].value, e[3]), "Valid select" ); +}); + +test("required with dependencies", function() { + var v = jQuery("#form").validate(), + method = $.validator.methods.required, + e = $('#hidden2, #select1, #area2, #radio1, #check2'); + ok( method.call( v, e[0].value, e[0], "asffsaa"), "Valid text input due to depencie not met" ); + ok(!method.call( v, e[0].value, e[0], "input"), "Invalid text input" ); + ok( method.call( v, e[0].value, e[0], function() { return false; }), "Valid text input due to depencie not met" ); + ok(!method.call( v, e[0].value, e[0], function() { return true; }), "Invalid text input" ); + ok( method.call( v, e[1].value, e[1], "asfsfa"), "Valid select due to dependency not met" ); + ok(!method.call( v, e[1].value, e[1], "input"), "Invalid select" ); + ok( method.call( v, e[2].value, e[2], "asfsafsfa"), "Valid textarea due to dependency not met" ); + ok(!method.call( v, e[2].value, e[2], "input"), "Invalid textarea" ); + ok( method.call( v, e[3].value, e[3], "asfsafsfa"), "Valid radio due to dependency not met" ); + ok(!method.call( v, e[3].value, e[3], "input"), "Invalid radio" ); + ok( method.call( v, e[4].value, e[4], "asfsafsfa"), "Valid checkbox due to dependency not met" ); + ok(!method.call( v, e[4].value, e[4], "input"), "Invalid checkbox" ); +}); + +test("minlength", function() { + var v = jQuery("#form").validate(), + method = $.validator.methods.minlength, + param = 2, + e = $('#text1, #text1c, #text2, #text3'); + ok( method.call( v, e[0].value, e[0], param), "Valid text input" ); + ok(!method.call( v, e[1].value, e[1], param), "Invalid text input" ); + ok(!method.call( v, e[2].value, e[2], param), "Invalid text input" ); + ok( method.call( v, e[3].value, e[3], param), "Valid text input" ); + + e = $('#check1, #check2, #check3'); + ok(!method.call( v, e[0].value, e[0], param), "Valid checkbox" ); + ok( method.call( v, e[1].value, e[1], param), "Valid checkbox" ); + ok( method.call( v, e[2].value, e[2], param), "Invalid checkbox" ); + + e = $('#select1, #select2, #select3, #select4, #select5'); + ok(method.call( v, e[0].value, e[0], param), "Valid select " + e[0].id ); + ok(!method.call( v, e[1].value, e[1], param), "Invalid select " + e[1].id ); + ok( method.call( v, e[2].value, e[2], param), "Valid select " + e[2].id ); + ok( method.call( v, e[3].value, e[3], param), "Valid select " + e[3].id ); + ok( method.call( v, e[4].value, e[4], param), "Valid select " + e[4].id ); +}); + +test("maxlength", function() { + var v = jQuery("#form").validate(); + var method = $.validator.methods.maxlength, + param = 4, + e = $('#text1, #text2, #text3'); + ok( method.call( v, e[0].value, e[0], param), "Valid text input" ); + ok( method.call( v, e[1].value, e[1], param), "Valid text input" ); + ok(!method.call( v, e[2].value, e[2], param), "Invalid text input" ); + + e = $('#check1, #check2, #check3'); + ok( method.call( v, e[0].value, e[0], param), "Valid checkbox" ); + ok( method.call( v, e[1].value, e[1], param), "Invalid checkbox" ); + ok(!method.call( v, e[2].value, e[2], param), "Invalid checkbox" ); + + e = $('#select1, #select2, #select3, #select4'); + ok( method.call( v, e[0].value, e[0], param), "Valid select" ); + ok( method.call( v, e[1].value, e[1], param), "Valid select" ); + ok( method.call( v, e[2].value, e[2], param), "Valid select" ); + ok(!method.call( v, e[3].value, e[3], param), "Invalid select" ); +}); + +test("rangelength", function() { + var v = jQuery("#form").validate(); + var method = $.validator.methods.rangelength, + param = [2, 4], + e = $('#text1, #text2, #text3'); + ok( method.call( v, e[0].value, e[0], param), "Valid text input" ); + ok(!method.call( v, e[1].value, e[1], param), "Invalid text input" ); + ok(!method.call( v, e[2].value, e[2], param), "Invalid text input" ); +}); + +test("min", function() { + var v = jQuery("#form").validate(); + var method = $.validator.methods.min, + param = 8, + e = $('#value1, #value2, #value3'); + ok(!method.call( v, e[0].value, e[0], param), "Invalid text input" ); + ok( method.call( v, e[1].value, e[1], param), "Valid text input" ); + ok( method.call( v, e[2].value, e[2], param), "Valid text input" ); +}); + +test("max", function() { + var v = jQuery("#form").validate(); + var method = $.validator.methods.max, + param = 12, + e = $('#value1, #value2, #value3'); + ok( method.call( v, e[0].value, e[0], param), "Valid text input" ); + ok( method.call( v, e[1].value, e[1], param), "Valid text input" ); + ok(!method.call( v, e[2].value, e[2], param), "Invalid text input" ); +}); + +test("range", function() { + var v = jQuery("#form").validate(); + var method = $.validator.methods.range, + param = [4,12], + e = $('#value1, #value2, #value3'); + ok(!method.call( v, e[0].value, e[0], param), "Invalid text input" ); + ok( method.call( v, e[1].value, e[1], param), "Valid text input" ); + ok(!method.call( v, e[2].value, e[2], param), "Invalid text input" ); +}); + +test("equalTo", function() { + var v = jQuery("#form").validate(); + var method = $.validator.methods.equalTo, + e = $('#text1, #text2'); + ok( method.call( v, "Test", e[0], "#text1"), "Text input" ); + ok( method.call( v, "T", e[1], "#text2"), "Another one" ); +}); + +test("creditcard", function() { + var method = methodTest("creditcard"); + ok( method( "446-667-651" ), "Valid creditcard number" ); + ok( method( "446 667 651" ), "Valid creditcard number" ); + ok( !method( "asdf" ), "Invalid creditcard number" ); +}); + +test("extension", function() { + var method = methodTest("extension"); + ok( method( "picture.gif" ), "Valid default accept type" ); + ok( method( "picture.jpg" ), "Valid default accept type" ); + ok( method( "picture.jpeg" ), "Valid default accept type" ); + ok( method( "picture.png" ), "Valid default accept type" ); + ok( !method( "picture.pgn" ), "Invalid default accept type" ); + + var v = jQuery("#form").validate(), + method = function(value, param) { + return $.validator.methods.extension.call(v, value, $('#text1')[0], param); + }; + ok( method( "picture.doc", "doc"), "Valid custom accept type" ); + ok( method( "picture.pdf", "doc|pdf"), "Valid custom accept type" ); + ok( method( "picture.pdf", "pdf|doc"), "Valid custom accept type" ); + ok( !method( "picture.pdf", "doc"), "Invalid custom accept type" ); + ok( !method( "picture.doc", "pdf"), "Invalid custom accept type" ); + + ok( method( "picture.pdf", "doc,pdf"), "Valid custom accept type, comma seperated" ); + ok( method( "picture.pdf", "pdf,doc"), "Valid custom accept type, comma seperated" ); + ok( !method( "picture.pdf", "gop,top"), "Invalid custom accept type, comma seperated" ); +}); + +test("remote", function() { + expect(7); + stop(); + var e = $("#username"); + var v = $("#userForm").validate({ + rules: { + username: { + required: true, + remote: "users.php" + } + }, + messages: { + username: { + required: "Please", + remote: jQuery.validator.format("{0} in use") + } + }, + submitHandler: function() { + ok( false, "submitHandler may never be called when validating only elements"); + } + }); + $(document).ajaxStop(function() { + $(document).unbind("ajaxStop"); + equal( 1, v.size(), "There must be one error" ); + equal( "Peter in use", v.errorList[0].message ); + + $(document).ajaxStop(function() { + $(document).unbind("ajaxStop"); + equal( 1, v.size(), "There must be one error" ); + equal( "Peter2 in use", v.errorList[0].message ); + start(); + }); + e.val("Peter2"); + strictEqual( v.element(e), true, "new value, new request; dependency-mismatch considered as valid though" ); + }); + strictEqual( v.element(e), false, "invalid element, nothing entered yet" ); + e.val("Peter"); + strictEqual( v.element(e), true, "still invalid, because remote validation must block until it returns; dependency-mismatch considered as valid though" ); +}); + +test("remote, customized ajax options", function() { + expect(2); + stop(); + var v = $("#userForm").validate({ + rules: { + username: { + required: true, + remote: { + url: "users.php", + type: "POST", + beforeSend: function(request, settings) { + deepEqual(settings.type, "POST"); + deepEqual(settings.data, "username=asdf&email=email.com"); + }, + data: { + email: function() { + return "email.com"; + } + }, + complete: function() { + start(); + } + } + } + } + }); + $("#username").val("asdf"); + $("#userForm").valid(); +}); + + +test("remote extensions", function() { + expect(5); + stop(); + var e = $("#username"); + var v = $("#userForm").validate({ + rules: { + username: { + required: true, + remote: "users2.php" + } + }, + messages: { + username: { + required: "Please" + } + }, + submitHandler: function() { + ok( false, "submitHandler may never be called when validating only elements"); + } + }); + $(document).ajaxStop(function() { + $(document).unbind("ajaxStop"); + equal( 1, v.size(), "There must be one error" ); + equal( v.errorList[0].message, "asdf is already taken, please try something else" ); + v.element(e); + equal( v.errorList[0].message, "asdf is already taken, please try something else", "message doesn't change on revalidation" ); + start(); + }); + strictEqual( v.element(e), false, "invalid element, nothing entered yet" ); + e.val("asdf"); + strictEqual( v.element(e), true, "still invalid, because remote validation must block until it returns; dependency-mismatch considered as valid though" ); +}); + +asyncTest("remote radio correct value sent", function() { + expect(1); + var e = $("#testForm10Radio2"); + e.attr('checked', 'checked'); + var v = $("#testForm10").validate({ + rules: { + testForm10Radio: { + required: true, + remote: { + url: "echo.php", + dataType: "json", + success: function(data) { + equal( data['testForm10Radio'], '2', ' correct radio value sent' ); + start(); + } + } + }, + } + }); + + v.element(e); +}); + +asyncTest("remote reset clear old value", function() { + expect(1); + + var e = $("#username"); + var v = $("#userForm").validate({ + rules: { + username: { + required: true, + remote: { + url: "echo.php", + dataFilter: function(data) { + var json = JSON.parse(data); + if(json.username == 'asdf') { + return "\"asdf is already taken\""; + } + return "\"" + true + "\""; + } + } + } + } + }); + $(document).ajaxStop(function() { + var waitTimeout; + + $(document).unbind("ajaxStop"); + + + $(document).ajaxStop(function() { + clearTimeout(waitTimeout); + ok( true, "Remote request sent to server" ); + start(); + }); + + + v.resetForm(); + e.val("asdf"); + waitTimeout = setTimeout(function() { + ok( false, "Remote server did not get request"); + start(); + }, 200); + v.element(e); + }); + e.val("asdf"); + v.element(e); +}); + +module("additional methods"); + +test("phone (us)", function() { + var method = methodTest("phoneUS"); + ok( method( "1(212)-999-2345" ), "Valid us phone number" ); + ok( method( "212 999 2344" ), "Valid us phone number" ); + ok( method( "212-999-0983" ), "Valid us phone number" ); + ok(!method( "111-123-5434" ), "Invalid us phone number" ); + ok(!method( "212 123 4567" ), "Invalid us phone number" ); +}); + +test("mobileUK", function() { + var method = methodTest("mobileUK"); + ok( method( "07734234323" ), "Valid UK Mobile Number" ); + ok( method( "+447734234323" ), "Valid UK Mobile Number" ); + ok( !method( "07034234323" ), "Invalid UK Mobile Number" ); + ok( !method( "0753423432" ), "Invalid UK Mobile Number" ); + ok( !method( "07604234323" ), "Invalid UK Mobile Number" ); + ok( !method( "077342343234" ), "Invalid UK Mobile Number" ); + ok( !method( "044342343234" ), "Invalid UK Mobile Number" ); + ok( !method( "+44753423432" ), "Invalid UK Mobile Number" ); + ok( !method( "+447604234323" ), "Invalid UK Mobile Number" ); + ok( !method( "+4477342343234" ), "Invalid UK Mobile Number" ); + ok( !method( "+4444342343234" ), "Invalid UK Mobile Number" ); +}); + +test("dateITA", function() { + var method = methodTest("dateITA"); + ok( method( "01/01/1900" ), "Valid date ITA" ); + ok(!method( "01/13/1990" ), "Invalid date ITA" ); + ok(!method( "01.01.1900" ), "Invalid date ITA" ); +}); + +test("time", function() { + var method = methodTest("time"); + ok( method("00:00"), "Valid time, lower bound" ); + ok( method("23:59"), "Valid time, upper bound" ); + ok( !method("12"), "Invalid time" ); + ok( !method("00:60"), "Invalid time" ); + ok( !method("24:60"), "Invalid time" ); + ok( !method("24:00"), "Invalid time" ); + ok( !method("29:59"), "Invalid time" ); + ok( !method("30:00"), "Invalid time" ); +}); + +test("time12h", function() { + var method = methodTest("time12h"); + ok( method("12:00 AM"), "Valid time, lower bound, am" ); + ok( method("11:59 AM"), "Valid time, upper bound, am" ); + ok( method("12:00 PM"), "Valid time, lower bound, pm" ); + ok( method("11:59 PM"), "Valid time, upper bound, pm" ); + ok( method("11:59 am"), "Valid time, also accept lowercase" ); + ok( method("11:59 pm"), "Valid time, also accept lowercase" ); + ok( !method("12:00"), "Invalid time" ); + ok( !method("12:61 am"), "Invalid time" ); + ok( !method("13:00 am"), "Invalid time" ); +}); + +test("minWords", function() { + var method = methodTest("minWords"); + ok( method("hello worlds", 2), "plain text, valid" ); + ok( method("<b>hello</b> world", 2), "html, valid" ); + ok( !method("hello", 2), "plain text, invalid" ); + ok( !method("<b>world</b>", 2), "html, invalid" ); + ok( !method("world <br/>", 2), "html, invalid" ); +}); + +test("maxWords", function() { + var method = methodTest("maxWords"); + ok( method("hello", 2), "plain text, valid" ); + ok( method("<b>world</b>", 2), "html, valid" ); + ok( method("world <br/>", 2), "html, valid" ); + ok( method("hello worlds", 2), "plain text, valid" ); + ok( method("<b>hello</b> world", 2), "html, valid" ); + ok( !method("hello 123 world", 2), "plain text, invalid" ); + ok( !method("<b>hello</b> 123 world", 2), "html, invalid" ); +}); + +test("rangeWords", function() { + var method = methodTest("rangeWords"); + ok( method("hello", [0, 2]), "plain text, valid" ); + ok( method("hello worlds", [0, 2]), "plain text, valid" ); + ok( method("<b>hello</b> world", [0, 2]), "html, valid" ); + ok( !method("hello worlds what is up", [0, 2]), "plain text, invalid" ); + ok( !method("<b>Hello</b> <b>world</b> <b>hello</b>", [0, 2]), "html, invalid" ); +}); + +test("pattern", function() { + var method = methodTest("pattern"); + ok( method( "AR1004", "AR\\d{4}" ), "Correct format for the given RegExp" ); + ok( method( "AR1004", /^AR\d{4}$/ ), "Correct format for the given RegExp" ); + ok( !method( "BR1004", /^AR\d{4}$/ ), "Invalid format for the given RegExp" ); +}); + +function testCardTypeByNumber(number, cardname, expected) { + $("#cardnumber").val(number); + var actual = $("#ccform").valid(); + equal(actual, expected, $.format("Expect card number {0} to validate to {1}, actually validated to ", number, expected)); +} + +test('creditcardtypes, all', function() { + $("#ccform").validate({ + rules: { + cardnumber: { + creditcard: true, + creditcardtypes: { + all: true + } + } + } + }); + + testCardTypeByNumber("4111-1111-1111-1111", "VISA", true) + testCardTypeByNumber("5111-1111-1111-1118", "MasterCard", true) + testCardTypeByNumber("6111-1111-1111-1116", "Discover", true) + testCardTypeByNumber("3400-0000-0000-009", "AMEX", true); + + testCardTypeByNumber("4111-1111-1111-1110", "VISA", false) + testCardTypeByNumber("5432-1111-1111-1111", "MasterCard", false) + testCardTypeByNumber("6611-6611-6611-6611", "Discover", false) + testCardTypeByNumber("3777-7777-7777-7777", "AMEX", false) + +}); + +test('creditcardtypes, visa', function() { + $("#ccform").validate({ + rules: { + cardnumber: { + creditcard: true, + creditcardtypes: { + visa: true + } + } + } + }); + + testCardTypeByNumber("4111-1111-1111-1111", "VISA", true) + testCardTypeByNumber("5111-1111-1111-1118", "MasterCard", false) + testCardTypeByNumber("6111-1111-1111-1116", "Discover", false) + testCardTypeByNumber("3400-0000-0000-009", "AMEX", false); +}); + +test('creditcardtypes, mastercard', function() { + $("#ccform").validate({ + rules: { + cardnumber: { + creditcard: true, + creditcardtypes: { + mastercard: true + } + } + } + }); + + testCardTypeByNumber("5111-1111-1111-1118", "MasterCard", true) + testCardTypeByNumber("6111-1111-1111-1116", "Discover", false) + testCardTypeByNumber("3400-0000-0000-009", "AMEX", false); + testCardTypeByNumber("4111-1111-1111-1111", "VISA", false); +}); + +function fillFormWithValuesAndExpect(formSelector, inputValues, expected) { + for (i=0; i < inputValues.length; i++) { + $(formSelector + ' input:eq(' + i + ')').val(inputValues[i]); + } + var actual = $(formSelector).valid(); + equal(actual, expected, $.format("Filled inputs of form '{0}' with {1} values ({2})", formSelector, inputValues.length, inputValues.toString())); + +} + +test('require_from_group', function() { + $("#productInfo").validate({ + rules: { + partnumber: {require_from_group: [2,".productInfo"]}, + description: {require_from_group: [2,".productInfo"]}, + discount: {require_from_group: [2,".productInfo"]} + } + }); + + fillFormWithValuesAndExpect('#productInfo', [], false); + fillFormWithValuesAndExpect('#productInfo', [123], false); + $('#productInfo input[type="checkbox"]').attr('checked', 'checked'); + fillFormWithValuesAndExpect('#productInfo', [123], true); + $('#productInfo input[type="checkbox"]').removeAttr('checked'); + fillFormWithValuesAndExpect('#productInfo', [123, 'widget'], true); + fillFormWithValuesAndExpect('#productInfo', [123, 'widget', 'red'], true); + fillFormWithValuesAndExpect('#productInfo', [123, 'widget', 'red'], true); +}); + +test('skip_or_fill_minimum', function() { + $("#productInfo").validate({ + rules: { + partnumber: {skip_or_fill_minimum: [2,".productInfo"]}, + description: {skip_or_fill_minimum: [2,".productInfo"]}, + color: {skip_or_fill_minimum: [2,".productInfo"]} + } + }); + + fillFormWithValuesAndExpect('#productInfo', [], true); + fillFormWithValuesAndExpect('#productInfo', [123], false); + fillFormWithValuesAndExpect('#productInfo', [123, 'widget'], true); + fillFormWithValuesAndExpect('#productInfo', [123, 'widget', 'red'], true); +}); + +test("zipcodeUS", function() { + var method = methodTest("zipcodeUS"); + ok( method( "12345" ), "Valid zip" ); + ok( method( "12345-2345" ), "Valid zip" ); + ok(!method( "1" ), "Invalid zip" ); + ok(!method( "1234" ), "Invalid zip" ); + ok(!method( "123-23" ), "Invalid zip" ); + ok(!method( "12345-43" ), "Invalid zip" ); +}); + +})(jQuery); diff --git a/wqflask/wqflask/static/new/packages/ValidationPlugin/test/qunit/qunit.css b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/qunit/qunit.css new file mode 100644 index 00000000..b948bae1 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/qunit/qunit.css @@ -0,0 +1,235 @@ +/** + * QUnit v1.5.0 - A JavaScript Unit Testing Framework + * + * http://docs.jquery.com/QUnit + * + * Copyright (c) 2012 John Resig, Jörn Zaefferer + * Dual licensed under the MIT (MIT-LICENSE.txt) + * or GPL (GPL-LICENSE.txt) licenses. + */ + +/** Font Family and Sizes */ + +#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult { + font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif; +} + +#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; } +#qunit-tests { font-size: smaller; } + + +/** Resets */ + +#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult { + margin: 0; + padding: 0; +} + + +/** Header */ + +#qunit-header { + padding: 0.5em 0 0.5em 1em; + + color: #8699a4; + background-color: #0d3349; + + font-size: 1.5em; + line-height: 1em; + font-weight: normal; + + border-radius: 15px 15px 0 0; + -moz-border-radius: 15px 15px 0 0; + -webkit-border-top-right-radius: 15px; + -webkit-border-top-left-radius: 15px; +} + +#qunit-header a { + text-decoration: none; + color: #c2ccd1; +} + +#qunit-header a:hover, +#qunit-header a:focus { + color: #fff; +} + +#qunit-header label { + display: inline-block; +} + +#qunit-banner { + height: 5px; +} + +#qunit-testrunner-toolbar { + padding: 0.5em 0 0.5em 2em; + color: #5E740B; + background-color: #eee; +} + +#qunit-userAgent { + padding: 0.5em 0 0.5em 2.5em; + background-color: #2b81af; + color: #fff; + text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px; +} + + +/** Tests: Pass/Fail */ + +#qunit-tests { + list-style-position: inside; +} + +#qunit-tests li { + padding: 0.4em 0.5em 0.4em 2.5em; + border-bottom: 1px solid #fff; + list-style-position: inside; +} + +#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running { + display: none; +} + +#qunit-tests li strong { + cursor: pointer; +} + +#qunit-tests li a { + padding: 0.5em; + color: #c2ccd1; + text-decoration: none; +} +#qunit-tests li a:hover, +#qunit-tests li a:focus { + color: #000; +} + +#qunit-tests ol { + margin-top: 0.5em; + padding: 0.5em; + + background-color: #fff; + + border-radius: 15px; + -moz-border-radius: 15px; + -webkit-border-radius: 15px; + + box-shadow: inset 0px 2px 13px #999; + -moz-box-shadow: inset 0px 2px 13px #999; + -webkit-box-shadow: inset 0px 2px 13px #999; +} + +#qunit-tests table { + border-collapse: collapse; + margin-top: .2em; +} + +#qunit-tests th { + text-align: right; + vertical-align: top; + padding: 0 .5em 0 0; +} + +#qunit-tests td { + vertical-align: top; +} + +#qunit-tests pre { + margin: 0; + white-space: pre-wrap; + word-wrap: break-word; +} + +#qunit-tests del { + background-color: #e0f2be; + color: #374e0c; + text-decoration: none; +} + +#qunit-tests ins { + background-color: #ffcaca; + color: #500; + text-decoration: none; +} + +/*** Test Counts */ + +#qunit-tests b.counts { color: black; } +#qunit-tests b.passed { color: #5E740B; } +#qunit-tests b.failed { color: #710909; } + +#qunit-tests li li { + margin: 0.5em; + padding: 0.4em 0.5em 0.4em 0.5em; + background-color: #fff; + border-bottom: none; + list-style-position: inside; +} + +/*** Passing Styles */ + +#qunit-tests li li.pass { + color: #5E740B; + background-color: #fff; + border-left: 26px solid #C6E746; +} + +#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; } +#qunit-tests .pass .test-name { color: #366097; } + +#qunit-tests .pass .test-actual, +#qunit-tests .pass .test-expected { color: #999999; } + +#qunit-banner.qunit-pass { background-color: #C6E746; } + +/*** Failing Styles */ + +#qunit-tests li li.fail { + color: #710909; + background-color: #fff; + border-left: 26px solid #EE5757; + white-space: pre; +} + +#qunit-tests > li:last-child { + border-radius: 0 0 15px 15px; + -moz-border-radius: 0 0 15px 15px; + -webkit-border-bottom-right-radius: 15px; + -webkit-border-bottom-left-radius: 15px; +} + +#qunit-tests .fail { color: #000000; background-color: #EE5757; } +#qunit-tests .fail .test-name, +#qunit-tests .fail .module-name { color: #000000; } + +#qunit-tests .fail .test-actual { color: #EE5757; } +#qunit-tests .fail .test-expected { color: green; } + +#qunit-banner.qunit-fail { background-color: #EE5757; } + + +/** Result */ + +#qunit-testresult { + padding: 0.5em 0.5em 0.5em 2.5em; + + color: #2b81af; + background-color: #D2E0E6; + + border-bottom: 1px solid white; +} +#qunit-testresult .module-name { + font-weight: bold; +} + +/** Fixture */ + +#qunit-fixture { + position: absolute; + top: -10000px; + left: -10000px; + width: 1000px; + height: 1000px; +} diff --git a/wqflask/wqflask/static/new/packages/ValidationPlugin/test/qunit/qunit.js b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/qunit/qunit.js new file mode 100644 index 00000000..66dd7215 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/qunit/qunit.js @@ -0,0 +1,1669 @@ +/** + * QUnit v1.5.0 - A JavaScript Unit Testing Framework + * + * http://docs.jquery.com/QUnit + * + * Copyright (c) 2012 John Resig, Jörn Zaefferer + * Dual licensed under the MIT (MIT-LICENSE.txt) + * or GPL (GPL-LICENSE.txt) licenses. + */ + +(function(window) { + +var defined = { + setTimeout: typeof window.setTimeout !== "undefined", + sessionStorage: (function() { + var x = "qunit-test-string"; + try { + sessionStorage.setItem(x, x); + sessionStorage.removeItem(x); + return true; + } catch(e) { + return false; + } + }()) +}; + +var testId = 0, + toString = Object.prototype.toString, + hasOwn = Object.prototype.hasOwnProperty; + +var Test = function(name, testName, expected, async, callback) { + this.name = name; + this.testName = testName; + this.expected = expected; + 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.className = "running"; + li.id = this.id = "test-output" + testId++; + tests.appendChild( li ); + } + }, + setup: function() { + if (this.module != config.previousModule) { + if ( config.previousModule ) { + runLoggingCallbacks('moduleDone', QUnit, { + name: config.previousModule, + failed: config.moduleStats.bad, + passed: config.moduleStats.all - config.moduleStats.bad, + total: config.moduleStats.all + } ); + } + config.previousModule = this.module; + config.moduleStats = { all: 0, bad: 0 }; + runLoggingCallbacks( 'moduleStart', QUnit, { + name: this.module + } ); + } else if (config.autorun) { + runLoggingCallbacks( 'moduleStart', QUnit, { + name: this.module + } ); + } + + config.current = this; + this.testEnvironment = extend({ + setup: function() {}, + teardown: function() {} + }, this.moduleTestEnvironment); + + runLoggingCallbacks( 'testStart', QUnit, { + name: this.testName, + module: this.module + }); + + // allow utility functions to access the current test environment + // TODO why?? + QUnit.current_testEnvironment = this.testEnvironment; + + if ( !config.pollution ) { + saveGlobal(); + } + if ( config.notrycatch ) { + this.testEnvironment.setup.call(this.testEnvironment); + return; + } + try { + this.testEnvironment.setup.call(this.testEnvironment); + } catch(e) { + QUnit.pushFailure( "Setup failed on " + this.testName + ": " + e.message, extractStacktrace( e, 1 ) ); + } + }, + run: function() { + config.current = this; + + var running = id("qunit-testresult"); + + if ( running ) { + running.innerHTML = "Running: <br/>" + this.name; + } + + if ( this.async ) { + QUnit.stop(); + } + + if ( config.notrycatch ) { + this.callback.call(this.testEnvironment); + return; + } + try { + this.callback.call(this.testEnvironment); + } catch(e) { + QUnit.pushFailure( "Died on test #" + (this.assertions.length + 1) + ": " + e.message, extractStacktrace( e, 1 ) ); + // else next test will carry the responsibility + saveGlobal(); + + // Restart the tests if they're blocking + if ( config.blocking ) { + QUnit.start(); + } + } + }, + teardown: function() { + config.current = this; + if ( config.notrycatch ) { + this.testEnvironment.teardown.call(this.testEnvironment); + return; + } else { + try { + this.testEnvironment.teardown.call(this.testEnvironment); + } catch(e) { + QUnit.pushFailure( "Teardown failed on " + this.testName + ": " + e.message, extractStacktrace( e, 1 ) ); + } + } + checkPollution(); + }, + finish: function() { + config.current = this; + if ( this.expected != null && this.expected != this.assertions.length ) { + QUnit.pushFailure( "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run" ); + } else if ( this.expected == null && !this.assertions.length ) { + QUnit.pushFailure( "Expected at least one assertion, but none were run - call expect(0) to accept zero assertions." ); + } + + var good = 0, bad = 0, + li, i, + tests = id("qunit-tests"); + + config.stats.all += this.assertions.length; + config.moduleStats.all += this.assertions.length; + + if ( tests ) { + var ol = document.createElement("ol"); + + for ( i = 0; i < this.assertions.length; i++ ) { + var assertion = this.assertions[i]; + + 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 + if ( QUnit.config.reorder && defined.sessionStorage ) { + if (bad) { + sessionStorage.setItem("qunit-test-" + this.module + "-" + this.testName, bad); + } else { + sessionStorage.removeItem("qunit-test-" + this.module + "-" + this.testName); + } + } + + 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>"; + + var a = document.createElement("a"); + a.innerHTML = "Rerun"; + a.href = QUnit.url({ filter: getText([b]).replace(/\([^)]+\)$/, "").replace(/(^\s*|\s*$)/g, "") }); + + addEvent(b, "click", function() { + var next = b.nextSibling.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 = QUnit.url({ filter: getText([target]).replace(/\([^)]+\)$/, "").replace(/(^\s*|\s*$)/g, "") }); + } + }); + + li = id(this.id); + li.className = bad ? "fail" : "pass"; + li.removeChild( li.firstChild ); + li.appendChild( b ); + li.appendChild( a ); + li.appendChild( ol ); + + } else { + for ( i = 0; i < this.assertions.length; i++ ) { + if ( !this.assertions[i].result ) { + bad++; + config.stats.bad++; + config.moduleStats.bad++; + } + } + } + + QUnit.reset(); + + runLoggingCallbacks( 'testDone', QUnit, { + name: this.testName, + module: this.module, + failed: bad, + passed: this.assertions.length - bad, + total: 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 = QUnit.config.reorder && defined.sessionStorage && +sessionStorage.getItem("qunit-test-" + this.module + "-" + this.testName); + if (bad) { + run(); + } else { + synchronize(run, true); + } + } + +}; + +var QUnit = { + + // call on start of module test to prepend name to all tests + module: function(name, testEnvironment) { + config.currentModule = name; + config.currentModuleTestEnviroment = testEnvironment; + }, + + asyncTest: function(testName, expected, callback) { + if ( arguments.length === 2 ) { + callback = expected; + expected = null; + } + + QUnit.test(testName, expected, callback, true); + }, + + test: function(testName, expected, callback, async) { + var name = '<span class="test-name">' + escapeInnerText(testName) + '</span>'; + + if ( arguments.length === 2 ) { + callback = expected; + expected = null; + } + + if ( config.currentModule ) { + name = '<span class="module-name">' + config.currentModule + "</span>: " + name; + } + + if ( !validTest(config.currentModule + ": " + testName) ) { + return; + } + + var test = new Test(name, testName, expected, async, callback); + test.module = config.currentModule; + test.moduleTestEnvironment = config.currentModuleTestEnviroment; + test.queue(); + }, + + // Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through. + expect: function(asserts) { + config.current.expected = asserts; + }, + + // Asserts true. + // @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" ); + ok: function(result, msg) { + if (!config.current) { + throw new Error("ok() assertion outside test context, was " + sourceFromStacktrace(2)); + } + result = !!result; + var details = { + result: result, + message: msg + }; + msg = escapeInnerText(msg || (result ? "okay" : "failed")); + if ( !result ) { + var source = sourceFromStacktrace(2); + if (source) { + details.source = source; + msg += '<table><tr class="test-source"><th>Source: </th><td><pre>' + escapeInnerText(source) + '</pre></td></tr></table>'; + } + } + runLoggingCallbacks( 'log', QUnit, details ); + config.current.assertions.push({ + result: result, + message: msg + }); + }, + + // Checks that the first two arguments are equal, with an optional message. Prints out both actual and expected values. + // @example equal( format("Received {0} bytes.", 2), "Received 2 bytes." ); + equal: function(actual, expected, message) { + QUnit.push(expected == actual, actual, expected, message); + }, + + notEqual: function(actual, expected, message) { + QUnit.push(expected != actual, actual, expected, message); + }, + + deepEqual: function(actual, expected, message) { + QUnit.push(QUnit.equiv(actual, expected), actual, expected, message); + }, + + notDeepEqual: function(actual, expected, message) { + QUnit.push(!QUnit.equiv(actual, expected), actual, expected, message); + }, + + strictEqual: function(actual, expected, message) { + QUnit.push(expected === actual, actual, expected, message); + }, + + notStrictEqual: function(actual, expected, message) { + QUnit.push(expected !== actual, actual, expected, message); + }, + + raises: function(block, expected, message) { + var actual, ok = false; + + if (typeof expected === 'string') { + message = expected; + expected = null; + } + + try { + block.call(config.current.testEnvironment); + } catch (e) { + actual = e; + } + + if (actual) { + // we don't want to validate thrown error + if (!expected) { + ok = true; + // expected is a regexp + } else if (QUnit.objectType(expected) === "regexp") { + ok = expected.test(actual); + // expected is a constructor + } else if (actual instanceof expected) { + ok = true; + // expected is a validation function which returns true is validation passed + } else if (expected.call({}, actual) === true) { + ok = true; + } + } + + QUnit.ok(ok, message); + }, + + start: function(count) { + config.semaphore -= count || 1; + if (config.semaphore > 0) { + // don't start until equal number of stop-calls + return; + } + if (config.semaphore < 0) { + // ignore if start is called more often then stop + config.semaphore = 0; + } + // A slight delay, to avoid any current callbacks + if ( defined.setTimeout ) { + window.setTimeout(function() { + if (config.semaphore > 0) { + return; + } + if ( config.timeout ) { + clearTimeout(config.timeout); + } + + config.blocking = false; + process(true); + }, 13); + } else { + config.blocking = false; + process(true); + } + }, + + stop: function(count) { + config.semaphore += count || 1; + config.blocking = true; + + if ( config.testTimeout && defined.setTimeout ) { + clearTimeout(config.timeout); + config.timeout = window.setTimeout(function() { + QUnit.ok( false, "Test timed out" ); + config.semaphore = 1; + QUnit.start(); + }, config.testTimeout); + } + } +}; + +//We want access to the constructor's prototype +(function() { + function F(){} + F.prototype = QUnit; + QUnit = new F(); + //Make F QUnit's constructor so that we can add to the prototype later + QUnit.constructor = F; +}()); + +// deprecated; still export them to window to provide clear error messages +// next step: remove entirely +QUnit.equals = function() { + QUnit.push(false, false, false, "QUnit.equals has been deprecated since 2009 (e88049a0), use QUnit.equal instead"); +}; +QUnit.same = function() { + QUnit.push(false, false, false, "QUnit.same has been deprecated since 2009 (e88049a0), use QUnit.deepEqual instead"); +}; + +// Maintain internal state +var config = { + // The queue of tests to run + queue: [], + + // block until document ready + blocking: true, + + // when enabled, show only failing tests + // gets persisted through sessionStorage and can be changed in UI via checkbox + hidepassed: false, + + // by default, run previously failed tests first + // very useful in combination with "Hide passed tests" checked + reorder: true, + + // by default, modify document.title when suite is done + altertitle: true, + + urlConfig: ['noglobals', 'notrycatch'], + + //logging callback queues + begin: [], + done: [], + log: [], + testStart: [], + testDone: [], + moduleStart: [], + moduleDone: [] +}; + +// Load paramaters +(function() { + var location = window.location || { search: "", protocol: "file:" }, + params = location.search.slice( 1 ).split( "&" ), + length = params.length, + urlParams = {}, + current; + + if ( params[ 0 ] ) { + for ( var i = 0; i < length; i++ ) { + current = params[ i ].split( "=" ); + current[ 0 ] = decodeURIComponent( current[ 0 ] ); + // allow just a key to turn on a flag, e.g., test.html?noglobals + current[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true; + urlParams[ current[ 0 ] ] = current[ 1 ]; + } + } + + QUnit.urlParams = urlParams; + config.filter = urlParams.filter; + + // Figure out if we're running the tests from a server or not + QUnit.isLocal = location.protocol === 'file:'; +}()); + +// Expose the API as global variables, unless an 'exports' +// object exists, in that case we assume we're in CommonJS - export everything at the end +if ( typeof exports === "undefined" || typeof require === "undefined" ) { + extend(window, QUnit); + window.QUnit = QUnit; +} + +// define these after exposing globals to keep them in these QUnit namespace only +extend(QUnit, { + config: config, + + // Initialize the configuration options + init: function() { + extend(config, { + stats: { all: 0, bad: 0 }, + moduleStats: { all: 0, bad: 0 }, + started: +new Date(), + updateRate: 1000, + blocking: false, + autostart: true, + autorun: false, + filter: "", + queue: [], + semaphore: 0 + }); + + var qunit = id( "qunit" ); + if ( qunit ) { + qunit.innerHTML = + '<h1 id="qunit-header">' + escapeInnerText( document.title ) + '</h1>' + + '<h2 id="qunit-banner"></h2>' + + '<div id="qunit-testrunner-toolbar"></div>' + + '<h2 id="qunit-userAgent"></h2>' + + '<ol id="qunit-tests"></ol>'; + } + + var tests = id( "qunit-tests" ), + banner = id( "qunit-banner" ), + result = id( "qunit-testresult" ); + + if ( tests ) { + tests.innerHTML = ""; + } + + if ( banner ) { + banner.className = ""; + } + + if ( result ) { + result.parentNode.removeChild( result ); + } + + if ( tests ) { + result = document.createElement( "p" ); + result.id = "qunit-testresult"; + result.className = "result"; + tests.parentNode.insertBefore( result, tests ); + result.innerHTML = 'Running...<br/> '; + } + }, + + // Resets the test setup. Useful for tests that modify the DOM. + // If jQuery is available, uses jQuery's html(), otherwise just innerHTML. + reset: function() { + if ( window.jQuery ) { + jQuery( "#qunit-fixture" ).html( config.fixture ); + } else { + var main = id( 'qunit-fixture' ); + if ( main ) { + main.innerHTML = config.fixture; + } + } + }, + + // Trigger an event on an element. + // @example triggerEvent( document.body, "click" ); + triggerEvent: function( elem, type, event ) { + if ( document.createEvent ) { + event = document.createEvent("MouseEvents"); + event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView, + 0, 0, 0, 0, 0, false, false, false, false, 0, null); + elem.dispatchEvent( event ); + + } else if ( elem.fireEvent ) { + elem.fireEvent("on"+type); + } + }, + + // Safe object type checking + is: function( type, obj ) { + return QUnit.objectType( obj ) == type; + }, + + objectType: function( obj ) { + if (typeof obj === "undefined") { + return "undefined"; + + // consider: typeof null === object + } + if (obj === null) { + return "null"; + } + + var type = toString.call( obj ).match(/^\[object\s(.*)\]$/)[1] || ''; + + switch (type) { + case 'Number': + if (isNaN(obj)) { + return "nan"; + } + return "number"; + case 'String': + case 'Boolean': + case 'Array': + case 'Date': + case 'RegExp': + case 'Function': + return type.toLowerCase(); + } + if (typeof obj === "object") { + return "object"; + } + return undefined; + }, + + push: function(result, actual, expected, message) { + if (!config.current) { + throw new Error("assertion outside test context, was " + sourceFromStacktrace()); + } + var details = { + result: result, + message: message, + actual: actual, + expected: expected + }; + + message = escapeInnerText(message) || (result ? "okay" : "failed"); + message = '<span class="test-message">' + message + "</span>"; + var output = message; + if (!result) { + expected = escapeInnerText(QUnit.jsDump.parse(expected)); + actual = escapeInnerText(QUnit.jsDump.parse(actual)); + output += '<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>'; + } + var source = sourceFromStacktrace(); + if (source) { + details.source = source; + output += '<tr class="test-source"><th>Source: </th><td><pre>' + escapeInnerText(source) + '</pre></td></tr>'; + } + output += "</table>"; + } + + runLoggingCallbacks( 'log', QUnit, details ); + + config.current.assertions.push({ + result: !!result, + message: output + }); + }, + + pushFailure: function(message, source) { + var details = { + result: false, + message: message + }; + var output = escapeInnerText(message); + if (source) { + details.source = source; + output += '<table><tr class="test-source"><th>Source: </th><td><pre>' + escapeInnerText(source) + '</pre></td></tr></table>'; + } + runLoggingCallbacks( 'log', QUnit, details ); + config.current.assertions.push({ + result: false, + message: output + }); + }, + + url: function( params ) { + params = extend( extend( {}, QUnit.urlParams ), params ); + var querystring = "?", + key; + for ( key in params ) { + if ( !hasOwn.call( params, key ) ) { + continue; + } + querystring += encodeURIComponent( key ) + "=" + + encodeURIComponent( params[ key ] ) + "&"; + } + return window.location.pathname + querystring.slice( 0, -1 ); + }, + + extend: extend, + id: id, + addEvent: addEvent +}); + +//QUnit.constructor is set to the empty F() above so that we can add to it's prototype later +//Doing this allows us to tell if the following methods have been overwritten on the actual +//QUnit object, which is a deprecated way of using the callbacks. +extend(QUnit.constructor.prototype, { + // Logging callbacks; all receive a single argument with the listed properties + // run test/logs.html for any related changes + begin: registerLoggingCallback('begin'), + // done: { failed, passed, total, runtime } + done: registerLoggingCallback('done'), + // log: { result, actual, expected, message } + log: registerLoggingCallback('log'), + // testStart: { name } + testStart: registerLoggingCallback('testStart'), + // testDone: { name, failed, passed, total } + testDone: registerLoggingCallback('testDone'), + // moduleStart: { name } + moduleStart: registerLoggingCallback('moduleStart'), + // moduleDone: { name, failed, passed, total } + moduleDone: registerLoggingCallback('moduleDone') +}); + +if ( typeof document === "undefined" || document.readyState === "complete" ) { + config.autorun = true; +} + +QUnit.load = function() { + runLoggingCallbacks( 'begin', QUnit, {} ); + + // Initialize the config, saving the execution queue + var oldconfig = extend({}, config); + QUnit.init(); + extend(config, oldconfig); + + config.blocking = false; + + var urlConfigHtml = '', len = config.urlConfig.length; + for ( var i = 0, val; i < len; i++ ) { + val = config.urlConfig[i]; + config[val] = QUnit.urlParams[val]; + urlConfigHtml += '<label><input name="' + val + '" type="checkbox"' + ( config[val] ? ' checked="checked"' : '' ) + '>' + val + '</label>'; + } + + var userAgent = id("qunit-userAgent"); + if ( userAgent ) { + userAgent.innerHTML = navigator.userAgent; + } + var banner = id("qunit-header"); + if ( banner ) { + banner.innerHTML = '<a href="' + QUnit.url({ filter: undefined }) + '"> ' + banner.innerHTML + '</a> ' + urlConfigHtml; + addEvent( banner, "change", function( event ) { + var params = {}; + params[ event.target.name ] = event.target.checked ? true : undefined; + window.location = QUnit.url( params ); + }); + } + + var toolbar = id("qunit-testrunner-toolbar"); + if ( toolbar ) { + var filter = document.createElement("input"); + filter.type = "checkbox"; + filter.id = "qunit-filter-pass"; + addEvent( filter, "click", function() { + var ol = document.getElementById("qunit-tests"); + if ( filter.checked ) { + ol.className = ol.className + " hidepass"; + } else { + var tmp = " " + ol.className.replace( /[\n\t\r]/g, " " ) + " "; + ol.className = tmp.replace(/ hidepass /, " "); + } + if ( defined.sessionStorage ) { + if (filter.checked) { + sessionStorage.setItem("qunit-filter-passed-tests", "true"); + } else { + sessionStorage.removeItem("qunit-filter-passed-tests"); + } + } + }); + if ( config.hidepassed || defined.sessionStorage && sessionStorage.getItem("qunit-filter-passed-tests") ) { + filter.checked = true; + var ol = document.getElementById("qunit-tests"); + ol.className = ol.className + " hidepass"; + } + toolbar.appendChild( filter ); + + var label = document.createElement("label"); + label.setAttribute("for", "qunit-filter-pass"); + label.innerHTML = "Hide passed tests"; + toolbar.appendChild( label ); + } + + var main = id('qunit-fixture'); + if ( main ) { + config.fixture = main.innerHTML; + } + + if (config.autostart) { + QUnit.start(); + } +}; + +addEvent(window, "load", QUnit.load); + +// addEvent(window, "error") gives us a useless event object +window.onerror = function( message, file, line ) { + if ( QUnit.config.current ) { + QUnit.pushFailure( message, file + ":" + line ); + } else { + QUnit.test( "global failure", function() { + QUnit.pushFailure( message, file + ":" + line ); + }); + } +}; + +function done() { + config.autorun = true; + + // Log the last module results + if ( config.currentModule ) { + runLoggingCallbacks( 'moduleDone', QUnit, { + name: config.currentModule, + failed: config.moduleStats.bad, + passed: config.moduleStats.all - config.moduleStats.bad, + total: config.moduleStats.all + } ); + } + + var banner = id("qunit-banner"), + tests = id("qunit-tests"), + runtime = +new Date() - config.started, + passed = config.stats.all - config.stats.bad, + html = [ + 'Tests completed in ', + runtime, + ' milliseconds.<br/>', + '<span class="passed">', + passed, + '</span> tests of <span class="total">', + config.stats.all, + '</span> passed, <span class="failed">', + config.stats.bad, + '</span> failed.' + ].join(''); + + if ( banner ) { + banner.className = (config.stats.bad ? "qunit-fail" : "qunit-pass"); + } + + if ( tests ) { + id( "qunit-testresult" ).innerHTML = html; + } + + if ( config.altertitle && typeof document !== "undefined" && document.title ) { + // show ✖ for good, ✔ for bad suite result in title + // use escape sequences in case file gets loaded with non-utf-8-charset + document.title = [ + (config.stats.bad ? "\u2716" : "\u2714"), + document.title.replace(/^[\u2714\u2716] /i, "") + ].join(" "); + } + + // clear own sessionStorage items if all tests passed + if ( config.reorder && defined.sessionStorage && config.stats.bad === 0 ) { + var key; + for ( var i = 0; i < sessionStorage.length; i++ ) { + key = sessionStorage.key( i++ ); + if ( key.indexOf("qunit-test-") === 0 ) { + sessionStorage.removeItem( key ); + } + } + } + + runLoggingCallbacks( 'done', QUnit, { + failed: config.stats.bad, + passed: passed, + total: config.stats.all, + runtime: runtime + } ); +} + +function validTest( name ) { + var filter = config.filter, + run = false; + + if ( !filter ) { + return true; + } + + var not = filter.charAt( 0 ) === "!"; + if ( not ) { + filter = filter.slice( 1 ); + } + + if ( name.indexOf( filter ) !== -1 ) { + return !not; + } + + if ( not ) { + run = true; + } + + return run; +} + +// so far supports only Firefox, Chrome and Opera (buggy), Safari (for real exceptions) +// Later Safari and IE10 are supposed to support error.stack as well +// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack +function extractStacktrace( e, offset ) { + offset = offset || 3; + if (e.stacktrace) { + // Opera + return e.stacktrace.split("\n")[offset + 3]; + } else if (e.stack) { + // Firefox, Chrome + var stack = e.stack.split("\n"); + if (/^error$/i.test(stack[0])) { + stack.shift(); + } + return stack[offset]; + } else if (e.sourceURL) { + // Safari, PhantomJS + // hopefully one day Safari provides actual stacktraces + // exclude useless self-reference for generated Error objects + if ( /qunit.js$/.test( e.sourceURL ) ) { + return; + } + // for actual exceptions, this is useful + return e.sourceURL + ":" + e.line; + } +} +function sourceFromStacktrace(offset) { + try { + throw new Error(); + } catch ( e ) { + return extractStacktrace( e, offset ); + } +} + +function escapeInnerText(s) { + if (!s) { + return ""; + } + s = s + ""; + return s.replace(/[\&<>]/g, function(s) { + switch(s) { + case "&": return "&"; + case "<": return "<"; + case ">": return ">"; + default: return s; + } + }); +} + +function synchronize( callback, last ) { + config.queue.push( callback ); + + if ( config.autorun && !config.blocking ) { + process(last); + } +} + +function process( last ) { + function next() { + process( last ); + } + var start = new Date().getTime(); + config.depth = config.depth ? config.depth + 1 : 1; + + while ( config.queue.length && !config.blocking ) { + if ( !defined.setTimeout || config.updateRate <= 0 || ( ( new Date().getTime() - start ) < config.updateRate ) ) { + config.queue.shift()(); + } else { + window.setTimeout( next, 13 ); + break; + } + } + config.depth--; + if ( last && !config.blocking && !config.queue.length && config.depth === 0 ) { + done(); + } +} + +function saveGlobal() { + config.pollution = []; + + if ( config.noglobals ) { + for ( var key in window ) { + if ( !hasOwn.call( window, key ) ) { + continue; + } + config.pollution.push( key ); + } + } +} + +function checkPollution( name ) { + var old = config.pollution; + saveGlobal(); + + var newGlobals = diff( config.pollution, old ); + if ( newGlobals.length > 0 ) { + QUnit.pushFailure( "Introduced global variable(s): " + newGlobals.join(", ") ); + } + + var deletedGlobals = diff( old, config.pollution ); + if ( deletedGlobals.length > 0 ) { + QUnit.pushFailure( "Deleted global variable(s): " + deletedGlobals.join(", ") ); + } +} + +// returns a new Array with the elements that are in a but not in b +function diff( a, b ) { + var result = a.slice(); + for ( var i = 0; i < result.length; i++ ) { + for ( var j = 0; j < b.length; j++ ) { + if ( result[i] === b[j] ) { + result.splice(i, 1); + i--; + break; + } + } + } + return result; +} + +function extend(a, b) { + for ( var prop in b ) { + if ( b[prop] === undefined ) { + delete a[prop]; + + // Avoid "Member not found" error in IE8 caused by setting window.constructor + } else if ( prop !== "constructor" || a !== window ) { + a[prop] = b[prop]; + } + } + + return a; +} + +function addEvent(elem, type, fn) { + if ( elem.addEventListener ) { + elem.addEventListener( type, fn, false ); + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, fn ); + } else { + fn(); + } +} + +function id(name) { + return !!(typeof document !== "undefined" && document && document.getElementById) && + document.getElementById( name ); +} + +function registerLoggingCallback(key){ + return function(callback){ + config[key].push( callback ); + }; +} + +// Supports deprecated method of completely overwriting logging callbacks +function runLoggingCallbacks(key, scope, args) { + //debugger; + var callbacks; + if ( QUnit.hasOwnProperty(key) ) { + QUnit[key].call(scope, args); + } else { + callbacks = config[key]; + for( var i = 0; i < callbacks.length; i++ ) { + callbacks[i].call( scope, args ); + } + } +} + +// Test for equality any JavaScript type. +// Author: Philippe Rathé <prathe@gmail.com> +QUnit.equiv = (function() { + + var innerEquiv; // the real equiv function + var callers = []; // stack to decide between skip/abort functions + var parents = []; // stack to avoiding loops from circular referencing + + // Call the o related callback with the given arguments. + function bindCallbacks(o, callbacks, args) { + var prop = QUnit.objectType(o); + if (prop) { + if (QUnit.objectType(callbacks[prop]) === "function") { + return callbacks[prop].apply(callbacks, args); + } else { + return callbacks[prop]; // or undefined + } + } + } + + var getProto = Object.getPrototypeOf || function (obj) { + return obj.__proto__; + }; + + var callbacks = (function () { + + // for string, boolean, number and null + function useStrictEquality(b, a) { + if (b instanceof a.constructor || a instanceof b.constructor) { + // to catch short annotaion VS 'new' annotation of a + // declaration + // e.g. var i = 1; + // var j = new Number(1); + return a == b; + } else { + return a === b; + } + } + + return { + "string" : useStrictEquality, + "boolean" : useStrictEquality, + "number" : useStrictEquality, + "null" : useStrictEquality, + "undefined" : useStrictEquality, + + "nan" : function(b) { + return isNaN(b); + }, + + "date" : function(b, a) { + return QUnit.objectType(b) === "date" && a.valueOf() === b.valueOf(); + }, + + "regexp" : function(b, a) { + return QUnit.objectType(b) === "regexp" && + // the regex itself + a.source === b.source && + // and its modifers + a.global === b.global && + // (gmi) ... + a.ignoreCase === b.ignoreCase && + a.multiline === b.multiline; + }, + + // - skip when the property is a method of an instance (OOP) + // - abort otherwise, + // initial === would have catch identical references anyway + "function" : function() { + var caller = callers[callers.length - 1]; + return caller !== Object && typeof caller !== "undefined"; + }, + + "array" : function(b, a) { + var i, j, loop; + var len; + + // b could be an object literal here + if (QUnit.objectType(b) !== "array") { + return false; + } + + len = a.length; + if (len !== b.length) { // safe and faster + return false; + } + + // track reference to avoid circular references + parents.push(a); + for (i = 0; i < len; i++) { + loop = false; + for (j = 0; j < parents.length; j++) { + if (parents[j] === a[i]) { + loop = true;// dont rewalk array + } + } + if (!loop && !innerEquiv(a[i], b[i])) { + parents.pop(); + return false; + } + } + parents.pop(); + return true; + }, + + "object" : function(b, a) { + var i, j, loop; + var eq = true; // unless we can proove it + var aProperties = [], bProperties = []; // collection of + // strings + + // comparing constructors is more strict than using + // instanceof + if (a.constructor !== b.constructor) { + // Allow objects with no prototype to be equivalent to + // objects with Object as their constructor. + if (!((getProto(a) === null && getProto(b) === Object.prototype) || + (getProto(b) === null && getProto(a) === Object.prototype))) + { + return false; + } + } + + // stack constructor before traversing properties + callers.push(a.constructor); + // track reference to avoid circular references + parents.push(a); + + for (i in a) { // be strict: don't ensures hasOwnProperty + // and go deep + loop = false; + for (j = 0; j < parents.length; j++) { + if (parents[j] === a[i]) { + // don't go down the same path twice + loop = true; + } + } + aProperties.push(i); // collect a's properties + + if (!loop && !innerEquiv(a[i], b[i])) { + eq = false; + break; + } + } + + callers.pop(); // unstack, we are done + parents.pop(); + + for (i in b) { + bProperties.push(i); // collect b's properties + } + + // Ensures identical properties name + return eq && innerEquiv(aProperties.sort(), bProperties.sort()); + } + }; + }()); + + innerEquiv = function() { // can take multiple arguments + var args = Array.prototype.slice.apply(arguments); + if (args.length < 2) { + return true; // end transition + } + + return (function(a, b) { + if (a === b) { + return true; // catch the most you can + } else if (a === null || b === null || typeof a === "undefined" || + typeof b === "undefined" || + QUnit.objectType(a) !== QUnit.objectType(b)) { + return false; // don't lose time with error prone cases + } else { + return bindCallbacks(a, callbacks, [ b, a ]); + } + + // apply transition with (1..n) arguments + }(args[0], args[1]) && arguments.callee.apply(this, args.splice(1, args.length - 1))); + }; + + return innerEquiv; + +}()); + +/** + * jsDump Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com | + * http://flesler.blogspot.com Licensed under BSD + * (http://www.opensource.org/licenses/bsd-license.php) Date: 5/15/2008 + * + * @projectDescription Advanced and extensible data dumping for Javascript. + * @version 1.0.0 + * @author Ariel Flesler + * @link {http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html} + */ +QUnit.jsDump = (function() { + function quote( str ) { + return '"' + str.toString().replace(/"/g, '\\"') + '"'; + } + function literal( o ) { + return o + ''; + } + function join( pre, arr, post ) { + var s = jsDump.separator(), + base = jsDump.indent(), + inner = jsDump.indent(1); + if ( arr.join ) { + arr = arr.join( ',' + s + inner ); + } + if ( !arr ) { + return pre + post; + } + return [ pre, inner + arr, base + post ].join(s); + } + function array( arr, stack ) { + var i = arr.length, ret = new Array(i); + this.up(); + while ( i-- ) { + ret[i] = this.parse( arr[i] , undefined , stack); + } + this.down(); + return join( '[', ret, ']' ); + } + + var reName = /^function (\w+)/; + + var jsDump = { + parse: function( obj, type, stack ) { //type is used mostly internally, you can fix a (custom)type in advance + stack = stack || [ ]; + var parser = this.parsers[ type || this.typeOf(obj) ]; + type = typeof parser; + var inStack = inArray(obj, stack); + if (inStack != -1) { + return 'recursion('+(inStack - stack.length)+')'; + } + //else + if (type == 'function') { + stack.push(obj); + var res = parser.call( this, obj, stack ); + stack.pop(); + return res; + } + // else + return (type == 'string') ? parser : this.parsers.error; + }, + typeOf: function( obj ) { + var type; + if ( obj === null ) { + type = "null"; + } else if (typeof obj === "undefined") { + type = "undefined"; + } else if (QUnit.is("RegExp", obj)) { + type = "regexp"; + } else if (QUnit.is("Date", obj)) { + type = "date"; + } else if (QUnit.is("Function", obj)) { + type = "function"; + } else if (typeof obj.setInterval !== undefined && typeof obj.document !== "undefined" && typeof obj.nodeType === "undefined") { + type = "window"; + } else if (obj.nodeType === 9) { + type = "document"; + } else if (obj.nodeType) { + type = "node"; + } else if ( + // native arrays + toString.call( obj ) === "[object Array]" || + // NodeList objects + ( typeof obj.length === "number" && typeof obj.item !== "undefined" && ( obj.length ? obj.item(0) === obj[0] : ( obj.item( 0 ) === null && typeof obj[0] === "undefined" ) ) ) + ) { + type = "array"; + } else { + type = typeof obj; + } + return type; + }, + separator: function() { + return this.multiline ? this.HTML ? '<br />' : '\n' : this.HTML ? ' ' : ' '; + }, + indent: function( extra ) {// extra can be a number, shortcut for increasing-calling-decreasing + if ( !this.multiline ) { + return ''; + } + var chr = this.indentChar; + if ( this.HTML ) { + chr = chr.replace(/\t/g,' ').replace(/ /g,' '); + } + return new Array( this._depth_ + (extra||0) ).join(chr); + }, + up: function( a ) { + this._depth_ += a || 1; + }, + down: function( a ) { + this._depth_ -= a || 1; + }, + setParser: function( name, parser ) { + this.parsers[name] = parser; + }, + // The next 3 are exposed so you can use them + quote: quote, + literal: literal, + join: join, + // + _depth_: 1, + // This is the list of parsers, to modify them, use jsDump.setParser + parsers: { + window: '[Window]', + document: '[Document]', + error: '[ERROR]', //when no parser is found, shouldn't happen + unknown: '[Unknown]', + 'null': 'null', + 'undefined': 'undefined', + 'function': function( fn ) { + var ret = 'function', + name = 'name' in fn ? fn.name : (reName.exec(fn)||[])[1];//functions never have name in IE + if ( name ) { + ret += ' ' + name; + } + ret += '('; + + ret = [ ret, QUnit.jsDump.parse( fn, 'functionArgs' ), '){'].join(''); + return join( ret, QUnit.jsDump.parse(fn,'functionCode'), '}' ); + }, + array: array, + nodelist: array, + 'arguments': array, + object: function( map, stack ) { + var ret = [ ], keys, key, val, i; + QUnit.jsDump.up(); + if (Object.keys) { + keys = Object.keys( map ); + } else { + keys = []; + for (key in map) { keys.push( key ); } + } + keys.sort(); + for (i = 0; i < keys.length; i++) { + key = keys[ i ]; + val = map[ key ]; + ret.push( QUnit.jsDump.parse( key, 'key' ) + ': ' + QUnit.jsDump.parse( val, undefined, stack ) ); + } + QUnit.jsDump.down(); + return join( '{', ret, '}' ); + }, + node: function( node ) { + var open = QUnit.jsDump.HTML ? '<' : '<', + close = QUnit.jsDump.HTML ? '>' : '>'; + + var tag = node.nodeName.toLowerCase(), + ret = open + tag; + + for ( var a in QUnit.jsDump.DOMAttrs ) { + var val = node[QUnit.jsDump.DOMAttrs[a]]; + if ( val ) { + ret += ' ' + a + '=' + QUnit.jsDump.parse( val, 'attribute' ); + } + } + return ret + close + open + '/' + tag + close; + }, + functionArgs: function( fn ) {//function calls it internally, it's the arguments part of the function + var l = fn.length; + if ( !l ) { + return ''; + } + + var args = new Array(l); + while ( l-- ) { + args[l] = String.fromCharCode(97+l);//97 is 'a' + } + return ' ' + args.join(', ') + ' '; + }, + key: quote, //object calls it internally, the key part of an item in a map + functionCode: '[code]', //function calls it internally, it's the content of the function + attribute: quote, //node calls it internally, it's an html attribute value + string: quote, + date: quote, + regexp: literal, //regex + number: literal, + 'boolean': literal + }, + DOMAttrs:{//attributes to dump from nodes, name=>realName + id:'id', + name:'name', + 'class':'className' + }, + HTML:false,//if true, entities are escaped ( <, >, \t, space and \n ) + indentChar:' ',//indentation unit + multiline:true //if true, items in a collection, are separated by a \n, else just a space. + }; + + return jsDump; +}()); + +// from Sizzle.js +function getText( elems ) { + var ret = "", elem; + + for ( var i = 0; elems[i]; i++ ) { + elem = elems[i]; + + // Get the text from text nodes and CDATA nodes + if ( elem.nodeType === 3 || elem.nodeType === 4 ) { + ret += elem.nodeValue; + + // Traverse everything else, except comment nodes + } else if ( elem.nodeType !== 8 ) { + ret += getText( elem.childNodes ); + } + } + + return ret; +} + +//from jquery.js +function inArray( elem, array ) { + if ( array.indexOf ) { + return array.indexOf( elem ); + } + + for ( var i = 0, length = array.length; i < length; i++ ) { + if ( array[ i ] === elem ) { + return i; + } + } + + return -1; +} + +/* + * Javascript Diff Algorithm + * By John Resig (http://ejohn.org/) + * Modified by Chu Alan "sprite" + * + * Released under the MIT license. + * + * More Info: + * http://ejohn.org/projects/javascript-diff-algorithm/ + * + * Usage: QUnit.diff(expected, actual) + * + * QUnit.diff("the quick brown fox jumped over", "the quick fox jumps over") == "the quick <del>brown </del> fox <del>jumped </del><ins>jumps </ins> over" + */ +QUnit.diff = (function() { + function diff(o, n) { + var ns = {}; + var os = {}; + var i; + + for (i = 0; i < n.length; i++) { + if (ns[n[i]] == null) { + ns[n[i]] = { + rows: [], + o: null + }; + } + ns[n[i]].rows.push(i); + } + + for (i = 0; i < o.length; i++) { + if (os[o[i]] == null) { + os[o[i]] = { + rows: [], + n: null + }; + } + os[o[i]].rows.push(i); + } + + for (i in ns) { + if ( !hasOwn.call( ns, i ) ) { + continue; + } + if (ns[i].rows.length == 1 && typeof(os[i]) != "undefined" && os[i].rows.length == 1) { + n[ns[i].rows[0]] = { + text: n[ns[i].rows[0]], + row: os[i].rows[0] + }; + o[os[i].rows[0]] = { + text: o[os[i].rows[0]], + row: ns[i].rows[0] + }; + } + } + + for (i = 0; i < n.length - 1; i++) { + if (n[i].text != null && n[i + 1].text == null && n[i].row + 1 < o.length && o[n[i].row + 1].text == null && + n[i + 1] == o[n[i].row + 1]) { + n[i + 1] = { + text: n[i + 1], + row: n[i].row + 1 + }; + o[n[i].row + 1] = { + text: o[n[i].row + 1], + row: i + 1 + }; + } + } + + for (i = n.length - 1; i > 0; i--) { + if (n[i].text != null && n[i - 1].text == null && n[i].row > 0 && o[n[i].row - 1].text == null && + n[i - 1] == o[n[i].row - 1]) { + n[i - 1] = { + text: n[i - 1], + row: n[i].row - 1 + }; + o[n[i].row - 1] = { + text: o[n[i].row - 1], + row: i - 1 + }; + } + } + + return { + o: o, + n: n + }; + } + + return function(o, n) { + o = o.replace(/\s+$/, ''); + n = n.replace(/\s+$/, ''); + var out = diff(o === "" ? [] : o.split(/\s+/), n === "" ? [] : n.split(/\s+/)); + + var str = ""; + var i; + + var oSpace = o.match(/\s+/g); + if (oSpace == null) { + oSpace = [" "]; + } + else { + oSpace.push(" "); + } + var nSpace = n.match(/\s+/g); + if (nSpace == null) { + nSpace = [" "]; + } + else { + nSpace.push(" "); + } + + if (out.n.length === 0) { + for (i = 0; i < out.o.length; i++) { + str += '<del>' + out.o[i] + oSpace[i] + "</del>"; + } + } + else { + if (out.n[0].text == null) { + for (n = 0; n < out.o.length && out.o[n].text == null; n++) { + str += '<del>' + out.o[n] + oSpace[n] + "</del>"; + } + } + + for (i = 0; i < out.n.length; i++) { + if (out.n[i].text == null) { + str += '<ins>' + out.n[i] + nSpace[i] + "</ins>"; + } + else { + var pre = ""; + + for (n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++) { + pre += '<del>' + out.o[n] + oSpace[n] + "</del>"; + } + str += " " + out.n[i].text + nSpace[i] + pre; + } + } + } + + return str; + }; +}()); + +// for CommonJS enviroments, export everything +if ( typeof exports !== "undefined" || typeof require !== "undefined" ) { + extend(exports, QUnit); +} + +// get at whatever the global object is, like window in browsers +}( (function() {return this;}.call()) )); diff --git a/wqflask/wqflask/static/new/packages/ValidationPlugin/test/rules.js b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/rules.js new file mode 100644 index 00000000..0b2f6d44 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/rules.js @@ -0,0 +1,273 @@ +module("rules"); + +test("rules() - internal - input", function() { + var element = $('#firstname'); + var v = $('#testForm1').validate(); + deepEqual( element.rules(), { required: true, minlength: 2 } ); +}); + +test("rules(), ignore method:false", function() { + var element = $('#firstnamec'); + var v = $('#testForm1clean').validate({ + rules: { + firstname: { required: false, minlength: 2 } + } + }); + deepEqual( element.rules(), { minlength: 2 } ); +}); + +test("rules() HTML5 required (no value)", function() { + var element = $('#testForm11text1'); + var v = $('#testForm11').validate(); + deepEqual( element.rules(), { required: true } ); +}); + +test("rules() - internal - select", function() { + var element = $('#meal'); + var v = $('#testForm3').validate(); + deepEqual( element.rules(), {required: true} ); +}); + +test("rules() - external", function() { + var element = $('#text1'); + var v = $('#form').validate({ + rules: { + action: {date: true, min: 5} + } + }); + deepEqual( element.rules(), {date: true, min: 5} ); +}); + +test("rules() - external - complete form", function() { + expect(1); + + var methods = $.extend({}, $.validator.methods); + var messages = $.extend({}, $.validator.messages); + + $.validator.addMethod("verifyTest", function() { + ok( true, "method executed" ); + return true; + }); + var v = $('#form').validate({ + rules: { + action: {verifyTest: true} + } + }); + v.form(); + + $.validator.methods = methods; + $.validator.messages = messages; +}); + +test("rules() - internal - input", function() { + var element = $('#form8input'); + var v = $('#testForm8').validate(); + deepEqual( element.rules(), {required: true, number: true, rangelength: [2, 8]}); +}); + +test("rules(), merge min/max to range, minlength/maxlength to rangelength", function() { + jQuery.validator.autoCreateRanges = true; + var v = $("#testForm1clean").validate({ + rules: { + firstname: { + min: 5, + max: 12 + }, + lastname: { + minlength: 2, + maxlength: 8 + } + } + }); + deepEqual( $("#firstnamec").rules(), {range: [5, 12]}); + + deepEqual( $("#lastnamec").rules(), {rangelength: [2, 8]} ); + jQuery.validator.autoCreateRanges = false; +}); + +test("rules(), gurantee that required is at front", function() { + $("#testForm1").validate(); + var v = $("#v2").validate(); + $("#subformRequired").validate(); + function flatRules(element) { + var result = []; + jQuery.each($(element).rules(), function(key, value) { result.push(key) }); + return result.join(" "); + } + equal( "required minlength", flatRules("#firstname") ); + equal( "required maxlength minlength", flatRules("#v2-i6") ); + equal( "required maxlength", flatRules("#co_name") ); + + QUnit.reset(); + jQuery.validator.autoCreateRanges = true; + v = $("#v2").validate(); + equal( "required rangelength", flatRules("#v2-i6") ); + + $("#subformRequired").validate({ + rules: { + co_name: "required" + } + }); + $("#co_name").removeClass(); + equal( "required maxlength", flatRules("#co_name") ); + jQuery.validator.autoCreateRanges = false; +}); + +test("rules(), evaluate dynamic parameters", function() { + expect(2); + var v = $("#testForm1clean").validate({ + rules: { + firstname: { + min: function(element) { + equal( $("#firstnamec")[0], element ); + return 12; + } + } + } + }); + deepEqual( $("#firstnamec").rules(), {min:12}); +}); + +test("rules(), class and attribute combinations", function() { + + $.validator.addMethod("customMethod1", function() { + return false; + }, ""); + $.validator.addMethod("customMethod2", function() { + return false; + }, ""); + var v = $("#v2").validate({ + rules: { + 'v2-i7': { + required: true, + minlength: 2, + customMethod: true + } + } + }); + deepEqual( $("#v2-i1").rules(), { required: true }); + deepEqual( $("#v2-i2").rules(), { required: true, email: true }); + deepEqual( $("#v2-i3").rules(), { url: true }); + deepEqual( $("#v2-i4").rules(), { required: true, minlength: 2 }); + deepEqual( $("#v2-i5").rules(), { required: true, minlength: 2, maxlength: 5, customMethod1: "123" }); + jQuery.validator.autoCreateRanges = true; + deepEqual( $("#v2-i5").rules(), { required: true, customMethod1: "123", rangelength: [2, 5] }); + deepEqual( $("#v2-i6").rules(), { required: true, customMethod2: true, rangelength: [2, 5] }); + jQuery.validator.autoCreateRanges = false; + deepEqual( $("#v2-i7").rules(), { required: true, minlength: 2, customMethod: true }); + + delete $.validator.methods.customMethod1; + delete $.validator.messages.customMethod1; + delete $.validator.methods.customMethod2; + delete $.validator.messages.customMethod2; +}); + +test("rules(), dependency checks", function() { + var v = $("#testForm1clean").validate({ + rules: { + firstname: { + min: { + param: 5, + depends: function(el) { + return /^a/.test($(el).val()); + } + } + }, + lastname: { + max: { + param: 12 + }, + email: { + depends: function() { return true; } + } + } + } + }); + + var rules = $("#firstnamec").rules(); + equal( 0, v.objectLength(rules) ); + + $("#firstnamec").val('ab'); + deepEqual( $("#firstnamec").rules(), {min:5}); + + deepEqual( $("#lastnamec").rules(), {max:12, email:true}); +}); + +test("rules(), add and remove", function() { + $.validator.addMethod("customMethod1", function() { + return false; + }, ""); + $("#v2").validate(); + var removedAttrs = $("#v2-i5").removeClass("required").removeAttrs("minlength maxlength"); + deepEqual( $("#v2-i5").rules(), { customMethod1: "123" }); + + $("#v2-i5").addClass("required").attr(removedAttrs); + deepEqual( $("#v2-i5").rules(), { required: true, minlength: 2, maxlength: 5, customMethod1: "123" }); + + $("#v2-i5").addClass("email").attr({min: 5}); + deepEqual( $("#v2-i5").rules(), { required: true, email: true, minlength: 2, maxlength: 5, min: 5, customMethod1: "123" }); + + $("#v2-i5").removeClass("required email").removeAttrs("minlength maxlength customMethod1 min"); + deepEqual( $("#v2-i5").rules(), {}); + + delete $.validator.methods.customMethod1; + delete $.validator.messages.customMethod1; +}); + +test("rules(), add and remove static rules", function() { + var v = $("#testForm1clean").validate({ + rules: { + firstname: "required date" + } + }); + deepEqual( $("#firstnamec").rules(), { required: true, date: true } ); + + $("#firstnamec").rules("remove", "date") + deepEqual( $("#firstnamec").rules(), { required: true } ); + $("#firstnamec").rules("add", "email"); + deepEqual( $("#firstnamec").rules(), { required: true, email: true } ); + + $("#firstnamec").rules("remove", "required"); + deepEqual( $("#firstnamec").rules(), { email: true } ); + + deepEqual( $("#firstnamec").rules("remove"), { email: true } ); + deepEqual( $("#firstnamec").rules(), { } ); + + $("#firstnamec").rules("add", "required email"); + deepEqual( $("#firstnamec").rules(), { required: true, email: true } ); + + + deepEqual( $("#lastnamec").rules(), {} ); + $("#lastnamec").rules("add", "required"); + $("#lastnamec").rules("add", { + minlength: 2 + }); + deepEqual( $("#lastnamec").rules(), { required: true, minlength: 2 } ); + + + var removedRules = $("#lastnamec").rules("remove", "required email"); + deepEqual( $("#lastnamec").rules(), { minlength: 2 } ); + $("#lastnamec").rules("add", removedRules); + deepEqual( $("#lastnamec").rules(), { required: true, minlength: 2 } ); +}); + +test("rules(), add messages", function() { + $("#firstnamec").attr("title", null); + var v = $("#testForm1clean").validate({ + rules: { + firstname: "required" + } + }); + $("#testForm1clean").valid(); + $("#firstnamec").valid(); + deepEqual( v.settings.messages.firstname, undefined ); + + $("#firstnamec").rules("add", { + messages: { + required: "required" + } + }); + + $("#firstnamec").valid(); + deepEqual( v.errorList[0] && v.errorList[0].message, "required" ); +}); diff --git a/wqflask/wqflask/static/new/packages/ValidationPlugin/test/selects/index.html b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/selects/index.html new file mode 100644 index 00000000..fae8127a --- /dev/null +++ b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/selects/index.html @@ -0,0 +1,436 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + +<title>Fun with jQuery</title> + +<script src="http://www.google.com/jsapi"></script> +<script> + google.load("jquery", "1"); +</script> + +<script type="text/javascript"> + +$.fn.options = function(selector) { + return this.each(function() { + function container(select) { + if (select.next().is(".option-container")) { + return $(select).next(); + } + return $('<select class="option-container" />').append(select.children()).insertAfter(select).hide(); + } + var container = container($(this)); + $(this).empty().append(container.children(selector).clone()); + }); +} + +$(document).ready(function(){ + + $("#State").hide() + + $("#Country").change(function() { + var selected = this.options[this.selectedIndex].value; + if (selected == "US") { + $("#State").show().options(".state"); + } else if (selected == "CA") { + $("#State").show().options(".province"); + } else { + $("#State").hide(); + } + }).change(); + + +}); +</script> + + + +</head> + +<body> +Mission: + +<xmp> +CODE + +</xmp> + + + <select size="1" id="Country" name="country"> + <option value="">Select One</option> + + <option value="US" selected="selected">United States</option> + <option value="CA">Canada</option> + <option value="">----------</option> + <option value="AF">Afghanistan</option> + <option value="AL">Albania</option> + <option value="DZ">Algeria</option> + + <option value="AS">American Samoa</option> + <option value="AD">Andorra</option> + <option value="AO">Angola</option> + <option value="AI">Anguilla</option> + <option value="AQ">Antarctica</option> + <option value="AG">Antigua and Barbuda</option> + + <option value="AR">Argentina</option> + <option value="AM">Armenia</option> + <option value="AW">Aruba</option> + <option value="AU">Australia</option> + <option value="AT">Austria</option> + <option value="AZ">Azerbaidjan</option> + + <option value="BS">Bahamas</option> + <option value="BH">Bahrain</option> + <option value="BD">Bangladesh</option> + <option value="BB">Barbados</option> + <option value="BY">Belarus</option> + <option value="BE">Belgium</option> + + <option value="BZ">Belize</option> + <option value="BJ">Benin</option> + <option value="BM">Bermuda</option> + <option value="BT">Bhutan</option> + <option value="BO">Bolivia</option> + <option value="BA">Bosnia-Herzegovina</option> + + <option value="BW">Botswana</option> + <option value="BV">Bouvet Island</option> + <option value="BR">Brazil</option> + <option value="IO">British Indian Ocean Territory</option> + <option value="BN">Brunei Darussalam</option> + <option value="BG">Bulgaria</option> + + <option value="BF">Burkina Faso</option> + <option value="BI">Burundi</option> + <option value="KH">Cambodia</option> + <option value="CM">Cameroon</option> + <option value="CV">Cape Verde</option> + <option value="KY">Cayman Islands</option> + + <option value="CF">Central African Republic</option> + <option value="TD">Chad</option> + <option value="CL">Chile</option> + <option value="CN">China</option> + <option value="CX">Christmas Island</option> + <option value="CC">Cocos (Keeling) Islands</option> + + <option value="CO">Colombia</option> + <option value="KM">Comoros</option> + <option value="CG">Congo</option> + <option value="CK">Cook Islands</option> + <option value="CR">Costa Rica</option> + <option value="HR">Croatia</option> + + <option value="CU">Cuba</option> + <option value="CY">Cyprus</option> + <option value="CZ">Czech Republic</option> + <option value="DK">Denmark</option> + <option value="DJ">Djibouti</option> + <option value="DM">Dominica</option> + + <option value="DO">Dominican Republic</option> + <option value="TP">East Timor</option> + <option value="EC">Ecuador</option> + <option value="EG">Egypt</option> + <option value="SV">El Salvador</option> + <option value="GQ">Equatorial Guinea</option> + + <option value="ER">Eritrea</option> + <option value="EE">Estonia</option> + <option value="ET">Ethiopia</option> + <option value="FK">Falkland Islands</option> + <option value="FO">Faroe Islands</option> + <option value="FJ">Fiji</option> + + <option value="FI">Finland</option> + <option value="CS">Former Czechoslovakia</option> + <option value="SU">Former USSR</option> + <option value="FR">France</option> + <option value="FX">France (European Territory)</option> + <option value="GF">French Guyana</option> + + <option value="TF">French Southern Territories</option> + <option value="GA">Gabon</option> + <option value="GM">Gambia</option> + <option value="GE">Georgia</option> + <option value="DE">Germany</option> + <option value="GH">Ghana</option> + + <option value="GI">Gibraltar</option> + <option value="GB">Great Britain</option> + <option value="GR">Greece</option> + <option value="GL">Greenland</option> + <option value="GD">Grenada</option> + <option value="GP">Guadeloupe (French)</option> + + <option value="GU">Guam (USA)</option> + <option value="GT">Guatemala</option> + <option value="GN">Guinea</option> + <option value="GW">Guinea Bissau</option> + <option value="GY">Guyana</option> + <option value="HT">Haiti</option> + + <option value="HM">Heard and McDonald Islands</option> + <option value="HN">Honduras</option> + <option value="HK">Hong Kong</option> + <option value="HU">Hungary</option> + <option value="IS">Iceland</option> + <option value="IN">India</option> + + <option value="ID">Indonesia</option> + <option value="INT">International</option> + <option value="IR">Iran</option> + <option value="IQ">Iraq</option> + <option value="IE">Ireland</option> + <option value="IL">Israel</option> + + <option value="IT">Italy</option> + <option value="CI">Ivory Coast (Cote D'Ivoire)</option> + <option value="JM">Jamaica</option> + <option value="JP">Japan</option> + <option value="JO">Jordan</option> + <option value="KZ">Kazakhstan</option> + + <option value="KE">Kenya</option> + <option value="KI">Kiribati</option> + <option value="KW">Kuwait</option> + <option value="KG">Kyrgyzstan</option> + <option value="LA">Laos</option> + <option value="LV">Latvia</option> + + <option value="LB">Lebanon</option> + <option value="LS">Lesotho</option> + <option value="LR">Liberia</option> + <option value="LY">Libya</option> + <option value="LI">Liechtenstein</option> + <option value="LT">Lithuania</option> + + <option value="LU">Luxembourg</option> + <option value="MO">Macau</option> + <option value="MK">Macedonia</option> + <option value="MG">Madagascar</option> + <option value="MW">Malawi</option> + <option value="MY">Malaysia</option> + + <option value="MV">Maldives</option> + <option value="ML">Mali</option> + <option value="MT">Malta</option> + <option value="MH">Marshall Islands</option> + <option value="MQ">Martinique (French)</option> + <option value="MR">Mauritania</option> + + <option value="MU">Mauritius</option> + <option value="YT">Mayotte</option> + <option value="MX">Mexico</option> + <option value="FM">Micronesia</option> + <option value="MD">Moldavia</option> + <option value="MC">Monaco</option> + + <option value="MN">Mongolia</option> + <option value="MS">Montserrat</option> + <option value="MA">Morocco</option> + <option value="MZ">Mozambique</option> + <option value="MM">Myanmar</option> + <option value="NA">Namibia</option> + + <option value="NR">Nauru</option> + <option value="NP">Nepal</option> + <option value="NL">Netherlands</option> + <option value="AN">Netherlands Antilles</option> + <option value="NT">Neutral Zone</option> + <option value="NC">New Caledonia (French)</option> + + <option value="NZ">New Zealand</option> + <option value="NI">Nicaragua</option> + <option value="NE">Niger</option> + <option value="NG">Nigeria</option> + <option value="NU">Niue</option> + <option value="NF">Norfolk Island</option> + + <option value="KP">North Korea</option> + <option value="MP">Northern Mariana Islands</option> + <option value="NO">Norway</option> + <option value="OM">Oman</option> + <option value="PK">Pakistan</option> + <option value="PW">Palau</option> + + <option value="PA">Panama</option> + <option value="PG">Papua New Guinea</option> + <option value="PY">Paraguay</option> + <option value="PE">Peru</option> + <option value="PH">Philippines</option> + <option value="PN">Pitcairn Island</option> + + <option value="PL">Poland</option> + <option value="PF">Polynesia (French)</option> + <option value="PT">Portugal</option> + <option value="PR">Puerto Rico</option> + <option value="QA">Qatar</option> + <option value="RE">Reunion (French)</option> + + <option value="RO">Romania</option> + <option value="RU">Russian Federation</option> + <option value="RW">Rwanda</option> + <option value="GS">S. Georgia & S. Sandwich Isls.</option> + <option value="SH">Saint Helena</option> + <option value="KN">Saint Kitts & Nevis Anguilla</option> + + <option value="LC">Saint Lucia</option> + <option value="PM">Saint Pierre and Miquelon</option> + <option value="ST">Saint Tome (Sao Tome) and Principe</option> + <option value="VC">Saint Vincent & Grenadines</option> + <option value="WS">Samoa</option> + <option value="SM">San Marino</option> + + <option value="SA">Saudi Arabia</option> + <option value="SN">Senegal</option> + <option value="SC">Seychelles</option> + <option value="SL">Sierra Leone</option> + <option value="SG">Singapore</option> + <option value="SK">Slovak Republic</option> + + <option value="SI">Slovenia</option> + <option value="SB">Solomon Islands</option> + <option value="SO">Somalia</option> + <option value="ZA">South Africa</option> + <option value="KR">South Korea</option> + <option value="ES">Spain</option> + + <option value="LK">Sri Lanka</option> + <option value="SD">Sudan</option> + <option value="SR">Suriname</option> + <option value="SJ">Svalbard and Jan Mayen Islands</option> + <option value="SZ">Swaziland</option> + <option value="SE">Sweden</option> + + <option value="CH">Switzerland</option> + <option value="SY">Syria</option> + <option value="TJ">Tadjikistan</option> + <option value="TW">Taiwan</option> + <option value="TZ">Tanzania</option> + <option value="TH">Thailand</option> + + <option value="TG">Togo</option> + <option value="TK">Tokelau</option> + <option value="TO">Tonga</option> + <option value="TT">Trinidad and Tobago</option> + <option value="TN">Tunisia</option> + <option value="TR">Turkey</option> + + <option value="TM">Turkmenistan</option> + <option value="TC">Turks and Caicos Islands</option> + <option value="TV">Tuvalu</option> + <option value="UG">Uganda</option> + <option value="UA">Ukraine</option> + <option value="AE">United Arab Emirates</option> + + <option value="GB">United Kingdom</option> + <option value="UY">Uruguay</option> + <option value="MIL">USA Military</option> + <option value="UM">USA Minor Outlying Islands</option> + <option value="UZ">Uzbekistan</option> + <option value="VU">Vanuatu</option> + + <option value="VA">Vatican City State</option> + <option value="VE">Venezuela</option> + <option value="VN">Vietnam</option> + <option value="VG">Virgin Islands (British)</option> + <option value="VI">Virgin Islands (USA)</option> + <option value="WF">Wallis and Futuna Islands</option> + + <option value="EH">Western Sahara</option> + <option value="YE">Yemen</option> + <option value="YU">Yugoslavia</option> + <option value="ZR">Zaire</option> + <option value="ZM">Zambia</option> + <option value="ZW">Zimbabwe</option> + + </select> +<br /> + +<select id="State" name="State"> + + <option value="" class="selectone">Select One</option> + <option value="AB" class="province">Alberta</option> + <option value="BC" class="province">British Columbia</option> + <option value="MB" class="province">Manitoba</option> + + <option value="NB" class="province">New Brunswick</option> + <option value="NF" class="province">Newfoundland</option> + <option value="NT" class="province">Northwest Territories</option> + <option value="NS" class="province">Nova Scotia</option> + <option value="NU" class="province">Nunavut</option> + <option value="ON" class="province">Ontario</option> + + <option value="PE" class="province">Prince Edward Island</option> + <option value="QC" class="province">Quebec</option> + <option value="SK" class="province">Saskatchewan</option> + <option value="YT" class="province">Yukon Territory</option> + + <option value="AK" class="state">Alaska</option> + <option value="AL" class="state">Alabama</option> + + <option value="AR" class="state">Arkansas</option> + <option value="AZ" class="state">Arizona</option> + <option value="CA" class="state">California</option> + <option value="CO" class="state">Colorado</option> + <option value="CT" class="state">Connecticut</option> + <option value="DC" class="state">District of Columbia</option> + + <option value="DE" class="state">Delaware</option> + <option value="FL" class="state">Florida</option> + <option value="GA" class="state">Georgia</option> + <option value="HI" class="state">Hawaii</option> + <option value="IA" class="state">Iowa</option> + <option value="ID" class="state">Idaho</option> + + <option value="IL" class="state">Illinois</option> + <option value="IN" class="state">Indiana</option> + <option value="KS" class="state">Kansas</option> + <option value="KY" class="state">Kentucky</option> + <option value="LA" class="state">Louisiana</option> + <option value="MA" class="state">Massachusetts</option> + + <option value="MD" class="state">Maryland</option> + <option value="ME" class="state">Maine</option> + <option value="MI" class="state">Michigan</option> + <option value="MN" class="state">Minnesota</option> + <option value="MO" class="state">Missouri</option> + <option value="MS" class="state">Mississippi</option> + + <option value="MT" class="state">Montana</option> + <option value="NC" class="state">North Carolina</option> + <option value="ND" class="state">North Dakota</option> + <option value="NE" class="state">Nebraska</option> + <option value="NH" class="state">New Hampshire</option> + <option value="NJ" class="state">New Jersey</option> + + <option value="NM" class="state">New Mexico</option> + <option value="NV" class="state">Nevada</option> + <option value="NY" class="state">New York</option> + <option value="OH" class="state">Ohio</option> + <option value="OK" class="state">Oklahoma</option> + <option value="OR" class="state">Oregon</option> + + <option value="PA" class="state">Pennsylvania</option> + <option value="PR" class="state">Puerto Rico</option> + <option value="RI" class="state">Rhode Island</option> + <option value="SC" class="state">South Carolina</option> + <option value="SD" class="state">South Dakota</option> + <option value="TN" class="state">Tennessee</option> + + <option value="TX" class="state">Texas</option> + <option value="UT" class="state">Utah</option> + <option value="VA" class="state">Virginia</option> + <option value="VT" class="state">Vermont</option> + <option value="WA" class="state">Washington</option> + <option value="WI" class="state">Wisconsin</option> + + <option value="WV" class="state">West Virginia</option> + <option value="WY" class="state">Wyoming</option> +</select> + +</body> +</html> diff --git a/wqflask/wqflask/static/new/packages/ValidationPlugin/test/tabs.html b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/tabs.html new file mode 100644 index 00000000..06f1022c --- /dev/null +++ b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/tabs.html @@ -0,0 +1,78 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /> +<title>Test for jQuery validate() plugin</title> + +<link rel="stylesheet" type="text/css" media="screen" href="../demo/css/screen.css" /> +<link rel="stylesheet" href="../../../themes/flora/flora.all.css" type="text/css" media="screen" title="Flora (Default)"> + +<script src="../lib/jquery.js" type="text/javascript"></script> +<script src="../../../ui/current/ui.tabs.js" type="text/javascript"></script> +<script type="text/javascript" src="../lib/jquery.metadata.js"></script> +<script type="text/javascript" src="../jquery.validate.js"></script> +<script src="firebug/firebug.js" type="text/javascript"></script> + +<script type="text/javascript"> + +$().ready(function() { + $("#commentForm").validate({debug:true}); + $("#example > ul").tabs(); +}); +</script> + +<style type="text/css"> +form.cmxform { width: 470px; } +</style> + +</head> +<body> + + <form class="cmxform" id="commentForm" method="get" action=""> + + <div id="example" class="flora"> + <ul> + + <li><a href="#fragment-1"><span>One</span></a></li> + <li><a href="#fragment-2"><span>Two</span></a></li> + <li><a href="#fragment-3"><span>Three</span></a></li> + </ul> + <div id="fragment-1"> + <fieldset> + <legend>A simple comment form with submit validation and default messages</legend> + <p> + <label for="cname">Name (required, at least 2 characters)</label> + <input id="cname" name="name" class="some other styles {required:true,minLength:2}" /> + <p> + <label for="cemail">E-Mail (required)</label> + <input id="cemail" name="email" class="{required:true,email:true}" /> + </p> + <p> + <label for="curl">URL (optional)</label> + <input id="curl" name="url" class="{url:true}" value="" /> + </p> + <p> + <label for="ccomment">Your comment (required)</label> + <textarea id="ccomment" name="comment" class="{required:true}"></textarea> + </p> + </fieldset> + + </div> + <div id="fragment-2"> + Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. + Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. + </div> + <div id="fragment-3"> + Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. + Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. + Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. + </div> + </div> + <p> + <input class="submit" type="submit" value="Submit"/> + </p> + + </form> + +</body> +</html> diff --git a/wqflask/wqflask/static/new/packages/ValidationPlugin/test/test.js b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/test.js new file mode 100644 index 00000000..cc384d19 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/ValidationPlugin/test/test.js @@ -0,0 +1,1266 @@ +window.sessionStorage && sessionStorage.clear(); +jQuery.validator.defaults.debug = true; +$.mockjaxSettings.log = $.noop; + +$.mockjax({ + url: "form.php?user=Peter&password=foobar", + responseText: 'Hi Peter, welcome back.', + responseStatus: 200, + responseTime: 1 +}); +$.mockjax({ + url: "users.php", + data: { username: /Peter2?|asdf/}, + responseText: 'false', + responseStatus: 200, + responseTime: 1 +}); +$.mockjax({ + url: "users2.php", + data: { username: "asdf"}, + responseText: '"asdf is already taken, please try something else"', + responseStatus: 200, + responseTime: 1 +}); +$.mockjax({ + url: "echo.php", + response: function(data) { + this.responseText = JSON.stringify(data.data); + }, + responseTime: 100 +}); + +module("validator"); + +test("Constructor", function() { + var v1 = $("#testForm1").validate(); + var v2 = $("#testForm1").validate(); + equal( v1, v2, "Calling validate() multiple times must return the same validator instance" ); + equal( v1.elements().length, 3, "validator elements" ); +}); + +test("validate() without elements, with non-form elements", 0, function() { + $("#doesn'texist").validate(); +}); + +test("valid() plugin method", function() { + var form = $("#userForm"); + form.validate(); + ok ( !form.valid(), "Form isn't valid yet" ); + var input = $("#username"); + ok ( !input.valid(), "Input isn't valid either" ); + input.val("Hello world"); + ok ( form.valid(), "Form is now valid" ); + ok ( input.valid(), "Input is valid, too" ); +}); + +test("valid() plugin method", function() { + var form = $("#testForm1"); + form.validate(); + var inputs = form.find("input"); + ok( !inputs.valid(), "all invalid" ); + inputs.not(":first").val("ok"); + ok( !inputs.valid(), "just one invalid" ); + inputs.val("ok"); + ok( inputs.valid(), "all valid" ); +}); + +test("valid() plugin method, special handling for checkable groups", function() { + // rule is defined on first checkbox, must apply to others, too + var checkable = $("#checkable2"); + ok( !checkable.valid(), "must be invalid, not checked yet" ); + checkable.attr("checked", true); + ok( checkable.valid(), "valid, is now checked" ); + checkable.attr("checked", false); + ok( !checkable.valid(), "invalid again" ); + $("#checkable3").attr("checked", true); + ok( checkable.valid(), "valid, third box is checked" ); +}); + +test("addMethod", function() { + expect( 3 ); + $.validator.addMethod("hi", function(value) { + return value == "hi"; + }, "hi me too"); + var method = $.validator.methods.hi, + e = $('#text1')[0]; + ok( !method(e.value, e), "Invalid" ); + e.value = "hi"; + ok( method(e.value, e), "Invalid" ); + ok( jQuery.validator.messages.hi == "hi me too", "Check custom message" ); +}); + +test("addMethod2", function() { + expect( 4 ); + $.validator.addMethod("complicatedPassword", function(value, element, param) { + return this.optional(element) || /\D/.test(value) && /\d/.test(value) + }, "Your password must contain at least one number and one letter"); + var v = jQuery("#form").validate({ + rules: { + action: { complicatedPassword: true } + } + }); + var rule = $.validator.methods.complicatedPassword, + e = $('#text1')[0]; + e.value = ""; + strictEqual( v.element(e), true, "Rule is optional, valid" ); + equal( 0, v.size() ); + e.value = "ko"; + ok( !v.element(e), "Invalid, doesn't contain one of the required characters" ); + e.value = "ko1"; + ok( v.element(e) ); +}); + +test("form(): simple", function() { + expect( 2 ); + var form = $('#testForm1')[0]; + var v = $(form).validate(); + ok( !v.form(), 'Invalid form' ); + $('#firstname').val("hi"); + $('#lastname').val("hi"); + ok( v.form(), 'Valid form' ); +}); + +test("form(): checkboxes: min/required", function() { + expect( 3 ); + var form = $('#testForm6')[0]; + var v = $(form).validate(); + ok( !v.form(), 'Invalid form' ); + $('#form6check1').attr("checked", true); + ok( !v.form(), 'Invalid form' ); + $('#form6check2').attr("checked", true); + ok( v.form(), 'Valid form' ); +}); + +test("form(): radio buttons: required", function () { + expect( 6 ); + var form = $('#testForm10')[0]; + + var v = $(form).validate({ rules: { testForm10Radio: "required"} }); + ok(!v.form(), 'Invalid Form'); + equal($('#testForm10Radio1').attr('class'), 'error'); + equal($('#testForm10Radio2').attr('class'), 'error'); + + $('#testForm10Radio2').attr("checked", true); + ok(v.form(), 'Valid form'); + + equal($('#testForm10Radio1').attr('class'), 'valid'); + equal($('#testForm10Radio2').attr('class'), 'valid'); +}); + +test("form(): selects: min/required", function() { + expect( 3 ); + var form = $('#testForm7')[0]; + var v = $(form).validate(); + ok( !v.form(), 'Invalid form' ); + $("#optionxa").attr("selected", true); + ok( !v.form(), 'Invalid form' ); + $("#optionxb").attr("selected", true); + ok( v.form(), 'Valid form' ); +}); + +test("form(): with equalTo", function() { + expect( 2 ); + var form = $('#testForm5')[0]; + var v = $(form).validate(); + ok( !v.form(), 'Invalid form' ); + $('#x1, #x2').val("hi"); + ok( v.form(), 'Valid form' ); +}); + +test("form(): with equalTo and onfocusout=false", function() { + expect( 4 ); + var form = $('#testForm5')[0]; + var v = $(form).validate({ + onfocusout: false, + showErrors: function() { + ok(true, 'showErrors should only be called twice'); + this.defaultShowErrors(); + } + }); + $('#x1, #x2').val("hi"); + ok( v.form(), 'Valid form' ); + $('#x2').val('not equal').blur(); + ok( !v.form(), 'Invalid form' ); +}); + + +test("check(): simple", function() { + expect( 3 ); + var element = $('#firstname')[0]; + var v = $('#testForm1').validate(); + ok( v.size() == 0, 'No errors yet' ); + v.check(element); + ok( v.size() == 1, 'error exists' ); + v.errorList = []; + $('#firstname').val("hi"); + v.check(element); + ok( !v.size() == 1, 'No more errors' ); +}); + +test("hide(): input", function() { + expect( 3 ); + var errorLabel = $('#errorFirstname'); + var element = $('#firstname')[0]; + element.value ="bla"; + var v = $('#testForm1').validate(); + errorLabel.show(); + ok( errorLabel.is(":visible"), "Error label visible before validation" ); + ok( v.element(element) ); + ok( errorLabel.is(":hidden"), "Error label not visible after validation" ); +}); + +test("hide(): radio", function() { + expect( 2 ); + var errorLabel = $('#agreeLabel'); + var element = $('#agb')[0]; + element.checked = true; + var v = $('#testForm2').validate({ errorClass: "xerror" }); + errorLabel.show(); + ok( errorLabel.is(":visible"), "Error label visible after validation" ); + v.element(element); + ok( errorLabel.is(":hidden"), "Error label not visible after hiding it" ); +}); + +test("hide(): errorWrapper", function() { + expect(2); + var errorLabel = $('#errorWrapper'); + var element = $('#meal')[0]; + element.selectedIndex = 1; + + errorLabel.show(); + ok( errorLabel.is(":visible"), "Error label visible after validation" ); + var v = $('#testForm3').validate({ wrapper: "li", errorLabelContainer: $("#errorContainer") }); + v.element(element); + ok( errorLabel.is(":hidden"), "Error label not visible after hiding it" ); +}); + +test("hide(): container", function() { + expect(4); + var errorLabel = $('#errorContainer'); + var element = $('#testForm3')[0]; + var v = $('#testForm3').validate({ errorWrapper: "li", errorContainer: $("#errorContainer") }); + v.form(); + ok( errorLabel.is(":visible"), "Error label visible after validation" ); + $('#meal')[0].selectedIndex = 1; + v.form(); + ok( errorLabel.is(":hidden"), "Error label not visible after hiding it" ); + $('#meal')[0].selectedIndex = -1; + v.element("#meal"); + ok( errorLabel.is(":visible"), "Error label visible after validation" ); + $('#meal')[0].selectedIndex = 1; + v.element("#meal"); + ok( errorLabel.is(":hidden"), "Error label not visible after hiding it" ); +}); + +test("valid()", function() { + expect(4); + var errorList = [{name:"meal",message:"foo", element:$("#meal")[0]}]; + var v = $('#testForm3').validate(); + ok( v.valid(), "No errors, must be valid" ); + v.errorList = errorList; + ok( !v.valid(), "One error, must be invalid" ); + QUnit.reset(); + v = $('#testForm3').validate({ submitHandler: function() { + ok( false, "Submit handler was called" ); + }}); + ok( v.valid(), "No errors, must be valid and returning true, even with the submit handler" ); + v.errorList = errorList; + ok( !v.valid(), "One error, must be invalid, no call to submit handler" ); +}); + +test("submitHandler keeps submitting button", function() { + $("#userForm").validate({ + debug: true, + submitHandler: function(form) { + // dunno how to test this better; this tests the implementation that uses a hidden input + var hidden = $(form).find("input:hidden")[0]; + deepEqual(hidden.value, button.value) + deepEqual(hidden.name, button.name) + } + }); + $("#username").val("bla"); + var button = $("#userForm :submit")[0] + var event = $.Event("click"); + event.preventDefault(); + $.event.trigger(event, null, button); + $("#userForm").submit(); +}); + +test("showErrors()", function() { + expect( 4 ); + var errorLabel = $('#errorFirstname').hide(); + var element = $('#firstname')[0]; + var v = $('#testForm1').validate(); + ok( errorLabel.is(":hidden") ); + equal( 0, $("label.error[for=lastname]").size() ); + v.showErrors({"firstname": "required", "lastname": "bla"}); + equal( true, errorLabel.is(":visible") ); + equal( true, $("label.error[for=lastname]").is(":visible") ); +}); + +test("showErrors(), allow empty string and null as default message", function() { + $("#userForm").validate({ + rules: { + username: { + required: true, + minlength: 3 + } + }, + messages: { + username: { + required: "", + minlength: "too short" + } + } + }); + ok( !$("#username").valid() ); + equal( "", $("label.error[for=username]").text() ); + + $("#username").val("ab"); + ok( !$("#username").valid() ); + equal( "too short", $("label.error[for=username]").text() ); + + $("#username").val("abc"); + ok( $("#username").valid() ); + ok( $("label.error[for=username]").is(":hidden") ); +}); + +test("showErrors() - external messages", function() { + expect( 4 ); + var methods = $.extend({}, $.validator.methods); + var messages = $.extend({}, $.validator.messages); + $.validator.addMethod("foo", function() { return false; }); + $.validator.addMethod("bar", function() { return false; }); + equal( 0, $("#testForm4 label.error[for=f1]").size() ); + equal( 0, $("#testForm4 label.error[for=f2]").size() ); + var form = $('#testForm4')[0]; + var v = $(form).validate({ + messages: { + f1: "Please!", + f2: "Wohoo!" + } + }); + v.form(); + equal( $("#testForm4 label.error[for=f1]").text(), "Please!" ); + equal( $("#testForm4 label.error[for=f2]").text(), "Wohoo!" ); + + $.validator.methods = methods; + $.validator.messages = messages; +}); + +test("showErrors() - custom handler", function() { + expect(5); + var v = $('#testForm1').validate({ + showErrors: function(errorMap, errorList) { + equal( v, this ); + equal( v.errorList, errorList ); + equal( v.errorMap, errorMap ); + equal( "buga", errorMap.firstname ); + equal( "buga", errorMap.lastname ); + } + }); + v.form(); +}); + +test("option: (un)highlight, default", function() { + $("#testForm1").validate(); + var e = $("#firstname") + ok( !e.hasClass("error") ); + ok( !e.hasClass("valid") ); + e.valid() + ok( e.hasClass("error") ); + ok( !e.hasClass("valid") ); + e.val("hithere").valid() + ok( !e.hasClass("error") ); + ok( e.hasClass("valid") ); +}); + +test("option: (un)highlight, nothing", function() { + expect(3); + $("#testForm1").validate({ + highlight: false, + unhighlight: false + }); + var e = $("#firstname") + ok( !e.hasClass("error") ); + e.valid() + ok( !e.hasClass("error") ); + e.valid() + ok( !e.hasClass("error") ); +}); + +test("option: (un)highlight, custom", function() { + expect(5); + $("#testForm1clean").validate({ + highlight: function(element, errorClass) { + equal( "invalid", errorClass ); + $(element).hide(); + }, + unhighlight: function(element, errorClass) { + equal( "invalid", errorClass ) + $(element).show(); + }, + errorClass: "invalid", + rules: { + firstname: "required" + } + }); + var e = $("#firstnamec") + ok( e.is(":visible") ); + e.valid() + ok( !e.is(":visible") ); + e.val("hithere").valid() + ok( e.is(":visible") ); +}); + +test("option: (un)highlight, custom2", function() { + expect(6); + $("#testForm1").validate({ + highlight: function(element, errorClass) { + $(element).addClass(errorClass); + $(element.form).find("label[for=" + element.id + "]").addClass(errorClass); + }, + unhighlight: function(element, errorClass) { + $(element).removeClass(errorClass); + $(element.form).find("label[for=" + element.id + "]").removeClass(errorClass); + }, + errorClass: "invalid" + }); + var e = $("#firstname") + var l = $("#errorFirstname") + ok( !e.is(".invalid") ); + ok( !l.is(".invalid") ); + e.valid() + ok( e.is(".invalid") ); + ok( l.is(".invalid") ); + e.val("hithere").valid() + ok( !e.is(".invalid") ); + ok( !l.is(".invalid") ); +}); + +test("option: focusCleanup default false", function() { + var form = $("#userForm") + form.validate(); + form.valid(); + ok( form.is(":has(label.error[for=username]:visible)")); + $("#username").focus(); + ok( form.is(":has(label.error[for=username]:visible)")); +}); + +test("option: focusCleanup true", function() { + var form = $("#userForm") + form.validate({ + focusCleanup: true + }); + form.valid(); + ok( form.is(":has(label.error[for=username]:visible)") ); + $("#username").focus().trigger("focusin"); + ok( !form.is(":has(label.error[for=username]:visible)") ); +}); + +test("option: focusCleanup with wrapper", function() { + var form = $("#userForm") + form.validate({ + focusCleanup: true, + wrapper: "span" + }); + form.valid(); + ok( form.is(":has(span:visible:has(label.error[for=username]))") ); + $("#username").focus().trigger("focusin"); + ok( !form.is(":has(span:visible:has(label.error[for=username]))") ); +}); + +test("option: errorClass with multiple classes", function() { + var form = $("#userForm") + form.validate({ + focusCleanup: true, + wrapper: "span", + errorClass: "error error1" + }); + form.valid(); + ok( form.is(":has(span:visible:has(label.error[for=username]))") ); + ok( form.is(":has(span:visible:has(label.error1[for=username]))") ); + $("#username").focus().trigger("focusin"); + ok( !form.is(":has(span:visible:has(label.error[for=username]))") ); + ok( !form.is(":has(span:visible:has(label.error1[for=username]))") ); +}); + +test("elements() order", function() { + var container = $("#orderContainer"); + var v = $("#elementsOrder").validate({ + errorLabelContainer: container, + wrap: "li" + }); + deepEqual( v.elements().map(function() { + return $(this).attr("id"); + }).get(), ["order1", "order2", "order3", "order4", "order5", "order6"], "elements must be in document order" ); + v.form(); + deepEqual( container.children().map(function() { + return $(this).attr("for"); + }).get(), ["order1", "order2", "order3", "order4", "order5", "order6"], "labels in error container must be in document order" ); +}); + +test("defaultMessage(), empty title is ignored", function() { + var v = $("#userForm").validate(); + equal( "This field is required.", v.defaultMessage($("#username")[0], "required") ); +}); + +test("formatAndAdd", function() { + expect(4); + var v = $("#form").validate(); + var fakeElement = { form: $("#form")[0], name: "bar" }; + v.formatAndAdd(fakeElement, {method: "maxlength", parameters: 2}) + equal( "Please enter no more than 2 characters.", v.errorList[0].message ); + equal( "bar", v.errorList[0].element.name ); + + v.formatAndAdd(fakeElement, {method: "range", parameters:[2,4]}) + equal( "Please enter a value between 2 and 4.", v.errorList[1].message ); + + v.formatAndAdd(fakeElement, {method: "range", parameters:[0,4]}) + equal( "Please enter a value between 0 and 4.", v.errorList[2].message ); +}); + +test("formatAndAdd2", function() { + expect(3); + var v = $("#form").validate(); + var fakeElement = { form: $("#form")[0], name: "bar" }; + jQuery.validator.messages.test1 = function(param, element) { + equal( v, this ); + equal( 0, param ); + return "element " + element.name + " is not valid"; + }; + v.formatAndAdd(fakeElement, {method: "test1", parameters: 0}) + equal( "element bar is not valid", v.errorList[0].message ); +}); + +test("formatAndAdd, auto detect substitution string", function() { + var v = $("#testForm1clean").validate({ + rules: { + firstname: { + required: true, + rangelength: [5, 10] + } + }, + messages: { + firstname: { + rangelength: "at least ${0}, up to {1}" + } + } + }); + $("#firstnamec").val("abc"); + v.form(); + equal( "at least 5, up to 10", v.errorList[0].message ); +}) + +test("error containers, simple", function() { + expect(14); + var container = $("#simplecontainer"); + var v = $("#form").validate({ + errorLabelContainer: container, + showErrors: function() { + container.find("h3").html( jQuery.validator.format("There are {0} errors in your form.", this.size()) ); + this.defaultShowErrors(); + } + }); + + v.prepareForm(); + ok( v.valid(), "form is valid" ); + equal( 0, container.find("label").length, "There should be no error labels" ); + equal( "", container.find("h3").html() ); + + v.prepareForm(); + v.errorList = [{message:"bar", element: {name:"foo"}}, {message: "necessary", element: {name:"required"}}]; + ok( !v.valid(), "form is not valid after adding errors manually" ); + v.showErrors(); + equal( container.find("label").length, 2, "There should be two error labels" ); + ok( container.is(":visible"), "Check that the container is visible" ); + container.find("label").each(function() { + ok( $(this).is(":visible"), "Check that each label is visible" ); + }); + equal( "There are 2 errors in your form.", container.find("h3").html() ); + + v.prepareForm(); + ok( v.valid(), "form is valid after a reset" ); + v.showErrors(); + equal( container.find("label").length, 2, "There should still be two error labels" ); + ok( container.is(":hidden"), "Check that the container is hidden" ); + container.find("label").each(function() { + ok( $(this).is(":hidden"), "Check that each label is hidden" ); + }); +}); + +test("error containers, with labelcontainer I", function() { + expect(16); + var container = $("#container"), + labelcontainer = $("#labelcontainer"); + var v = $("#form").validate({ + errorContainer: container, + errorLabelContainer: labelcontainer, + wrapper: "li" + }); + + ok( v.valid(), "form is valid" ); + equal( 0, container.find("label").length, "There should be no error labels in the container" ); + equal( 0, labelcontainer.find("label").length, "There should be no error labels in the labelcontainer" ); + equal( 0, labelcontainer.find("li").length, "There should be no lis labels in the labelcontainer" ); + + v.errorList = [{message:"bar", element: {name:"foo"}}, {name: "required", message: "necessary", element: {name:"required"}}]; + ok( !v.valid(), "form is not valid after adding errors manually" ); + v.showErrors(); + equal( 0, container.find("label").length, "There should be no error label in the container" ); + equal( 2, labelcontainer.find("label").length, "There should be two error labels in the labelcontainer" ); + equal( 2, labelcontainer.find("li").length, "There should be two error lis in the labelcontainer" ); + ok( container.is(":visible"), "Check that the container is visible" ); + ok( labelcontainer.is(":visible"), "Check that the labelcontainer is visible" ); + var labels = labelcontainer.find("label").each(function() { + ok( $(this).is(":visible"), "Check that each label is visible1" ); + equal( "li", $(this).parent()[0].tagName.toLowerCase(), "Check that each label is wrapped in an li" ); + ok( $(this).parent("li").is(":visible"), "Check that each parent li is visible" ); + }); +}); + +test("errorcontainer, show/hide only on submit", function() { + expect(14); + var container = $("#container"); + var labelContainer = $("#labelcontainer"); + var v = $("#testForm1").bind("invalid-form.validate", function() { + ok( true, "invalid-form event triggered called" ); + }).validate({ + errorContainer: container, + errorLabelContainer: labelContainer, + showErrors: function() { + container.html( jQuery.validator.format("There are {0} errors in your form.", this.numberOfInvalids()) ); + ok( true, "showErrors called" ); + this.defaultShowErrors(); + } + }); + equal( "", container.html(), "must be empty" ); + equal( "", labelContainer.html(), "must be empty" ); + // validate whole form, both showErrors and invalidHandler must be called once + // preferably invalidHandler first, showErrors second + ok( !v.form(), "invalid form" ); + equal( 2, labelContainer.find("label").length ); + equal( "There are 2 errors in your form.", container.html() ); + ok( labelContainer.is(":visible"), "must be visible" ); + ok( container.is(":visible"), "must be visible" ); + + $("#firstname").val("hix").keyup(); + $("#testForm1").triggerHandler("keyup", [jQuery.event.fix({ type: "keyup", target: $("#firstname")[0] })]); + equal( 1, labelContainer.find("label:visible").length ); + equal( "There are 1 errors in your form.", container.html() ); + + $("#lastname").val("abc"); + ok( v.form(), "Form now valid, trigger showErrors but not invalid-form" ); +}); + +test("option invalidHandler", function() { + expect(1); + var v = $("#testForm1clean").validate({ + invalidHandler: function() { + ok( true, "invalid-form event triggered called" ); + start(); + } + }); + $("#usernamec").val("asdf").rules("add", { required: true, minlength: 5 }); + stop(); + $("#testForm1clean").submit(); +}); + +test("findByName()", function() { + deepEqual( new $.validator({}, document.getElementById("form")).findByName(document.getElementById("radio1").name).get(), $("#form").find("[name=radio1]").get() ); +}); + +test("focusInvalid()", function() { + // TODO when using custom focusin, this is triggered just once + // TODO when using 1.4 focusin, triggered twice; fix once not testing against 1.3 anymore + // expect(1); + var inputs = $("#testForm1 input").focus(function() { + equal( inputs[0], this, "focused first element" ); + }); + var v = $("#testForm1").validate(); + v.form(); + v.focusInvalid(); +}); + +test("findLastActive()", function() { + expect(3); + var v = $("#testForm1").validate(); + ok( !v.findLastActive() ); + v.form(); + v.focusInvalid(); + equal( v.findLastActive(), $("#firstname")[0] ); + var lastActive = $("#lastname").trigger("focus").trigger("focusin")[0]; + equal( v.lastActive, lastActive ); +}); + +test("validating multiple checkboxes with 'required'", function() { + expect(3); + var checkboxes = $("#form input[name=check3]").attr("checked", false); + equal(checkboxes.size(), 5); + var v = $("#form").validate({ + rules: { + check3: "required" + } + }); + v.form(); + equal(v.size(), 1); + checkboxes.filter(":last").attr("checked", true); + v.form(); + equal(v.size(), 0); +}); + +test("dynamic form", function() { + var counter = 0; + function add() { + $("<input class='{required:true}' name='list" + counter++ + "' />").appendTo("#testForm2"); + } + function errors(expected, message) { + equal(expected, v.size(), message ); + } + var v = $("#testForm2").validate(); + v.form(); + errors(1); + add(); + v.form(); + errors(2); + add(); + v.form(); + errors(3); + $("#testForm2 input[name=list1]").remove(); + v.form(); + errors(2); + add(); + v.form(); + errors(3); + $("#testForm2 input[name^=list]").remove(); + v.form(); + errors(1); + $("#agb").attr("disabled", true); + v.form(); + errors(0); + $("#agb").attr("disabled", false); + v.form(); + errors(1); +}); + +test("idOrName()", function() { + expect(4); + var v = $("#testForm1").validate(); + equal( "form8input", v.idOrName( $("#form8input")[0] ) ); + equal( "check", v.idOrName( $("#form6check1")[0] ) ); + equal( "agree", v.idOrName( $("#agb")[0] ) ); + equal( "button", v.idOrName( $("#form :button")[0] ) ); +}); + +test("resetForm()", function() { + function errors(expected, message) { + equal(expected, v.size(), message ); + } + var v = $("#testForm1").validate(); + v.form(); + errors(2); + $("#firstname").val("hiy"); + v.resetForm(); + errors(0); + equal("", $("#firstname").val(), "form plugin is included, therefor resetForm must also reset inputs, not only errors"); +}); + +test("message from title", function() { + var v = $("#withTitle").validate(); + v.checkForm(); + equal(v.errorList[0].message, "fromtitle", "title not used"); +}); + +test("ignoreTitle", function() { + var v = $("#withTitle").validate({ignoreTitle:true}); + v.checkForm(); + equal(v.errorList[0].message, $.validator.messages["required"], "title used when it should have been ignored"); +}); + +test("ajaxSubmit", function() { + expect(1); + stop(); + $("#user").val("Peter"); + $("#password").val("foobar"); + jQuery("#signupForm").validate({ + submitHandler: function(form) { + jQuery(form).ajaxSubmit({ + success: function(response) { + equal("Hi Peter, welcome back.", response); + start(); + } + }); + } + }); + jQuery("#signupForm").triggerHandler("submit"); +}); + + +module("misc"); + +test("success option", function() { + expect(7); + equal( "", $("#firstname").val() ); + var v = $("#testForm1").validate({ + success: "valid" + }); + var label = $("#testForm1 label"); + ok( label.is(".error") ); + ok( !label.is(".valid") ); + v.form(); + ok( label.is(".error") ); + ok( !label.is(".valid") ); + $("#firstname").val("hi"); + v.form(); + ok( label.is(".error") ); + ok( label.is(".valid") ); +}); + +test("success option2", function() { + expect(5); + equal( "", $("#firstname").val() ); + var v = $("#testForm1").validate({ + success: "valid" + }); + var label = $("#testForm1 label"); + ok( label.is(".error") ); + ok( !label.is(".valid") ); + $("#firstname").val("hi"); + v.form(); + ok( label.is(".error") ); + ok( label.is(".valid") ); +}); + +test("success option3", function() { + expect(5); + equal( "", $("#firstname").val() ); + $("#errorFirstname").remove(); + var v = $("#testForm1").validate({ + success: "valid" + }); + equal( 0, $("#testForm1 label").size() ); + $("#firstname").val("hi"); + v.form(); + var labels = $("#testForm1 label"); + equal( 3, labels.size() ); + ok( labels.eq(0).is(".valid") ); + ok( !labels.eq(1).is(".valid") ); +}); + +test("successlist", function() { + var v = $("#form").validate({ success: "xyz" }); + v.form(); + equal(0, v.successList.length); +}); + +test("success isn't called for optional elements", function() { + expect(4); + equal( "", $("#firstname").removeClass().val() ); + $("#something").remove(); + $("#lastname").remove(); + $("#errorFirstname").remove(); + var v = $("#testForm1").validate({ + success: function() { + ok( false, "don't call success for optional elements!" ); + }, + rules: { + firstname: "email" + } + }); + equal( 0, $("#testForm1 label").size() ); + v.form(); + equal( 0, $("#testForm1 label").size() ); + $("#firstname").valid(); + equal( 0, $("#testForm1 label").size() ); +}); + +test("success callback with element", function() { + expect(1); + var v = $("#userForm").validate({ + success: function( label, element ) { + equal( element, $('#username').get(0) ); + } + }); + $("#username").val("hi"); + v.form(); +}); + +test("all rules are evaluated even if one returns a dependency-mistmatch", function() { + expect(6); + equal( "", $("#firstname").removeClass().val() ); + $("#lastname").remove(); + $("#errorFirstname").remove(); + $.validator.addMethod("custom1", function() { + ok( true, "custom method must be evaluated" ); + return true; + }, ""); + var v = $("#testForm1").validate({ + rules: { + firstname: {email:true, custom1: true} + } + }); + equal( 0, $("#testForm1 label").size() ); + v.form(); + equal( 0, $("#testForm1 label").size() ); + $("#firstname").valid(); + equal( 0, $("#testForm1 label").size() ); + + delete $.validator.methods.custom1; + delete $.validator.messages.custom1; +}); + +test("messages", function() { + var m = jQuery.validator.messages; + equal( "Please enter no more than 0 characters.", m.maxlength(0) ); + equal( "Please enter at least 1 characters.", m.minlength(1) ); + equal( "Please enter a value between 1 and 2 characters long.", m.rangelength([1, 2]) ); + equal( "Please enter a value less than or equal to 1.", m.max(1) ); + equal( "Please enter a value greater than or equal to 0.", m.min(0) ); + equal( "Please enter a value between 1 and 2.", m.range([1, 2]) ); +}); + +test("jQuery.validator.format", function() { + equal( "Please enter a value between 0 and 1.", jQuery.validator.format("Please enter a value between {0} and {1}.", 0, 1) ); + equal( "0 is too fast! Enter a value smaller then 0 and at least -15", jQuery.validator.format("{0} is too fast! Enter a value smaller then {0} and at least {1}", 0, -15) ); + var template = jQuery.validator.format("{0} is too fast! Enter a value smaller then {0} and at least {1}"); + equal( "0 is too fast! Enter a value smaller then 0 and at least -15", template(0, -15) ); + template = jQuery.validator.format("Please enter a value between {0} and {1}."); + equal( "Please enter a value between 1 and 2.", template([1, 2]) ); +}); + +test("option: ignore", function() { + var v = $("#testForm1").validate({ + ignore: "[name=lastname]" + }); + v.form(); + equal( 1, v.size() ); +}); + +test("option: subformRequired", function() { + jQuery.validator.addMethod("billingRequired", function(value, element) { + if ($("#bill_to_co").is(":checked")) + return $(element).parents("#subform").length; + return !this.optional(element); + }, ""); + var v = $("#subformRequired").validate(); + v.form(); + equal( 1, v.size() ); + $("#bill_to_co").attr("checked", false); + v.form(); + equal( 2, v.size() ); + + delete $.validator.methods.billingRequired; + delete $.validator.messages.billingRequired; +}); + +module("expressions"); + +test("expression: :blank", function() { + var e = $("#lastname")[0]; + equal( 1, $(e).filter(":blank").length ); + e.value = " "; + equal( 1, $(e).filter(":blank").length ); + e.value = " " + equal( 1, $(e).filter(":blank").length ); + e.value= " a "; + equal( 0, $(e).filter(":blank").length ); +}); + +test("expression: :filled", function() { + var e = $("#lastname")[0]; + equal( 0, $(e).filter(":filled").length ); + e.value = " "; + equal( 0, $(e).filter(":filled").length ); + e.value = " " + equal( 0, $(e).filter(":filled").length ); + e.value= " a "; + equal( 1, $(e).filter(":filled").length ); +}); + +test("expression: :unchecked", function() { + var e = $("#check2")[0]; + equal( 1, $(e).filter(":unchecked").length ); + e.checked = true; + equal( 0, $(e).filter(":unchecked").length ); + e.checked = false; + equal( 1, $(e).filter(":unchecked").length ); +}); + +module("events"); + +test("validate on blur", function() { + function errors(expected, message) { + equal(v.size(), expected, message ); + } + function labels(expected) { + equal(v.errors().filter(":visible").size(), expected); + } + function blur(target) { + target.trigger("blur").trigger("focusout"); + } + $("#errorFirstname").hide(); + var e = $("#firstname"); + var v = $("#testForm1").validate(); + $("#something").val(""); + blur(e); + errors(0, "No value yet, required is skipped on blur"); + labels(0); + e.val("h"); + blur(e); + errors(1, "Required was ignored, but as something was entered, check other rules, minlength isn't met"); + labels(1); + e.val("hh"); + blur(e); + errors(0, "All is fine"); + labels(0); + e.val(""); + v.form(); + errors(3, "Submit checks all rules, both fields invalid"); + labels(3); + blur(e); + errors(1, "Blurring the field results in emptying the error list first, then checking the invalid field: its still invalid, don't remove the error" ); + labels(3); + e.val("h"); + blur(e); + errors(1, "Entering a single character fulfills required, but not minlength: 2, still invalid"); + labels(3); + e.val("hh"); + blur(e); + errors(0, "Both required and minlength are met, no errors left"); + labels(2); +}); + +test("validate on keyup", function() { + function errors(expected, message) { + equal(expected, v.size(), message ); + } + function keyup(target) { + target.trigger("keyup"); + } + var e = $("#firstname"); + var v = $("#testForm1").validate(); + keyup(e); + errors(0, "No value, no errors"); + e.val("a"); + keyup(e); + errors(0, "Value, but not invalid"); + e.val(""); + v.form(); + errors(2, "Both invalid"); + keyup(e); + errors(1, "Only one field validated, still invalid"); + e.val("hh"); + keyup(e); + errors(0, "Not invalid anymore"); + e.val("h"); + keyup(e); + errors(1, "Field didn't loose focus, so validate again, invalid"); + e.val("hh"); + keyup(e); + errors(0, "Valid"); +}); + +test("validate on not keyup, only blur", function() { + function errors(expected, message) { + equal(expected, v.size(), message ); + } + var e = $("#firstname"); + var v = $("#testForm1").validate({ + onkeyup: false + }); + errors(0); + e.val("a"); + e.trigger("keyup"); + e.keyup(); + errors(0); + e.trigger("blur").trigger("focusout"); + errors(1); +}); + +test("validate on keyup and blur", function() { + function errors(expected, message) { + equal(expected, v.size(), message ); + } + var e = $("#firstname"); + var v = $("#testForm1").validate(); + errors(0); + e.val("a"); + e.trigger("keyup"); + errors(0); + e.trigger("blur").trigger("focusout"); + errors(1); +}); + +test("validate email on keyup and blur", function() { + function errors(expected, message) { + equal(expected, v.size(), message ); + } + var e = $("#firstname"); + var v = $("#testForm1").validate(); + v.form(); + errors(2); + e.val("a"); + e.trigger("keyup"); + errors(1); + e.val("aa"); + e.trigger("keyup"); + errors(0); +}); + +test("validate checkbox on click", function() { + function errors(expected, message) { + equal(expected, v.size(), message ); + } + function trigger(element) { + element.click(); + // triggered click event screws up checked-state in 1.4 + element.valid(); + } + var e = $("#check2"); + var v = $("#form").validate({ + rules: { + check2: "required" + } + }); + trigger(e); + errors(0); + trigger(e); + equal( false, v.form() ); + errors(1); + trigger(e); + errors(0); + trigger(e); + errors(1); +}); + +test("validate multiple checkbox on click", function() { + function errors(expected, message) { + equal(expected, v.size(), message ); + } + function trigger(element) { + element.click(); + // triggered click event screws up checked-state in 1.4 + element.valid(); + } + var e1 = $("#check1").attr("checked", false); + var e2 = $("#check1b"); + var v = $("#form").validate({ + rules: { + check: { + required: true, + minlength: 2 + } + } + }); + trigger(e1); + trigger(e2); + errors(0); + trigger(e2); + equal( false, v.form() ); + errors(1); + trigger(e2); + errors(0); + trigger(e2); + errors(1); +}); + +test("correct checkbox receives the error", function(){ + function trigger(element) { + element.click(); + // triggered click event screws up checked-state in 1.4 + element.valid(); + } + var e1 = $("#check1").attr("checked", false); + var e2 = $("#check1b").attr("checked", false); + var v = $("#form").find('[type=checkbox]').attr('checked', false).end().validate({ + rules:{ + check: { + required: true, + minlength: 2 + } + } + }); + equal(false, v.form()); + trigger(e1); + equal(false, v.form()); + ok(v.errorList[0].element.id === v.currentElements[0].id, "the proper checkbox has the error AND is present in currentElements"); +}); + +test("validate radio on click", function() { + function errors(expected, message) { + equal(expected, v.size(), message ); + } + function trigger(element) { + element.click(); + // triggered click event screws up checked-state in 1.4 + element.valid(); + } + var e1 = $("#radio1"); + var e2 = $("#radio1a"); + var v = $("#form").validate({ + rules: { + radio1: "required" + } + }); + errors(0); + equal( false, v.form() ); + errors(1); + trigger(e2); + errors(0); + trigger(e1); + errors(0); +}); + +test("validate input with no type attribute, defaulting to text", function() { + function errors(expected, message) { + equal(expected, v.size(), message ); + } + var v = $("#testForm12").validate(); + var e = $("#testForm12text"); + errors(0); + e.valid(); + errors(1); + e.val('test'); + e.trigger('keyup'); + errors(0); +}); + +test("ignore hidden elements", function(){ + var form = $('#userForm'); + var validate = form.validate({ + rules:{ + "username": "required" + } + }); + form.get(0).reset(); + ok(! validate.form(), "form should be initially invalid"); + $('#userForm [name=username]').hide(); + ok(validate.form(), "hidden elements should be ignored by default"); +}); + +test("ignore hidden elements at start", function(){ + var form = $('#userForm'); + var validate = form.validate({ + rules:{ + "username": "required" + } + }); + form.get(0).reset(); + $('#userForm [name=username]').hide(); + ok(validate.form(), "hidden elements should be ignored by default"); + $('#userForm [name=username]').show(); + ok(! validate.form(), "form should be invalid when required element is visible"); +}); + +test("Specify error messages through data attributes", function() { + var form = $('#dataMessages'); + var name = $('#dataMessagesName'); + var v = form.validate(); + + form.get(0).reset(); + name.valid(); + + var label = $('#dataMessages label'); + equal( label.text(), "You must enter a value here", "Correct error label" ); +}); |