seperated test files into JS and HTML fixtures. Added Ruby test file builder and test template.

This commit is contained in:
Tobie Langel 2008-04-16 16:51:20 +02:00
parent a1d89b4503
commit 81de0e3a77
44 changed files with 4966 additions and 5315 deletions

View File

@ -46,7 +46,7 @@ Rake::PackageTask.new('prototype', PROTOTYPE_VERSION) do |package|
end
desc "Builds the distribution, runs the JavaScript unit tests and collects their results."
task :test => [:dist, :test_units]
task :test => [:build_tests, :dist, :test_units]
require 'test/lib/jstest'
desc "Runs all the JavaScript unit tests and collects the results"
@ -58,9 +58,9 @@ JavaScriptTestTask.new(:test_units) do |t|
t.mount("/dist")
t.mount("/test")
Dir["test/unit/*.html"].sort.each do |test_file|
Dir["test/unit/tmp/*_test.html"].sort.each do |test_file|
tests = testcases ? { :url => "/#{test_file}", :testcases => testcases } : "/#{test_file}"
test_filename = test_file[/.*\/(.+?)\.html/, 1]
test_filename = test_file[/.*\/(.+?)_test\.html/, 1]
t.run(tests) unless tests_to_run && !tests_to_run.include?(test_filename)
end
@ -69,6 +69,8 @@ JavaScriptTestTask.new(:test_units) do |t|
end
end
task :clean_package_source do
rm_rf File.join(PROTOTYPE_PKG_DIR, "prototype-#{PROTOTYPE_VERSION}")
end
task :build_tests do
Dir["test/unit/*_test.js"].each do |test_file|
TestBuilder.new(test_file).render
end
end

View File

@ -3,6 +3,7 @@ require 'thread'
require 'webrick'
require 'fileutils'
include FileUtils
require 'erb'
class Browser
def supported?; true; end
@ -380,3 +381,38 @@ class JavaScriptTestTask < ::Rake::TaskLib
@browsers<<browser
end
end
class TestBuilder
UNITTEST_DIR = File.expand_path('test')
TEMPLATE = File.join(UNITTEST_DIR, 'lib', 'template.erb')
FIXTURES_EXTENSION = "html"
FIXTURES_DIR = File.join(UNITTEST_DIR, 'unit', 'fixtures')
def initialize(filename)
@filename = filename
@js_filename = File.basename(@filename)
@basename = @js_filename.sub("_test.js", "")
@fixtures_filename = "#{@basename}.#{FIXTURES_EXTENSION}"
@title = @basename.gsub("_", " ").strip.capitalize
end
def find_fixtures
@fixtures = ""
file = File.join(FIXTURES_DIR, @fixtures_filename)
if File.exists?(file)
File.open(file).each { |line| @fixtures << line }
end
end
def render
find_fixtures
File.open(destination, "w+") do |file|
file << ERB.new(IO.read(TEMPLATE), nil, "%").result(binding)
end
end
def destination
basename = File.basename(@filename, ".js")
File.join(UNITTEST_DIR, 'unit', 'tmp', "#{basename}.html")
end
end

33
test/lib/template.erb Normal file
View File

@ -0,0 +1,33 @@
<!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 %></title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script type="text/javascript" charset="utf-8">
var eventResults = {};
var originalElement = Element;
</script>
<script src="../../../dist/prototype.js" type="text/javascript"></script>
<script src="../../lib/unittest.js" type="text/javascript"></script>
<script src="../<%= @js_filename %>" type="text/javascript"></script>
<link rel="stylesheet" href="../../test.css" type="text/css" />
</head>
<body>
<h1>Prototype Unit test file</h1>
<h2><%= @title %></h2>
<!-- This file is programmatically generated. Do not attempt to modify it. Instead, modify <%= @fixtures_filename %> -->
<!-- Log output -->
<div id="testlog"></div>
<!-- Fixtures start -->
<%= @fixtures %>
<!-- Fixtures end -->
</body>
</html>
<script type="text/javascript" charset="utf-8">
eventResults.endOfDocument = true;
</script>

BIN
test/unit/.DS_Store vendored Normal file

Binary file not shown.

View File

@ -1,451 +0,0 @@
<!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" />
</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 Fixtures = {
js: {
responseBody: '$("content").update("<H2>Hello world!</H2>");',
'Content-Type': ' text/javascript '
},
html: {
responseBody: "Pack my box with <em>five dozen</em> liquor jugs! " +
"Oh, how <strong>quickly</strong> daft jumping zebras vex..."
},
xml: {
responseBody: '<?xml version="1.0" encoding="UTF-8" ?><name attr="foo">bar</name>',
'Content-Type': 'application/xml'
},
json: {
responseBody: '{\n\r"test": 123}',
'Content-Type': 'application/json'
},
jsonWithoutContentType: {
responseBody: '{"test": 123}'
},
invalidJson: {
responseBody: '{});window.attacked = true;({}',
'Content-Type': 'application/json'
},
headerJson: {
'X-JSON': '{"test": "hello #éà"}'
}
};
var extendDefault = function(options) {
return Object.extend({
asynchronous: false,
method: 'get',
onException: function(e) { throw e }
}, options);
};
var responderCounter = 0;
// 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();
var message = 'You must be running your tests from rake to test this feature.';
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() {
this.assertEqual("", $("content").innerHTML);
this.assertEqual(0, Ajax.activeRequestCount);
new Ajax.Request("fixtures/hello.js", {
asynchronous: false,
method: 'GET',
evalJS: 'force'
});
this.assertEqual(0, Ajax.activeRequestCount);
var h2 = $("content").firstChild;
this.assertEqual("Hello world!", h2.innerHTML);
},
testAsynchronousRequest: function() {
this.assertEqual("", $("content").innerHTML);
new Ajax.Request("fixtures/hello.js", {
asynchronous: true,
method: 'get',
evalJS: 'force'
});
this.wait(1000, function() {
var h2 = $("content").firstChild;
this.assertEqual("Hello world!", h2.innerHTML);
});
},
testUpdater: function() {
this.assertEqual("", $("content").innerHTML);
new Ajax.Updater("content", "fixtures/content.html", { method:'get' });
this.wait(1000, function() {
this.assertEqual(sentence, $("content").innerHTML.strip().toLowerCase());
$('content').update('');
this.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" });
this.wait(1000, function() {
this.assertEqual(sentence, $("content").innerHTML.strip().toLowerCase());
this.assertEqual("", $("content2").innerHTML);
});
});
},
testUpdaterWithInsertion: function() {
$('content').update();
new Ajax.Updater("content", "fixtures/content.html", { method:'get', insertion: Insertion.Top });
this.wait(1000, function() {
this.assertEqual(sentence, $("content").innerHTML.strip().toLowerCase());
$('content').update();
new Ajax.Updater("content", "fixtures/content.html", { method:'get', insertion: 'bottom' });
this.wait(1000, function() {
this.assertEqual(sentence, $("content").innerHTML.strip().toLowerCase());
$('content').update();
new Ajax.Updater("content", "fixtures/content.html", { method:'get', insertion: 'after' });
this.wait(1000, function() {
this.assertEqual('five dozen', $("content").next().innerHTML.strip().toLowerCase());
});
});
});
},
testUpdaterOptions: function() {
var options = {
method: 'get',
asynchronous: false,
evalJS: 'force',
onComplete: Prototype.emptyFunction
}
var request = new Ajax.Updater("content", "fixtures/hello.js", options);
request.options.onComplete = function() {};
this.assertIdentical(Prototype.emptyFunction, options.onComplete);
},
testResponders: function(){
// check for internal responder
this.assertEqual(1, Ajax.Responders.responders.length);
var dummyResponder = {
onComplete: function(req) { /* dummy */ }
};
Ajax.Responders.register(dummyResponder);
this.assertEqual(2, Ajax.Responders.responders.length);
// don't add twice
Ajax.Responders.register(dummyResponder);
this.assertEqual(2, Ajax.Responders.responders.length);
Ajax.Responders.unregister(dummyResponder);
this.assertEqual(1, Ajax.Responders.responders.length);
var responder = {
onCreate: function(req){ responderCounter++ },
onLoading: function(req){ responderCounter++ },
onComplete: function(req){ responderCounter++ }
};
Ajax.Responders.register(responder);
this.assertEqual(0, responderCounter);
this.assertEqual(0, Ajax.activeRequestCount);
new Ajax.Request("fixtures/content.html", { method:'get', parameters:"pet=monkey" });
this.assertEqual(1, responderCounter);
this.assertEqual(1, Ajax.activeRequestCount);
this.wait(1000,function() {
this.assertEqual(3, responderCounter);
this.assertEqual(0, Ajax.activeRequestCount);
});
},
testEvalResponseShouldBeCalledBeforeOnComplete: function() {
if (this.isRunningFromRake) {
this.assertEqual("", $("content").innerHTML);
this.assertEqual(0, Ajax.activeRequestCount);
new Ajax.Request("fixtures/hello.js", extendDefault({
onComplete: function(response) { this.assertNotEqual("", $("content").innerHTML) }.bind(this)
}));
this.assertEqual(0, Ajax.activeRequestCount);
var h2 = $("content").firstChild;
this.assertEqual("Hello world!", h2.innerHTML);
} else {
this.info(message);
}
},
testContentTypeSetForSimulatedVerbs: function() {
if (this.isRunningFromRake) {
new Ajax.Request('/inspect', extendDefault({
method: 'put',
contentType: 'application/bogus',
onComplete: function(response) {
this.assertEqual('application/bogus; charset=UTF-8', response.responseJSON.headers['content-type']);
}.bind(this)
}));
} else {
this.info(message);
}
},
testOnCreateCallback: function() {
new Ajax.Request("fixtures/content.html", extendDefault({
onCreate: function(transport) { this.assertEqual(0, transport.readyState) }.bind(this),
onComplete: function(transport) { this.assertNotEqual(0, transport.readyState) }.bind(this)
}));
},
testEvalJS: function() {
if (this.isRunningFromRake) {
$('content').update();
new Ajax.Request("/response", extendDefault({
parameters: Fixtures.js,
onComplete: function(transport) {
var h2 = $("content").firstChild;
this.assertEqual("Hello world!", h2.innerHTML);
}.bind(this)
}));
$('content').update();
new Ajax.Request("/response", extendDefault({
evalJS: false,
parameters: Fixtures.js,
onComplete: function(transport) {
this.assertEqual("", $("content").innerHTML);
}.bind(this)
}));
} else {
this.info(message);
}
$('content').update();
new Ajax.Request("fixtures/hello.js", extendDefault({
evalJS: 'force',
onComplete: function(transport) {
var h2 = $("content").firstChild;
this.assertEqual("Hello world!", h2.innerHTML);
}.bind(this)
}));
},
testCallbacks: function() {
var options = extendDefault({
onCreate: function(transport) { this.assertInstanceOf(Ajax.Response, transport) }.bind(this)
});
Ajax.Request.Events.each(function(state){
options['on' + state] = options.onCreate;
});
new Ajax.Request("fixtures/content.html", options);
},
testResponseText: function() {
new Ajax.Request("fixtures/empty.html", extendDefault({
onComplete: function(transport) { this.assertEqual('', transport.responseText) }.bind(this)
}));
new Ajax.Request("fixtures/content.html", extendDefault({
onComplete: function(transport) { this.assertEqual(sentence, transport.responseText.toLowerCase()) }.bind(this)
}));
},
testResponseXML: function() {
if (this.isRunningFromRake) {
new Ajax.Request("/response", extendDefault({
parameters: Fixtures.xml,
onComplete: function(transport) {
this.assertEqual('foo', transport.responseXML.getElementsByTagName('name')[0].getAttribute('attr'))
}.bind(this)
}));
} else {
this.info(message);
}
},
testResponseJSON: function() {
if (this.isRunningFromRake) {
new Ajax.Request("/response", extendDefault({
parameters: Fixtures.json,
onComplete: function(transport) { this.assertEqual(123, transport.responseJSON.test) }.bind(this)
}));
new Ajax.Request("/response", extendDefault({
parameters: {
'Content-Length': 0,
'Content-Type': 'application/json'
},
onComplete: function(transport) { this.assertNull(transport.responseJSON) }.bind(this)
}));
new Ajax.Request("/response", extendDefault({
evalJSON: false,
parameters: Fixtures.json,
onComplete: function(transport) { this.assertNull(transport.responseJSON) }.bind(this)
}));
new Ajax.Request("/response", extendDefault({
parameters: Fixtures.jsonWithoutContentType,
onComplete: function(transport) { this.assertNull(transport.responseJSON) }.bind(this)
}));
new Ajax.Request("/response", extendDefault({
sanitizeJSON: true,
parameters: Fixtures.invalidJson,
onException: function(request, error) {
this.assert(error.message.include('Badly formed JSON string'));
this.assertInstanceOf(Ajax.Request, request);
}.bind(this)
}));
} else {
this.info(message);
}
new Ajax.Request("fixtures/data.json", extendDefault({
evalJSON: 'force',
onComplete: function(transport) { this.assertEqual(123, transport.responseJSON.test) }.bind(this)
}));
},
testHeaderJSON: function() {
if (this.isRunningFromRake) {
new Ajax.Request("/response", extendDefault({
parameters: Fixtures.headerJson,
onComplete: function(transport, json) {
this.assertEqual('hello #éà', transport.headerJSON.test);
this.assertEqual('hello #éà', json.test);
}.bind(this)
}));
new Ajax.Request("/response", extendDefault({
onComplete: function(transport, json) {
this.assertNull(transport.headerJSON)
this.assertNull(json)
}.bind(this)
}));
} else {
this.info(message);
}
},
testGetHeader: function() {
if (this.isRunningFromRake) {
new Ajax.Request("/response", extendDefault({
parameters: { 'X-TEST': 'some value' },
onComplete: function(transport) {
this.assertEqual('some value', transport.getHeader('X-Test'));
this.assertNull(transport.getHeader('X-Inexistant'));
}.bind(this)
}));
} else {
this.info(message);
}
},
testParametersCanBeHash: function() {
if (this.isRunningFromRake) {
new Ajax.Request("/response", extendDefault({
parameters: $H({ "one": "two", "three": "four" }),
onComplete: function(transport) {
this.assertEqual("two", transport.getHeader("one"));
this.assertEqual("four", transport.getHeader("three"));
this.assertNull(transport.getHeader("toObject"));
}.bind(this)
}));
} else {
this.info(message);
}
},
testIsSameOriginMethod: function() {
var isSameOrigin = Ajax.Request.prototype.isSameOrigin;
this.assert(isSameOrigin.call({ url: '/foo/bar.html' }), '/foo/bar.html');
this.assert(isSameOrigin.call({ url: window.location.toString() }), window.location);
this.assert(!isSameOrigin.call({ url: 'http://example.com' }), 'http://example.com');
if (this.isRunningFromRake) {
Ajax.Request.prototype.isSameOrigin = function() {
return false
};
$("content").update('same origin policy');
new Ajax.Request("/response", extendDefault({
parameters: Fixtures.js,
onComplete: function(transport) {
this.assertEqual("same origin policy", $("content").innerHTML);
}.bind(this)
}));
new Ajax.Request("/response", extendDefault({
parameters: Fixtures.invalidJson,
onException: function(request, error) {
this.assert(error.message.include('Badly formed JSON string'));
}.bind(this)
}));
new Ajax.Request("/response", extendDefault({
parameters: { 'X-JSON': '{});window.attacked = true;({}' },
onException: function(request, error) {
this.assert(error.message.include('Badly formed JSON string'));
}.bind(this)
}));
Ajax.Request.prototype.isSameOrigin = isSameOrigin;
} else {
this.info(message);
}
}
});
// ]]>
</script>
</body>
</html>

422
test/unit/ajax_test.js Normal file
View File

@ -0,0 +1,422 @@
var Fixtures = {
js: {
responseBody: '$("content").update("<H2>Hello world!</H2>");',
'Content-Type': ' text/javascript '
},
html: {
responseBody: "Pack my box with <em>five dozen</em> liquor jugs! " +
"Oh, how <strong>quickly</strong> daft jumping zebras vex..."
},
xml: {
responseBody: '<?xml version="1.0" encoding="UTF-8" ?><name attr="foo">bar</name>',
'Content-Type': 'application/xml'
},
json: {
responseBody: '{\n\r"test": 123}',
'Content-Type': 'application/json'
},
jsonWithoutContentType: {
responseBody: '{"test": 123}'
},
invalidJson: {
responseBody: '{});window.attacked = true;({}',
'Content-Type': 'application/json'
},
headerJson: {
'X-JSON': '{"test": "hello #éà"}'
}
};
var extendDefault = function(options) {
return Object.extend({
asynchronous: false,
method: 'get',
onException: function(e) { throw e }
}, options);
};
var responderCounter = 0;
// 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();
var message = 'You must be running your tests from rake to test this feature.';
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() {
this.assertEqual("", $("content").innerHTML);
this.assertEqual(0, Ajax.activeRequestCount);
new Ajax.Request("../fixtures/hello.js", {
asynchronous: false,
method: 'GET',
evalJS: 'force'
});
this.assertEqual(0, Ajax.activeRequestCount);
var h2 = $("content").firstChild;
this.assertEqual("Hello world!", h2.innerHTML);
},
testAsynchronousRequest: function() {
this.assertEqual("", $("content").innerHTML);
new Ajax.Request("../fixtures/hello.js", {
asynchronous: true,
method: 'get',
evalJS: 'force'
});
this.wait(1000, function() {
var h2 = $("content").firstChild;
this.assertEqual("Hello world!", h2.innerHTML);
});
},
testUpdater: function() {
this.assertEqual("", $("content").innerHTML);
new Ajax.Updater("content", "../fixtures/content.html", { method:'get' });
this.wait(1000, function() {
this.assertEqual(sentence, $("content").innerHTML.strip().toLowerCase());
$('content').update('');
this.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" });
this.wait(1000, function() {
this.assertEqual(sentence, $("content").innerHTML.strip().toLowerCase());
this.assertEqual("", $("content2").innerHTML);
});
});
},
testUpdaterWithInsertion: function() {
$('content').update();
new Ajax.Updater("content", "../fixtures/content.html", { method:'get', insertion: Insertion.Top });
this.wait(1000, function() {
this.assertEqual(sentence, $("content").innerHTML.strip().toLowerCase());
$('content').update();
new Ajax.Updater("content", "../fixtures/content.html", { method:'get', insertion: 'bottom' });
this.wait(1000, function() {
this.assertEqual(sentence, $("content").innerHTML.strip().toLowerCase());
$('content').update();
new Ajax.Updater("content", "../fixtures/content.html", { method:'get', insertion: 'after' });
this.wait(1000, function() {
this.assertEqual('five dozen', $("content").next().innerHTML.strip().toLowerCase());
});
});
});
},
testUpdaterOptions: function() {
var options = {
method: 'get',
asynchronous: false,
evalJS: 'force',
onComplete: Prototype.emptyFunction
}
var request = new Ajax.Updater("content", "../fixtures/hello.js", options);
request.options.onComplete = function() {};
this.assertIdentical(Prototype.emptyFunction, options.onComplete);
},
testResponders: function(){
// check for internal responder
this.assertEqual(1, Ajax.Responders.responders.length);
var dummyResponder = {
onComplete: function(req) { /* dummy */ }
};
Ajax.Responders.register(dummyResponder);
this.assertEqual(2, Ajax.Responders.responders.length);
// don't add twice
Ajax.Responders.register(dummyResponder);
this.assertEqual(2, Ajax.Responders.responders.length);
Ajax.Responders.unregister(dummyResponder);
this.assertEqual(1, Ajax.Responders.responders.length);
var responder = {
onCreate: function(req){ responderCounter++ },
onLoading: function(req){ responderCounter++ },
onComplete: function(req){ responderCounter++ }
};
Ajax.Responders.register(responder);
this.assertEqual(0, responderCounter);
this.assertEqual(0, Ajax.activeRequestCount);
new Ajax.Request("../fixtures/content.html", { method:'get', parameters:"pet=monkey" });
this.assertEqual(1, responderCounter);
this.assertEqual(1, Ajax.activeRequestCount);
this.wait(1000,function() {
this.assertEqual(3, responderCounter);
this.assertEqual(0, Ajax.activeRequestCount);
});
},
testEvalResponseShouldBeCalledBeforeOnComplete: function() {
if (this.isRunningFromRake) {
this.assertEqual("", $("content").innerHTML);
this.assertEqual(0, Ajax.activeRequestCount);
new Ajax.Request("../fixtures/hello.js", extendDefault({
onComplete: function(response) { this.assertNotEqual("", $("content").innerHTML) }.bind(this)
}));
this.assertEqual(0, Ajax.activeRequestCount);
var h2 = $("content").firstChild;
this.assertEqual("Hello world!", h2.innerHTML);
} else {
this.info(message);
}
},
testContentTypeSetForSimulatedVerbs: function() {
if (this.isRunningFromRake) {
new Ajax.Request('/inspect', extendDefault({
method: 'put',
contentType: 'application/bogus',
onComplete: function(response) {
this.assertEqual('application/bogus; charset=UTF-8', response.responseJSON.headers['content-type']);
}.bind(this)
}));
} else {
this.info(message);
}
},
testOnCreateCallback: function() {
new Ajax.Request("../fixtures/content.html", extendDefault({
onCreate: function(transport) { this.assertEqual(0, transport.readyState) }.bind(this),
onComplete: function(transport) { this.assertNotEqual(0, transport.readyState) }.bind(this)
}));
},
testEvalJS: function() {
if (this.isRunningFromRake) {
$('content').update();
new Ajax.Request("/response", extendDefault({
parameters: Fixtures.js,
onComplete: function(transport) {
var h2 = $("content").firstChild;
this.assertEqual("Hello world!", h2.innerHTML);
}.bind(this)
}));
$('content').update();
new Ajax.Request("/response", extendDefault({
evalJS: false,
parameters: Fixtures.js,
onComplete: function(transport) {
this.assertEqual("", $("content").innerHTML);
}.bind(this)
}));
} else {
this.info(message);
}
$('content').update();
new Ajax.Request("../fixtures/hello.js", extendDefault({
evalJS: 'force',
onComplete: function(transport) {
var h2 = $("content").firstChild;
this.assertEqual("Hello world!", h2.innerHTML);
}.bind(this)
}));
},
testCallbacks: function() {
var options = extendDefault({
onCreate: function(transport) { this.assertInstanceOf(Ajax.Response, transport) }.bind(this)
});
Ajax.Request.Events.each(function(state){
options['on' + state] = options.onCreate;
});
new Ajax.Request("../fixtures/content.html", options);
},
testResponseText: function() {
new Ajax.Request("../fixtures/empty.html", extendDefault({
onComplete: function(transport) { this.assertEqual('', transport.responseText) }.bind(this)
}));
new Ajax.Request("../fixtures/content.html", extendDefault({
onComplete: function(transport) { this.assertEqual(sentence, transport.responseText.toLowerCase()) }.bind(this)
}));
},
testResponseXML: function() {
if (this.isRunningFromRake) {
new Ajax.Request("/response", extendDefault({
parameters: Fixtures.xml,
onComplete: function(transport) {
this.assertEqual('foo', transport.responseXML.getElementsByTagName('name')[0].getAttribute('attr'))
}.bind(this)
}));
} else {
this.info(message);
}
},
testResponseJSON: function() {
if (this.isRunningFromRake) {
new Ajax.Request("/response", extendDefault({
parameters: Fixtures.json,
onComplete: function(transport) { this.assertEqual(123, transport.responseJSON.test) }.bind(this)
}));
new Ajax.Request("/response", extendDefault({
parameters: {
'Content-Length': 0,
'Content-Type': 'application/json'
},
onComplete: function(transport) { this.assertNull(transport.responseJSON) }.bind(this)
}));
new Ajax.Request("/response", extendDefault({
evalJSON: false,
parameters: Fixtures.json,
onComplete: function(transport) { this.assertNull(transport.responseJSON) }.bind(this)
}));
new Ajax.Request("/response", extendDefault({
parameters: Fixtures.jsonWithoutContentType,
onComplete: function(transport) { this.assertNull(transport.responseJSON) }.bind(this)
}));
new Ajax.Request("/response", extendDefault({
sanitizeJSON: true,
parameters: Fixtures.invalidJson,
onException: function(request, error) {
this.assert(error.message.include('Badly formed JSON string'));
this.assertInstanceOf(Ajax.Request, request);
}.bind(this)
}));
} else {
this.info(message);
}
new Ajax.Request("../fixtures/data.json", extendDefault({
evalJSON: 'force',
onComplete: function(transport) { this.assertEqual(123, transport.responseJSON.test) }.bind(this)
}));
},
testHeaderJSON: function() {
if (this.isRunningFromRake) {
new Ajax.Request("/response", extendDefault({
parameters: Fixtures.headerJson,
onComplete: function(transport, json) {
this.assertEqual('hello #éà', transport.headerJSON.test);
this.assertEqual('hello #éà', json.test);
}.bind(this)
}));
new Ajax.Request("/response", extendDefault({
onComplete: function(transport, json) {
this.assertNull(transport.headerJSON)
this.assertNull(json)
}.bind(this)
}));
} else {
this.info(message);
}
},
testGetHeader: function() {
if (this.isRunningFromRake) {
new Ajax.Request("/response", extendDefault({
parameters: { 'X-TEST': 'some value' },
onComplete: function(transport) {
this.assertEqual('some value', transport.getHeader('X-Test'));
this.assertNull(transport.getHeader('X-Inexistant'));
}.bind(this)
}));
} else {
this.info(message);
}
},
testParametersCanBeHash: function() {
if (this.isRunningFromRake) {
new Ajax.Request("/response", extendDefault({
parameters: $H({ "one": "two", "three": "four" }),
onComplete: function(transport) {
this.assertEqual("two", transport.getHeader("one"));
this.assertEqual("four", transport.getHeader("three"));
this.assertNull(transport.getHeader("toObject"));
}.bind(this)
}));
} else {
this.info(message);
}
},
testIsSameOriginMethod: function() {
var isSameOrigin = Ajax.Request.prototype.isSameOrigin;
this.assert(isSameOrigin.call({ url: '/foo/bar.html' }), '/foo/bar.html');
this.assert(isSameOrigin.call({ url: window.location.toString() }), window.location);
this.assert(!isSameOrigin.call({ url: 'http://example.com' }), 'http://example.com');
if (this.isRunningFromRake) {
Ajax.Request.prototype.isSameOrigin = function() {
return false
};
$("content").update('same origin policy');
new Ajax.Request("/response", extendDefault({
parameters: Fixtures.js,
onComplete: function(transport) {
this.assertEqual("same origin policy", $("content").innerHTML);
}.bind(this)
}));
new Ajax.Request("/response", extendDefault({
parameters: Fixtures.invalidJson,
onException: function(request, error) {
this.assert(error.message.include('Badly formed JSON string'));
}.bind(this)
}));
new Ajax.Request("/response", extendDefault({
parameters: { 'X-JSON': '{});window.attacked = true;({}' },
onException: function(request, error) {
this.assert(error.message.include('Badly formed JSON string'));
}.bind(this)
}));
Ajax.Request.prototype.isSameOrigin = isSameOrigin;
} else {
this.info(message);
}
}
});

View File

@ -1,219 +0,0 @@
<!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" />
</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({
test$A: function(){
this.assertEnumEqual([], $A({}));
},
testToArrayOnArguments: function(){
function toArrayOnArguments(){
globalArgsTest = $A(arguments);
}
toArrayOnArguments();
this.assertEnumEqual([], globalArgsTest);
toArrayOnArguments('foo');
this.assertEnumEqual(['foo'], globalArgsTest);
toArrayOnArguments('foo','bar');
this.assertEnumEqual(['foo','bar'], globalArgsTest);
},
testToArrayOnNodeList: function(){
// direct HTML
this.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')) });
this.assertEqual(3, $A(element.childNodes).length);
// HTML String
element = document.createElement('div');
$(element).update('22<span></span><span></span');
this.assertEqual(3, $A(element.childNodes).length);
},
testClear: function(){
this.assertEnumEqual([], [].clear());
this.assertEnumEqual([], [1].clear());
this.assertEnumEqual([], [1,2].clear());
},
testClone: function(){
this.assertEnumEqual([], [].clone());
this.assertEnumEqual([1], [1].clone());
this.assertEnumEqual([1,2], [1,2].clone());
this.assertEnumEqual([0,1,2], [0,1,2].clone());
var a = [0,1,2];
var b = a;
this.assertIdentical(a, b);
b = a.clone();
this.assertNotIdentical(a, b);
},
testFirst: function(){
this.assertUndefined([].first());
this.assertEqual(1, [1].first());
this.assertEqual(1, [1,2].first());
},
testLast: function(){
this.assertUndefined([].last());
this.assertEqual(1, [1].last());
this.assertEqual(2, [1,2].last());
},
testCompact: function(){
this.assertEnumEqual([], [].compact());
this.assertEnumEqual([1,2,3], [1,2,3].compact());
this.assertEnumEqual([0,1,2,3], [0,null,1,2,undefined,3].compact());
this.assertEnumEqual([1,2,3], [null,1,2,3,null].compact());
},
testFlatten: function(){
this.assertEnumEqual([], [].flatten());
this.assertEnumEqual([1,2,3], [1,2,3].flatten());
this.assertEnumEqual([1,2,3], [1,[[[2,3]]]].flatten());
this.assertEnumEqual([1,2,3], [[1],[2],[3]].flatten());
this.assertEnumEqual([1,2,3], [[[[[[[1]]]]]],2,3].flatten());
},
testIndexOf: function(){
this.assertEqual(-1, [].indexOf(1));
this.assertEqual(-1, [0].indexOf(1));
this.assertEqual(0, [1].indexOf(1));
this.assertEqual(1, [0,1,2].indexOf(1));
this.assertEqual(0, [1,2,1].indexOf(1));
this.assertEqual(2, [1,2,1].indexOf(1, -1));
this.assertEqual(1, [undefined,null].indexOf(null));
},
testLastIndexOf: function(){
this.assertEqual(-1,[].lastIndexOf(1));
this.assertEqual(-1, [0].lastIndexOf(1));
this.assertEqual(0, [1].lastIndexOf(1));
this.assertEqual(2, [0,2,4,6].lastIndexOf(4));
this.assertEqual(3, [4,4,2,4,6].lastIndexOf(4));
this.assertEqual(3, [0,2,4,6].lastIndexOf(6,3));
this.assertEqual(-1, [0,2,4,6].lastIndexOf(6,2));
this.assertEqual(0, [6,2,4,6].lastIndexOf(6,2));
var fixture = [1,2,3,4,3];
this.assertEqual(4, fixture.lastIndexOf(3));
this.assertEnumEqual([1,2,3,4,3],fixture);
//tests from http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:lastIndexOf
var array = [2, 5, 9, 2];
this.assertEqual(3,array.lastIndexOf(2));
this.assertEqual(-1,array.lastIndexOf(7));
this.assertEqual(3,array.lastIndexOf(2,3));
this.assertEqual(0,array.lastIndexOf(2,2));
this.assertEqual(0,array.lastIndexOf(2,-2));
this.assertEqual(3,array.lastIndexOf(2,-1));
},
testInspect: function(){
this.assertEqual('[]',[].inspect());
this.assertEqual('[1]',[1].inspect());
this.assertEqual('[\'a\']',['a'].inspect());
this.assertEqual('[\'a\', 1]',['a',1].inspect());
},
testIntersect: function(){
this.assertEnumEqual([1,3], [1,1,3,5].intersect([1,2,3]));
this.assertEnumEqual([1], [1,1].intersect([1,1]));
this.assertEnumEqual([], [1,1,3,5].intersect([4]));
this.assertEnumEqual([], [1].intersect(['1']));
this.assertEnumEqual(
['B','C','D'],
$R('A','Z').toArray().intersect($R('B','D').toArray())
);
},
testToJSON: function(){
this.assertEqual('[]', [].toJSON());
this.assertEqual('[\"a\"]', ['a'].toJSON());
this.assertEqual('[\"a\", 1]', ['a', 1].toJSON());
this.assertEqual('[\"a\", {\"b\": null}]', ['a', {'b': null}].toJSON());
},
testReduce: function(){
this.assertUndefined([].reduce());
this.assertNull([null].reduce());
this.assertEqual(1, [1].reduce());
this.assertEnumEqual([1,2,3], [1,2,3].reduce());
this.assertEnumEqual([1,null,3], [1,null,3].reduce());
},
testReverse: function(){
this.assertEnumEqual([], [].reverse());
this.assertEnumEqual([1], [1].reverse());
this.assertEnumEqual([2,1], [1,2].reverse());
this.assertEnumEqual([3,2,1], [1,2,3].reverse());
},
testSize: function(){
this.assertEqual(4, [0, 1, 2, 3].size());
this.assertEqual(0, [].size());
},
testUniq: function(){
this.assertEnumEqual([1], [1, 1, 1].uniq());
this.assertEnumEqual([1], [1].uniq());
this.assertEnumEqual([], [].uniq());
this.assertEnumEqual([0, 1, 2, 3], [0, 1, 2, 2, 3, 0, 2].uniq());
this.assertEnumEqual([0, 1, 2, 3], [0, 0, 1, 1, 2, 3, 3, 3].uniq(true));
},
testWithout: function(){
this.assertEnumEqual([], [].without(0));
this.assertEnumEqual([], [0].without(0));
this.assertEnumEqual([1], [0,1].without(0));
this.assertEnumEqual([1,2], [0,1,2].without(0));
},
test$w: function(){
this.assertEnumEqual(['a', 'b', 'c', 'd'], $w('a b c d'));
this.assertEnumEqual([], $w(' '));
this.assertEnumEqual([], $w(''));
this.assertEnumEqual([], $w(null));
this.assertEnumEqual([], $w(undefined));
this.assertEnumEqual([], $w());
this.assertEnumEqual([], $w(10));
this.assertEnumEqual(['a'], $w('a'));
this.assertEnumEqual(['a'], $w('a '));
this.assertEnumEqual(['a'], $w(' a'));
this.assertEnumEqual(['a', 'b', 'c', 'd'], $w(' a b\nc\t\nd\n'));
}
});
// ]]>
</script>
</body>
</html>

189
test/unit/array_test.js Normal file
View File

@ -0,0 +1,189 @@
var globalArgsTest = 'nothing to see here';
new Test.Unit.Runner({
test$A: function(){
this.assertEnumEqual([], $A({}));
},
testToArrayOnArguments: function(){
function toArrayOnArguments(){
globalArgsTest = $A(arguments);
}
toArrayOnArguments();
this.assertEnumEqual([], globalArgsTest);
toArrayOnArguments('foo');
this.assertEnumEqual(['foo'], globalArgsTest);
toArrayOnArguments('foo','bar');
this.assertEnumEqual(['foo','bar'], globalArgsTest);
},
testToArrayOnNodeList: function(){
// direct HTML
this.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')) });
this.assertEqual(3, $A(element.childNodes).length);
// HTML String
element = document.createElement('div');
$(element).update('22<span></span><span></span');
this.assertEqual(3, $A(element.childNodes).length);
},
testClear: function(){
this.assertEnumEqual([], [].clear());
this.assertEnumEqual([], [1].clear());
this.assertEnumEqual([], [1,2].clear());
},
testClone: function(){
this.assertEnumEqual([], [].clone());
this.assertEnumEqual([1], [1].clone());
this.assertEnumEqual([1,2], [1,2].clone());
this.assertEnumEqual([0,1,2], [0,1,2].clone());
var a = [0,1,2];
var b = a;
this.assertIdentical(a, b);
b = a.clone();
this.assertNotIdentical(a, b);
},
testFirst: function(){
this.assertUndefined([].first());
this.assertEqual(1, [1].first());
this.assertEqual(1, [1,2].first());
},
testLast: function(){
this.assertUndefined([].last());
this.assertEqual(1, [1].last());
this.assertEqual(2, [1,2].last());
},
testCompact: function(){
this.assertEnumEqual([], [].compact());
this.assertEnumEqual([1,2,3], [1,2,3].compact());
this.assertEnumEqual([0,1,2,3], [0,null,1,2,undefined,3].compact());
this.assertEnumEqual([1,2,3], [null,1,2,3,null].compact());
},
testFlatten: function(){
this.assertEnumEqual([], [].flatten());
this.assertEnumEqual([1,2,3], [1,2,3].flatten());
this.assertEnumEqual([1,2,3], [1,[[[2,3]]]].flatten());
this.assertEnumEqual([1,2,3], [[1],[2],[3]].flatten());
this.assertEnumEqual([1,2,3], [[[[[[[1]]]]]],2,3].flatten());
},
testIndexOf: function(){
this.assertEqual(-1, [].indexOf(1));
this.assertEqual(-1, [0].indexOf(1));
this.assertEqual(0, [1].indexOf(1));
this.assertEqual(1, [0,1,2].indexOf(1));
this.assertEqual(0, [1,2,1].indexOf(1));
this.assertEqual(2, [1,2,1].indexOf(1, -1));
this.assertEqual(1, [undefined,null].indexOf(null));
},
testLastIndexOf: function(){
this.assertEqual(-1,[].lastIndexOf(1));
this.assertEqual(-1, [0].lastIndexOf(1));
this.assertEqual(0, [1].lastIndexOf(1));
this.assertEqual(2, [0,2,4,6].lastIndexOf(4));
this.assertEqual(3, [4,4,2,4,6].lastIndexOf(4));
this.assertEqual(3, [0,2,4,6].lastIndexOf(6,3));
this.assertEqual(-1, [0,2,4,6].lastIndexOf(6,2));
this.assertEqual(0, [6,2,4,6].lastIndexOf(6,2));
var fixture = [1,2,3,4,3];
this.assertEqual(4, fixture.lastIndexOf(3));
this.assertEnumEqual([1,2,3,4,3],fixture);
//tests from http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:lastIndexOf
var array = [2, 5, 9, 2];
this.assertEqual(3,array.lastIndexOf(2));
this.assertEqual(-1,array.lastIndexOf(7));
this.assertEqual(3,array.lastIndexOf(2,3));
this.assertEqual(0,array.lastIndexOf(2,2));
this.assertEqual(0,array.lastIndexOf(2,-2));
this.assertEqual(3,array.lastIndexOf(2,-1));
},
testInspect: function(){
this.assertEqual('[]',[].inspect());
this.assertEqual('[1]',[1].inspect());
this.assertEqual('[\'a\']',['a'].inspect());
this.assertEqual('[\'a\', 1]',['a',1].inspect());
},
testIntersect: function(){
this.assertEnumEqual([1,3], [1,1,3,5].intersect([1,2,3]));
this.assertEnumEqual([1], [1,1].intersect([1,1]));
this.assertEnumEqual([], [1,1,3,5].intersect([4]));
this.assertEnumEqual([], [1].intersect(['1']));
this.assertEnumEqual(
['B','C','D'],
$R('A','Z').toArray().intersect($R('B','D').toArray())
);
},
testToJSON: function(){
this.assertEqual('[]', [].toJSON());
this.assertEqual('[\"a\"]', ['a'].toJSON());
this.assertEqual('[\"a\", 1]', ['a', 1].toJSON());
this.assertEqual('[\"a\", {\"b\": null}]', ['a', {'b': null}].toJSON());
},
testReduce: function(){
this.assertUndefined([].reduce());
this.assertNull([null].reduce());
this.assertEqual(1, [1].reduce());
this.assertEnumEqual([1,2,3], [1,2,3].reduce());
this.assertEnumEqual([1,null,3], [1,null,3].reduce());
},
testReverse: function(){
this.assertEnumEqual([], [].reverse());
this.assertEnumEqual([1], [1].reverse());
this.assertEnumEqual([2,1], [1,2].reverse());
this.assertEnumEqual([3,2,1], [1,2,3].reverse());
},
testSize: function(){
this.assertEqual(4, [0, 1, 2, 3].size());
this.assertEqual(0, [].size());
},
testUniq: function(){
this.assertEnumEqual([1], [1, 1, 1].uniq());
this.assertEnumEqual([1], [1].uniq());
this.assertEnumEqual([], [].uniq());
this.assertEnumEqual([0, 1, 2, 3], [0, 1, 2, 2, 3, 0, 2].uniq());
this.assertEnumEqual([0, 1, 2, 3], [0, 0, 1, 1, 2, 3, 3, 3].uniq(true));
},
testWithout: function(){
this.assertEnumEqual([], [].without(0));
this.assertEnumEqual([], [0].without(0));
this.assertEnumEqual([1], [0,1].without(0));
this.assertEnumEqual([1,2], [0,1,2].without(0));
},
test$w: function(){
this.assertEnumEqual(['a', 'b', 'c', 'd'], $w('a b c d'));
this.assertEnumEqual([], $w(' '));
this.assertEnumEqual([], $w(''));
this.assertEnumEqual([], $w(null));
this.assertEnumEqual([], $w(undefined));
this.assertEnumEqual([], $w());
this.assertEnumEqual([], $w(10));
this.assertEnumEqual(['a'], $w('a'));
this.assertEnumEqual(['a'], $w('a '));
this.assertEnumEqual(['a'], $w(' a'));
this.assertEnumEqual(['a', 'b', 'c', 'd'], $w(' a b\nc\t\nd\n'));
}
});

View File

@ -1,31 +1,4 @@
<!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" />
</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>
<ul id="list">
<li></li>
<li></li>
<li></li>
</ul>
<!-- Tests follow -->
<script type="text/javascript" language="javascript" charset="utf-8">
// <![CDATA[
var Person = function(name){
var Person = function(name){
this.name = name;
};
@ -627,9 +600,4 @@
this.assertEqual("toString", new Foo().toString());
this.assertEqual("valueOf", new Foo().valueOf());
}
});
// ]]>
</script>
</body>
</html>
});

File diff suppressed because it is too large Load Diff

1376
test/unit/dom_test.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,67 +0,0 @@
<!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" />
</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[
Form.Element.Methods.coffee = Prototype.K;
Element.addMethods();
new Test.Unit.Runner({
testInput: function() {
this.assert($("input").present != null);
this.assert(typeof $("input").present == 'function');
this.assert($("input").select != null);
this.assertRespondsTo('present', Form.Element);
this.assertRespondsTo('present', Form.Element.Methods);
this.assertRespondsTo('coffee', $('input'));
this.assertIdentical(Prototype.K, Form.Element.coffee);
this.assertIdentical(Prototype.K, Form.Element.Methods.coffee);
},
testForm: function() {
this.assert($("form").reset != null);
this.assert($("form").getInputs().length == 2);
},
testEvent: function() {
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() {
this.assert($$("input").all(function(input) {
return (input.focus != null);
}));
}
});
// ]]>
</script>
</body>
</html>

View File

@ -0,0 +1,35 @@
Form.Element.Methods.coffee = Prototype.K;
Element.addMethods();
new Test.Unit.Runner({
testInput: function() {
this.assert($("input").present != null);
this.assert(typeof $("input").present == 'function');
this.assert($("input").select != null);
this.assertRespondsTo('present', Form.Element);
this.assertRespondsTo('present', Form.Element.Methods);
this.assertRespondsTo('coffee', $('input'));
this.assertIdentical(Prototype.K, Form.Element.coffee);
this.assertIdentical(Prototype.K, Form.Element.Methods.coffee);
},
testForm: function() {
this.assert($("form").reset != null);
this.assert($("form").getInputs().length == 2);
},
testEvent: function() {
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() {
this.assert($$("input").all(function(input) {
return (input.focus != null);
}));
}
});

View File

@ -1,322 +0,0 @@
<!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" />
</head>
<body>
<h1>Prototype Unit test file</h1>
<p>
Test of utility functions in enumerable.js
</p>
<!-- Log output -->
<div id="testlog"> </div>
<table id="grepTable">
<tbody id="grepTBody">
<tr id="grepRow">
<th id="grepHeader" class="cell"></th>
<td id="grepCell" class="cell"></td>
</tr>
</tbody>
</table>
<!-- 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'),
Basic: [1, 2, 3],
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() {
var result = 0;
Fixtures.Basic.each(function(value) {
if ((result = value) == 2) throw $break;
});
this.assertEqual(2, result);
},
testEachReturnActsAsContinue: function() {
var results = [];
Fixtures.Basic.each(function(value) {
if (value == 2) return;
results.push(value);
});
this.assertEqual('1, 3', results.join(', '));
},
testEachChaining: function() {
this.assertEqual(Fixtures.Primes, Fixtures.Primes.each(Prototype.emptyFunction));
this.assertEqual(3, Fixtures.Basic.each(Prototype.emptyFunction).length);
},
testEnumContext: function() {
var results = [];
Fixtures.Basic.each(function(value) {
results.push(value * this.i);
}, { i: 2 });
this.assertEqual('2 4 6', results.join(' '));
this.assert(Fixtures.Basic.all(function(value){
return value >= this.min && value <= this.max;
}, { min: 1, max: 3 }));
this.assert(!Fixtures.Basic.all(function(value){
return value >= this.min && value <= this.max;
}));
this.assert(Fixtures.Basic.any(function(value){
return value == this.target_value;
}, { target_value: 2 }));
},
testAny: function() {
this.assert(!([].any()));
this.assert([true, true, true].any());
this.assert([true, false, false].any());
this.assert(![false, false, false].any());
this.assert(Fixtures.Basic.any(function(value) {
return value > 2;
}));
this.assert(!Fixtures.Basic.any(function(value) {
return value > 5;
}));
},
testAll: function() {
this.assert([].all());
this.assert([true, true, true].all());
this.assert(![true, false, false].all());
this.assert(![false, false, false].all());
this.assert(Fixtures.Basic.all(function(value) {
return value > 0;
}));
this.assert(!Fixtures.Basic.all(function(value) {
return value > 1;
}));
},
testCollect: function() {
this.assertEqual(Fixtures.Nicknames.join(', '),
Fixtures.People.collect(function(person) {
return person.nickname;
}).join(", "));
this.assertEqual(26, Fixtures.Primes.map().length);
},
testDetect: function() {
this.assertEqual('Marcel Molina Jr.',
Fixtures.People.detect(function(person) {
return person.nickname.match(/no/);
}).name);
},
testEachSlice: function() {
this.assertEnumEqual([], [].eachSlice(2));
this.assertEqual(1, [1].eachSlice(1).length);
this.assertEnumEqual([1], [1].eachSlice(1)[0]);
this.assertEqual(2, Fixtures.Basic.eachSlice(2).length);
this.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()
);
this.assertEnumEqual(Fixtures.Basic, Fixtures.Basic.eachSlice(-10));
this.assertEnumEqual(Fixtures.Basic, Fixtures.Basic.eachSlice(0));
this.assertNotIdentical(Fixtures.Basic, Fixtures.Basic.eachSlice(0));
},
testEachWithIndex: function() {
var nicknames = [], indexes = [];
Fixtures.People.each(function(person, index) {
nicknames.push(person.nickname);
indexes.push(index);
});
this.assertEqual(Fixtures.Nicknames.join(', '),
nicknames.join(', '));
this.assertEqual('0, 1, 2, 3', indexes.join(', '));
},
testFindAll: function() {
this.assertEqual(Fixtures.Primes.join(', '),
Fixtures.Z.findAll(prime).join(', '));
},
testGrep: function() {
this.assertEqual('noradio, htonl',
Fixtures.Nicknames.grep(/o/).join(", "));
this.assertEqual('NORADIO, HTONL',
Fixtures.Nicknames.grep(/o/, function(nickname) {
return nickname.toUpperCase();
}).join(", "))
this.assertEnumEqual($('grepHeader', 'grepCell'),
$('grepTable', 'grepTBody', 'grepRow', 'grepHeader', 'grepCell').grep(new Selector('.cell')));
},
testInclude: function() {
this.assert(Fixtures.Nicknames.include('sam-'));
this.assert(Fixtures.Nicknames.include('noradio'));
this.assert(!Fixtures.Nicknames.include('gmosx'));
this.assert(Fixtures.Basic.include(2));
this.assert(Fixtures.Basic.include('2'));
this.assert(!Fixtures.Basic.include('4'));
},
testInGroupsOf: function() {
this.assertEnumEqual([], [].inGroupsOf(3));
var arr = [1, 2, 3, 4, 5, 6].inGroupsOf(3);
this.assertEqual(2, arr.length);
this.assertEnumEqual([1, 2, 3], arr[0]);
this.assertEnumEqual([4, 5, 6], arr[1]);
arr = [1, 2, 3, 4, 5, 6].inGroupsOf(4);
this.assertEqual(2, arr.length);
this.assertEnumEqual([1, 2, 3, 4], arr[0]);
this.assertEnumEqual([5, 6, null, null], arr[1]);
var basic = Fixtures.Basic
arr = basic.inGroupsOf(4,'x');
this.assertEqual(1, arr.length);
this.assertEnumEqual([1, 2, 3, 'x'], arr[0]);
this.assertEnumEqual([1,2,3,'a'], basic.inGroupsOf(2, 'a').flatten());
arr = basic.inGroupsOf(5, '');
this.assertEqual(1, arr.length);
this.assertEnumEqual([1, 2, 3, '', ''], arr[0]);
this.assertEnumEqual([1,2,3,0], basic.inGroupsOf(2, 0).flatten());
this.assertEnumEqual([1,2,3,false], basic.inGroupsOf(2, false).flatten());
},
testInject: function() {
this.assertEqual(1061,
Fixtures.Primes.inject(0, function(sum, value) {
return sum + value;
}));
},
testInvoke: function() {
var result = [[2, 1, 3], [6, 5, 4]].invoke('sort');
this.assertEqual(2, result.length);
this.assertEqual('1, 2, 3', result[0].join(', '));
this.assertEqual('4, 5, 6', result[1].join(', '));
result = result.invoke('invoke', 'toString', 2);
this.assertEqual('1, 10, 11', result[0].join(', '));
this.assertEqual('100, 101, 110', result[1].join(', '));
},
testMax: function() {
this.assertEqual(100, Fixtures.Z.max());
this.assertEqual(97, Fixtures.Primes.max());
this.assertEqual(2, [ -9, -8, -7, -6, -4, -3, -2, 0, -1, 2 ].max());
this.assertEqual('sam-', Fixtures.Nicknames.max()); // ?s > ?U
},
testMin: function() {
this.assertEqual(1, Fixtures.Z.min());
this.assertEqual(0, [ 1, 2, 3, 4, 5, 6, 7, 8, 0, 9 ].min());
this.assertEqual('Ulysses', Fixtures.Nicknames.min()); // ?U < ?h
},
testPartition: function() {
var result = Fixtures.People.partition(function(person) {
return person.name.length < 15;
}).invoke('pluck', 'nickname');
this.assertEqual(2, result.length);
this.assertEqual('sam-, htonl', result[0].join(', '));
this.assertEqual('noradio, Ulysses', result[1].join(', '));
},
testPluck: function() {
this.assertEqual(Fixtures.Nicknames.join(', '),
Fixtures.People.pluck('nickname').join(', '));
},
testReject: function() {
this.assertEqual(0,
Fixtures.Nicknames.reject(Prototype.K).length);
this.assertEqual('sam-, noradio, htonl',
Fixtures.Nicknames.reject(function(nickname) {
return nickname != nickname.toLowerCase();
}).join(', '));
},
testSortBy: function() {
this.assertEqual('htonl, noradio, sam-, Ulysses',
Fixtures.People.sortBy(function(value) {
return value.nickname.toLowerCase();
}).pluck('nickname').join(', '));
},
testToArray: function() {
var result = Fixtures.People.toArray();
this.assert(result != Fixtures.People); // they're different objects...
this.assertEqual(Fixtures.Nicknames.join(', '),
result.pluck('nickname').join(', ')); // but the values are the same
},
testZip: function() {
var result = [1, 2, 3].zip([4, 5, 6], [7, 8, 9]);
this.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() });
this.assertEqual('[[7, 4, 1], [8, 5, 2], [9, 6, 3]]', result.inspect());
},
testSize: function() {
this.assertEqual(4, Fixtures.People.size());
this.assertEqual(4, Fixtures.Nicknames.size());
this.assertEqual(26, Fixtures.Primes.size());
this.assertEqual(0, [].size());
}
});
// ]]>
</script>
</body>
</html>

View File

@ -0,0 +1,287 @@
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'),
Basic: [1, 2, 3],
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() {
var result = 0;
Fixtures.Basic.each(function(value) {
if ((result = value) == 2) throw $break;
});
this.assertEqual(2, result);
},
testEachReturnActsAsContinue: function() {
var results = [];
Fixtures.Basic.each(function(value) {
if (value == 2) return;
results.push(value);
});
this.assertEqual('1, 3', results.join(', '));
},
testEachChaining: function() {
this.assertEqual(Fixtures.Primes, Fixtures.Primes.each(Prototype.emptyFunction));
this.assertEqual(3, Fixtures.Basic.each(Prototype.emptyFunction).length);
},
testEnumContext: function() {
var results = [];
Fixtures.Basic.each(function(value) {
results.push(value * this.i);
}, { i: 2 });
this.assertEqual('2 4 6', results.join(' '));
this.assert(Fixtures.Basic.all(function(value){
return value >= this.min && value <= this.max;
}, { min: 1, max: 3 }));
this.assert(!Fixtures.Basic.all(function(value){
return value >= this.min && value <= this.max;
}));
this.assert(Fixtures.Basic.any(function(value){
return value == this.target_value;
}, { target_value: 2 }));
},
testAny: function() {
this.assert(!([].any()));
this.assert([true, true, true].any());
this.assert([true, false, false].any());
this.assert(![false, false, false].any());
this.assert(Fixtures.Basic.any(function(value) {
return value > 2;
}));
this.assert(!Fixtures.Basic.any(function(value) {
return value > 5;
}));
},
testAll: function() {
this.assert([].all());
this.assert([true, true, true].all());
this.assert(![true, false, false].all());
this.assert(![false, false, false].all());
this.assert(Fixtures.Basic.all(function(value) {
return value > 0;
}));
this.assert(!Fixtures.Basic.all(function(value) {
return value > 1;
}));
},
testCollect: function() {
this.assertEqual(Fixtures.Nicknames.join(', '),
Fixtures.People.collect(function(person) {
return person.nickname;
}).join(", "));
this.assertEqual(26, Fixtures.Primes.map().length);
},
testDetect: function() {
this.assertEqual('Marcel Molina Jr.',
Fixtures.People.detect(function(person) {
return person.nickname.match(/no/);
}).name);
},
testEachSlice: function() {
this.assertEnumEqual([], [].eachSlice(2));
this.assertEqual(1, [1].eachSlice(1).length);
this.assertEnumEqual([1], [1].eachSlice(1)[0]);
this.assertEqual(2, Fixtures.Basic.eachSlice(2).length);
this.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()
);
this.assertEnumEqual(Fixtures.Basic, Fixtures.Basic.eachSlice(-10));
this.assertEnumEqual(Fixtures.Basic, Fixtures.Basic.eachSlice(0));
this.assertNotIdentical(Fixtures.Basic, Fixtures.Basic.eachSlice(0));
},
testEachWithIndex: function() {
var nicknames = [], indexes = [];
Fixtures.People.each(function(person, index) {
nicknames.push(person.nickname);
indexes.push(index);
});
this.assertEqual(Fixtures.Nicknames.join(', '),
nicknames.join(', '));
this.assertEqual('0, 1, 2, 3', indexes.join(', '));
},
testFindAll: function() {
this.assertEqual(Fixtures.Primes.join(', '),
Fixtures.Z.findAll(prime).join(', '));
},
testGrep: function() {
this.assertEqual('noradio, htonl',
Fixtures.Nicknames.grep(/o/).join(", "));
this.assertEqual('NORADIO, HTONL',
Fixtures.Nicknames.grep(/o/, function(nickname) {
return nickname.toUpperCase();
}).join(", "))
this.assertEnumEqual($('grepHeader', 'grepCell'),
$('grepTable', 'grepTBody', 'grepRow', 'grepHeader', 'grepCell').grep(new Selector('.cell')));
},
testInclude: function() {
this.assert(Fixtures.Nicknames.include('sam-'));
this.assert(Fixtures.Nicknames.include('noradio'));
this.assert(!Fixtures.Nicknames.include('gmosx'));
this.assert(Fixtures.Basic.include(2));
this.assert(Fixtures.Basic.include('2'));
this.assert(!Fixtures.Basic.include('4'));
},
testInGroupsOf: function() {
this.assertEnumEqual([], [].inGroupsOf(3));
var arr = [1, 2, 3, 4, 5, 6].inGroupsOf(3);
this.assertEqual(2, arr.length);
this.assertEnumEqual([1, 2, 3], arr[0]);
this.assertEnumEqual([4, 5, 6], arr[1]);
arr = [1, 2, 3, 4, 5, 6].inGroupsOf(4);
this.assertEqual(2, arr.length);
this.assertEnumEqual([1, 2, 3, 4], arr[0]);
this.assertEnumEqual([5, 6, null, null], arr[1]);
var basic = Fixtures.Basic
arr = basic.inGroupsOf(4,'x');
this.assertEqual(1, arr.length);
this.assertEnumEqual([1, 2, 3, 'x'], arr[0]);
this.assertEnumEqual([1,2,3,'a'], basic.inGroupsOf(2, 'a').flatten());
arr = basic.inGroupsOf(5, '');
this.assertEqual(1, arr.length);
this.assertEnumEqual([1, 2, 3, '', ''], arr[0]);
this.assertEnumEqual([1,2,3,0], basic.inGroupsOf(2, 0).flatten());
this.assertEnumEqual([1,2,3,false], basic.inGroupsOf(2, false).flatten());
},
testInject: function() {
this.assertEqual(1061,
Fixtures.Primes.inject(0, function(sum, value) {
return sum + value;
}));
},
testInvoke: function() {
var result = [[2, 1, 3], [6, 5, 4]].invoke('sort');
this.assertEqual(2, result.length);
this.assertEqual('1, 2, 3', result[0].join(', '));
this.assertEqual('4, 5, 6', result[1].join(', '));
result = result.invoke('invoke', 'toString', 2);
this.assertEqual('1, 10, 11', result[0].join(', '));
this.assertEqual('100, 101, 110', result[1].join(', '));
},
testMax: function() {
this.assertEqual(100, Fixtures.Z.max());
this.assertEqual(97, Fixtures.Primes.max());
this.assertEqual(2, [ -9, -8, -7, -6, -4, -3, -2, 0, -1, 2 ].max());
this.assertEqual('sam-', Fixtures.Nicknames.max()); // ?s > ?U
},
testMin: function() {
this.assertEqual(1, Fixtures.Z.min());
this.assertEqual(0, [ 1, 2, 3, 4, 5, 6, 7, 8, 0, 9 ].min());
this.assertEqual('Ulysses', Fixtures.Nicknames.min()); // ?U < ?h
},
testPartition: function() {
var result = Fixtures.People.partition(function(person) {
return person.name.length < 15;
}).invoke('pluck', 'nickname');
this.assertEqual(2, result.length);
this.assertEqual('sam-, htonl', result[0].join(', '));
this.assertEqual('noradio, Ulysses', result[1].join(', '));
},
testPluck: function() {
this.assertEqual(Fixtures.Nicknames.join(', '),
Fixtures.People.pluck('nickname').join(', '));
},
testReject: function() {
this.assertEqual(0,
Fixtures.Nicknames.reject(Prototype.K).length);
this.assertEqual('sam-, noradio, htonl',
Fixtures.Nicknames.reject(function(nickname) {
return nickname != nickname.toLowerCase();
}).join(', '));
},
testSortBy: function() {
this.assertEqual('htonl, noradio, sam-, Ulysses',
Fixtures.People.sortBy(function(value) {
return value.nickname.toLowerCase();
}).pluck('nickname').join(', '));
},
testToArray: function() {
var result = Fixtures.People.toArray();
this.assert(result != Fixtures.People); // they're different objects...
this.assertEqual(Fixtures.Nicknames.join(', '),
result.pluck('nickname').join(', ')); // but the values are the same
},
testZip: function() {
var result = [1, 2, 3].zip([4, 5, 6], [7, 8, 9]);
this.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() });
this.assertEqual('[[7, 4, 1], [8, 5, 2], [9, 6, 3]]', result.inspect());
},
testSize: function() {
this.assertEqual(4, Fixtures.People.size());
this.assertEqual(4, Fixtures.Nicknames.size());
this.assertEqual(26, Fixtures.Primes.size());
this.assertEqual(0, [].size());
}
});

View File

@ -1,268 +0,0 @@
<!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" />
</head>
<body>
<h1>Prototype Unit test file</h1>
<p>
Test of event handling code in event.js
</p>
<!-- Log output -->
<div id="testlog"> </div>
<div id="outer" style="display: none">
<p id="inner">One two three <span id="span">four</span></p>
</div>
<div id="container"><div></div></div>
<!-- Tests follow -->
<script type="text/javascript" language="javascript" charset="utf-8">
// <![CDATA[
var eventResults = { }, documentLoaded = document.loaded;
new Test.Unit.Runner({
// test firing an event and observing it on the element it's fired from
testCustomEventFiring: function() {
var span = $("span"), fired = false, observer = function(event) {
this.assertEqual(span, event.element());
this.assertEqual(1, event.memo.index);
fired = true;
}.bind(this);
span.observe("test:somethingHappened", observer);
span.fire("test:somethingHappened", { index: 1 });
this.assert(fired);
fired = false;
span.fire("test:somethingElseHappened");
this.assert(!fired);
span.stopObserving("test:somethingHappened", observer);
span.fire("test:somethingHappened");
this.assert(!fired);
},
// test firing an event and observing it on a containing element
testCustomEventBubbling: function() {
var span = $("span"), outer = $("outer"), fired = false, observer = function(event) {
this.assertEqual(span, event.element());
fired = true;
}.bind(this);
outer.observe("test:somethingHappened", observer);
span.fire("test:somethingHappened");
this.assert(fired);
fired = false;
span.fire("test:somethingElseHappened");
this.assert(!fired);
outer.stopObserving("test:somethingHappened", observer);
span.fire("test:somethingHappened");
this.assert(!fired);
},
testCustomEventCanceling: function() {
var span = $("span"), outer = $("outer"), inner = $("inner");
var fired = false, stopped = false;
function outerObserver(event) {
fired = span == event.element();
}
function innerObserver(event) {
event.stop();
stopped = true;
}
inner.observe("test:somethingHappened", innerObserver);
outer.observe("test:somethingHappened", outerObserver);
span.fire("test:somethingHappened");
this.assert(stopped);
this.assert(!fired);
fired = stopped = false;
inner.stopObserving("test:somethingHappened", innerObserver);
span.fire("test:somethingHappened");
this.assert(!stopped);
this.assert(fired);
outer.stopObserving("test:somethingHappened", outerObserver);
},
testEventObjectIsExtended: function() {
var span = $("span"), event, observedEvent, observer = function(e) { observedEvent = e };
span.observe("test:somethingHappened", observer);
event = span.fire("test:somethingHappened");
this.assertEqual(event, observedEvent);
this.assertEqual(Event.Methods.stop.methodize(), event.stop);
span.stopObserving("test:somethingHappened", observer);
event = span.fire("test:somethingHappenedButNoOneIsListening");
this.assertEqual(Event.Methods.stop.methodize(), event.stop);
},
testEventObserversAreBoundToTheObservedElement: function() {
var span = $("span"), target, observer = function() { target = this };
span.observe("test:somethingHappened", observer);
span.fire("test:somethingHappened");
span.stopObserving("test:somethingHappened", observer);
this.assertEqual(span, target);
target = null;
var outer = $("outer");
outer.observe("test:somethingHappened", observer);
span.fire("test:somethingHappened");
outer.stopObserving("test:somethingHappened", observer);
this.assertEqual(outer, target);
},
testMultipleCustomEventObserversWithTheSameHandler: function() {
var span = $("span"), count = 0, observer = function() { count++ };
span.observe("test:somethingHappened", observer);
span.observe("test:somethingElseHappened", observer);
span.fire("test:somethingHappened");
this.assertEqual(1, count);
span.fire("test:somethingElseHappened");
this.assertEqual(2, count);
},
testStopObservingWithoutArguments: function() {
var span = $("span"), count = 0, observer = function() { count++ };
span.observe("test:somethingHappened", observer);
span.observe("test:somethingElseHappened", observer);
span.stopObserving();
span.fire("test:somethingHappened");
this.assertEqual(0, count);
span.fire("test:somethingElseHappened");
this.assertEqual(0, count);
},
testStopObservingWithoutHandlerArgument: function() {
var span = $("span"), count = 0, observer = function() { count++ };
span.observe("test:somethingHappened", observer);
span.observe("test:somethingElseHappened", observer);
span.stopObserving("test:somethingHappened");
span.fire("test:somethingHappened");
this.assertEqual(0, count);
span.fire("test:somethingElseHappened");
this.assertEqual(1, count);
span.stopObserving("test:somethingElseHappened");
span.fire("test:somethingElseHappened");
this.assertEqual(1, count);
},
testStopObservingRemovesHandlerFromCache: function() {
var span = $("span"), observer = function() { }, eventID;
span.observe("test:somethingHappened", observer);
eventID = span._prototypeEventID;
this.assert(Event.cache[eventID]);
this.assert(Object.isArray(Event.cache[eventID]["test:somethingHappened"]));
this.assertEqual(1, Event.cache[eventID]["test:somethingHappened"].length);
span.stopObserving("test:somethingHappened", observer);
this.assert(Event.cache[eventID]);
this.assert(Object.isArray(Event.cache[eventID]["test:somethingHappened"]));
this.assertEqual(0, Event.cache[eventID]["test:somethingHappened"].length);
},
testObserveAndStopObservingAreChainable: function() {
var span = $("span"), observer = function() { };
this.assertEqual(span, span.observe("test:somethingHappened", observer));
this.assertEqual(span, span.stopObserving("test:somethingHappened", observer));
span.observe("test:somethingHappened", observer);
this.assertEqual(span, span.stopObserving("test:somethingHappened"));
span.observe("test:somethingHappened", observer);
this.assertEqual(span, span.stopObserving());
this.assertEqual(span, span.stopObserving()); // assert it again, after there are no observers
span.observe("test:somethingHappened", observer);
this.assertEqual(span, span.observe("test:somethingHappened", observer)); // try to reuse the same observer
span.stopObserving();
},
testDocumentLoaded: function() {
this.assert(!documentLoaded);
this.assert(document.loaded);
},
testDocumentContentLoadedEventFiresBeforeWindowLoad: function() {
this.assert(eventResults.contentLoaded, "contentLoaded");
this.assert(eventResults.contentLoaded.endOfDocument, "contentLoaded.endOfDocument");
this.assert(!eventResults.contentLoaded.windowLoad, "!contentLoaded.windowLoad");
this.assert(eventResults.windowLoad, "windowLoad");
this.assert(eventResults.windowLoad.endOfDocument, "windowLoad.endOfDocument");
this.assert(eventResults.windowLoad.contentLoaded, "windowLoad.contentLoaded");
},
testEventStopped: function() {
var span = $("span"), event;
span.observe("test:somethingHappened", function() { });
event = span.fire("test:somethingHappened");
this.assert(!event.stopped, "event.stopped should be false with an empty observer");
span.stopObserving("test:somethingHappened");
span.observe("test:somethingHappened", function(e) { e.stop() });
event = span.fire("test:somethingHappened");
this.assert(event.stopped, "event.stopped should be true for an observer that calls stop");
span.stopObserving("test:somethingHappened");
},
testEventFindElement: function() {
var span = $("span"), event;
event = span.fire("test:somethingHappened");
this.assertElementMatches(event.findElement(), 'span#span');
this.assertElementMatches(event.findElement('span'), 'span#span');
this.assertElementMatches(event.findElement('p'), 'p#inner');
this.assertEqual(null, event.findElement('div.does_not_exist'));
this.assertElementMatches(event.findElement('.does_not_exist, span'), 'span#span');
},
testEventIDDuplication: function() {
$('container').down().observe("test:somethingHappened", Prototype.emptyFunction);
$('container').innerHTML += $('container').innerHTML;
this.assertUndefined($('container').down(1)._prototypeEventID);
}
});
document.observe("dom:loaded", function(event) {
eventResults.contentLoaded = {
endOfDocument: eventResults.endOfDocument,
windowLoad: eventResults.windowLoad
};
});
Event.observe(window, "load", function(event) {
eventResults.windowLoad = {
endOfDocument: eventResults.endOfDocument,
contentLoaded: eventResults.contentLoaded
};
});
// ]]>
</script>
</body>
</html>
<script type="text/javascript">
eventResults.endOfDocument = true;
</script>

231
test/unit/event_test.js Normal file
View File

@ -0,0 +1,231 @@
var documentLoaded = document.loaded;
new Test.Unit.Runner({
// test firing an event and observing it on the element it's fired from
testCustomEventFiring: function() {
var span = $("span"), fired = false, observer = function(event) {
this.assertEqual(span, event.element());
this.assertEqual(1, event.memo.index);
fired = true;
}.bind(this);
span.observe("test:somethingHappened", observer);
span.fire("test:somethingHappened", { index: 1 });
this.assert(fired);
fired = false;
span.fire("test:somethingElseHappened");
this.assert(!fired);
span.stopObserving("test:somethingHappened", observer);
span.fire("test:somethingHappened");
this.assert(!fired);
},
// test firing an event and observing it on a containing element
testCustomEventBubbling: function() {
var span = $("span"), outer = $("outer"), fired = false, observer = function(event) {
this.assertEqual(span, event.element());
fired = true;
}.bind(this);
outer.observe("test:somethingHappened", observer);
span.fire("test:somethingHappened");
this.assert(fired);
fired = false;
span.fire("test:somethingElseHappened");
this.assert(!fired);
outer.stopObserving("test:somethingHappened", observer);
span.fire("test:somethingHappened");
this.assert(!fired);
},
testCustomEventCanceling: function() {
var span = $("span"), outer = $("outer"), inner = $("inner");
var fired = false, stopped = false;
function outerObserver(event) {
fired = span == event.element();
}
function innerObserver(event) {
event.stop();
stopped = true;
}
inner.observe("test:somethingHappened", innerObserver);
outer.observe("test:somethingHappened", outerObserver);
span.fire("test:somethingHappened");
this.assert(stopped);
this.assert(!fired);
fired = stopped = false;
inner.stopObserving("test:somethingHappened", innerObserver);
span.fire("test:somethingHappened");
this.assert(!stopped);
this.assert(fired);
outer.stopObserving("test:somethingHappened", outerObserver);
},
testEventObjectIsExtended: function() {
var span = $("span"), event, observedEvent, observer = function(e) { observedEvent = e };
span.observe("test:somethingHappened", observer);
event = span.fire("test:somethingHappened");
this.assertEqual(event, observedEvent);
this.assertEqual(Event.Methods.stop.methodize(), event.stop);
span.stopObserving("test:somethingHappened", observer);
event = span.fire("test:somethingHappenedButNoOneIsListening");
this.assertEqual(Event.Methods.stop.methodize(), event.stop);
},
testEventObserversAreBoundToTheObservedElement: function() {
var span = $("span"), target, observer = function() { target = this };
span.observe("test:somethingHappened", observer);
span.fire("test:somethingHappened");
span.stopObserving("test:somethingHappened", observer);
this.assertEqual(span, target);
target = null;
var outer = $("outer");
outer.observe("test:somethingHappened", observer);
span.fire("test:somethingHappened");
outer.stopObserving("test:somethingHappened", observer);
this.assertEqual(outer, target);
},
testMultipleCustomEventObserversWithTheSameHandler: function() {
var span = $("span"), count = 0, observer = function() { count++ };
span.observe("test:somethingHappened", observer);
span.observe("test:somethingElseHappened", observer);
span.fire("test:somethingHappened");
this.assertEqual(1, count);
span.fire("test:somethingElseHappened");
this.assertEqual(2, count);
},
testStopObservingWithoutArguments: function() {
var span = $("span"), count = 0, observer = function() { count++ };
span.observe("test:somethingHappened", observer);
span.observe("test:somethingElseHappened", observer);
span.stopObserving();
span.fire("test:somethingHappened");
this.assertEqual(0, count);
span.fire("test:somethingElseHappened");
this.assertEqual(0, count);
},
testStopObservingWithoutHandlerArgument: function() {
var span = $("span"), count = 0, observer = function() { count++ };
span.observe("test:somethingHappened", observer);
span.observe("test:somethingElseHappened", observer);
span.stopObserving("test:somethingHappened");
span.fire("test:somethingHappened");
this.assertEqual(0, count);
span.fire("test:somethingElseHappened");
this.assertEqual(1, count);
span.stopObserving("test:somethingElseHappened");
span.fire("test:somethingElseHappened");
this.assertEqual(1, count);
},
testStopObservingRemovesHandlerFromCache: function() {
var span = $("span"), observer = function() { }, eventID;
span.observe("test:somethingHappened", observer);
eventID = span._prototypeEventID;
this.assert(Event.cache[eventID]);
this.assert(Object.isArray(Event.cache[eventID]["test:somethingHappened"]));
this.assertEqual(1, Event.cache[eventID]["test:somethingHappened"].length);
span.stopObserving("test:somethingHappened", observer);
this.assert(Event.cache[eventID]);
this.assert(Object.isArray(Event.cache[eventID]["test:somethingHappened"]));
this.assertEqual(0, Event.cache[eventID]["test:somethingHappened"].length);
},
testObserveAndStopObservingAreChainable: function() {
var span = $("span"), observer = function() { };
this.assertEqual(span, span.observe("test:somethingHappened", observer));
this.assertEqual(span, span.stopObserving("test:somethingHappened", observer));
span.observe("test:somethingHappened", observer);
this.assertEqual(span, span.stopObserving("test:somethingHappened"));
span.observe("test:somethingHappened", observer);
this.assertEqual(span, span.stopObserving());
this.assertEqual(span, span.stopObserving()); // assert it again, after there are no observers
span.observe("test:somethingHappened", observer);
this.assertEqual(span, span.observe("test:somethingHappened", observer)); // try to reuse the same observer
span.stopObserving();
},
testDocumentLoaded: function() {
this.assert(!documentLoaded);
this.assert(document.loaded);
},
testDocumentContentLoadedEventFiresBeforeWindowLoad: function() {
this.assert(eventResults.contentLoaded, "contentLoaded");
this.assert(eventResults.contentLoaded.endOfDocument, "contentLoaded.endOfDocument");
this.assert(!eventResults.contentLoaded.windowLoad, "!contentLoaded.windowLoad");
this.assert(eventResults.windowLoad, "windowLoad");
this.assert(eventResults.windowLoad.endOfDocument, "windowLoad.endOfDocument");
this.assert(eventResults.windowLoad.contentLoaded, "windowLoad.contentLoaded");
},
testEventStopped: function() {
var span = $("span"), event;
span.observe("test:somethingHappened", function() { });
event = span.fire("test:somethingHappened");
this.assert(!event.stopped, "event.stopped should be false with an empty observer");
span.stopObserving("test:somethingHappened");
span.observe("test:somethingHappened", function(e) { e.stop() });
event = span.fire("test:somethingHappened");
this.assert(event.stopped, "event.stopped should be true for an observer that calls stop");
span.stopObserving("test:somethingHappened");
},
testEventFindElement: function() {
var span = $("span"), event;
event = span.fire("test:somethingHappened");
this.assertElementMatches(event.findElement(), 'span#span');
this.assertElementMatches(event.findElement('span'), 'span#span');
this.assertElementMatches(event.findElement('p'), 'p#inner');
this.assertEqual(null, event.findElement('div.does_not_exist'));
this.assertElementMatches(event.findElement('.does_not_exist, span'), 'span#span');
},
testEventIDDuplication: function() {
$('container').down().observe("test:somethingHappened", Prototype.emptyFunction);
$('container').innerHTML += $('container').innerHTML;
this.assertUndefined($('container').down(1)._prototypeEventID);
}
});
document.observe("dom:loaded", function(event) {
eventResults.contentLoaded = {
endOfDocument: eventResults.endOfDocument,
windowLoad: eventResults.windowLoad
};
});
Event.observe(window, "load", function(event) {
eventResults.windowLoad = {
endOfDocument: eventResults.endOfDocument,
contentLoaded: eventResults.contentLoaded
};
});

View File

@ -0,0 +1,2 @@
<div id="content"></div>
<div id="content2" style="color:red"></div>

View File

@ -0,0 +1 @@
<div id="test_node">22<span id="span_1"></span><span id="span_2"></span></div>

View File

@ -0,0 +1,6 @@
<div id="test"></div>
<ul id="list">
<li></li>
<li></li>
<li></li>
</ul>

366
test/unit/fixtures/dom.html Normal file
View File

@ -0,0 +1,366 @@
<style type="text/css" media="screen">
/* <![CDATA[ */
#style_test_1 { cursor: pointer; font-size:12px;}
div.style-test { margin-left: 1px }
#style_test_dimensions_container {
position: absolute;
top: 0;
left: 500px;
width: 20px;
height: 30px;
margin: 10px;
padding: 10px;
border: 3px solid red;
}
#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;
}
#notInlineAbsoluted { position: absolute; }
#elementToViewportDimensions {
position: absolute;
top: 0;
left: 0;
height: 10px;
width: 10px;
background: #000;
}
/* for scroll test on really big screens */
body {
height: 40000px;
}
/* ]]> */
</style>
<div id="scroll_test_1">
<p id="scroll_test_2">Scroll test</p>
</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="testdiv-replace-container-element"><div id="testdiv-replace-element"></div></div>
<div id="testdiv-replace-container-toelement"><div id="testdiv-replace-toelement"></div></div>
<div id="testdiv-replace-container-tohtml"><div id="testdiv-replace-tohtml"></div></div>
<div id="testtable-replace-container"><table id="testtable-replace"></table></div>
<table id="testrow-replace-container"><tr id="testrow-replace"></tr></table>
<select id="testoption-replace-container"><option id="testoption-replace"></option><option>stays</option></select>
<div id="testform-replace-container"><p>some text</p><form id="testform-replace"><input id="testinput-replace" type="text" /></form><p>some text</p></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">
<!-- comment node to screw things up -->
<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>
<li class="1"></li>
</ul>
<div class="B C D"></div>
<div id="unextended"></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>
<span id="style_test_4">blah</span>
<span id="style_test_5">blah</span>
<div id="style_test_dimensions_container">
<div id="style_test_dimensions" style="background:#ddd;padding:1px;margin:1px;border:1px solid #00f"><div style="height:5px;background:#eee;width:5px;padding:2px;margin:2px;border:2px solid #0f0"> </div>
</div>
</div>
<div id="test_csstext_1">test_csstext_1</div>
<div id="test_csstext_2">test_csstext_2</div>
<div id="test_csstext_3" style="border: 1px solid red">test_csstext_3</div>
<div id="test_csstext_4" style="font-size: 20px">test_csstext_4</div>
<div id="test_csstext_5">test_csstext_5</div>
<div id="custom_attributes">
<div foo="1" bar="2"></div>
<div foo="2"></div>
</div>
<div id="cloned_element_attributes_issue" foo="original"></div>
<a id="attributes_with_issues_1" href="test.html" accesskey="L" tabindex="50" title="a link" onclick="alert('hello world');"></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"/>
<input type="date" id="attributes_with_issues_type" value="blech" />
<select id="attributes_with_issues_multiple" name="e" multiple="multiple">
<option>blech</option>
<option>blah</option>
</select>
</form>
<!-- writeAttributes -->
<p id="write_attribute_para"></a>
<a id="write_attribute_link" href="test.html"></a>
<form action="/dev/null" id="write_attribute_form" method="get" accept-charset="utf-8">
<label id="write_attribute_label"></label>
<input type="checkbox" name="write_attribute_checkbox" value="" id="write_attribute_checkbox">
<input type="checkbox" checked="checked" name="write_attribute_checked_checkbox" value="" id="write_attribute_checked_checkbox">
<input type="text" name="write_attribute_input" value="" id="write_attribute_input">
<select id="write_attribute_select">
<option>Cat</option>
<option>Dog</option>
</select>
</form>
<table id="write_attribute_table" cellpadding="6" cellspacing="4">
<tr><td id="write_attribute_td">A</td><td>B</td></tr>
<tr><td>C</td></tr>
<tr><td>D</td><td>E</td><td>F</td></tr>
</table>
<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 id="grand-child">
<div id="great-grand-child"></div>
</div></div><!-- intentional formatting; don't change this line -->
<div id="sibling"><div id="grand-sibling"></div></div>
</div>
<div id="not-in-the-family"></div>
<div id="insertions-container"><div id="insertions-main"><p>some content.</p></div></div>
<div id="insertions-node-container"><div id="insertions-node-main"><p>some content.</p></div></div>
<div id="element-insertions-container"><div id="element-insertions-main"><p>some content.</p></div></div>
<div id="element-insertions-multiple-container"><div id="element-insertions-multiple-main"><p>some content.</p></div></div>
<table id="table_for_insertions"></table>
<table id="table_for_row_insertions"><tr id="row_1"></tr></table>
<form method="post" action="blah">
<select id="select_for_update" name="select_for_update">
<option>option 1</option>
<option>option 2</option>
</select>
<select id="select_for_insert_bottom" name="select_for_insert_bottom">
<option>option 1</option>
<option>option 2</option>
</select>
<select id="select_for_insert_top" name="select_for_insert_top">
<option>option 1</option>
<option>option 2</option>
</select>
</form>
<div id="wrap-container"><p id="wrap"></p></div>
<!-- Positioning methods bench -->
<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;font-size:2px">test<span id="inline">test</span></div>
<div id="absolute_relative_undefined">XYZ</div>
</div>
<div id="absolute_fixed" style="position: fixed; top: 10px; left: 10px">
<span id="absolute_fixed_absolute" style="position: absolute; top: 10px; left: 10px">foo</span>
<span id="absolute_fixed_undefined" style="display:block">bar</span>
</div></div>
<div id="notInlineAbsoluted"></div>
<div id="inlineAbsoluted" style="position: absolute"></div>
<div id="unextended"></div>
<div id="identification">
<div id="predefined_id"></div>
<div></div>
<div></div>
<div></div>
<div id="anonymous_element_3"></div>
</div>
<div id='elementToViewportDimensions' style='display: none'></div>

View File

@ -0,0 +1,4 @@
<form id="form">
<input type="text" id="input" value="4" />
<input type="submit" />
</form>

View File

@ -0,0 +1,8 @@
<table id="grepTable">
<tbody id="grepTBody">
<tr id="grepRow">
<th id="grepHeader" class="cell"></th>
<td id="grepCell" class="cell"></td>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,4 @@
<div id="outer" style="display: none">
<p id="inner">One two three <span id="span">four</span></p>
</div>
<div id="container"><div></div></div>

View File

@ -0,0 +1,104 @@
<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" name="first_submit" value="Commit it!" />
<input type="submit" name="second_submit" value="Delete it!" />
<input type="text" name="action" value="blah" />
</form>
<form id="bigform" method="get" action="fixtures/empty.js">
<div id="inputs">
<input type="text" name="dummy" id="dummy_disabled" disabled="disabled"/>
<input type="submit" name="commit" id="submit" />
<input type="button" name="clicky" value="click me" />
<input type="reset" name="revert" />
<input type="text" name="greeting" id="focus_text" value="Hello" />
</div>
<!-- some edge cases in serialization -->
<div id="value_checks">
<input name="twin" type="text" value="" />
<input name="twin" type="text" value="siamese" />
<!-- Rails checkbox hack with hidden input: -->
<input name="checky" type="checkbox" id="checkbox_hack" value="1" />
<input name="checky" type="hidden" value="0" />
</div>
<!-- all variations of SELECT controls -->
<div id="selects_wrapper">
<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="selects_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>
</div>
<div id="various">
<select name="tf_selectOne"><option selected="selected"></option><option>1</option></select>
<textarea name="tf_textarea"></textarea>
<input type="checkbox" name="tf_checkbox" value="on" />
<select name="tf_selectMany" multiple="multiple"></select>
<input type="text" name="tf_text" />
<div>This is not a form element</div>
<input type="radio" name="tf_radio" value="on" />
<input type="hidden" name="tf_hidden" />
<input type="password" name="tf_password" />
</div>
</form>
<form id="form_focus_hidden" style="display: none">
<input type="text" />
</form>
<!-- tabindexed forms -->
<div id="tabindex">
<form id="ffe">
<p><input type="text" disabled="disabled" id="ffe_disabled" /></p>
<input type="hidden" id="ffe_hidden" />
<input type="checkbox" id="ffe_checkbox" />
</form>
<form id="ffe_ti">
<p><input type="text" disabled="disabled" id="ffe_ti_disabled" /></p>
<input type="hidden" id="ffe_ti_hidden" />
<input type="checkbox" id="ffe_ti_checkbox" />
<input type="submit" id="ffe_ti_submit" tabindex="1" />
</form>
<form id="ffe_ti2">
<p><input type="text" disabled="disabled" id="ffe_ti2_disabled" /></p>
<input type="hidden" id="ffe_ti2_hidden" />
<input type="checkbox" id="ffe_ti2_checkbox" tabindex="0" />
<input type="submit" id="ffe_ti2_submit" tabindex="1" />
</form>
</div>

View File

@ -0,0 +1,9 @@
<div id="ensure_scrollbars" style="width:10000px; height:10000px; position:absolute" > </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;font-size:2px">test<span id="inline">test</span></div>
<div id="absolute_relative_undefined"> </div>
</div>
</div>

View File

@ -0,0 +1,69 @@
<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>
<form id="troubleForm2">
<input type="checkbox" name="brackets[5][]" id="chk_1" checked="checked" value="1" />
<input type="checkbox" name="brackets[5][]" id="chk_2" value="2" />
</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" class="span_foo span_bar">
<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 id="counted_container"><div class="is_counted"></div></div>
</div>

View File

@ -0,0 +1,18 @@
<div id="testlog_2"> </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>

View File

@ -1,489 +0,0 @@
<!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" />
</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" name="first_submit" value="Commit it!" />
<input type="submit" name="second_submit" value="Delete it!" />
<input type="text" name="action" value="blah" />
</form>
<form id="bigform" method="get" action="fixtures/empty.js">
<div id="inputs">
<input type="text" name="dummy" id="dummy_disabled" disabled="disabled"/>
<input type="submit" name="commit" id="submit" />
<input type="button" name="clicky" value="click me" />
<input type="reset" name="revert" />
<input type="text" name="greeting" id="focus_text" value="Hello" />
</div>
<!-- some edge cases in serialization -->
<div id="value_checks">
<input name="twin" type="text" value="" />
<input name="twin" type="text" value="siamese" />
<!-- Rails checkbox hack with hidden input: -->
<input name="checky" type="checkbox" id="checkbox_hack" value="1" />
<input name="checky" type="hidden" value="0" />
</div>
<!-- all variations of SELECT controls -->
<div id="selects_wrapper">
<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="selects_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>
</div>
<div id="various">
<select name="tf_selectOne"><option selected="selected"></option><option>1</option></select>
<textarea name="tf_textarea"></textarea>
<input type="checkbox" name="tf_checkbox" value="on" />
<select name="tf_selectMany" multiple="multiple"></select>
<input type="text" name="tf_text" />
<div>This is not a form element</div>
<input type="radio" name="tf_radio" value="on" />
<input type="hidden" name="tf_hidden" />
<input type="password" name="tf_password" />
</div>
</form>
<form id="form_focus_hidden" style="display: none">
<input type="text" />
</form>
<!-- tabindexed forms -->
<div id="tabindex">
<form id="ffe">
<p><input type="text" disabled="disabled" id="ffe_disabled" /></p>
<input type="hidden" id="ffe_hidden" />
<input type="checkbox" id="ffe_checkbox" />
</form>
<form id="ffe_ti">
<p><input type="text" disabled="disabled" id="ffe_ti_disabled" /></p>
<input type="hidden" id="ffe_ti_hidden" />
<input type="checkbox" id="ffe_ti_checkbox" />
<input type="submit" id="ffe_ti_submit" tabindex="1" />
</form>
<form id="ffe_ti2">
<p><input type="text" disabled="disabled" id="ffe_ti2_disabled" /></p>
<input type="hidden" id="ffe_ti2_hidden" />
<input type="checkbox" id="ffe_ti2_checkbox" tabindex="0" />
<input type="submit" id="ffe_ti2_submit" tabindex="1" />
</form>
</div>
<!-- Tests follow -->
<script type="text/javascript" charset="utf-8">
// <![CDATA[
// sweet sweet additional assertions
Object.extend(Test.Unit.Testcase.prototype, {
assertEnabled: function() {
for (var i = 0, element; element = arguments[i]; i++) {
this.assert(!$(element).disabled, Test.Unit.inspect(element) + ' was disabled');
}
},
assertDisabled: function() {
for (var i = 0, element; element = arguments[i]; i++) {
this.assert($(element).disabled, Test.Unit.inspect(element) + ' was enabled');
}
}
});
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(){
$$('form').each(function(f){ f.reset() });
// hidden value does not reset (for some reason)
$('bigform')['tf_hidden'].value = '';
},
testDollarF: function(){
this.assertEqual("4", $F("input_enabled"));
},
testFormElementEventObserver: function(){
var callbackCounter = 0;
var observer = new Form.Element.EventObserver('input_enabled', function(){
callbackCounter++;
});
this.assertEqual(0, callbackCounter);
$('input_enabled').value = 'boo!';
observer.onElementEvent(); // can't test the event directly, simulating
this.assertEqual(1, callbackCounter);
},
testFormElementObserver: function(){
var timedCounter = 0;
// First part: regular field
var observer = new Form.Element.Observer('input_enabled', 0.5, function() {
++timedCounter;
});
// Test it's unchanged yet
this.assertEqual(0, timedCounter);
// Test it doesn't change on first check
this.wait(550, function() {
this.assertEqual(0, timedCounter);
// Change, test it doesn't immediately change
$('input_enabled').value = 'yowza!';
this.assertEqual(0, timedCounter);
// Test it changes on next check, but not again on the next
this.wait(550, function() {
this.assertEqual(1, timedCounter);
this.wait(550, function() {
this.assertEqual(1, timedCounter);
observer.stop();
});
});
});
// Second part: multiple-select
[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
this.assertEqual(0, timedCounter);
// Test it doesn't change on first check
this.wait(550, function() {
this.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;
this.assertEqual(0, timedCounter);
// Test it changes on next check, but not again on the next
this.wait(550, function() {
this.assertEqual(1, timedCounter);
this.wait(550, function() {
this.assertEqual(1, timedCounter);
observer.stop();
});
});
});
},
testFormObserver: function(){
var timedCounter = 0;
// should work the same way was Form.Element.Observer
var observer = new Form.Observer('form', 0.5, function(form, value) {
++timedCounter;
});
// Test it's unchanged yet
this.assertEqual(0, timedCounter);
// Test it doesn't change on first check
this.wait(550, function() {
this.assertEqual(0, timedCounter);
// Change, test it doesn't immediately change
$('input_enabled').value = 'yowza!';
this.assertEqual(0, timedCounter);
// Test it changes on next check, but not again on the next
this.wait(550, function() {
this.assertEqual(1, timedCounter);
this.wait(550, function() {
this.assertEqual(1, timedCounter);
observer.stop();
});
});
});
},
testFormEnabling: function(){
var form = $('bigform')
var input1 = $('dummy_disabled');
var input2 = $('focus_text');
this.assertDisabled(input1);
this.assertEnabled(input2);
form.disable();
this.assertDisabled(input1, input2);
form.enable();
this.assertEnabled(input1, input2);
input1.disable();
this.assertDisabled(input1);
// non-form elements:
var fieldset = $('selects_fieldset');
var fields = fieldset.immediateDescendants();
fields.each(function(select) { this.assertEnabled(select) }, this);
Form.disable(fieldset)
fields.each(function(select) { this.assertDisabled(select) }, this);
Form.enable(fieldset)
fields.each(function(select) { this.assertEnabled(select) }, this);
},
testFormElementEnabling: function(){
var field = $('input_disabled');
field.enable();
this.assertEnabled(field);
field.disable();
this.assertDisabled(field);
var field = $('input_enabled');
this.assertEnabled(field);
field.disable();
this.assertDisabled(field);
field.enable();
this.assertEnabled(field);
},
// due to the lack of a DOM hasFocus() API method,
// we're simulating things here a little bit
testFormActivating: function(){
// 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('bigform');
this.assertEqual('submit', element.id);
// Test IE doesn't select text on buttons
Form.focusFirstElement('bigform');
if(document.selection) this.assertEqual('', getSelection(element));
// Form.Element.activate shouldn't select text on buttons
element = $('focus_text');
this.assertEqual('', getSelection(element));
// Form.Element.activate should select text on text input elements
element.activate();
this.assertEqual('Hello', getSelection(element));
// Form.Element.activate shouldn't raise an exception when the form or field is hidden
this.assertNothingRaised(function() {
$('form_focus_hidden').focusFirstElement();
});
},
testFormGetElements: function() {
var elements = Form.getElements('various'),
names = $w('tf_selectOne tf_textarea tf_checkbox tf_selectMany tf_text tf_radio tf_hidden tf_password');
this.assertEnumEqual(names, elements.pluck('name'))
},
testFormGetInputs: function() {
var form = $('form');
[form.getInputs(), Form.getInputs(form)].each(function(inputs){
this.assertEqual(inputs.length, 5);
this.assert(inputs instanceof Array);
this.assert(inputs.all(function(input) { return (input.tagName == "INPUT"); }));
}, this);
},
testFormFindFirstElement: function() {
this.assertEqual($('ffe_checkbox'), $('ffe').findFirstElement());
this.assertEqual($('ffe_ti_submit'), $('ffe_ti').findFirstElement());
this.assertEqual($('ffe_ti2_checkbox'), $('ffe_ti2').findFirstElement());
},
testFormSerialize: function() {
// form is initially empty
var form = $('bigform');
var expected = { tf_selectOne:'', tf_textarea:'', tf_text:'', tf_hidden:'', tf_password:'' };
this.assertHashEqual(expected, Form.serialize('various', true));
// set up some stuff
form['tf_selectOne'].selectedIndex = 1;
form['tf_textarea'].value = "boo hoo!";
form['tf_text'].value = "123öäü";
form['tf_hidden'].value = "moo%hoo&test";
form['tf_password'].value = 'sekrit code';
form['tf_checkbox'].checked = true;
form['tf_radio'].checked = true;
var expected = { tf_selectOne:1, tf_textarea:"boo hoo!", tf_text:"123öäü",
tf_hidden:"moo%hoo&test", tf_password:'sekrit code', tf_checkbox:'on', tf_radio:'on' }
// return params
this.assertHashEqual(expected, Form.serialize('various', true));
// return string
this.assertEnumEqual(Object.toQueryString(expected).split('&').sort(),
Form.serialize('various').split('&').sort());
this.assertEqual('string', typeof $('form').serialize({ hash:false }));
// Checks that disabled element is not included in serialized form.
$('input_enabled').enable();
this.assertHashEqual({ val1:4, action:'blah', first_submit:'Commit it!' },
$('form').serialize(true));
// should not eat empty values for duplicate names
$('checkbox_hack').checked = false;
var data = Form.serialize('value_checks', true);
this.assertEnumEqual(['', 'siamese'], data['twin']);
this.assertEqual('0', data['checky']);
$('checkbox_hack').checked = true;
this.assertEnumEqual($w('1 0'), Form.serialize('value_checks', true)['checky']);
// all kinds of SELECT controls
var params = Form.serialize('selects_fieldset', true);
var expected = { 'nvm[]':['One', 'Three'], evu:'', 'evm[]':['', 'Three'] };
this.assertHashEqual(expected, params);
params = Form.serialize('selects_wrapper', true);
this.assertHashEqual(Object.extend(expected, { vu:1, 'vm[]':[1, 3], nvu:'One' }), params);
// explicit submit button
this.assertHashEqual({ val1:4, action:'blah', second_submit:'Delete it!' },
$('form').serialize({ submit: 'second_submit' }));
this.assertHashEqual({ val1:4, action:'blah' },
$('form').serialize({ submit: false }));
this.assertHashEqual({ val1:4, action:'blah' },
$('form').serialize({ submit: 'inexistent' }));
},
testFormMethodsOnExtendedElements: function() {
var form = $('form');
this.assertEqual(Form.serialize('form'), form.serialize());
this.assertEqual(Form.Element.serialize('input_enabled'), $('input_enabled').serialize());
this.assertNotEqual(form.serialize, $('input_enabled').serialize);
Element.addMethods('INPUT', { anInputMethod: function(input) { return 'input' } });
Element.addMethods('SELECT', { aSelectMethod: function(select) { return 'select' } });
form = $('bigform');
var input = form['tf_text'], select = form['tf_selectOne'];
input._extendedByPrototype = select._extendedByPrototype = false;
this.assert($(input).anInputMethod);
this.assert(!input.aSelectMethod);
this.assertEqual('input', input.anInputMethod());
this.assert($(select).aSelectMethod);
this.assert(!select.anInputMethod);
this.assertEqual('select', select.aSelectMethod());
},
testFormRequest: function() {
request = $("form").request();
this.assert($("form").hasAttribute("method"));
this.assert(request.url.include("fixtures/empty.js?val1=4"));
this.assertEqual("get", request.method);
request = $("form").request({ method: "put", parameters: {val2: "hello"} });
this.assert(request.url.endsWith("fixtures/empty.js"));
this.assertEqual(4, request.options.parameters['val1']);
this.assertEqual('hello', request.options.parameters['val2']);
this.assertEqual("post", request.method);
this.assertEqual("put", request.parameters['_method']);
// with empty action attribute
request = $("ffe").request({ method: 'post' });
this.assert(request.url.include("unit/form.html"),
'wrong default action for form element with empty action attribute');
},
testFormElementMethodsChaining: function(){
var methods = $w('clear activate disable enable'),
formElements = $('form').getElements();
methods.each(function(method){
formElements.each(function(element){
var returned = element[method]();
this.assertIdentical(element, returned);
}, this);
}, this);
},
testSetValue: function(){
// text input
var input = $('input_enabled'), oldValue = input.getValue();
this.assertEqual(input, input.setValue('foo'), 'setValue chaining is broken');
this.assertEqual('foo', input.getValue(), 'value improperly set');
input.setValue(oldValue);
this.assertEqual(oldValue, input.getValue(), 'value improperly restored to original');
// checkbox
input = $('checkbox_hack');
input.setValue(false);
this.assertEqual(null, input.getValue(), 'checkbox should be unchecked');
input.setValue(true);
this.assertEqual("1", input.getValue(), 'checkbox should be checked');
// selectbox
input = $('bigform')['vu'];
input.setValue('3');
this.assertEqual('3', input.getValue(), 'single select option improperly set');
input.setValue('1');
this.assertEqual('1', input.getValue());
// multiple select
input = $('bigform')['vm[]'];
input.setValue(['2', '3']);
this.assertEnumEqual(['2', '3'], input.getValue(),
'multiple select options improperly set');
input.setValue(['1', '3']);
this.assertEnumEqual(['1', '3'], input.getValue());
}
});
// ]]>
</script>
</body>
</html>

357
test/unit/form_test.js Normal file
View File

@ -0,0 +1,357 @@
// sweet sweet additional assertions
Object.extend(Test.Unit.Testcase.prototype, {
assertEnabled: function() {
for (var i = 0, element; element = arguments[i]; i++) {
this.assert(!$(element).disabled, Test.Unit.inspect(element) + ' was disabled');
}
},
assertDisabled: function() {
for (var i = 0, element; element = arguments[i]; i++) {
this.assert($(element).disabled, Test.Unit.inspect(element) + ' was enabled');
}
}
});
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(){
$$('form').each(function(f){ f.reset() });
// hidden value does not reset (for some reason)
$('bigform')['tf_hidden'].value = '';
},
testDollarF: function(){
this.assertEqual("4", $F("input_enabled"));
},
testFormElementEventObserver: function(){
var callbackCounter = 0;
var observer = new Form.Element.EventObserver('input_enabled', function(){
callbackCounter++;
});
this.assertEqual(0, callbackCounter);
$('input_enabled').value = 'boo!';
observer.onElementEvent(); // can't test the event directly, simulating
this.assertEqual(1, callbackCounter);
},
testFormElementObserver: function(){
var timedCounter = 0;
// First part: regular field
var observer = new Form.Element.Observer('input_enabled', 0.5, function() {
++timedCounter;
});
// Test it's unchanged yet
this.assertEqual(0, timedCounter);
// Test it doesn't change on first check
this.wait(550, function() {
this.assertEqual(0, timedCounter);
// Change, test it doesn't immediately change
$('input_enabled').value = 'yowza!';
this.assertEqual(0, timedCounter);
// Test it changes on next check, but not again on the next
this.wait(550, function() {
this.assertEqual(1, timedCounter);
this.wait(550, function() {
this.assertEqual(1, timedCounter);
observer.stop();
});
});
});
// Second part: multiple-select
[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
this.assertEqual(0, timedCounter);
// Test it doesn't change on first check
this.wait(550, function() {
this.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;
this.assertEqual(0, timedCounter);
// Test it changes on next check, but not again on the next
this.wait(550, function() {
this.assertEqual(1, timedCounter);
this.wait(550, function() {
this.assertEqual(1, timedCounter);
observer.stop();
});
});
});
},
testFormObserver: function(){
var timedCounter = 0;
// should work the same way was Form.Element.Observer
var observer = new Form.Observer('form', 0.5, function(form, value) {
++timedCounter;
});
// Test it's unchanged yet
this.assertEqual(0, timedCounter);
// Test it doesn't change on first check
this.wait(550, function() {
this.assertEqual(0, timedCounter);
// Change, test it doesn't immediately change
$('input_enabled').value = 'yowza!';
this.assertEqual(0, timedCounter);
// Test it changes on next check, but not again on the next
this.wait(550, function() {
this.assertEqual(1, timedCounter);
this.wait(550, function() {
this.assertEqual(1, timedCounter);
observer.stop();
});
});
});
},
testFormEnabling: function(){
var form = $('bigform')
var input1 = $('dummy_disabled');
var input2 = $('focus_text');
this.assertDisabled(input1);
this.assertEnabled(input2);
form.disable();
this.assertDisabled(input1, input2);
form.enable();
this.assertEnabled(input1, input2);
input1.disable();
this.assertDisabled(input1);
// non-form elements:
var fieldset = $('selects_fieldset');
var fields = fieldset.immediateDescendants();
fields.each(function(select) { this.assertEnabled(select) }, this);
Form.disable(fieldset)
fields.each(function(select) { this.assertDisabled(select) }, this);
Form.enable(fieldset)
fields.each(function(select) { this.assertEnabled(select) }, this);
},
testFormElementEnabling: function(){
var field = $('input_disabled');
field.enable();
this.assertEnabled(field);
field.disable();
this.assertDisabled(field);
var field = $('input_enabled');
this.assertEnabled(field);
field.disable();
this.assertDisabled(field);
field.enable();
this.assertEnabled(field);
},
// due to the lack of a DOM hasFocus() API method,
// we're simulating things here a little bit
testFormActivating: function(){
// 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('bigform');
this.assertEqual('submit', element.id);
// Test IE doesn't select text on buttons
Form.focusFirstElement('bigform');
if(document.selection) this.assertEqual('', getSelection(element));
// Form.Element.activate shouldn't select text on buttons
element = $('focus_text');
this.assertEqual('', getSelection(element));
// Form.Element.activate should select text on text input elements
element.activate();
this.assertEqual('Hello', getSelection(element));
// Form.Element.activate shouldn't raise an exception when the form or field is hidden
this.assertNothingRaised(function() {
$('form_focus_hidden').focusFirstElement();
});
},
testFormGetElements: function() {
var elements = Form.getElements('various'),
names = $w('tf_selectOne tf_textarea tf_checkbox tf_selectMany tf_text tf_radio tf_hidden tf_password');
this.assertEnumEqual(names, elements.pluck('name'))
},
testFormGetInputs: function() {
var form = $('form');
[form.getInputs(), Form.getInputs(form)].each(function(inputs){
this.assertEqual(inputs.length, 5);
this.assert(inputs instanceof Array);
this.assert(inputs.all(function(input) { return (input.tagName == "INPUT"); }));
}, this);
},
testFormFindFirstElement: function() {
this.assertEqual($('ffe_checkbox'), $('ffe').findFirstElement());
this.assertEqual($('ffe_ti_submit'), $('ffe_ti').findFirstElement());
this.assertEqual($('ffe_ti2_checkbox'), $('ffe_ti2').findFirstElement());
},
testFormSerialize: function() {
// form is initially empty
var form = $('bigform');
var expected = { tf_selectOne:'', tf_textarea:'', tf_text:'', tf_hidden:'', tf_password:'' };
this.assertHashEqual(expected, Form.serialize('various', true));
// set up some stuff
form['tf_selectOne'].selectedIndex = 1;
form['tf_textarea'].value = "boo hoo!";
form['tf_text'].value = "123öäü";
form['tf_hidden'].value = "moo%hoo&test";
form['tf_password'].value = 'sekrit code';
form['tf_checkbox'].checked = true;
form['tf_radio'].checked = true;
var expected = { tf_selectOne:1, tf_textarea:"boo hoo!", tf_text:"123öäü",
tf_hidden:"moo%hoo&test", tf_password:'sekrit code', tf_checkbox:'on', tf_radio:'on' }
// return params
this.assertHashEqual(expected, Form.serialize('various', true));
// return string
this.assertEnumEqual(Object.toQueryString(expected).split('&').sort(),
Form.serialize('various').split('&').sort());
this.assertEqual('string', typeof $('form').serialize({ hash:false }));
// Checks that disabled element is not included in serialized form.
$('input_enabled').enable();
this.assertHashEqual({ val1:4, action:'blah', first_submit:'Commit it!' },
$('form').serialize(true));
// should not eat empty values for duplicate names
$('checkbox_hack').checked = false;
var data = Form.serialize('value_checks', true);
this.assertEnumEqual(['', 'siamese'], data['twin']);
this.assertEqual('0', data['checky']);
$('checkbox_hack').checked = true;
this.assertEnumEqual($w('1 0'), Form.serialize('value_checks', true)['checky']);
// all kinds of SELECT controls
var params = Form.serialize('selects_fieldset', true);
var expected = { 'nvm[]':['One', 'Three'], evu:'', 'evm[]':['', 'Three'] };
this.assertHashEqual(expected, params);
params = Form.serialize('selects_wrapper', true);
this.assertHashEqual(Object.extend(expected, { vu:1, 'vm[]':[1, 3], nvu:'One' }), params);
// explicit submit button
this.assertHashEqual({ val1:4, action:'blah', second_submit:'Delete it!' },
$('form').serialize({ submit: 'second_submit' }));
this.assertHashEqual({ val1:4, action:'blah' },
$('form').serialize({ submit: false }));
this.assertHashEqual({ val1:4, action:'blah' },
$('form').serialize({ submit: 'inexistent' }));
},
testFormMethodsOnExtendedElements: function() {
var form = $('form');
this.assertEqual(Form.serialize('form'), form.serialize());
this.assertEqual(Form.Element.serialize('input_enabled'), $('input_enabled').serialize());
this.assertNotEqual(form.serialize, $('input_enabled').serialize);
Element.addMethods('INPUT', { anInputMethod: function(input) { return 'input' } });
Element.addMethods('SELECT', { aSelectMethod: function(select) { return 'select' } });
form = $('bigform');
var input = form['tf_text'], select = form['tf_selectOne'];
input._extendedByPrototype = select._extendedByPrototype = false;
this.assert($(input).anInputMethod);
this.assert(!input.aSelectMethod);
this.assertEqual('input', input.anInputMethod());
this.assert($(select).aSelectMethod);
this.assert(!select.anInputMethod);
this.assertEqual('select', select.aSelectMethod());
},
testFormRequest: function() {
request = $("form").request();
this.assert($("form").hasAttribute("method"));
this.assert(request.url.include("fixtures/empty.js?val1=4"));
this.assertEqual("get", request.method);
request = $("form").request({ method: "put", parameters: {val2: "hello"} });
this.assert(request.url.endsWith("fixtures/empty.js"));
this.assertEqual(4, request.options.parameters['val1']);
this.assertEqual('hello', request.options.parameters['val2']);
this.assertEqual("post", request.method);
this.assertEqual("put", request.parameters['_method']);
// with empty action attribute
request = $("ffe").request({ method: 'post' });
this.assert(request.url.include("unit/tmp/form_test.html"),
'wrong default action for form element with empty action attribute');
},
testFormElementMethodsChaining: function(){
var methods = $w('clear activate disable enable'),
formElements = $('form').getElements();
methods.each(function(method){
formElements.each(function(element){
var returned = element[method]();
this.assertIdentical(element, returned);
}, this);
}, this);
},
testSetValue: function(){
// text input
var input = $('input_enabled'), oldValue = input.getValue();
this.assertEqual(input, input.setValue('foo'), 'setValue chaining is broken');
this.assertEqual('foo', input.getValue(), 'value improperly set');
input.setValue(oldValue);
this.assertEqual(oldValue, input.getValue(), 'value improperly restored to original');
// checkbox
input = $('checkbox_hack');
input.setValue(false);
this.assertEqual(null, input.getValue(), 'checkbox should be unchecked');
input.setValue(true);
this.assertEqual("1", input.getValue(), 'checkbox should be checked');
// selectbox
input = $('bigform')['vu'];
input.setValue('3');
this.assertEqual('3', input.getValue(), 'single select option improperly set');
input.setValue('1');
this.assertEqual('1', input.getValue());
// multiple select
input = $('bigform')['vm[]'];
input.setValue(['2', '3']);
this.assertEnumEqual(['2', '3'], input.getValue(),
'multiple select options improperly set');
input.setValue(['1', '3']);
this.assertEnumEqual(['1', '3'], input.getValue());
}
});

View File

@ -1,228 +0,0 @@
<!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" />
</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 }
};
new Test.Unit.Runner({
testSet: function() {
var h = $H({a: 'A'})
this.assertEqual('B', h.set('b', 'B'));
this.assertHashEqual({a: 'A', b: 'B'}, h);
this.assertUndefined(h.set('c'));
this.assertHashEqual({a: 'A', b: 'B', c: undefined}, h);
},
testGet: function() {
var h = $H({a: 'A'});
this.assertEqual('A', h.get('a'));
this.assertUndefined(h.a);
this.assertUndefined($H({}).get('a'));
},
testUnset: function() {
var hash = $H(Fixtures.many);
this.assertEqual('B', hash.unset('b'));
this.assertHashEqual({a:'A', c: 'C', d:'D#'}, hash);
this.assertUndefined(hash.unset('z'));
this.assertHashEqual({a:'A', c: 'C', d:'D#'}, hash);
// not equivalent to Hash#remove
this.assertEqual('A', hash.unset('a', 'c'));
this.assertHashEqual({c: 'C', d:'D#'}, hash);
},
testToObject: function() {
var hash = $H(Fixtures.many), object = hash.toObject();
this.assertInstanceOf(Object, object);
this.assertHashEqual(Fixtures.many, object);
this.assertNotIdentical(Fixtures.many, object);
hash.set('foo', 'bar');
this.assertHashNotEqual(object, hash.toObject());
},
testConstruct: function() {
var object = Object.clone(Fixtures.one);
var h = new Hash(object), h2 = $H(object);
this.assertInstanceOf(Hash, h);
this.assertInstanceOf(Hash, h2);
this.assertHashEqual({}, new Hash());
this.assertHashEqual(object, h);
this.assertHashEqual(object, h2);
h.set('foo', 'bar');
this.assertHashNotEqual(object, h);
var clone = $H(h);
this.assertInstanceOf(Hash, clone);
this.assertHashEqual(h, clone);
h.set('foo', 'foo');
this.assertHashNotEqual(h, clone);
this.assertIdentical($H, Hash.from);
},
testKeys: function() {
this.assertEnumEqual([], $H({}).keys());
this.assertEnumEqual(['a'], $H(Fixtures.one).keys());
this.assertEnumEqual($w('a b c d'), $H(Fixtures.many).keys().sort());
this.assertEnumEqual($w('plus quad'), $H(Fixtures.functions).keys().sort());
},
testValues: function() {
this.assertEnumEqual([], $H({}).values());
this.assertEnumEqual(['A#'], $H(Fixtures.one).values());
this.assertEnumEqual($w('A B C D#'), $H(Fixtures.many).values().sort());
this.assertEnumEqual($w('function function'),
$H(Fixtures.functions).values().map(function(i){ return typeof i }));
this.assertEqual(9, $H(Fixtures.functions).get('quad')(3));
this.assertEqual(6, $H(Fixtures.functions).get('plus')(3));
},
testIndex: function() {
this.assertUndefined($H().index('foo'));
this.assert('a', $H(Fixtures.one).index('A#'));
this.assert('a', $H(Fixtures.many).index('A'));
this.assertUndefined($H(Fixtures.many).index('Z'))
var hash = $H({a:1,b:'2',c:1});
this.assert(['a','c'].include(hash.index(1)));
this.assertUndefined(hash.index('1'));
},
testMerge: function() {
var h = $H(Fixtures.many);
this.assertNotIdentical(h, h.merge());
this.assertNotIdentical(h, h.merge({}));
this.assertInstanceOf(Hash, h.merge());
this.assertInstanceOf(Hash, h.merge({}));
this.assertHashEqual(h, h.merge());
this.assertHashEqual(h, h.merge({}));
this.assertHashEqual(h, h.merge($H()));
this.assertHashEqual({a:'A', b:'B', c:'C', d:'D#', aaa:'AAA' }, h.merge({aaa: 'AAA'}));
this.assertHashEqual({a:'A#', b:'B', c:'C', d:'D#' }, h.merge(Fixtures.one));
},
testUpdate: function() {
var h = $H(Fixtures.many);
this.assertIdentical(h, h.update());
this.assertIdentical(h, h.update({}));
this.assertHashEqual(h, h.update());
this.assertHashEqual(h, h.update({}));
this.assertHashEqual(h, h.update($H()));
this.assertHashEqual({a:'A', b:'B', c:'C', d:'D#', aaa:'AAA' }, h.update({aaa: 'AAA'}));
this.assertHashEqual({a:'A#', b:'B', c:'C', d:'D#', aaa:'AAA' }, h.update(Fixtures.one));
},
testToQueryString: function() {
this.assertEqual('', $H({}).toQueryString());
this.assertEqual('a%23=A', $H({'a#': 'A'}).toQueryString());
this.assertEqual('a=A%23', $H(Fixtures.one).toQueryString());
this.assertEqual('a=A&b=B&c=C&d=D%23', $H(Fixtures.many).toQueryString());
this.assertEqual("a=b&c", $H(Fixtures.value_undefined).toQueryString());
this.assertEqual("a=b&c", $H("a=b&c".toQueryParams()).toQueryString());
this.assertEqual("a=b&c=", $H(Fixtures.value_null).toQueryString());
this.assertEqual("a=b&c=0", $H(Fixtures.value_zero).toQueryString());
this.assertEqual("color=r&color=g&color=b", $H(Fixtures.multiple).toQueryString());
this.assertEqual("color=r&color=&color=g&color&color=0", $H(Fixtures.multiple_nil).toQueryString());
this.assertEqual("color=&color", $H(Fixtures.multiple_all_nil).toQueryString());
this.assertEqual("", $H(Fixtures.multiple_empty).toQueryString());
this.assertEqual("", $H({foo: {}, bar: {}}).toQueryString());
this.assertEqual("stuff%5B%5D=%24&stuff%5B%5D=a&stuff%5B%5D=%3B", $H(Fixtures.multiple_special).toQueryString());
this.assertHashEqual(Fixtures.multiple_special, $H(Fixtures.multiple_special).toQueryString().toQueryParams());
this.assertIdentical(Object.toQueryString, Hash.toQueryString);
},
testInspect: function() {
this.assertEqual('#<Hash:{}>', $H({}).inspect());
this.assertEqual("#<Hash:{'a': 'A#'}>", $H(Fixtures.one).inspect());
this.assertEqual("#<Hash:{'a': 'A', 'b': 'B', 'c': 'C', 'd': 'D#'}>", $H(Fixtures.many).inspect());
},
testClone: function() {
var h = $H(Fixtures.many);
this.assertHashEqual(h, h.clone());
this.assertInstanceOf(Hash, h.clone());
this.assertNotIdentical(h, h.clone());
},
testToJSON: function() {
this.assertEqual('{\"b\": [false, true], \"c\": {\"a\": \"hello!\"}}',
$H({'b': [undefined, false, true, undefined], c: {a: 'hello!'}}).toJSON());
},
testAbilityToContainAnyKey: function() {
var h = $H({ _each: 'E', map: 'M', keys: 'K', pluck: 'P', unset: 'U' });
this.assertEnumEqual($w('_each keys map pluck unset'), h.keys().sort());
this.assertEqual('U', h.unset('unset'));
this.assertHashEqual({ _each: 'E', map: 'M', keys: 'K', pluck: 'P' }, h);
},
testHashToTemplateReplacements: function() {
var template = new Template("#{a} #{b}"), hash = $H({ a: "hello", b: "world" });
this.assertEqual("hello world", template.evaluate(hash.toObject()));
this.assertEqual("hello world", template.evaluate(hash));
this.assertEqual("hello", "#{a}".interpolate(hash));
},
testPreventIterationOverShadowedProperties: function() {
// redundant now that object is systematically cloned.
var FooMaker = function(value) {
this.key = value;
};
FooMaker.prototype.key = 'foo';
var foo = new FooMaker('bar');
this.assertEqual("key=bar", new Hash(foo).toQueryString());
this.assertEqual("key=bar", new Hash(new Hash(foo)).toQueryString());
}
});
// ]]>
</script>
</body>
</html>

201
test/unit/hash_test.js Normal file
View File

@ -0,0 +1,201 @@
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 }
};
new Test.Unit.Runner({
testSet: function() {
var h = $H({a: 'A'})
this.assertEqual('B', h.set('b', 'B'));
this.assertHashEqual({a: 'A', b: 'B'}, h);
this.assertUndefined(h.set('c'));
this.assertHashEqual({a: 'A', b: 'B', c: undefined}, h);
},
testGet: function() {
var h = $H({a: 'A'});
this.assertEqual('A', h.get('a'));
this.assertUndefined(h.a);
this.assertUndefined($H({}).get('a'));
},
testUnset: function() {
var hash = $H(Fixtures.many);
this.assertEqual('B', hash.unset('b'));
this.assertHashEqual({a:'A', c: 'C', d:'D#'}, hash);
this.assertUndefined(hash.unset('z'));
this.assertHashEqual({a:'A', c: 'C', d:'D#'}, hash);
// not equivalent to Hash#remove
this.assertEqual('A', hash.unset('a', 'c'));
this.assertHashEqual({c: 'C', d:'D#'}, hash);
},
testToObject: function() {
var hash = $H(Fixtures.many), object = hash.toObject();
this.assertInstanceOf(Object, object);
this.assertHashEqual(Fixtures.many, object);
this.assertNotIdentical(Fixtures.many, object);
hash.set('foo', 'bar');
this.assertHashNotEqual(object, hash.toObject());
},
testConstruct: function() {
var object = Object.clone(Fixtures.one);
var h = new Hash(object), h2 = $H(object);
this.assertInstanceOf(Hash, h);
this.assertInstanceOf(Hash, h2);
this.assertHashEqual({}, new Hash());
this.assertHashEqual(object, h);
this.assertHashEqual(object, h2);
h.set('foo', 'bar');
this.assertHashNotEqual(object, h);
var clone = $H(h);
this.assertInstanceOf(Hash, clone);
this.assertHashEqual(h, clone);
h.set('foo', 'foo');
this.assertHashNotEqual(h, clone);
this.assertIdentical($H, Hash.from);
},
testKeys: function() {
this.assertEnumEqual([], $H({}).keys());
this.assertEnumEqual(['a'], $H(Fixtures.one).keys());
this.assertEnumEqual($w('a b c d'), $H(Fixtures.many).keys().sort());
this.assertEnumEqual($w('plus quad'), $H(Fixtures.functions).keys().sort());
},
testValues: function() {
this.assertEnumEqual([], $H({}).values());
this.assertEnumEqual(['A#'], $H(Fixtures.one).values());
this.assertEnumEqual($w('A B C D#'), $H(Fixtures.many).values().sort());
this.assertEnumEqual($w('function function'),
$H(Fixtures.functions).values().map(function(i){ return typeof i }));
this.assertEqual(9, $H(Fixtures.functions).get('quad')(3));
this.assertEqual(6, $H(Fixtures.functions).get('plus')(3));
},
testIndex: function() {
this.assertUndefined($H().index('foo'));
this.assert('a', $H(Fixtures.one).index('A#'));
this.assert('a', $H(Fixtures.many).index('A'));
this.assertUndefined($H(Fixtures.many).index('Z'))
var hash = $H({a:1,b:'2',c:1});
this.assert(['a','c'].include(hash.index(1)));
this.assertUndefined(hash.index('1'));
},
testMerge: function() {
var h = $H(Fixtures.many);
this.assertNotIdentical(h, h.merge());
this.assertNotIdentical(h, h.merge({}));
this.assertInstanceOf(Hash, h.merge());
this.assertInstanceOf(Hash, h.merge({}));
this.assertHashEqual(h, h.merge());
this.assertHashEqual(h, h.merge({}));
this.assertHashEqual(h, h.merge($H()));
this.assertHashEqual({a:'A', b:'B', c:'C', d:'D#', aaa:'AAA' }, h.merge({aaa: 'AAA'}));
this.assertHashEqual({a:'A#', b:'B', c:'C', d:'D#' }, h.merge(Fixtures.one));
},
testUpdate: function() {
var h = $H(Fixtures.many);
this.assertIdentical(h, h.update());
this.assertIdentical(h, h.update({}));
this.assertHashEqual(h, h.update());
this.assertHashEqual(h, h.update({}));
this.assertHashEqual(h, h.update($H()));
this.assertHashEqual({a:'A', b:'B', c:'C', d:'D#', aaa:'AAA' }, h.update({aaa: 'AAA'}));
this.assertHashEqual({a:'A#', b:'B', c:'C', d:'D#', aaa:'AAA' }, h.update(Fixtures.one));
},
testToQueryString: function() {
this.assertEqual('', $H({}).toQueryString());
this.assertEqual('a%23=A', $H({'a#': 'A'}).toQueryString());
this.assertEqual('a=A%23', $H(Fixtures.one).toQueryString());
this.assertEqual('a=A&b=B&c=C&d=D%23', $H(Fixtures.many).toQueryString());
this.assertEqual("a=b&c", $H(Fixtures.value_undefined).toQueryString());
this.assertEqual("a=b&c", $H("a=b&c".toQueryParams()).toQueryString());
this.assertEqual("a=b&c=", $H(Fixtures.value_null).toQueryString());
this.assertEqual("a=b&c=0", $H(Fixtures.value_zero).toQueryString());
this.assertEqual("color=r&color=g&color=b", $H(Fixtures.multiple).toQueryString());
this.assertEqual("color=r&color=&color=g&color&color=0", $H(Fixtures.multiple_nil).toQueryString());
this.assertEqual("color=&color", $H(Fixtures.multiple_all_nil).toQueryString());
this.assertEqual("", $H(Fixtures.multiple_empty).toQueryString());
this.assertEqual("", $H({foo: {}, bar: {}}).toQueryString());
this.assertEqual("stuff%5B%5D=%24&stuff%5B%5D=a&stuff%5B%5D=%3B", $H(Fixtures.multiple_special).toQueryString());
this.assertHashEqual(Fixtures.multiple_special, $H(Fixtures.multiple_special).toQueryString().toQueryParams());
this.assertIdentical(Object.toQueryString, Hash.toQueryString);
},
testInspect: function() {
this.assertEqual('#<Hash:{}>', $H({}).inspect());
this.assertEqual("#<Hash:{'a': 'A#'}>", $H(Fixtures.one).inspect());
this.assertEqual("#<Hash:{'a': 'A', 'b': 'B', 'c': 'C', 'd': 'D#'}>", $H(Fixtures.many).inspect());
},
testClone: function() {
var h = $H(Fixtures.many);
this.assertHashEqual(h, h.clone());
this.assertInstanceOf(Hash, h.clone());
this.assertNotIdentical(h, h.clone());
},
testToJSON: function() {
this.assertEqual('{\"b\": [false, true], \"c\": {\"a\": \"hello!\"}}',
$H({'b': [undefined, false, true, undefined], c: {a: 'hello!'}}).toJSON());
},
testAbilityToContainAnyKey: function() {
var h = $H({ _each: 'E', map: 'M', keys: 'K', pluck: 'P', unset: 'U' });
this.assertEnumEqual($w('_each keys map pluck unset'), h.keys().sort());
this.assertEqual('U', h.unset('unset'));
this.assertHashEqual({ _each: 'E', map: 'M', keys: 'K', pluck: 'P' }, h);
},
testHashToTemplateReplacements: function() {
var template = new Template("#{a} #{b}"), hash = $H({ a: "hello", b: "world" });
this.assertEqual("hello world", template.evaluate(hash.toObject()));
this.assertEqual("hello world", template.evaluate(hash));
this.assertEqual("hello", "#{a}".interpolate(hash));
},
testPreventIterationOverShadowedProperties: function() {
// redundant now that object is systematically cloned.
var FooMaker = function(value) {
this.key = value;
};
FooMaker.prototype.key = 'foo';
var foo = new FooMaker('bar');
this.assertEqual("key=bar", new Hash(foo).toQueryString());
this.assertEqual("key=bar", new Hash(new Hash(foo)).toQueryString());
}
});

View File

@ -1,63 +0,0 @@
<!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" />
</head>
<body>
<h1>Prototype Unit test file</h1>
<p>
Test of utility functions in number.js
</p>
<!-- Log output -->
<div id="testlog"> </div>
<!-- Tests follow -->
<script type="text/javascript" language="javascript" charset="utf-8">
// <![CDATA[
new Test.Unit.Runner({
testNumberMathMethods: function() {
this.assertEqual(1, (0.9).round());
this.assertEqual(-2, (-1.9).floor());
this.assertEqual(-1, (-1.9).ceil());
$w('abs floor round ceil').each(function(method) {
this.assertEqual(Math[method](Math.PI), Math.PI[method]());
}, this);
},
testNumberToColorPart: function() {
this.assertEqual('00', (0).toColorPart());
this.assertEqual('0a', (10).toColorPart());
this.assertEqual('ff', (255).toColorPart());
},
testNumberToPaddedString: function() {
this.assertEqual('00', (0).toPaddedString(2, 16));
this.assertEqual('0a', (10).toPaddedString(2, 16));
this.assertEqual('ff', (255).toPaddedString(2, 16));
this.assertEqual('000', (0).toPaddedString(3));
this.assertEqual('010', (10).toPaddedString(3));
this.assertEqual('100', (100).toPaddedString(3));
this.assertEqual('1000', (1000).toPaddedString(3));
},
testNumberToJSON: function() {
this.assertEqual('null', Number.NaN.toJSON());
this.assertEqual('0', (0).toJSON());
this.assertEqual('-293', (-293).toJSON());
}
});
// ]]>
</script>
</body>
</html>

34
test/unit/number_test.js Normal file
View File

@ -0,0 +1,34 @@
new Test.Unit.Runner({
testNumberMathMethods: function() {
this.assertEqual(1, (0.9).round());
this.assertEqual(-2, (-1.9).floor());
this.assertEqual(-1, (-1.9).ceil());
$w('abs floor round ceil').each(function(method) {
this.assertEqual(Math[method](Math.PI), Math.PI[method]());
}, this);
},
testNumberToColorPart: function() {
this.assertEqual('00', (0).toColorPart());
this.assertEqual('0a', (10).toColorPart());
this.assertEqual('ff', (255).toColorPart());
},
testNumberToPaddedString: function() {
this.assertEqual('00', (0).toPaddedString(2, 16));
this.assertEqual('0a', (10).toPaddedString(2, 16));
this.assertEqual('ff', (255).toPaddedString(2, 16));
this.assertEqual('000', (0).toPaddedString(3));
this.assertEqual('010', (10).toPaddedString(3));
this.assertEqual('100', (100).toPaddedString(3));
this.assertEqual('1000', (1000).toPaddedString(3));
},
testNumberToJSON: function() {
this.assertEqual('null', Number.NaN.toJSON());
this.assertEqual('0', (0).toJSON());
this.assertEqual('-293', (-293).toJSON());
}
});

View File

@ -1,82 +0,0 @@
<!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" />
</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;font-size:2px">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() {
Position.prepare();
this.assertEqual(0, Position.deltaX);
this.assertEqual(0, Position.deltaY);
scrollTo(20,30);
Position.prepare();
this.assertEqual(20, Position.deltaX);
this.assertEqual(30, Position.deltaY);
},
testWithin: function() {
[true, false].each(function(withScrollOffsets) {
Position.includeScrollOffsets = withScrollOffsets;
this.assert(!Position.within($('body_absolute'), 9, 9), 'outside left/top');
this.assert(Position.within($('body_absolute'), 10, 10), 'left/top corner');
this.assert(Position.within($('body_absolute'), 10, 19), 'left/bottom corner');
this.assert(!Position.within($('body_absolute'), 10, 20), 'outside bottom');
}, this);
scrollTo(20,30);
Position.prepare();
Position.includeScrollOffsets = true;
this.assert(!Position.within($('body_absolute'), 9, 9), 'outside left/top');
this.assert(Position.within($('body_absolute'), 10, 10), 'left/top corner');
this.assert(Position.within($('body_absolute'), 10, 19), 'left/bottom corner');
this.assert(!Position.within($('body_absolute'), 10, 20), 'outside bottom');
}
});
// ]]>
</script>
</body>
</html>

View File

@ -0,0 +1,44 @@
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() {
Position.prepare();
this.assertEqual(0, Position.deltaX);
this.assertEqual(0, Position.deltaY);
scrollTo(20,30);
Position.prepare();
this.assertEqual(20, Position.deltaX);
this.assertEqual(30, Position.deltaY);
},
testWithin: function() {
[true, false].each(function(withScrollOffsets) {
Position.includeScrollOffsets = withScrollOffsets;
this.assert(!Position.within($('body_absolute'), 9, 9), 'outside left/top');
this.assert(Position.within($('body_absolute'), 10, 10), 'left/top corner');
this.assert(Position.within($('body_absolute'), 10, 19), 'left/bottom corner');
this.assert(!Position.within($('body_absolute'), 10, 20), 'outside bottom');
}, this);
scrollTo(20,30);
Position.prepare();
Position.includeScrollOffsets = true;
this.assert(!Position.within($('body_absolute'), 9, 9), 'outside left/top');
this.assert(Position.within($('body_absolute'), 10, 10), 'left/top corner');
this.assert(Position.within($('body_absolute'), 10, 19), 'left/bottom corner');
this.assert(!Position.within($('body_absolute'), 10, 20), 'outside bottom');
}
});

View File

@ -1,84 +0,0 @@
<!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" />
</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() {
this.assert(!$R(0, 0, true).include(0));
this.assert($R(0, 0, false).include(0));
this.assert($R(0, 5, true).include(0));
this.assert($R(0, 5, true).include(4));
this.assert(!$R(0, 5, true).include(5));
this.assert($R(0, 5, false).include(0));
this.assert($R(0, 5, false).include(5));
this.assert(!$R(0, 5, false).include(6));
},
testEach: function() {
var results = [];
$R(0, 0, true).each(function(value) {
results.push(value);
});
this.assertEnumEqual([], results);
results = [];
$R(0, 3, false).each(function(value) {
results.push(value);
});
this.assertEnumEqual([0, 1, 2, 3], results);
},
testAny: function() {
this.assert(!$R(1, 1, true).any());
this.assert($R(0, 3, false).any(function(value) {
return value == 3;
}));
},
testAll: function() {
this.assert($R(1, 1, true).all());
this.assert($R(0, 3, false).all(function(value) {
return value <= 3;
}));
},
testToArray: function() {
this.assertEnumEqual([], $R(0, 0, true).toArray());
this.assertEnumEqual([0], $R(0, 0, false).toArray());
this.assertEnumEqual([0], $R(0, 1, true).toArray());
this.assertEnumEqual([0, 1], $R(0, 1, false).toArray());
this.assertEnumEqual([-3, -2, -1, 0, 1, 2], $R(-3, 3, true).toArray());
this.assertEnumEqual([-3, -2, -1, 0, 1, 2, 3], $R(-3, 3, false).toArray());
},
testDefaultsToNotExclusive: function() {
this.assertEnumEqual($R(-3,3), $R(-3,3,false));
}
});
// ]]>
</script>
</body>
</html>

58
test/unit/range_test.js Normal file
View File

@ -0,0 +1,58 @@
new Test.Unit.Runner({
testInclude: function() {
this.assert(!$R(0, 0, true).include(0));
this.assert($R(0, 0, false).include(0));
this.assert($R(0, 5, true).include(0));
this.assert($R(0, 5, true).include(4));
this.assert(!$R(0, 5, true).include(5));
this.assert($R(0, 5, false).include(0));
this.assert($R(0, 5, false).include(5));
this.assert(!$R(0, 5, false).include(6));
},
testEach: function() {
var results = [];
$R(0, 0, true).each(function(value) {
results.push(value);
});
this.assertEnumEqual([], results);
results = [];
$R(0, 3, false).each(function(value) {
results.push(value);
});
this.assertEnumEqual([0, 1, 2, 3], results);
},
testAny: function() {
this.assert(!$R(1, 1, true).any());
this.assert($R(0, 3, false).any(function(value) {
return value == 3;
}));
},
testAll: function() {
this.assert($R(1, 1, true).all());
this.assert($R(0, 3, false).all(function(value) {
return value <= 3;
}));
},
testToArray: function() {
this.assertEnumEqual([], $R(0, 0, true).toArray());
this.assertEnumEqual([0], $R(0, 0, false).toArray());
this.assertEnumEqual([0], $R(0, 1, true).toArray());
this.assertEnumEqual([0, 1], $R(0, 1, false).toArray());
this.assertEnumEqual([-3, -2, -1, 0, 1, 2], $R(-3, 3, true).toArray());
this.assertEnumEqual([-3, -2, -1, 0, 1, 2, 3], $R(-3, 3, false).toArray());
},
testDefaultsToNotExclusive: function() {
this.assertEnumEqual($R(-3,3), $R(-3,3,false));
}
});

View File

@ -1,477 +0,0 @@
<!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" />
</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>
<form id="troubleForm2">
<input type="checkbox" name="brackets[5][]" id="chk_1" checked="checked" value="1" />
<input type="checkbox" name="brackets[5][]" id="chk_2" value="2" />
</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" class="span_foo span_bar">
<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 id="counted_container"><div class="is_counted"></div></div>
</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() {
this.assertEnumEqual($A(document.getElementsByTagName('li')), $$('li'));
this.assertEnumEqual([$('strong')], $$('strong'));
this.assertEnumEqual([], $$('nonexistent'));
var allNodes = $A(document.getElementsByTagName('*')).select( function(node) {
return node.tagName !== '!';
});
this.assertEnumEqual(allNodes, $$('*'));
},
testSelectorWithId: function() {
this.assertEnumEqual([$('fixtures')], $$('#fixtures'));
this.assertEnumEqual([], $$('#nonexistent'));
this.assertEnumEqual([$('troubleForm')], $$('#troubleForm'));
},
testSelectorWithClassName: function() {
this.assertEnumEqual($('p', 'link_1', 'item_1'), $$('.first'));
this.assertEnumEqual([], $$('.second'));
},
testSelectorWithTagNameAndId: function() {
this.assertEnumEqual([$('strong')], $$('strong#strong'));
this.assertEnumEqual([], $$('p#strong'));
},
testSelectorWithTagNameAndClassName: function() {
this.assertEnumEqual($('link_1', 'link_2'), $$('a.internal'));
this.assertEnumEqual([$('link_2')], $$('a.internal.highlight'));
this.assertEnumEqual([$('link_2')], $$('a.highlight.internal'));
this.assertEnumEqual([], $$('a.highlight.internal.nonexistent'));
},
testSelectorWithIdAndClassName: function() {
this.assertEnumEqual([$('link_2')], $$('#link_2.internal'));
this.assertEnumEqual([$('link_2')], $$('.internal#link_2'));
this.assertEnumEqual([$('link_2')], $$('#link_2.internal.highlight'));
this.assertEnumEqual([], $$('#link_2.internal.nonexistent'));
},
testSelectorWithTagNameAndIdAndClassName: function() {
this.assertEnumEqual([$('link_2')], $$('a#link_2.internal'));
this.assertEnumEqual([$('link_2')], $$('a.internal#link_2'));
this.assertEnumEqual([$('item_1')], $$('li#item_1.first'));
this.assertEnumEqual([], $$('li#item_1.nonexistent'));
this.assertEnumEqual([], $$('li#item_1.first.nonexistent'));
},
test$$MatchesAncestryWithTokensSeparatedByWhitespace: function() {
this.assertEnumEqual($('em2', 'em', 'span'), $$('#fixtures a *'));
this.assertEnumEqual([$('p')], $$('div#fixtures p'));
},
test$$CombinesResultsWhenMultipleExpressionsArePassed: function() {
this.assertEnumEqual($('link_1', 'link_2', 'item_1', 'item_2', 'item_3'), $$('#p a', ' ul#list li '));
},
testSelectorWithTagNameAndAttributeExistence: function() {
this.assertEnumEqual($$('#fixtures h1'), $$('h1[class]'), 'h1[class]');
this.assertEnumEqual($$('#fixtures h1'), $$('h1[CLASS]'), 'h1[CLASS]');
this.assertEnumEqual([$('item_3')], $$('li#item_3[class]'), 'li#item_3[class]');
},
testSelectorWithTagNameAndSpecificAttributeValue: function() {
this.assertEnumEqual($('link_1', 'link_2', 'link_3'), $$('a[href="#"]'));
this.assertEnumEqual($('link_1', 'link_2', 'link_3'), $$('a[href=#]'));
},
testSelectorWithTagNameAndWhitespaceTokenizedAttributeValue: function() {
this.assertEnumEqual($('link_1', 'link_2'), $$('a[class~="internal"]'), "a[class~=\"internal\"]");
this.assertEnumEqual($('link_1', 'link_2'), $$('a[class~=internal]'), "a[class~=internal]");
},
testSelectorWithAttributeAndNoTagName: function() {
this.assertEnumEqual($(document.body).select('a[href]'), $(document.body).select('[href]'));
this.assertEnumEqual($$('a[class~="internal"]'), $$('[class~=internal]'));
this.assertEnumEqual($$('*[id]'), $$('[id]'));
this.assertEnumEqual($('checked_radio', 'unchecked_radio'), $$('[type=radio]'));
this.assertEnumEqual($$('*[type=checkbox]'), $$('[type=checkbox]'));
this.assertEnumEqual($('with_title', 'commaParent'), $$('[title]'));
this.assertEnumEqual($$('#troubleForm *[type=radio]'), $$('#troubleForm [type=radio]'));
this.assertEnumEqual($$('#troubleForm *[type]'), $$('#troubleForm [type]'));
},
testSelectorWithUniversalAndHyphenTokenizedAttributeValue: function() {
this.assertEnumEqual([$('item_3')], $$('*[xml:lang|="es"]'));
this.assertEnumEqual([$('item_3')], $$('*[xml:lang|="ES"]'));
},
testSelectorWithTagNameAndNegatedAttributeValue: function() {
this.assertEnumEqual([], $$('a[href!="#"]'));
},
testSelectorWithBracketAttributeValue: function() {
this.assertEnumEqual($('chk_1', 'chk_2'), $$('#troubleForm2 input[name="brackets[5][]"]'));
this.assertEnumEqual([$('chk_1')], $$('#troubleForm2 input[name="brackets[5][]"]:checked'));
this.assertEnumEqual([$('chk_2')], $$('#troubleForm2 input[name="brackets[5][]"][value=2]'));
this.assertEnumEqual([], $$('#troubleForm2 input[name=brackets[5][]]'));
},
test$$WithNestedAttributeSelectors: function() {
this.assertEnumEqual([$('strong')], $$('div[style] p[id] strong'), 'div[style] p[id] strong');
},
testSelectorWithMultipleConditions: function() {
this.assertEnumEqual([$('link_3')], $$('a[class~=external][href="#"]'),
'a[class~=external][href="#"]');
this.assertEnumEqual([], $$('a[class~=external][href!="#"]'),
'a[class~=external][href!="#"]');
},
testSelectorMatchElements: function() {
this.assertElementsMatch(Selector.matchElements($('list').descendants(), 'li'), '#item_1', '#item_2', '#item_3');
this.assertElementsMatch(Selector.matchElements($('fixtures').descendants(), 'a.internal'), '#link_1', '#link_2');
this.assertEnumEqual([], Selector.matchElements($('fixtures').descendants(), 'p.last'));
this.assertElementsMatch(Selector.matchElements($('fixtures').descendants(), '.inexistant, a.internal'), '#link_1', '#link_2');
},
testSelectorFindElement: function() {
this.assertElementMatches(Selector.findElement($('list').descendants(), 'li'), 'li#item_1.first');
this.assertElementMatches(Selector.findElement($('list').descendants(), 'li', 1), 'li#item_2');
this.assertElementMatches(Selector.findElement($('list').descendants(), 'li#item_3'), 'li');
this.assertEqual(undefined, Selector.findElement($('list').descendants(), 'em'));
},
testElementMatch: function() {
var span = $('dupL1');
// tests that should pass
this.assert(span.match('span'));
this.assert(span.match('span#dupL1'));
this.assert(span.match('div > span'), 'child combinator');
this.assert(span.match('#dupContainer span'), 'descendant combinator');
this.assert(span.match('#dupL1'), 'ID only');
this.assert(span.match('span.span_foo'), 'class name 1');
this.assert(span.match('span.span_bar'), 'class name 2');
this.assert(span.match('span:first-child'), 'first-child pseudoclass');
this.assert(!span.match('span.span_wtf'), 'bogus class name');
this.assert(!span.match('#dupL2'), 'different ID');
this.assert(!span.match('div'), 'different tag name');
this.assert(!span.match('span span'), 'different ancestry');
this.assert(!span.match('span > span'), 'different parent');
this.assert(!span.match('span:nth-child(5)'), 'different pseudoclass');
this.assert(!$('link_2').match('a[rel^=external]'));
this.assert($('link_1').match('a[rel^=external]'));
this.assert($('link_1').match('a[rel^="external"]'));
this.assert($('link_1').match("a[rel^='external']"));
this.assert(span.match({ match: function(element) { return true }}), 'custom selector');
this.assert(!span.match({ match: function(element) { return false }}), 'custom selector');
},
testSelectorWithSpaceInAttributeValue: function() {
this.assertEnumEqual([$('with_title')], $$('cite[title="hello world!"]'));
},
// AND NOW COME THOSE NEW TESTS AFTER ANDREW'S REWRITE!
testSelectorWithNamespacedAttributes: function() {
if (Prototype.BrowserFeatures.XPath) {
this.assertUndefined(new Selector('html[xml:lang]').xpath);
this.assertUndefined(new Selector('body p[xml:lang]').xpath);
} else
this.info("Could not test XPath bypass: no XPath to begin with!");
this.assertElementsMatch($$('[xml:lang]'), 'html', '#item_3');
this.assertElementsMatch($$('*[xml:lang]'), 'html', '#item_3');
},
testSelectorWithChild: function() {
this.assertEnumEqual($('link_1', 'link_2'), $$('p.first > a'));
this.assertEnumEqual($('father', 'uncle'), $$('div#grandfather > div'));
this.assertEnumEqual($('level2_1', 'level2_2'), $$('#level1>span'));
this.assertEnumEqual($('level2_1', 'level2_2'), $$('#level1 > span'));
this.assertEnumEqual($('level3_1', 'level3_2'), $$('#level2_1 > *'));
this.assertEnumEqual([], $$('div > #nonexistent'));
$RunBenchmarks && this.wait(500, function() {
this.benchmark(function() { $$('#level1 > span') }, 1000);
});
},
testSelectorWithAdjacence: function() {
this.assertEnumEqual([$('uncle')], $$('div.brothers + div.brothers'));
this.assertEnumEqual([$('uncle')], $$('div.brothers + div'));
this.assertEqual($('level2_2'), $$('#level2_1+span').reduce());
this.assertEqual($('level2_2'), $$('#level2_1 + span').reduce());
this.assertEqual($('level2_2'), $$('#level2_1 + *').reduce());
this.assertEnumEqual([], $$('#level2_2 + span'));
this.assertEqual($('level3_2'), $$('#level3_1 + span').reduce());
this.assertEqual($('level3_2'), $$('#level3_1 + *').reduce());
this.assertEnumEqual([], $$('#level3_2 + *'));
this.assertEnumEqual([], $$('#level3_1 + em'));
$RunBenchmarks && this.wait(500, function() {
this.benchmark(function() { $$('#level3_1 + span') }, 1000);
});
},
testSelectorWithLaterSibling: function() {
this.assertEnumEqual([$('list')], $$('h1 ~ ul'));
this.assertEqual($('level2_2'), $$('#level2_1 ~ span').reduce());
this.assertEnumEqual($('level2_2', 'level2_3'), $$('#level2_1 ~ *').reduce());
this.assertEnumEqual([], $$('#level2_2 ~ span'));
this.assertEnumEqual([], $$('#level3_2 ~ *'));
this.assertEnumEqual([], $$('#level3_1 ~ em'));
this.assertEnumEqual([$('level3_2')], $$('#level3_1 ~ #level3_2'));
this.assertEnumEqual([$('level3_2')], $$('span ~ #level3_2'));
this.assertEnumEqual([], $$('div ~ #level3_2'));
this.assertEnumEqual([], $$('div ~ #level2_3'));
$RunBenchmarks && this.wait(500, function() {
this.benchmark(function() { $$('#level2_1 ~ span') }, 1000);
});
},
testSelectorWithNewAttributeOperators: function() {
this.assertEnumEqual($('father', 'uncle'), $$('div[class^=bro]'), 'matching beginning of string');
this.assertEnumEqual($('father', 'uncle'), $$('div[class$=men]'), 'matching end of string');
this.assertEnumEqual($('father', 'uncle'), $$('div[class*="ers m"]'), 'matching substring')
this.assertEnumEqual($('level2_1', 'level2_2', 'level2_3'), $$('#level1 *[id^="level2_"]'));
this.assertEnumEqual($('level2_1', 'level2_2', 'level2_3'), $$('#level1 *[id^=level2_]'));
this.assertEnumEqual($('level2_1', 'level3_1'), $$('#level1 *[id$="_1"]'));
this.assertEnumEqual($('level2_1', 'level3_1'), $$('#level1 *[id$=_1]'));
this.assertEnumEqual($('level2_1', 'level3_2', 'level2_2', 'level2_3'), $$('#level1 *[id*="2"]'));
this.assertEnumEqual($('level2_1', 'level3_2', 'level2_2', 'level2_3'), $$('#level1 *[id*=2]'));
$RunBenchmarks && this.wait(500, function() {
this.benchmark(function() { $$('#level1 *[id^=level2_]') }, 1000, '[^=]');
this.benchmark(function() { $$('#level1 *[id$=_1]') }, 1000, '[$=]');
this.benchmark(function() { $$('#level1 *[id*=_2]') }, 1000, '[*=]');
});
},
testSelectorWithDuplicates: function() {
this.assertEnumEqual($$('div div'), $$('div div').uniq());
this.assertEnumEqual($('dupL2', 'dupL3', 'dupL4', 'dupL5'), $$('#dupContainer span span'));
$RunBenchmarks && this.wait(500, function() {
this.benchmark(function() { $$('#dupContainer span span') }, 1000);
});
},
testSelectorWithFirstLastOnlyNthNthLastChild: function() {
this.assertEnumEqual([$('level2_1')], $$('#level1>*:first-child'));
this.assertEnumEqual($('level2_1', 'level3_1', 'level_only_child'), $$('#level1 *:first-child'));
this.assertEnumEqual([$('level2_3')], $$('#level1>*:last-child'));
this.assertEnumEqual($('level3_2', 'level_only_child', 'level2_3'), $$('#level1 *:last-child'));
this.assertEnumEqual([$('level2_3')], $$('#level1>div:last-child'));
this.assertEnumEqual([$('level2_3')], $$('#level1 div:last-child'));
this.assertEnumEqual([], $$('#level1>div:first-child'));
this.assertEnumEqual([], $$('#level1>span:last-child'));
this.assertEnumEqual($('level2_1', 'level3_1'), $$('#level1 span:first-child'));
this.assertEnumEqual([], $$('#level1:first-child'));
this.assertEnumEqual([], $$('#level1>*:only-child'));
this.assertEnumEqual([$('level_only_child')], $$('#level1 *:only-child'));
this.assertEnumEqual([], $$('#level1:only-child'));
this.assertEnumEqual([$('link_2')], $$('#p *:nth-last-child(2)'), 'nth-last-child');
this.assertEnumEqual([$('link_2')], $$('#p *:nth-child(3)'), 'nth-child');
this.assertEnumEqual([$('link_2')], $$('#p a:nth-child(3)'), 'nth-child');
this.assertEnumEqual($('item_2', 'item_3'), $$('#list > li:nth-child(n+2)'));
this.assertEnumEqual($('item_1', 'item_2'), $$('#list > li:nth-child(-n+2)'));
$RunBenchmarks && this.wait(500, function() {
this.benchmark(function() { $$('#level1 *:first-child') }, 1000, ':first-child');
this.benchmark(function() { $$('#level1 *:last-child') }, 1000, ':last-child');
this.benchmark(function() { $$('#level1 *:only-child') }, 1000, ':only-child');
});
},
testSelectorWithFirstLastNthNthLastOfType: function() {
this.assertEnumEqual([$('link_2')], $$('#p a:nth-of-type(2)'), 'nth-of-type');
this.assertEnumEqual([$('link_1')], $$('#p a:nth-of-type(1)'), 'nth-of-type');
this.assertEnumEqual([$('link_2')], $$('#p a:nth-last-of-type(1)'), 'nth-last-of-type');
this.assertEnumEqual([$('link_1')], $$('#p a:first-of-type'), 'first-of-type');
this.assertEnumEqual([$('link_2')], $$('#p a:last-of-type'), 'last-of-type');
},
testSelectorWithNot: function() {
this.assertEnumEqual([$('link_2')], $$('#p a:not(a:first-of-type)'), 'first-of-type');
this.assertEnumEqual([$('link_1')], $$('#p a:not(a:last-of-type)'), 'last-of-type');
this.assertEnumEqual([$('link_2')], $$('#p a:not(a:nth-of-type(1))'), 'nth-of-type');
this.assertEnumEqual([$('link_1')], $$('#p a:not(a:nth-last-of-type(1))'), 'nth-last-of-type');
this.assertEnumEqual([$('link_2')], $$('#p a:not([rel~=nofollow])'), 'attribute 1');
this.assertEnumEqual([$('link_2')], $$('#p a:not(a[rel^=external])'), 'attribute 2');
this.assertEnumEqual([$('link_2')], $$('#p a:not(a[rel$=nofollow])'), 'attribute 3');
this.assertEnumEqual([$('em')], $$('#p a:not(a[rel$="nofollow"]) > em'), 'attribute 4')
this.assertEnumEqual([$('item_2')], $$('#list li:not(#item_1):not(#item_3)'), 'adjacent :not clauses');
this.assertEnumEqual([$('son')], $$('#grandfather > div:not(#uncle) #son'));
this.assertEnumEqual([$('em')], $$('#p a:not(a[rel$="nofollow"]) em'), 'attribute 4 + all descendants');
this.assertEnumEqual([$('em')], $$('#p a:not(a[rel$="nofollow"])>em'), 'attribute 4 (without whitespace)');
},
testSelectorWithEnabledDisabledChecked: function() {
this.assertEnumEqual([$('disabled_text_field')], $$('#troubleForm > *:disabled'));
this.assertEnumEqual($('troubleForm').getInputs().without($('disabled_text_field'), $('hidden')), $$('#troubleForm > *:enabled'));
this.assertEnumEqual($('checked_box', 'checked_radio'), $$('#troubleForm *:checked'));
},
testSelectorWithEmpty: function() {
$('level3_1').innerHTML = "";
this.assertEnumEqual($('level3_1', 'level3_2', 'level2_3'),
$$('#level1 *:empty'), '#level1 *:empty');
this.assertEnumEqual([], $$('#level_only_child:empty'), 'newlines count as content!');
},
testIdenticalResultsFromEquivalentSelectors: function() {
this.assertEnumEqual($$('div.brothers'), $$('div[class~=brothers]'));
this.assertEnumEqual($$('div.brothers'), $$('div[class~=brothers].brothers'));
this.assertEnumEqual($$('div:not(.brothers)'), $$('div:not([class~=brothers])'));
this.assertEnumEqual($$('li ~ li'), $$('li:not(:first-child)'));
this.assertEnumEqual($$('ul > li'), $$('ul > li:nth-child(n)'));
this.assertEnumEqual($$('ul > li:nth-child(even)'), $$('ul > li:nth-child(2n)'));
this.assertEnumEqual($$('ul > li:nth-child(odd)'), $$('ul > li:nth-child(2n+1)'));
this.assertEnumEqual($$('ul > li:first-child'), $$('ul > li:nth-child(1)'));
this.assertEnumEqual($$('ul > li:last-child'), $$('ul > li:nth-last-child(1)'));
this.assertEnumEqual($$('ul > li:nth-child(n-999)'), $$('ul > li'));
this.assertEnumEqual($$('ul>li'), $$('ul > li'));
this.assertEnumEqual($$('#p a:not(a[rel$="nofollow"])>em'), $$('#p a:not(a[rel$="nofollow"]) > em'))
},
testSelectorsThatShouldReturnNothing: function() {
this.assertEnumEqual([], $$('span:empty > *'));
this.assertEnumEqual([], $$('div.brothers:not(.brothers)'));
this.assertEnumEqual([], $$('#level2_2 :only-child:not(:last-child)'));
this.assertEnumEqual([], $$('#level2_2 :only-child:not(:first-child)'));
},
testCommasFor$$: function() {
this.assertEnumEqual($('list', 'p', 'link_1', 'item_1', 'item_3', 'troubleForm'), $$('#list, .first,*[xml:lang="es-us"] , #troubleForm'));
this.assertEnumEqual($('list', 'p', 'link_1', 'item_1', 'item_3', 'troubleForm'), $$('#list, .first,', '*[xml:lang="es-us"] , #troubleForm'));
this.assertEnumEqual($('commaParent', 'commaChild'), $$('form[title*="commas,"], input[value="#commaOne,#commaTwo"]'));
this.assertEnumEqual($('commaParent', 'commaChild'), $$('form[title*="commas,"]', 'input[value="#commaOne,#commaTwo"]'));
},
testSelectorExtendsAllNodes: function(){
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');
this.assert(typeof results[0].show == 'function');
this.assert(typeof results[1].show == 'function');
this.assert(typeof results[2].show == 'function');
},
testCountedIsNotAnAttribute: function() {
var el = $('list');
Selector.handlers.mark([el]);
this.assert(!el.innerHTML.include("_counted"));
Selector.handlers.unmark([el]);
this.assert(!el.innerHTML.include("_counted"));
},
testCopiedNodesGetIncluded: function() {
this.assertElementsMatch(
Selector.matchElements($('counted_container').descendants(), 'div'),
'div.is_counted'
);
$('counted_container').innerHTML += $('counted_container').innerHTML;
this.assertElementsMatch(
Selector.matchElements($('counted_container').descendants(), 'div'), 'div.is_counted',
'div.is_counted'
);
},
testElementDown: function() {
var a = $('dupL4');
var b = $('dupContainer').down('#dupL4');
this.assertEqual(a, b);
}
});
// ]]>
</script>
</body>
</html>

377
test/unit/selector_test.js Normal file
View File

@ -0,0 +1,377 @@
var $RunBenchmarks = false;
new Test.Unit.Runner({
testSelectorWithTagName: function() {
this.assertEnumEqual($A(document.getElementsByTagName('li')), $$('li'));
this.assertEnumEqual([$('strong')], $$('strong'));
this.assertEnumEqual([], $$('nonexistent'));
var allNodes = $A(document.getElementsByTagName('*')).select( function(node) {
return node.tagName !== '!';
});
this.assertEnumEqual(allNodes, $$('*'));
},
testSelectorWithId: function() {
this.assertEnumEqual([$('fixtures')], $$('#fixtures'));
this.assertEnumEqual([], $$('#nonexistent'));
this.assertEnumEqual([$('troubleForm')], $$('#troubleForm'));
},
testSelectorWithClassName: function() {
this.assertEnumEqual($('p', 'link_1', 'item_1'), $$('.first'));
this.assertEnumEqual([], $$('.second'));
},
testSelectorWithTagNameAndId: function() {
this.assertEnumEqual([$('strong')], $$('strong#strong'));
this.assertEnumEqual([], $$('p#strong'));
},
testSelectorWithTagNameAndClassName: function() {
this.assertEnumEqual($('link_1', 'link_2'), $$('a.internal'));
this.assertEnumEqual([$('link_2')], $$('a.internal.highlight'));
this.assertEnumEqual([$('link_2')], $$('a.highlight.internal'));
this.assertEnumEqual([], $$('a.highlight.internal.nonexistent'));
},
testSelectorWithIdAndClassName: function() {
this.assertEnumEqual([$('link_2')], $$('#link_2.internal'));
this.assertEnumEqual([$('link_2')], $$('.internal#link_2'));
this.assertEnumEqual([$('link_2')], $$('#link_2.internal.highlight'));
this.assertEnumEqual([], $$('#link_2.internal.nonexistent'));
},
testSelectorWithTagNameAndIdAndClassName: function() {
this.assertEnumEqual([$('link_2')], $$('a#link_2.internal'));
this.assertEnumEqual([$('link_2')], $$('a.internal#link_2'));
this.assertEnumEqual([$('item_1')], $$('li#item_1.first'));
this.assertEnumEqual([], $$('li#item_1.nonexistent'));
this.assertEnumEqual([], $$('li#item_1.first.nonexistent'));
},
test$$MatchesAncestryWithTokensSeparatedByWhitespace: function() {
this.assertEnumEqual($('em2', 'em', 'span'), $$('#fixtures a *'));
this.assertEnumEqual([$('p')], $$('div#fixtures p'));
},
test$$CombinesResultsWhenMultipleExpressionsArePassed: function() {
this.assertEnumEqual($('link_1', 'link_2', 'item_1', 'item_2', 'item_3'), $$('#p a', ' ul#list li '));
},
testSelectorWithTagNameAndAttributeExistence: function() {
this.assertEnumEqual($$('#fixtures h1'), $$('h1[class]'), 'h1[class]');
this.assertEnumEqual($$('#fixtures h1'), $$('h1[CLASS]'), 'h1[CLASS]');
this.assertEnumEqual([$('item_3')], $$('li#item_3[class]'), 'li#item_3[class]');
},
testSelectorWithTagNameAndSpecificAttributeValue: function() {
this.assertEnumEqual($('link_1', 'link_2', 'link_3'), $$('a[href="#"]'));
this.assertEnumEqual($('link_1', 'link_2', 'link_3'), $$('a[href=#]'));
},
testSelectorWithTagNameAndWhitespaceTokenizedAttributeValue: function() {
this.assertEnumEqual($('link_1', 'link_2'), $$('a[class~="internal"]'), "a[class~=\"internal\"]");
this.assertEnumEqual($('link_1', 'link_2'), $$('a[class~=internal]'), "a[class~=internal]");
},
testSelectorWithAttributeAndNoTagName: function() {
this.assertEnumEqual($(document.body).select('a[href]'), $(document.body).select('[href]'));
this.assertEnumEqual($$('a[class~="internal"]'), $$('[class~=internal]'));
this.assertEnumEqual($$('*[id]'), $$('[id]'));
this.assertEnumEqual($('checked_radio', 'unchecked_radio'), $$('[type=radio]'));
this.assertEnumEqual($$('*[type=checkbox]'), $$('[type=checkbox]'));
this.assertEnumEqual($('with_title', 'commaParent'), $$('[title]'));
this.assertEnumEqual($$('#troubleForm *[type=radio]'), $$('#troubleForm [type=radio]'));
this.assertEnumEqual($$('#troubleForm *[type]'), $$('#troubleForm [type]'));
},
testSelectorWithUniversalAndHyphenTokenizedAttributeValue: function() {
this.assertEnumEqual([$('item_3')], $$('*[xml:lang|="es"]'));
this.assertEnumEqual([$('item_3')], $$('*[xml:lang|="ES"]'));
},
testSelectorWithTagNameAndNegatedAttributeValue: function() {
this.assertEnumEqual([], $$('a[href!="#"]'));
},
testSelectorWithBracketAttributeValue: function() {
this.assertEnumEqual($('chk_1', 'chk_2'), $$('#troubleForm2 input[name="brackets[5][]"]'));
this.assertEnumEqual([$('chk_1')], $$('#troubleForm2 input[name="brackets[5][]"]:checked'));
this.assertEnumEqual([$('chk_2')], $$('#troubleForm2 input[name="brackets[5][]"][value=2]'));
this.assertEnumEqual([], $$('#troubleForm2 input[name=brackets[5][]]'));
},
test$$WithNestedAttributeSelectors: function() {
this.assertEnumEqual([$('strong')], $$('div[style] p[id] strong'), 'div[style] p[id] strong');
},
testSelectorWithMultipleConditions: function() {
this.assertEnumEqual([$('link_3')], $$('a[class~=external][href="#"]'),
'a[class~=external][href="#"]');
this.assertEnumEqual([], $$('a[class~=external][href!="#"]'),
'a[class~=external][href!="#"]');
},
testSelectorMatchElements: function() {
this.assertElementsMatch(Selector.matchElements($('list').descendants(), 'li'), '#item_1', '#item_2', '#item_3');
this.assertElementsMatch(Selector.matchElements($('fixtures').descendants(), 'a.internal'), '#link_1', '#link_2');
this.assertEnumEqual([], Selector.matchElements($('fixtures').descendants(), 'p.last'));
this.assertElementsMatch(Selector.matchElements($('fixtures').descendants(), '.inexistant, a.internal'), '#link_1', '#link_2');
},
testSelectorFindElement: function() {
this.assertElementMatches(Selector.findElement($('list').descendants(), 'li'), 'li#item_1.first');
this.assertElementMatches(Selector.findElement($('list').descendants(), 'li', 1), 'li#item_2');
this.assertElementMatches(Selector.findElement($('list').descendants(), 'li#item_3'), 'li');
this.assertEqual(undefined, Selector.findElement($('list').descendants(), 'em'));
},
testElementMatch: function() {
var span = $('dupL1');
// tests that should pass
this.assert(span.match('span'));
this.assert(span.match('span#dupL1'));
this.assert(span.match('div > span'), 'child combinator');
this.assert(span.match('#dupContainer span'), 'descendant combinator');
this.assert(span.match('#dupL1'), 'ID only');
this.assert(span.match('span.span_foo'), 'class name 1');
this.assert(span.match('span.span_bar'), 'class name 2');
this.assert(span.match('span:first-child'), 'first-child pseudoclass');
this.assert(!span.match('span.span_wtf'), 'bogus class name');
this.assert(!span.match('#dupL2'), 'different ID');
this.assert(!span.match('div'), 'different tag name');
this.assert(!span.match('span span'), 'different ancestry');
this.assert(!span.match('span > span'), 'different parent');
this.assert(!span.match('span:nth-child(5)'), 'different pseudoclass');
this.assert(!$('link_2').match('a[rel^=external]'));
this.assert($('link_1').match('a[rel^=external]'));
this.assert($('link_1').match('a[rel^="external"]'));
this.assert($('link_1').match("a[rel^='external']"));
this.assert(span.match({ match: function(element) { return true }}), 'custom selector');
this.assert(!span.match({ match: function(element) { return false }}), 'custom selector');
},
testSelectorWithSpaceInAttributeValue: function() {
this.assertEnumEqual([$('with_title')], $$('cite[title="hello world!"]'));
},
// AND NOW COME THOSE NEW TESTS AFTER ANDREW'S REWRITE!
testSelectorWithNamespacedAttributes: function() {
if (Prototype.BrowserFeatures.XPath) {
this.assertUndefined(new Selector('html[xml:lang]').xpath);
this.assertUndefined(new Selector('body p[xml:lang]').xpath);
} else
this.info("Could not test XPath bypass: no XPath to begin with!");
this.assertElementsMatch($$('[xml:lang]'), 'html', '#item_3');
this.assertElementsMatch($$('*[xml:lang]'), 'html', '#item_3');
},
testSelectorWithChild: function() {
this.assertEnumEqual($('link_1', 'link_2'), $$('p.first > a'));
this.assertEnumEqual($('father', 'uncle'), $$('div#grandfather > div'));
this.assertEnumEqual($('level2_1', 'level2_2'), $$('#level1>span'));
this.assertEnumEqual($('level2_1', 'level2_2'), $$('#level1 > span'));
this.assertEnumEqual($('level3_1', 'level3_2'), $$('#level2_1 > *'));
this.assertEnumEqual([], $$('div > #nonexistent'));
$RunBenchmarks && this.wait(500, function() {
this.benchmark(function() { $$('#level1 > span') }, 1000);
});
},
testSelectorWithAdjacence: function() {
this.assertEnumEqual([$('uncle')], $$('div.brothers + div.brothers'));
this.assertEnumEqual([$('uncle')], $$('div.brothers + div'));
this.assertEqual($('level2_2'), $$('#level2_1+span').reduce());
this.assertEqual($('level2_2'), $$('#level2_1 + span').reduce());
this.assertEqual($('level2_2'), $$('#level2_1 + *').reduce());
this.assertEnumEqual([], $$('#level2_2 + span'));
this.assertEqual($('level3_2'), $$('#level3_1 + span').reduce());
this.assertEqual($('level3_2'), $$('#level3_1 + *').reduce());
this.assertEnumEqual([], $$('#level3_2 + *'));
this.assertEnumEqual([], $$('#level3_1 + em'));
$RunBenchmarks && this.wait(500, function() {
this.benchmark(function() { $$('#level3_1 + span') }, 1000);
});
},
testSelectorWithLaterSibling: function() {
this.assertEnumEqual([$('list')], $$('h1 ~ ul'));
this.assertEqual($('level2_2'), $$('#level2_1 ~ span').reduce());
this.assertEnumEqual($('level2_2', 'level2_3'), $$('#level2_1 ~ *').reduce());
this.assertEnumEqual([], $$('#level2_2 ~ span'));
this.assertEnumEqual([], $$('#level3_2 ~ *'));
this.assertEnumEqual([], $$('#level3_1 ~ em'));
this.assertEnumEqual([$('level3_2')], $$('#level3_1 ~ #level3_2'));
this.assertEnumEqual([$('level3_2')], $$('span ~ #level3_2'));
this.assertEnumEqual([], $$('div ~ #level3_2'));
this.assertEnumEqual([], $$('div ~ #level2_3'));
$RunBenchmarks && this.wait(500, function() {
this.benchmark(function() { $$('#level2_1 ~ span') }, 1000);
});
},
testSelectorWithNewAttributeOperators: function() {
this.assertEnumEqual($('father', 'uncle'), $$('div[class^=bro]'), 'matching beginning of string');
this.assertEnumEqual($('father', 'uncle'), $$('div[class$=men]'), 'matching end of string');
this.assertEnumEqual($('father', 'uncle'), $$('div[class*="ers m"]'), 'matching substring')
this.assertEnumEqual($('level2_1', 'level2_2', 'level2_3'), $$('#level1 *[id^="level2_"]'));
this.assertEnumEqual($('level2_1', 'level2_2', 'level2_3'), $$('#level1 *[id^=level2_]'));
this.assertEnumEqual($('level2_1', 'level3_1'), $$('#level1 *[id$="_1"]'));
this.assertEnumEqual($('level2_1', 'level3_1'), $$('#level1 *[id$=_1]'));
this.assertEnumEqual($('level2_1', 'level3_2', 'level2_2', 'level2_3'), $$('#level1 *[id*="2"]'));
this.assertEnumEqual($('level2_1', 'level3_2', 'level2_2', 'level2_3'), $$('#level1 *[id*=2]'));
$RunBenchmarks && this.wait(500, function() {
this.benchmark(function() { $$('#level1 *[id^=level2_]') }, 1000, '[^=]');
this.benchmark(function() { $$('#level1 *[id$=_1]') }, 1000, '[$=]');
this.benchmark(function() { $$('#level1 *[id*=_2]') }, 1000, '[*=]');
});
},
testSelectorWithDuplicates: function() {
this.assertEnumEqual($$('div div'), $$('div div').uniq());
this.assertEnumEqual($('dupL2', 'dupL3', 'dupL4', 'dupL5'), $$('#dupContainer span span'));
$RunBenchmarks && this.wait(500, function() {
this.benchmark(function() { $$('#dupContainer span span') }, 1000);
});
},
testSelectorWithFirstLastOnlyNthNthLastChild: function() {
this.assertEnumEqual([$('level2_1')], $$('#level1>*:first-child'));
this.assertEnumEqual($('level2_1', 'level3_1', 'level_only_child'), $$('#level1 *:first-child'));
this.assertEnumEqual([$('level2_3')], $$('#level1>*:last-child'));
this.assertEnumEqual($('level3_2', 'level_only_child', 'level2_3'), $$('#level1 *:last-child'));
this.assertEnumEqual([$('level2_3')], $$('#level1>div:last-child'));
this.assertEnumEqual([$('level2_3')], $$('#level1 div:last-child'));
this.assertEnumEqual([], $$('#level1>div:first-child'));
this.assertEnumEqual([], $$('#level1>span:last-child'));
this.assertEnumEqual($('level2_1', 'level3_1'), $$('#level1 span:first-child'));
this.assertEnumEqual([], $$('#level1:first-child'));
this.assertEnumEqual([], $$('#level1>*:only-child'));
this.assertEnumEqual([$('level_only_child')], $$('#level1 *:only-child'));
this.assertEnumEqual([], $$('#level1:only-child'));
this.assertEnumEqual([$('link_2')], $$('#p *:nth-last-child(2)'), 'nth-last-child');
this.assertEnumEqual([$('link_2')], $$('#p *:nth-child(3)'), 'nth-child');
this.assertEnumEqual([$('link_2')], $$('#p a:nth-child(3)'), 'nth-child');
this.assertEnumEqual($('item_2', 'item_3'), $$('#list > li:nth-child(n+2)'));
this.assertEnumEqual($('item_1', 'item_2'), $$('#list > li:nth-child(-n+2)'));
$RunBenchmarks && this.wait(500, function() {
this.benchmark(function() { $$('#level1 *:first-child') }, 1000, ':first-child');
this.benchmark(function() { $$('#level1 *:last-child') }, 1000, ':last-child');
this.benchmark(function() { $$('#level1 *:only-child') }, 1000, ':only-child');
});
},
testSelectorWithFirstLastNthNthLastOfType: function() {
this.assertEnumEqual([$('link_2')], $$('#p a:nth-of-type(2)'), 'nth-of-type');
this.assertEnumEqual([$('link_1')], $$('#p a:nth-of-type(1)'), 'nth-of-type');
this.assertEnumEqual([$('link_2')], $$('#p a:nth-last-of-type(1)'), 'nth-last-of-type');
this.assertEnumEqual([$('link_1')], $$('#p a:first-of-type'), 'first-of-type');
this.assertEnumEqual([$('link_2')], $$('#p a:last-of-type'), 'last-of-type');
},
testSelectorWithNot: function() {
this.assertEnumEqual([$('link_2')], $$('#p a:not(a:first-of-type)'), 'first-of-type');
this.assertEnumEqual([$('link_1')], $$('#p a:not(a:last-of-type)'), 'last-of-type');
this.assertEnumEqual([$('link_2')], $$('#p a:not(a:nth-of-type(1))'), 'nth-of-type');
this.assertEnumEqual([$('link_1')], $$('#p a:not(a:nth-last-of-type(1))'), 'nth-last-of-type');
this.assertEnumEqual([$('link_2')], $$('#p a:not([rel~=nofollow])'), 'attribute 1');
this.assertEnumEqual([$('link_2')], $$('#p a:not(a[rel^=external])'), 'attribute 2');
this.assertEnumEqual([$('link_2')], $$('#p a:not(a[rel$=nofollow])'), 'attribute 3');
this.assertEnumEqual([$('em')], $$('#p a:not(a[rel$="nofollow"]) > em'), 'attribute 4')
this.assertEnumEqual([$('item_2')], $$('#list li:not(#item_1):not(#item_3)'), 'adjacent :not clauses');
this.assertEnumEqual([$('son')], $$('#grandfather > div:not(#uncle) #son'));
this.assertEnumEqual([$('em')], $$('#p a:not(a[rel$="nofollow"]) em'), 'attribute 4 + all descendants');
this.assertEnumEqual([$('em')], $$('#p a:not(a[rel$="nofollow"])>em'), 'attribute 4 (without whitespace)');
},
testSelectorWithEnabledDisabledChecked: function() {
this.assertEnumEqual([$('disabled_text_field')], $$('#troubleForm > *:disabled'));
this.assertEnumEqual($('troubleForm').getInputs().without($('disabled_text_field'), $('hidden')), $$('#troubleForm > *:enabled'));
this.assertEnumEqual($('checked_box', 'checked_radio'), $$('#troubleForm *:checked'));
},
testSelectorWithEmpty: function() {
$('level3_1').innerHTML = "";
this.assertEnumEqual($('level3_1', 'level3_2', 'level2_3'),
$$('#level1 *:empty'), '#level1 *:empty');
this.assertEnumEqual([], $$('#level_only_child:empty'), 'newlines count as content!');
},
testIdenticalResultsFromEquivalentSelectors: function() {
this.assertEnumEqual($$('div.brothers'), $$('div[class~=brothers]'));
this.assertEnumEqual($$('div.brothers'), $$('div[class~=brothers].brothers'));
this.assertEnumEqual($$('div:not(.brothers)'), $$('div:not([class~=brothers])'));
this.assertEnumEqual($$('li ~ li'), $$('li:not(:first-child)'));
this.assertEnumEqual($$('ul > li'), $$('ul > li:nth-child(n)'));
this.assertEnumEqual($$('ul > li:nth-child(even)'), $$('ul > li:nth-child(2n)'));
this.assertEnumEqual($$('ul > li:nth-child(odd)'), $$('ul > li:nth-child(2n+1)'));
this.assertEnumEqual($$('ul > li:first-child'), $$('ul > li:nth-child(1)'));
this.assertEnumEqual($$('ul > li:last-child'), $$('ul > li:nth-last-child(1)'));
this.assertEnumEqual($$('ul > li:nth-child(n-999)'), $$('ul > li'));
this.assertEnumEqual($$('ul>li'), $$('ul > li'));
this.assertEnumEqual($$('#p a:not(a[rel$="nofollow"])>em'), $$('#p a:not(a[rel$="nofollow"]) > em'))
},
testSelectorsThatShouldReturnNothing: function() {
this.assertEnumEqual([], $$('span:empty > *'));
this.assertEnumEqual([], $$('div.brothers:not(.brothers)'));
this.assertEnumEqual([], $$('#level2_2 :only-child:not(:last-child)'));
this.assertEnumEqual([], $$('#level2_2 :only-child:not(:first-child)'));
},
testCommasFor$$: function() {
this.assertEnumEqual($('list', 'p', 'link_1', 'item_1', 'item_3', 'troubleForm'), $$('#list, .first,*[xml:lang="es-us"] , #troubleForm'));
this.assertEnumEqual($('list', 'p', 'link_1', 'item_1', 'item_3', 'troubleForm'), $$('#list, .first,', '*[xml:lang="es-us"] , #troubleForm'));
this.assertEnumEqual($('commaParent', 'commaChild'), $$('form[title*="commas,"], input[value="#commaOne,#commaTwo"]'));
this.assertEnumEqual($('commaParent', 'commaChild'), $$('form[title*="commas,"]', 'input[value="#commaOne,#commaTwo"]'));
},
testSelectorExtendsAllNodes: function(){
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');
this.assert(typeof results[0].show == 'function');
this.assert(typeof results[1].show == 'function');
this.assert(typeof results[2].show == 'function');
},
testCountedIsNotAnAttribute: function() {
var el = $('list');
Selector.handlers.mark([el]);
this.assert(!el.innerHTML.include("_counted"));
Selector.handlers.unmark([el]);
this.assert(!el.innerHTML.include("_counted"));
},
testCopiedNodesGetIncluded: function() {
this.assertElementsMatch(
Selector.matchElements($('counted_container').descendants(), 'div'),
'div.is_counted'
);
$('counted_container').innerHTML += $('counted_container').innerHTML;
this.assertElementsMatch(
Selector.matchElements($('counted_container').descendants(), 'div'), 'div.is_counted',
'div.is_counted'
);
},
testElementDown: function() {
var a = $('dupL4');
var b = $('dupContainer').down('#dupL4');
this.assertEqual(a, b);
}
});

View File

@ -1,563 +0,0 @@
<!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" />
</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(){
this.assertIdentical('true', String.interpret(true));
this.assertIdentical('123', String.interpret(123));
this.assertIdentical('foo bar', String.interpret('foo bar'));
this.assertIdentical(
'object string',
String.interpret({ toString: function(){ return 'object string' } }));
this.assertIdentical('0', String.interpret(0));
this.assertIdentical('false', String.interpret(false));
this.assertIdentical('', String.interpret(undefined));
this.assertIdentical('', String.interpret(null));
this.assertIdentical('', String.interpret(''));
},
testGsubWithReplacementFunction: function() {
var source = 'foo boo boz';
this.assertEqual('Foo Boo BoZ',
source.gsub(/[^o]+/, function(match) {
return match[0].toUpperCase()
}));
this.assertEqual('f2 b2 b1z',
source.gsub(/o+/, function(match) {
return match[0].length;
}));
this.assertEqual('f0 b0 b1z',
source.gsub(/o+/, function(match) {
return match[0].length % 2;
}));
},
testGsubWithReplacementString: function() {
var source = 'foo boo boz';
this.assertEqual('foobooboz',
source.gsub(/\s+/, ''));
this.assertEqual(' z',
source.gsub(/(.)(o+)/, ''));
this.assertEqual('ウィメンズ2007<br/>クルーズコレクション',
'ウィメンズ2007\nクルーズコレクション'.gsub(/\n/,'<br/>'));
this.assertEqual('ウィメンズ2007<br/>クルーズコレクション',
'ウィメンズ2007\nクルーズコレクション'.gsub('\n','<br/>'));
},
testGsubWithReplacementTemplateString: function() {
var source = 'foo boo boz';
this.assertEqual('-oo-#{1}- -oo-#{1}- -o-#{1}-z',
source.gsub(/(.)(o+)/, '-#{2}-\\#{1}-'));
this.assertEqual('-foo-f- -boo-b- -bo-b-z',
source.gsub(/(.)(o+)/, '-#{0}-#{1}-'));
this.assertEqual('-oo-f- -oo-b- -o-b-z',
source.gsub(/(.)(o+)/, '-#{2}-#{1}-'));
this.assertEqual(' z',
source.gsub(/(.)(o+)/, '#{3}'));
},
testSubWithReplacementFunction: function() {
var source = 'foo boo boz';
this.assertEqual('Foo boo boz',
source.sub(/[^o]+/, function(match) {
return match[0].toUpperCase()
}), 1);
this.assertEqual('Foo Boo boz',
source.sub(/[^o]+/, function(match) {
return match[0].toUpperCase()
}, 2), 2);
this.assertEqual(source,
source.sub(/[^o]+/, function(match) {
return match[0].toUpperCase()
}, 0), 0);
this.assertEqual(source,
source.sub(/[^o]+/, function(match) {
return match[0].toUpperCase()
}, -1), -1);
},
testSubWithReplacementString: function() {
var source = 'foo boo boz';
this.assertEqual('oo boo boz',
source.sub(/[^o]+/, ''));
this.assertEqual('oooo boz',
source.sub(/[^o]+/, '', 2));
this.assertEqual('-f-oo boo boz',
source.sub(/[^o]+/, '-#{0}-'));
this.assertEqual('-f-oo- b-oo boz',
source.sub(/[^o]+/, '-#{0}-', 2));
},
testScan: function() {
var source = 'foo boo boz', results = [];
var str = source.scan(/[o]+/, function(match) {
results.push(match[0].length);
});
this.assertEnumEqual([2, 2, 1], results);
this.assertEqual(source, source.scan(/x/, this.fail));
this.assert(typeof str == 'string');
},
testToArray: function() {
this.assertEnumEqual([],''.toArray());
this.assertEnumEqual(['a'],'a'.toArray());
this.assertEnumEqual(['a','b'],'ab'.toArray());
this.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() {
this.assertEqual('', ''.camelize());
this.assertEqual('', '-'.camelize());
this.assertEqual('foo', 'foo'.camelize());
this.assertEqual('foo_bar', 'foo_bar'.camelize());
this.assertEqual('FooBar', '-foo-bar'.camelize());
this.assertEqual('FooBar', 'FooBar'.camelize());
this.assertEqual('fooBar', 'foo-bar'.camelize());
this.assertEqual('borderBottomWidth', 'border-bottom-width'.camelize());
this.assertEqual('classNameTest','class-name-test'.camelize());
this.assertEqual('classNameTest','className-test'.camelize());
this.assertEqual('classNameTest','class-nameTest'.camelize());
/* this.benchmark(function(){
'class-name-test'.camelize();
},10000); */
},
testCapitalize: function() {
this.assertEqual('',''.capitalize());
this.assertEqual('Ä','ä'.capitalize());
this.assertEqual('A','A'.capitalize());
this.assertEqual('Hello','hello'.capitalize());
this.assertEqual('Hello','HELLO'.capitalize());
this.assertEqual('Hello','Hello'.capitalize());
this.assertEqual('Hello world','hello WORLD'.capitalize());
},
testUnderscore: function() {
this.assertEqual('', ''.underscore());
this.assertEqual('_', '-'.underscore());
this.assertEqual('foo', 'foo'.underscore());
this.assertEqual('foo', 'Foo'.underscore());
this.assertEqual('foo_bar', 'foo_bar'.underscore());
this.assertEqual('border_bottom', 'borderBottom'.underscore());
this.assertEqual('border_bottom_width', 'borderBottomWidth'.underscore());
this.assertEqual('border_bottom_width', 'border-Bottom-Width'.underscore());
},
testDasherize: function() {
this.assertEqual('', ''.dasherize());
this.assertEqual('foo', 'foo'.dasherize());
this.assertEqual('Foo', 'Foo'.dasherize());
this.assertEqual('foo-bar', 'foo-bar'.dasherize());
this.assertEqual('border-bottom-width', 'border_bottom_width'.dasherize());
},
testTruncate: function() {
var source = 'foo boo boz foo boo boz foo boo boz foo boo boz';
this.assertEqual(source, source.truncate(source.length));
this.assertEqual('foo boo boz foo boo boz foo...', source.truncate(0));
this.assertEqual('fo...', source.truncate(5));
this.assertEqual('foo b', source.truncate(5, ''));
this.assert(typeof 'foo'.truncate(5) == 'string');
this.assert(typeof 'foo bar baz'.truncate(5) == 'string');
},
testStrip: function() {
this.assertEqual('hello world', ' hello world '.strip());
this.assertEqual('hello world', 'hello world'.strip());
this.assertEqual('hello \n world', ' hello \n world '.strip());
this.assertEqual('', ' '.strip());
},
testStripTags: function() {
this.assertEqual('hello world', 'hello world'.stripTags());
this.assertEqual('hello world', 'hello <span>world</span>'.stripTags());
this.assertEqual('hello world', '<a href="#" onclick="moo!">hello</a> world'.stripTags());
this.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());
this.assertEqual('1\n2', '1\n2'.stripTags());
},
testStripScripts: function() {
this.assertEqual('foo bar', 'foo bar'.stripScripts());
this.assertEqual('foo bar', ('foo <script>boo();<'+'/script>bar').stripScripts());
this.assertEqual('foo bar', ('foo <script type="text/javascript">boo();\nmoo();<'+'/script>bar').stripScripts());
},
testExtractScripts: function() {
this.assertEnumEqual([], 'foo bar'.extractScripts());
this.assertEnumEqual(['boo();'], ('foo <script>boo();<'+'/script>bar').extractScripts());
this.assertEnumEqual(['boo();','boo();\nmoo();'],
('foo <script>boo();<'+'/script><script type="text/javascript">boo();\nmoo();<'+'/script>bar').extractScripts());
this.assertEnumEqual(['boo();','boo();\nmoo();'],
('foo <script>boo();<'+'/script>blub\nblub<script type="text/javascript">boo();\nmoo();<'+'/script>bar').extractScripts());
},
testEvalScripts: function() {
this.assertEqual(0, evalScriptsCounter);
('foo <script>evalScriptsCounter++<'+'/script>bar').evalScripts();
this.assertEqual(1, evalScriptsCounter);
var stringWithScripts = '';
(3).times(function(){ stringWithScripts += 'foo <script>evalScriptsCounter++<'+'/script>bar' });
stringWithScripts.evalScripts();
this.assertEqual(4, evalScriptsCounter);
},
testEscapeHTML: function() {
this.assertEqual('foo bar', 'foo bar'.escapeHTML());
this.assertEqual('foo &lt;span&gt;bar&lt;/span&gt;', 'foo <span>bar</span>'.escapeHTML());
this.assertEqual('foo ß bar', 'foo ß bar'.escapeHTML());
this.assertEqual('ウィメンズ2007\nクルーズコレクション',
'ウィメンズ2007\nクルーズコレクション'.escapeHTML());
this.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());
this.assertEqual(largeTextEscaped, largeTextUnescaped.escapeHTML());
this.assertEqual('1\n2', '1\n2'.escapeHTML());
this.benchmark(function() { largeTextUnescaped.escapeHTML() }, 1000);
},
testUnescapeHTML: function() {
this.assertEqual('foo bar', 'foo bar'.unescapeHTML());
this.assertEqual('foo <span>bar</span>', 'foo &lt;span&gt;bar&lt;/span&gt;'.unescapeHTML());
this.assertEqual('foo ß bar', 'foo ß bar'.unescapeHTML());
this.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());
this.assertEqual(largeTextUnescaped, largeTextEscaped.unescapeHTML());
this.assertEqual('1\n2', '1\n2'.unescapeHTML());
this.assertEqual('Pride & Prejudice', '<h1>Pride &amp; Prejudice</h1>'.unescapeHTML());
this.benchmark(function() { largeTextEscaped.unescapeHTML() }, 1000);
},
testTemplateEvaluation: function() {
var source = '<tr><td>#{name}</td><td>#{age}</td></tr>';
var person = {name: 'Sam', age: 21};
var template = new Template(source);
this.assertEqual('<tr><td>Sam</td><td>21</td></tr>',
template.evaluate(person));
this.assertEqual('<tr><td></td><td></td></tr>',
template.evaluate({}));
},
testTemplateEvaluationWithEmptyReplacement: function() {
var template = new Template('##{}');
this.assertEqual('#', template.evaluate({}));
this.assertEqual('#', template.evaluate({foo: 'bar'}));
template = new Template('#{}');
this.assertEqual('', template.evaluate({}));
},
testTemplateEvaluationWithFalses: function() {
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);
this.assertEqual('<tr><td>0</td><td>false</td><td></td><td></td><td></td></tr>',
template.evaluate(falses));
},
testTemplateEvaluationWithNested: function() {
var source = '#{name} #{manager.name} #{manager.age} #{manager.undef} #{manager.age.undef} #{colleagues.first.name}';
var subject = { manager: { name: 'John', age: 29 }, name: 'Stephan', age: 22, colleagues: { first: { name: 'Mark' }} };
this.assertEqual('Stephan', new Template('#{name}').evaluate(subject));
this.assertEqual('John', new Template('#{manager.name}').evaluate(subject));
this.assertEqual('29', new Template('#{manager.age}').evaluate(subject));
this.assertEqual('', new Template('#{manager.undef}').evaluate(subject));
this.assertEqual('', new Template('#{manager.age.undef}').evaluate(subject));
this.assertEqual('Mark', new Template('#{colleagues.first.name}').evaluate(subject));
this.assertEqual('Stephan John 29 Mark', new Template(source).evaluate(subject));
},
testTemplateEvaluationWithIndexing: function() {
var source = '#{0} = #{[0]} - #{1} = #{[1]} - #{[2][0]} - #{[2].name} - #{first[0]} - #{[first][0]} - #{[\\]]} - #{first[\\]]}';
var subject = [ 'zero', 'one', [ 'two-zero' ] ];
subject[2].name = 'two-zero-name';
subject.first = subject[2];
subject[']'] = '\\';
subject.first[']'] = 'first\\';
this.assertEqual('zero', new Template('#{[0]}').evaluate(subject));
this.assertEqual('one', new Template('#{[1]}').evaluate(subject));
this.assertEqual('two-zero', new Template('#{[2][0]}').evaluate(subject));
this.assertEqual('two-zero-name', new Template('#{[2].name}').evaluate(subject));
this.assertEqual('two-zero', new Template('#{first[0]}').evaluate(subject));
this.assertEqual('\\', new Template('#{[\\]]}').evaluate(subject));
this.assertEqual('first\\', new Template('#{first[\\]]}').evaluate(subject));
this.assertEqual('empty - empty2', new Template('#{[]} - #{m[]}').evaluate({ '': 'empty', m: {'': 'empty2'}}));
this.assertEqual('zero = zero - one = one - two-zero - two-zero-name - two-zero - two-zero - \\ - first\\', new Template(source).evaluate(subject));
},
testTemplateToTemplateReplacements: function() {
var source = 'My name is #{name}, my job is #{job}';
var subject = {
name: 'Stephan',
getJob: function() { return 'Web developer'; },
toTemplateReplacements: function() { return { name: this.name, job: this.getJob() } }
};
this.assertEqual('My name is Stephan, my job is Web developer', new Template(source).evaluate(subject));
},
testTemplateEvaluationCombined: function() {
var source = '#{name} is #{age} years old, managed by #{manager.name}, #{manager.age}.\n' +
'Colleagues include #{colleagues[0].name} and #{colleagues[1].name}.';
var subject = {
name: 'Stephan', age: 22,
manager: { name: 'John', age: 29 },
colleagues: [ { name: 'Mark' }, { name: 'Indy' } ]
};
this.assertEqual('Stephan is 22 years old, managed by John, 29.\n' +
'Colleagues include Mark and Indy.',
new Template(source).evaluate(subject));
},
testInterpolate: function() {
var subject = { name: 'Stephan' };
var pattern = /(^|.|\r|\n)(#\((.*?)\))/;
this.assertEqual('#{name}: Stephan', '\\#{name}: #{name}'.interpolate(subject));
this.assertEqual('#(name): Stephan', '\\#(name): #(name)'.interpolate(subject, pattern));
},
testToQueryParams: function() {
// only the query part
var result = {a:undefined, b:'c'};
this.assertHashEqual({}, ''.toQueryParams(), 'empty query');
this.assertHashEqual({}, 'foo?'.toQueryParams(), 'empty query with URL');
this.assertHashEqual(result, 'foo?a&b=c'.toQueryParams(), 'query with URL');
this.assertHashEqual(result, 'foo?a&b=c#fragment'.toQueryParams(), 'query with URL and fragment');
this.assertHashEqual(result, 'a;b=c'.toQueryParams(';'), 'custom delimiter');
this.assertHashEqual({a:undefined}, 'a'.toQueryParams(), 'key without value');
this.assertHashEqual({a:'b'}, 'a=b&=c'.toQueryParams(), 'empty key');
this.assertHashEqual({a:'b', c:''}, 'a=b&c='.toQueryParams(), 'empty value');
this.assertHashEqual({'a b':'c', d:'e f', g:'h'},
'a%20b=c&d=e%20f&g=h'.toQueryParams(), 'proper decoding');
this.assertHashEqual({a:'b=c=d'}, 'a=b=c=d'.toQueryParams(), 'multiple equal signs');
this.assertHashEqual({a:'b', c:'d'}, '&a=b&&&c=d'.toQueryParams(), 'proper splitting');
this.assertEnumEqual($w('r g b'), 'col=r&col=g&col=b'.toQueryParams()['col'],
'collection without square brackets');
var msg = 'empty values inside collection';
this.assertEnumEqual(['r', '', 'b'], 'c=r&c=&c=b'.toQueryParams()['c'], msg);
this.assertEnumEqual(['', 'blue'], 'c=&c=blue'.toQueryParams()['c'], msg);
this.assertEnumEqual(['blue', ''], 'c=blue&c='.toQueryParams()['c'], msg);
},
testInspect: function() {
this.assertEqual('\'\'', ''.inspect());
this.assertEqual('\'test\'', 'test'.inspect());
this.assertEqual('\'test \\\'test\\\' "test"\'', 'test \'test\' "test"'.inspect());
this.assertEqual('\"test \'test\' \\"test\\"\"', 'test \'test\' "test"'.inspect(true));
this.assertEqual('\'\\b\\t\\n\\f\\r"\\\\\'', '\b\t\n\f\r"\\'.inspect());
this.assertEqual('\"\\b\\t\\n\\f\\r\\"\\\\\"', '\b\t\n\f\r"\\'.inspect(true));
this.assertEqual('\'\\b\\t\\n\\f\\r\'', '\x08\x09\x0a\x0c\x0d'.inspect());
this.assertEqual('\'\\u001a\'', '\x1a'.inspect());
},
testInclude: function() {
this.assert('hello world'.include('h'));
this.assert('hello world'.include('hello'));
this.assert('hello world'.include('llo w'));
this.assert('hello world'.include('world'));
this.assert(!'hello world'.include('bye'));
this.assert(!''.include('bye'));
},
testStartsWith: function() {
this.assert('hello world'.startsWith('h'));
this.assert('hello world'.startsWith('hello'));
this.assert(!'hello world'.startsWith('bye'));
this.assert(!''.startsWith('bye'));
this.assert(!'hell'.startsWith('hello'));
},
testEndsWith: function() {
this.assert('hello world'.endsWith('d'));
this.assert('hello world'.endsWith(' world'));
this.assert(!'hello world'.endsWith('planet'));
this.assert(!''.endsWith('planet'));
this.assert('hello world world'.endsWith(' world'));
this.assert(!'z'.endsWith('az'));
},
testBlank: function() {
this.assert(''.blank());
this.assert(' '.blank());
this.assert('\t\r\n '.blank());
this.assert(!'a'.blank());
this.assert(!'\t y \n'.blank());
},
testEmpty: function() {
this.assert(''.empty());
this.assert(!' '.empty());
this.assert(!'\t\r\n '.empty());
this.assert(!'a'.empty());
this.assert(!'\t y \n'.empty());
},
testSucc: function() {
this.assertEqual('b', 'a'.succ());
this.assertEqual('B', 'A'.succ());
this.assertEqual('1', '0'.succ());
this.assertEqual('abce', 'abcd'.succ());
this.assertEqual('{', 'z'.succ());
this.assertEqual(':', '9'.succ());
},
testTimes: function() {
this.assertEqual('', ''.times(0));
this.assertEqual('', ''.times(5));
this.assertEqual('', 'a'.times(-1));
this.assertEqual('', 'a'.times(0));
this.assertEqual('a', 'a'.times(1));
this.assertEqual('aa', 'a'.times(2));
this.assertEqual('aaaaa', 'a'.times(5));
this.assertEqual('foofoofoofoofoo', 'foo'.times(5));
this.assertEqual('', 'foo'.times(-5));
/*window.String.prototype.oldTimes = function(count) {
var result = '';
for (var i = 0; i < count; i++) result += this;
return result;
};
this.benchmark(function() {
'foo'.times(15);
}, 1000, 'new: ');
this.benchmark(function() {
'foo'.oldTimes(15);
}, 1000, 'previous: ');*/
},
testToJSON: function() {
this.assertEqual('\"\"', ''.toJSON());
this.assertEqual('\"test\"', 'test'.toJSON());
},
testIsJSON: function() {
this.assert(!''.isJSON());
this.assert(!' '.isJSON());
this.assert('""'.isJSON());
this.assert('"foo"'.isJSON());
this.assert('{}'.isJSON());
this.assert('[]'.isJSON());
this.assert('null'.isJSON());
this.assert('123'.isJSON());
this.assert('true'.isJSON());
this.assert('false'.isJSON());
this.assert('"\\""'.isJSON());
this.assert(!'\\"'.isJSON());
this.assert(!'new'.isJSON());
this.assert(!'\u0028\u0029'.isJSON());
// we use '@' as a placeholder for characters authorized only inside brackets,
// so this tests make sure it is not considered authorized elsewhere.
this.assert(!'@'.isJSON());
},
testEvalJSON: function() {
var valid = '{"test": \n\r"hello world!"}';
var invalid = '{"test": "hello world!"';
var dangerous = '{});attackTarget = "attack succeeded!";({}';
// use smaller huge string size for KHTML
var size = navigator.userAgent.include('KHTML') ? 20 : 100;
var longString = '"' + '123456789\\"'.times(size * 10) + '"';
var object = '{' + longString + ': ' + longString + '},';
var huge = '[' + object.times(size) + '{"test": 123}]';
this.assertEqual('hello world!', valid.evalJSON().test);
this.assertEqual('hello world!', valid.evalJSON(true).test);
this.assertRaise('SyntaxError', function() { invalid.evalJSON() });
this.assertRaise('SyntaxError', function() { invalid.evalJSON(true) });
attackTarget = "scared";
dangerous.evalJSON();
this.assertEqual("attack succeeded!", attackTarget);
attackTarget = "Not scared!";
this.assertRaise('SyntaxError', function(){dangerous.evalJSON(true)});
this.assertEqual("Not scared!", attackTarget);
this.assertEqual('hello world!', ('/*-secure- \r \n ' + valid + ' \n */').evalJSON().test);
var temp = Prototype.JSONFilter;
Prototype.JSONFilter = /^\/\*([\s\S]*)\*\/$/; // test custom delimiters.
this.assertEqual('hello world!', ('/*' + valid + '*/').evalJSON().test);
Prototype.JSONFilter = temp;
this.assertMatch(123, huge.evalJSON(true).last().test);
this.assertEqual('', '""'.evalJSON());
this.assertEqual('foo', '"foo"'.evalJSON());
this.assert('object', typeof '{}'.evalJSON());
this.assert(Object.isArray('[]'.evalJSON()));
this.assertNull('null'.evalJSON());
this.assert(123, '123'.evalJSON());
this.assertIdentical(true, 'true'.evalJSON());
this.assertIdentical(false, 'false'.evalJSON());
this.assertEqual('"', '"\\""'.evalJSON());
}
});
// ]]>
</script>
</body>
</html>

537
test/unit/string_test.js Normal file
View File

@ -0,0 +1,537 @@
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(){
this.assertIdentical('true', String.interpret(true));
this.assertIdentical('123', String.interpret(123));
this.assertIdentical('foo bar', String.interpret('foo bar'));
this.assertIdentical(
'object string',
String.interpret({ toString: function(){ return 'object string' } }));
this.assertIdentical('0', String.interpret(0));
this.assertIdentical('false', String.interpret(false));
this.assertIdentical('', String.interpret(undefined));
this.assertIdentical('', String.interpret(null));
this.assertIdentical('', String.interpret(''));
},
testGsubWithReplacementFunction: function() {
var source = 'foo boo boz';
this.assertEqual('Foo Boo BoZ',
source.gsub(/[^o]+/, function(match) {
return match[0].toUpperCase()
}));
this.assertEqual('f2 b2 b1z',
source.gsub(/o+/, function(match) {
return match[0].length;
}));
this.assertEqual('f0 b0 b1z',
source.gsub(/o+/, function(match) {
return match[0].length % 2;
}));
},
testGsubWithReplacementString: function() {
var source = 'foo boo boz';
this.assertEqual('foobooboz',
source.gsub(/\s+/, ''));
this.assertEqual(' z',
source.gsub(/(.)(o+)/, ''));
this.assertEqual('ウィメンズ2007<br/>クルーズコレクション',
'ウィメンズ2007\nクルーズコレクション'.gsub(/\n/,'<br/>'));
this.assertEqual('ウィメンズ2007<br/>クルーズコレクション',
'ウィメンズ2007\nクルーズコレクション'.gsub('\n','<br/>'));
},
testGsubWithReplacementTemplateString: function() {
var source = 'foo boo boz';
this.assertEqual('-oo-#{1}- -oo-#{1}- -o-#{1}-z',
source.gsub(/(.)(o+)/, '-#{2}-\\#{1}-'));
this.assertEqual('-foo-f- -boo-b- -bo-b-z',
source.gsub(/(.)(o+)/, '-#{0}-#{1}-'));
this.assertEqual('-oo-f- -oo-b- -o-b-z',
source.gsub(/(.)(o+)/, '-#{2}-#{1}-'));
this.assertEqual(' z',
source.gsub(/(.)(o+)/, '#{3}'));
},
testSubWithReplacementFunction: function() {
var source = 'foo boo boz';
this.assertEqual('Foo boo boz',
source.sub(/[^o]+/, function(match) {
return match[0].toUpperCase()
}), 1);
this.assertEqual('Foo Boo boz',
source.sub(/[^o]+/, function(match) {
return match[0].toUpperCase()
}, 2), 2);
this.assertEqual(source,
source.sub(/[^o]+/, function(match) {
return match[0].toUpperCase()
}, 0), 0);
this.assertEqual(source,
source.sub(/[^o]+/, function(match) {
return match[0].toUpperCase()
}, -1), -1);
},
testSubWithReplacementString: function() {
var source = 'foo boo boz';
this.assertEqual('oo boo boz',
source.sub(/[^o]+/, ''));
this.assertEqual('oooo boz',
source.sub(/[^o]+/, '', 2));
this.assertEqual('-f-oo boo boz',
source.sub(/[^o]+/, '-#{0}-'));
this.assertEqual('-f-oo- b-oo boz',
source.sub(/[^o]+/, '-#{0}-', 2));
},
testScan: function() {
var source = 'foo boo boz', results = [];
var str = source.scan(/[o]+/, function(match) {
results.push(match[0].length);
});
this.assertEnumEqual([2, 2, 1], results);
this.assertEqual(source, source.scan(/x/, this.fail));
this.assert(typeof str == 'string');
},
testToArray: function() {
this.assertEnumEqual([],''.toArray());
this.assertEnumEqual(['a'],'a'.toArray());
this.assertEnumEqual(['a','b'],'ab'.toArray());
this.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() {
this.assertEqual('', ''.camelize());
this.assertEqual('', '-'.camelize());
this.assertEqual('foo', 'foo'.camelize());
this.assertEqual('foo_bar', 'foo_bar'.camelize());
this.assertEqual('FooBar', '-foo-bar'.camelize());
this.assertEqual('FooBar', 'FooBar'.camelize());
this.assertEqual('fooBar', 'foo-bar'.camelize());
this.assertEqual('borderBottomWidth', 'border-bottom-width'.camelize());
this.assertEqual('classNameTest','class-name-test'.camelize());
this.assertEqual('classNameTest','className-test'.camelize());
this.assertEqual('classNameTest','class-nameTest'.camelize());
/* this.benchmark(function(){
'class-name-test'.camelize();
},10000); */
},
testCapitalize: function() {
this.assertEqual('',''.capitalize());
this.assertEqual('Ä','ä'.capitalize());
this.assertEqual('A','A'.capitalize());
this.assertEqual('Hello','hello'.capitalize());
this.assertEqual('Hello','HELLO'.capitalize());
this.assertEqual('Hello','Hello'.capitalize());
this.assertEqual('Hello world','hello WORLD'.capitalize());
},
testUnderscore: function() {
this.assertEqual('', ''.underscore());
this.assertEqual('_', '-'.underscore());
this.assertEqual('foo', 'foo'.underscore());
this.assertEqual('foo', 'Foo'.underscore());
this.assertEqual('foo_bar', 'foo_bar'.underscore());
this.assertEqual('border_bottom', 'borderBottom'.underscore());
this.assertEqual('border_bottom_width', 'borderBottomWidth'.underscore());
this.assertEqual('border_bottom_width', 'border-Bottom-Width'.underscore());
},
testDasherize: function() {
this.assertEqual('', ''.dasherize());
this.assertEqual('foo', 'foo'.dasherize());
this.assertEqual('Foo', 'Foo'.dasherize());
this.assertEqual('foo-bar', 'foo-bar'.dasherize());
this.assertEqual('border-bottom-width', 'border_bottom_width'.dasherize());
},
testTruncate: function() {
var source = 'foo boo boz foo boo boz foo boo boz foo boo boz';
this.assertEqual(source, source.truncate(source.length));
this.assertEqual('foo boo boz foo boo boz foo...', source.truncate(0));
this.assertEqual('fo...', source.truncate(5));
this.assertEqual('foo b', source.truncate(5, ''));
this.assert(typeof 'foo'.truncate(5) == 'string');
this.assert(typeof 'foo bar baz'.truncate(5) == 'string');
},
testStrip: function() {
this.assertEqual('hello world', ' hello world '.strip());
this.assertEqual('hello world', 'hello world'.strip());
this.assertEqual('hello \n world', ' hello \n world '.strip());
this.assertEqual('', ' '.strip());
},
testStripTags: function() {
this.assertEqual('hello world', 'hello world'.stripTags());
this.assertEqual('hello world', 'hello <span>world</span>'.stripTags());
this.assertEqual('hello world', '<a href="#" onclick="moo!">hello</a> world'.stripTags());
this.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());
this.assertEqual('1\n2', '1\n2'.stripTags());
},
testStripScripts: function() {
this.assertEqual('foo bar', 'foo bar'.stripScripts());
this.assertEqual('foo bar', ('foo <script>boo();<'+'/script>bar').stripScripts());
this.assertEqual('foo bar', ('foo <script type="text/javascript">boo();\nmoo();<'+'/script>bar').stripScripts());
},
testExtractScripts: function() {
this.assertEnumEqual([], 'foo bar'.extractScripts());
this.assertEnumEqual(['boo();'], ('foo <script>boo();<'+'/script>bar').extractScripts());
this.assertEnumEqual(['boo();','boo();\nmoo();'],
('foo <script>boo();<'+'/script><script type="text/javascript">boo();\nmoo();<'+'/script>bar').extractScripts());
this.assertEnumEqual(['boo();','boo();\nmoo();'],
('foo <script>boo();<'+'/script>blub\nblub<script type="text/javascript">boo();\nmoo();<'+'/script>bar').extractScripts());
},
testEvalScripts: function() {
this.assertEqual(0, evalScriptsCounter);
('foo <script>evalScriptsCounter++<'+'/script>bar').evalScripts();
this.assertEqual(1, evalScriptsCounter);
var stringWithScripts = '';
(3).times(function(){ stringWithScripts += 'foo <script>evalScriptsCounter++<'+'/script>bar' });
stringWithScripts.evalScripts();
this.assertEqual(4, evalScriptsCounter);
},
testEscapeHTML: function() {
this.assertEqual('foo bar', 'foo bar'.escapeHTML());
this.assertEqual('foo &lt;span&gt;bar&lt;/span&gt;', 'foo <span>bar</span>'.escapeHTML());
this.assertEqual('foo ß bar', 'foo ß bar'.escapeHTML());
this.assertEqual('ウィメンズ2007\nクルーズコレクション',
'ウィメンズ2007\nクルーズコレクション'.escapeHTML());
this.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());
this.assertEqual(largeTextEscaped, largeTextUnescaped.escapeHTML());
this.assertEqual('1\n2', '1\n2'.escapeHTML());
this.benchmark(function() { largeTextUnescaped.escapeHTML() }, 1000);
},
testUnescapeHTML: function() {
this.assertEqual('foo bar', 'foo bar'.unescapeHTML());
this.assertEqual('foo <span>bar</span>', 'foo &lt;span&gt;bar&lt;/span&gt;'.unescapeHTML());
this.assertEqual('foo ß bar', 'foo ß bar'.unescapeHTML());
this.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());
this.assertEqual(largeTextUnescaped, largeTextEscaped.unescapeHTML());
this.assertEqual('1\n2', '1\n2'.unescapeHTML());
this.assertEqual('Pride & Prejudice', '<h1>Pride &amp; Prejudice</h1>'.unescapeHTML());
this.benchmark(function() { largeTextEscaped.unescapeHTML() }, 1000);
},
testTemplateEvaluation: function() {
var source = '<tr><td>#{name}</td><td>#{age}</td></tr>';
var person = {name: 'Sam', age: 21};
var template = new Template(source);
this.assertEqual('<tr><td>Sam</td><td>21</td></tr>',
template.evaluate(person));
this.assertEqual('<tr><td></td><td></td></tr>',
template.evaluate({}));
},
testTemplateEvaluationWithEmptyReplacement: function() {
var template = new Template('##{}');
this.assertEqual('#', template.evaluate({}));
this.assertEqual('#', template.evaluate({foo: 'bar'}));
template = new Template('#{}');
this.assertEqual('', template.evaluate({}));
},
testTemplateEvaluationWithFalses: function() {
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);
this.assertEqual('<tr><td>0</td><td>false</td><td></td><td></td><td></td></tr>',
template.evaluate(falses));
},
testTemplateEvaluationWithNested: function() {
var source = '#{name} #{manager.name} #{manager.age} #{manager.undef} #{manager.age.undef} #{colleagues.first.name}';
var subject = { manager: { name: 'John', age: 29 }, name: 'Stephan', age: 22, colleagues: { first: { name: 'Mark' }} };
this.assertEqual('Stephan', new Template('#{name}').evaluate(subject));
this.assertEqual('John', new Template('#{manager.name}').evaluate(subject));
this.assertEqual('29', new Template('#{manager.age}').evaluate(subject));
this.assertEqual('', new Template('#{manager.undef}').evaluate(subject));
this.assertEqual('', new Template('#{manager.age.undef}').evaluate(subject));
this.assertEqual('Mark', new Template('#{colleagues.first.name}').evaluate(subject));
this.assertEqual('Stephan John 29 Mark', new Template(source).evaluate(subject));
},
testTemplateEvaluationWithIndexing: function() {
var source = '#{0} = #{[0]} - #{1} = #{[1]} - #{[2][0]} - #{[2].name} - #{first[0]} - #{[first][0]} - #{[\\]]} - #{first[\\]]}';
var subject = [ 'zero', 'one', [ 'two-zero' ] ];
subject[2].name = 'two-zero-name';
subject.first = subject[2];
subject[']'] = '\\';
subject.first[']'] = 'first\\';
this.assertEqual('zero', new Template('#{[0]}').evaluate(subject));
this.assertEqual('one', new Template('#{[1]}').evaluate(subject));
this.assertEqual('two-zero', new Template('#{[2][0]}').evaluate(subject));
this.assertEqual('two-zero-name', new Template('#{[2].name}').evaluate(subject));
this.assertEqual('two-zero', new Template('#{first[0]}').evaluate(subject));
this.assertEqual('\\', new Template('#{[\\]]}').evaluate(subject));
this.assertEqual('first\\', new Template('#{first[\\]]}').evaluate(subject));
this.assertEqual('empty - empty2', new Template('#{[]} - #{m[]}').evaluate({ '': 'empty', m: {'': 'empty2'}}));
this.assertEqual('zero = zero - one = one - two-zero - two-zero-name - two-zero - two-zero - \\ - first\\', new Template(source).evaluate(subject));
},
testTemplateToTemplateReplacements: function() {
var source = 'My name is #{name}, my job is #{job}';
var subject = {
name: 'Stephan',
getJob: function() { return 'Web developer'; },
toTemplateReplacements: function() { return { name: this.name, job: this.getJob() } }
};
this.assertEqual('My name is Stephan, my job is Web developer', new Template(source).evaluate(subject));
},
testTemplateEvaluationCombined: function() {
var source = '#{name} is #{age} years old, managed by #{manager.name}, #{manager.age}.\n' +
'Colleagues include #{colleagues[0].name} and #{colleagues[1].name}.';
var subject = {
name: 'Stephan', age: 22,
manager: { name: 'John', age: 29 },
colleagues: [ { name: 'Mark' }, { name: 'Indy' } ]
};
this.assertEqual('Stephan is 22 years old, managed by John, 29.\n' +
'Colleagues include Mark and Indy.',
new Template(source).evaluate(subject));
},
testInterpolate: function() {
var subject = { name: 'Stephan' };
var pattern = /(^|.|\r|\n)(#\((.*?)\))/;
this.assertEqual('#{name}: Stephan', '\\#{name}: #{name}'.interpolate(subject));
this.assertEqual('#(name): Stephan', '\\#(name): #(name)'.interpolate(subject, pattern));
},
testToQueryParams: function() {
// only the query part
var result = {a:undefined, b:'c'};
this.assertHashEqual({}, ''.toQueryParams(), 'empty query');
this.assertHashEqual({}, 'foo?'.toQueryParams(), 'empty query with URL');
this.assertHashEqual(result, 'foo?a&b=c'.toQueryParams(), 'query with URL');
this.assertHashEqual(result, 'foo?a&b=c#fragment'.toQueryParams(), 'query with URL and fragment');
this.assertHashEqual(result, 'a;b=c'.toQueryParams(';'), 'custom delimiter');
this.assertHashEqual({a:undefined}, 'a'.toQueryParams(), 'key without value');
this.assertHashEqual({a:'b'}, 'a=b&=c'.toQueryParams(), 'empty key');
this.assertHashEqual({a:'b', c:''}, 'a=b&c='.toQueryParams(), 'empty value');
this.assertHashEqual({'a b':'c', d:'e f', g:'h'},
'a%20b=c&d=e%20f&g=h'.toQueryParams(), 'proper decoding');
this.assertHashEqual({a:'b=c=d'}, 'a=b=c=d'.toQueryParams(), 'multiple equal signs');
this.assertHashEqual({a:'b', c:'d'}, '&a=b&&&c=d'.toQueryParams(), 'proper splitting');
this.assertEnumEqual($w('r g b'), 'col=r&col=g&col=b'.toQueryParams()['col'],
'collection without square brackets');
var msg = 'empty values inside collection';
this.assertEnumEqual(['r', '', 'b'], 'c=r&c=&c=b'.toQueryParams()['c'], msg);
this.assertEnumEqual(['', 'blue'], 'c=&c=blue'.toQueryParams()['c'], msg);
this.assertEnumEqual(['blue', ''], 'c=blue&c='.toQueryParams()['c'], msg);
},
testInspect: function() {
this.assertEqual('\'\'', ''.inspect());
this.assertEqual('\'test\'', 'test'.inspect());
this.assertEqual('\'test \\\'test\\\' "test"\'', 'test \'test\' "test"'.inspect());
this.assertEqual('\"test \'test\' \\"test\\"\"', 'test \'test\' "test"'.inspect(true));
this.assertEqual('\'\\b\\t\\n\\f\\r"\\\\\'', '\b\t\n\f\r"\\'.inspect());
this.assertEqual('\"\\b\\t\\n\\f\\r\\"\\\\\"', '\b\t\n\f\r"\\'.inspect(true));
this.assertEqual('\'\\b\\t\\n\\f\\r\'', '\x08\x09\x0a\x0c\x0d'.inspect());
this.assertEqual('\'\\u001a\'', '\x1a'.inspect());
},
testInclude: function() {
this.assert('hello world'.include('h'));
this.assert('hello world'.include('hello'));
this.assert('hello world'.include('llo w'));
this.assert('hello world'.include('world'));
this.assert(!'hello world'.include('bye'));
this.assert(!''.include('bye'));
},
testStartsWith: function() {
this.assert('hello world'.startsWith('h'));
this.assert('hello world'.startsWith('hello'));
this.assert(!'hello world'.startsWith('bye'));
this.assert(!''.startsWith('bye'));
this.assert(!'hell'.startsWith('hello'));
},
testEndsWith: function() {
this.assert('hello world'.endsWith('d'));
this.assert('hello world'.endsWith(' world'));
this.assert(!'hello world'.endsWith('planet'));
this.assert(!''.endsWith('planet'));
this.assert('hello world world'.endsWith(' world'));
this.assert(!'z'.endsWith('az'));
},
testBlank: function() {
this.assert(''.blank());
this.assert(' '.blank());
this.assert('\t\r\n '.blank());
this.assert(!'a'.blank());
this.assert(!'\t y \n'.blank());
},
testEmpty: function() {
this.assert(''.empty());
this.assert(!' '.empty());
this.assert(!'\t\r\n '.empty());
this.assert(!'a'.empty());
this.assert(!'\t y \n'.empty());
},
testSucc: function() {
this.assertEqual('b', 'a'.succ());
this.assertEqual('B', 'A'.succ());
this.assertEqual('1', '0'.succ());
this.assertEqual('abce', 'abcd'.succ());
this.assertEqual('{', 'z'.succ());
this.assertEqual(':', '9'.succ());
},
testTimes: function() {
this.assertEqual('', ''.times(0));
this.assertEqual('', ''.times(5));
this.assertEqual('', 'a'.times(-1));
this.assertEqual('', 'a'.times(0));
this.assertEqual('a', 'a'.times(1));
this.assertEqual('aa', 'a'.times(2));
this.assertEqual('aaaaa', 'a'.times(5));
this.assertEqual('foofoofoofoofoo', 'foo'.times(5));
this.assertEqual('', 'foo'.times(-5));
/*window.String.prototype.oldTimes = function(count) {
var result = '';
for (var i = 0; i < count; i++) result += this;
return result;
};
this.benchmark(function() {
'foo'.times(15);
}, 1000, 'new: ');
this.benchmark(function() {
'foo'.oldTimes(15);
}, 1000, 'previous: ');*/
},
testToJSON: function() {
this.assertEqual('\"\"', ''.toJSON());
this.assertEqual('\"test\"', 'test'.toJSON());
},
testIsJSON: function() {
this.assert(!''.isJSON());
this.assert(!' '.isJSON());
this.assert('""'.isJSON());
this.assert('"foo"'.isJSON());
this.assert('{}'.isJSON());
this.assert('[]'.isJSON());
this.assert('null'.isJSON());
this.assert('123'.isJSON());
this.assert('true'.isJSON());
this.assert('false'.isJSON());
this.assert('"\\""'.isJSON());
this.assert(!'\\"'.isJSON());
this.assert(!'new'.isJSON());
this.assert(!'\u0028\u0029'.isJSON());
// we use '@' as a placeholder for characters authorized only inside brackets,
// so this tests make sure it is not considered authorized elsewhere.
this.assert(!'@'.isJSON());
},
testEvalJSON: function() {
var valid = '{"test": \n\r"hello world!"}';
var invalid = '{"test": "hello world!"';
var dangerous = '{});attackTarget = "attack succeeded!";({}';
// use smaller huge string size for KHTML
var size = navigator.userAgent.include('KHTML') ? 20 : 100;
var longString = '"' + '123456789\\"'.times(size * 10) + '"';
var object = '{' + longString + ': ' + longString + '},';
var huge = '[' + object.times(size) + '{"test": 123}]';
this.assertEqual('hello world!', valid.evalJSON().test);
this.assertEqual('hello world!', valid.evalJSON(true).test);
this.assertRaise('SyntaxError', function() { invalid.evalJSON() });
this.assertRaise('SyntaxError', function() { invalid.evalJSON(true) });
attackTarget = "scared";
dangerous.evalJSON();
this.assertEqual("attack succeeded!", attackTarget);
attackTarget = "Not scared!";
this.assertRaise('SyntaxError', function(){dangerous.evalJSON(true)});
this.assertEqual("Not scared!", attackTarget);
this.assertEqual('hello world!', ('/*-secure- \r \n ' + valid + ' \n */').evalJSON().test);
var temp = Prototype.JSONFilter;
Prototype.JSONFilter = /^\/\*([\s\S]*)\*\/$/; // test custom delimiters.
this.assertEqual('hello world!', ('/*' + valid + '*/').evalJSON().test);
Prototype.JSONFilter = temp;
this.assertMatch(123, huge.evalJSON(true).last().test);
this.assertEqual('', '""'.evalJSON());
this.assertEqual('foo', '"foo"'.evalJSON());
this.assert('object', typeof '{}'.evalJSON());
this.assert(Object.isArray('[]'.evalJSON()));
this.assertNull('null'.evalJSON());
this.assert(123, '123'.evalJSON());
this.assertIdentical(true, 'true'.evalJSON());
this.assertIdentical(false, 'false'.evalJSON());
this.assertEqual('"', '"\\""'.evalJSON());
}
});

View File

@ -1,193 +0,0 @@
<!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" />
</head>
<body>
<h1>Prototype Unit test file</h1>
<p>
Test the unit testing library (unittest.js)
</p>
<!-- Log output -->
<div id="testlog"> </div>
<div id="testlog_2"> </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({
testIsRunningFromRake: function() {
if (window.location.toString().startsWith('http')) {
this.assert(this.isRunningFromRake);
this.info('These tests are running from rake.')
} else {
this.assert(!this.isRunningFromRake);
this.info('These tests are *not* running from rake.')
}
},
testBuildMessage: function() {
this.assertEqual("'foo' 'bar'", this.buildMessage('', '? ?', 'foo', 'bar'))
},
testAssertEqual: function() {
this.assertEqual(0, 0);
this.assertEqual(0, 0, "test");
this.assertEqual(0,'0');
this.assertEqual(65.0, 65);
this.assertEqual("a", "a");
this.assertEqual("a", "a", "test");
this.assertNotEqual(0, 1);
this.assertNotEqual("a","b");
this.assertNotEqual({},{});
this.assertNotEqual([],[]);
this.assertNotEqual([],{});
},
testAssertEnumEqual: function() {
this.assertEnumEqual([], []);
this.assertEnumEqual(['a', 'b'], ['a', 'b']);
this.assertEnumEqual(['1', '2'], [1, 2]);
this.assertEnumNotEqual(['1', '2'], [1, 2, 3]);
},
testAssertHashEqual: function() {
this.assertHashEqual({}, {});
this.assertHashEqual({a:'b'}, {a:'b'});
this.assertHashEqual({a:'b', c:'d'}, {c:'d', a:'b'});
this.assertHashNotEqual({a:'b', c:'d'}, {c:'d', a:'boo!'});
},
testAssertRespondsTo: function() {
this.assertRespondsTo('isNice', testObj);
this.assertRespondsTo('isBroken', testObj);
},
testAssertIdentical: function() {
this.assertIdentical(0, 0);
this.assertIdentical(0, 0, "test");
this.assertIdentical(1, 1);
this.assertIdentical('a', 'a');
this.assertIdentical('a', 'a', "test");
this.assertIdentical('', '');
this.assertIdentical(undefined, undefined);
this.assertIdentical(null, null);
this.assertIdentical(true, true);
this.assertIdentical(false, false);
var obj = {a:'b'};
this.assertIdentical(obj, obj);
this.assertNotIdentical({1:2,3:4},{1:2,3:4});
this.assertIdentical(1, 1.0); // both are typeof == 'number'
this.assertNotIdentical(1, '1');
this.assertNotIdentical(1, '1.0');
},
testAssertNullAndAssertUndefined: function() {
this.assertNull(null);
this.assertNotNull(undefined);
this.assertNotNull(0);
this.assertNotNull('');
this.assertNotUndefined(null);
this.assertUndefined(undefined);
this.assertNotUndefined(0);
this.assertNotUndefined('');
this.assertNullOrUndefined(null);
this.assertNullOrUndefined(undefined);
this.assertNotNullOrUndefined(0);
this.assertNotNullOrUndefined('');
},
testAssertMatch: function() {
this.assertMatch(/knowmad.jpg$/, 'http://script.aculo.us/images/knowmad.jpg');
this.assertMatch(/Fuc/, 'Thomas Fuchs');
this.assertMatch(/^\$(\d{1,3}(\,\d{3})*|(\d+))(\.\d{2})?$/, '$19.95');
this.assertMatch(/(\d{3}\) ?)|(\d{3}[- \.])?\d{3}[- \.]\d{4}(\s(x\d+)?){0,1}$/, '704-343-9330');
this.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');
this.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');
this.assertNoMatch(/zubar/, 'foo bar');
},
testAssertInstanceOf: function() {
this.assertInstanceOf(String, new String);
this.assertInstanceOf(RegExp, /foo/);
this.assertNotInstanceOf(String, {});
},
testAssertVisible: function() {
this.assertVisible('testcss1');
this.assertNotVisible('testcss1_span');
//this.assertNotVisible('testcss2', "Due to a Safari bug, this test fails in Safari.");
Element.hide('testcss1');
this.assertNotVisible('testcss1');
this.assertNotVisible('testcss1_span');
Element.show('testcss1');
this.assertVisible('testcss1');
this.assertNotVisible('testcss1_span');
Element.show('testcss1_span');
this.assertVisible('testcss1_span');
Element.hide('testcss1');
this.assertNotVisible('testcss1_span'); // hidden by parent
},
testAssertElementsMatch: function() {
this.assertElementsMatch($$('#tlist'), '#tlist');
this.assertElementMatches($('tlist'), '#tlist');
}
});
new Test.Unit.Runner({
testDummy: function() {
this.assert(true);
},
testMultipleTestRunner: function() {
this.assertEqual('passed', $('testlog_2').down('td', 1).innerHTML);
}
}, {testLog: 'testlog_2'});
// ]]>
</script>
</body>
</html>

148
test/unit/unittest_test.js Normal file
View File

@ -0,0 +1,148 @@
var testObj = {
isNice: function() {
return true;
},
isBroken: function() {
return false;
}
}
new Test.Unit.Runner({
testIsRunningFromRake: function() {
if (window.location.toString().startsWith('http')) {
this.assert(this.isRunningFromRake);
this.info('These tests are running from rake.')
} else {
this.assert(!this.isRunningFromRake);
this.info('These tests are *not* running from rake.')
}
},
testBuildMessage: function() {
this.assertEqual("'foo' 'bar'", this.buildMessage('', '? ?', 'foo', 'bar'))
},
testAssertEqual: function() {
this.assertEqual(0, 0);
this.assertEqual(0, 0, "test");
this.assertEqual(0,'0');
this.assertEqual(65.0, 65);
this.assertEqual("a", "a");
this.assertEqual("a", "a", "test");
this.assertNotEqual(0, 1);
this.assertNotEqual("a","b");
this.assertNotEqual({},{});
this.assertNotEqual([],[]);
this.assertNotEqual([],{});
},
testAssertEnumEqual: function() {
this.assertEnumEqual([], []);
this.assertEnumEqual(['a', 'b'], ['a', 'b']);
this.assertEnumEqual(['1', '2'], [1, 2]);
this.assertEnumNotEqual(['1', '2'], [1, 2, 3]);
},
testAssertHashEqual: function() {
this.assertHashEqual({}, {});
this.assertHashEqual({a:'b'}, {a:'b'});
this.assertHashEqual({a:'b', c:'d'}, {c:'d', a:'b'});
this.assertHashNotEqual({a:'b', c:'d'}, {c:'d', a:'boo!'});
},
testAssertRespondsTo: function() {
this.assertRespondsTo('isNice', testObj);
this.assertRespondsTo('isBroken', testObj);
},
testAssertIdentical: function() {
this.assertIdentical(0, 0);
this.assertIdentical(0, 0, "test");
this.assertIdentical(1, 1);
this.assertIdentical('a', 'a');
this.assertIdentical('a', 'a', "test");
this.assertIdentical('', '');
this.assertIdentical(undefined, undefined);
this.assertIdentical(null, null);
this.assertIdentical(true, true);
this.assertIdentical(false, false);
var obj = {a:'b'};
this.assertIdentical(obj, obj);
this.assertNotIdentical({1:2,3:4},{1:2,3:4});
this.assertIdentical(1, 1.0); // both are typeof == 'number'
this.assertNotIdentical(1, '1');
this.assertNotIdentical(1, '1.0');
},
testAssertNullAndAssertUndefined: function() {
this.assertNull(null);
this.assertNotNull(undefined);
this.assertNotNull(0);
this.assertNotNull('');
this.assertNotUndefined(null);
this.assertUndefined(undefined);
this.assertNotUndefined(0);
this.assertNotUndefined('');
this.assertNullOrUndefined(null);
this.assertNullOrUndefined(undefined);
this.assertNotNullOrUndefined(0);
this.assertNotNullOrUndefined('');
},
testAssertMatch: function() {
this.assertMatch(/knowmad.jpg$/, 'http://script.aculo.us/images/knowmad.jpg');
this.assertMatch(/Fuc/, 'Thomas Fuchs');
this.assertMatch(/^\$(\d{1,3}(\,\d{3})*|(\d+))(\.\d{2})?$/, '$19.95');
this.assertMatch(/(\d{3}\) ?)|(\d{3}[- \.])?\d{3}[- \.]\d{4}(\s(x\d+)?){0,1}$/, '704-343-9330');
this.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');
this.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');
this.assertNoMatch(/zubar/, 'foo bar');
},
testAssertInstanceOf: function() {
this.assertInstanceOf(String, new String);
this.assertInstanceOf(RegExp, /foo/);
this.assertNotInstanceOf(String, {});
},
testAssertVisible: function() {
this.assertVisible('testcss1');
this.assertNotVisible('testcss1_span');
//this.assertNotVisible('testcss2', "Due to a Safari bug, this test fails in Safari.");
Element.hide('testcss1');
this.assertNotVisible('testcss1');
this.assertNotVisible('testcss1_span');
Element.show('testcss1');
this.assertVisible('testcss1');
this.assertNotVisible('testcss1_span');
Element.show('testcss1_span');
this.assertVisible('testcss1_span');
Element.hide('testcss1');
this.assertNotVisible('testcss1_span'); // hidden by parent
},
testAssertElementsMatch: function() {
this.assertElementsMatch($$('#tlist'), '#tlist');
this.assertElementMatches($('tlist'), '#tlist');
}
});
new Test.Unit.Runner({
testDummy: function() {
this.assert(true);
},
testMultipleTestRunner: function() {
this.assertEqual('passed', $('testlog_2').down('td', 1).innerHTML);
}
}, {testLog: 'testlog_2'});