<html>
<head>
<title>Arrow</title>
<style type="text/css">
.test-ok {
color: green;
}
.test-ng {
color: red;
}
</style>
</head>
<body>
<script type="text/javascript" src="Arrow.js"></script>
<script type="text/javascript">
function test(f) {
if (!test.tests) {
test.tests = [];
window.onload = function() {
test.element = document.body;
for (var i = 0; i < test.tests.length; i++) {
test.currentGroup = test.tests[i].group;
var groupID = 'test-' + test.currentGroup.replace(/ /g, '-').toLowerCase();
test.element = document.getElementById(groupID);
if (!test.element) {
var heading = document.createElement('h2');
heading.innerHTML = test.currentGroup;
heading.onclick = function() {
var display = this.nextSibling.style.display;
this.nextSibling.style.display = (display == 'none' ? '' : 'none');
}
heading.style.cursor = 'pointer';
document.body.appendChild(heading);
test.element = document.createElement('div');
test.element.id = groupID;
test.element = document.body.appendChild(test.element);
}
try {
test.tests[i].proc();
} catch (e) {
ok(false, decamelize(functionName(test.tests[i].proc)), e);
}
var elements = test.tests[i]._elements;
for (var j = 0; elements && j < elements.length; j++) {
elements[j].parentNode.removeChild(elements[j]);
}
}
}
}
test.tests.push({ group: test.currentGroup, proc: f });
}
function testGroup(group) {
test.currentGroup = group;
}
function ok(a, text, description) {
text = text || decamelize(functionName(arguments.callee.caller));
var msg = test.element.appendChild(document.createElement('span'));
msg.appendChild(document.createTextNode((a ? 'ok' : 'ng') + ' - ' + text));
msg.appendChild(document.createElement('br'));
if (description) {
msg.appendChild(document.createTextNode(' :: '))
msg.appendChild(document.createTextNode(description.description || description))
msg.appendChild(document.createElement('br'));
}
msg.className = (a ? 'test-ok' : 'test-ng');
var heading = test.element.previousSibling;
if (heading) {
heading.innerHTML += '<span class="' + msg.className + '">' + (a ? '+' : '-') + '</span>';
}
}
function is(a, b, text) {
text = text || decamelize(functionName(arguments.callee.caller));
var is = equals(a, b);
ok(is, text, !is && ('expected ' + b + ', got ' + a));
}
function isnt(a, b, text) {
text = text || decamelize(functionName(arguments.callee.caller));
var is = equals(a, b);
ok(!is, text);
}
function functionName(func) {
if (func) {
return func.name || func.toString().match(/function (\w+)/)[1];
} else {
return '';
}
}
function decamelize(str) {
return str.split(/(?=[A-Z][a-z]+)/).join(' ').toLowerCase().replace(/[_]/g, ' ');
}
function equals(a, b) {
if (a instanceof Array && b instanceof Array) {
for (var i = 0; i < a.length && i < b.length; i++)
if (a[i] != b[i])
return false;
return true;
} else {
return a == b;
}
}
function _element(tag) {
var element = test.element.appendChild(document.createElement(tag));
if (!arguments.callee.caller._elements)
arguments.callee.caller._elements = [];
arguments.callee.caller._elements.push(element);
return element;
}
function _clearElements() {
var elements = arguments.callee.caller._elements;
for (var i = 0; i < elements.length; i++) {
elements[i].parentNode && elements[i].parentNode.removeChild(elements[i]);
}
}
var a1 = Arrow.Const(1);
var a2 = Arrow.Const(2);
var a3 = Arrow.Const(3);
var aFail = Arrow(function() { throw 'aFail exception not caught' });
var aPlus1 = Arrow(function(x) { return x + 1 });
var aMul3 = Arrow(function(x) { return x * 3 });
testGroup('Basic methods');
test(function simpleArrow() {
is(a1.call(), 1);
});
test(function connectedArrows() {
is((a1)['>>>'](aPlus1).call(), 2);
});
test(function threeConnectedArrows() {
is((a1)['>>>'](aPlus1)['>>>'](aMul3).call(), 6);
});
test(function forkArrows() {
is((a1)['>>>']((aPlus1)['&&&'](aMul3)).call(), [2, 3]);
});
test(function paralellArrows3() {
is((a1)['&&&'](a2)['&&&'](a3).call(), [1, 2, 3]);
});
test(function combineArrows() {
is(((a1)['&&&'](a1))['>>>']((aPlus1)['***'](aMul3)).call(), [2, 3]);
});
test(function chooseArrow() {
var x = (Arrow.Const(Arrow.Value.In(0)(1)))['>>>']((a1)['|||'](a2))['>>>']((aPlus1)['|||'](aPlus1)).call()
is(x.index, 0);
is(x.value, 2);
});
test(function joinArrow() {
is((a1)['>>>']((a1)['+++'](a2)).call(), 1);
is((aFail)['>>>']((a1)['+++'](a2)).call(), 2);
});
testGroup('Asynchronous arrows');
test(function delayedArrow() {
(a1)['>>>'](Arrow.Delay(500))['>>>'](function(x) { is(x, 1, 'delayed arrow') }).call();
});
test(function chooseArrow() {
(
((Arrow.Delay(1))['>>>'](a1))
['<+>']
((Arrow.Delay(1000))['>>>'](a2))
)
['>>>']
(Arrow(function(x) { is(x, 1, 'faster arrow is chosen') })).call();
});
test(function clickEvent() {
(Arrow.Event(document, 'click'))
['>>>']
(function(e) { is(e.type, 'click', 'click event') }).call();
});
test(function keypressAndMousemoveEvent() {
(Arrow.Event(document, 'keypress'))
['>>>']
(function(e) {
var key = String.fromCharCode(e.charCode || e.keyCode);
is(e.type, 'keypress', 'keypress event [' + key + '] - then move mouse');
return key;
})
['>>>']
((Arrow.Identity)['&&&'](Arrow.Event(document, 'mousemove')))
['>>>']
(function(x) {
var key = x[0], e = x[1];
is(e.type, 'mousemove', 'keypress [' + key + '] and mouesmove event')
}).call();
});
test(function xhrArrow() {
(Arrow.XHR('http://www.example.com/'))
['>>>']
(
(Arrow(function(xhr) { ng(xhr, 'XHR arrow should not success') }))
['+++']
(Arrow(function(e) { ok(e, 'XHR arrow fail route') }))
).call();
});
test(function jsonpArrow() {
var url = 'http://d.hatena.ne.jp/motemen/20080514/1210751236';
(Arrow.JSONP('http://s.hatena.ne.jp/entries.json?uri=' + url))
['>>>']
(
(Arrow(function(json) { is(json.entries[0].uri, url, 'JSONP arrow') }))
['+++']
(Arrow(function(e) { ok(e, 'JSONP failed: ' + e) }))
)
.call();
});
</script>
</body>
</html>