Add Prototype.js library unit tests. Hopefully the first of many AJAX test suites. Patch by John Resig <jresig@mozilla.com>. r=sayrer

This commit is contained in:
sayrer@gmail.com 2007-04-23 21:01:42 -07:00
parent 52be8d23c9
commit 78fb404c9f
30 changed files with 14262 additions and 0 deletions

View File

@ -45,6 +45,7 @@ include $(DEPTH)/config/autoconf.mk
DIRS += dom-level1-core \
dom-level2-core \
ajax \
bugs \
$(NULL)

View File

@ -0,0 +1,49 @@
#
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is
# Mozilla Foundation.
# Portions created by the Initial Developer are Copyright (C) 2007
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
#
# Alternatively, the contents of this file may be used under the terms of
# either of the GNU General Public License Version 2 or later (the "GPL"),
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = lib \
prototype \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,30 @@
var AJAXtests = [];
function runAJAXTest() {
if (AJAXtests.length == 0) {
SimpleTest.finish();
return;
}
var test = AJAXtests.shift();
var testframe = document.getElementById("testframe");
testframe.src = test;
}
function onManifestLoad(manifest) {
if (manifest.testcases) {
AJAXtests = manifest.testcases;
runAJAXTest();
} else {
ok(false, "manifest check", "no manifest!?!");
SimpleTest.finish();
}
}
function fetchManifest() {
var d = loadJSONDoc("manifest.json");
d.addBoth(onManifestLoad);
}
SimpleTest.waitForExplicitFinish();
addLoadEvent(fetchManifest);

View File

@ -0,0 +1,55 @@
#
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is
# Mozilla Foundation.
# Portions created by the Initial Developer are Copyright (C) 2007
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
#
# Alternatively, the contents of this file may be used under the terms of
# either of the GNU General Public License Version 2 or later (the "GPL"),
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
DEPTH = ../../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
relativesrcdir = dom/tests/mochitest/ajax/lib
include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk
_TEST_FILES = \
AJAX_setup.js \
MochiKit_packed.js \
SimpleTest.js \
test.css \
$(NULL)
libs:: $(_TEST_FILES)
$(INSTALL) $^ $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,419 @@
/**
* SimpleTest, a partial Test.Simple/Test.More API compatible test library.
*
* Why?
*
* Test.Simple doesn't work on IE < 6.
* TODO:
* * Support the Test.Simple API used by MochiKit, to be able to test MochiKit
* itself against IE 5.5
*
**/
if (typeof(SimpleTest) == "undefined") {
var SimpleTest = {};
}
var parentRunner = null;
if (typeof(parent) != "undefined" && parent.TestRunner) {
parentRunner = parent.TestRunner;
} else if (parent && parent.wrappedJSObject &&
parent.wrappedJSObject.TestRunner) {
parentRunner = parent.wrappedJSObject.TestRunner;
}
// Check to see if the TestRunner is present and has logging
if (parentRunner) {
SimpleTest._logEnabled = parentRunner.logEnabled;
}
SimpleTest._tests = [];
SimpleTest._stopOnLoad = true;
/**
* Something like assert.
**/
SimpleTest.ok = function (condition, name, diag) {
var test = {'result': !!condition, 'name': name, 'diag': diag || ""};
if (SimpleTest._logEnabled)
SimpleTest._logResult(test, "PASS", "FAIL");
SimpleTest._tests.push(test);
};
/**
* Roughly equivalent to ok(a==b, name)
**/
SimpleTest.is = function (a, b, name) {
var repr = MochiKit.Base.repr;
SimpleTest.ok(a == b, name, "got " + repr(a) + ", expected " + repr(b));
};
SimpleTest.isnot = function (a, b, name) {
var repr = MochiKit.Base.repr;
SimpleTest.ok(a != b, name, "Didn't expect " + repr(a) + ", but got it.");
};
// --------------- Test.Builder/Test.More todo() -----------------
SimpleTest.todo = function(condition, name, diag) {
var test = {'result': !!condition, 'name': name, 'diag': diag || "", todo: true};
if (SimpleTest._logEnabled)
SimpleTest._logResult(test, "TODO WORKED?", "TODO");
SimpleTest._tests.push(test);
}
SimpleTest._logResult = function(test, passString, failString) {
var msg = test.result ? passString : failString;
msg += " | " + test.name;
if (test.result) {
if (test.todo)
parentRunner.logger.error(msg)
else
parentRunner.logger.log(msg);
} else {
msg += " | " + test.diag;
if (test.todo)
parentRunner.logger.log(msg)
else
parentRunner.logger.error(msg);
}
}
/**
* Makes a test report, returns it as a DIV element.
**/
SimpleTest.report = function () {
var DIV = MochiKit.DOM.DIV;
var passed = 0;
var failed = 0;
var todo = 0;
var results = MochiKit.Base.map(
function (test) {
var cls, msg;
if (test.todo && !test.result) {
todo++;
cls = "test_todo"
msg = "todo - " + test.name;
} else if (test.result &&!test.todo) {
passed++;
cls = "test_ok";
msg = "ok - " + test.name;
} else {
failed++;
cls = "test_not_ok";
msg = "not ok - " + test.name + " " + test.diag;
}
return DIV({"class": cls}, msg);
},
SimpleTest._tests
);
var summary_class = ((failed == 0) ? 'all_pass' : 'some_fail');
return DIV({'class': 'tests_report'},
DIV({'class': 'tests_summary ' + summary_class},
DIV({'class': 'tests_passed'}, "Passed: " + passed),
DIV({'class': 'tests_failed'}, "Failed: " + failed),
DIV({'class': 'tests_todo'}, "Todo: " + todo)),
results
);
};
/**
* Toggle element visibility
**/
SimpleTest.toggle = function(el) {
if (MochiKit.Style.computedStyle(el, 'display') == 'block') {
el.style.display = 'none';
} else {
el.style.display = 'block';
}
};
/**
* Toggle visibility for divs with a specific class.
**/
SimpleTest.toggleByClass = function (cls) {
var elems = getElementsByTagAndClassName('div', cls);
MochiKit.Base.map(SimpleTest.toggle, elems);
};
/**
* Shows the report in the browser
**/
SimpleTest.showReport = function() {
var togglePassed = A({'href': '#'}, "Toggle passed tests");
var toggleFailed = A({'href': '#'}, "Toggle failed tests");
togglePassed.onclick = partial(SimpleTest.toggleByClass, 'test_ok');
toggleFailed.onclick = partial(SimpleTest.toggleByClass, 'test_not_ok');
var body = document.getElementsByTagName("body")[0];
var firstChild = body.childNodes[0];
var addNode;
if (firstChild) {
addNode = function (el) {
body.insertBefore(el, firstChild);
};
} else {
addNode = function (el) {
body.appendChild(el)
};
}
addNode(togglePassed);
addNode(SPAN(null, " "));
addNode(toggleFailed);
addNode(SimpleTest.report());
};
/**
* Tells SimpleTest to don't finish the test when the document is loaded,
* useful for asynchronous tests.
*
* When SimpleTest.waitForExplicitFinish is called,
* explicit SimpleTest.finish() is required.
**/
SimpleTest.waitForExplicitFinish = function () {
SimpleTest._stopOnLoad = false;
};
/**
* Talks to the TestRunner if being ran on a iframe and the parent has a
* TestRunner object.
**/
SimpleTest.talkToRunner = function () {
if (parentRunner) {
parentRunner.testFinished(document);
}
};
/**
* Finishes the tests. This is automatically called, except when
* SimpleTest.waitForExplicitFinish() has been invoked.
**/
SimpleTest.finish = function () {
SimpleTest.showReport();
SimpleTest.talkToRunner();
};
addLoadEvent(function() {
if (SimpleTest._stopOnLoad) {
SimpleTest.finish();
}
});
// --------------- Test.Builder/Test.More isDeeply() -----------------
SimpleTest.DNE = {dne: 'Does not exist'};
SimpleTest.LF = "\r\n";
SimpleTest._isRef = function (object) {
var type = typeof(object);
return type == 'object' || type == 'function';
};
SimpleTest._deepCheck = function (e1, e2, stack, seen) {
var ok = false;
// Either they're both references or both not.
var sameRef = !(!SimpleTest._isRef(e1) ^ !SimpleTest._isRef(e2));
if (e1 == null && e2 == null) {
ok = true;
} else if (e1 != null ^ e2 != null) {
ok = false;
} else if (e1 == SimpleTest.DNE ^ e2 == SimpleTest.DNE) {
ok = false;
} else if (sameRef && e1 == e2) {
// Handles primitives and any variables that reference the same
// object, including functions.
ok = true;
} else if (SimpleTest.isa(e1, 'Array') && SimpleTest.isa(e2, 'Array')) {
ok = SimpleTest._eqArray(e1, e2, stack, seen);
} else if (typeof e1 == "object" && typeof e2 == "object") {
ok = SimpleTest._eqAssoc(e1, e2, stack, seen);
} else {
// If we get here, they're not the same (function references must
// always simply rererence the same function).
stack.push({ vals: [e1, e2] });
ok = false;
}
return ok;
};
SimpleTest._eqArray = function (a1, a2, stack, seen) {
// Return if they're the same object.
if (a1 == a2) return true;
// JavaScript objects have no unique identifiers, so we have to store
// references to them all in an array, and then compare the references
// directly. It's slow, but probably won't be much of an issue in
// practice. Start by making a local copy of the array to as to avoid
// confusing a reference seen more than once (such as [a, a]) for a
// circular reference.
for (var j = 0; j < seen.length; j++) {
if (seen[j][0] == a1) {
return seen[j][1] == a2;
}
}
// If we get here, we haven't seen a1 before, so store it with reference
// to a2.
seen.push([ a1, a2 ]);
var ok = true;
// Only examines enumerable attributes. Only works for numeric arrays!
// Associative arrays return 0. So call _eqAssoc() for them, instead.
var max = a1.length > a2.length ? a1.length : a2.length;
if (max == 0) return SimpleTest._eqAssoc(a1, a2, stack, seen);
for (var i = 0; i < max; i++) {
var e1 = i > a1.length - 1 ? SimpleTest.DNE : a1[i];
var e2 = i > a2.length - 1 ? SimpleTest.DNE : a2[i];
stack.push({ type: 'Array', idx: i, vals: [e1, e2] });
if (ok = SimpleTest._deepCheck(e1, e2, stack, seen)) {
stack.pop();
} else {
break;
}
}
return ok;
};
SimpleTest._eqAssoc = function (o1, o2, stack, seen) {
// Return if they're the same object.
if (o1 == o2) return true;
// JavaScript objects have no unique identifiers, so we have to store
// references to them all in an array, and then compare the references
// directly. It's slow, but probably won't be much of an issue in
// practice. Start by making a local copy of the array to as to avoid
// confusing a reference seen more than once (such as [a, a]) for a
// circular reference.
seen = seen.slice(0);
for (var j = 0; j < seen.length; j++) {
if (seen[j][0] == o1) {
return seen[j][1] == o2;
}
}
// If we get here, we haven't seen o1 before, so store it with reference
// to o2.
seen.push([ o1, o2 ]);
// They should be of the same class.
var ok = true;
// Only examines enumerable attributes.
var o1Size = 0; for (var i in o1) o1Size++;
var o2Size = 0; for (var i in o2) o2Size++;
var bigger = o1Size > o2Size ? o1 : o2;
for (var i in bigger) {
var e1 = o1[i] == undefined ? SimpleTest.DNE : o1[i];
var e2 = o2[i] == undefined ? SimpleTest.DNE : o2[i];
stack.push({ type: 'Object', idx: i, vals: [e1, e2] });
if (ok = SimpleTest._deepCheck(e1, e2, stack, seen)) {
stack.pop();
} else {
break;
}
}
return ok;
};
SimpleTest._formatStack = function (stack) {
var variable = '$Foo';
for (var i = 0; i < stack.length; i++) {
var entry = stack[i];
var type = entry['type'];
var idx = entry['idx'];
if (idx != null) {
if (/^\d+$/.test(idx)) {
// Numeric array index.
variable += '[' + idx + ']';
} else {
// Associative array index.
idx = idx.replace("'", "\\'");
variable += "['" + idx + "']";
}
}
}
var vals = stack[stack.length-1]['vals'].slice(0, 2);
var vars = [
variable.replace('$Foo', 'got'),
variable.replace('$Foo', 'expected')
];
var out = "Structures begin differing at:" + SimpleTest.LF;
for (var i = 0; i < vals.length; i++) {
var val = vals[i];
if (val == null) {
val = 'undefined';
} else {
val == SimpleTest.DNE ? "Does not exist" : "'" + val + "'";
}
}
out += vars[0] + ' = ' + vals[0] + SimpleTest.LF;
out += vars[1] + ' = ' + vals[1] + SimpleTest.LF;
return ' ' + out;
};
SimpleTest.isDeeply = function (it, as, name) {
var ok;
// ^ is the XOR operator.
if (SimpleTest._isRef(it) ^ SimpleTest._isRef(as)) {
// One's a reference, one isn't.
ok = false;
} else if (!SimpleTest._isRef(it) && !SimpleTest._isRef(as)) {
// Neither is an object.
ok = SimpleTest.is(it, as, name);
} else {
// We have two objects. Do a deep comparison.
var stack = [], seen = [];
if ( SimpleTest._deepCheck(it, as, stack, seen)) {
ok = SimpleTest.ok(true, name);
} else {
ok = SimpleTest.ok(false, name, SimpleTest._formatStack(stack));
}
}
return ok;
};
SimpleTest.typeOf = function (object) {
var c = Object.prototype.toString.apply(object);
var name = c.substring(8, c.length - 1);
if (name != 'Object') return name;
// It may be a non-core class. Try to extract the class name from
// the constructor function. This may not work in all implementations.
if (/function ([^(\s]+)/.test(Function.toString.call(object.constructor))) {
return RegExp.$1;
}
// No idea. :-(
return name;
};
SimpleTest.isa = function (object, clas) {
return SimpleTest.typeOf(object) == clas;
};
// Global symbols:
var ok = SimpleTest.ok;
var is = SimpleTest.is;
var isnot = SimpleTest.isnot;
var todo = SimpleTest.todo;
var isDeeply = SimpleTest.isDeeply;
var oldOnError = window.onerror;
window.onerror = function (ev) {
is(0, 1, "Error thrown during test: " + ev);
if (oldOnError) {
try {
oldOnError(ev);
} catch (e) {
}
}
if (SimpleTest._stopOnLoad == false) {
// Need to finish() manually here
SimpleTest.finish();
}
}

View File

@ -0,0 +1,28 @@
.test_ok {
color: green;
display: none;
}
.test_not_ok {
color: red;
display: block;
}
.test_ok, .test_not_ok {
border-bottom-width: 2px;
border-bottom-style: solid;
border-bottom-color: black;
}
.all_pass {
background-color: lime;
}
.some_fail {
background-color: red;
}
.tests_report {
border-width: 2px;
border-style: solid;
width: 20em;
}

View File

@ -0,0 +1,55 @@
#
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is
# Mozilla Foundation.
# Portions created by the Initial Developer are Copyright (C) 2007
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
#
# Alternatively, the contents of this file may be used under the terms of
# either of the GNU General Public License Version 2 or later (the "GPL"),
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
DEPTH = ../../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
relativesrcdir = dom/tests/mochitest/ajax/prototype
include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk
_TEST_FILES = \
test_Prototype.html \
manifest.json \
dist \
test \
$(NULL)
libs:: $(_TEST_FILES)
$(INSTALL) $^ $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
{testcases:["test/unit/ajax.html","test/unit/array.html","test/unit/base.html","test/unit/dom.html","test/unit/element_mixins.html","test/unit/enumerable.html","test/unit/form.html","test/unit/hash.html","test/unit/position.html","test/unit/range.html","test/unit/selector.html","test/unit/string.html","test/unit/unit_tests.html"]}

View File

@ -0,0 +1,553 @@
// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
// (c) 2005 Jon Tirsen (http://www.tirsen.com)
// (c) 2005 Michael Schuerig (http://www.schuerig.de/michael/)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// experimental, Firefox-only
Event.simulateMouse = function(element, eventName) {
var options = Object.extend({
pointerX: 0,
pointerY: 0,
buttons: 0
}, arguments[2] || {});
var oEvent = document.createEvent("MouseEvents");
oEvent.initMouseEvent(eventName, true, true, document.defaultView,
options.buttons, options.pointerX, options.pointerY, options.pointerX, options.pointerY,
false, false, false, false, 0, $(element));
if(this.mark) Element.remove(this.mark);
this.mark = document.createElement('div');
this.mark.appendChild(document.createTextNode(" "));
document.body.appendChild(this.mark);
this.mark.style.position = 'absolute';
this.mark.style.top = options.pointerY + "px";
this.mark.style.left = options.pointerX + "px";
this.mark.style.width = "5px";
this.mark.style.height = "5px;";
this.mark.style.borderTop = "1px solid red;"
this.mark.style.borderLeft = "1px solid red;"
if(this.step)
alert('['+new Date().getTime().toString()+'] '+eventName+'/'+Test.Unit.inspect(options));
$(element).dispatchEvent(oEvent);
};
// Note: Due to a fix in Firefox 1.0.5/6 that probably fixed "too much", this doesn't work in 1.0.6 or DP2.
// You need to downgrade to 1.0.4 for now to get this working
// See https://bugzilla.mozilla.org/show_bug.cgi?id=289940 for the fix that fixed too much
Event.simulateKey = function(element, eventName) {
var options = Object.extend({
ctrlKey: false,
altKey: false,
shiftKey: false,
metaKey: false,
keyCode: 0,
charCode: 0
}, arguments[2] || {});
var oEvent = document.createEvent("KeyEvents");
oEvent.initKeyEvent(eventName, true, true, window,
options.ctrlKey, options.altKey, options.shiftKey, options.metaKey,
options.keyCode, options.charCode );
$(element).dispatchEvent(oEvent);
};
Event.simulateKeys = function(element, command) {
for(var i=0; i<command.length; i++) {
Event.simulateKey(element,'keypress',{charCode:command.charCodeAt(i)});
}
};
var Test = {}
Test.Unit = {};
// security exception workaround
Test.Unit.inspect = Object.inspect;
Test.Unit.Logger = Class.create();
Test.Unit.Logger.prototype = {
initialize: function(log) {
this.log = $(log);
if (this.log) {
this._createLogTable();
}
},
start: function(testName) {
if (!this.log) return;
this.testName = testName;
this.lastLogLine = document.createElement('tr');
this.statusCell = document.createElement('td');
this.nameCell = document.createElement('td');
this.nameCell.appendChild(document.createTextNode(testName));
this.messageCell = document.createElement('td');
this.lastLogLine.appendChild(this.statusCell);
this.lastLogLine.appendChild(this.nameCell);
this.lastLogLine.appendChild(this.messageCell);
this.loglines.appendChild(this.lastLogLine);
},
finish: function(status, summary) {
if (!this.log) return;
this.lastLogLine.className = status;
this.statusCell.innerHTML = status;
this.messageCell.innerHTML = this._toHTML(summary);
},
message: function(message) {
if (!this.log) return;
this.messageCell.innerHTML = this._toHTML(message);
},
summary: function(summary) {
if (!this.log) return;
this.logsummary.innerHTML = this._toHTML(summary);
},
_createLogTable: function() {
this.log.innerHTML =
'<div id="logsummary"></div>' +
'<table id="logtable">' +
'<thead><tr><th>Status</th><th>Test</th><th>Message</th></tr></thead>' +
'<tbody id="loglines"></tbody>' +
'</table>';
this.logsummary = $('logsummary')
this.loglines = $('loglines');
},
_toHTML: function(txt) {
return txt.escapeHTML().replace(/\n/g,"<br/>");
}
}
Test.Unit.Runner = Class.create();
Test.Unit.Runner.prototype = {
initialize: function(testcases) {
this.options = Object.extend({
testLog: 'testlog'
}, arguments[1] || {});
this.options.resultsURL = this.parseResultsURLQueryParameter();
if (this.options.testLog) {
this.options.testLog = $(this.options.testLog) || null;
}
if(this.options.tests) {
this.tests = [];
for(var i = 0; i < this.options.tests.length; i++) {
if(/^test/.test(this.options.tests[i])) {
this.tests.push(new Test.Unit.Testcase(this.options.tests[i], testcases[this.options.tests[i]], testcases["setup"], testcases["teardown"]));
}
}
} else {
if (this.options.test) {
this.tests = [new Test.Unit.Testcase(this.options.test, testcases[this.options.test], testcases["setup"], testcases["teardown"])];
} else {
this.tests = [];
for(var testcase in testcases) {
if(/^test/.test(testcase)) {
this.tests.push(new Test.Unit.Testcase(testcase, testcases[testcase], testcases["setup"], testcases["teardown"]));
}
}
}
}
this.currentTest = 0;
this.logger = new Test.Unit.Logger(this.options.testLog);
setTimeout(this.runTests.bind(this), 1000);
},
parseResultsURLQueryParameter: function() {
return window.location.search.parseQuery()["resultsURL"];
},
// Returns:
// "ERROR" if there was an error,
// "FAILURE" if there was a failure, or
// "SUCCESS" if there was neither
getResult: function() {
var hasFailure = false;
for(var i=0;i<this.tests.length;i++) {
if (this.tests[i].errors > 0) {
return "ERROR";
}
if (this.tests[i].failures > 0) {
hasFailure = true;
}
}
if (hasFailure) {
return "FAILURE";
} else {
return "SUCCESS";
}
},
postResults: function() {
if (this.options.resultsURL) {
new Ajax.Request(this.options.resultsURL,
{ method: 'get', parameters: 'result=' + this.getResult(), asynchronous: false });
}
},
runTests: function() {
var test = this.tests[this.currentTest];
if (!test) {
// finished!
this.postResults();
this.logger.summary(this.summary());
return;
}
if(!test.isWaiting) {
this.logger.start(test.name);
}
test.run();
if(test.isWaiting) {
this.logger.message("Waiting for " + test.timeToWait + "ms");
setTimeout(this.runTests.bind(this), test.timeToWait || 1000);
} else {
this.logger.finish(test.status(), test.summary());
var actionButtons = test.actionButtons();
if (actionButtons)
$(this.logger.lastLogLine).down('td', 2).appendChild(actionButtons);
this.currentTest++;
// tail recursive, hopefully the browser will skip the stackframe
this.runTests();
}
},
summary: function() {
var assertions = 0;
var failures = 0;
var errors = 0;
var messages = [];
for(var i=0;i<this.tests.length;i++) {
assertions += this.tests[i].assertions;
failures += this.tests[i].failures;
errors += this.tests[i].errors;
}
return (
this.tests.length + " tests, " +
assertions + " assertions, " +
failures + " failures, " +
errors + " errors");
}
}
Test.Unit.Assertions = Class.create();
Test.Unit.Assertions.prototype = {
initialize: function() {
this.assertions = 0;
this.failures = 0;
this.errors = 0;
this.messages = [];
this.actions = {};
},
summary: function() {
return (
this.assertions + " assertions, " +
this.failures + " failures, " +
this.errors + " errors" + "\n" +
this.messages.join("\n"));
},
actionButtons: function() {
if (!Object.keys(this.actions).any()) return false;
var div = $(document.createElement("div"));
div.addClassName("action_buttons");
for (var title in this.actions) {
var button = $(document.createElement("input"));
button.value = title;
button.type = "button";
button.observe("click", this.actions[title]);
div.appendChild(button);
}
return div;
},
pass: function() {
this.assertions++;
},
fail: function(message) {
this.failures++;
this.messages.push("Failure: " + message);
},
info: function(message) {
this.messages.push("Info: " + message);
},
error: function(error, test) {
this.errors++;
this.actions['retry with throw'] = function() { test.run(true) };
this.messages.push(error.name + ": "+ error.message + "(" + Test.Unit.inspect(error) + ")");
},
status: function() {
if (this.failures > 0) return 'failed';
if (this.errors > 0) return 'error';
return 'passed';
},
assert: function(expression) {
var message = arguments[1] || 'assert: got "' + Test.Unit.inspect(expression) + '"';
try { expression ? this.pass() :
this.fail(message); }
catch(e) { this.error(e); }
},
assertEqual: function(expected, actual) {
var message = arguments[2] || "assertEqual";
try { (expected == actual) ? this.pass() :
this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
'", actual "' + Test.Unit.inspect(actual) + '"'); }
catch(e) { this.error(e); }
},
assertNotEqual: function(expected, actual) {
var message = arguments[2] || "assertNotEqual";
try { (expected != actual) ? this.pass() :
this.fail(message + ': got "' + Test.Unit.inspect(actual) + '"'); }
catch(e) { this.error(e); }
},
assertEnumEqual: function(expected, actual) {
var message = arguments[2] || "assertEnumEqual";
expected = $A(expected);
actual = $A(actual);
try { expected.length == actual.length &&
expected.zip(actual).all(function(pair) { return pair[0] == pair[1] }) ?
this.pass() : this.fail(message + ': expected ' + Test.Unit.inspect(expected) +
', actual ' + Test.Unit.inspect(actual)); }
catch(e) { this.error(e); }
},
assertEnumNotEqual: function(expected, actual) {
var message = arguments[2] || "assertEnumEqual";
expected = $A(expected);
actual = $A(actual);
try { expected.length != actual.length ||
expected.zip(actual).any(function(pair) { return pair[0] != pair[1] }) ?
this.pass() : this.fail(message + ': ' + Test.Unit.inspect(expected) +
' was the same as ' + Test.Unit.inspect(actual)); }
catch(e) { this.error(e); }
},
assertHashEqual: function(expected, actual) {
var message = arguments[2] || "assertHashEqual";
expected = $H(expected);
actual = $H(actual);
var expected_array = expected.toArray().sort(), actual_array = actual.toArray().sort();
// from now we recursively zip & compare nested arrays
try { expected_array.length == actual_array.length &&
expected_array.zip(actual_array).all(function(pair) {
return pair.all(function(i){ return i && i.constructor == Array }) ?
pair[0].zip(pair[1]).all(arguments.callee) : pair[0] == pair[1];
}) ?
this.pass() : this.fail(message + ': expected ' + Test.Unit.inspect(expected) +
', actual ' + Test.Unit.inspect(actual)); }
catch(e) { this.error(e); }
},
assertHashNotEqual: function(expected, actual) {
var message = arguments[2] || "assertHashEqual";
expected = $H(expected);
actual = $H(actual);
var expected_array = expected.toArray().sort(), actual_array = actual.toArray().sort();
// from now we recursively zip & compare nested arrays
try { !(expected_array.length == actual_array.length &&
expected_array.zip(actual_array).all(function(pair) {
return pair.all(function(i){ return i && i.constructor == Array }) ?
pair[0].zip(pair[1]).all(arguments.callee) : pair[0] == pair[1];
})) ?
this.pass() : this.fail(message + ': ' + Test.Unit.inspect(expected) +
' was the same as ' + Test.Unit.inspect(actual)); }
catch(e) { this.error(e); }
},
assertIdentical: function(expected, actual) {
var message = arguments[2] || "assertIdentical";
try { (expected === actual) ? this.pass() :
this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
'", actual "' + Test.Unit.inspect(actual) + '"'); }
catch(e) { this.error(e); }
},
assertNotIdentical: function(expected, actual) {
var message = arguments[2] || "assertNotIdentical";
try { !(expected === actual) ? this.pass() :
this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
'", actual "' + Test.Unit.inspect(actual) + '"'); }
catch(e) { this.error(e); }
},
assertNull: function(obj) {
var message = arguments[1] || 'assertNull'
try { (obj===null) ? this.pass() :
this.fail(message + ': got "' + Test.Unit.inspect(obj) + '"'); }
catch(e) { this.error(e); }
},
assertNotNull: function(obj) {
var message = arguments[1] || 'assertNotNull'
try { (obj!==null) ? this.pass() :
this.fail(message + ': got "' + Test.Unit.inspect(obj) + '"'); }
catch(e) { this.error(e); }
},
assertUndefined: function(obj) {
var message = arguments[1] || 'assertUndefined'
try { (typeof obj=="undefined") ? this.pass() :
this.fail(message + ': got "' + Test.Unit.inspect(obj) + '"'); }
catch(e) { this.error(e); }
},
assertNotUndefined: function(obj) {
var message = arguments[1] || 'assertNotUndefined'
try { (typeof obj != "undefined") ? this.pass() :
this.fail(message + ': got "' + Test.Unit.inspect(obj) + '"'); }
catch(e) { this.error(e); }
},
assertNullOrUndefined: function(obj){
var message = arguments[1] || 'assertNullOrUndefined'
try { (obj==null) ? this.pass() :
this.fail(message + ': got "' + Test.Unit.inspect(obj) + '"'); }
catch(e) { this.error(e); }
},
assertNotNullOrUndefined: function(obj){
var message = arguments[1] || 'assertNotNullOrUndefined'
try { (obj!=null) ? this.pass() :
this.fail(message + ': got "' + Test.Unit.inspect(obj) + '"'); }
catch(e) { this.error(e); }
},
assertMatch: function(expected, actual) {
var message = arguments[2] || 'assertMatch';
var regex = new RegExp(expected);
try { regex.exec(actual) ? this.pass() :
this.fail(message + ' : regex: "' + Test.Unit.inspect(expected) + ' did not match: ' + Test.Unit.inspect(actual) + '"'); }
catch(e) { this.error(e); }
},
assertNoMatch: function(expected, actual) {
var message = arguments[2] || 'assertMatch';
var regex = new RegExp(expected);
try { !regex.exec(actual) ? this.pass() :
this.fail(message + ' : regex: "' + Test.Unit.inspect(expected) + ' matched: ' + Test.Unit.inspect(actual) + '"'); }
catch(e) { this.error(e); }
},
assertHidden: function(element) {
var message = arguments[1] || 'assertHidden';
this.assertEqual("none", element.style.display, message);
},
assertInstanceOf: function(expected, actual) {
var message = arguments[2] || 'assertInstanceOf';
try {
(actual instanceof expected) ? this.pass() :
this.fail(message + ": object was not an instance of the expected type"); }
catch(e) { this.error(e); }
},
assertNotInstanceOf: function(expected, actual) {
var message = arguments[2] || 'assertNotInstanceOf';
try {
!(actual instanceof expected) ? this.pass() :
this.fail(message + ": object was an instance of the not expected type"); }
catch(e) { this.error(e); }
},
assertRespondsTo: function(method, obj) {
var message = arguments[2] || 'assertRespondsTo';
try {
(obj[method] && typeof obj[method] == 'function') ? this.pass() :
this.fail(message + ": object doesn't respond to [" + method + "]"); }
catch(e) { this.error(e); }
},
assertRaise: function(exceptionName, method) {
var message = arguments[2] || 'assertRaise';
try {
method();
this.fail(message + ": exception expected but none was raised"); }
catch(e) {
(e.name==exceptionName) ? this.pass() : this.error(e);
}
},
assertNothingRaised: function(method) {
var message = arguments[1] || 'assertNothingRaised';
try {
method();
this.pass();
} catch (e) {
this.fail(message + ": " + e.toString());
}
},
_isVisible: function(element) {
element = $(element);
if(!element.parentNode) return true;
this.assertNotNull(element);
if(element.style && Element.getStyle(element, 'display') == 'none')
return false;
return this._isVisible(element.parentNode);
},
assertNotVisible: function(element) {
this.assert(!this._isVisible(element), Test.Unit.inspect(element) + " was not hidden and didn't have a hidden parent either. " + ("" || arguments[1]));
},
assertVisible: function(element) {
this.assert(this._isVisible(element), Test.Unit.inspect(element) + " was not visible. " + ("" || arguments[1]));
},
assertElementsMatch: function() {
var expressions = $A(arguments), elements = $A(expressions.shift());
if (elements.length != expressions.length) {
this.fail('assertElementsMatch: size mismatch: ' + elements.length + ' elements, ' + expressions.length + ' expressions');
return false;
}
elements.zip(expressions).all(function(pair, index) {
var element = $(pair.first()), expression = pair.last();
if (element.match(expression)) return true;
this.fail('assertElementsMatch: (in index ' + index + ') expected ' + expression.inspect() + ' but got ' + element.inspect());
}.bind(this)) && this.pass();
},
assertElementMatches: function(element, expression) {
this.assertElementsMatch([element], expression);
},
benchmark: function(operation, iterations) {
var startAt = new Date();
(iterations || 1).times(operation);
var timeTaken = ((new Date())-startAt);
this.info((arguments[2] || 'Operation') + ' finished ' +
iterations + ' iterations in ' + (timeTaken/1000)+'s' );
return timeTaken;
}
}
Test.Unit.Testcase = Class.create();
Object.extend(Object.extend(Test.Unit.Testcase.prototype, Test.Unit.Assertions.prototype), {
initialize: function(name, test, setup, teardown) {
Test.Unit.Assertions.prototype.initialize.bind(this)();
this.name = name;
this.test = test || function() {};
this.setup = setup || function() {};
this.teardown = teardown || function() {};
this.isWaiting = false;
this.timeToWait = 1000;
},
wait: function(time, nextPart) {
this.isWaiting = true;
this.test = nextPart;
this.timeToWait = time;
},
run: function(rethrow) {
try {
try {
if (!this.isWaiting) this.setup.bind(this)();
this.isWaiting = false;
this.test.bind(this)();
} finally {
if(!this.isWaiting) {
this.teardown.bind(this)();
}
}
}
catch(e) {
if (rethrow) throw e;
this.error(e, this);
}
}
});
if ( parent.SimpleTest && parent.runAJAXTest ) (function(){
var finish = Test.Unit.Logger.prototype.finish;
Test.Unit.Logger.prototype.finish = function(status,summary){
parent.SimpleTest.ok( status == "passed", this.testName, summary );
return finish.apply( this, arguments );
};
// Intentionally overwrite (to stop the Ajax request)
Test.Unit.Runner.prototype.postResults = parent.runAJAXTest;
})();

View File

@ -0,0 +1,49 @@
body, div, p, h1, h2, h3, ul, ol, span, a, table, td, form, img, li {
font-family: sans-serif;
}
body {
font-size:0.8em;
}
#log {
padding-bottom: 1em;
border-bottom: 2px solid #000;
margin-bottom: 2em;
}
#logsummary {
margin-bottom: 1em;
padding: 1ex;
border: 1px solid #000;
font-weight: bold;
}
#logtable {
width:100%;
border-collapse: collapse;
border: 1px dotted #666;
}
#logtable td, #logtable th {
text-align: left;
padding: 3px 8px;
border: 1px dotted #666;
}
#logtable .passed {
background-color: #cfc;
}
#logtable .failed, #logtable .error {
background-color: #fcc;
}
#logtable td div.action_buttons {
display: inline;
}
#logtable td div.action_buttons input {
margin: 0 5px;
font-size: 10px;
}

View File

@ -0,0 +1,174 @@
<!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" xml:lang="en" lang="en">
<head>
<title>Prototype Unit test file</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script src="../../dist/prototype.js" type="text/javascript"></script>
<script src="../lib/unittest.js" type="text/javascript"></script>
<link rel="stylesheet" href="../test.css" type="text/css" />
<style type="text/css" media="screen">
/* <![CDATA[ */
#testcss1 { font-size:11px; color: #f00; }
#testcss2 { font-size:12px; color: #0f0; display: none; }
/* ]]> */
</style>
</head>
<body>
<h1>Prototype Unit test file</h1>
<p>
Test of utility functions in ajax.js
</p>
<!-- Log output -->
<div id="testlog"> </div>
<div id="content"></div>
<div id="content2" style="color:red"></div>
<!-- Tests follow -->
<script type="text/javascript" language="javascript" charset="utf-8">
// <![CDATA[
var responderCounter = 0;
new Test.Unit.Runner({
setup: function(){
$('content').update('');
$('content2').update('');
},
teardown: function(){
// hack to cleanup responders
Ajax.Responders.responders = [Ajax.Responders.responders[0]];
},
testSynchronousRequest: function() {with(this) {
assertEqual("", $("content").innerHTML);
assertEqual(0, Ajax.activeRequestCount);
new Ajax.Request("fixtures/hello.js", {
asynchronous: false,
method: 'GET',
onComplete: function(response) { eval(response.responseText) }
});
assertEqual(0, Ajax.activeRequestCount);
var h2 = $("content").firstChild;
assertEqual("Hello world!", h2.innerHTML);
}},
testAsynchronousRequest: function() {with(this) {
assertEqual("", $("content").innerHTML);
new Ajax.Request("fixtures/hello.js", {
asynchronous: true,
method: 'get',
onComplete: function(response) { eval(response.responseText) }
});
wait(1000,function(){
var h2 = $("content").firstChild;
assertEqual("Hello world!", h2.innerHTML);
});
}},
testUpdater: function() {with(this) {
assertEqual("", $("content").innerHTML);
new Ajax.Updater("content", "fixtures/content.html", { method:'get' });
// lowercase comparison because of MSIE which presents HTML tags in uppercase
var sentence = ("Pack my box with <em>five dozen</em> liquor jugs! " +
"Oh, how <strong>quickly</strong> daft jumping zebras vex...").toLowerCase();
wait(1000,function(){
assertEqual(sentence, $("content").innerHTML.strip().toLowerCase());
$('content').update('');
assertEqual("", $("content").innerHTML);
new Ajax.Updater({ success:"content", failure:"content2" },
"fixtures/content.html", { method:'get', parameters:{ pet:'monkey' } });
new Ajax.Updater("", "fixtures/content.html", { method:'get', parameters:"pet=monkey" });
wait(1000,function(){
assertEqual(sentence, $("content").innerHTML.strip().toLowerCase());
assertEqual("", $("content2").innerHTML);
});
});
}},
testResponders: function(){with(this) {
// check for internal responder
assertEqual(1, Ajax.Responders.responders.length);
var dummyResponder = {
onComplete: function(req){ /* dummy */ }
};
Ajax.Responders.register(dummyResponder);
assertEqual(2, Ajax.Responders.responders.length);
// don't add twice
Ajax.Responders.register(dummyResponder);
assertEqual(2, Ajax.Responders.responders.length);
Ajax.Responders.unregister(dummyResponder);
assertEqual(1, Ajax.Responders.responders.length);
var responder = {
onCreate: function(req){ responderCounter++ },
onLoading: function(req){ responderCounter++ },
onComplete: function(req){ responderCounter++ }
};
Ajax.Responders.register(responder);
assertEqual(0, responderCounter);
assertEqual(0, Ajax.activeRequestCount);
new Ajax.Request("fixtures/content.html", { method:'get', parameters:"pet=monkey" });
assertEqual(1, responderCounter);
assertEqual(1, Ajax.activeRequestCount);
wait(1000,function(){
assertEqual(3, responderCounter);
assertEqual(0, Ajax.activeRequestCount);
});
}},
testEvalResponseShouldBeCalledBeforeOnComplete: function() {with(this) {
assertEqual("", $("content").innerHTML);
assertEqual(0, Ajax.activeRequestCount);
new Ajax.Request("fixtures/hello.js", {
asynchronous: false,
method: 'GET',
onComplete: function(response) { assertNotEqual("", $("content").innerHTML) }
});
assertEqual(0, Ajax.activeRequestCount);
var h2 = $("content").firstChild;
assertEqual("Hello world!", h2.innerHTML);
}},
testContentTypeSetForSimulatedVerbs: function() {with(this) {
var isRunningFromRake = true;
new Ajax.Request('/content-type', {
method: 'put',
contentType: 'application/bogus',
asynchronous: false,
onFailure: function() {
isRunningFromRake = false;
},
onComplete: function(response) {
if (isRunningFromRake)
assertEqual('application/bogus; charset=UTF-8', response.responseText);
}
});
}}
}, 'testlog');
// ]]>
</script>
</body>
</html>

View File

@ -0,0 +1,178 @@
<!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" xml:lang="en" lang="en">
<head>
<title>Prototype Unit test file</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script src="../../dist/prototype.js" type="text/javascript"></script>
<script src="../lib/unittest.js" type="text/javascript"></script>
<link rel="stylesheet" href="../test.css" type="text/css" />
<style type="text/css" media="screen">
/* <![CDATA[ */
#testcss1 { font-size:11px; color: #f00; }
#testcss2 { font-size:12px; color: #0f0; display: none; }
/* ]]> */
</style>
</head>
<body>
<h1>Prototype Unit test file</h1>
<p>
Test of the Array.prototype extensions
</p>
<!-- Log output -->
<div id="testlog"> </div>
<div id="test_node">22<span id="span_1"></span><span id="span_2"></span></div>
<!-- Tests follow -->
<script type="text/javascript" language="javascript" charset="utf-8">
// <![CDATA[
var globalArgsTest = 'nothing to see here';
new Test.Unit.Runner({
testToArrayOnArguments: function(){ with(this) {
function toArrayOnArguments(){
globalArgsTest = $A(arguments);
}
toArrayOnArguments();
assertEnumEqual([], globalArgsTest);
toArrayOnArguments('foo');
assertEnumEqual(['foo'], globalArgsTest);
toArrayOnArguments('foo','bar');
assertEnumEqual(['foo','bar'], globalArgsTest);
}},
testToArrayOnNodeList: function(){ with(this) {
// direct HTML
assertEqual(3, $A($('test_node').childNodes).length);
// DOM
var element = document.createElement('div');
element.appendChild(document.createTextNode('22'));
(2).times(function(){ element.appendChild(document.createElement('span')) });
assertEqual(3, $A(element.childNodes).length);
// HTML String
element = document.createElement('div');
$(element).update('22<span></span><span></span');
assertEqual(3, $A(element.childNodes).length);
}},
testClear: function(){ with(this) {
assertEnumEqual([], [].clear());
assertEnumEqual([], [1].clear());
assertEnumEqual([], [1,2].clear());
}},
testClone: function(){ with(this) {
assertEnumEqual([], [].clone());
assertEnumEqual([1], [1].clone());
assertEnumEqual([1,2], [1,2].clone());
assertEnumEqual([0,1,2], [0,1,2].clone());
var a = [0,1,2];
var b = a;
assertIdentical(a, b);
b = a.clone();
assertNotIdentical(a, b);
}},
testFirst: function(){ with(this) {
assertUndefined([].first());
assertEqual(1, [1].first());
assertEqual(1, [1,2].first());
}},
testLast: function(){ with(this) {
assertUndefined([].last());
assertEqual(1, [1].last());
assertEqual(2, [1,2].last());
}},
testCompact: function(){ with(this) {
assertEnumEqual([], [].compact());
assertEnumEqual([1,2,3], [1,2,3].compact());
assertEnumEqual([0,1,2,3], [0,null,1,2,undefined,3].compact());
assertEnumEqual([1,2,3], [null,1,2,3,null].compact());
}},
testFlatten: function(){ with(this) {
assertEnumEqual([], [].flatten());
assertEnumEqual([1,2,3], [1,2,3].flatten());
assertEnumEqual([1,2,3], [1,[[[2,3]]]].flatten());
assertEnumEqual([1,2,3], [[1],[2],[3]].flatten());
assertEnumEqual([1,2,3], [[[[[[[1]]]]]],2,3].flatten());
}},
testIndexOf: function(){ with(this) {
assertEqual(-1, [].indexOf(1));
assertEqual(-1, [0].indexOf(1));
assertEqual(0, [1].indexOf(1));
assertEqual(1, [0,1,2].indexOf(1));
}},
testInspect: function(){ with(this) {
assertEqual('[]',[].inspect());
assertEqual('[1]',[1].inspect());
assertEqual('[\'a\']',['a'].inspect());
assertEqual('[\'a\', 1]',['a',1].inspect());
}},
testToJSON: function(){ with(this) {
assertEqual('[]', [].toJSON());
assertEqual('[\"a\"]', ['a'].toJSON());
assertEqual('[\"a\",1]', ['a', 1].toJSON());
assertEqual('[\"a\",{\"b\":null}]', ['a', {'b': null}].toJSON());
}},
testReduce: function(){ with(this) {
assertUndefined([].reduce());
assertNull([null].reduce());
assertEqual(1, [1].reduce());
assertEnumEqual([1,2,3], [1,2,3].reduce());
assertEnumEqual([1,null,3], [1,null,3].reduce());
}},
testReverse: function(){ with(this) {
assertEnumEqual([], [].reverse());
assertEnumEqual([1], [1].reverse());
assertEnumEqual([2,1], [1,2].reverse());
assertEnumEqual([3,2,1], [1,2,3].reverse());
}},
testSize: function(){ with(this) {
assertEqual(4, [0, 1, 2, 3].size());
assertEqual(0, [].size());
}},
testUniq: function(){ with(this) {
assertEnumEqual([1], [1, 1, 1].uniq());
assertEnumEqual([1], [1].uniq());
assertEnumEqual([], [].uniq());
assertEnumEqual([0, 1, 2, 3], [0, 1, 2, 2, 3, 0, 2].uniq());
assertEnumEqual([0, 1, 2, 3], [0, 0, 1, 1, 2, 3, 3, 3].uniq(true));
}},
testWithout: function(){ with(this) {
assertEnumEqual([], [].without(0));
assertEnumEqual([], [0].without(0));
assertEnumEqual([1], [0,1].without(0));
assertEnumEqual([1,2], [0,1,2].without(0));
}},
test$w: function(){ with(this) {
assertEnumEqual(['a', 'b', 'c', 'd'], $w('a b c d'));
assertEnumEqual([], $w(' '));
assertEnumEqual(['a'], $w('a'));
assertEnumEqual(['a'], $w('a '));
assertEnumEqual(['a'], $w(' a'));
assertEnumEqual(['a', 'b', 'c', 'd'], $w(' a b\nc\t\nd\n'));
}}
}, 'testlog');
// ]]>
</script>
</body>
</html>

View File

@ -0,0 +1,234 @@
<!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" xml:lang="en" lang="en">
<head>
<title>Prototype Unit test file</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script src="../../dist/prototype.js" type="text/javascript"></script>
<script src="../lib/unittest.js" type="text/javascript"></script>
<link rel="stylesheet" href="../test.css" type="text/css" />
<style type="text/css" media="screen">
/* <![CDATA[ */
#testcss1 { font-size:11px; color: #f00; }
#testcss2 { font-size:12px; color: #0f0; display: none; }
/* ]]> */
</style>
</head>
<body>
<h1>Prototype Unit test file</h1>
<p>
Test of utility functions in base.js
</p>
<!-- Log output -->
<div id="testlog"> </div>
<div id="test"></div>
<!-- Tests follow -->
<script type="text/javascript" language="javascript" charset="utf-8">
// <![CDATA[
var Person = function(name){
this.name = name;
};
Person.prototype.toJSON = function() {
return '-' + this.name;
};
var peEventCount = 0;
// peEventFired will stop the PeriodicalExecuter after 3 callbacks
function peEventFired(pe) {
if (++peEventCount>2) {
pe.stop();
}
}
var arg1 = 1;
var arg2 = 2;
var arg3 = 3;
function TestObj(){}
TestObj.prototype.assertingEventHandler =
function( event, assertEvent, assert1, assert2, assert3, a1, a2, a3 ){
assertEvent(event);
assert1(a1);
assert2(a2);
assert3(a3);
}
var globalBindTest = null;
new Test.Unit.Runner({
testFunctionBind: function() { with(this) {
function methodWithoutArguments(){
globalBindTest = this.hi;
}
function methodWithArguments(){
globalBindTest = this.hi + ',' + $A(arguments).join(',');
}
function methodWithBindArguments(){
globalBindTest = this.hi + ',' + $A(arguments).join(',');
}
function methodWithBindArgumentsAndArguments(){
globalBindTest = this.hi + ',' + $A(arguments).join(',');
}
methodWithoutArguments.bind({hi:'without'})();
assertEqual('without', globalBindTest);
methodWithArguments.bind({hi:'with'})('arg1','arg2');
assertEqual('with,arg1,arg2', globalBindTest);
methodWithBindArguments.bind({hi:'withBindArgs'},'arg1','arg2')();
assertEqual('withBindArgs,arg1,arg2', globalBindTest);
methodWithBindArgumentsAndArguments.bind({hi:'withBindArgsAndArgs'},'arg1','arg2')('arg3','arg4');
assertEqual('withBindArgsAndArgs,arg1,arg2,arg3,arg4', globalBindTest);
}},
testObjectInspect: function() { with(this) {
assertEqual('undefined', Object.inspect());
assertEqual('undefined', Object.inspect(undefined));
assertEqual('null', Object.inspect(null));
assertEqual("'foo\\\\b\\\'ar'", Object.inspect('foo\\b\'ar'));
assertEqual('[]', Object.inspect([]));
}},
testObjectToJSON: function() { with(this) {
assertUndefined(Object.toJSON(undefined));
assertUndefined(Object.toJSON(Prototype.K));
assertEqual('\"\"', Object.toJSON(''));
assertEqual('[]', Object.toJSON([]));
assertEqual('[\"a\"]', Object.toJSON(['a']));
assertEqual('[\"a\",1]', Object.toJSON(['a', 1]));
assertEqual('[\"a\",{\"b\":null}]', Object.toJSON(['a', {'b': null}]));
assertEqual('{\"a\":\"hello!\"}', Object.toJSON({a: 'hello!'}));
assertEqual('{}', Object.toJSON({}));
assertEqual('{}', Object.toJSON({a: undefined, b: undefined, c: Prototype.K}));
assertEqual('{\"b\":[false,true],\"c\":{\"a\":\"hello!\"}}',
Object.toJSON({'b': [undefined, false, true, undefined], c: {a: 'hello!'}}));
assertEqual('{\"b\":[false,true],\"c\":{\"a\":\"hello!\"}}',
Object.toJSON($H({'b': [undefined, false, true, undefined], c: {a: 'hello!'}})));
assertEqual('true', Object.toJSON(true));
assertEqual('false', Object.toJSON(false));
assertEqual('null', Object.toJSON(null));
var sam = new Person('sam');
assertEqual('-sam', Object.toJSON(sam));
assertEqual('-sam', sam.toJSON());
var element = $('test');
assertUndefined(Object.toJSON(element));
element.toJSON = function(){return 'I\'m a div with id test'};
assertEqual('I\'m a div with id test', Object.toJSON(element));
}},
// sanity check
testDoesntExtendObjectPrototype: function() {with(this) {
// for-in is supported with objects
var iterations = 0, obj = { a: 1, b: 2, c: 3 };
for(property in obj) iterations++;
assertEqual(3, iterations);
// for-in is not supported with arrays
iterations = 0;
var arr = [1,2,3];
for(property in arr) iterations++;
assert(iterations > 3);
}},
testPeriodicalExecuterStop: function() {with(this) {
new PeriodicalExecuter(peEventFired, 0.1);
wait(1000, function() {
assertEqual(3, peEventCount);
});
}},
testBindAsEventListener: function() {
for( var i = 0; i < 10; ++i ){
var div = document.createElement('div');
div.setAttribute('id','test-'+i);
document.body.appendChild(div);
var tobj = new TestObj();
var eventTest = {test:true};
var call = tobj.assertingEventHandler.bindAsEventListener(tobj,
this.assertEqual.bind(this,eventTest),
this.assertEqual.bind(this,arg1),
this.assertEqual.bind(this,arg2),
this.assertEqual.bind(this,arg3), arg1, arg2, arg3 );
call(eventTest);
}
},
testNumberToColorPart: function() {with(this) {
assertEqual('00', (0).toColorPart());
assertEqual('0a', (10).toColorPart());
assertEqual('ff', (255).toColorPart());
}},
testNumberToPaddedString: function() {with(this) {
assertEqual('00', (0).toPaddedString(2, 16));
assertEqual('0a', (10).toPaddedString(2, 16));
assertEqual('ff', (255).toPaddedString(2, 16));
assertEqual('000', (0).toPaddedString(3));
assertEqual('010', (10).toPaddedString(3));
assertEqual('100', (100).toPaddedString(3));
assertEqual('1000', (1000).toPaddedString(3));
}},
testNumberToJSON: function() {with(this) {
assertEqual('null', Number.NaN.toJSON());
assertEqual('0', (0).toJSON());
assertEqual('-293', (-293).toJSON());
}},
testDateToJSON: function() {with(this) {
assertEqual('\"1969-12-31T19:00:00\"', new Date(1969, 11, 31, 19).toJSON());
}},
testBrowserDetection: function() {with(this) {
var results = $H(Prototype.Browser).map(function(engine){
return engine;
}).partition(function(engine){
return engine[1] === true
});
var trues = results[0], falses = results[1];
info('User agent string is: ' + navigator.userAgent);
assert(trues.size() == 0 || trues.size() == 1,
'There should be only one or no browser detected.');
// we should have definite trues or falses here
trues.each(function(result){
assert(result[1] === true);
});
falses.each(function(result){
assert(result[1] === false);
});
if(navigator.userAgent.indexOf('AppleWebKit/') > -1) {
info('Running on WebKit');
assert(Prototype.Browser.WebKit);
}
if(!!window.opera) {
info('Running on Opera');
assert(Prototype.Browser.Opera);
}
if(!!(window.attachEvent && !window.opera)) {
info('Running on IE');
assert(Prototype.Browser.IE);
}
if(navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1) {
info('Running on Gecko');
assert(Prototype.Browser.Gecko);
}
}}
}, 'testlog');
// ]]>
</script>
</body>
</html>

View File

@ -0,0 +1,969 @@
<!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" xml:lang="en" lang="en">
<head>
<title>Prototype Unit test file</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script src="../../dist/prototype.js" type="text/javascript"></script>
<script src="../lib/unittest.js" type="text/javascript"></script>
<link rel="stylesheet" href="../test.css" type="text/css" />
<style type="text/css" media="screen">
/* <![CDATA[ */
#testcss1 { font-size:11px; color: #f00; }
#testcss2 { font-size:12px; color: #0f0; display: none; }
#style_test_1 { cursor: pointer; font-size:12px;}
div.style-test { margin-left: 1px }
#not_floating_style { float: none }
#floating_style { float: left }
#op2 { opacity:0.5;filter:alpha(opacity=50)progid:DXImageTransform.Microsoft.Blur(strength=10);}
#scroll_test_1 {
margin: 10px;
padding: 10px;
position: relative;
}
#scroll_test_2 {
position: absolute;
left: 10px;
top: 10px;
}
#dimensions-visible,
#dimensions-display-none,
#dimensions-visible-pos-rel,
#dimensions-display-none-pos-rel,
#dimensions-visible-pos-abs,
#dimensions-display-none-pos-abs {
font-size: 10px;
height: 10em;
width: 20em;
}
#dimensions-visible-pos-abs,
#dimensions-display-none-pos-abs {
position: absolute;
top: 15px;
left: 15px;
}
#dimensions-visible-pos-rel,
#dimensions-display-none-pos-rel {
position: relative;
top: 15px;
left: 15px;
}
#dimensions-display-none, #imensions-display-none-pos-rel, #dimensions-display-none-pos-abs {
display: none;
}
#dimensions-table, #dimensions-tbody, #dimensions-tr, #dimensions-td {
font-size: 10px;
margin: 0;
padding: 0;
border: 0;
border-spacing: 0;
height: 10em;
width: 20em;
}
/* for scroll test on really big screens */
body {
height: 40000px;
}
/* ]]> */
</style>
</head>
<body>
<h1>Prototype Unit test file</h1>
<p>
Test of functions in dom.js
</p>
<!-- Log output -->
<div id="scroll_test_1">
<p id="scroll_test_2">Scroll test</p>
</div>
<div id="testlog"> </div>
<div id="test-visible">visible</div>
<div id="test-hidden" style="display:none;">hidden</div>
<div id="test-toggle-visible">visible</div>
<div id="test-toggle-hidden" style="display:none;">hidden</div>
<div id="test-hide-visible">visible</div>
<div id="test-hide-hidden" style="display:none;">hidden</div>
<div id="test-show-visible">visible</div>
<div id="test-show-hidden" style="display:none;">hidden</div>
<div id="removable-container"><div id="removable"></div></div>
<div>
<table>
<tbody id="table">
<tr>
<td>Data</td>
</tr>
<tr>
<td id="a_cell">First Row</td>
</tr>
<tr id="second_row">
<td>Second Row</td>
</tr>
</tbody>
</table>
</div>
<div id="table-container-to-replace">
<table>
<tbody id="table-to-replace">
<tr>
<td>Data</td>
</tr>
<tr>
<td id="a_cell-to-replace">First Row</td>
</tr>
<tr id="second_row-to-replace">
<td>Second Row</td>
</tr>
</tbody>
</table>
</div>
<p class="test">Test paragraph outside of container</p>
<div id="container">
<p class="test" id="intended">Test paragraph 1 inside of container</p>
<p class="test">Test paragraph 2 inside of container</p>
<p class="test">Test paragraph 3 inside of container</p>
<p class="test">Test paragraph 4 inside of container</p>
</div>
<div id="testdiv">to be updated</div>
<div id="testdiv-replace-container-1"><div id="testdiv-replace-1"></div></div>
<div id="testdiv-replace-container-2"><div id="testdiv-replace-2"></div></div>
<div id="testdiv-replace-container-3"><div id="testdiv-replace-3"></div></div>
<div id="testdiv-replace-container-4"><div id="testdiv-replace-4"></div></div>
<div id="testdiv-replace-container-5"><div id="testdiv-replace-5"></div></div>
<div id="element_with_visible_overflow" style="overflow:visible">V</div>
<div id="element_with_hidden_overflow" style="overflow:hidden">H</div>
<div id="element_with_scroll_overflow" style="overflow:scroll">S</div>
<div id="element_extend_test"> </div>
<div id="element_reextend_test"><div id="discard_1"></div></div>
<div id="test_whitespace"> <span> </span>
<div><div></div> </div><span> </span>
</div>
<div id="nav_tests_isolator">
<div id="nav_test_first_sibling"></div>
<div></div>
<p id="nav_test_p" class="test"></p>
<span id="nav_test_prev_sibling"></span>
<ul id="navigation_test" style="display: none">
<li class="first"><em>A</em></li>
<li><em class="dim">B</em></li>
<li id="navigation_test_c">
<em>C</em>
<ul>
<li><em class="dim">E</em></li>
<li id="navigation_test_f"><em>F</em></li>
</ul>
</li>
<li class="last"><em>D</em></li>
</ul>
<div id="navigation_test_next_sibling">
<!-- -->
</div>
<p></p>
</div>
<div id="class_names">
<p class="A"></p>
<ul class="A B" id="class_names_ul">
<li class="C"></li>
<li class="A C"></li>
</ul>
<div class="B C D"></div>
</div>
<div id="style_test_1" style="display:none;"></div>
<div id="style_test_2" class="style-test" style="font-size:11px;"></div>
<div id="style_test_3">blah</div>
<div id="custom_attributes">
<div foo="1" bar="2"></div>
<div foo="2"></div>
</div>
<a id="attributes_with_issues_1" href="test.html" accesskey="L" tabindex="50" title="a link"></a>
<a id="attributes_with_issues_2" href="" accesskey="" tabindex="" title=""></a>
<a id="attributes_with_issues_3"></a>
<form id="attributes_with_issues_form" method="post" action="blah">
<input type="checkbox" id="attributes_with_issues_checked" name="a" checked="checked"/>
<input type="checkbox" id="attributes_with_issues_disabled" name="b" checked="checked" disabled="disabled"/>
<input type="text" id="attributes_with_issues_readonly" name="c" readonly="readonly" value="blech"/>
<select id="attributes_with_issues_multiple" name="e" multiple="multiple">
<option>blech</option>
<option>blah</option>
</select>
</form>
<div id="dom_attribute_precedence">
<form action="blech" method="post">
<input type="submit" id="update" />
</form>
</div>
<div id="not_floating_none">NFN</div>
<div id="not_floating_inline" style="float:none">NFI</div>
<div id="not_floating_style">NFS</div>
<div id="floating_inline" style="float:left">FI</div>
<div id="floating_style">FS</div>
<!-- Test Element opacity functions -->
<img id="op1" alt="op2" src="fixtures/logo.gif" style="opacity:0.5;filter:alpha(opacity=50)" />
<img id="op2" alt="op2" src="fixtures/logo.gif"/>
<img id="op3" alt="op3" src="fixtures/logo.gif"/>
<img id="op4-ie" alt="op3" src="fixtures/logo.gif" style="filter:alpha(opacity=30)" />
<div id="dimensions-visible"></div>
<div id="dimensions-display-none"></div>
<div id="dimensions-visible-pos-rel"></div>
<div id="dimensions-display-none-pos-rel"></div>
<div id="dimensions-visible-pos-abs"></div>
<div id="dimensions-display-none-pos-abs"></div>
<table border="0" cellspacing="0" cellpadding="0" id="dimensions-table">
<tbody id="dimensions-tbody">
<tr id="dimensions-tr">
<td id="dimensions-td">Data</td>
</tr>
</tbody>
</table>
<div id="dimensions-nester" style="width: 500px;">
<div id="dimensions-nestee" style="display: none">This is a nested DIV. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
</div>
<p id="test-empty"></p>
<p id="test-empty-but-contains-whitespace">
</p>
<p id="test-full">content</p>
<div id="ancestor"><div id="child"><div><div id="great-grand-child"></div></div></div></div>
<div id="not-in-the-family"></div>
<!-- Tests follow -->
<script type="text/javascript" language="javascript" charset="utf-8">
// <![CDATA[
var testVar = 'to be updated', testVar2 = '';
Element.addMethods("LI", {
pancakes: function(element) { return "pancakes"; }
});
Element.addMethods("DIV", {
waffles: function(element) { return "waffles"; }
});
Element.addMethods($w("li div"), {
orangeJuice: function(element) { return "orange juice"; }
});
new Test.Unit.Runner({
testDollarFunction: function() { with(this) {
assertUndefined($());
assertNull(document.getElementById('noWayThisIDExists'));
assertNull($('noWayThisIDExists'));
assertIdentical(document.getElementById('testdiv'), $('testdiv'));
assertEnumEqual([ $('testdiv'), $('container') ], $('testdiv', 'container'));
assertEnumEqual([ $('testdiv'), undefined, $('container') ],
$('testdiv', 'noWayThisIDExists', 'container'));
var elt = $('testdiv');
assertIdentical(elt, $(elt));
assertRespondsTo('hide', elt);
assertRespondsTo('childOf', elt);
}},
testGetElementsByClassName: function() {with(this) {
assertElementsMatch(document.getElementsByClassName('A'), 'p.A', 'ul#class_names_ul.A', 'li.A.C');
assertElementsMatch(document.getElementsByClassName('A', 'class_names_ul'), 'li.A.C');
assertElementsMatch(document.getElementsByClassName('B', 'class_names'), 'ul#class_names_ul.A.B', 'div.B.C.D');
assertElementsMatch(document.getElementsByClassName('B', 'class_names_ul'));
}},
testInsertWithTR: function() {with(this) {
new Insertion.After('second_row', '<tr id="third_row"><td>Third Row</td></tr>');
assert($('second_row').descendantOf('table'));
}},
testElementVisible: function(){with(this) {
assertNotEqual('none', $('test-visible').style.display);
assertEqual('none', $('test-hidden').style.display);
}},
testElementToggle: function(){with(this) {
$('test-toggle-visible').toggle();
assert(!$('test-toggle-visible').visible());
$('test-toggle-visible').toggle();
assert($('test-toggle-visible').visible());
$('test-toggle-hidden').toggle();
assert($('test-toggle-hidden').visible());
$('test-toggle-hidden').toggle();
assert(!$('test-toggle-hidden').visible());
}},
testElementShow: function(){with(this) {
$('test-show-visible').show();
assert($('test-show-visible').visible());
$('test-show-hidden').show();
assert($('test-show-hidden').visible());
}},
testElementHide: function(){with(this) {
$('test-hide-visible').hide();
assert(!$('test-hide-visible').visible());
$('test-hide-hidden').hide();
assert(!$('test-hide-hidden').visible());
}},
testElementRemove: function(){with(this) {
$('removable').remove();
assert($('removable-container').empty());
}},
testElementUpdate: function() {with(this) {
$('testdiv').update('hello from div!');
assertEqual('hello from div!', $('testdiv').innerHTML);
Element.update('testdiv', 'another hello from div!');
assertEqual('another hello from div!', $('testdiv').innerHTML);
Element.update('testdiv', 123);
assertEqual('123', $('testdiv').innerHTML)
Element.update('testdiv');
assertEqual('', $('testdiv').innerHTML)
}},
testElementUpdateWithScript: function() {with(this) {
$('testdiv').update('hello from div!<script>\ntestVar="hello!";\n</'+'script>');
assertEqual('hello from div!',$('testdiv').innerHTML);
wait(100,function(){
assertEqual('hello!',testVar);
Element.update('testdiv','another hello from div!\n<script>testVar="another hello!"</'+'script>\nhere it goes');
// note: IE normalizes whitespace (like line breaks) to single spaces, thus the match test
assertMatch(/^another hello from div!\s+here it goes$/,$('testdiv').innerHTML);
wait(100,function(){
assertEqual('another hello!',testVar);
Element.update('testdiv','a\n<script>testVar="a"\ntestVar="b"</'+'script>');
wait(100,function(){
assertEqual('b', testVar);
Element.update('testdiv',
'x<script>testVar2="a"</'+'script>\nblah\n'+
'x<script>testVar2="b"</'+'script>');
wait(100,function(){
assertEqual('b', testVar2);
});
});
});
});
}},
testElementUpdateInTableRow: function() {with(this) {
$('second_row').update('<td id="i_am_a_td">test</td>');
assertEqual('test',$('i_am_a_td').innerHTML);
Element.update('second_row','<td id="i_am_a_td">another <span>test</span></td>');
assertEqual('another <span>test</span>',$('i_am_a_td').innerHTML.toLowerCase());
}},
testElementUpdateInTableCell: function() {with(this) {
Element.update('a_cell','another <span>test</span>');
assertEqual('another <span>test</span>',$('a_cell').innerHTML.toLowerCase());
}},
testElementUpdateInTable: function() {with(this) {
Element.update('table','<tr><td>boo!</td></tr>');
assertMatch(/^<tr>\s*<td>boo!<\/td><\/tr>$/,$('table').innerHTML.toLowerCase());
}},
testElementReplace: function() {with(this) {
$('testdiv-replace-1').replace('hello from div!');
assertEqual('hello from div!', $('testdiv-replace-container-1').innerHTML);
$('testdiv-replace-2').replace(123);
assertEqual('123', $('testdiv-replace-container-2').innerHTML)
$('testdiv-replace-3').replace();
assertEqual('', $('testdiv-replace-container-3').innerHTML)
}},
testElementReplaceWithScript: function() {with(this) {
$('testdiv-replace-4').replace('hello from div!<script>testVarReplace="hello!"</'+'script>');
assertEqual('hello from div!', $('testdiv-replace-container-4').innerHTML);
wait(100,function(){
assertEqual('hello!',testVarReplace);
$('testdiv-replace-5').replace('another hello from div!\n<script>testVarReplace="another hello!"</'+'script>\nhere it goes');
// note: IE normalizes whitespace (like line breaks) to single spaces, thus the match test
assertMatch(/^another hello from div!\s+here it goes$/,$('testdiv-replace-container-5').innerHTML);
wait(100,function(){
assertEqual('another hello!',testVarReplace);
});
});
}},
testElementSelectorMethod: function() {with(this) {
var testSelector = $('container').getElementsBySelector('p.test');
assertEqual(testSelector.length, 4);
assertEqual(testSelector[0], $('intended'));
assertEqual(testSelector[0], $$('#container p.test')[0]);
}},
testElementClassNameMethod: function() {with(this) {
var testClassNames = $('container').getElementsByClassName('test');
var testSelector = $('container').getElementsBySelector('p.test');
assertEqual(testClassNames[0], $('intended'));
assertEqual(testClassNames.length, 4);
assertEqual(testSelector[3], testClassNames[3]);
assertEqual(testClassNames.length, testSelector.length);
}},
testElementAncestors: function() {with(this) {
var ancestors = $('navigation_test_f').ancestors();
assertElementsMatch(ancestors, 'ul', 'li', 'ul#navigation_test',
'div#nav_tests_isolator', 'body', 'html');
assertElementsMatch(ancestors.last().ancestors());
var dummy = $(document.createElement('DIV'));
dummy.innerHTML = '<div></div>'.times(3);
assert(typeof $(dummy.childNodes[0]).ancestors()[0]['setStyle'] == 'function');
}},
testElementDescendants: function() {with(this) {
assertElementsMatch($('navigation_test').descendants(),
'li', 'em', 'li', 'em.dim', 'li', 'em', 'ul', 'li',
'em.dim', 'li#navigation_test_f', 'em', 'li', 'em');
assertElementsMatch($('navigation_test_f').descendants(), 'em');
var dummy = $(document.createElement('DIV'));
dummy.innerHTML = '<div></div>'.times(3);
assert(typeof dummy.descendants()[0].setStyle == 'function');
}},
testElementImmediateDescendants: function() {with(this) {
assertElementsMatch($('navigation_test').immediateDescendants(),
'li.first', 'li', 'li#navigation_test_c', 'li.last');
assertNotEqual(0, $('navigation_test_next_sibling').childNodes.length);
assertEnumEqual([], $('navigation_test_next_sibling').immediateDescendants());
var dummy = $(document.createElement('DIV'));
dummy.innerHTML = '<div></div>'.times(3);
assert(typeof dummy.immediateDescendants()[0].setStyle == 'function');
}},
testElementPreviousSiblings: function() {with(this) {
assertElementsMatch($('navigation_test').previousSiblings(),
'span#nav_test_prev_sibling', 'p.test', 'div', 'div#nav_test_first_sibling');
assertElementsMatch($('navigation_test_f').previousSiblings(), 'li');
var dummy = $(document.createElement('DIV'));
dummy.innerHTML = '<div></div>'.times(3);
assert(typeof $(dummy.childNodes[1]).previousSiblings()[0].setStyle == 'function');
}},
testElementNextSiblings: function() {with(this) {
assertElementsMatch($('navigation_test').nextSiblings(),
'div#navigation_test_next_sibling', 'p');
assertElementsMatch($('navigation_test_f').nextSiblings());
var dummy = $(document.createElement('DIV'));
dummy.innerHTML = '<div></div>'.times(3);
assert(typeof $(dummy.childNodes[0]).nextSiblings()[0].setStyle == 'function');
}},
testElementSiblings: function() {with(this) {
assertElementsMatch($('navigation_test').siblings(),
'div#nav_test_first_sibling', 'div', 'p.test',
'span#nav_test_prev_sibling', 'div#navigation_test_next_sibling', 'p');
var dummy = $(document.createElement('DIV'));
dummy.innerHTML = '<div></div>'.times(3);
assert(typeof $(dummy.childNodes[0]).siblings()[0].setStyle == 'function');
}},
testElementUp: function() {with(this) {
var element = $('navigation_test_f');
assertElementMatches(element.up(), 'ul');
assertElementMatches(element.up(0), 'ul');
assertElementMatches(element.up(1), 'li');
assertElementMatches(element.up(2), 'ul#navigation_test');
assertElementsMatch(element.up('li').siblings(), 'li.first', 'li', 'li.last');
assertElementMatches(element.up('ul', 1), 'ul#navigation_test');
assertEqual(undefined, element.up('garbage'));
assertEqual(undefined, element.up(6));
var dummy = $(document.createElement('DIV'));
dummy.innerHTML = '<div></div>'.times(3);
assert(typeof $(dummy.childNodes[0]).up().setStyle == 'function');
}},
testElementDown: function() {with(this) {
var element = $('navigation_test');
assertElementMatches(element.down(), 'li.first');
assertElementMatches(element.down(0), 'li.first');
assertElementMatches(element.down(1), 'em');
assertElementMatches(element.down('li', 5), 'li.last');
assertElementMatches(element.down('ul').down('li', 1), 'li#navigation_test_f');
var dummy = $(document.createElement('DIV'));
dummy.innerHTML = '<div></div>'.times(3);
assert(typeof dummy.down().setStyle == 'function');
}},
testElementPrevious: function() {with(this) {
var element = $('navigation_test').down('li.last');
assertElementMatches(element.previous(), 'li#navigation_test_c');
assertElementMatches(element.previous(1), 'li');
assertElementMatches(element.previous('.first'), 'li.first');
assertEqual(undefined, element.previous(3));
assertEqual(undefined, $('navigation_test').down().previous());
var dummy = $(document.createElement('DIV'));
dummy.innerHTML = '<div></div>'.times(3);
assert(typeof $(dummy.childNodes[1]).previous().setStyle == 'function');
}},
testElementNext: function() {with(this) {
var element = $('navigation_test').down('li.first');
assertElementMatches(element.next(), 'li');
assertElementMatches(element.next(1), 'li#navigation_test_c');
assertElementMatches(element.next(2), 'li.last');
assertElementMatches(element.next('.last'), 'li.last');
assertEqual(undefined, element.next(3));
assertEqual(undefined, element.next(2).next());
var dummy = $(document.createElement('DIV'));
dummy.innerHTML = '<div></div>'.times(3);
assert(typeof $(dummy.childNodes[0]).next().setStyle == 'function');
}},
testElementInspect: function() {with(this) {
assertEqual('<ul id="navigation_test">', $('navigation_test').inspect());
assertEqual('<li class="first">', $('navigation_test').down().inspect());
assertEqual('<em>', $('navigation_test').down(1).inspect());
}},
testElementMakeClipping: function() {with(this) {
var chained = Element.extend(document.createElement('DIV'));
assertEqual(chained, chained.makeClipping());
assertEqual(chained, chained.makeClipping());
assertEqual(chained, chained.makeClipping().makeClipping());
assertEqual(chained, chained.undoClipping());
assertEqual(chained, chained.undoClipping());
assertEqual(chained, chained.undoClipping().makeClipping());
['hidden','visible','scroll'].each( function(overflowValue) {
var element = $('element_with_'+overflowValue+'_overflow');
assertEqual(overflowValue, element.getStyle('overflow'));
element.makeClipping();
assertEqual('hidden', element.getStyle('overflow'));
element.undoClipping();
assertEqual(overflowValue, element.getStyle('overflow'));
});
}},
testElementExtend: function() {with(this) {
var element = $('element_extend_test');
assertRespondsTo('show', element);
var XHTML_TAGS = $w(
'a abbr acronym address applet area '+
'b bdo big blockquote br button caption '+
'cite code col colgroup dd del dfn div dl dt '+
'em fieldset form h1 h2 h3 h4 h5 h6 hr '+
'i iframe img input ins kbd label legend li '+
'map object ol optgroup option p param pre q samp '+
'script select small span strong style sub sup '+
'table tbody td textarea tfoot th thead tr tt ul var');
XHTML_TAGS.each(function(tag) {
var element = document.createElement(tag);
assertEqual(element, Element.extend(element));
assertRespondsTo('show', element);
});
[null,'','a','aa'].each(function(content) {
var textnode = document.createTextNode(content);
assertEqual(textnode, Element.extend(textnode));
assert(typeof textnode['show'] == 'undefined');
});
}},
testElementExtendReextendsDiscardedNodes: function() {with(this) {
assertRespondsTo('show', $('discard_1'));
$('element_reextend_test').innerHTML += '<div id="discard_2"></div>';
assertRespondsTo('show', $('discard_1'));
}},
testElementCleanWhitespace: function() {with(this) {
Element.cleanWhitespace("test_whitespace");
assertEqual(3, $("test_whitespace").childNodes.length);
assertEqual(1, $("test_whitespace").firstChild.nodeType);
assertEqual('SPAN', $("test_whitespace").firstChild.tagName);
assertEqual(1, $("test_whitespace").firstChild.nextSibling.nodeType);
assertEqual('DIV', $("test_whitespace").firstChild.nextSibling.tagName);
assertEqual(1, $("test_whitespace").firstChild.nextSibling.nextSibling.nodeType);
assertEqual('SPAN', $("test_whitespace").firstChild.nextSibling.nextSibling.tagName);
var element = document.createElement('DIV');
element.appendChild(document.createTextNode(''));
element.appendChild(document.createTextNode(''));
assertEqual(2, element.childNodes.length);
Element.cleanWhitespace(element);
assertEqual(0, element.childNodes.length);
}},
testElementEmpty: function() {with(this) {
assert($('test-empty').empty());
assert($('test-empty-but-contains-whitespace').empty());
assert(!$('test-full').empty());
}},
testDescendantOf: function() {with(this) {
assert($('child').descendantOf('ancestor'));
assert($('child').descendantOf($('ancestor')));
assert($('great-grand-child').descendantOf('ancestor'));
assert(!$('great-grand-child').descendantOf('not-in-the-family'));
}},
testChildOf: function() {with(this) {
assert($('child').childOf('ancestor'));
assert($('child').childOf($('ancestor')));
assert($('great-grand-child').childOf('ancestor'));
assert(!$('great-grand-child').childOf('not-in-the-family'));
assertIdentical(Element.Methods.childOf, Element.Methods.descendantOf);
}},
testElementSetStyle: function() { with(this) {
Element.setStyle('style_test_3',{ 'left': '2px' });
assertEqual('2px', $('style_test_3').style.left);
Element.setStyle('style_test_3',{ marginTop: '1px' });
assertEqual('1px', $('style_test_3').style.marginTop);
$('style_test_3').setStyle({ 'margin-top': '2px', left: '-1px' });
assertEqual('-1px', $('style_test_3').style.left);
assertEqual('2px', $('style_test_3').style.marginTop);
assertEqual('none', $('style_test_3').getStyle('float'));
$('style_test_3').setStyle({ 'float': 'left' });
assertEqual('left', $('style_test_3').getStyle('float'));
$('style_test_3').setStyle({ cssFloat: 'none' });
assertEqual('none', $('style_test_3').getStyle('float'));
assertEqual(1, $('style_test_3').getStyle('opacity'));
$('style_test_3').setStyle({ opacity: 0.5 });
assertEqual(0.5, $('style_test_3').getStyle('opacity'));
$('style_test_3').setStyle({ opacity: '' });
assertEqual(1, $('style_test_3').getStyle('opacity'));
$('style_test_3').setStyle({ opacity: 0 });
assertEqual(0, $('style_test_3').getStyle('opacity'));
}},
testElementSetStyleCamelized: function() { with(this) {
assertNotEqual('30px', $('style_test_3').style.marginTop);
$('style_test_3').setStyle({ marginTop: '30px'}, true);
assertEqual('30px', $('style_test_3').style.marginTop);
}},
testElementSetOpacity: function() { with(this) {
[0,0.1,0.5,0.999].each(function(opacity){
$('style_test_3').setOpacity(opacity);
// b/c of rounding issues on IE special case
assert($('style_test_3').getStyle('opacity').toString().startsWith(opacity));
});
assertEqual(0,
$('style_test_3').setOpacity(0.0000001).getStyle('opacity'));
// for Firefox, we don't set to 1, because of flickering
assert(
$('style_test_3').setOpacity(0.9999999).getStyle('opacity') > 0.999
);
}},
testElementGetStyle: function() { with(this) {
assertEqual("none",
$('style_test_1').getStyle('display'));
// not displayed, so "null" ("auto" is tranlated to "null")
assertNull(Element.getStyle('style_test_1','width'));
$('style_test_1').show();
// from id rule
assertEqual("pointer",
Element.getStyle('style_test_1','cursor'));
assertEqual("block",
Element.getStyle('style_test_2','display'));
// we should always get something for width (if displayed)
// firefox and safari automatically send the correct value,
// IE is special-cased to do the same
assertEqual($('style_test_2').offsetWidth+'px', Element.getStyle('style_test_2','width'));
assertEqual("static",Element.getStyle('style_test_1','position'));
// from style
assertEqual("11px",
Element.getStyle('style_test_2','font-size'));
// from class
assertEqual("1px",
Element.getStyle('style_test_2','margin-left'));
['not_floating_none','not_floating_style','not_floating_inline'].each(function(element){
assertEqual('none', $(element).getStyle('float'));
assertEqual('none', $(element).getStyle('cssFloat'));
});
['floating_style','floating_inline'].each(function(element){
assertEqual('left', $(element).getStyle('float'));
assertEqual('left', $(element).getStyle('cssFloat'));
});
assertEqual(0.5, $('op1').getStyle('opacity'));
assertEqual(0.5, $('op2').getStyle('opacity'));
assertEqual(1.0, $('op3').getStyle('opacity'));
$('op1').setStyle({opacity: '0.3'});
$('op2').setStyle({opacity: '0.3'});
$('op3').setStyle({opacity: '0.3'});
assertEqual(0.3, $('op1').getStyle('opacity'));
assertEqual(0.3, $('op2').getStyle('opacity'));
assertEqual(0.3, $('op3').getStyle('opacity'));
$('op3').setStyle({opacity: 0});
assertEqual(0, $('op3').getStyle('opacity'));
if(navigator.appVersion.match(/MSIE/)) {
assertEqual('alpha(opacity=30)', $('op1').getStyle('filter'));
assertEqual('progid:DXImageTransform.Microsoft.Blur(strength=10)alpha(opacity=30)', $('op2').getStyle('filter'));
$('op2').setStyle({opacity:''});
assertEqual('progid:DXImageTransform.Microsoft.Blur(strength=10)', $('op2').getStyle('filter'));
assertEqual('alpha(opacity=0)', $('op3').getStyle('filter'));
assertEqual(0.3, $('op4-ie').getStyle('opacity'));
}
// verify that value is stil found when using camelized
// strings (function previously used getPropertyValue()
// which expected non-camelized strings)
assertEqual("12px", $('style_test_1').getStyle('fontSize'));
}},
testElementGetOpacity: function() {with(this) {
assertEqual(0.45, $('op1').setOpacity(0.45).getOpacity());
}},
testElementReadAttribute: function() {with(this) {
assertEqual('test.html' , $('attributes_with_issues_1').readAttribute('href'));
assertEqual('L' , $('attributes_with_issues_1').readAttribute('accesskey'));
assertEqual('50' , $('attributes_with_issues_1').readAttribute('tabindex'));
assertEqual('a link' , $('attributes_with_issues_1').readAttribute('title'));
['href', 'accesskey', 'accesskey', 'title'].each(function(attr){
assertEqual('' , $('attributes_with_issues_2').readAttribute(attr));
});
['checked','disabled','readonly','multiple'].each(function(attr){
assertEqual(attr, $('attributes_with_issues_'+attr).readAttribute(attr));
});
var elements = $('custom_attributes').immediateDescendants();
assertEnumEqual(['1', '2'], elements.invoke('readAttribute', 'foo'));
assertEnumEqual(['2', null], elements.invoke('readAttribute', 'bar'));
}},
testElementGetHeight: function() {with(this) {
assertIdentical(100, $('dimensions-visible').getHeight());
assertIdentical(100, $('dimensions-display-none').getHeight());
}},
testElementGetWidth: function() {with(this) {
assertIdentical(200, $('dimensions-visible').getWidth());
assertIdentical(200, $('dimensions-display-none').getWidth());
}},
testElementGetDimensions: function() {with(this) {
assertIdentical(100, $('dimensions-visible').getDimensions().height);
assertIdentical(200, $('dimensions-visible').getDimensions().width);
assertIdentical(100, $('dimensions-display-none').getDimensions().height);
assertIdentical(200, $('dimensions-display-none').getDimensions().width);
assertIdentical(100, $('dimensions-visible-pos-rel').getDimensions().height);
assertIdentical(200, $('dimensions-visible-pos-rel').getDimensions().width);
assertIdentical(100, $('dimensions-display-none-pos-rel').getDimensions().height);
assertIdentical(200, $('dimensions-display-none-pos-rel').getDimensions().width);
assertIdentical(100, $('dimensions-visible-pos-abs').getDimensions().height);
assertIdentical(200, $('dimensions-visible-pos-abs').getDimensions().width);
assertIdentical(100, $('dimensions-display-none-pos-abs').getDimensions().height);
assertIdentical(200, $('dimensions-display-none-pos-abs').getDimensions().width);
// known failing issue
// assert($('dimensions-nestee').getDimensions().width <= 500, 'check for proper dimensions of hidden child elements');
$('dimensions-td').hide();
assertIdentical(100, $('dimensions-td').getDimensions().height);
assertIdentical(200, $('dimensions-td').getDimensions().width);
$('dimensions-td').show();
$('dimensions-tr').hide();
assertIdentical(100, $('dimensions-tr').getDimensions().height);
assertIdentical(200, $('dimensions-tr').getDimensions().width);
$('dimensions-tr').show();
$('dimensions-table').hide();
assertIdentical(100, $('dimensions-table').getDimensions().height);
assertIdentical(200, $('dimensions-table').getDimensions().width);
}},
testDOMAttributesHavePrecedenceOverExtendedElementMethods: function() {with(this) {
assertNothingRaised(function() { $('dom_attribute_precedence').down('form') });
assertEqual($('dom_attribute_precedence').down('input'), $('dom_attribute_precedence').down('form').update);
}},
testClassNames: function() {with(this) {
assertEnumEqual([], $('class_names').classNames());
assertEnumEqual(['A'], $('class_names').down().classNames());
assertEnumEqual(['A', 'B'], $('class_names_ul').classNames());
}},
testHasClassName: function() {with(this) {
assert(!$('class_names').hasClassName('does_not_exist'));
assert($('class_names').down().hasClassName('A'));
assert(!$('class_names').down().hasClassName('does_not_exist'));
assert($('class_names_ul').hasClassName('A'));
assert($('class_names_ul').hasClassName('B'));
assert(!$('class_names_ul').hasClassName('does_not_exist'));
}},
testAddClassName: function() {with(this) {
$('class_names').addClassName('added_className');
assertEnumEqual(['added_className'], $('class_names').classNames());
$('class_names').addClassName('added_className'); // verify that className cannot be added twice.
assertEnumEqual(['added_className'], $('class_names').classNames());
$('class_names').addClassName('another_added_className');
assertEnumEqual(['added_className', 'another_added_className'], $('class_names').classNames());
}},
testRemoveClassName: function() {with(this) {
$('class_names').removeClassName('added_className');
assertEnumEqual(['another_added_className'], $('class_names').classNames());
$('class_names').removeClassName('added_className'); // verify that removing a non existent className is safe.
assertEnumEqual(['another_added_className'], $('class_names').classNames());
$('class_names').removeClassName('another_added_className');
assertEnumEqual([], $('class_names').classNames());
}},
testToggleClassName: function() {with(this) {
$('class_names').toggleClassName('toggled_className');
assertEnumEqual(['toggled_className'], $('class_names').classNames());
$('class_names').toggleClassName('toggled_className');
assertEnumEqual([], $('class_names').classNames());
$('class_names_ul').toggleClassName('toggled_className');
assertEnumEqual(['A', 'B', 'toggled_className'], $('class_names_ul').classNames());
$('class_names_ul').toggleClassName('toggled_className');
assertEnumEqual(['A', 'B'], $('class_names_ul').classNames());
}},
testElementScrollTo: function() {with(this) {
var elem = $('scroll_test_2');
Element.scrollTo('scroll_test_2');
assertEqual(Position.page(elem)[1], 0);
window.scrollTo(0, 0);
elem.scrollTo();
assertEqual(Position.page(elem)[1], 0);
window.scrollTo(0, 0);
}},
testSpecificElementMethods: function() {with(this) {
var elem = $('navigation_test_f');
assert(Element.Methods.ByTag[elem.tagName]);
assertRespondsTo('pancakes', elem);
assertEqual("pancakes", elem.pancakes());
var elem2 = $('test-visible');
assert(Element.Methods.ByTag[elem2.tagName]);
assertUndefined(elem2.pancakes);
assertRespondsTo('waffles', elem2);
assertEqual("waffles", elem2.waffles());
assertRespondsTo('orangeJuice', elem);
assertRespondsTo('orangeJuice', elem2);
assertEqual("orange juice", elem.orangeJuice());
assertEqual("orange juice", elem2.orangeJuice());
}},
testScriptFragment: function() {with(this) {
var element = document.createElement('div');
// tests an issue with Safari 2.0 crashing when the ScriptFragment
// regular expression is using a pipe-based approach for
// matching any character
['\r','\n',' '].each(function(character){
$(element).update("<script>"+character.times(10000)+"</scr"+"ipt>");
assertEqual('', element.innerHTML);
});
$(element).update("<script>var blah='"+'\\'.times(10000)+"'</scr"+"ipt>");
assertEqual('', element.innerHTML);
}}
}, 'testlog');
// ]]>
</script>
</body>
</html>

View File

@ -0,0 +1,65 @@
<!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" xml:lang="en" lang="en">
<head>
<title>Prototype Unit test file</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script src="../../dist/prototype.js" type="text/javascript"></script>
<script src="../lib/unittest.js" type="text/javascript"></script>
<link rel="stylesheet" href="../test.css" type="text/css" />
<style type="text/css" media="screen">
/* <![CDATA[ */
#testcss1 { font-size:11px; color: #f00; }
#testcss2 { font-size:12px; color: #0f0; display: none; }
/* ]]> */
</style>
</head>
<body>
<h1>Prototype Unit test file</h1>
<p>
Test of extra methods mixed in to elements with $() and $$().
</p>
<!-- Log output -->
<div id="testlog"> </div>
<h2>Test Form Elements</h2>
<form id="form">
<input type="text" id="input" value="4" />
<input type="submit" />
</form>
<!-- Tests follow -->
<script type="text/javascript" language="javascript" charset="utf-8">
// <![CDATA[
new Test.Unit.Runner({
testInput: function() {with(this) {
assert($("input").present != null);
assert(typeof $("input").present == 'function');
assert($("input").select != null);
}},
testForm: function() {with(this) {
assert($("form").reset != null);
assert($("form").getInputs().length == 2);
}},
testEvent: function() {with(this) {
assert($("form").observe != null)
// Can't really test this one with TestUnit...
$('form').observe("submit", function(e) {
alert("yeah!");
Event.stop(e);
});
}},
testCollections: function() {with(this) {
assert($$("input").all(function(input) {
return (input.focus != null);
}));
}}
}, 'testlog');
// ]]>
</script>
</body>
</html>

View File

@ -0,0 +1,289 @@
<!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" xml:lang="en" lang="en">
<head>
<title>Prototype Unit test file</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script src="../../dist/prototype.js" type="text/javascript"></script>
<script src="../lib/unittest.js" type="text/javascript"></script>
<link rel="stylesheet" href="../test.css" type="text/css" />
<style type="text/css" media="screen">
/* <![CDATA[ */
#testcss1 { font-size:11px; color: #f00; }
#testcss2 { font-size:12px; color: #0f0; display: none; }
/* ]]> */
</style>
</head>
<body>
<h1>Prototype Unit test file</h1>
<p>
Test of utility functions in enumerable.js
</p>
<!-- Log output -->
<div id="testlog"> </div>
<!-- Tests follow -->
<script type="text/javascript" language="javascript" charset="utf-8">
// <![CDATA[
var Fixtures = {
People: [
{name: 'Sam Stephenson', nickname: 'sam-'},
{name: 'Marcel Molina Jr.', nickname: 'noradio'},
{name: 'Scott Barron', nickname: 'htonl'},
{name: 'Nicholas Seckar', nickname: 'Ulysses'}
],
Nicknames: $w('sam- noradio htonl Ulysses'),
Primes: [
1, 2, 3, 5, 7, 11, 13, 17, 19, 23,
29, 31, 37, 41, 43, 47, 53, 59, 61, 67,
71, 73, 79, 83, 89, 97
],
Z: []
};
for (var i = 1; i <= 100; i++)
Fixtures.Z.push(i);
function prime(value) {
for (var i = 2; i < value; i++)
if (value % i == 0) return false;
return true;
}
new Test.Unit.Runner({
testEachBreak: function() {with(this) {
var result = 0;
[1, 2, 3].each(function(value) {
if ((result = value) == 2) throw $break;
});
assertEqual(2, result);
}},
testEachReturnActsAsContinue: function() {with(this) {
var results = [];
[1, 2, 3].each(function(value) {
if (value == 2) return;
results.push(value);
});
assertEqual('1, 3', results.join(', '));
}},
testEachChaining: function() {with(this) {
assertEqual(Fixtures.Primes, Fixtures.Primes.each(Prototype.emptyFunction));
assertEqual(3, [1, 2, 3].each(Prototype.emptyFunction).length);
}},
testAny: function() {with(this) {
assert(!([].any()));
assert([true, true, true].any());
assert([true, false, false].any());
assert(![false, false, false].any());
assert([1, 2, 3, 4, 5].any(function(value) {
return value > 3;
}));
assert(![1, 2, 3, 4, 5].any(function(value) {
return value > 10;
}));
}},
testAll: function() {with(this) {
assert([].all());
assert([true, true, true].all());
assert(![true, false, false].all());
assert(![false, false, false].all());
assert([1, 2, 3, 4, 5].all(function(value) {
return value > 0;
}));
assert(![1, 2, 3, 4, 5].all(function(value) {
return value > 3;
}));
}},
testCollect: function() {with(this) {
assertEqual(Fixtures.Nicknames.join(', '),
Fixtures.People.collect(function(person) {
return person.nickname;
}).join(", "));
assertEqual(26, Fixtures.Primes.map().length);
}},
testDetect: function() {with(this) {
assertEqual('Marcel Molina Jr.',
Fixtures.People.detect(function(person) {
return person.nickname.match(/no/);
}).name);
}},
testEachSlice: function() {with(this) {
assertEnumEqual([], [].eachSlice(2));
assertEqual(1, [1].eachSlice(1).length);
assertEnumEqual([1], [1].eachSlice(1)[0]);
assertEqual(2, [1,2,3].eachSlice(2).length);
assertEnumEqual(
[3, 2, 1, 11, 7, 5, 19, 17, 13, 31, 29, 23, 43, 41, 37, 59, 53, 47, 71, 67, 61, 83, 79, 73, 97, 89],
Fixtures.Primes.eachSlice( 3, function(slice){ return slice.reverse() }).flatten()
);
}},
testEachWithIndex: function() {with(this) {
var nicknames = [], indexes = [];
Fixtures.People.each(function(person, index) {
nicknames.push(person.nickname);
indexes.push(index);
});
assertEqual(Fixtures.Nicknames.join(', '),
nicknames.join(', '));
assertEqual('0, 1, 2, 3', indexes.join(', '));
}},
testFindAll: function() {with(this) {
assertEqual(Fixtures.Primes.join(', '),
Fixtures.Z.findAll(prime).join(', '));
}},
testGrep: function() {with(this) {
assertEqual('noradio, htonl',
Fixtures.Nicknames.grep(/o/).join(", "));
assertEqual('NORADIO, HTONL',
Fixtures.Nicknames.grep(/o/, function(nickname) {
return nickname.toUpperCase();
}).join(", "))
}},
testInclude: function() {with(this) {
assert(Fixtures.Nicknames.include('sam-'));
assert(Fixtures.Nicknames.include('noradio'));
assert(Fixtures.Nicknames.include('htonl'));
assert(Fixtures.Nicknames.include('Ulysses'));
assert(!Fixtures.Nicknames.include('gmosx'));
}},
testInGroupsOf: function() { with(this) {
assertEnumEqual([], [].inGroupsOf(3));
var arr = [1, 2, 3, 4, 5, 6].inGroupsOf(3);
assertEqual(2, arr.length);
assertEnumEqual([1, 2, 3], arr[0]);
assertEnumEqual([4, 5, 6], arr[1]);
arr = [1, 2, 3, 4, 5, 6].inGroupsOf(4);
assertEqual(2, arr.length);
assertEnumEqual([1, 2, 3, 4], arr[0]);
assertEnumEqual([5, 6, null, null], arr[1]);
arr = [1, 2, 3].inGroupsOf(4,'x');
assertEqual(1, arr.length);
assertEnumEqual([1, 2, 3, 'x'], arr[0]);
assertEnumEqual([1,2,3,'a'], [1,2,3].inGroupsOf(2, 'a').flatten());
arr = [1, 2, 3].inGroupsOf(5, '');
assertEqual(1, arr.length);
assertEnumEqual([1, 2, 3, '', ''], arr[0]);
assertEnumEqual([1,2,3,0], [1,2,3].inGroupsOf(2, 0).flatten());
assertEnumEqual([1,2,3,false], [1,2,3].inGroupsOf(2, false).flatten());
}},
testInject: function() {with(this) {
assertEqual(1061,
Fixtures.Primes.inject(0, function(sum, value) {
return sum + value;
}));
}},
testInvoke: function() {with(this) {
var result = [[2, 1, 3], [6, 5, 4]].invoke('sort');
assertEqual(2, result.length);
assertEqual('1, 2, 3', result[0].join(', '));
assertEqual('4, 5, 6', result[1].join(', '));
result = result.invoke('invoke', 'toString', 2);
assertEqual('1, 10, 11', result[0].join(', '));
assertEqual('100, 101, 110', result[1].join(', '));
}},
testMax: function() {with(this) {
assertEqual(100, Fixtures.Z.max());
assertEqual(97, Fixtures.Primes.max());
assertEqual(2, [ -9, -8, -7, -6, -4, -3, -2, 0, -1, 2 ].max());
assertEqual('sam-', Fixtures.Nicknames.max()); // ?s > ?U
}},
testMin: function() {with(this) {
assertEqual(1, Fixtures.Z.min());
assertEqual(0, [ 1, 2, 3, 4, 5, 6, 7, 8, 0, 9 ].min());
assertEqual('Ulysses', Fixtures.Nicknames.min()); // ?U < ?h
}},
testPartition: function() {with(this) {
var result = Fixtures.People.partition(function(person) {
return person.name.length < 15;
}).invoke('pluck', 'nickname');
assertEqual(2, result.length);
assertEqual('sam-, htonl', result[0].join(', '));
assertEqual('noradio, Ulysses', result[1].join(', '));
}},
testPluck: function() {with(this) {
assertEqual(Fixtures.Nicknames.join(', '),
Fixtures.People.pluck('nickname').join(', '));
}},
testReject: function() {with(this) {
assertEqual(0,
Fixtures.Nicknames.reject(Prototype.K).length);
assertEqual('sam-, noradio, htonl',
Fixtures.Nicknames.reject(function(nickname) {
return nickname != nickname.toLowerCase();
}).join(', '));
}},
testSortBy: function() {with(this) {
assertEqual('htonl, noradio, sam-, Ulysses',
Fixtures.People.sortBy(function(value) {
return value.nickname.toLowerCase();
}).pluck('nickname').join(', '));
}},
testToArray: function() {with(this) {
var result = Fixtures.People.toArray();
assert(result != Fixtures.People); // they're different objects...
assertEqual(Fixtures.Nicknames.join(', '),
result.pluck('nickname').join(', ')); // but the values are the same
}},
testZip: function() {with(this) {
var result = [1, 2, 3].zip([4, 5, 6], [7, 8, 9]);
assertEqual('[[1, 4, 7], [2, 5, 8], [3, 6, 9]]', result.inspect());
result = [1, 2, 3].zip([4, 5, 6], [7, 8, 9], function(array) { return array.reverse() });
assertEqual('[[7, 4, 1], [8, 5, 2], [9, 6, 3]]', result.inspect());
}},
testSize: function() {with(this) {
assertEqual(4, Fixtures.People.size());
assertEqual(4, Fixtures.Nicknames.size());
assertEqual(26, Fixtures.Primes.size());
assertEqual(0, [].size());
}}
}, 'testlog');
// ]]>
</script>
</body>
</html>

View File

@ -0,0 +1 @@
Pack my box with <em>five dozen</em> liquor jugs! Oh, how <strong>quickly</strong> daft jumping zebras vex...

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@
$("content").update("<H2>Hello world!</H2>");

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -0,0 +1,394 @@
<!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" xml:lang="en" lang="en">
<head>
<title>Prototype Unit test file</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script src="../../dist/prototype.js" type="text/javascript"></script>
<script src="../lib/unittest.js" type="text/javascript"></script>
<link rel="stylesheet" href="../test.css" type="text/css" />
<style type="text/css" media="screen">
/* <![CDATA[ */
#testcss1 { font-size:11px; color: #f00; }
#testcss2 { font-size:12px; color: #0f0; display: none; }
/* ]]> */
</style>
</head>
<body>
<h1>Prototype Unit test file</h1>
<p>
Test of utility functions in form.js
</p>
<!-- Log output -->
<div id="testlog"> </div>
<form id="form" method="get" action="fixtures/empty.js">
<input type="text" name="val1" id="input_enabled" value="4" />
<div>This is not a form element</div>
<input type="text" name="val2" id="input_disabled" disabled="disabled" value="5" />
<input type="submit" />
<input type="text" name="action" value="blah" />
</form>
<div id="form_wrapper">
<form id="form_selects" action="fixtures/empty.js">
<select name="vu">
<option value="1" selected="selected">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
<select id="multiSel1" name="vm[]" multiple="multiple">
<option id="multiSel1_opt1" value="1" selected="selected">One</option>
<option id="multiSel1_opt2" value="2">Two</option>
<option id="multiSel1_opt3" value="3" selected="selected">Three</option>
</select>
<select name="nvu">
<option selected="selected">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
<fieldset id="form_fieldset">
<select name="nvm[]" multiple="multiple">
<option selected="selected">One</option>
<option>Two</option>
<option selected="selected">Three</option>
</select>
<select name="evu">
<option value="" selected="selected">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
<select name="evm[]" multiple="multiple">
<option value="" selected="selected">One</option>
<option>Two</option>
<option selected="selected">Three</option>
</select>
</fieldset>
</form>
</div>
<form id="form_array">
<input type="text" name="twin" value="" />
<input type="text" name="twin" value="siamese" />
<!-- Rails checkbox hack with hidden input: -->
<input type="checkbox" id="checkbox_hack" name="checky" value="1" />
<input name="checky" type="hidden" value="0" />
</form>
<form id="form_getelements">
<select id="tf_selectOne" name="tf_selectOne"><option></option><option>1</option></select>
<textarea id="tf_textarea" name="tf_textarea"></textarea>
<input type="checkbox" id="tf_checkbox" name="tf_checkbox" value="on" />
<select id="tf_selectMany" name="tf_selectMany" multiple="multiple"></select>
<input type="text" id="tf_text" name="tf_text" />
<div>This is not a form element</div>
<input type="radio" id="tf_radio" name="tf_radio" value="on" />
<input type="hidden" id="tf_hidden" name="tf_hidden" />
<input type="password" id="tf_password" name="tf_password" />
</form>
<form id="form_focus">
<input type="text" name="focus_disabled" id="focus_disabled" disabled="disabled"/>
<input type="submit" name="focus_submit" id="focus_submit" />
<input type="button" name="focus_button" id="focus_button" value="button" />
<input type="reset" name="focus_reset" id="focus_reset" />
<input type="text" name="focus_text" id="focus_text" value="Hello" />
</form>
<form id="form_focus_hidden" style="display: none">
<input type="text" />
</form>
<!-- Tests follow -->
<script type="text/javascript" language="javascript" charset="utf-8">
// <![CDATA[
var callbackCounter = 0;
var timedCounter = 0;
new Test.Unit.Runner({
// Make sure to set defaults in the test forms, as some browsers override this
// with previously entered values on page reload
setup: function(){ with(this) {
$('input_enabled').value = '4';
$('input_disabled').value = '5';
$('tf_selectOne').selectedIndex = 0;
$('tf_textarea').value = '';
$('tf_text').value = '';
$('tf_hidden').value = '';
$('tf_password').value = '';
$('tf_checkbox').checked = false;
$('tf_radio').checked = false;
}},
testFormElementEventObserver: function(){ with(this) {
var observer = new Form.Element.EventObserver('input_enabled', function(){
callbackCounter++;
});
assertEqual(0, callbackCounter);
$('input_enabled').value = 'boo!';
observer.onElementEvent(); // can't test the event directly, simulating
assertEqual(1, callbackCounter);
}},
testFormElementObserver: function(){ with(this) {
// First part: regular field
var observer = new Form.Element.Observer('input_enabled', 0.5, function() {
++timedCounter;
});
// Test it's unchanged yet
assertEqual(0, timedCounter);
// Test it doesn't change on first check
wait(550, function() {
assertEqual(0, timedCounter);
// Change, test it doesn't immediately change
$('input_enabled').value = 'yowza!';
assertEqual(0, timedCounter);
// Test it changes on next check, but not again on the next
wait(550, function() {
assertEqual(1, timedCounter);
wait(550, function() {
assertEqual(1, timedCounter);
});
});
});
// Second part: multiple-select! -- Fails before patch in #6593.
[1, 2, 3].each(function(index) {
$('multiSel1_opt' + index).selected = (1 == index);
});
timedCounter = 0;
observer = new Form.Element.Observer('multiSel1', 0.5, function() {
++timedCounter;
});
// Test it's unchanged yet
assertEqual(0, timedCounter);
// Test it doesn't change on first check
wait(550, function() {
assertEqual(0, timedCounter);
// Change, test it doesn't immediately change
// NOTE: it is important that the 3rd be re-selected, for the
// serialize form to obtain the expected value :-)
$('multiSel1_opt3').selected = true;
assertEqual(0, timedCounter);
// Test it changes on next check, but not again on the next
wait(550, function() {
assertEqual(1, timedCounter);
wait(550, function() {
assertEqual(1, timedCounter);
});
});
});
}},
testFormEnabling: function(){ with(this) {
var form = $('form_focus')
var input1 = form.focus_disabled
var input2 = form.focus_text
assert(input1.disabled)
assert(!input2.disabled)
form.disable()
assert(input1.disabled)
assert(input2.disabled)
form.enable()
assert(!input1.disabled)
assert(!input2.disabled)
input1.disable()
assert(input1.disabled)
// non-form elements:
var fieldset = $('form_fieldset')
var fields = fieldset.immediateDescendants()
assert(fields.all(function(select){ return !select.disabled }))
Form.disable(fieldset)
assert(fields.all(function(select){ return select.disabled }))
Form.enable(fieldset)
assert(fields.all(function(select){ return !select.disabled }))
}},
testFormElementEnabling: function(){ with(this) {
assert($('input_disabled').disabled);
$('input_disabled').enable();
assert(!$('input_disabled').disabled);
$('input_disabled').disable();
assert($('input_disabled').disabled);
assert(!$('input_enabled').disabled);
$('input_enabled').disable();
assert($('input_enabled').disabled);
$('input_enabled').enable();
assert(!$('input_enabled').disabled);
}},
// due to the lack of a DOM hasFocus() API method,
// we're simulating things here a little bit
testFormActivating: function(){ with(this) {
// Firefox, IE, and Safari 2+
function getSelection(element){
try {
if (typeof element.selectionStart == 'number') {
return element.value.substring(element.selectionStart, element.selectionEnd);
} else if (document.selection && document.selection.createRange) {
return document.selection.createRange().text;
}
}
catch(e){ return null }
}
// Form.focusFirstElement shouldn't focus disabled elements
var element = Form.findFirstElement('form_focus');
assertEqual('focus_submit',element.id);
// Test IE doesn't select text on buttons
Form.focusFirstElement('form_focus');
if(document.selection) assertEqual('', getSelection(element));
// Form.Element.activate shouldn't select text on buttons
element = $('focus_text');
assertEqual('', getSelection(element));
// Form.Element.activate should select text on text input elements
element.activate();
assertEqual('Hello', getSelection(element));
// Form.Element.activate shouldn't raise an exception when the form or field is hidden
assertNothingRaised(function() {
$('form_focus_hidden').focusFirstElement();
});
}},
testFormGetElements: function() {with(this) {
var formElements = $('form_getelements').getElements();
assertEqual(8, formElements.length);
assertEqual('tf_selectOne', formElements[0].id);
assertEqual('tf_textarea', formElements[1].id);
assertEqual('tf_checkbox', formElements[2].id);
assertEqual('tf_selectMany', formElements[3].id);
assertEqual('tf_text', formElements[4].id);
assertEqual('tf_radio', formElements[5].id);
assertEqual('tf_hidden', formElements[6].id);
assertEqual('tf_password', formElements[7].id);
}},
testFormGetInputs: function() {with(this){
var form = $('form_getelements'), formInputs = Form.getInputs(form);
assertEqual(formInputs.length, 5);
assert(formInputs instanceof Array);
assert(formInputs.all(function(input) { return (input.tagName == "INPUT"); }));
var formInputs2 = form.getInputs();
assertEqual(formInputs2.length, 5);
assert(formInputs2 instanceof Array);
assert(formInputs2.all(function(input) { return (input.tagName == "INPUT"); }));
}},
testFormSerialize: function() {with(this){
assertEqual('tf_selectOne=&tf_textarea=&tf_text=&tf_hidden=&tf_password=',
Form.serialize('form_getelements'));
$('tf_selectOne').selectedIndex = 1;
$('tf_textarea').value = "boo hoo!";
$('tf_text').value = "123öäü";
$('tf_hidden').value = "moo%hoo&test";
$('tf_password').value = 'sekrit code';
$('tf_checkbox').checked = true;
$('tf_radio').checked = true;
assertEqual(
'tf_selectOne=1&tf_textarea=boo%20hoo!&tf_checkbox=on&tf_text=123%C3%B6%C3%A4%C3%BC&'+
'tf_radio=on&tf_hidden=moo%25hoo%26test&tf_password=sekrit%20code',
Form.serialize('form_getelements'));
// Checks that disabled element is not included in serialized form.
$('input_enabled').enable();
assertEqual('val1=4&action=blah', Form.serialize('form'));
// Checks that select-related serializations work just fine
assertEqual('vu=1&vm%5B%5D=1&vm%5B%5D=3&nvu=One&nvm%5B%5D=One'+
'&nvm%5B%5D=Three&evu=&evm%5B%5D=&evm%5B%5D=Three',
Form.serialize('form_selects'));
// should not eat empty values for duplicate names
$('checkbox_hack').checked = false;
var data = Form.serialize('form_array', true);
assertEnumEqual(['', 'siamese'], data['twin']);
assertEqual('0', data['checky']);
$('checkbox_hack').checked = true;
assertEnumEqual($w('1 0'), Form.serialize('form_array', true)['checky']);
}},
testFormSerializeWorksWithNonFormElements: function() {with(this) {
assertEqual('nvm%5B%5D=One&nvm%5B%5D=Three&evu=&evm%5B%5D=&evm%5B%5D=Three', Form.serialize('form_fieldset'));
assertEqual('vu=1&vm%5B%5D=1&vm%5B%5D=3&nvu=One&nvm%5B%5D=One&nvm%5B%5D=Three&evu=&evm%5B%5D=&evm%5B%5D=Three', Form.serialize('form_wrapper'));
}},
testFormMethodsOnExtendedElements: function() {with(this) {
assertEqual(Form.serialize('form'), $('form').serialize());
assertEqual(Form.Element.serialize('input_enabled'), $('input_enabled').serialize());
assertNotEqual($('form').serialize, $('input_enabled').serialize);
Element.addMethods('INPUT', { anInputMethod: function(input) { return 'input' } });
Element.addMethods('SELECT', { aSelectMethod: function(select) { return 'select' } });
document.getElementById('tf_text')._extended = false;
document.getElementById('tf_selectOne')._extended = false;
assert($('tf_text').anInputMethod);
assert(!$('tf_text').aSelectMethod);
assertEqual('input', $('tf_text').anInputMethod());
assert($('tf_selectOne').aSelectMethod);
assert(!$('tf_selectOne').anInputMethod);
assertEqual('select', $('tf_selectOne').aSelectMethod());
}},
testFormRequest: function() {with(this) {
var request = $("form_selects").request();
assert(!$("form_selects").hasAttribute("method"));
assert(request.url.endsWith("fixtures/empty.js"));
assertEqual("post", request.method);
assertEqual("vu=1&vm%5B%5D=1&vm%5B%5D=3&nvu=One&nvm%5B%5D=One&nvm%5B%5D=Three&evu=&evm%5B%5D=&evm%5B%5D=Three", Hash.toQueryString(request.options.parameters));
request = $("form_selects").request({method: "put", parameters: {val2: "hello", val3: "world"}});
assertEqual("post", request.method);
assertEqual("put", request.parameters['_method']);
assertEqual("vu=1&vm%5B%5D=1&vm%5B%5D=3&nvu=One&nvm%5B%5D=One&nvm%5B%5D=Three&evu=&evm%5B%5D=&evm%5B%5D=Three&val2=hello&val3=world", Hash.toQueryString(request.options.parameters));
request = $("form").request();
assert($("form").hasAttribute("method"));
assert(request.url.endsWith("fixtures/empty.js?val1=4&action=blah"));
assertEqual("get", request.method);
request = $("form").request({method: "post"});
assert(request.url.endsWith("fixtures/empty.js"));
assertEqual("val1=4&action=blah", Hash.toQueryString(request.options.parameters));
assertEqual("post", request.method);
}},
testFormElementMethodsChaining: function(){ with(this) {
var methods = $w('clear activate disable enable'),
formElements = $('form_getelements').getElements();
methods.each(function(method){
formElements.each(function(element){
var returned = element[method]();
assertIdentical(element, returned);
});
});
}}
}, 'testlog');
// ]]>
</script>
</body>
</html>

View File

@ -0,0 +1,145 @@
<!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" xml:lang="en" lang="en">
<head>
<title>Prototype Unit test file</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script src="../../dist/prototype.js" type="text/javascript"></script>
<script src="../lib/unittest.js" type="text/javascript"></script>
<link rel="stylesheet" href="../test.css" type="text/css" />
<style type="text/css" media="screen">
/* <![CDATA[ */
#testcss1 { font-size:11px; color: #f00; }
#testcss2 { font-size:12px; color: #0f0; display: none; }
/* ]]> */
</style>
</head>
<body>
<h1>Prototype Unit test file</h1>
<p>
Test of the Hash.prototype extensions
</p>
<!-- Log output -->
<div id="testlog"> </div>
<!-- Tests follow -->
<script type="text/javascript" language="javascript" charset="utf-8">
// <![CDATA[
var Fixtures = {
one: { a: 'A#' },
many: {
a: 'A',
b: 'B',
c: 'C',
d: 'D#'
},
functions: {
quad: function(n) { return n*n },
plus: function(n) { return n+n }
},
multiple: { color: $w('r g b') },
multiple_nil: { color: ['r', null, 'g', undefined, 0] },
multiple_all_nil: { color: [null, undefined] },
multiple_empty: { color: [] },
multiple_special: { 'stuff[]': $w('$ a ;') },
value_undefined: { a:"b", c:undefined },
value_null: { a:"b", c:null },
value_zero: { a:"b", c:0 },
dangerous: {
_each: 'E',
map: 'M',
keys: 'K',
values: 'V',
collect: 'C',
inject: 'I'
}
};
new Test.Unit.Runner({
testConstruct: function(){ with(this) {
var h = $H(Fixtures.one);
assertNotIdentical(Fixtures.one, h);
assertIdentical(h, $H(h));
var h2 = new Hash(h);
assertNotIdentical(h, h2);
assertHashEqual(h, h2);
}},
testKeys: function(){ with(this) {
assertEnumEqual([], $H({}).keys());
assertEnumEqual(['a'], $H(Fixtures.one).keys());
assertEnumEqual($w('a b c d'), $H(Fixtures.many).keys().sort());
assertEnumEqual($w('plus quad'), $H(Fixtures.functions).keys().sort());
}},
testValues: function(){ with(this) {
assertEnumEqual([], $H({}).values());
assertEnumEqual(['A#'], $H(Fixtures.one).values());
assertEnumEqual($w('A B C D#'), $H(Fixtures.many).values().sort());
assertEnumEqual($w('function function'),
$H(Fixtures.functions).values().map(function(i){ return typeof i }));
assertEqual(9, $H(Fixtures.functions).quad(3));
assertEqual(6, $H(Fixtures.functions).plus(3));
}},
testMerge: function(){ with(this) {
assertHashEqual(Fixtures.many, $H(Fixtures.many).merge());
assertHashEqual(Fixtures.many, $H(Fixtures.many).merge({}));
assertHashEqual(Fixtures.many, $H(Fixtures.many).merge($H()));
assertHashEqual({a:'A', b:'B', c:'C', d:'D#', aaa:'AAA' }, $H(Fixtures.many).merge({aaa: 'AAA'}));
assertHashEqual({a:'A#', b:'B', c:'C', d:'D#' }, $H(Fixtures.many).merge(Fixtures.one));
}},
testRemove: function(){ with(this) {
var hash = $H(Fixtures.many);
var values = hash.remove('b', 'c');
assertHashEqual({a:'A', d:'D#'}, hash);
assertEnumEqual($w('B C'), values);
}},
testToQueryString: function(){ with(this) {
assertEqual('', $H({}).toQueryString());
assertEqual('a=A%23', $H(Fixtures.one).toQueryString());
assertEqual('a=A&b=B&c=C&d=D%23', $H(Fixtures.many).toQueryString());
assertEqual("a=b&c", $H(Fixtures.value_undefined).toQueryString());
assertEqual("a=b&c", $H("a=b&c".toQueryParams()).toQueryString());
assertEqual("a=b&c=", $H(Fixtures.value_null).toQueryString());
assertEqual("a=b&c=0", $H(Fixtures.value_zero).toQueryString());
assertEqual("color=r&color=g&color=b", $H(Fixtures.multiple).toQueryString());
assertEqual("color=r&color=&color=g&color&color=0", $H(Fixtures.multiple_nil).toQueryString());
assertEqual("color=&color", $H(Fixtures.multiple_all_nil).toQueryString());
assertEqual("", $H(Fixtures.multiple_empty).toQueryString());
assertEqual("stuff%5B%5D=%24&stuff%5B%5D=a&stuff%5B%5D=%3B", $H(Fixtures.multiple_special).toQueryString());
assertHashEqual(Fixtures.multiple_special, $H(Fixtures.multiple_special).toQueryString().toQueryParams());
var danger = $w("_each=E collect=C inject=I keys=K map=M values=V");
assertEnumEqual(danger, Hash.toQueryString(Fixtures.dangerous).split('&').sort());
assertEnumEqual(danger, $H(Fixtures.dangerous).toQueryString().split('&').sort());
}},
testInspect: function(){ with(this) {
assertEqual('#<Hash:{}>', $H({}).inspect());
assertEqual("#<Hash:{'a': 'A#'}>", $H(Fixtures.one).inspect());
assertEqual("#<Hash:{'a': 'A', 'b': 'B', 'c': 'C', 'd': 'D#'}>", $H(Fixtures.many).inspect());
}},
testToJSON: function(){ with(this) {
assertEqual('{\"b\":[false,true],\"c\":{\"a\":\"hello!\"}}',
$H({'b': [undefined, false, true, undefined], c: {a: 'hello!'}}).toJSON());
assertEqual('E', eval('(' + $H(Fixtures.dangerous).toJSON() + ')')._each);
}}
}, 'testlog');
// ]]>
</script>
</body>
</html>

View File

@ -0,0 +1,118 @@
<!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" xml:lang="en" lang="en">
<head>
<title>Prototype Unit test file</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script src="../../dist/prototype.js" type="text/javascript"></script>
<script src="../lib/unittest.js" type="text/javascript"></script>
<link rel="stylesheet" href="../test.css" type="text/css" />
<style type="text/css" media="screen">
/* <![CDATA[ */
#testcss1 { font-size:11px; color: #f00; }
#testcss2 { font-size:12px; color: #0f0; display: none; }
/* ]]> */
</style>
</head>
<body>
<div id="ensure_scrollbars" style="width:10000px; height:10000px; position:absolute" > </div>
<h1>Prototype Unit test file</h1>
<p>
Test of functions in position.js
</p>
<!-- Log output -->
<div id="testlog"> </div>
<div id="body_absolute" style="position: absolute; top: 10px; left: 10px">
<div id="absolute_absolute" style="position: absolute; top: 10px; left:10px"> </div>
<div id="absolute_relative" style="position: relative; top: 10px; left:10px">
<div style="height:10px">test<span id="inline">test</span></div>
<div id="absolute_relative_undefined"> </div>
</div>
</div>
<!-- Tests follow -->
<script type="text/javascript" language="javascript" charset="utf-8">
// <![CDATA[
var testVar = 'to be updated';
new Test.Unit.Runner({
setup: function() {
scrollTo(0,0);
Position.prepare();
Position.includeScrollOffsets = false;
},
teardown: function() {
scrollTo(0,0);
Position.prepare();
Position.includeScrollOffsets = false;
},
testPrepare: function() {with(this) {
Position.prepare();
assertEqual(0, Position.deltaX);
assertEqual(0, Position.deltaY);
scrollTo(20,30);
Position.prepare();
assertEqual(20, Position.deltaX);
assertEqual(30, Position.deltaY);
}},
testPositionedOffset: function() {with(this) {
assertEnumEqual([10,10],
Position.positionedOffset($('body_absolute')));
assertEnumEqual([10,10],
Position.positionedOffset($('absolute_absolute')));
assertEnumEqual([10,10],
Position.positionedOffset($('absolute_relative')));
assertEnumEqual([0,10],
Position.positionedOffset($('absolute_relative_undefined')));
}},
testPage: function() {with(this) {
assertEnumEqual([10,10],
Position.page($('body_absolute')));
assertEnumEqual([20,20],
Position.page($('absolute_absolute')));
assertEnumEqual([20,20],
Position.page($('absolute_relative')));
assertEnumEqual([20,30],
Position.page($('absolute_relative_undefined')));
}},
testOffsetParent: function() {with(this) {
assertEqual('body_absolute', Position.offsetParent($('absolute_absolute')).id);
assertEqual('body_absolute', Position.offsetParent($('absolute_relative')).id);
assertEqual('absolute_relative', Position.offsetParent($('inline')).id);
assertEqual('absolute_relative', Position.offsetParent($('absolute_relative_undefined')).id);
}},
testWithin: function() {with(this) {
[true, false].each(function(withScrollOffsets) {
Position.includeScrollOffsets = withScrollOffsets;
assert(!Position.within($('body_absolute'), 9, 9), 'outside left/top');
assert(Position.within($('body_absolute'), 10, 10), 'left/top corner');
assert(Position.within($('body_absolute'), 10, 19), 'left/bottom corner');
assert(!Position.within($('body_absolute'), 10, 20), 'outside bottom');
});
scrollTo(20,30);
Position.prepare();
Position.includeScrollOffsets = true;
assert(!Position.within($('body_absolute'), 9, 9), 'outside left/top');
assert(Position.within($('body_absolute'), 10, 10), 'left/top corner');
assert(Position.within($('body_absolute'), 10, 19), 'left/bottom corner');
assert(!Position.within($('body_absolute'), 10, 20), 'outside bottom');
}}
}, 'testlog');
// ]]>
</script>
</body>
</html>

View File

@ -0,0 +1,93 @@
<!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" xml:lang="en" lang="en">
<head>
<title>Prototype Unit test file</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script src="../../dist/prototype.js" type="text/javascript"></script>
<script src="../lib/unittest.js" type="text/javascript"></script>
<link rel="stylesheet" href="../test.css" type="text/css" />
<style type="text/css" media="screen">
/* <![CDATA[ */
#testcss1 { font-size:11px; color: #f00; }
#testcss2 { font-size:12px; color: #0f0; display: none; }
/* ]]> */
</style>
</head>
<body>
<h1>Prototype Unit test file</h1>
<p>
Test of utility functions in range.js
</p>
<!-- Log output -->
<div id="testlog"> </div>
<!-- Tests follow -->
<script type="text/javascript" language="javascript" charset="utf-8">
// <![CDATA[
new Test.Unit.Runner({
testInclude: function() {with(this) {
assert(!$R(0, 0, true).include(0));
assert($R(0, 0, false).include(0));
assert($R(0, 5, true).include(0));
assert($R(0, 5, true).include(4));
assert(!$R(0, 5, true).include(5));
assert($R(0, 5, false).include(0));
assert($R(0, 5, false).include(5));
assert(!$R(0, 5, false).include(6));
}},
testEach: function() {with(this) {
var results = [];
$R(0, 0, true).each(function(value) {
results.push(value);
});
assertEnumEqual([], results);
results = [];
$R(0, 3, false).each(function(value) {
results.push(value);
});
assertEnumEqual([0, 1, 2, 3], results);
}},
testAny: function() {with(this) {
assert(!$R(1, 1, true).any());
assert($R(0, 3, false).any(function(value) {
return value == 3;
}));
}},
testAll: function() {with(this) {
assert($R(1, 1, true).all());
assert($R(0, 3, false).all(function(value) {
return value <= 3;
}));
}},
testToArray: function() {with(this) {
assertEnumEqual([], $R(0, 0, true).toArray());
assertEnumEqual([0], $R(0, 0, false).toArray());
assertEnumEqual([0], $R(0, 1, true).toArray());
assertEnumEqual([0, 1], $R(0, 1, false).toArray());
assertEnumEqual([-3, -2, -1, 0, 1, 2], $R(-3, 3, true).toArray());
assertEnumEqual([-3, -2, -1, 0, 1, 2, 3], $R(-3, 3, false).toArray());
}},
testDefaultsToNotExclusive: function() {with(this) {
assertEnumEqual(
$R(-3,3), $R(-3,3,false)
);
}}
}, 'testlog');
// ]]>
</script>
</body>
</html>

View File

@ -0,0 +1,386 @@
<!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" xml:lang="en" lang="en"
xmlns:html="http://www.w3.org/1999/xhtml">
<head>
<title>Prototype Unit test file</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script src="../../dist/prototype.js" type="text/javascript"></script>
<script src="../lib/unittest.js" type="text/javascript"></script>
<link rel="stylesheet" href="../test.css" type="text/css" />
<style type="text/css" media="screen">
/* <![CDATA[ */
#testcss1 { font-size:11px; color: #f00; }
#testcss2 { font-size:12px; color: #0f0; display: none; }
/* ]]> */
</style>
</head>
<body>
<h1>Prototype Unit test file</h1>
<p>
Test of utility functions in selector.js
</p>
<div id="fixtures" style="display: none">
<h1 class="title">Some title <span>here</span></h1>
<p id="p" class="first summary">
<strong id="strong">This</strong> is a short blurb
<a id="link_1" class="first internal" rel="external nofollow" href="#">with a <em id="em2">link</em></a> or
<a id="link_2" class="internal highlight" href="#"><em id="em">two</em></a>.
Or <cite id="with_title" title="hello world!">a citation</cite>.
</p>
<ul id="list">
<li id="item_1" class="first"><a id="link_3" href="#" class="external"><span id="span">Another link</span></a></li>
<li id="item_2">Some text</li>
<li id="item_3" xml:lang="es-us" class="">Otra cosa</li>
</ul>
<!-- this form has a field with the name 'id',
therefore its ID property won't be 'troubleForm': -->
<form id="troubleForm">
<input type="hidden" name="id" id="hidden" />
<input type="text" name="disabled_text_field" id="disabled_text_field" disabled="disabled" />
<input type="text" name="enabled_text_field" id="enabled_text_field" />
<input type="checkbox" name="checkboxes" id="checked_box" checked="checked" value="Checked" />
<input type="checkbox" name="checkboxes" id="unchecked_box" value="Unchecked"/>
<input type="radio" name="radiobuttons" id="checked_radio" checked="checked" value="Checked" />
<input type="radio" name="radiobuttons" id="unchecked_radio" value="Unchecked" />
</form>
<div id="level1">
<span id="level2_1">
<span id="level3_1"></span>
<!-- This comment should be ignored by the adjacent selector -->
<span id="level3_2"></span>
</span>
<span id="level2_2">
<em id="level_only_child">
</em>
</span>
<div id="level2_3"></div>
</div> <!-- #level1 -->
<div id="dupContainer">
<span id="dupL1">
<span id="dupL2">
<span id="dupL3">
<span id="dupL4">
<span id="dupL5"></span>
</span>
</span>
</span>
</span>
</div> <!-- #dupContainer -->
<div id="grandfather"> grandfather
<div id="father" class="brothers men"> father
<div id="son"> son </div>
</div>
<div id="uncle" class="brothers men"> uncle </div>
</div>
<form id="commaParent" title="commas,are,good">
<input type="hidden" id="commaChild" name="foo" value="#commaOne,#commaTwo" />
<input type="hidden" id="commaTwo" name="foo2" value="oops" />
</form>
</div> <!-- #fixtures -->
<!-- Log output -->
<div id="testlog"> </div>
<!-- Tests follow -->
<script type="text/javascript" language="javascript" charset="utf-8">
// <![CDATA[
// Added by TDD - 2007.02.20
$RunBenchmarks = false;
new Test.Unit.Runner({
testSelectorWithTagName: function() {with(this) {
assertEnumEqual($A(document.getElementsByTagName('li')), $$('li'));
assertEnumEqual([$('strong')], $$('strong'));
assertEnumEqual([], $$('nonexistent'));
assertEnumEqual($A(document.getElementsByTagName('*')), $$('*'));
}},
testSelectorWithId: function() {with(this) {
assertEnumEqual([$('fixtures')], $$('#fixtures'));
assertEnumEqual([], $$('#nonexistent'));
assertEnumEqual([$('troubleForm')], $$('#troubleForm'));
}},
testSelectorWithClassName: function() {with(this) {
assertEnumEqual($('p', 'link_1', 'item_1'), $$('.first'));
assertEnumEqual([], $$('.second'));
}},
testSelectorWithTagNameAndId: function() {with(this) {
assertEnumEqual([$('strong')], $$('strong#strong'));
assertEnumEqual([], $$('p#strong'));
}},
testSelectorWithTagNameAndClassName: function() {with(this) {
assertEnumEqual($('link_1', 'link_2'), $$('a.internal'));
assertEnumEqual([$('link_2')], $$('a.internal.highlight'));
assertEnumEqual([$('link_2')], $$('a.highlight.internal'));
assertEnumEqual([], $$('a.highlight.internal.nonexistent'));
}},
testSelectorWithIdAndClassName: function() {with(this) {
assertEnumEqual([$('link_2')], $$('#link_2.internal'));
assertEnumEqual([$('link_2')], $$('.internal#link_2'));
assertEnumEqual([$('link_2')], $$('#link_2.internal.highlight'));
assertEnumEqual([], $$('#link_2.internal.nonexistent'));
}},
testSelectorWithTagNameAndIdAndClassName: function() {with(this) {
assertEnumEqual([$('link_2')], $$('a#link_2.internal'));
assertEnumEqual([$('link_2')], $$('a.internal#link_2'));
assertEnumEqual([$('item_1')], $$('li#item_1.first'));
assertEnumEqual([], $$('li#item_1.nonexistent'));
assertEnumEqual([], $$('li#item_1.first.nonexistent'));
}},
test$$MatchesAncestryWithTokensSeparatedByWhitespace: function() {with(this) {
assertEnumEqual($('em2', 'em', 'span'), $$('#fixtures a *'));
assertEnumEqual([$('p')], $$('div#fixtures p'));
}},
test$$CombinesResultsWhenMultipleExpressionsArePassed: function() {with(this) {
assertEnumEqual($('link_1', 'link_2', 'item_1', 'item_2', 'item_3'), $$('#p a', ' ul#list li '));
}},
testSelectorWithTagNameAndAttributeExistence: function() {with(this) {
assertEnumEqual($$('#fixtures h1'), $$('h1[class]'));
assertEnumEqual($$('#fixtures h1'), $$('h1[CLASS]'));
assertEnumEqual([$('item_3')], $$('li#item_3[class]'));
}},
testSelectorWithTagNameAndSpecificAttributeValue: function() {with(this) {
assertEnumEqual($('link_1', 'link_2', 'link_3'), $$('a[href="#"]'));
assertEnumEqual($('link_1', 'link_2', 'link_3'), $$('a[href=#]'));
}},
testSelectorWithTagNameAndWhitespaceTokenizedAttributeValue: function() {with(this) {
assertEnumEqual($('link_1', 'link_2'), $$('a[class~="internal"]'));
assertEnumEqual($('link_1', 'link_2'), $$('a[class~=internal]'));
}},
testSelectorWithUniversalAndHyphenTokenizedAttributeValue: function() {with(this) {
assertEnumEqual([$('item_3')], $$('*[xml:lang|="es"]'));
assertEnumEqual([$('item_3')], $$('*[xml:lang|="ES"]'));
}},
testSelectorWithTagNameAndNegatedAttributeValue: function() {with(this) {
assertEnumEqual([], $$('a[href!=#]'));
}},
test$$WithNestedAttributeSelectors: function() {with(this) {
assertEnumEqual([$('strong')], $$('div[style] p[id] strong'));
}},
testSelectorWithMultipleConditions: function() {with(this) {
assertEnumEqual([$('link_3')], $$('a[class~=external][href="#"]'));
assertEnumEqual([], $$('a[class~=external][href!="#"]'));
}},
testSelectorMatchElements: function() {with(this) {
assertElementsMatch(Selector.matchElements($('list').descendants(), 'li'), '#item_1', '#item_2', '#item_3');
assertElementsMatch(Selector.matchElements($('fixtures').descendants(), 'a.internal'), '#link_1', '#link_2');
assertEnumEqual([], Selector.matchElements($('fixtures').descendants(), 'p.last'));
}},
testSelectorFindElement: function() {with(this) {
assertElementMatches(Selector.findElement($('list').descendants(), 'li'), 'li#item_1.first');
assertElementMatches(Selector.findElement($('list').descendants(), 'li', 1), 'li#item_2');
assertElementMatches(Selector.findElement($('list').descendants(), 'li#item_3'), 'li');
assertEqual(undefined, Selector.findElement($('list').descendants(), 'em'));
}},
testSelectorWithSpaceInAttributeValue: function() {with(this) {
assertEnumEqual([$('with_title')], $$('cite[title="hello world!"]'));
}},
// AND NOW COME THOSE NEW TESTS AFTER ANDREW'S REWRITE!
testSelectorWithNamespacedAttributes: function() { with(this) {
if (Prototype.BrowserFeatures.XPath) {
assertUndefined(new Selector('html[xml:lang]').xpath);
assertUndefined(new Selector('body p[xml:lang]').xpath);
} else
info("Could not test XPath bypass: no XPath to begin with!");
}},
testSelectorWithChild: function() { with(this) {
assertEnumEqual($('link_1', 'link_2'), $$('p.first > a'));
assertEnumEqual($('father', 'uncle'), $$('div#grandfather > div'));
assertEnumEqual($('level2_1', 'level2_2'), $$('#level1>span'));
assertEnumEqual($('level2_1', 'level2_2'), $$('#level1 > span'));
assertEnumEqual($('level3_1', 'level3_2'), $$('#level2_1 > *'));
$RunBenchmarks && wait(500, function() {
benchmark(function() { $$('#level1 > span') }, 1000);
});
}},
testSelectorWithAdjacence: function() { with(this) {
assertEnumEqual([$('uncle')], $$('div.brothers + div.brothers'));
assertEnumEqual([$('uncle')], $$('div.brothers + div'));
assertEqual($('level2_2'), $$('#level2_1+span').reduce());
assertEqual($('level2_2'), $$('#level2_1 + span').reduce());
assertEqual($('level2_2'), $$('#level2_1 + *').reduce());
assertEnumEqual([], $$('#level2_2 + span'));
assertEqual($('level3_2'), $$('#level3_1 + span').reduce());
assertEqual($('level3_2'), $$('#level3_1 + *').reduce());
assertEnumEqual([], $$('#level3_2 + *'));
assertEnumEqual([], $$('#level3_1 + em'));
$RunBenchmarks && wait(500, function() {
benchmark(function() { $$('#level3_1 + span') }, 1000);
});
}},
testSelectorWithLaterSibling: function() { with(this) {
assertEnumEqual([$('list')], $$('h1 ~ ul'));
assertEqual($('level2_2'), $$('#level2_1 ~ span').reduce());
assertEnumEqual($('level2_2', 'level2_3'), $$('#level2_1 ~ *').reduce());
assertEnumEqual([], $$('#level2_2 ~ span'));
assertEnumEqual([], $$('#level3_2 ~ *'));
assertEnumEqual([], $$('#level3_1 ~ em'));
assertEnumEqual([$('level3_2')], $$('#level3_1 ~ #level3_2'));
assertEnumEqual([$('level3_2')], $$('span ~ #level3_2'));
assertEnumEqual([], $$('div ~ #level3_2'));
assertEnumEqual([], $$('div ~ #level2_3'));
$RunBenchmarks && wait(500, function() {
benchmark(function() { $$('#level2_1 ~ span') }, 1000);
});
}},
testSelectorWithNewAttributeOperators: function() { with(this) {
assertEnumEqual($('father', 'uncle'), $$('div[class^=bro]'), 'matching beginning of string');
assertEnumEqual($('father', 'uncle'), $$('div[class$=men]'), 'matching end of string');
assertEnumEqual($('father', 'uncle'), $$('div[class*="ers m"]'), 'matching substring')
assertEnumEqual($('level2_1', 'level2_2', 'level2_3'), $$('#level1 *[id^="level2_"]'));
assertEnumEqual($('level2_1', 'level2_2', 'level2_3'), $$('#level1 *[id^=level2_]'));
assertEnumEqual($('level2_1', 'level3_1'), $$('#level1 *[id$="_1"]'));
assertEnumEqual($('level2_1', 'level3_1'), $$('#level1 *[id$=_1]'));
assertEnumEqual($('level2_1', 'level3_2', 'level2_2', 'level2_3'), $$('#level1 *[id*="2"]'));
assertEnumEqual($('level2_1', 'level3_2', 'level2_2', 'level2_3'), $$('#level1 *[id*=2]'));
$RunBenchmarks && wait(500, function() {
benchmark(function() { $$('#level1 *[id^=level2_]') }, 1000, '[^=]');
benchmark(function() { $$('#level1 *[id$=_1]') }, 1000, '[$=]');
benchmark(function() { $$('#level1 *[id*=_2]') }, 1000, '[*=]');
});
}},
testSelectorWithDuplicates: function() { with(this) {
assertEnumEqual($$('div div'), $$('div div').uniq());
assertEnumEqual($('dupL2', 'dupL3', 'dupL4', 'dupL5'), $$('#dupContainer span span'));
$RunBenchmarks && wait(500, function() {
benchmark(function() { $$('#dupContainer span span') }, 1000);
});
}},
testSelectorWithFirstLastOnlyNthNthLastChild: function() { with(this) {
assertEnumEqual([$('level2_1')], $$('#level1>*:first-child'));
assertEnumEqual($('level2_1', 'level3_1', 'level_only_child'), $$('#level1 *:first-child'));
assertEnumEqual([$('level2_3')], $$('#level1>*:last-child'));
assertEnumEqual($('level3_2', 'level_only_child', 'level2_3'), $$('#level1 *:last-child'));
assertEnumEqual([$('level2_3')], $$('#level1>div:last-child'));
assertEnumEqual([$('level2_3')], $$('#level1 div:last-child'));
assertEnumEqual([], $$('#level1>div:first-child'));
assertEnumEqual([], $$('#level1>span:last-child'));
assertEnumEqual($('level2_1', 'level3_1'), $$('#level1 span:first-child'));
assertEnumEqual([], $$('#level1:first-child'));
assertEnumEqual([], $$('#level1>*:only-child'));
assertEnumEqual([$('level_only_child')], $$('#level1 *:only-child'));
assertEnumEqual([], $$('#level1:only-child'));
assertEnumEqual([$('link_2')], $$('#p *:nth-last-child(2)'), 'nth-last-child');
assertEnumEqual([$('link_2')], $$('#p *:nth-child(3)'), 'nth-child');
assertEnumEqual([$('link_2')], $$('#p a:nth-child(3)'), 'nth-child');
assertEnumEqual($('item_2', 'item_3'), $$('#list > li:nth-child(n+2)'));
assertEnumEqual($('item_1', 'item_2'), $$('#list > li:nth-child(-n+2)'));
$RunBenchmarks && wait(500, function() {
benchmark(function() { $$('#level1 *:first-child') }, 1000, ':first-child');
benchmark(function() { $$('#level1 *:last-child') }, 1000, ':last-child');
benchmark(function() { $$('#level1 *:only-child') }, 1000, ':only-child');
});
}},
testSelectorWithFirstLastNthNthLastOfType: function() {with(this) {
assertEnumEqual([$('link_2')], $$('#p a:nth-of-type(2)'), 'nth-of-type');
assertEnumEqual([$('link_1')], $$('#p a:nth-of-type(1)'), 'nth-of-type');
assertEnumEqual([$('link_2')], $$('#p a:nth-last-of-type(1)'), 'nth-last-of-type');
assertEnumEqual([$('link_1')], $$('#p a:first-of-type'), 'first-of-type');
assertEnumEqual([$('link_2')], $$('#p a:last-of-type'), 'last-of-type');
}},
testSelectorWithNot: function() {with(this) {
assertEnumEqual([$('link_2')], $$('#p a:not(a:first-of-type)'), 'first-of-type');
assertEnumEqual([$('link_1')], $$('#p a:not(a:last-of-type)'), 'last-of-type');
assertEnumEqual([$('link_2')], $$('#p a:not(a:nth-of-type(1))'), 'nth-of-type');
assertEnumEqual([$('link_1')], $$('#p a:not(a:nth-last-of-type(1))'), 'nth-last-of-type');
assertEnumEqual([$('link_2')], $$('#p a:not([rel~=nofollow])'), 'attribute 1');
assertEnumEqual([$('link_2')], $$('#p a:not(a[rel^=external])'), 'attribute 2');
assertEnumEqual([$('link_2')], $$('#p a:not(a[rel$=nofollow])'), 'attribute 3');
assertEnumEqual([$('em')], $$('#p a:not(a[rel$="nofollow"]) > em'), 'attribute 4')
}},
testSelectorWithEnabledDisabledChecked: function() {with(this) {
assertEnumEqual([$('disabled_text_field')], $$('#troubleForm > *:disabled'));
assertEnumEqual($('troubleForm').getInputs().without($('disabled_text_field')), $$('#troubleForm > *:enabled'));
assertEnumEqual($('checked_box', 'checked_radio'), $$('#troubleForm *:checked'));
}},
testSelectorWithEmpty: function() {with(this) {
$('level3_1').innerHTML = "\t\n\n\r\n\t ";
assertEnumEqual($('level3_1', 'level3_2', 'level_only_child', 'level2_3'), $$('#level1 *:empty'));
assertEnumEqual([$('level_only_child')], $$('#level_only_child:empty'));
}},
testIdenticalResultsFromEquivalentSelectors: function() {with(this) {
assertEnumEqual($$('div.brothers'), $$('div[class~=brothers]'));
assertEnumEqual($$('div.brothers'), $$('div[class~=brothers].brothers'));
assertEnumEqual($$('div:not(.brothers)'), $$('div:not([class~=brothers])'));
assertEnumEqual($$('li ~ li'), $$('li:not(:first-child)'));
assertEnumEqual($$('ul > li'), $$('ul > li:nth-child(n)'));
assertEnumEqual($$('ul > li:nth-child(even)'), $$('ul > li:nth-child(2n)'));
assertEnumEqual($$('ul > li:nth-child(odd)'), $$('ul > li:nth-child(2n+1)'));
assertEnumEqual($$('ul > li:first-child'), $$('ul > li:nth-child(1)'));
assertEnumEqual($$('ul > li:last-child'), $$('ul > li:nth-last-child(1)'));
assertEnumEqual($$('#troubleForm *:enabled'), $$('#troubleForm *:not(:disabled)'));
assertEnumEqual($$('ul > li:nth-child(n-999)'), $$('ul > li'));
}},
testSelectorsThatShouldReturnNothing: function() {with(this) {
assertEnumEqual([], $$('span:empty > *'));
assertEnumEqual([], $$('div.brothers:not(.brothers)'));
assertEnumEqual([], $$('#level2_2 :only-child:not(:last-child)'));
assertEnumEqual([], $$('#level2_2 :only-child:not(:first-child)'));
}},
testCommasFor$$: function() {with(this) {
assertEnumEqual($('list', 'p', 'link_1', 'item_1', 'item_3', 'troubleForm'), $$('#list, .first,*[xml:lang="es-us"] , #troubleForm'));
assertEnumEqual($('list', 'p', 'link_1', 'item_1', 'item_3', 'troubleForm'), $$('#list, .first,', '*[xml:lang="es-us"] , #troubleForm'));
assertEnumEqual($('commaParent', 'commaChild'), $$('form[title*="commas,"], input[value="#commaOne,#commaTwo"]'));
assertEnumEqual($('commaParent', 'commaChild'), $$('form[title*="commas,"]', 'input[value="#commaOne,#commaTwo"]'));
}},
testSelectorExtendsAllNodes: function(){ with(this) {
var element = document.createElement('div');
(3).times(function(){
element.appendChild(document.createElement('div'));
});
element.setAttribute('id','scratch_element');
$$('body')[0].appendChild(element);
var results = $$('#scratch_element div');
assert(typeof results[0].show == 'function');
assert(typeof results[1].show == 'function');
assert(typeof results[2].show == 'function');
}}
}, 'testlog');
// ]]>
</script>
</body>
</html>

View File

@ -0,0 +1,438 @@
<!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" xml:lang="en" lang="en">
<head>
<title>Prototype Unit test file</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script src="../../dist/prototype.js" type="text/javascript"></script>
<script src="../lib/unittest.js" type="text/javascript"></script>
<link rel="stylesheet" href="../test.css" type="text/css" />
<style type="text/css" media="screen">
/* <![CDATA[ */
#testcss1 { font-size:11px; color: #f00; }
#testcss2 { font-size:12px; color: #0f0; display: none; }
/* ]]> */
</style>
</head>
<body>
<h1>Prototype Unit test file</h1>
<p>
Test of utility functions in string.js
</p>
<!-- Log output -->
<div id="testlog"> </div>
<!-- Tests follow -->
<script type="text/javascript" language="javascript" charset="utf-8">
// <![CDATA[
var attackTarget;
var evalScriptsCounter = 0,
largeTextEscaped = '&lt;span&gt;test&lt;/span&gt;',
largeTextUnescaped = '<span>test</span>';
(2048).times(function(){
largeTextEscaped += ' ABC';
largeTextUnescaped += ' ABC';
});
new Test.Unit.Runner({
testInterpret: function(){with(this) {
assertIdentical('true', String.interpret(true));
assertIdentical('123', String.interpret(123));
assertIdentical('foo bar', String.interpret('foo bar'));
assertIdentical(
'object string',
String.interpret({ toString: function(){ return 'object string' } }));
assertIdentical('0', String.interpret(0));
assertIdentical('false', String.interpret(false));
assertIdentical('', String.interpret(undefined));
assertIdentical('', String.interpret(null));
assertIdentical('', String.interpret(''));
}},
testGsubWithReplacementFunction: function() {with(this) {
var source = 'foo boo boz';
assertEqual('Foo Boo BoZ',
source.gsub(/[^o]+/, function(match) {
return match[0].toUpperCase()
}));
assertEqual('f2 b2 b1z',
source.gsub(/o+/, function(match) {
return match[0].length;
}));
assertEqual('f0 b0 b1z',
source.gsub(/o+/, function(match) {
return match[0].length % 2;
}));
}},
testGsubWithReplacementString: function() {with(this) {
var source = 'foo boo boz';
assertEqual('foobooboz',
source.gsub(/\s+/, ''));
assertEqual(' z',
source.gsub(/(.)(o+)/, ''));
assertEqual('ウィメンズ2007<br/>クルーズコレクション',
'ウィメンズ2007\nクルーズコレクション'.gsub(/\n/,'<br/>'));
assertEqual('ウィメンズ2007<br/>クルーズコレクション',
'ウィメンズ2007\nクルーズコレクション'.gsub('\n','<br/>'));
}},
testGsubWithReplacementTemplateString: function() {with(this) {
var source = 'foo boo boz';
assertEqual('-oo-#{1}- -oo-#{1}- -o-#{1}-z',
source.gsub(/(.)(o+)/, '-#{2}-\\#{1}-'));
assertEqual('-foo-f- -boo-b- -bo-b-z',
source.gsub(/(.)(o+)/, '-#{0}-#{1}-'));
assertEqual('-oo-f- -oo-b- -o-b-z',
source.gsub(/(.)(o+)/, '-#{2}-#{1}-'));
assertEqual(' z',
source.gsub(/(.)(o+)/, '#{3}'));
}},
testSubWithReplacementFunction: function() {with(this) {
var source = 'foo boo boz';
assertEqual('Foo boo boz',
source.sub(/[^o]+/, function(match) {
return match[0].toUpperCase()
}), 1);
assertEqual('Foo Boo boz',
source.sub(/[^o]+/, function(match) {
return match[0].toUpperCase()
}, 2), 2);
assertEqual(source,
source.sub(/[^o]+/, function(match) {
return match[0].toUpperCase()
}, 0), 0);
assertEqual(source,
source.sub(/[^o]+/, function(match) {
return match[0].toUpperCase()
}, -1), -1);
}},
testSubWithReplacementString: function() {with(this) {
var source = 'foo boo boz';
assertEqual('oo boo boz',
source.sub(/[^o]+/, ''));
assertEqual('oooo boz',
source.sub(/[^o]+/, '', 2));
assertEqual('-f-oo boo boz',
source.sub(/[^o]+/, '-#{0}-'));
assertEqual('-f-oo- b-oo boz',
source.sub(/[^o]+/, '-#{0}-', 2));
}},
testScan: function() {with(this) {
var source = 'foo boo boz', results = [];
source.scan(/[o]+/, function(match) {
results.push(match[0].length);
});
assertEnumEqual([2, 2, 1], results);
assertEqual(source, source.scan(/x/, fail));
}},
testToArray: function() {with(this) {
assertEnumEqual([],''.toArray());
assertEnumEqual(['a'],'a'.toArray());
assertEnumEqual(['a','b'],'ab'.toArray());
assertEnumEqual(['f','o','o'],'foo'.toArray());
}},
/*
Note that camelize() differs from its Rails counterpart,
as it is optimized for dealing with JavaScript object
properties in conjunction with CSS property names:
- Looks for dashes, not underscores
- CamelCases first word if there is a front dash
*/
testCamelize: function() {with(this) {
assertEqual('', ''.camelize());
assertEqual('', '-'.camelize());
assertEqual('foo', 'foo'.camelize());
assertEqual('foo_bar', 'foo_bar'.camelize());
assertEqual('FooBar', '-foo-bar'.camelize());
assertEqual('FooBar', 'FooBar'.camelize());
assertEqual('fooBar', 'foo-bar'.camelize());
assertEqual('borderBottomWidth', 'border-bottom-width'.camelize());
assertEqual('classNameTest','class-name-test'.camelize());
assertEqual('classNameTest','className-test'.camelize());
assertEqual('classNameTest','class-nameTest'.camelize());
/* benchmark(function(){
'class-name-test'.camelize();
},10000); */
}},
testCapitalize: function() {with(this) {
assertEqual('',''.capitalize());
assertEqual('Ä','ä'.capitalize());
assertEqual('A','A'.capitalize());
assertEqual('Hello','hello'.capitalize());
assertEqual('Hello','HELLO'.capitalize());
assertEqual('Hello','Hello'.capitalize());
assertEqual('Hello world','hello WORLD'.capitalize());
}},
testUnderscore: function() {with(this) {
assertEqual('', ''.underscore());
assertEqual('_', '-'.underscore());
assertEqual('foo', 'foo'.underscore());
assertEqual('foo', 'Foo'.underscore());
assertEqual('foo_bar', 'foo_bar'.underscore());
assertEqual('border_bottom', 'borderBottom'.underscore());
assertEqual('border_bottom_width', 'borderBottomWidth'.underscore());
assertEqual('border_bottom_width', 'border-Bottom-Width'.underscore());
}},
testDasherize: function() {with(this) {
assertEqual('', ''.dasherize());
assertEqual('foo', 'foo'.dasherize());
assertEqual('Foo', 'Foo'.dasherize());
assertEqual('foo-bar', 'foo-bar'.dasherize());
assertEqual('border-bottom-width', 'border_bottom_width'.dasherize());
}},
testTruncate: function() {with(this) {
var source = 'foo boo boz foo boo boz foo boo boz foo boo boz';
assertEqual(source, source.truncate(source.length));
assertEqual('foo boo boz foo boo boz foo...', source.truncate(0));
assertEqual('fo...', source.truncate(5));
assertEqual('foo b', source.truncate(5, ''));
}},
testStrip: function() {with(this) {
assertEqual('hello world', ' hello world '.strip());
assertEqual('hello world', 'hello world'.strip());
assertEqual('hello \n world', ' hello \n world '.strip());
assertEqual('', ' '.strip());
}},
testStripTags: function() {with(this) {
assertEqual('hello world', 'hello world'.stripTags());
assertEqual('hello world', 'hello <span>world</span>'.stripTags());
assertEqual('hello world', '<a href="#" onclick="moo!">hello</a> world'.stripTags());
assertEqual('hello world', 'h<b><em>e</em></b>l<i>l</i>o w<span class="moo" id="x"><b>o</b></span>rld'.stripTags());
assertEqual('1\n2', '1\n2'.stripTags());
}},
testStripScripts: function() {with(this) {
assertEqual('foo bar', 'foo bar'.stripScripts());
assertEqual('foo bar', ('foo <script>boo();<'+'/script>bar').stripScripts());
assertEqual('foo bar', ('foo <script type="text/javascript">boo();\nmoo();<'+'/script>bar').stripScripts());
}},
testExtractScripts: function() {with(this) {
assertEnumEqual([], 'foo bar'.extractScripts());
assertEnumEqual(['boo();'], ('foo <script>boo();<'+'/script>bar').extractScripts());
assertEnumEqual(['boo();','boo();\nmoo();'],
('foo <script>boo();<'+'/script><script type="text/javascript">boo();\nmoo();<'+'/script>bar').extractScripts());
assertEnumEqual(['boo();','boo();\nmoo();'],
('foo <script>boo();<'+'/script>blub\nblub<script type="text/javascript">boo();\nmoo();<'+'/script>bar').extractScripts());
}},
testEvalScripts: function() {with(this) {
assertEqual(0, evalScriptsCounter);
('foo <script>evalScriptsCounter++<'+'/script>bar').evalScripts();
assertEqual(1, evalScriptsCounter);
var stringWithScripts = '';
(3).times(function(){ stringWithScripts += 'foo <script>evalScriptsCounter++<'+'/script>bar' });
stringWithScripts.evalScripts();
assertEqual(4, evalScriptsCounter);
}},
testEscapeHTML: function() {with(this) {
assertEqual('foo bar', 'foo bar'.escapeHTML());
assertEqual('foo &lt;span&gt;bar&lt;/span&gt;', 'foo <span>bar</span>'.escapeHTML());
assertEqual('foo ß bar', 'foo ß bar'.escapeHTML());
assertEqual('ウィメンズ2007\nクルーズコレクション',
'ウィメンズ2007\nクルーズコレクション'.escapeHTML());
assertEqual('a&lt;a href="blah"&gt;blub&lt;/a&gt;b&lt;span&gt;&lt;div&gt;&lt;/div&gt;&lt;/span&gt;cdef&lt;strong&gt;!!!!&lt;/strong&gt;g',
'a<a href="blah">blub</a>b<span><div></div></span>cdef<strong>!!!!</strong>g'.escapeHTML());
assertEqual(largeTextEscaped, largeTextUnescaped.escapeHTML());
assertEqual('1\n2', '1\n2'.escapeHTML());
benchmark(function(){
largeTextUnescaped.escapeHTML();
},1000);
}},
testUnescapeHTML: function() {with(this) {
assertEqual('foo bar', 'foo bar'.unescapeHTML());
assertEqual('foo <span>bar</span>', 'foo &lt;span&gt;bar&lt;/span&gt;'.unescapeHTML());
assertEqual('foo ß bar', 'foo ß bar'.unescapeHTML());
assertEqual('a<a href="blah">blub</a>b<span><div></div></span>cdef<strong>!!!!</strong>g',
'a&lt;a href="blah"&gt;blub&lt;/a&gt;b&lt;span&gt;&lt;div&gt;&lt;/div&gt;&lt;/span&gt;cdef&lt;strong&gt;!!!!&lt;/strong&gt;g'.unescapeHTML());
assertEqual(largeTextUnescaped, largeTextEscaped.unescapeHTML());
assertEqual('1\n2', '1\n2'.unescapeHTML());
benchmark(function(){
largeTextEscaped.unescapeHTML();
},1000);
}},
testTemplateEvaluation: function() {with(this) {
var source = '<tr><td>#{name}</td><td>#{age}</td></tr>';
var person = {name: 'Sam', age: 21};
var template = new Template(source);
assertEqual('<tr><td>Sam</td><td>21</td></tr>',
template.evaluate(person));
assertEqual('<tr><td></td><td></td></tr>',
template.evaluate({}));
}},
testTemplateEvaluationWithFalses: function() {with(this) {
var source = '<tr><td>#{zero}</td><td>#{false_}</td><td>#{undef}</td><td>#{null_}</td><td>#{empty}</td></tr>';
var falses = {zero:0, false_:false, undef:undefined, null_:null, empty:""};
var template = new Template(source);
assertEqual('<tr><td>0</td><td>false</td><td></td><td></td><td></td></tr>',
template.evaluate(falses));
}},
testToQueryParams: function() {with(this) {
// only the query part
var result = {a:undefined, b:'c'};
assertHashEqual({}, ''.toQueryParams(), 'empty query');
assertHashEqual({}, 'foo?'.toQueryParams(), 'empty query with URL');
assertHashEqual(result, 'foo?a&b=c'.toQueryParams(), 'query with URL');
assertHashEqual(result, 'foo?a&b=c#fragment'.toQueryParams(), 'query with URL and fragment');
assertHashEqual(result, 'a;b=c'.toQueryParams(';'), 'custom delimiter');
assertHashEqual({a:undefined}, 'a'.toQueryParams(), 'key without value');
assertHashEqual({a:'b'}, 'a=b&=c'.toQueryParams(), 'empty key');
assertHashEqual({a:'b', c:''}, 'a=b&c='.toQueryParams(), 'empty value');
assertHashEqual({'a b':'c', d:'e f', g:'h'},
'a%20b=c&d=e%20f&g=h'.toQueryParams(), 'proper decoding');
assertHashEqual({a:'b=c=d'}, 'a=b=c=d'.toQueryParams(), 'multiple equal signs');
assertHashEqual({a:'b', c:'d'}, '&a=b&&&c=d'.toQueryParams(), 'proper splitting');
assertEnumEqual($w('r g b'), 'col=r&col=g&col=b'.toQueryParams()['col'],
'collection without square brackets');
var msg = 'empty values inside collection';
assertEnumEqual(['r', '', 'b'], 'c=r&c=&c=b'.toQueryParams()['c'], msg);
assertEnumEqual(['', 'blue'], 'c=&c=blue'.toQueryParams()['c'], msg);
assertEnumEqual(['blue', ''], 'c=blue&c='.toQueryParams()['c'], msg);
}},
testInspect: function() {with(this) {
assertEqual('\'\'', ''.inspect());
assertEqual('\'test\'', 'test'.inspect());
assertEqual('\'test \\\'test\\\' "test"\'', 'test \'test\' "test"'.inspect());
assertEqual('\"test \'test\' \\"test\\"\"', 'test \'test\' "test"'.inspect(true));
assertEqual('\'\\b\\t\\n\\f\\r"\\\\\'', '\b\t\n\f\r"\\'.inspect());
assertEqual('\"\\b\\t\\n\\f\\r\\"\\\\\"', '\b\t\n\f\r"\\'.inspect(true));
assertEqual('\'\\b\\t\\n\\f\\r\'', '\x08\x09\x0a\x0c\x0d'.inspect());
assertEqual('\'\\u001a\'', '\x1a'.inspect());
}},
testInclude: function() {with(this) {
assert('hello world'.include('h'));
assert('hello world'.include('hello'));
assert('hello world'.include('llo w'));
assert('hello world'.include('world'));
assert(!'hello world'.include('bye'));
assert(!''.include('bye'));
}},
testStartsWith: function() {with(this) {
assert('hello world'.startsWith('h'));
assert('hello world'.startsWith('hello'));
assert(!'hello world'.startsWith('bye'));
assert(!''.startsWith('bye'));
assert(!'hell'.startsWith('hello'));
}},
testEndsWith: function() {with(this) {
assert('hello world'.endsWith('d'));
assert('hello world'.endsWith(' world'));
assert(!'hello world'.endsWith('planet'));
assert(!''.endsWith('planet'));
assert('hello world world'.endsWith(' world'));
assert(!'z'.endsWith('az'));
}},
testBlank: function() { with(this) {
assert(''.blank());
assert(' '.blank());
assert('\t\r\n '.blank());
assert(!'a'.blank());
assert(!'\t y \n'.blank());
}},
testEmpty: function() { with(this) {
assert(''.empty());
assert(!' '.empty());
assert(!'\t\r\n '.empty());
assert(!'a'.empty());
assert(!'\t y \n'.empty());
}},
testSucc: function() {with(this) {
assertEqual('b', 'a'.succ());
assertEqual('B', 'A'.succ());
assertEqual('1', '0'.succ());
assertEqual('abce', 'abcd'.succ());
assertEqual('{', 'z'.succ());
assertEqual(':', '9'.succ());
}},
testTimes: function() {with(this) {
assertEqual('', ''.times(0));
assertEqual('', ''.times(5));
assertEqual('', 'a'.times(0));
assertEqual('a', 'a'.times(1));
assertEqual('aaaaa', 'a'.times(5));
assertEqual('foofoofoofoofoo', 'foo'.times(5));
assertEqual('', 'foo'.times(-5));
}},
testToJSON: function() {with(this) {
assertEqual('\"\"', ''.toJSON());
assertEqual('\"test\"', 'test'.toJSON());
}},
testEvalJSON: function() {with(this) {
var valid = '{test: "hello world!"}';
var invalid = '{test: "hello world!"';
var dangerous = '{});attackTarget = "attack succeeded!";({}';
assertEqual('hello world!', valid.evalJSON().test);
assertEqual('hello world!', valid.evalJSON(true).test);
assertRaise('SyntaxError', function(){invalid.evalJSON();});
assertRaise('SyntaxError', function(){invalid.evalJSON(true);});
attackTarget = "scared";
dangerous.evalJSON();
assertEqual("attack succeeded!", attackTarget);
attackTarget = "Not scared!";
assertRaise('SyntaxError', function(){dangerous.evalJSON(true)});
assertEqual("Not scared!", attackTarget);
}}
}, 'testlog');
// ]]>
</script>
</body>
</html>

View File

@ -0,0 +1,170 @@
<!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" xml:lang="en" lang="en">
<head>
<title>Prototype Unit test file</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script src="../../dist/prototype.js" type="text/javascript"></script>
<script src="../lib/unittest.js" type="text/javascript"></script>
<link rel="stylesheet" href="../test.css" type="text/css" />
<style type="text/css" media="screen">
/* <![CDATA[ */
#testcss1 { font-size:11px; color: #f00; }
#testcss2 { font-size:12px; color: #0f0; display: none; }
/* ]]> */
</style>
</head>
<body>
<h1>Prototype Unit test file</h1>
<p>
Test the unit testing library (unittest.js)
</p>
<!-- Log output -->
<div id="testlog"> </div>
<!-- Test elements follow -->
<div id="test_1" class="a bbbbbbbbbbbb cccccccccc dddd"> </div>
<div id="test_2"> <span> </span>
<div><div></div> </div><span> </span>
</div>
<ul id="tlist"><li id="tlist_1">x1</li><li id="tlist_2">x2</li></ul>
<ul id="tlist2"><li class="a" id="tlist2_1">x1</li><li id="tlist2_2">x2</li></ul>
<div id="testmoveby" style="background-color:#333;width:100px;">XXXX</div>
<div id="testcss1">testcss1<span id="testcss1_span" style="display:none;">blah</span></div><div id="testcss2">testcss1</div>
<!-- Tests follow -->
<script type="text/javascript" language="javascript" charset="utf-8">
// <![CDATA[
var testObj = {
isNice: function(){
return true;
},
isBroken: function(){
return false;
}
}
new Test.Unit.Runner({
testAssertEqual: function() { with(this) {
assertEqual(0, 0);
assertEqual(0, 0, "test");
assertEqual(0,'0');
assertEqual(65.0, 65);
assertEqual("a", "a");
assertEqual("a", "a", "test");
assertNotEqual(0, 1);
assertNotEqual("a","b");
assertNotEqual({},{});
assertNotEqual([],[]);
assertNotEqual([],{});
}},
testAssertEnumEqual: function() { with(this) {
assertEnumEqual([], []);
assertEnumEqual(['a', 'b'], ['a', 'b']);
assertEnumEqual(['1', '2'], [1, 2]);
assertEnumNotEqual(['1', '2'], [1, 2, 3]);
}},
testAssertHashEqual: function() { with(this) {
assertHashEqual({}, {});
assertHashEqual({a:'b'}, {a:'b'});
assertHashEqual({a:'b', c:'d'}, {c:'d', a:'b'});
assertHashNotEqual({a:'b', c:'d'}, {c:'d', a:'boo!'});
}},
testAssertRespondsTo: function() { with(this) {
assertRespondsTo('isNice', testObj);
assertRespondsTo('isBroken', testObj);
}},
testAssertIdentical: function() { with(this) {
assertIdentical(0, 0);
assertIdentical(0, 0, "test");
assertIdentical(1, 1);
assertIdentical('a', 'a');
assertIdentical('a', 'a', "test");
assertIdentical('', '');
assertIdentical(undefined, undefined);
assertIdentical(null, null);
assertIdentical(true, true);
assertIdentical(false, false);
var obj = {a:'b'};
assertIdentical(obj, obj);
assertNotIdentical({1:2,3:4},{1:2,3:4});
assertIdentical(1, 1.0); // both are typeof == 'number'
assertNotIdentical(1, '1');
assertNotIdentical(1, '1.0');
}},
testAssertNullAndAssertUndefined: function() { with(this) {
assertNull(null);
assertNotNull(undefined);
assertNotNull(0);
assertNotNull('');
assertNotUndefined(null);
assertUndefined(undefined);
assertNotUndefined(0);
assertNotUndefined('');
assertNullOrUndefined(null);
assertNullOrUndefined(undefined);
assertNotNullOrUndefined(0);
assertNotNullOrUndefined('');
}},
testAssertMatch: function() { with(this) {
assertMatch(/knowmad.jpg$/, 'http://script.aculo.us/images/knowmad.jpg');
assertMatch(/Fuc/, 'Thomas Fuchs');
assertMatch(/^\$(\d{1,3}(\,\d{3})*|(\d+))(\.\d{2})?$/, '$19.95');
assertMatch(/(\d{3}\) ?)|(\d{3}[- \.])?\d{3}[- \.]\d{4}(\s(x\d+)?){0,1}$/, '704-343-9330');
assertMatch(/^(?:(?:(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00)))(\/|-|\.)(?:0?2\1(?:29)))|(?:(?:(?:1[6-9]|[2-9]\d)?\d{2})(\/|-|\.)(?:(?:(?:0?[13578]|1[02])\2(?:31))|(?:(?:0?[1,3-9]|1[0-2])\2(29|30))|(?:(?:0?[1-9])|(?:1[0-2]))\2(?:0?[1-9]|1\d|2[0-8]))))$/, '2001-06-16');
assertMatch(/^((0?[123456789])|(1[012]))\s*:\s*([012345]\d)(\s*:\s*([012345]\d))?\s*[ap]m\s*-\s*((0?[123456789])|(1[012]))\s*:\s*([012345]\d)(\s*:\s*([012345]\d))?\s*[ap]m$/i, '2:00PM-2:15PM');
assertNoMatch(/zubar/, 'foo bar');
}},
testAssertInstanceOf: function() { with(this) {
assertInstanceOf(String, new String);
assertInstanceOf(RegExp, /foo/);
assertNotInstanceOf(String, {});
}},
testAssertVisible: function() { with(this) {
assertVisible('testcss1');
assertNotVisible('testcss1_span');
//assertNotVisible('testcss2', "Due to a Safari bug, this test fails in Safari.");
Element.hide('testcss1');
assertNotVisible('testcss1');
assertNotVisible('testcss1_span');
Element.show('testcss1');
assertVisible('testcss1');
assertNotVisible('testcss1_span');
Element.show('testcss1_span');
assertVisible('testcss1_span');
Element.hide('testcss1');
assertNotVisible('testcss1_span'); // hidden by parent
}}
}, "testlog");
// ]]>
</script>
</body>
</html>

View File

@ -0,0 +1,14 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for Prototype</title>
<script type="text/javascript" src="../lib/MochiKit_packed.js"></script>
<script type="text/javascript" src="../lib/SimpleTest.js"></script>
<script type="text/javascript" src="../lib/AJAX_setup.js"></script>
<link rel="stylesheet" type="text/css" href="../lib/test.css" />
</head>
<body>
<iframe width="100%" height="500" id="testframe" src=""></iframe>
</body>
</html>