Skip to content
Browse files

refactored unit tests quite a bit. Added JS and CSS fixtures.

  • Loading branch information...
1 parent 81de0e3 commit cf5d18097e5883d9b5d2f9490466c42036f6bb32 @tobie tobie committed Apr 23, 2008
View
25 Rakefile
@@ -9,7 +9,7 @@ PROTOTYPE_VERSION = '1.6.0.2'
task :default => [:dist, :dist_helper, :package, :clean_package_source]
-desc "Builds the distribution"
+desc "Builds the distribution."
task :dist do
$:.unshift File.join(PROTOTYPE_ROOT, 'lib')
require 'protodoc'
@@ -21,7 +21,7 @@ task :dist do
end
end
-desc "Builds the updating helper"
+desc "Builds the updating helper."
task :dist_helper do
$:.unshift File.join(PROTOTYPE_ROOT, 'lib')
require 'protodoc'
@@ -45,8 +45,8 @@ Rake::PackageTask.new('prototype', PROTOTYPE_VERSION) do |package|
)
end
-desc "Builds the distribution, runs the JavaScript unit tests and collects their results."
-task :test => [:build_tests, :dist, :test_units]
+desc "Builds the distribution and the test suite, runs the tests and collects their results."
+task :test => [:dist, :test_units]
require 'test/lib/jstest'
desc "Runs all the JavaScript unit tests and collects the results"
@@ -58,19 +58,16 @@ JavaScriptTestTask.new(:test_units) do |t|
t.mount("/dist")
t.mount("/test")
- Dir["test/unit/tmp/*_test.html"].sort.each do |test_file|
- tests = testcases ? { :url => "/#{test_file}", :testcases => testcases } : "/#{test_file}"
- test_filename = test_file[/.*\/(.+?)_test\.html/, 1]
- t.run(tests) unless tests_to_run && !tests_to_run.include?(test_filename)
+ Dir["test/unit/*_test.js"].each do |file|
+ TestBuilder.new(file).render
+ test_file = File.basename(file, ".js")
+ test_name = test_file.sub("_test", "")
+ unless tests_to_run && !tests_to_run.include?(test_name)
+ t.run("/test/unit/tmp/#{test_file}.html", testcases)
+ end
end
%w( safari firefox ie konqueror opera ).each do |browser|
t.browser(browser.to_sym) unless browsers_to_test && !browsers_to_test.include?(browser)
end
end
-
-task :build_tests do
- Dir["test/unit/*_test.js"].each do |test_file|
- TestBuilder.new(test_file).render
- end
-end
View
155 test/lib/jstest.rb
@@ -278,12 +278,7 @@ def initialize(name=:test)
@server = WEBrick::HTTPServer.new(:Port => 4711) # TODO: make port configurable
@server.mount_proc("/results") do |req, res|
- @queue.push({
- :tests => req.query['tests'].to_i,
- :assertions => req.query['assertions'].to_i,
- :failures => req.query['failures'].to_i,
- :errors => req.query['errors'].to_i
- })
+ @queue.push(req)
res.body = "OK"
end
@server.mount("/response", BasicServlet)
@@ -303,62 +298,49 @@ def define
@browsers.each do |browser|
if browser.supported?
t0 = Time.now
- results = {:tests => 0, :assertions => 0, :failures => 0, :errors => 0}
- errors = []
- failures = []
+ test_suite_results = TestSuiteResults.new
+
browser.setup
- puts "\nStarted tests in #{browser}"
+ puts "\nStarted tests in #{browser}."
+
@tests.each do |test|
- params = "resultsURL=http://localhost:4711/results&t=" + ("%.6f" % Time.now.to_f)
- if test.is_a?(Hash)
- params << "&tests=#{test[:testcases]}" if test[:testcases]
- test = test[:url]
- end
- browser.visit("http://localhost:4711#{test}?#{params}")
-
- result = @queue.pop
- result.each { |k, v| results[k] += v }
- value = "."
-
- if result[:failures] > 0
- value = "F"
- failures.push(test)
- end
-
- if result[:errors] > 0
- value = "E"
- errors.push(test)
- end
-
- print value
+ browser.visit(get_url(test))
+ results = TestResults.new(@queue.pop.query)
+ print results
+ test_suite_results.add(results, test[:url])
end
- puts "\nFinished in #{(Time.now - t0).round.to_s} seconds."
- puts " Failures: #{failures.join(', ')}" unless failures.empty?
- puts " Errors: #{errors.join(', ')}" unless errors.empty?
- puts "#{results[:tests]} tests, #{results[:assertions]} assertions, #{results[:failures]} failures, #{results[:errors]} errors"
+ print "\nFinished in #{Time.now - t0} seconds."
+ print test_suite_results
browser.teardown
else
- puts "\nSkipping #{browser}, not supported on this OS"
+ puts "\nSkipping #{browser}, not supported on this OS."
end
end
@server.shutdown
t.join
end
end
-
+
+ def get_url(test)
+ params = "resultsURL=http://localhost:4711/results&t=" + ("%.6f" % Time.now.to_f)
+ params << "&tests=#{test[:testcases]}" unless test[:testcases] == :all
+ "http://localhost:4711#{test[:url]}?#{params}"
+ end
+
def mount(path, dir=nil)
dir = Dir.pwd + path unless dir
# don't cache anything in our tests
@server.mount(path, NonCachingFileHandler, dir)
end
- # test should be specified as a url or as a hash of the form
- # {:url => "url", :testcases => "testFoo,testBar"}
- def run(test)
- @tests<<test
+ # test should be specified as a hash of the form
+ # {:url => "url", :testcases => "testFoo,testBar"}.
+ # specifying :testcases is optional
+ def run(url, testcases = :all)
+ @tests << { :url => url, :testcases => testcases }
end
def browser(browser)
@@ -382,37 +364,104 @@ def browser(browser)
end
end
+class TestResults
+ attr_reader :tests, :assertions, :failures, :errors
+ def initialize(query)
+ @tests = query['tests'].to_i
+ @assertions = query['assertions'].to_i
+ @failures = query['failures'].to_i
+ @errors = query['errors'].to_i
+ end
+
+ def error?
+ @errors > 0
+ end
+
+ def failure?
+ @failures > 0
+ end
+
+ def to_s
+ return "E" if error?
+ return "F" if failure?
+ "."
+ end
+end
+
+class TestSuiteResults
+ def initialize
+ @tests = 0
+ @assertions = 0
+ @failures = 0
+ @errors = 0
+ @error_files = []
+ @failure_files = []
+ end
+
+ def add(result, file)
+ @tests += result.tests
+ @assertions += result.assertions
+ @failures += result.failures
+ @errors += result.errors
+ @error_files.push(file) if result.error?
+ @failure_files.push(file) if result.failure?
+ end
+
+ def error?
+ @errors > 0
+ end
+
+ def failure?
+ @failures > 0
+ end
+
+ def to_s
+ str = ""
+ str << "\n Failures: #{@failure_files.join(', ')}" if failure?
+ str << "\n Errors: #{@error_files.join(', ')}" if error?
+ "#{str}\n#{summary}\n\n"
+ end
+
+ def summary
+ "#{@tests} tests, #{@assertions} assertions, #{@failures} failures, #{@errors} errors."
+ 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
+ @html_fixtures = html_fixtures
+ @js_fixtures_filename = external_fixtures("js")
+ @css_fixtures_filename = external_fixtures("css")
end
- def find_fixtures
- @fixtures = ""
- file = File.join(FIXTURES_DIR, @fixtures_filename)
- if File.exists?(file)
- File.open(file).each { |line| @fixtures << line }
- end
+ def html_fixtures
+ content = ""
+ file = File.join(FIXTURES_DIR, "#{@basename}.html")
+ File.open(file).each { |l| content << l } if File.exists?(file)
+ content
+ end
+
+ def external_fixtures(type)
+ filename = "#{@basename}.#{type}"
+ File.exists?(File.join(FIXTURES_DIR, filename)) ? filename : nil
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")
+ filename = File.basename(@filename, ".js")
+ File.join(UNITTEST_DIR, 'unit', 'tmp', "#{filename}.html")
end
end
View
23 test/lib/template.erb
@@ -6,26 +6,35 @@
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script type="text/javascript" charset="utf-8">
var eventResults = {};
- var originalElement = Element;
+ var originalElement = window.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" />
+
+ <% if @css_fixtures_filename %>
+ <link rel="stylesheet" href="../fixtures/<%= @css_fixtures_filename %>" type="text/css" charset="utf-8" />
+ <% end %>
+
+ <% if @js_fixtures_filename %>
+ <script src="../fixtures/<%= @js_fixtures_filename %>" type="text/javascript" charset="utf-8"></script>
+ <% end %>
+
+ <script src="../<%= @js_filename %>" type="text/javascript"></script>
</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 -->
+<!-- Log output start -->
<div id="testlog"></div>
+<!-- Log output end -->
-<!-- Fixtures start -->
-<%= @fixtures %>
-<!-- Fixtures end -->
+<!-- HTML Fixtures start -->
+<%= @html_fixtures %>
+<!-- HTML Fixtures end -->
</body>
</html>
<script type="text/javascript" charset="utf-8">
View
43 test/unit/ajax_test.js
@@ -1,38 +1,3 @@
-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,
@@ -41,14 +6,6 @@ var extendDefault = function(options) {
}, 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('');
View
1,008 test/unit/base_test.js
@@ -1,603 +1,495 @@
-var Person = function(name){
- this.name = name;
- };
-
- Person.prototype.toJSON = function() {
- return '-' + this.name;
- };
-
- var arg1 = 1;
- var arg2 = 2;
- var arg3 = 3;
- function TestObj() { };
- TestObj.prototype.assertingEventHandler =
- function(event, assertEvent, assert1, assert2, assert3, a1, a2, a3) {
- assertEvent(event);
- assert1(a1);
- assert2(a2);
- assert3(a3);
- };
+new Test.Unit.Runner({
+ testFunctionArgumentNames: function() {
+ this.assertEnumEqual([], (function() {}).argumentNames());
+ this.assertEnumEqual(["one"], (function(one) {}).argumentNames());
+ this.assertEnumEqual(["one", "two", "three"], (function(one, two, three) {}).argumentNames());
+ this.assertEqual("$super", (function($super) {}).argumentNames().first());
- var globalBindTest = null;
-
+ function named1() {};
+ this.assertEnumEqual([], named1.argumentNames());
+ function named2(one) {};
+ this.assertEnumEqual(["one"], named2.argumentNames());
+ function named3(one, two, three) {};
+ this.assertEnumEqual(["one", "two", "three"], named3.argumentNames());
+ },
- // base class
- var Animal = Class.create({
- initialize: function(name) {
- this.name = name;
- },
- name: "",
- eat: function() {
- return this.say("Yum!");
- },
- say: function(message) {
- return this.name + ": " + message;
- }
- });
+ testFunctionBind: function() {
+ function methodWithoutArguments() { return this.hi };
+ function methodWithArguments() { return this.hi + ',' + $A(arguments).join(',') };
+ var func = Prototype.emptyFunction;
- // subclass that augments a method
- var Cat = Class.create(Animal, {
- eat: function($super, food) {
- if (food instanceof Mouse) return $super();
- else return this.say("Yuk! I only eat mice.");
- }
- });
+ this.assertIdentical(func, func.bind());
+ this.assertIdentical(func, func.bind(undefined));
+ this.assertNotIdentical(func, func.bind(null));
- // empty subclass
- var Mouse = Class.create(Animal, {});
+ this.assertEqual('without', methodWithoutArguments.bind({ hi: 'without' })());
+ this.assertEqual('with,arg1,arg2', methodWithArguments.bind({ hi: 'with' })('arg1','arg2'));
+ this.assertEqual('withBindArgs,arg1,arg2',
+ methodWithArguments.bind({ hi: 'withBindArgs' }, 'arg1', 'arg2')());
+ this.assertEqual('withBindArgsAndArgs,arg1,arg2,arg3,arg4',
+ methodWithArguments.bind({ hi: 'withBindArgsAndArgs' }, 'arg1', 'arg2')('arg3', 'arg4'));
+ },
- //mixins
- var Sellable = {
- getValue: function(pricePerKilo) {
- return this.weight * pricePerKilo;
- },
-
- inspect: function() {
- return '#<Sellable: #{weight}kg>'.interpolate(this);
- }
- };
-
- var Reproduceable = {
- reproduce: function(partner) {
- if (partner.constructor != this.constructor || partner.sex == this.sex)
- return null;
- var weight = this.weight / 10, sex = Math.random(1).round() ? 'male' : 'female';
- return new this.constructor('baby', weight, sex);
- }
- };
-
- // base class with mixin
- var Plant = Class.create(Sellable, {
- initialize: function(name, weight) {
- this.name = name;
- this.weight = weight;
- },
-
- inspect: function() {
- return '#<Plant: #{name}>'.interpolate(this);
- }
- });
+ testFunctionCurry: function() {
+ var split = function(delimiter, string) { return string.split(delimiter); };
+ var splitOnColons = split.curry(":");
+ this.assertNotIdentical(split, splitOnColons);
+ this.assertEnumEqual(split(":", "0:1:2:3:4:5"), splitOnColons("0:1:2:3:4:5"));
+ this.assertIdentical(split, split.curry());
+ },
- // subclass with mixin
- var Dog = Class.create(Animal, Reproduceable, {
- initialize: function($super, name, weight, sex) {
- this.weight = weight;
- this.sex = sex;
- $super(name);
- }
- });
+ testFunctionDelay: function() {
+ window.delayed = undefined;
+ var delayedFunction = function() { window.delayed = true; };
+ var delayedFunctionWithArgs = function() { window.delayedWithArgs = $A(arguments).join(' '); };
+ delayedFunction.delay(0.8);
+ delayedFunctionWithArgs.delay(0.8, 'hello', 'world');
+ this.assertUndefined(window.delayed);
+ this.wait(1000, function() {
+ this.assert(window.delayed);
+ this.assertEqual('hello world', window.delayedWithArgs);
+ });
+ },
- // subclass with mixins
- var Ox = Class.create(Animal, Sellable, Reproduceable, {
- initialize: function($super, name, weight, sex) {
- this.weight = weight;
- this.sex = sex;
- $super(name);
- },
+ testFunctionWrap: function() {
+ function sayHello(){
+ return 'hello world';
+ };
- eat: function(food) {
- if (food instanceof Plant)
- this.weight += food.weight;
- },
+ this.assertEqual('HELLO WORLD', sayHello.wrap(function(proceed) {
+ return proceed().toUpperCase();
+ })());
- inspect: function() {
- return '#<Ox: #{name}>'.interpolate(this);
- }
- });
+ var temp = String.prototype.capitalize;
+ String.prototype.capitalize = String.prototype.capitalize.wrap(function(proceed, eachWord) {
+ if(eachWord && this.include(' ')) return this.split(' ').map(function(str){
+ return str.capitalize();
+ }).join(' ');
+ return proceed();
+ });
+ this.assertEqual('Hello world', 'hello world'.capitalize());
+ this.assertEqual('Hello World', 'hello world'.capitalize(true));
+ this.assertEqual('Hello', 'hello'.capitalize());
+ String.prototype.capitalize = temp;
+ },
- new Test.Unit.Runner({
-
- testFunctionArgumentNames: function() {
- this.assertEnumEqual([], (function() {}).argumentNames());
- this.assertEnumEqual(["one"], (function(one) {}).argumentNames());
- this.assertEnumEqual(["one", "two", "three"], (function(one, two, three) {}).argumentNames());
- this.assertEqual("$super", (function($super) {}).argumentNames().first());
+ testFunctionDefer: function() {
+ window.deferred = undefined;
+ var deferredFunction = function() { window.deferred = true; };
+ deferredFunction.defer();
+ this.assertUndefined(window.deferred);
+ this.wait(50, function() {
+ this.assert(window.deferred);
- function named1() {};
- this.assertEnumEqual([], named1.argumentNames());
- function named2(one) {};
- this.assertEnumEqual(["one"], named2.argumentNames());
- function named3(one, two, three) {};
- this.assertEnumEqual(["one", "two", "three"], named3.argumentNames());
- },
+ window.deferredValue = 0;
+ var deferredFunction2 = function(arg) { window.deferredValue = arg; };
+ deferredFunction2.defer('test');
+ this.wait(50, function() {
+ this.assertEqual('test', window.deferredValue);
+ });
+ });
+ },
+
+ testFunctionMethodize: function() {
+ var Foo = { bar: function(baz) { return baz } };
+ var baz = { quux: Foo.bar.methodize() };
- testFunctionBind: function() {
- function methodWithoutArguments() { return this.hi };
- function methodWithArguments() { return this.hi + ',' + $A(arguments).join(',') };
- var func = Prototype.emptyFunction;
+ this.assertEqual(Foo.bar.methodize(), baz.quux);
+ this.assertEqual(baz, Foo.bar(baz));
+ this.assertEqual(baz, baz.quux());
+ },
- this.assertIdentical(func, func.bind());
- this.assertIdentical(func, func.bind(undefined));
- this.assertNotIdentical(func, func.bind(null));
+ testObjectExtend: function() {
+ var object = {foo: 'foo', bar: [1, 2, 3]};
+ this.assertIdentical(object, Object.extend(object));
+ this.assertHashEqual({foo: 'foo', bar: [1, 2, 3]}, object);
+ this.assertIdentical(object, Object.extend(object, {bla: 123}));
+ this.assertHashEqual({foo: 'foo', bar: [1, 2, 3], bla: 123}, object);
+ this.assertHashEqual({foo: 'foo', bar: [1, 2, 3], bla: null},
+ Object.extend(object, {bla: null}));
+ },
+
+ testObjectToQueryString: function() {
+ this.assertEqual('a=A&b=B&c=C&d=D%23', Object.toQueryString({a: 'A', b: 'B', c: 'C', d: 'D#'}));
+ },
+
+ testObjectClone: function() {
+ var object = {foo: 'foo', bar: [1, 2, 3]};
+ this.assertNotIdentical(object, Object.clone(object));
+ this.assertHashEqual(object, Object.clone(object));
+ this.assertHashEqual({}, Object.clone());
+ var clone = Object.clone(object);
+ delete clone.bar;
+ this.assertHashEqual({foo: 'foo'}, clone,
+ "Optimizing Object.clone perf using prototyping doesn't allow properties to be deleted.");
+ },
- this.assertEqual('without', methodWithoutArguments.bind({ hi: 'without' })());
- this.assertEqual('with,arg1,arg2', methodWithArguments.bind({ hi: 'with' })('arg1','arg2'));
- this.assertEqual('withBindArgs,arg1,arg2',
- methodWithArguments.bind({ hi: 'withBindArgs' }, 'arg1', 'arg2')());
- this.assertEqual('withBindArgsAndArgs,arg1,arg2,arg3,arg4',
- methodWithArguments.bind({ hi: 'withBindArgsAndArgs' }, 'arg1', 'arg2')('arg3', 'arg4'));
- },
-
- testFunctionCurry: function() {
- var split = function(delimiter, string) { return string.split(delimiter); };
- var splitOnColons = split.curry(":");
- this.assertNotIdentical(split, splitOnColons);
- this.assertEnumEqual(split(":", "0:1:2:3:4:5"), splitOnColons("0:1:2:3:4:5"));
- this.assertIdentical(split, split.curry());
- },
-
- testFunctionDelay: function() {
- window.delayed = undefined;
- var delayedFunction = function() { window.delayed = true; };
- var delayedFunctionWithArgs = function() { window.delayedWithArgs = $A(arguments).join(' '); };
- delayedFunction.delay(0.8);
- delayedFunctionWithArgs.delay(0.8, 'hello', 'world');
- this.assertUndefined(window.delayed);
- this.wait(1000, function() {
- this.assert(window.delayed);
- this.assertEqual('hello world', window.delayedWithArgs);
- });
- },
+ testObjectInspect: function() {
+ this.assertEqual('undefined', Object.inspect());
+ this.assertEqual('undefined', Object.inspect(undefined));
+ this.assertEqual('null', Object.inspect(null));
+ this.assertEqual("'foo\\\\b\\\'ar'", Object.inspect('foo\\b\'ar'));
+ this.assertEqual('[]', Object.inspect([]));
+ this.assertNothingRaised(function() { Object.inspect(window.Node) });
+ },
+
+ testObjectToJSON: function() {
+ this.assertUndefined(Object.toJSON(undefined));
+ this.assertUndefined(Object.toJSON(Prototype.K));
+ this.assertEqual('\"\"', Object.toJSON(''));
+ this.assertEqual('[]', Object.toJSON([]));
+ this.assertEqual('[\"a\"]', Object.toJSON(['a']));
+ this.assertEqual('[\"a\", 1]', Object.toJSON(['a', 1]));
+ this.assertEqual('[\"a\", {\"b\": null}]', Object.toJSON(['a', {'b': null}]));
+ this.assertEqual('{\"a\": \"hello!\"}', Object.toJSON({a: 'hello!'}));
+ this.assertEqual('{}', Object.toJSON({}));
+ this.assertEqual('{}', Object.toJSON({a: undefined, b: undefined, c: Prototype.K}));
+ this.assertEqual('{\"b\": [false, true], \"c\": {\"a\": \"hello!\"}}',
+ Object.toJSON({'b': [undefined, false, true, undefined], c: {a: 'hello!'}}));
+ this.assertEqual('{\"b\": [false, true], \"c\": {\"a\": \"hello!\"}}',
+ Object.toJSON($H({'b': [undefined, false, true, undefined], c: {a: 'hello!'}})));
+ this.assertEqual('true', Object.toJSON(true));
+ this.assertEqual('false', Object.toJSON(false));
+ this.assertEqual('null', Object.toJSON(null));
+ var sam = new Person('sam');
+ this.assertEqual('-sam', Object.toJSON(sam));
+ this.assertEqual('-sam', sam.toJSON());
+ var element = $('test');
+ this.assertUndefined(Object.toJSON(element));
+ element.toJSON = function(){return 'I\'m a div with id test'};
+ this.assertEqual('I\'m a div with id test', Object.toJSON(element));
+ },
+
+ testObjectToHTML: function() {
+ this.assertIdentical('', Object.toHTML());
+ this.assertIdentical('', Object.toHTML(''));
+ this.assertIdentical('', Object.toHTML(null));
+ this.assertIdentical('0', Object.toHTML(0));
+ this.assertIdentical('123', Object.toHTML(123));
+ this.assertEqual('hello world', Object.toHTML('hello world'));
+ this.assertEqual('hello world', Object.toHTML({toHTML: function() { return 'hello world' }}));
+ },
+
+ testObjectIsArray: function() {
+ this.assert(Object.isArray([]));
+ this.assert(Object.isArray([0]));
+ this.assert(Object.isArray([0, 1]));
+ this.assert(!Object.isArray({}));
+ this.assert(!Object.isArray($('list').childNodes));
+ this.assert(!Object.isArray());
+ this.assert(!Object.isArray(''));
+ this.assert(!Object.isArray('foo'));
+ this.assert(!Object.isArray(0));
+ this.assert(!Object.isArray(1));
+ this.assert(!Object.isArray(null));
+ this.assert(!Object.isArray(true));
+ this.assert(!Object.isArray(false));
+ this.assert(!Object.isArray(undefined));
+ },
+
+ testObjectIsHash: function() {
+ this.assert(Object.isHash($H()));
+ this.assert(Object.isHash(new Hash()));
+ this.assert(!Object.isHash({}));
+ },
+
+ testObjectIsElement: function() {
+ this.assert(Object.isElement(document.createElement('div')));
+ this.assert(Object.isElement(new Element('div')));
+ this.assert(Object.isElement($('testlog')));
+ this.assert(!Object.isElement(document.createTextNode('bla')));
+ },
+
+ testObjectIsFunction: function() {
+ this.assert(Object.isFunction(function() { }));
+ this.assert(Object.isFunction(Class.create()));
+ this.assert(!Object.isFunction("a string"));
+ this.assert(!Object.isFunction($("testlog")));
+ this.assert(!Object.isFunction([]));
+ this.assert(!Object.isFunction({}));
+ this.assert(!Object.isFunction(0));
+ this.assert(!Object.isFunction(false));
+ this.assert(!Object.isFunction(undefined));
+ },
+
+ testObjectIsString: function() {
+ this.assert(!Object.isString(function() { }));
+ this.assert(Object.isString("a string"));
+ this.assert(!Object.isString(0));
+ this.assert(!Object.isString([]));
+ this.assert(!Object.isString({}));
+ this.assert(!Object.isString(false));
+ this.assert(!Object.isString(undefined));
+ },
+
+ testObjectIsNumber: function() {
+ this.assert(Object.isNumber(0));
+ this.assert(Object.isNumber(1.0));
+ this.assert(!Object.isNumber(function() { }));
+ this.assert(!Object.isNumber("a string"));
+ this.assert(!Object.isNumber([]));
+ this.assert(!Object.isNumber({}));
+ this.assert(!Object.isNumber(false));
+ this.assert(!Object.isNumber(undefined));
+ },
+
+ testObjectIsUndefined: function() {
+ this.assert(Object.isUndefined(undefined));
+ this.assert(!Object.isUndefined(null));
+ this.assert(!Object.isUndefined(false));
+ this.assert(!Object.isUndefined(0));
+ this.assert(!Object.isUndefined(""));
+ this.assert(!Object.isUndefined(function() { }));
+ this.assert(!Object.isUndefined([]));
+ this.assert(!Object.isUndefined({}));
+ },
+
+ // sanity check
+ testDoesntExtendObjectPrototype: function() {
+ // for-in is supported with objects
+ var iterations = 0, obj = { a: 1, b: 2, c: 3 };
+ for(property in obj) iterations++;
+ this.assertEqual(3, iterations);
- testFunctionWrap: function() {
- function sayHello(){
- return 'hello world';
- };
-
- this.assertEqual('HELLO WORLD', sayHello.wrap(function(proceed) {
- return proceed().toUpperCase();
- })());
-
- var temp = String.prototype.capitalize;
- String.prototype.capitalize = String.prototype.capitalize.wrap(function(proceed, eachWord) {
- if(eachWord && this.include(' ')) return this.split(' ').map(function(str){
- return str.capitalize();
- }).join(' ');
- return proceed();
- });
- this.assertEqual('Hello world', 'hello world'.capitalize());
- this.assertEqual('Hello World', 'hello world'.capitalize(true));
- this.assertEqual('Hello', 'hello'.capitalize());
- String.prototype.capitalize = temp;
- },
+ // for-in is not supported with arrays
+ iterations = 0;
+ var arr = [1,2,3];
+ for(property in arr) iterations++;
+ this.assert(iterations > 3);
+ },
+
+ testPeriodicalExecuterStop: function() {
+ var peEventCount = 0;
+ function peEventFired(pe) {
+ if (++peEventCount > 2) pe.stop();
+ }
- testFunctionDefer: function() {
- window.deferred = undefined;
- var deferredFunction = function() { window.deferred = true; };
- deferredFunction.defer();
- this.assertUndefined(window.deferred);
- this.wait(50, function() {
- this.assert(window.deferred);
-
- window.deferredValue = 0;
- var deferredFunction2 = function(arg) { window.deferredValue = arg; };
- deferredFunction2.defer('test');
- this.wait(50, function() {
- this.assertEqual('test', window.deferredValue);
- });
- });
- },
+ // peEventFired will stop the PeriodicalExecuter after 3 callbacks
+ new PeriodicalExecuter(peEventFired, 0.05);
- testFunctionMethodize: function() {
- var Foo = { bar: function(baz) { return baz } };
- var baz = { quux: Foo.bar.methodize() };
-
- this.assertEqual(Foo.bar.methodize(), baz.quux);
- this.assertEqual(baz, Foo.bar(baz));
- this.assertEqual(baz, baz.quux());
- },
+ this.wait(600, function() {
+ this.assertEqual(3, peEventCount);
+ });
+ },
- testObjectExtend: function() {
- var object = {foo: 'foo', bar: [1, 2, 3]};
- this.assertIdentical(object, Object.extend(object));
- this.assertHashEqual({foo: 'foo', bar: [1, 2, 3]}, object);
- this.assertIdentical(object, Object.extend(object, {bla: 123}));
- this.assertHashEqual({foo: 'foo', bar: [1, 2, 3], bla: 123}, object);
- this.assertHashEqual({foo: 'foo', bar: [1, 2, 3], bla: null},
- Object.extend(object, {bla: null}));
- },
+ testBindAsEventListener: function() {
+ for( var i = 0; i < 10; ++i ){
+ var div = document.createElement('div');
+ div.setAttribute('id','test-'+i);
+ document.body.appendChild(div);
+ var tobj = new TestObj();
+ var eventTest = { test: true };
+ var call = tobj.assertingEventHandler.bindAsEventListener(tobj,
+ this.assertEqual.bind(this, eventTest),
+ this.assertEqual.bind(this, arg1),
+ this.assertEqual.bind(this, arg2),
+ this.assertEqual.bind(this, arg3), arg1, arg2, arg3 );
+ call(eventTest);
+ }
+ },
+
+ testDateToJSON: function() {
+ this.assertEqual('\"1970-01-01T00:00:00Z\"', new Date(Date.UTC(1970, 0, 1)).toJSON());
+ },
+
+ testRegExpEscape: function() {
+ this.assertEqual('word', RegExp.escape('word'));
+ this.assertEqual('\\/slashes\\/', RegExp.escape('/slashes/'));
+ this.assertEqual('\\\\backslashes\\\\', RegExp.escape('\\backslashes\\'));
+ this.assertEqual('\\\\border of word', RegExp.escape('\\border of word'));
- testObjectToQueryString: function() {
- this.assertEqual('a=A&b=B&c=C&d=D%23', Object.toQueryString({a: 'A', b: 'B', c: 'C', d: 'D#'}));
- },
+ this.assertEqual('\\(\\?\\:non-capturing\\)', RegExp.escape('(?:non-capturing)'));
+ this.assertEqual('non-capturing', new RegExp(RegExp.escape('(?:') + '([^)]+)').exec('(?:non-capturing)')[1]);
- testObjectClone: function() {
- var object = {foo: 'foo', bar: [1, 2, 3]};
- this.assertNotIdentical(object, Object.clone(object));
- this.assertHashEqual(object, Object.clone(object));
- this.assertHashEqual({}, Object.clone());
- var clone = Object.clone(object);
- delete clone.bar;
- this.assertHashEqual({foo: 'foo'}, clone,
- "Optimizing Object.clone perf using prototyping doesn't allow properties to be deleted.");
- },
-
- testObjectInspect: function() {
- this.assertEqual('undefined', Object.inspect());
- this.assertEqual('undefined', Object.inspect(undefined));
- this.assertEqual('null', Object.inspect(null));
- this.assertEqual("'foo\\\\b\\\'ar'", Object.inspect('foo\\b\'ar'));
- this.assertEqual('[]', Object.inspect([]));
- this.assertNothingRaised(function() { Object.inspect(window.Node) });
- },
+ this.assertEqual('\\(\\?\\=positive-lookahead\\)', RegExp.escape('(?=positive-lookahead)'));
+ this.assertEqual('positive-lookahead', new RegExp(RegExp.escape('(?=') + '([^)]+)').exec('(?=positive-lookahead)')[1]);
- testObjectToJSON: function() {
- this.assertUndefined(Object.toJSON(undefined));
- this.assertUndefined(Object.toJSON(Prototype.K));
- this.assertEqual('\"\"', Object.toJSON(''));
- this.assertEqual('[]', Object.toJSON([]));
- this.assertEqual('[\"a\"]', Object.toJSON(['a']));
- this.assertEqual('[\"a\", 1]', Object.toJSON(['a', 1]));
- this.assertEqual('[\"a\", {\"b\": null}]', Object.toJSON(['a', {'b': null}]));
- this.assertEqual('{\"a\": \"hello!\"}', Object.toJSON({a: 'hello!'}));
- this.assertEqual('{}', Object.toJSON({}));
- this.assertEqual('{}', Object.toJSON({a: undefined, b: undefined, c: Prototype.K}));
- this.assertEqual('{\"b\": [false, true], \"c\": {\"a\": \"hello!\"}}',
- Object.toJSON({'b': [undefined, false, true, undefined], c: {a: 'hello!'}}));
- this.assertEqual('{\"b\": [false, true], \"c\": {\"a\": \"hello!\"}}',
- Object.toJSON($H({'b': [undefined, false, true, undefined], c: {a: 'hello!'}})));
- this.assertEqual('true', Object.toJSON(true));
- this.assertEqual('false', Object.toJSON(false));
- this.assertEqual('null', Object.toJSON(null));
- var sam = new Person('sam');
- this.assertEqual('-sam', Object.toJSON(sam));
- this.assertEqual('-sam', sam.toJSON());
- var element = $('test');
- this.assertUndefined(Object.toJSON(element));
- element.toJSON = function(){return 'I\'m a div with id test'};
- this.assertEqual('I\'m a div with id test', Object.toJSON(element));
- },
+ this.assertEqual('\\(\\?<\\=positive-lookbehind\\)', RegExp.escape('(?<=positive-lookbehind)'));
+ this.assertEqual('positive-lookbehind', new RegExp(RegExp.escape('(?<=') + '([^)]+)').exec('(?<=positive-lookbehind)')[1]);
- testObjectToHTML: function() {
- this.assertIdentical('', Object.toHTML());
- this.assertIdentical('', Object.toHTML(''));
- this.assertIdentical('', Object.toHTML(null));
- this.assertIdentical('0', Object.toHTML(0));
- this.assertIdentical('123', Object.toHTML(123));
- this.assertEqual('hello world', Object.toHTML('hello world'));
- this.assertEqual('hello world', Object.toHTML({toHTML: function() { return 'hello world' }}));
- },
+ this.assertEqual('\\(\\?\\!negative-lookahead\\)', RegExp.escape('(?!negative-lookahead)'));
+ this.assertEqual('negative-lookahead', new RegExp(RegExp.escape('(?!') + '([^)]+)').exec('(?!negative-lookahead)')[1]);
- testObjectIsArray: function() {
- this.assert(Object.isArray([]));
- this.assert(Object.isArray([0]));
- this.assert(Object.isArray([0, 1]));
- this.assert(!Object.isArray({}));
- this.assert(!Object.isArray($('list').childNodes));
- this.assert(!Object.isArray());
- this.assert(!Object.isArray(''));
- this.assert(!Object.isArray('foo'));
- this.assert(!Object.isArray(0));
- this.assert(!Object.isArray(1));
- this.assert(!Object.isArray(null));
- this.assert(!Object.isArray(true));
- this.assert(!Object.isArray(false));
- this.assert(!Object.isArray(undefined));
- },
+ this.assertEqual('\\(\\?<\\!negative-lookbehind\\)', RegExp.escape('(?<!negative-lookbehind)'));
+ this.assertEqual('negative-lookbehind', new RegExp(RegExp.escape('(?<!') + '([^)]+)').exec('(?<!negative-lookbehind)')[1]);
- testObjectIsHash: function() {
- this.assert(Object.isHash($H()));
- this.assert(Object.isHash(new Hash()));
- this.assert(!Object.isHash({}));
- },
+ this.assertEqual('\\[\\\\w\\]\\+', RegExp.escape('[\\w]+'));
+ this.assertEqual('character class', new RegExp(RegExp.escape('[') + '([^\\]]+)').exec('[character class]')[1]);
- testObjectIsElement: function() {
- this.assert(Object.isElement(document.createElement('div')));
- this.assert(Object.isElement(new Element('div')));
- this.assert(Object.isElement($('testlog')));
- this.assert(!Object.isElement(document.createTextNode('bla')));
- },
+ this.assertEqual('<div>', new RegExp(RegExp.escape('<div>')).exec('<td><div></td>')[0]);
- testObjectIsFunction: function() {
- this.assert(Object.isFunction(function() { }));
- this.assert(Object.isFunction(Class.create()));
- this.assert(!Object.isFunction("a string"));
- this.assert(!Object.isFunction($("testlog")));
- this.assert(!Object.isFunction([]));
- this.assert(!Object.isFunction({}));
- this.assert(!Object.isFunction(0));
- this.assert(!Object.isFunction(false));
- this.assert(!Object.isFunction(undefined));
- },
+ this.assertEqual('false', RegExp.escape(false));
+ this.assertEqual('undefined', RegExp.escape());
+ this.assertEqual('null', RegExp.escape(null));
+ this.assertEqual('42', RegExp.escape(42));
- testObjectIsString: function() {
- this.assert(!Object.isString(function() { }));
- this.assert(Object.isString("a string"));
- this.assert(!Object.isString(0));
- this.assert(!Object.isString([]));
- this.assert(!Object.isString({}));
- this.assert(!Object.isString(false));
- this.assert(!Object.isString(undefined));
- },
+ this.assertEqual('\\\\n\\\\r\\\\t', RegExp.escape('\\n\\r\\t'));
+ this.assertEqual('\n\r\t', RegExp.escape('\n\r\t'));
+ this.assertEqual('\\{5,2\\}', RegExp.escape('{5,2}'));
- testObjectIsNumber: function() {
- this.assert(Object.isNumber(0));
- this.assert(Object.isNumber(1.0));
- this.assert(!Object.isNumber(function() { }));
- this.assert(!Object.isNumber("a string"));
- this.assert(!Object.isNumber([]));
- this.assert(!Object.isNumber({}));
- this.assert(!Object.isNumber(false));
- this.assert(!Object.isNumber(undefined));
- },
+ this.assertEqual(
+ '\\/\\(\\[\\.\\*\\+\\?\\^\\=\\!\\:\\$\\{\\}\\(\\)\\|\\[\\\\\\]\\\\\\\/\\\\\\\\\\]\\)\\/g',
+ RegExp.escape('/([.*+?^=!:${}()|[\\]\\/\\\\])/g')
+ );
+ },
+
+ testBrowserDetection: function() {
+ var results = $H(Prototype.Browser).map(function(engine){
+ return engine;
+ }).partition(function(engine){
+ return engine[1] === true
+ });
+ var trues = results[0], falses = results[1];
- testObjectIsUndefined: function() {
- this.assert(Object.isUndefined(undefined));
- this.assert(!Object.isUndefined(null));
- this.assert(!Object.isUndefined(false));
- this.assert(!Object.isUndefined(0));
- this.assert(!Object.isUndefined(""));
- this.assert(!Object.isUndefined(function() { }));
- this.assert(!Object.isUndefined([]));
- this.assert(!Object.isUndefined({}));
- },
+ this.info('User agent string is: ' + navigator.userAgent);
- // sanity check
- testDoesntExtendObjectPrototype: function() {
- // for-in is supported with objects
- var iterations = 0, obj = { a: 1, b: 2, c: 3 };
- for(property in obj) iterations++;
- this.assertEqual(3, iterations);
-
- // for-in is not supported with arrays
- iterations = 0;
- var arr = [1,2,3];
- for(property in arr) iterations++;
- this.assert(iterations > 3);
- },
+ this.assert(trues.size() == 0 || trues.size() == 1,
+ 'There should be only one or no browser detected.');
- testPeriodicalExecuterStop: function() {
- var peEventCount = 0;
- function peEventFired(pe) {
- if (++peEventCount > 2) pe.stop();
- }
-
- // peEventFired will stop the PeriodicalExecuter after 3 callbacks
- new PeriodicalExecuter(peEventFired, 0.05);
-
- this.wait(600, function() {
- this.assertEqual(3, peEventCount);
- });
- },
-
- testBindAsEventListener: function() {
- for( var i = 0; i < 10; ++i ){
- var div = document.createElement('div');
- div.setAttribute('id','test-'+i);
- document.body.appendChild(div);
- var tobj = new TestObj();
- var eventTest = { test: true };
- var call = tobj.assertingEventHandler.bindAsEventListener(tobj,
- this.assertEqual.bind(this, eventTest),
- this.assertEqual.bind(this, arg1),
- this.assertEqual.bind(this, arg2),
- this.assertEqual.bind(this, arg3), arg1, arg2, arg3 );
- call(eventTest);
- }
- },
+ // we should have definite trues or falses here
+ trues.each(function(result) {
+ this.assert(result[1] === true);
+ }, this);
+ falses.each(function(result) {
+ this.assert(result[1] === false);
+ }, this);
- testDateToJSON: function() {
- this.assertEqual('\"1970-01-01T00:00:00Z\"', new Date(Date.UTC(1970, 0, 1)).toJSON());
- },
+ if(navigator.userAgent.indexOf('AppleWebKit/') > -1) {
+ this.info('Running on WebKit');
+ this.assert(Prototype.Browser.WebKit);
+ }
- testRegExpEscape: function() {
- this.assertEqual('word', RegExp.escape('word'));
- this.assertEqual('\\/slashes\\/', RegExp.escape('/slashes/'));
- this.assertEqual('\\\\backslashes\\\\', RegExp.escape('\\backslashes\\'));
- this.assertEqual('\\\\border of word', RegExp.escape('\\border of word'));
-
- this.assertEqual('\\(\\?\\:non-capturing\\)', RegExp.escape('(?:non-capturing)'));
- this.assertEqual('non-capturing', new RegExp(RegExp.escape('(?:') + '([^)]+)').exec('(?:non-capturing)')[1]);
-
- this.assertEqual('\\(\\?\\=positive-lookahead\\)', RegExp.escape('(?=positive-lookahead)'));
- this.assertEqual('positive-lookahead', new RegExp(RegExp.escape('(?=') + '([^)]+)').exec('(?=positive-lookahead)')[1]);
-
- this.assertEqual('\\(\\?<\\=positive-lookbehind\\)', RegExp.escape('(?<=positive-lookbehind)'));
- this.assertEqual('positive-lookbehind', new RegExp(RegExp.escape('(?<=') + '([^)]+)').exec('(?<=positive-lookbehind)')[1]);
-
- this.assertEqual('\\(\\?\\!negative-lookahead\\)', RegExp.escape('(?!negative-lookahead)'));
- this.assertEqual('negative-lookahead', new RegExp(RegExp.escape('(?!') + '([^)]+)').exec('(?!negative-lookahead)')[1]);
-
- this.assertEqual('\\(\\?<\\!negative-lookbehind\\)', RegExp.escape('(?<!negative-lookbehind)'));
- this.assertEqual('negative-lookbehind', new RegExp(RegExp.escape('(?<!') + '([^)]+)').exec('(?<!negative-lookbehind)')[1]);
-
- this.assertEqual('\\[\\\\w\\]\\+', RegExp.escape('[\\w]+'));
- this.assertEqual('character class', new RegExp(RegExp.escape('[') + '([^\\]]+)').exec('[character class]')[1]);
-
- this.assertEqual('<div>', new RegExp(RegExp.escape('<div>')).exec('<td><div></td>')[0]);
-
- this.assertEqual('false', RegExp.escape(false));
- this.assertEqual('undefined', RegExp.escape());
- this.assertEqual('null', RegExp.escape(null));
- this.assertEqual('42', RegExp.escape(42));
-
- this.assertEqual('\\\\n\\\\r\\\\t', RegExp.escape('\\n\\r\\t'));
- this.assertEqual('\n\r\t', RegExp.escape('\n\r\t'));
- this.assertEqual('\\{5,2\\}', RegExp.escape('{5,2}'));
-
- this.assertEqual(
- '\\/\\(\\[\\.\\*\\+\\?\\^\\=\\!\\:\\$\\{\\}\\(\\)\\|\\[\\\\\\]\\\\\\\/\\\\\\\\\\]\\)\\/g',
- RegExp.escape('/([.*+?^=!:${}()|[\\]\\/\\\\])/g')
- );
- },
+ if(!!window.opera) {
+ this.info('Running on Opera');
+ this.assert(Prototype.Browser.Opera);
+ }
- testBrowserDetection: function() {
- var results = $H(Prototype.Browser).map(function(engine){
- return engine;
- }).partition(function(engine){
- return engine[1] === true
- });
- var trues = results[0], falses = results[1];
-
- this.info('User agent string is: ' + navigator.userAgent);
-
- this.assert(trues.size() == 0 || trues.size() == 1,
- 'There should be only one or no browser detected.');
-
- // we should have definite trues or falses here
- trues.each(function(result) {
- this.assert(result[1] === true);
- }, this);
- falses.each(function(result) {
- this.assert(result[1] === false);
- }, this);
-
- if(navigator.userAgent.indexOf('AppleWebKit/') > -1) {
- this.info('Running on WebKit');
- this.assert(Prototype.Browser.WebKit);
- }
-
- if(!!window.opera) {
- this.info('Running on Opera');
- this.assert(Prototype.Browser.Opera);
- }
-
- if(!!(window.attachEvent && !window.opera)) {
- this.info('Running on IE');
- this.assert(Prototype.Browser.IE);
- }
-
- if(navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1) {
- this.info('Running on Gecko');
- this.assert(Prototype.Browser.Gecko);
- }
- },
+ if(!!(window.attachEvent && !window.opera)) {
+ this.info('Running on IE');
+ this.assert(Prototype.Browser.IE);
+ }
- testClassCreate: function() {
- this.assert(Object.isFunction(Animal), 'Animal is not a constructor');
- this.assertEnumEqual([Cat, Mouse, Dog, Ox], Animal.subclasses);
- Animal.subclasses.each(function(subclass) {
- this.assertEqual(Animal, subclass.superclass);
- }, this);
+ if(navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1) {
+ this.info('Running on Gecko');
+ this.assert(Prototype.Browser.Gecko);
+ }
+ },
+
+ testClassCreate: function() {
+ this.assert(Object.isFunction(Animal), 'Animal is not a constructor');
+ this.assertEnumEqual([Cat, Mouse, Dog, Ox], Animal.subclasses);
+ Animal.subclasses.each(function(subclass) {
+ this.assertEqual(Animal, subclass.superclass);
+ }, this);
- var Bird = Class.create(Animal);
- this.assertEqual(Bird, Animal.subclasses.last());
- // for..in loop (for some reason) doesn't iterate over the constructor property in top-level classes
- this.assertEnumEqual(Object.keys(new Animal).sort(), Object.keys(new Bird).without('constructor').sort());
- },
+ var Bird = Class.create(Animal);
+ this.assertEqual(Bird, Animal.subclasses.last());
+ // for..in loop (for some reason) doesn't iterate over the constructor property in top-level classes
+ this.assertEnumEqual(Object.keys(new Animal).sort(), Object.keys(new Bird).without('constructor').sort());
+ },
- testClassInstantiation: function() {
- var pet = new Animal("Nibbles");
- this.assertEqual("Nibbles", pet.name, "property not initialized");
- this.assertEqual('Nibbles: Hi!', pet.say('Hi!'));
- this.assertEqual(Animal, pet.constructor, "bad constructor reference");
- this.assertUndefined(pet.superclass);
+ testClassInstantiation: function() {
+ var pet = new Animal("Nibbles");
+ this.assertEqual("Nibbles", pet.name, "property not initialized");
+ this.assertEqual('Nibbles: Hi!', pet.say('Hi!'));
+ this.assertEqual(Animal, pet.constructor, "bad constructor reference");
+ this.assertUndefined(pet.superclass);
- var Empty = Class.create();
- this.assert('object', typeof new Empty);
- },
+ var Empty = Class.create();
+ this.assert('object', typeof new Empty);
+ },
- testInheritance: function() {
- var tom = new Cat('Tom');
- this.assertEqual(Cat, tom.constructor, "bad constructor reference");
- this.assertEqual(Animal, tom.constructor.superclass, 'bad superclass reference');
- this.assertEqual('Tom', tom.name);
- this.assertEqual('Tom: meow', tom.say('meow'));
- this.assertEqual('Tom: Yuk! I only eat mice.', tom.eat(new Animal));
- },
+ testInheritance: function() {
+ var tom = new Cat('Tom');
+ this.assertEqual(Cat, tom.constructor, "bad constructor reference");
+ this.assertEqual(Animal, tom.constructor.superclass, 'bad superclass reference');
+ this.assertEqual('Tom', tom.name);
+ this.assertEqual('Tom: meow', tom.say('meow'));
+ this.assertEqual('Tom: Yuk! I only eat mice.', tom.eat(new Animal));
+ },
- testSuperclassMethodCall: function() {
- var tom = new Cat('Tom');
- this.assertEqual('Tom: Yum!', tom.eat(new Mouse));
+ testSuperclassMethodCall: function() {
+ var tom = new Cat('Tom');
+ this.assertEqual('Tom: Yum!', tom.eat(new Mouse));
- // augment the constructor and test
- var Dodo = Class.create(Animal, {
- initialize: function($super, name) {
- $super(name);
- this.extinct = true;
- },
-
- say: function($super, message) {
- return $super(message) + " honk honk";
- }
- });
+ // augment the constructor and test
+ var Dodo = Class.create(Animal, {
+ initialize: function($super, name) {
+ $super(name);
+ this.extinct = true;
+ },
+
+ say: function($super, message) {
+ return $super(message) + " honk honk";
+ }
+ });
- var gonzo = new Dodo('Gonzo');
- this.assertEqual('Gonzo', gonzo.name);
- this.assert(gonzo.extinct, 'Dodo birds should be extinct');
- this.assertEqual("Gonzo: hello honk honk", gonzo.say("hello"));
- },
+ var gonzo = new Dodo('Gonzo');
+ this.assertEqual('Gonzo', gonzo.name);
+ this.assert(gonzo.extinct, 'Dodo birds should be extinct');
+ this.assertEqual("Gonzo: hello honk honk", gonzo.say("hello"));
+ },
- testClassAddMethods: function() {
- var tom = new Cat('Tom');
- var jerry = new Mouse('Jerry');
-
- Animal.addMethods({
- sleep: function() {
- return this.say('ZZZ');
- }
- });
-
- Mouse.addMethods({
- sleep: function($super) {
- return $super() + " ... no, can't sleep! Gotta steal cheese!";
- },
- escape: function(cat) {
- return this.say('(from a mousehole) Take that, ' + cat.name + '!');
- }
- });
-
- this.assertEqual('Tom: ZZZ', tom.sleep(), "added instance method not available to subclass");
- this.assertEqual("Jerry: ZZZ ... no, can't sleep! Gotta steal cheese!", jerry.sleep());
- this.assertEqual("Jerry: (from a mousehole) Take that, Tom!", jerry.escape(tom));
- // insure that a method has not propagated *up* the prototype chain:
- this.assertUndefined(tom.escape);
- this.assertUndefined(new Animal().escape);
-
- Animal.addMethods({
- sleep: function() {
- return this.say('zZzZ');
- }
- });
-
- this.assertEqual("Jerry: zZzZ ... no, can't sleep! Gotta steal cheese!", jerry.sleep());
- },
+ testClassAddMethods: function() {
+ var tom = new Cat('Tom');
+ var jerry = new Mouse('Jerry');
- testBaseClassWithMixin: function() {
- var grass = new Plant('grass', 3);
- this.assertRespondsTo('getValue', grass);
- this.assertEqual('#<Plant: grass>', grass.inspect());
- },
+ Animal.addMethods({
+ sleep: function() {
+ return this.say('ZZZ');
+ }
+ });
- testSubclassWithMixin: function() {
- var snoopy = new Dog('Snoopy', 12, 'male');
- this.assertRespondsTo('reproduce', snoopy);
- },
-
- testSubclassWithMixins: function() {
- var cow = new Ox('cow', 400, 'female');
- this.assertEqual('#<Ox: cow>', cow.inspect());
- this.assertRespondsTo('reproduce', cow);
- this.assertRespondsTo('getValue', cow);
- },
-
- testClassWithToStringAndValueOfMethods: function() {
- var Foo = Class.create({
- toString: function() { return "toString" },
- valueOf: function() { return "valueOf" }
- });
-
- this.assertEqual("toString", new Foo().toString());
- this.assertEqual("valueOf", new Foo().valueOf());
- }
- });
+ Mouse.addMethods({
+ sleep: function($super) {
+ return $super() + " ... no, can't sleep! Gotta steal cheese!";
+ },
+ escape: function(cat) {
+ return this.say('(from a mousehole) Take that, ' + cat.name + '!');
+ }
+ });
+
+ this.assertEqual('Tom: ZZZ', tom.sleep(), "added instance method not available to subclass");
+ this.assertEqual("Jerry: ZZZ ... no, can't sleep! Gotta steal cheese!", jerry.sleep());
+ this.assertEqual("Jerry: (from a mousehole) Take that, Tom!", jerry.escape(tom));
+ // insure that a method has not propagated *up* the prototype chain:
+ this.assertUndefined(tom.escape);
+ this.assertUndefined(new Animal().escape);
+
+ Animal.addMethods({
+ sleep: function() {
+ return this.say('zZzZ');
+ }
+ });
+
+ this.assertEqual("Jerry: zZzZ ... no, can't sleep! Gotta steal cheese!", jerry.sleep());
+ },
+
+ testBaseClassWithMixin: function() {
+ var grass = new Plant('grass', 3);
+ this.assertRespondsTo('getValue', grass);
+ this.assertEqual('#<Plant: grass>', grass.inspect());
+ },
+
+ testSubclassWithMixin: function() {
+ var snoopy = new Dog('Snoopy', 12, 'male');
+ this.assertRespondsTo('reproduce', snoopy);
+ },
+
+ testSubclassWithMixins: function() {
+ var cow = new Ox('cow', 400, 'female');
+ this.assertEqual('#<Ox: cow>', cow.inspect());
+ this.assertRespondsTo('reproduce', cow);
+ this.assertRespondsTo('getValue', cow);
+ },
+
+ testClassWithToStringAndValueOfMethods: function() {
+ var Foo = Class.create({
+ toString: function() { return "toString" },
+ valueOf: function() { return "valueOf" }
+ });
+
+ this.assertEqual("toString", new Foo().toString());
+ this.assertEqual("valueOf", new Foo().valueOf());
+ }
+});
View
18 test/unit/dom_test.js
@@ -1,4 +1,3 @@
-var testVar = 'to be updated', testVar2 = '';
var getInnerHTML = function(id) {
return $(id).innerHTML.toString().toLowerCase().gsub(/[\r\n\t]/, '');
};
@@ -7,23 +6,6 @@ var createParagraph = function(text) {
p.appendChild(document.createTextNode(text));
return p;
}
-Element.addMethods({
- hashBrowns: function(element) { return 'hash browns'; }
-});
-
-Element.addMethods("LI", {
- pancakes: function(element) { return "pancakes"; }
-});
-
-Element.addMethods("DIV", {
- waffles: function(element) { return "waffles"; }
-});
-
-Element.addMethods($w("li div"), {
- orangeJuice: function(element) { return "orange juice"; }
-});
-
-var documentViewportProperties;
new Test.Unit.Runner({
setup: function() {
View
3 test/unit/element_mixins_test.js
@@ -1,6 +1,3 @@
-Form.Element.Methods.coffee = Prototype.K;
-Element.addMethods();
-
new Test.Unit.Runner({
testInput: function() {
this.assert($("input").present != null);
View
24 test/unit/enumerable_test.js
@@ -1,27 +1,3 @@
-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;
View
42 test/unit/fixtures/ajax.js
@@ -0,0 +1,42 @@
+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 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.';
View
106 test/unit/fixtures/base.js
@@ -0,0 +1,106 @@
+var Person = function(name){
+ this.name = name;
+};
+
+Person.prototype.toJSON = function() {
+ return '-' + this.name;
+};
+
+var arg1 = 1;
+var arg2 = 2;
+var arg3 = 3;
+function TestObj() { };
+TestObj.prototype.assertingEventHandler =
+ function(event, assertEvent, assert1, assert2, assert3, a1, a2, a3) {
+ assertEvent(event);
+ assert1(a1);
+ assert2(a2);
+ assert3(a3);
+ };
+
+var globalBindTest = null;
+
+
+// base class
+var Animal = Class.create({
+ initialize: function(name) {
+ this.name = name;
+ },
+ name: "",
+ eat: function() {
+ return this.say("Yum!");
+ },
+ say: function(message) {
+ return this.name + ": " + message;
+ }
+});
+
+// subclass that augments a method
+var Cat = Class.create(Animal, {
+ eat: function($super, food) {
+ if (food instanceof Mouse) return $super();
+ else return this.say("Yuk! I only eat mice.");
+ }
+});
+
+// empty subclass
+var Mouse = Class.create(Animal, {});
+
+//mixins
+var Sellable = {
+ getValue: function(pricePerKilo) {
+ return this.weight * pricePerKilo;
+ },
+
+ inspect: function() {
+ return '#<Sellable: #{weight}kg>'.interpolate(this);
+ }
+};
+
+var Reproduceable = {
+ reproduce: function(partner) {
+ if (partner.constructor != this.constructor || partner.sex == this.sex)
+ return null;
+ var weight = this.weight / 10, sex = Math.random(1).round() ? 'male' : 'female';
+ return new this.constructor('baby', weight, sex);
+ }
+};
+
+// base class with mixin
+var Plant = Class.create(Sellable, {
+ initialize: function(name, weight) {
+ this.name = name;
+ this.weight = weight;
+ },
+
+ inspect: function() {
+ return '#<Plant: #{name}>'.interpolate(this);
+ }
+});
+
+// subclass with mixin
+var Dog = Class.create(Animal, Reproduceable, {
+ initialize: function($super, name, weight, sex) {
+ this.weight = weight;
+ this.sex = sex;
+ $super(name);
+ }
+});
+
+// subclass with mixins
+var Ox = Class.create(Animal, Sellable, Reproduceable, {
+ initialize: function($super, name, weight, sex) {
+ this.weight = weight;
+ this.sex = sex;
+ $super(name);
+ },
+
+ eat: function(food) {
+ if (food instanceof Plant)
+ this.weight += food.weight;
+ },
+
+ inspect: function() {
+ return '#<Ox: #{name}>'.interpolate(this);
+ }
+});
View
84 test/unit/fixtures/dom.css
@@ -0,0 +1,84 @@
+#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;
+}
View
89 test/unit/fixtures/dom.html
@@ -1,92 +1,3 @@
-<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>
View
17 test/unit/fixtures/dom.js
@@ -0,0 +1,17 @@
+var testVar = 'to be updated', testVar2 = '', documentViewportProperties;
+
+Element.addMethods({
+ hashBrowns: function(element) { return 'hash browns'; }
+});
+
+Element.addMethods("LI", {
+ pancakes: function(element) { return "pancakes"; }
+});
+
+Element.addMethods("DIV", {
+ waffles: function(element) { return "waffles"; }
+});
+
+Element.addMethods($w("li div"), {
+ orangeJuice: function(element) { return "orange juice"; }
+});
View
2 test/unit/fixtures/element_mixins.js
@@ -0,0 +1,2 @@
+Form.Element.Methods.coffee = Prototype.K;
+Element.addMethods();
View
23 test/unit/fixtures/enumerable.js
@@ -0,0 +1,23 @@
+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);
View
25 test/unit/fixtures/hash.js
@@ -0,0 +1,25 @@
+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 }
+};
View
8 test/unit/fixtures/string.js
@@ -0,0 +1,8 @@
+var attackTarget;
+var evalScriptsCounter = 0,
+ largeTextEscaped = '&lt;span&gt;test&lt;/span&gt;',
+ largeTextUnescaped = '<span>test</span>';
+(2048).times(function(){
+ largeTextEscaped += ' ABC';
+ largeTextUnescaped += ' ABC';
+});
View
26 test/unit/hash_test.js
@@ -1,29 +1,3 @@
-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'})
View
9 test/unit/string_test.js
@@ -1,12 +1,3 @@
-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));

0 comments on commit cf5d180

Please sign in to comment.
Something went wrong with that request. Please try again.