488 lines
18 KiB
HTML
488 lines
18 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
|
<head>
|
|
<title>Prototype Unit test file</title>
|
|
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
|
<script src="../../dist/prototype.js" type="text/javascript"></script>
|
|
<script src="../lib/unittest.js" type="text/javascript"></script>
|
|
<link rel="stylesheet" href="../test.css" type="text/css" />
|
|
<style type="text/css" media="screen">
|
|
/* <![CDATA[ */
|
|
#testcss1 { font-size:11px; color: #f00; }
|
|
#testcss2 { font-size:12px; color: #0f0; display: none; }
|
|
/* ]]> */
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<h1>Prototype Unit test file</h1>
|
|
<p>
|
|
Test of utility functions in base.js
|
|
</p>
|
|
|
|
<!-- Log output -->
|
|
<div id="testlog"> </div>
|
|
<div id="test"></div>
|
|
<!-- Tests follow -->
|
|
<script type="text/javascript" language="javascript" charset="utf-8">
|
|
// <![CDATA[
|
|
var Person = function(name){
|
|
this.name = name;
|
|
};
|
|
|
|
Person.prototype.toJSON = function() {
|
|
return '-' + this.name;
|
|
};
|
|
|
|
var 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, {});
|
|
|
|
new Test.Unit.Runner({
|
|
|
|
testFunctionArgumentNames: function() { with(this) {
|
|
assertEnumEqual([], (function() {}).argumentNames());
|
|
assertEnumEqual(["one"], (function(one) {}).argumentNames());
|
|
assertEnumEqual(["one", "two", "three"], (function(one, two, three) {}).argumentNames());
|
|
assertEqual("$super", (function($super) {}).argumentNames().first());
|
|
}},
|
|
|
|
testFunctionBind: function() { with(this) {
|
|
function methodWithoutArguments() { return this.hi };
|
|
function methodWithArguments() { return this.hi + ',' + $A(arguments).join(',') };
|
|
var func = Prototype.emptyFunction;
|
|
|
|
assertIdentical(func, func.bind());
|
|
assertIdentical(func, func.bind(undefined));
|
|
assertNotIdentical(func, func.bind(null));
|
|
|
|
assertEqual('without', methodWithoutArguments.bind({ hi: 'without' })());
|
|
assertEqual('with,arg1,arg2', methodWithArguments.bind({ hi: 'with' })('arg1','arg2'));
|
|
assertEqual('withBindArgs,arg1,arg2',
|
|
methodWithArguments.bind({ hi: 'withBindArgs' }, 'arg1', 'arg2')());
|
|
assertEqual('withBindArgsAndArgs,arg1,arg2,arg3,arg4',
|
|
methodWithArguments.bind({ hi: 'withBindArgsAndArgs' }, 'arg1', 'arg2')('arg3', 'arg4'));
|
|
}},
|
|
|
|
testFunctionCurry: function() { with(this) {
|
|
var split = function(delimiter, string) { return string.split(delimiter); };
|
|
var splitOnColons = split.curry(":");
|
|
assertNotIdentical(split, splitOnColons);
|
|
assertEnumEqual(split(":", "0:1:2:3:4:5"), splitOnColons("0:1:2:3:4:5"));
|
|
assertIdentical(split, split.curry());
|
|
}},
|
|
|
|
testFunctionDelay: function() { with(this) {
|
|
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');
|
|
assertUndefined(window.delayed);
|
|
wait(1000, function() {
|
|
assert(window.delayed);
|
|
assertEqual('hello world', window.delayedWithArgs);
|
|
});
|
|
}},
|
|
|
|
testFunctionWrap: function() { with(this) {
|
|
function sayHello(){
|
|
return 'hello world';
|
|
};
|
|
|
|
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();
|
|
});
|
|
assertEqual('Hello world', 'hello world'.capitalize());
|
|
assertEqual('Hello World', 'hello world'.capitalize(true));
|
|
assertEqual('Hello', 'hello'.capitalize());
|
|
String.prototype.capitalize = temp;
|
|
}},
|
|
|
|
testFunctionDefer: function() { with(this) {
|
|
window.deferred = undefined;
|
|
var deferredFunction = function() { window.deferred = true; };
|
|
deferredFunction.defer();
|
|
assertUndefined(window.deferred);
|
|
wait(50, function() {
|
|
assert(window.deferred);
|
|
});
|
|
}},
|
|
|
|
testFunctionMethodize: function() { with(this) {
|
|
var Foo = { bar: function(baz) { return baz } };
|
|
var baz = { quux: Foo.bar.methodize() };
|
|
|
|
assertEqual(Foo.bar.methodize(), baz.quux);
|
|
assertEqual(baz, Foo.bar(baz));
|
|
assertEqual(baz, baz.quux());
|
|
}},
|
|
|
|
testObjectInspect: function() { with(this) {
|
|
assertEqual('undefined', Object.inspect());
|
|
assertEqual('undefined', Object.inspect(undefined));
|
|
assertEqual('null', Object.inspect(null));
|
|
assertEqual("'foo\\\\b\\\'ar'", Object.inspect('foo\\b\'ar'));
|
|
assertEqual('[]', Object.inspect([]));
|
|
}},
|
|
|
|
testObjectToJSON: function() { with(this) {
|
|
assertUndefined(Object.toJSON(undefined));
|
|
assertUndefined(Object.toJSON(Prototype.K));
|
|
assertEqual('\"\"', Object.toJSON(''));
|
|
assertEqual('[]', Object.toJSON([]));
|
|
assertEqual('[\"a\"]', Object.toJSON(['a']));
|
|
assertEqual('[\"a\", 1]', Object.toJSON(['a', 1]));
|
|
assertEqual('[\"a\", {\"b\": null}]', Object.toJSON(['a', {'b': null}]));
|
|
assertEqual('{\"a\": \"hello!\"}', Object.toJSON({a: 'hello!'}));
|
|
assertEqual('{}', Object.toJSON({}));
|
|
assertEqual('{}', Object.toJSON({a: undefined, b: undefined, c: Prototype.K}));
|
|
assertEqual('{\"b\": [false, true], \"c\": {\"a\": \"hello!\"}}',
|
|
Object.toJSON({'b': [undefined, false, true, undefined], c: {a: 'hello!'}}));
|
|
assertEqual('{\"b\": [false, true], \"c\": {\"a\": \"hello!\"}}',
|
|
Object.toJSON($H({'b': [undefined, false, true, undefined], c: {a: 'hello!'}})));
|
|
assertEqual('true', Object.toJSON(true));
|
|
assertEqual('false', Object.toJSON(false));
|
|
assertEqual('null', Object.toJSON(null));
|
|
var sam = new Person('sam');
|
|
assertEqual('-sam', Object.toJSON(sam));
|
|
assertEqual('-sam', sam.toJSON());
|
|
var element = $('test');
|
|
assertUndefined(Object.toJSON(element));
|
|
element.toJSON = function(){return 'I\'m a div with id test'};
|
|
assertEqual('I\'m a div with id test', Object.toJSON(element));
|
|
}},
|
|
|
|
testObjectToHTML: function() { with(this) {
|
|
assertIdentical('', Object.toHTML());
|
|
assertIdentical('', Object.toHTML(''));
|
|
assertIdentical('', Object.toHTML(null));
|
|
assertIdentical('0', Object.toHTML(0));
|
|
assertIdentical('123', Object.toHTML(123));
|
|
assertEqual('hello world', Object.toHTML('hello world'));
|
|
assertEqual('hello world', Object.toHTML({toHTML: function() { return 'hello world' }}));
|
|
}},
|
|
|
|
testObjectIsArray: function() { with(this) {
|
|
assert(Object.isArray([]));
|
|
assert(Object.isArray([0]));
|
|
assert(Object.isArray([0, 1]));
|
|
assert(!Object.isArray({}));
|
|
}},
|
|
|
|
testObjectIsElement: function() { with(this) {
|
|
assert(Object.isElement(document.createElement('div')));
|
|
assert(Object.isElement(new Element('div')));
|
|
assert(Object.isElement($('testlog')));
|
|
assert(!Object.isElement(document.createTextNode('bla')));
|
|
}},
|
|
|
|
testObjectIsFunction: function() { with(this) {
|
|
assert(Object.isFunction(function() { }));
|
|
assert(Object.isFunction(Class.create()));
|
|
assert(!Object.isFunction("a string"));
|
|
assert(!Object.isFunction($("testlog")));
|
|
assert(!Object.isFunction([]));
|
|
assert(!Object.isFunction({}));
|
|
assert(!Object.isFunction(0));
|
|
assert(!Object.isFunction(false));
|
|
assert(!Object.isFunction(undefined));
|
|
}},
|
|
|
|
testObjectIsString: function() { with(this) {
|
|
assert(!Object.isString(function() { }));
|
|
assert(Object.isString("a string"));
|
|
assert(!Object.isString(0));
|
|
assert(!Object.isString([]));
|
|
assert(!Object.isString({}));
|
|
assert(!Object.isString(false));
|
|
assert(!Object.isString(undefined));
|
|
}},
|
|
|
|
testObjectIsNumber: function() { with(this) {
|
|
assert(Object.isNumber(0));
|
|
assert(Object.isNumber(1.0));
|
|
assert(!Object.isNumber(function() { }));
|
|
assert(!Object.isNumber("a string"));
|
|
assert(!Object.isNumber([]));
|
|
assert(!Object.isNumber({}));
|
|
assert(!Object.isNumber(false));
|
|
assert(!Object.isNumber(undefined));
|
|
}},
|
|
|
|
testObjectIsUndefined: function() { with(this) {
|
|
assert(Object.isUndefined(undefined));
|
|
assert(!Object.isUndefined(null));
|
|
assert(!Object.isUndefined(false));
|
|
assert(!Object.isUndefined(0));
|
|
assert(!Object.isUndefined(""));
|
|
assert(!Object.isUndefined(function() { }));
|
|
assert(!Object.isUndefined([]));
|
|
assert(!Object.isUndefined({}));
|
|
}},
|
|
|
|
// sanity check
|
|
testDoesntExtendObjectPrototype: function() {with(this) {
|
|
// for-in is supported with objects
|
|
var iterations = 0, obj = { a: 1, b: 2, c: 3 };
|
|
for(property in obj) iterations++;
|
|
assertEqual(3, iterations);
|
|
|
|
// for-in is not supported with arrays
|
|
iterations = 0;
|
|
var arr = [1,2,3];
|
|
for(property in arr) iterations++;
|
|
assert(iterations > 3);
|
|
}},
|
|
|
|
testPeriodicalExecuterStop: function() {with(this) {
|
|
var peEventCount = 0;
|
|
function peEventFired(pe) {
|
|
if (++peEventCount > 2) pe.stop();
|
|
}
|
|
|
|
// peEventFired will stop the PeriodicalExecuter after 3 callbacks
|
|
new PeriodicalExecuter(peEventFired, 0.05);
|
|
|
|
wait(600, function() {
|
|
assertEqual(3, peEventCount);
|
|
});
|
|
}},
|
|
|
|
testBindAsEventListener: function() {
|
|
for( var i = 0; i < 10; ++i ){
|
|
var div = document.createElement('div');
|
|
div.setAttribute('id','test-'+i);
|
|
document.body.appendChild(div);
|
|
var tobj = new TestObj();
|
|
var eventTest = { test: true };
|
|
var call = tobj.assertingEventHandler.bindAsEventListener(tobj,
|
|
this.assertEqual.bind(this, eventTest),
|
|
this.assertEqual.bind(this, arg1),
|
|
this.assertEqual.bind(this, arg2),
|
|
this.assertEqual.bind(this, arg3), arg1, arg2, arg3 );
|
|
call(eventTest);
|
|
}
|
|
},
|
|
|
|
testDateToJSON: function() {with(this) {
|
|
assertEqual('\"1969-12-31T19:00:00\"', new Date(1969, 11, 31, 19).toJSON());
|
|
}},
|
|
|
|
testRegExpEscape: function() {with(this) {
|
|
assertEqual('word', RegExp.escape('word'));
|
|
assertEqual('\\/slashes\\/', RegExp.escape('/slashes/'));
|
|
assertEqual('\\\\backslashes\\\\', RegExp.escape('\\backslashes\\'));
|
|
assertEqual('\\\\border of word', RegExp.escape('\\border of word'));
|
|
|
|
assertEqual('\\(\\?\\:non-capturing\\)', RegExp.escape('(?:non-capturing)'));
|
|
assertEqual('non-capturing', new RegExp(RegExp.escape('(?:') + '([^)]+)').exec('(?:non-capturing)')[1]);
|
|
|
|
assertEqual('\\(\\?\\=positive-lookahead\\)', RegExp.escape('(?=positive-lookahead)'));
|
|
assertEqual('positive-lookahead', new RegExp(RegExp.escape('(?=') + '([^)]+)').exec('(?=positive-lookahead)')[1]);
|
|
|
|
assertEqual('\\(\\?<\\=positive-lookbehind\\)', RegExp.escape('(?<=positive-lookbehind)'));
|
|
assertEqual('positive-lookbehind', new RegExp(RegExp.escape('(?<=') + '([^)]+)').exec('(?<=positive-lookbehind)')[1]);
|
|
|
|
assertEqual('\\(\\?\\!negative-lookahead\\)', RegExp.escape('(?!negative-lookahead)'));
|
|
assertEqual('negative-lookahead', new RegExp(RegExp.escape('(?!') + '([^)]+)').exec('(?!negative-lookahead)')[1]);
|
|
|
|
assertEqual('\\(\\?<\\!negative-lookbehind\\)', RegExp.escape('(?<!negative-lookbehind)'));
|
|
assertEqual('negative-lookbehind', new RegExp(RegExp.escape('(?<!') + '([^)]+)').exec('(?<!negative-lookbehind)')[1]);
|
|
|
|
assertEqual('\\[\\\\w\\]\\+', RegExp.escape('[\\w]+'));
|
|
assertEqual('character class', new RegExp(RegExp.escape('[') + '([^\\]]+)').exec('[character class]')[1]);
|
|
|
|
assertEqual('<div>', new RegExp(RegExp.escape('<div>')).exec('<td><div></td>')[0]);
|
|
|
|
assertEqual('false', RegExp.escape(false));
|
|
assertEqual('undefined', RegExp.escape());
|
|
assertEqual('null', RegExp.escape(null));
|
|
assertEqual('42', RegExp.escape(42));
|
|
|
|
assertEqual('\\\\n\\\\r\\\\t', RegExp.escape('\\n\\r\\t'));
|
|
assertEqual('\n\r\t', RegExp.escape('\n\r\t'));
|
|
assertEqual('\\{5,2\\}', RegExp.escape('{5,2}'));
|
|
|
|
assertEqual(
|
|
'\\/\\(\\[\\.\\*\\+\\?\\^\\=\\!\\:\\$\\{\\}\\(\\)\\|\\[\\\\\\]\\\\\\\/\\\\\\\\\\]\\)\\/g',
|
|
RegExp.escape('/([.*+?^=!:${}()|[\\]\\/\\\\])/g')
|
|
);
|
|
}},
|
|
|
|
testBrowserDetection: function() {with(this) {
|
|
var results = $H(Prototype.Browser).map(function(engine){
|
|
return engine;
|
|
}).partition(function(engine){
|
|
return engine[1] === true
|
|
});
|
|
var trues = results[0], falses = results[1];
|
|
|
|
info('User agent string is: ' + navigator.userAgent);
|
|
|
|
assert(trues.size() == 0 || trues.size() == 1,
|
|
'There should be only one or no browser detected.');
|
|
|
|
// we should have definite trues or falses here
|
|
trues.each(function(result){
|
|
assert(result[1] === true);
|
|
});
|
|
falses.each(function(result){
|
|
assert(result[1] === false);
|
|
});
|
|
|
|
if(navigator.userAgent.indexOf('AppleWebKit/') > -1) {
|
|
info('Running on WebKit');
|
|
assert(Prototype.Browser.WebKit);
|
|
}
|
|
|
|
if(!!window.opera) {
|
|
info('Running on Opera');
|
|
assert(Prototype.Browser.Opera);
|
|
}
|
|
|
|
if(!!(window.attachEvent && !window.opera)) {
|
|
info('Running on IE');
|
|
assert(Prototype.Browser.IE);
|
|
}
|
|
|
|
if(navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1) {
|
|
info('Running on Gecko');
|
|
assert(Prototype.Browser.Gecko);
|
|
}
|
|
}},
|
|
|
|
testClassCreate: function() { with(this) {
|
|
assert(Object.isFunction(Animal), 'Animal is not a constructor');
|
|
assertEnumEqual([Cat, Mouse], Animal.subclasses);
|
|
Animal.subclasses.each(function(subclass) {
|
|
assertEqual(Animal, subclass.superclass);
|
|
});
|
|
|
|
var Bird = Class.create(Animal);
|
|
assertEqual(Bird, Animal.subclasses.last());
|
|
// for..in loop (for some reason) doesn't iterate over the constructor property in top-level classes
|
|
assertEnumEqual(Object.keys(new Animal), Object.keys(new Bird).without('constructor'));
|
|
}},
|
|
|
|
testClassInstantiation: function() { with(this) {
|
|
var pet = new Animal("Nibbles");
|
|
assertEqual("Nibbles", pet.name, "property not initialized");
|
|
assertEqual('Nibbles: Hi!', pet.say('Hi!'));
|
|
assertEqual(Animal, pet.constructor, "bad constructor reference");
|
|
assertUndefined(pet.superclass);
|
|
|
|
var Empty = Class.create();
|
|
assert('object', typeof new Empty);
|
|
}},
|
|
|
|
testInheritance: function() { with(this) {
|
|
var tom = new Cat('Tom');
|
|
assertEqual(Cat, tom.constructor, "bad constructor reference");
|
|
assertEqual(Animal, tom.constructor.superclass, 'bad superclass reference');
|
|
assertEqual('Tom', tom.name);
|
|
assertEqual('Tom: meow', tom.say('meow'));
|
|
assertEqual('Tom: Yuk! I only eat mice.', tom.eat(new Animal));
|
|
}},
|
|
|
|
testSuperclassMethodCall: function() { with(this) {
|
|
var tom = new Cat('Tom');
|
|
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";
|
|
}
|
|
});
|
|
|
|
var gonzo = new Dodo('Gonzo');
|
|
assertEqual('Gonzo', gonzo.name);
|
|
assert(gonzo.extinct, 'Dodo birds should be extinct');
|
|
assertEqual("Gonzo: hello honk honk", gonzo.say("hello"));
|
|
}},
|
|
|
|
testClassExtend: function() { with(this) {
|
|
var tom = new Cat('Tom');
|
|
var jerry = new Mouse('Jerry');
|
|
|
|
Class.extend(Animal, {
|
|
sleep: function() {
|
|
return this.say('ZZZ');
|
|
}
|
|
});
|
|
|
|
Class.extend(Mouse, {
|
|
sleep: function($super) {
|
|
return $super() + " ... no, can't sleep! Gotta steal cheese!";
|
|
}
|
|
});
|
|
|
|
assertEqual('Tom: ZZZ', tom.sleep(), "added instance method not available to subclass");
|
|
assertEqual("Jerry: ZZZ ... no, can't sleep! Gotta steal cheese!", jerry.sleep());
|
|
|
|
Class.extend(Animal, {
|
|
sleep: function() {
|
|
return this.say('zZzZ');
|
|
}
|
|
});
|
|
|
|
assertEqual("Jerry: zZzZ ... no, can't sleep! Gotta steal cheese!", jerry.sleep());
|
|
}}
|
|
|
|
}, 'testlog');
|
|
|
|
// ]]>
|
|
</script>
|
|
</body>
|
|
</html>
|