Commit 80cef69a authored by Sindre Sorhus's avatar Sindre Sorhus

Merge pull request #238 from cujojs/cujo-pull-2

Update to latest cujo libs, remove unnecessary files
parents 90bb5cdc 65fa7403
......@@ -18,9 +18,11 @@ Some things we feel are interesting about cujojs's TodoMVC as compared to other
* HTML template (template.html)
* CSS file, typically unthemed (structure.css)
* HTML templates are clean and simple, editable by mere mortals.
* OOCSS is used for visual state changes
* zero direct style manipulation
* drastically simplifies HTML templates
* OOCSS principles
* Separates structural CSS from theme (skin)
* visual state changes done via CSS
* zero direct style manipulation
* drastically simplifies HTML templates
* JavaScript environment is shimmed, rather than abstracted
* code to modern standards, not to abstraction layers
* All strings are easily internationalized
......@@ -29,4 +31,4 @@ Some things we feel are interesting about cujojs's TodoMVC as compared to other
transparently. Things that can happen before DOMReady, do.
Things that can't, don't.
* DOM Query engine
* DOM Event library
\ No newline at end of file
* DOM Event library
......@@ -18,8 +18,6 @@
#clear-completed {
opacity: 1;
/* TODO: this is theme/skin. Move to a theme file */
-webkit-transition: all .1s ease;
}
.completed-zero #clear-completed {
opacity: 0;
......
define({
// Cujo uses OOCSS principles and thus separates theme (skin)
// from structure CSS.
theme: { module: 'css!theme/base.css' },
// The root node where all the views will be inserted
root: { $ref: 'dom!todoapp' },
......
......@@ -3,6 +3,7 @@
var config = {
baseUrl: 'app',
paths: {
theme: '../theme',
curl: '../lib/curl/src/curl'
},
pluginPath: 'curl/plugin',
......
[submodule "test/util"]
path = test/util
url = https://github.com/dojo/util.git
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>after Unit Tests</title>
<script type="text/javascript" src="util/doh/runner.js"></script>
<script type="text/javascript" src="../aop.js"></script>
<script type="text/javascript">
(function(global, doh, aop, undef) {
var arg = "foo"; // const
// Test fixture
function Fixture(shouldThrow) {
this.val = 0;
this.shouldThrow = shouldThrow;
}
Fixture.prototype = {
method: function(a) {
this.val++;
if(this.shouldThrow) {
throw new Error('testing after advice with throw');
}
return this.val;
}
};
doh.register('after', [
function testAfterReturn1() {
var target = new Fixture();
// Starting value
doh.assertEqual(0, target.val);
aop.after(target, 'method', function afterAdvice(a) {
// this should be the advised object
doh.assertEqual(target, this);
// arg should be the return value from the orig method
doh.assertEqual(this.val, a);
// after function should be called (duh) after
// the original, so val will have changed.
doh.assertEqual(1, this.val);
});
var ret = target.method(arg);
// after method call, val should have changed
doh.assertEqual(1, target.val);
// Make sure the return value is preserved
doh.assertEqual(ret, target.val);
},
function testAfterThrow1() {
var target = new Fixture(true);
// Starting value
doh.assertEqual(0, target.val);
aop.after(target, 'method', function afterAdvice(a) {
// this should be the advised object
doh.assertEqual(target, this);
// arg should be the exception that was thrown
doh.assertTrue(a instanceof Error);
// after function should be called (duh) after
// the original, so val will have changed.
doh.assertEqual(1, this.val);
});
try {
target.method(arg);
doh.assertTrue(false);
} catch(e) {}
// after method call, val should have changed
doh.assertEqual(1, target.val);
}
]);
doh.run();
})(window, doh, aop);
</script>
</head>
<body>
</body>
</html>
\ No newline at end of file
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>afterReturning Unit Tests</title>
<script type="text/javascript" src="util/doh/runner.js"></script>
<script type="text/javascript" src="../aop.js"></script>
<script type="text/javascript">
(function(global, doh, aop, undef) {
var arg = "foo"; // const
// Test fixture
function Fixture() {
this.val = 0;
}
Fixture.prototype = {
method: function(a) {
this.val++;
return this.val;
}
};
doh.register('afterReturning', [
function testAfterReturning1() {
var target = new Fixture();
// Starting value
doh.assertEqual(0, target.val);
aop.afterReturning(target, 'method', function afterReturning1(a) {
// this should be the advised object
doh.assertEqual(target, this);
// arg should be the return value from the orig method
doh.assertEqual(this.val, a);
// after function should be called (duh) after
// the original, so val will have changed.
doh.assertEqual(1, this.val);
});
var ret = target.method(arg);
// after method call, val should have changed
doh.assertEqual(1, target.val);
// Make sure the return value is preserved
doh.assertEqual(ret, target.val);
},
function testAfterReturning2() {
var target = new Fixture();
var count = 0;
// Add 3 advices and test their invocation order,
// args, and return value
// Starting value
doh.assertEqual(0, target.val);
aop.afterReturning(target, 'method', function afterReturning0(a) {
// this should be the advised object
doh.assertEqual(target, this);
// arg should be the return value from the orig method
doh.assertEqual(this.val, a);
// after function should be called (duh) after
// the original, so val will have changed.
doh.assertEqual(1, this.val);
// after* advice is stacked left to right such that advice added
// later is called later, so count should not have
// been incremented yet.
doh.assertEqual(0, count);
// Increment count so it can be verified in next advice
count++;
});
aop.afterReturning(target, 'method', function afterReturning1(a) {
// this should be the advised object
doh.assertEqual(target, this);
// arg should be the return value from the orig method
doh.assertEqual(this.val, a);
// after function should be called (duh) after
// the original, so val will have changed.
doh.assertEqual(1, this.val);
doh.assertEqual(1, count);
// Increment count so it can be verified in next advice
count++;
});
aop.afterReturning(target, 'method', function afterReturning2(a) {
// this should be the advised object
doh.assertEqual(target, this);
// arg should be the return value from the orig method
doh.assertEqual(this.val, a);
// after function should be called (duh) after
// the original, so val will have changed.
doh.assertEqual(1, this.val);
doh.assertEqual(2, count);
});
var ret = target.method(arg);
// original method should only have been called once, so
// val should only be 1.
doh.assertEqual(1, target.val);
// Make sure the return value is preserved
doh.assertEqual(ret, target.val);
}
]);
doh.run();
})(window, doh, aop);
</script>
</head>
<body>
</body>
</html>
\ No newline at end of file
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>afterThrowing Unit Tests</title>
<script type="text/javascript" src="util/doh/runner.js"></script>
<script type="text/javascript" src="../aop.js"></script>
<script type="text/javascript">
(function(global, doh, aop, undef) {
var arg = "foo"; // const
// Test fixture
function Fixture() {
this.val = 0;
}
Fixture.prototype = {
method: function(a) {
this.val++;
throw new Error('testing afterThrowing');
}
};
doh.register('afterThrowing', [
function testAfterReturning1() {
var target = new Fixture();
// Starting value
doh.assertEqual(0, target.val);
aop.afterThrowing(target, 'method', function afterReturning1(a) {
// this should be the advised object
doh.assertEqual(target, this);
// arg should be the exception that was thrown
doh.assertTrue(a instanceof Error);
// after function should be called (duh) after
// the original, so val will have changed.
doh.assertEqual(1, this.val);
});
try {
target.method(arg);
doh.assertTrue(false);
} catch(e) {}
// after method call, val should have changed
doh.assertEqual(1, target.val);
},
function testAfterReturning2() {
var target = new Fixture();
var count = 0;
// Add 3 advices and test their invocation order,
// args, and return value
// Starting value
doh.assertEqual(0, target.val);
aop.afterThrowing(target, 'method', function afterReturning0(a) {
// this should be the advised object
doh.assertEqual(target, this);
// arg should be the exception that was thrown
doh.assertTrue(a instanceof Error);
// after function should be called (duh) after
// the original, so val will have changed.
doh.assertEqual(1, this.val);
// after* advice is stacked left to right such that advice added
// later is called later, so count should not have
// been incremented yet.
doh.assertEqual(0, count);
// Increment count so it can be verified in next advice
count++;
});
aop.afterThrowing(target, 'method', function afterReturning1(a) {
// this should be the advised object
doh.assertEqual(target, this);
// arg should be the exception that was thrown
doh.assertTrue(a instanceof Error);
// after function should be called (duh) after
// the original, so val will have changed.
doh.assertEqual(1, this.val);
doh.assertEqual(1, count);
// Increment count so it can be verified in next advice
count++;
});
aop.afterThrowing(target, 'method', function afterReturning2(a) {
// this should be the advised object
doh.assertEqual(target, this);
// arg should be the exception that was thrown
doh.assertTrue(a instanceof Error);
// after function should be called (duh) after
// the original, so val will have changed.
doh.assertEqual(1, this.val);
doh.assertEqual(2, count);
});
try {
target.method(arg);
doh.assertTrue(false);
} catch(e) {}
// after method call, val should have changed
doh.assertEqual(1, target.val);
}
]);
doh.run();
})(window, doh, aop);
</script>
</head>
<body>
</body>
</html>
\ No newline at end of file
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>All Unit Tests</title>
<meta http-equiv="REFRESH" content="0;url=util/doh/runner.html?testUrl=../../all">
</head>
<body>
<div id="testBody"></div>
</body>
</html>
\ No newline at end of file
// DOH seems to faily consistently on the first test suite, so I'm putting
// in this fake suite so it will fail and all the real tests results will
// be meaningful.
doh.registerUrl('_fake', '../../_fake-doh.html');
// Real tests
// Basic advice
doh.registerUrl('before', '../../before.html');
doh.registerUrl('around', '../../around.html');
doh.registerUrl('on', '../../on.html');
doh.registerUrl('afterReturning', '../../afterReturning.html');
doh.registerUrl('afterThrowing', '../../afterThrowing.html');
doh.registerUrl('after', '../../after.html');
// Pointcuts
doh.registerUrl('pointcut', '../../pointcut.html');
doh.registerUrl('prototype', '../../prototype.html');
// Remove
doh.registerUrl('remove', '../../remove.html');
// Go
doh.run();
\ No newline at end of file
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>around Unit Tests</title>
<script type="text/javascript" src="util/doh/runner.js"></script>
<script type="text/javascript" src="../aop.js"></script>
<script type="text/javascript">
(function(global, doh, aop, undef) {
var arg = 1; // const
// Test fixture
function Fixture(shouldThrow) {
this.val = 0;
this.shouldThrow = shouldThrow;
}
Fixture.prototype = {
method: function(add) {
this.val += add;
if(this.shouldThrow) {
throw new Error('testing around advice with throw');
}
return this.val;
}
};
doh.register('around', [
function testAround() {
var target = new Fixture();
// Starting value
doh.assertEqual(0, target.val);
aop.around(target, 'method', function aroundAdvice(joinpoint) {
// this should be the advised object
doh.assertEqual(target, this);
doh.assertEqual(target, joinpoint.target);
// arg should be the return value from the orig method
doh.assertEqual(1, joinpoint.args.length);
doh.assertEqual(arg, joinpoint.args[0]);
// after function should be called (duh) after
// the original, so val will have changed.
doh.assertEqual(0, this.val);
var ret = joinpoint.proceed();
doh.assertEqual(1, ret);
doh.assertEqual(1, this.val);
return ret;
});
var ret = target.method(arg);
// after method call, val should have changed
doh.assertEqual(1, target.val);
// Make sure the return value is preserved
doh.assertEqual(1, ret);
},
function testAroundMultipleProceedShouldFail() {
var target = new Fixture();
aop.around(target, 'method', function aroundAdvice(joinpoint) {
// Calling joinpoint.proceed() multiple times should fail
var ret, success;
ret = joinpoint.proceed();
success = false;
try {
ret = joinpoint.proceed();
} catch(e) {
success = true;
}
doh.assertTrue(success);
return ret;
});
target.method(arg);
},
function testMultipleAround() {
var target = new Fixture();
var count = 0;
// Around advice should "stack" in layers from inner to outer
// Inner
aop.around(target, 'method', function aroundAdviceInner(joinpoint) {
// Verify the outer around has been called
doh.assertEqual(1, count);
// This will proceed to the original method
joinpoint.proceed();
// Verify no more arounds have been called
doh.assertEqual(1, count);
// Indicate this inner around has been called
count++;
});
// Outer
aop.around(target, 'method', function aroundAdviceOuter(joinpoint) {
// Verify this is the first around advice to be called
doh.assertEqual(0, count);
count++;
// This will proceed to the inner around
joinpoint.proceed();
// Verify that the inner around around has been called
doh.assertEqual(2, count);
});
target.method(arg);
},
function testAroundModifyArgs() {
var target = new Fixture();
// Starting value
doh.assertEqual(0, target.val);
aop.around(target, 'method', function aroundAdvice(joinpoint) {
// arg should be the return value from the orig method
doh.assertEqual(1, joinpoint.args.length);
doh.assertEqual(arg, joinpoint.args[0]);
// after function should be called (duh) after
// the original, so val will have changed.
doh.assertEqual(0, this.val);
// Modify the original args and pass them through to
// the original func
var modifiedArgs = [10];
var ret = joinpoint.proceed(modifiedArgs);
doh.assertEqual(10, ret);
doh.assertEqual(10, this.val);
return ret;
});
var ret = target.method(arg);
// after method call, val should have changed based on the modified args
doh.assertEqual(10, target.val);
// Make sure the return value is preserved, also based on the modified args
doh.assertEqual(10, ret);
},
function testAroundModifyReturnVal() {
var target = new Fixture();
// Starting value
doh.assertEqual(0, target.val);
aop.around(target, 'method', function aroundAdvice(joinpoint) {
joinpoint.proceed();
return 10;
});
var ret = target.method(arg);
// after method call, val should be 1, since original args were
// not modified.
doh.assertEqual(1, target.val);
// Make sure we got the modified return value
doh.assertEqual(10, ret);
},
function testAroundPreventOriginal() {
var target = new Fixture();
// Starting value
doh.assertEqual(0, target.val);
aop.around(target, 'method', function aroundAdvice(joinpoint) {
// Intentionally do not proceed to original method
// var ret = joinpoint.proceed();
return this.val;
});
var ret = target.method(arg);
// after method call, val should have changed
doh.assertEqual(0, target.val);
// Make sure the return value is preserved
doh.assertEqual(0, ret);
}
]);
doh.run();
})(window, doh, aop);
</script>
</head>
<body>
</body>
</html>
\ No newline at end of file
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>before Unit Tests</title>
<script type="text/javascript" src="util/doh/runner.js"></script>
<script type="text/javascript" src="../aop.js"></script>
<script type="text/javascript">
(function(global, doh, aop, undef) {
var arg = "foo"; // const
// Test fixture
function Fixture() {
this.val = 0;
}
Fixture.prototype = {
method: function(a) {
return (++this.val);
}
};
doh.register('before', [
function testBefore1() {
var target = new Fixture();
aop.before(target, 'method', function before1(a) {
// this should be the advised object
doh.assertEqual(target, this);
// arg should not change
doh.assertEqual(arg, a);
// before function should be called (duh) before
// the original, so val should not have changed yet.
doh.assertEqual(0, this.val);
});
var ret = target.method(arg);
// after method call, val should have changed
doh.assertEqual(1, target.val);
// Make sure the return value is preserved
doh.assertEqual(ret, target.val);
},
function testBefore2() {
var target = new Fixture();
var beforeCount = 0;
// Add 3 before advices and test their invocation order,
// args, and return value
aop.before(target, 'method', function before0(a) {
doh.assertEqual(target, this);
doh.assertEqual(arg, a);
// *ALL* before functions should be called (duh) before
// the original, so val should not have changed yet.
doh.assertEqual(0, this.val);
// Before advice is stacked such that advice added
// later is called first, so beforeCount should have
// been incremented.
doh.assertEqual(2, beforeCount);
});
aop.before(target, 'method', function before1(a) {
doh.assertEqual(target, this);
doh.assertEqual(arg, a);
// *ALL* before functions should be called (duh) before
// the original, so val should not have changed yet.
doh.assertEqual(0, this.val);
// Before advice is stacked "right to left", such that
// advice added later is called first, so before2
// should be called earlier than before1, and beforeCount
// should have been incremented.
doh.assertEqual(1, beforeCount);
// Increment beforeCount so it can be verified in before0
beforeCount++;
});
aop.before(target, 'method', function before2(a) {
doh.assertEqual(target, this);
doh.assertEqual(arg, a);
// *ALL* before functions should be called (duh) before
// the original, so val should not have changed yet.
doh.assertEqual(0, this.val);
// before2 should be called first, so beforeCount should
// be zero.
doh.assertEqual(0, beforeCount);
// Increment beforeCount so it can be verified in before1
beforeCount++;
});
var ret = target.method(arg);
// original method should only have been called once, so
// val should only be 1.
doh.assertEqual(1, target.val);
// Make sure the return value is preserved
doh.assertEqual(ret, target.val);
}
]);
doh.run();
})(window, doh, aop);
</script>
</head>
<body>
</body>
</html>
\ No newline at end of file
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>on Unit Tests</title>
<script type="text/javascript" src="util/doh/runner.js"></script>
<script type="text/javascript" src="../aop.js"></script>
<script type="text/javascript">
(function(global, doh, aop, undef) {
var arg = "foo"; // const
// Test fixture
function Fixture(shouldThrow) {
this.val = 0;
this.shouldThrow = shouldThrow;
}
Fixture.prototype = {
method: function(a) {
this.val++;
if(this.shouldThrow) {
throw new Error('testing after advice with throw');
}
return this.val;
}
};
doh.register('on', [
function testOn1() {
var target = new Fixture();
// Starting value
doh.assertEqual(0, target.val);
aop.on(target, 'method', function on(a) {
// this should be the advised object
doh.assertEqual(target, this);
// arg should be the return value from the orig method
doh.assertEqual(arg, a);
// on function should be called after
// the original, so val will have changed.
doh.assertEqual(1, this.val);
});
var ret = target.method(arg);
// after method call, val should have changed
doh.assertEqual(1, target.val);
// Make sure the return value is preserved
doh.assertEqual(ret, target.val);
}
]);
doh.run();
})(window, doh, aop);
</script>
</head>
<body>
</body>
</html>
\ No newline at end of file
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>Pointcut Unit Tests</title>
<script src="util/doh/runner.js"></script>
<script src="../aop.js"></script>
<script type="text/javascript">
(function(global, doh, aop, undef) {
function makeProto() {
var n, proto, i;
proto = {};
i = 0;
while((n = arguments[i++])) {
(function(n) {
proto[n] = function() { this.calls.push(n); };
})(n);
}
return proto;
}
// Test fixture
function Fixture() {
this.calls = [];
}
Fixture.prototype = makeProto('method1', 'method2', 'methodA', 'methodB', 'blah');
doh.register('pointcut', [
function testStringPointcut1() {
var target = new Fixture();
var called = 0;
function advice() { called++; }
aop.add(target, 'method1', {
before: advice,
after: advice
});
target.method1();
doh.assertEqual(2, called);
doh.assertEqual(['method1'], target.calls);
target.blah();
doh.assertEqual(2, called);
doh.assertEqual(['method1', 'blah'], target.calls);
},
function testArrayPointcut1() {
var target = new Fixture();
var called = 0;
function advice() { called++; }
aop.add(target, ['method1', 'methodA'], {
before: advice
});
target.method1();
doh.assertEqual(1, called);
doh.assertEqual(['method1'], target.calls);
target.methodA();
doh.assertEqual(2, called);
doh.assertEqual(['method1', 'methodA'], target.calls);
target.blah();
doh.assertEqual(2, called);
doh.assertEqual(['method1', 'methodA', 'blah'], target.calls);
},
function testRegExpPointcut1() {
var target = new Fixture();
var called = 0;
function advice() { called++; }
aop.add(target, /^method(1|a)$/i, {
before: advice
});
target.method1();
doh.assertEqual(1, called);
doh.assertEqual(['method1'], target.calls);
target.methodA();
doh.assertEqual(2, called);
doh.assertEqual(['method1', 'methodA'], target.calls);
target.blah();
doh.assertEqual(2, called);
doh.assertEqual(['method1', 'methodA', 'blah'], target.calls);
},
function testFunctionPointcut1() {
var target = new Fixture();
var called = 0;
function advice() { called++; }
function pointcut(target) {
return ['method1', 'methodA'];
}
aop.add(target, pointcut, {
before: advice
});
target.method1();
doh.assertEqual(1, called);
doh.assertEqual(['method1'], target.calls);
target.methodA();
doh.assertEqual(2, called);
doh.assertEqual(['method1', 'methodA'], target.calls);
target.blah();
doh.assertEqual(2, called);
doh.assertEqual(['method1', 'methodA', 'blah'], target.calls);
}
]);
doh.run();
})(window, doh, aop);
</script>
</head>
<body>
</body>
</html>
\ No newline at end of file
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>Prototype AOP Unit Tests</title>
<script src="util/doh/runner.js"></script>
<script src="../aop.js"></script>
<script type="text/javascript">
(function(global, doh, aop, undef) {
function makeProto() {
var n, proto, i;
proto = {};
i = 0;
while((n = arguments[i++])) {
(function(n) {
proto[n] = function() { this.calls.push(n); };
})(n);
}
return proto;
}
// Test fixture
function Fixture() {
this.calls = [];
}
Fixture.prototype = makeProto('method1', 'method2', 'methodA', 'methodB', 'blah');
doh.register('prototype', [
function testStringPrototype1() {
var target = new Fixture();
var called = 0;
function advice() { called++; }
aop.add(Fixture, 'method1', {
before: advice,
after: advice
});
target.method1();
doh.assertEqual(2, called);
doh.assertEqual(['method1'], target.calls);
target.blah();
doh.assertEqual(2, called);
doh.assertEqual(['method1', 'blah'], target.calls);
},
function testArrayPrototype1() {
var target = new Fixture();
var called = 0;
function advice() { called++; }
aop.add(Fixture, ['method1', 'methodA'], {
before: advice
});
target.method1();
doh.assertEqual(1, called);
doh.assertEqual(['method1'], target.calls);
target.methodA();
doh.assertEqual(2, called);
doh.assertEqual(['method1', 'methodA'], target.calls);
target.blah();
doh.assertEqual(2, called);
doh.assertEqual(['method1', 'methodA', 'blah'], target.calls);
},
function testRegExpPrototype1() {
var target = new Fixture();
var called = 0;
function advice() { called++; }
aop.add(Fixture, /^method(1|a)$/i, {
before: advice
});
target.method1();
doh.assertEqual(1, called);
doh.assertEqual(['method1'], target.calls);
target.methodA();
doh.assertEqual(2, called);
doh.assertEqual(['method1', 'methodA'], target.calls);
target.blah();
doh.assertEqual(2, called);
doh.assertEqual(['method1', 'methodA', 'blah'], target.calls);
},
function testFunctionPrototype1() {
var target = new Fixture();
var called = 0;
function advice() { called++; }
function pointcut(target) {
return ['method1', 'methodA'];
}
aop.add(Fixture, pointcut, {
before: advice
});
target.method1();
doh.assertEqual(1, called);
doh.assertEqual(['method1'], target.calls);
target.methodA();
doh.assertEqual(2, called);
doh.assertEqual(['method1', 'methodA'], target.calls);
target.blah();
doh.assertEqual(2, called);
doh.assertEqual(['method1', 'methodA', 'blah'], target.calls);
}
]);
doh.run();
})(window, doh, aop);
</script>
</head>
<body>
</body>
</html>
\ No newline at end of file
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>remove aspect Unit Tests</title>
<script type="text/javascript" src="util/doh/runner.js"></script>
<script type="text/javascript" src="../aop.js"></script>
<script type="text/javascript">
(function(global, doh, aop, undef) {
function Fixture() { this.count = 0; }
Fixture.prototype.method = function() {}
function increment(joinpoint) {
this.count++;
if(joinpoint) {
joinpoint.proceed();
}
}
doh.register('remove', [
function testRemove() {
// Just test that the advisor is added, and then
// removed when the final aspect is removed
var fixture, ref;
fixture = new Fixture();
ref = aop.before(fixture, 'method', increment);
doh.assertTrue(!!fixture.method._advisor);
ref.remove();
doh.assertEqual(undef, fixture.method._advisor);
},
function testRemove1() {
var fixture, ref;
fixture = new Fixture();
ref = aop.before(fixture, 'method', increment);
fixture.method();
// after method call, val should have changed
doh.assertEqual(1, fixture.count);
ref.remove();
fixture.method();
// after removing, advice should not be called
// again, so count should not have changed
doh.assertEqual(1, fixture.count);
},
function testRemoveAround() {
var fixture, ref;
fixture = new Fixture();
ref = aop.around(fixture, 'method', increment);
fixture.method();
// after method call, val should have changed
doh.assertEqual(1, fixture.count);
ref.remove();
fixture.method();
// after removing, advice should not be called
// again, so count should not have changed
doh.assertEqual(1, fixture.count);
},
function testRemoveAspect() {
var fixture, ref;
fixture = new Fixture();
ref = aop.add(fixture, 'method',{
before: increment,
on: increment,
around: increment,
afterReturning: increment,
after: increment
});
fixture.method();
// after method call, val should have changed
doh.assertEqual(5, fixture.count);
ref.remove();
fixture.method();
// after removing, advice should not be called
// again, so count should not have changed
doh.assertEqual(5, fixture.count);
},
function testRemoveOneFromMultiple() {
var fixture, ref;
fixture = new Fixture();
// Add 3 aspects, but only remove 1
aop.before(fixture, 'method', increment);
ref = aop.before(fixture, 'method', increment);
aop.before(fixture, 'method', increment);
fixture.method();
// after method call, val should have changed
doh.assertEqual(3, fixture.count);
ref.remove();
fixture.method();
// removed advice should not be called
doh.assertEqual(5, fixture.count);
}
]);
doh.run();
})(window, doh, aop);
</script>
</head>
<body>
</body>
</html>
\ No newline at end of file
[submodule "test/curl"]
path = test/curl
url = https://unscriptable@github.com/cujojs/curl.git
[submodule "test/util"]
path = test/util
url = https://unscriptable@github.com/cujojs/util.git
[submodule "support/when"]
path = support/when
url = https://github.com/cujojs/when.git
(function (buster, require) {
var assert, refute, undef;
assert = buster.assert;
refute = buster.refute;
var Hub = require('../Hub');
var ArrayAdapter = require('../adapter/Array');
buster.testCase('cola/Hub', {
'should not fail if not given any constructor params': function () {
refute.exception(function () {
new Hub();
});
},
'should add methods for eventNames': function () {
var h = new Hub();
// this isn't a complete list, but proves the mechanism basically works
assert.isObject(h);
assert.isFunction(h.add);
assert.isFunction(h.beforeAdd);
assert.isFunction(h.onAdd);
assert.isFunction(h.update);
assert.isFunction(h.beforeUpdate);
assert.isFunction(h.onUpdate);
assert.isFunction(h.remove);
assert.isFunction(h.beforeRemove);
assert.isFunction(h.onRemove);
},
'should return an adapter when calling addSource with a non-adapter': function () {
var h = new Hub();
var a = h.addSource([]);
// sniff for an adapter
assert.isObject(a);
assert.isFunction(a.add);
},
'should pass through an adapter when calling addSource with an adapter': function () {
var h = new Hub();
var adapter = new ArrayAdapter([], {});
var a = h.addSource(adapter);
// sniff for an adapter
assert.same(a, adapter);
},
'should override adapter default provide via options': function() {
var h = new Hub();
var defaultProvide = true;
var a = h.addSource([], { provide: false });
// sniff for an adapter
refute.equals(a.provide, defaultProvide);
},
'should find and add new event types from adapter': function () {
var e = {}, h = new Hub({
events: e
});
var adapter = new ArrayAdapter([]);
adapter.crazyNewEvent = function () {};
var a = h.addSource(adapter, {
eventNames: function (name) { return /^crazy/.test(name); }
});
// check for method on hub api
assert.isFunction(h.onCrazyNewEvent);
},
'should call findItem on each adapter': function () {
var e = {}, h = new Hub({
events: e
});
var adapter = new ArrayAdapter([]);
adapter.findItem = this.spy();
var a = h.addSource(adapter, {});
h.findItem();
// check that findItem was called
assert.calledOnce(adapter.findItem);
},
'should call findNode on each adapter': function () {
var e = {}, h = new Hub({
events: e
});
var adapter = new ArrayAdapter([]);
adapter.findNode = this.spy();
var a = h.addSource(adapter, {});
h.findNode();
// check that findItem was called
assert.calledOnce(adapter.findNode);
},
'should call strategy to join adapter': function () {
var strategy = this.spy();
var h = new Hub({
strategy: strategy
});
h.onJoin = this.spy();
h.addSource([]);
// strategy should be called to join primary into network
assert.calledOnce(h.onJoin);
},
'should not call events if strategy cancels event': function (done) {
var h = new Hub({
strategy: strategy
});
var primary = h.addSource([]);
var isAfterCanceled;
h.beforeAdd = this.spy();
h.onAdd = function() {
assert.calledOnce(h.beforeAdd);
done();
};
primary.name = 'primary'; // debug
primary.add({ id: 1 });
assert(isAfterCanceled, 'last event should be canceled');
function strategy (source, dest, data, type, api) {
isAfterCanceled = api.isAfterCanceled();
api.cancel();
}
},
'should run queued event in next turn': function (done) {
var h = new Hub({ strategy: strategy });
var primary = h.addSource([]);
var removeDetected;
primary.add({ id: 1 });
// ensure remove hasn't executed yet
refute.defined(removeDetected);
setTimeout(function () {
assert.defined(removeDetected);
done();
}, 100);
function strategy (source, dest, data, type, api) {
if ('add' == type) {
api.queueEvent(source, data, 'remove');
}
else if ('remove' == type) {
removeDetected = true;
}
}
},
'// should add property transforms to adapter': function () {}
});
})( require('buster'), require );
(function(buster, SortedMap) {
var assert, refute, undef;
assert = buster.assert;
refute = buster.refute;
function compareItems (a, b) {
return a.id - b.id;
}
function compareByLast (a, b) {
return a.last < b.last ? -1 : a.last > b.last ? 1 : 0;
}
function symbolizeItem (it) {
return it.id;
}
buster.testCase('SortedMap', {
'add': {
'should throw if key and value not provided': function() {
var map = new SortedMap(symbolizeItem, compareItems);
assert.exception(function() {
map.add({ id: 1});
});
},
'should add new items': function () {
var hash = new SortedMap(symbolizeItem, compareItems);
assert.equals(hash.add({ id: 1 }, 1), 0);
assert.equals(hash.add({ id: 2 }, 2), 1);
var spy = this.spy();
hash.forEach(spy);
assert.calledTwice(spy);
},
'should add very large item into last slot': function () {
var hash = new SortedMap(symbolizeItem, compareItems);
assert.equals(hash.add({ id: 1 }, 1), 0);
assert.equals(hash.add({ id: 9 }, 9), 1);
assert.equals(hash.add({ id: 99 }, 99), 2);
assert.equals(hash.add({ id: 999 }, 999), 3);
},
'should fail silently when adding an item that already exists': function () {
var hash = new SortedMap(symbolizeItem, compareItems);
hash.add({ id: 1 }, 1);
refute.defined(hash.add({ id: 1 }, 1));
},
'should add all items even when no comparator supplied': function() {
var map, count, result;
map = new SortedMap(symbolizeItem);
assert.equals(map.add({ id: 0 }, 0), 0);
assert.equals(map.add({ id: 1 }, 1), 1);
assert.equals(map.add({ id: 2 }, 2), 2);
count = 0;
result = 0;
map.forEach(function(item) {
count++;
result += item;
});
assert.equals(count, 3);
assert.equals(result, 3);
},
'should add all items even when comparator says all items are equivalent': function() {
var map, count, result;
map = new SortedMap(symbolizeItem, function() { return 0; });
assert.equals(map.add({ id: 0 }, 0), 0);
assert.equals(map.add({ id: 1 }, 1), 1);
assert.equals(map.add({ id: 2 }, 2), 2);
count = 0;
result = 0;
map.forEach(function(item) {
count++;
result += item;
});
assert.equals(count, 3);
assert.equals(result, 3);
}
},
'remove': {
'should remove items': function () {
var map = new SortedMap(symbolizeItem, compareItems);
var items = [
{ id: 1 },
{ id: 3 },
{ id: 4 },
{ id: 2 }
];
map.add(items[0], 'foo'); // id: 1
map.add(items[1], 'bar'); // id: 3
map.add(items[2], 'baz'); // id: 4
map.add(items[3], 'fot'); // id: 2
map.remove({ id: 3 });
var spy = this.spy();
map.forEach(spy);
assert.calledWith(spy, 'foo', items[0]);
refute.calledWith(spy, 'bar', items[1]);
assert.calledWith(spy, 'baz', items[2]);
assert.calledWith(spy, 'fot', items[3]);
},
'should silently fail when removing non-existent items': function () {
var map = new SortedMap(symbolizeItem, compareItems);
map.add({ id: 1 }, 1);
refute.defined(map.remove({ id: 2 }));
}
},
'clear': {
'should remove all items': function() {
var map = new SortedMap(symbolizeItem, compareItems);
map.add({ id: 1 }, 1);
map.add({ id: 2 }, 2);
map.add({ id: 3 }, 3);
map.clear();
refute.defined(map.get({ id: 1 }));
refute.defined(map.get({ id: 2 }));
refute.defined(map.get({ id: 3 }));
var spy = this.spy();
map.forEach(spy);
refute.called(spy);
}
},
'forEach': {
'should iterate over all items in order': function () {
var map = new SortedMap(symbolizeItem, compareByLast);
map.add({ id: 1, last: 'Attercop', expected: 2 }, 1);
map.add({ id: 3, last: 'TomNoddy', expected: 4 }, 2);
map.add({ id: 4, last: 'Aardvark', expected: 1 }, 3);
map.add({ id: 2, last: 'Bojangle', expected: 3 }, 4);
var count = 0, prev = 0;
map.forEach(function (value, key) {
count++;
// cheap test to see if they're in order
assert.equals(key.expected - prev, 1);
prev = key.expected;
});
assert(count == 4);
}
}
});
})(
require('buster'),
require('../SortedMap')
);
\ No newline at end of file
(function(buster, when, delay, ArrayAdapter) {
var assert, refute, undef;
assert = buster.assert;
refute = buster.refute;
function promiseFor(array) {
return delay(array, 0);
}
buster.testCase('adapter/Array', {
'canHandle': {
'should return true for an Array': function() {
assert(ArrayAdapter.canHandle([]));
},
'should return true for a promise': function() {
assert(ArrayAdapter.canHandle(when.defer().promise));
},
'should return false for a non-Array': function() {
refute(ArrayAdapter.canHandle(null));
refute(ArrayAdapter.canHandle(undef));
refute(ArrayAdapter.canHandle(0));
refute(ArrayAdapter.canHandle(true));
refute(ArrayAdapter.canHandle({ length: 1 }));
}
},
'options': {
'should be a provider by default': function() {
var a = new ArrayAdapter([]);
assert(a.provide);
},
'should allow overriding provide': function() {
var a = new ArrayAdapter([], { provide: false });
refute(a.provide);
}
},
'forEach': {
'should iterate over all items': function() {
var src, forEachSpy;
src = new ArrayAdapter([
{ id: 1 }, { id: 2 }
]);
forEachSpy = this.spy();
src.forEach(forEachSpy);
assert.calledTwice(forEachSpy);
assert.calledWith(forEachSpy, { id: 1 });
assert.calledWith(forEachSpy, { id: 2 });
},
'should iterate over all promised items': function(done) {
var src, forEachSpy;
src = new ArrayAdapter(promiseFor([
{ id: 1 }, { id: 2 }
]));
forEachSpy = this.spy();
src.forEach(forEachSpy).then(function() {
assert.calledTwice(forEachSpy);
assert.calledWith(forEachSpy, { id: 1 });
assert.calledWith(forEachSpy, { id: 2 });
done();
});
}
},
'add': {
'should add new items': function() {
var pa = new ArrayAdapter([
{ id: 1 }
]);
pa.add({ id: 2 });
var spy = this.spy();
pa.forEach(spy);
assert.calledTwice(spy);
},
'should allow adding an item that already exists': function() {
var pa = new ArrayAdapter([
{ id: 1 }
]);
var spy = this.spy();
pa.forEach(spy);
assert.calledOnce(spy);
},
'promise-aware': {
'should add new items': function(done) {
var pa, spy;
pa = new ArrayAdapter(promiseFor([
{ id: 1 }
]));
spy = this.spy();
when(pa.add({ id: 2 }),
function() {
return pa.forEach(spy);
}
).then(
function() {
assert.calledTwice(spy);
}
).then(done, done);
},
'should allow adding an item that already exists': function(done) {
var pa, spy;
pa = new ArrayAdapter(promiseFor([
{ id: 1 }
]));
spy = this.spy();
when(pa.add({ id: 1 }),
function() {
return pa.forEach(spy);
}
).then(
function() {
assert.calledOnce(spy);
}
).then(done, done);
}
}
},
'remove': {
'should remove items': function() {
var pa = new ArrayAdapter([
{ id: 1 }, { id: 2 }
]);
pa.remove({ id: 1 });
var spy = this.spy();
pa.forEach(spy);
assert.calledOnce(spy);
},
'should allow removing non-existent items': function() {
var pa = new ArrayAdapter([]);
var spy = this.spy();
pa.forEach(spy);
refute.called(spy);
},
'promise-aware': {
'should remove items': function(done) {
var pa, spy;
pa = new ArrayAdapter(promiseFor([
{ id: 1 }, { id: 2 }
]));
spy = this.spy();
when(pa.remove({ id: 2 }),
function() {
return pa.forEach(spy);
}
).then(
function() {
assert.calledOnce(spy);
}
).then(done, done);
},
'should allow removing non-existent items': function(done) {
var pa, spy;
pa = new ArrayAdapter(promiseFor([]));
spy = this.spy();
when(pa.remove({ id: 2 }),
function() {
return pa.forEach(spy);
}
).then(
function() {
refute.calledOnce(spy);
}
).then(done, done);
}
}
},
'update': {
'should update items': function() {
var pa = new ArrayAdapter([
{ id: 1, success: false }
]);
var spy = this.spy();
pa.update({ id: 1, success: true });
pa.forEach(spy);
assert.calledOnceWith(spy, { id: 1, success: true });
},
'should ignore updates to non-existent items': function() {
var pa = new ArrayAdapter([
{ id: 1, success: true }
]);
var spy = this.spy();
pa.update({ id: 2, success: false });
pa.forEach(spy);
assert.calledOnceWith(spy, { id: 1, success: true });
},
'promise-aware': {
'should update items': function(done) {
var pa, spy, expected;
pa = new ArrayAdapter(promiseFor([
{ id: 1, success: false }
]));
spy = this.spy();
expected = { id: 1, success: true };
when(pa.update(expected),
function() {
return pa.forEach(spy);
}
).then(
function() {
assert.calledOnceWith(spy, expected);
}
).then(done, done);
},
'should ignore updates to non-existent items': function(done) {
var pa, spy, expected;
expected = { id: 1, success: true };
pa = new ArrayAdapter(promiseFor([
expected
]));
spy = this.spy();
when(pa.update({ id: 2, success: false }),
function() {
return pa.forEach(spy);
}
).then(
function() {
assert.calledOnceWith(spy, expected);
}
).then(done, done);
}
}
},
'clear': {
'should remove all items': function() {
var src, forEachSpy;
src = new ArrayAdapter([
{ id: 1 }, { id: 2 }
]);
forEachSpy = this.spy();
src.clear();
src.forEach(forEachSpy);
refute.called(forEachSpy);
},
'promise-aware': {
'should remove all items': function(done) {
var src, forEachSpy;
src = new ArrayAdapter(promiseFor([
{ id: 1 }, { id: 2 }
]));
forEachSpy = this.spy();
when(src.clear(),
function() {
return src.forEach(forEachSpy);
}
).then(
function() {
refute.called(forEachSpy);
}
).then(done, done);
}
}
}
});
})(
require('buster'),
require('when'),
require('when/delay'),
require('../../adapter/Array')
);
\ No newline at end of file
(function(buster, LocalStorageAdapter) {
var assert, refute, fail;
assert = buster.assert;
refute = buster.refute;
fail = buster.assertions.fail;
function identifier(item) {
return item.id;
}
function fakeLocalStorage() {
return {
items: {},
setItem: function(key, val) {
this.items[key] = val;
},
getItem: function(key) {
return this.items[key];
},
removeItem: function(key) {
delete this.items[key];
}
}
}
buster.testCase('adapter/LocalStorage', {
'should throw when namespace not provided': function() {
assert.exception(function() {
new LocalStorageAdapter();
});
},
'should throw when localStorage not available and not provided in options': function() {
assert.exception(function() {
new LocalStorageAdapter('fail');
});
},
'forEach': {
'should iterate over zero items when empty': function() {
var storage, a, count;
storage = fakeLocalStorage();
a = new LocalStorageAdapter('test', { localStorage: storage, identifier: identifier });
count = 0;
a.forEach(function() {
++count;
});
assert.equals(count, 0);
},
'should iterate over all items': function() {
var storage, a, count;
storage = fakeLocalStorage();
a = new LocalStorageAdapter('test', { localStorage: storage, identifier: identifier });
a.add({ id: 1 });
a.add({ id: 2 });
a.add({ id: 3 });
count = 0;
a.forEach(function() {
++count;
});
assert.equals(count, 3);
}
},
'add': {
'should add items': function() {
var storage, a, count;
storage = fakeLocalStorage();
a = new LocalStorageAdapter('test', { localStorage: storage, identifier: identifier });
a.add({ id: 1 });
count = 0;
a.forEach(function(item) {
++count;
assert.equals(item, { id: 1 });
});
assert.equals(count, 1);
}
},
'update': {
'should update items': function() {
var storage, a, count;
storage = fakeLocalStorage();
a = new LocalStorageAdapter('test', { localStorage: storage, identifier: identifier });
a.add({ id: 1 });
a.update({ id: 1, success: true });
count = 0;
a.forEach(function(item) {
++count;
assert(item.success);
});
assert.equals(count, 1);
}
},
'remove': {
'should remove items': function() {
var storage, a, count;
storage = fakeLocalStorage();
a = new LocalStorageAdapter('test', { localStorage: storage, identifier: identifier });
a.add({ id: 1 });
count = 0;
a.forEach(function(item) {
++count;
assert.equals(item, { id: 1 });
});
assert.equals(count, 1);
a.remove({ id: 1 });
count = 0;
a.forEach(function() {
++count;
});
assert.equals(count, 0);
}
}
});
})(
require('buster'),
require('../../adapter/LocalStorage')
);
(function(buster, when, delay, ObjectAdapter) {
"use strict";
var assert, refute, fail;
assert = buster.assert;
refute = buster.refute;
fail = buster.assertions.fail;
function promiseFor(it) {
return delay(it, 0);
}
buster.testCase('adapter/Object', {
'options': {
'should pass options to getOptions': function () {
var bindings = {}, adaptedObject;
adaptedObject = new ObjectAdapter({}, {
bindings: bindings
});
assert.equals(bindings, adaptedObject.getOptions().bindings);
}
},
'canHandle': {
'should return true for a object literals': function () {
assert(ObjectAdapter.canHandle({}), 'object');
},
'should return true for a promise': function() {
assert(ObjectAdapter.canHandle(promiseFor({})));
},
'should return false for non-object literals': function () {
refute(ObjectAdapter.canHandle(), 'undefined');
refute(ObjectAdapter.canHandle(null), 'null');
refute(ObjectAdapter.canHandle(function(){}), 'function');
refute(ObjectAdapter.canHandle([]), 'array');
}
},
'update': {
'should update an object when update() called': function () {
var obj, adapted;
obj = { first: 'Fred', last: 'Flintstone' };
adapted = new ObjectAdapter(obj);
adapted.update({ first: 'Donna', last: 'Summer' });
assert.equals(adapted._obj.first, 'Donna');
assert.equals(adapted._obj.last, 'Summer');
},
'should update some properties when update() called with a partial': function () {
var obj, adapted;
obj = { first: 'Fred', last: 'Flintstone' };
adapted = new ObjectAdapter(obj);
adapted.update({ last: 'Astaire' });
assert.equals(adapted._obj.first, 'Fred');
assert.equals(adapted._obj.last, 'Astaire');
},
'promise-aware': {
'should update an object': function (done) {
var obj, adapted;
obj = { first: 'Fred', last: 'Flintstone' };
adapted = new ObjectAdapter(promiseFor(obj));
when(adapted.update({ first: 'Donna', last: 'Summer' }),
function() {
return when(adapted._obj, function(obj) {
assert.equals(obj.first, 'Donna');
assert.equals(obj.last, 'Summer');
});
},
fail
).then(done, done);
},
'should update supplied properties when called with a partial': function (done) {
var obj, adapted;
obj = { first: 'Fred', last: 'Flintstone' };
adapted = new ObjectAdapter(promiseFor(obj));
when(adapted.update({ last: 'Astaire' }),
function() {
return when(adapted._obj, function(obj) {
assert.equals(obj.first, 'Fred');
assert.equals(obj.last, 'Astaire');
});
},
fail
).then(done, done);
}
}
}
});
})(
require('buster'),
require('when'),
require('when/delay'),
require('../../adapter/Object')
);
(function(buster, when, delay, WidenAdapter) {
var assert, refute;
assert = buster.assert;
refute = buster.refute;
buster.testCase('adapter/ObjectToArray', {
'should throw if transform not supplied': function() {
assert.exception(function() {
new WidenAdapter({});
})
},
'forEach': {
'should iterate over all items': function() {
var a, spy;
a = new WidenAdapter(
{ array: [{ id: 1 }, { id: 2 }] },
{ transform: function(o) { return o.array; } }
);
spy = this.spy();
a.forEach(spy);
assert.calledTwice(spy);
assert.calledWith(spy, { id: 1 });
assert.calledWith(spy, { id: 2 });
}
}
});
})(
require('buster'),
require('when'),
require('when/delay'),
require('../../adapter/ObjectToArray')
);
\ No newline at end of file
(function(buster, when, QueryAdapter) {
var assert, refute, fail;
assert = buster.assert;
refute = buster.refute;
fail = buster.assertions.fail;
function promiseFor(it) {
return when(it);
}
function createDatasource() {
return {
getIdentity: function() {},
query: function() {},
add: function() {},
put: function() {},
remove: function() {}
};
}
buster.testCase('adapter/Query', {
'should throw if no datasource provided': function() {
assert.exception(function() {
new QueryAdapter();
});
},
'options': {
'should be a provider by default': function() {
var a = new QueryAdapter({});
assert(a.provide);
},
'should allow overriding provide': function() {
var a = new QueryAdapter({}, { provide: false });
refute(a.provide);
},
'should preserve bindings options': function() {
var bindings, adaptedObject;
bindings = {};
adaptedObject = new QueryAdapter({}, {
bindings: bindings
});
assert.equals(adaptedObject.getOptions().bindings, bindings);
}
},
'query': {
'should query datasource': function(done) {
var qa, ds, queryStub, added, removed;
ds = this.stub(createDatasource());
ds.query.returns(promiseFor([{ id: 1 }]));
// Have to hold onto this stub because QueryAdapter
// will replace ds.query
queryStub = ds.query;
added = this.spy();
removed = this.spy();
qa = new QueryAdapter(ds);
// TODO: Should be able to just return this, but there is an error
// in buster right now if we do. When that's fixed, we can remove
// the done() calls and just return a promise.
qa.query().then(
function() {
assert.calledOnce(queryStub);
},
fail
).then(done, done);
}
},
'add': {
'should add item to datasource': function(done) {
var ds, qa, item;
ds = this.stub(createDatasource());
ds.getIdentity.returns(1);
qa = new QueryAdapter(ds);
item = { id: 1 };
qa.add(item).then(
function() {
assert.calledOnceWith(ds.add, item);
},
fail
).then(done, done);
}
},
'remove': {
'should remove item from datasource': function(done) {
var ds, qa, item;
item = { id: 1 };
ds = this.stub(createDatasource());
ds.query.returns([item]);
ds.getIdentity.returns(item.id);
qa = new QueryAdapter(ds);
qa.query();
qa.remove(item).then(
function() {
assert.calledOnceWith(ds.remove, item.id);
},
fail
).then(done, done);
}
},
'update': {
'should update item in datasource': function(done) {
var ds, qa, item;
item = { id: 1 };
ds = this.stub(createDatasource());
ds.getIdentity.returns(1);
ds.query.returns([item]);
qa = new QueryAdapter(ds);
qa.query();
qa.update(item).then(
function() {
assert.calledOnceWith(ds.put, item);
},
fail
).then(done, done);
}
},
'forEach': {
'should iterate over empty results before query': function() {
var qa, spy;
qa = new QueryAdapter(createDatasource());
spy = this.spy();
qa.forEach(spy);
refute.called(spy);
},
'should iterate when results are available': function(done) {
var ds, qa, spy;
ds = this.stub(createDatasource());
ds.query.returns(promiseFor([{ id: 1 }]));
qa = new QueryAdapter(ds);
spy = this.spy();
qa.query();
qa.forEach(spy).then(
function() {
assert.calledOnce(spy);
},
fail
).then(done, done);
}
},
'async': {
'// should have tests to assert that values returned from server update internal state': function () {},
'// should have tests to assert that errors returned from server are handled': function () {}
}
});
})(
require('buster'),
require('when'),
require('../../adapter/Query')
);
\ No newline at end of file
(function(buster, when, delay, makeTransformed) {
"use strict";
var assert, refute, fail;
assert = buster.assert;
refute = buster.refute;
fail = buster.assertions.fail;
function createFakeAdapter(data) {
data = data || [];
return {
add: function(item) {},
remove: function(item) {},
update: function(item) {},
clear: function() {},
forEach: function(f) {
for(var i = 0, len = data.length; i < len; i++) {
f(data[i]);
}
},
getOptions: function() {}
}
}
function resolved(val) {
return delay(val, 0);
}
function makePromised(f) {
function promised(x) {
return resolved(f(x));
}
if(f.inverse) {
promised.inverse = function(x) {
return resolved(f.inverse(x));
}
}
return promised;
}
function addOne(x) {
return x + 1;
}
function addOneWithInverse(x) {
return addOne(x);
}
addOneWithInverse.inverse = function(x) {
return x - 1;
};
buster.testCase('adapter/makeTransformed', {
'should throw if no transform provided': function() {
assert.exception(function() {
makeTransformed(createFakeAdapter());
});
},
'should not modify original adapter': function() {
var adapter, p, originals;
originals = {};
adapter = createFakeAdapter();
for(p in adapter) {
originals[p] = adapter[p];
}
makeTransformed(adapter, addOneWithInverse);
for(p in adapter) {
assert.same(adapter[p], originals[p]);
}
},
'should preserve original comparator': function() {
var adapter, transformed;
function comparator(){}
adapter = createFakeAdapter();
adapter.comparator = comparator;
transformed = makeTransformed(adapter, addOneWithInverse);
assert.same(transformed.comparator, comparator);
},
'should preserve original identifier': function() {
var adapter, transformed;
function identifier(){}
adapter = createFakeAdapter();
adapter.identifier = identifier;
transformed = makeTransformed(adapter, addOneWithInverse);
assert.same(transformed.identifier, identifier);
},
'getOptions': {
'should return original adapter options': function() {
var adapter, transformed, options;
options = {};
adapter = this.stub(createFakeAdapter());
transformed = makeTransformed(adapter, addOneWithInverse);
adapter.getOptions.returns(options);
assert.same(transformed.getOptions(), options);
}
},
'forEach': {
'should delegate with transformed value': function() {
var adapter, transformed, lambda;
adapter = createFakeAdapter([1]);
transformed = makeTransformed(adapter, addOne);
lambda = this.spy();
transformed.forEach(lambda);
assert.calledOnceWith(lambda, 2);
},
'should allow promised transforms': function(done) {
var adapter, transformed, lambda, results;
adapter = createFakeAdapter([1, 2, 3]);
transformed = makeTransformed(adapter, makePromised(addOne));
results = [];
lambda = function(val) {
results.push(val);
};
when(transformed.forEach(lambda),
function() {
assert.equals(results, [2,3,4]);
},
fail
).then(done, done);
}
},
'add': {
'should call original with inverse transformed item': function() {
var adapter, transformed;
adapter = this.stub(createFakeAdapter());
transformed = makeTransformed(adapter, addOneWithInverse);
transformed.add(1);
assert.calledOnceWith(adapter.add, 0);
},
'should allow promised transforms': function(done) {
var adapter, transformed;
adapter = this.stub(createFakeAdapter());
transformed = makeTransformed(adapter, makePromised(addOneWithInverse));
when(transformed.add(1),
function() {
assert.calledOnceWith(adapter.add, 0);
},
fail
).then(done, done);
}
},
'remove': {
'should call original with inverse transformed item': function() {
var adapter, transformed;
adapter = this.stub(createFakeAdapter());
transformed = makeTransformed(adapter, addOneWithInverse);
transformed.remove(1);
assert.calledOnceWith(adapter.remove, 0);
},
'should allow promised transforms': function(done) {
var adapter, transformed;
adapter = this.stub(createFakeAdapter());
transformed = makeTransformed(adapter, makePromised(addOneWithInverse));
when(transformed.remove(1),
function() {
assert.calledOnceWith(adapter.remove, 0);
},
fail
).then(done, done);
}
},
'update': {
'should call original with inverse transformed item': function() {
var adapter, transformed;
adapter = this.stub(createFakeAdapter());
transformed = makeTransformed(adapter, addOneWithInverse);
transformed.update(1);
assert.calledOnceWith(adapter.update, 0);
},
'should allow promised transforms': function(done) {
var adapter, transformed;
adapter = this.stub(createFakeAdapter());
transformed = makeTransformed(adapter, makePromised(addOneWithInverse));
when(transformed.update(1),
function() {
assert.calledOnceWith(adapter.update, 0);
},
fail
).then(done, done);
}
},
'clear': {
'should call original clear': function() {
var adapter, transformed;
adapter = this.stub(createFakeAdapter());
transformed = makeTransformed(adapter, addOneWithInverse);
transformed.clear();
assert.calledOnce(adapter.clear);
}
}
});
})(
require('buster'),
require('when'),
require('when/delay'),
require('../../adapter/makeTransformed')
);
\ No newline at end of file
exports['shared tests'] = {
tests: [
'cola.js',
'SortedMap.js',
'Hub.js',
'adapter/*.js',
'network/strategy/*.js',
'transform/*.js',
'relational/*.js',
'relational/strategy/*.js',
'projection/*.js',
'comparator/*.js',
'validation/**/*.js',
'dom/**/*.js'
]
};
exports['node tests'] = {
environment: 'node',
extends: 'shared tests'
};
(function(buster, when, cola) {
"use strict";
var assert, refute, fail;
assert = buster.assert;
refute = buster.refute;
fail = buster.assertions.fail;
function resolver(resolve, reject) {
return {
resolve: resolve,
reject: reject
}
}
buster.testCase('cola', {
'wire plugin': {
'should return a valid plugin': function() {
var plugin = cola.wire$plugin(null, null, {});
assert.isFunction(plugin.facets.bind.ready);
},
'should fail if "to" not provided': function() {
var plugin, bind, wire, rejected;
plugin = cola.wire$plugin(null, null, {});
bind = plugin.facets.bind.ready;
wire = this.stub().returns({});
rejected = this.spy();
bind(resolver(null, rejected), { target: {} }, wire);
assert.calledOnce(rejected);
},
'should wire options': function() {
var plugin, bind, wire, resolved;
plugin = cola.wire$plugin(null, null, {});
bind = plugin.facets.bind.ready;
wire = this.stub().returns({
to: { addSource: this.spy() }
});
resolved = this.spy();
bind(resolver(resolved), { target: {} }, wire);
assert.calledOnce(wire);
assert.calledOnce(resolved);
},
'should add source': function() {
var plugin, bind, wire, addSource, target;
plugin = cola.wire$plugin(null, null, {});
bind = plugin.facets.bind.ready;
addSource = this.spy();
wire = this.stub().returns({
to: { addSource: addSource }
});
target = {};
bind(resolver(this.spy()), { target: target }, wire);
assert.calledOnceWith(addSource, target);
},
'should include default comparator if not provided': function() {
var plugin, bind, wire, resolved, wired;
plugin = cola.wire$plugin(null, null, {});
bind = plugin.facets.bind.ready;
wire = function(s) { wired = s; };
resolved = this.spy();
bind(resolver(resolved), { target: {} }, wire);
assert.isFunction(wired.comparator);
}
}
});
})(
require('buster'),
require('when'),
require('../cola')
);
(function(buster, require) {
var assert, refute, fail;
assert = buster.assert;
refute = buster.refute;
fail = buster.assertions.fail;
var compose = require('../../comparator/compose');
function lt() { return -1; }
function gt() { return 1; }
function eq() { return 0; }
buster.testCase('comparator/compose', {
'should return equality for equal items': function() {
assert.equals(compose(eq, eq)(), 0);
},
'should return -1 for nested less': function() {
assert.equals(compose(eq, lt)(), -1);
},
'should return 1 for nested less': function() {
assert.equals(compose(eq, gt)(), 1);
},
'should throw if no comparators provided': function() {
assert.exception(compose);
}
});
})(require('buster'), require);
(function(buster, require) {
var assert, refute, fail;
assert = buster.assert;
refute = buster.refute;
fail = buster.assertions.fail;
var reverse = require('../../comparator/reverse');
function compare(a, b) {
return a - b;
}
buster.testCase('comparator/reverse', {
'should return equality for equal items': function() {
assert.equals(reverse(compare)(1, 1), 0);
},
'should return -1 for nested less': function() {
assert.equals(reverse(compare)(1, 0), -1);
},
'should return 1 for nested less': function() {
assert.equals(reverse(compare)(0, 1), 1);
},
'should throw if no comparators provided': function() {
assert.exception(reverse);
}
});
})(require('buster'), require);
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>NodeAdapter test</title>
<script src="../util/doh/runner.js"></script>
<script src="../test-config.js"></script>
<script type="text/javascript">
require(['cola/dom/adapter/Node', 'domReady!'], function(NodeAdapter) {
function getNode (id) {
return document.getElementById(id);
}
function querySelector (selector, root) {
return root.querySelector(selector);
}
function querySelectorAll (selector, root) {
return root.querySelectorAll(selector);
}
function nodeFinder (name, form) {
return form.elements[name];
}
function simulateEvent (node, type) {
var evt;
if (document.createEvent) {
if (/click|mouse/.test(type)) {
evt = document.createEvent('MouseEvents');
evt.initMouseEvent(type, true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
}
else {
evt = document.createEvent('HTMLEvents');
evt.initEvent(type, false, true);
}
node.dispatchEvent(evt);
}
else {
var evt = document.createEventObject();
node.fireEvent('on' + type, evt);
}
}
// quick and dirty on() implementation
function on (node, event, handler, selector) {
function filter (e) {
var target, matches, i, len, match;
// if e.target matches the selector, call the handler
target = e.target;
matches = querySelectorAll(selector, node);
for (i = 0, len = matches.length; i < len; i++) {
match = matches[i];
if (target == match || contains(match, target)) {
e.selectorTarget = match;
return handler(e);
}
}
}
node.addEventListener(event, filter, false);
return function () {
node.removeEventListener(event, filter, false);
}
}
var contains;
if (document && document.compareDocumentPosition) {
contains = function w3cContains (refNode, testNode) {
return (refNode.compareDocumentPosition(testNode) & 16) == 16;
}
}
else {
contains = function oldContains (refNode, testNode) {
return refNode.contains(testNode);
}
}
function init () {
// this function has to run to ensure that the browser hasn't
// attempted to preserve form values across a browser reload
var node, first, last;
node = getNode('test');
first = node.elements.first;
last = node.elements.last;
first.value = 'Fred';
last.value = 'Flintstone';
}
doh.register('the basics', [
function getOptions (doh) {
var bindings = { cake: { attr: 'yes', selector: 'foo' } }, adaptedObject;
adaptedObject = new NodeAdapter(getNode('test'), {
bindings: bindings,
querySelector: querySelector,
on: on
});
doh.assertEqual(bindings.cake, adaptedObject.getOptions().bindings.cake);
},
function canHandle (doh) {
doh.assertFalse(NodeAdapter.canHandle(), 'undefined');
doh.assertFalse(NodeAdapter.canHandle(null), 'null');
doh.assertFalse(NodeAdapter.canHandle(function(){}), 'function');
doh.assertFalse(NodeAdapter.canHandle([]), 'array');
doh.assertFalse(NodeAdapter.canHandle({}), 'object');
doh.assertTrue(NodeAdapter.canHandle(getNode('test')), 'DOMNode');
}
]);
doh.register('events', [
function shouldInjectPropertyIntoNode (doh) {
var node, first, last, adapted;
node = getNode('test');
init();
first = node.elements.first;
last = node.elements.last;
adapted = new NodeAdapter(node, {
bindings: {
// test pre-resolved node
first: { attr: 'value', selector: 'first' },
// TODO: test auto-resolved form node (remove selector)
last: { attr: 'value', selector: 'last' }
},
querySelector: querySelector,
on: on,
nodeFinder: nodeFinder
});
adapted.set({ first: 'Fred', last: 'Astaire' });
doh.assertEqual('Fred', first.value, 'first name is set');
doh.assertEqual('Astaire', last.value, 'last name is set');
},
function shouldUpdatePropertyIntoNode (doh) {
var node, first, last, adapted;
node = getNode('test');
init();
first = node.elements.first;
last = node.elements.last;
adapted = new NodeAdapter(node, {
bindings: {
// test pre-resolved node
first: { attr: 'value', selector: 'first' },
// TODO: test auto-resolved form node (remove selector)
last: { attr: 'value', selector: 'last' }
},
querySelector: querySelector,
on: on,
nodeFinder: nodeFinder
});
adapted.set({ first: 'Fred', last: 'Astaire' });
adapted.update({ last: 'Flintstone' });
doh.assertEqual('Fred', first.value, 'first name is set');
doh.assertEqual('Flintstone', last.value, 'last name is set');
},
function shouldCallUpdateWhenEventFires (doh) {
var node, checked, adapted, item;
function inverseHandler (node, item, binding) {
item[binding.prop] = node[binding.attr];
}
node = getNode('test');
init();
checked = node.elements.checked;
adapted = new NodeAdapter(node, {
bindings: {
checked: { attr: 'checked', selector: '[name=checked]'/*, inverse: inverseHandler*/ },
first: { attr: 'value', selector: '[name=first]'},
last: { attr: 'value', selector: '[name=last]' }
},
querySelector: querySelector,
on: on,
// need to use qSA with our simplified on() implementation
nodeFinder: querySelectorAll
});
item = { first: 'Fred', last: 'Astaire' };
adapted.set(item);
checked.checked = false;
checked.click();
//simulateEvent(checked, 'click');
doh.assertEqual(item.checked, true);
},
function shouldInsertClassNamesUsingClassSet (doh) {
var node, first, adapted;
node = getNode('test');
init();
first = node.elements.first;
adapted = new NodeAdapter(node, {
bindings: {
// test classSet
state: { attr: 'classSet' }
},
querySelector: querySelector,
on: on
});
adapted.update({
state: {
'foo bar': true,
'baz bap': true,
'elmer fudd': false
}
});
doh.assertTrue(/foo bar/.test(node.className), 'class name contains "foo bar"');
doh.assertTrue(/baz bap/.test(node.className), 'class name contains "baz bap"');
doh.assertFalse(/elmer fudd/.test(node.className), 'class name contains "elmer fudd"');
}
]);
doh.run();
});
</script>
</head>
<body>
<form id="test">
<input name="first" value="Fred"/>
<input name="last" value="Flinstone"/>
<label><input type="checkbox" name="checked"/>check me</label>
</form>
</body>
</html>
\ No newline at end of file
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>NodeListAdapterList test</title>
<script src="../util/doh/runner.js"></script>
<script src="../test-config.js"></script>
<script type="text/javascript">
require(['cola/dom/adapter/NodeList', 'cola/adapter/Object', 'domReady!'], function(NodeListAdapter, ObjectAdapter) {
var rootNode, itemNode, baseHtml;
function getNode (id) {
return document.getElementById(id);
}
function simulateEvent (node, type) {
var evt = createEvent(type);
if (node.dispatchEvent) {
node.dispatchEvent(evt);
}
else {
node.fireEvent('on' + type, evt);
}
}
function createEvent (type) {
if (document.createEvent) {
var evt = document.createEvent('HTMLEvents');
evt.initEvent(type, false, true);
}
else {
var evt = document.createEventObject();
}
}
function compareById (a, b) { return a.id - b.id; }
function symbolizeById (a) { return a.id; }
function querySelector (selector, node) { return (node||document).querySelector(selector); }
function querySelectorAll (selector, node) { return (node||document).querySelectorAll(selector); }
function on (node, event, handler) {
node.addEventListener(event, handler, false);
return function () {
node.removeEventListener(event, handler, false);
}
}
function init () {
// this function has to run to ensure that the browser hasn't
// attempted to preserve form values across a browser reload
rootNode = getNode('test');
itemNode = 'fieldset';
if (baseHtml) {
rootNode.innerHTML = baseHtml;
}
else {
baseHtml = rootNode.innerHTML;
}
}
doh.register('the basics', [
function shouldHandleNodes (doh) {
doh.assertTrue(NodeListAdapter.canHandle(getNode('test')), 'DOMNode');
},
function shouldNotHandleNonNodes (doh) {
doh.assertFalse(NodeListAdapter.canHandle(), 'undefined');
doh.assertFalse(NodeListAdapter.canHandle(null), 'null');
doh.assertFalse(NodeListAdapter.canHandle(function(){}), 'function');
doh.assertFalse(NodeListAdapter.canHandle([]), 'array');
doh.assertFalse(NodeListAdapter.canHandle({}), 'object');
}
]);
doh.register('events', [
function shouldAddNodeForEachItem (doh) {
var item, adapted, options;
init();
options = {
querySelector: querySelector,
on: on,
itemTemplateSelector: itemNode,
comparator: compareById,
identifier: symbolizeById
};
adapted = new NodeListAdapter(rootNode, options);
item = { id: 1 };
adapted.add(item);
adapted.add({ id: 9 });
adapted.add({ id: 3 });
doh.assertEqual(3, rootNode.querySelectorAll('fieldset').length);
},
function shouldUpdateNode (doh) {
var item, adapted, options;
init();
function lastNameHandler (node, item, info) {
node.value = item && item.last || '(unknown)';
}
options = {
querySelector: querySelector,
on: on,
itemTemplateSelector: itemNode,
comparator: compareById,
identifier: symbolizeById,
bindings: {
name: { selector: '', attr: 'name' },
first: { selector: '[name="first"]' },
last: { selector: '[name="last"]', handler: lastNameHandler }
}
};
adapted = new NodeListAdapter(rootNode, options);
item = { id: 1, name: 'bar' };
adapted.add(item);
adapted.update({ id: 1, name: 'foo', first: 'Jane' });
doh.assertEqual('foo', querySelector(itemNode).name);
doh.assertEqual('Jane', querySelector(options.bindings.first.selector).value, rootNode);
doh.assertEqual('(unknown)', querySelector(options.bindings.last.selector).value, rootNode);
},
function shouldUpdateMultipleNodes (doh) {
var item, adapted, options;
init();
function allHandler (nodes, item, info) {
nodes.forEach(function (node) {
node[info.attr] = item[info.prop];
});
}
function disabledHandler (node, item, info) {
node.disabled = !!item.each;
}
options = {
querySelector: querySelector,
on: on,
nodeFinder: querySelectorAll,
itemTemplateSelector: itemNode,
comparator: compareById,
identifier: symbolizeById,
bindings: {
all: {
selector: 'label',
attr: 'data-value',
all: allHandler
},
each: {
selector: 'input[name=first]',
attr: 'disabled',
each: disabledHandler
},
"both": {
selector: 'input[name=last]',
attr: 'value',
each: disabledHandler,
all: allHandler
}
}
};
adapted = new NodeListAdapter(rootNode, options);
item = { id: 1, all: 'bar', both: 'both' };
adapted.add(item);
adapted.add({ id: 2, all: 'bar', each: true, both: 'both' });
adapted.add({ id: 3, all: 'bar', each: false, both: 'both' });
var nodes, i;
// check "all" binding
nodes = querySelectorAll(options.bindings.all.selector, rootNode);
for (i = 0; i < nodes.length; i++) {
doh.assertEqual('bar', nodes[i]['data-value'], 'value ' + i);
}
// check "each" binding
nodes = querySelectorAll(options.bindings.each.selector, rootNode);
for (i = 0; i < nodes.length; i++) {
// every other data item is disabled
doh.assertEqual(!!(i % 2), nodes[i].disabled, 'disabled ' + i);
}
// check that "each-and-all" is calling both handlers
nodes = querySelectorAll(options.bindings.both.selector, rootNode);
for (i = 0; i < nodes.length; i++) {
// every other data item is disabled
doh.assertEqual(!!(i % 2), nodes[i].disabled, 'disabled ' + i);
doh.assertEqual('both', nodes[i].value, 'value ' + i);
}
},
function shouldRemoveNode (doh) {
var item, adapted, options;
init();
options = {
querySelector: querySelector,
on: on,
itemTemplateSelector: itemNode,
comparator: compareById,
identifier: symbolizeById
};
adapted = new NodeListAdapter(rootNode, options);
item = { id: 1 };
adapted.add(item);
adapted.add({ id: 2 });
adapted.add({ id: 3 });
adapted.remove(item);
doh.assertEqual(2, querySelectorAll(itemNode, rootNode).length, 'two items remain in list');
},
function shouldFindItemByNode (doh) {
var last, item, adapted, options;
init();
options = {
querySelector: querySelector,
on: on,
itemTemplateSelector: itemNode,
comparator: compareById,
identifier: symbolizeById
};
adapted = new NodeListAdapter(rootNode, options);
last = { id: 3 };
adapted.add({ id: 1 });
adapted.add({ id: 2 });
adapted.add(last);
item = adapted.findItem(querySelector('[data-cola-id="3"] [name="last"]', rootNode));
doh.assertEqual(item.id, last.id, 'last item in list');
},
function shouldFindNodeByXXX (doh) {
var last, node, adapted, options;
init();
options = {
querySelector: querySelector,
on: on,
itemTemplateSelector: itemNode,
comparator: compareById,
identifier: symbolizeById
};
adapted = new NodeListAdapter(rootNode, options);
last = { id: 3 };
adapted.add({ id: 1 });
adapted.add({ id: 2 });
adapted.add(last);
// find by item
node = adapted.findNode(last);
doh.assertEqual(node.getAttribute('data-cola-id'), last.id, 'last node in list');
// find by id
node = adapted.findNode(3);
doh.assertTrue(!!node, 'node is not undefined');
doh.assertEqual(node.getAttribute('data-cola-id'), '3', 'last node in list');
}
]);
doh.run();
});
</script>
</head>
<body>
<form id="test">
<fieldset style="display:none">
<label>
<input name="first" value=""/>
</label>
<input name="last" value=""/>
</fieldset>
</form>
</body>
</html>
\ No newline at end of file
(function (buster, require) {
var assert, refute, undef;
assert = buster.assert;
refute = buster.refute;
var formToObject, fakeForm;
formToObject = require('../../dom/formToObject');
fakeForm = {
// name, value, type, checked, multiple, options
elements: [
{ name: 'text', type: 'text', value: 'text value' },
{ name: 'checkbox1', type: 'checkbox', value: 'checkbox value 1', checked: true },
{ name: 'checkbox2', type: 'checkbox', value: 'checkbox value 2', checked: false },
{ name: 'checkbox3', type: 'checkbox', value: null, checked: false },
{ name: 'checkbox4', type: 'checkbox', value: null, checked: true },
{ name: 'radio1', type: 'radio', value: 'radio value 1' },
{ name: 'radio2', type: 'radio', value: 'radio value 2', checked: true },
{ name: 'select', value: 'select value' },
// groups
{ name: 'radioGroup1', type: 'radio', value: 'rgroup value 1' },
{ name: 'radioGroup1', type: 'radio', value: 'rgroup value 2', checked: true },
{ name: 'radioGroup1', type: 'radio', value: 'rgroup value 3' },
{ name: 'checkboxGroup1', type: 'checkbox', value: 'group value 1' },
{ name: 'checkboxGroup1', type: 'checkbox', value: 'group value 2', checked: true },
{ name: 'checkboxGroup1', type: 'checkbox', value: 'group value 3' },
{ name: 'checkboxGroup2', type: 'checkbox', value: 'group value 1', checked: true },
{ name: 'checkboxGroup2', type: 'checkbox', value: 'group value 2', checked: true },
{ name: 'checkboxGroup2', type: 'checkbox', value: 'group value 3' },
{ name: 'checkboxGroup3', type: 'checkbox', value: 'group value 1' },
{ name: 'checkboxGroup3', type: 'checkbox', value: 'group value 2', checked: true },
{ name: 'checkboxGroup3', type: 'checkbox', value: 'group value 3', checked: true },
// multi-select
{ name: 'multiselect1', value: 'option value 2', multiple: true, options: [
{ value: 'option value 1' },
{ value: 'option value 2', selected: true },
{ value: 'option value 3' }
] },
{ name: 'multiselect2', value: 'option value 2', multiple: true, options: [
{ value: 'option value 1' },
{ value: 'option value 2', selected: true },
{ value: 'option value 3', selected: true }
] },
{ name: 'multiselect3', value: 'option value 1', multiple: true, options: [
{ value: 'option value 1', selected: true },
{ value: 'option value 2', selected: true },
{ value: 'option value 3' }
] },
// non-form elements
{ name: 'no-value' },
{ value: 'no-name' },
{ name: '', value: 'blank-name' }
]
};
// add fake attributes collection to each "element" since formToObject uses it
for (var i in fakeForm.elements) (function (el) {
el.attributes = el;
}(fakeForm.elements[i]));
buster.testCase('cola/dom/formToObject', {
'formToObject': {
'should extract values from non-grouped form inputs': function () {
var obj = formToObject(fakeForm);
assert.equals('text value', obj.text, 'text input');
assert.equals('checkbox value 1', obj.checkbox1, 'checked checkbox');
assert.equals(false, obj.checkbox2, 'unchecked checkbox');
assert.equals(false, obj.checkbox3, 'unchecked checkbox with no value');
assert.equals(true, obj.checkbox4, 'checked checkbox with no value');
assert.equals(false, obj.radio1, 'unchecked radio');
assert.equals('radio value 2', obj.radio2, 'checked radio');
assert.equals('select value', obj.select, 'select');
},
'should extract arrays from grouped form inputs': function () {
var obj = formToObject(fakeForm);
assert.equals('rgroup value 2', obj.radioGroup1, 'radio group');
assert.equals(['group value 2'], obj.checkboxGroup1, 'checkbox group with one checked');
assert.equals(['group value 1', 'group value 2'], obj.checkboxGroup2, 'checkbox group with multiple checked A');
assert.equals(['group value 2', 'group value 3'], obj.checkboxGroup3, 'checkbox group with multiple checked B');
assert.equals(['option value 2'], obj.multiselect1, 'multiple select with only one item selected');
assert.equals(['option value 2', 'option value 3'], obj.multiselect2, 'multiple select with many items selected A');
assert.equals(['option value 1', 'option value 2'], obj.multiselect3, 'multiple select with many items selected B');
},
'should skip over un-named and non-value elements': function () {
var obj = formToObject(fakeForm);
refute('no-value' in obj);
refute('no-name' in obj);
refute('' in obj);
}
}
});
})( require('buster'), require );
(function (buster, require) {
var assert, refute, undef;
assert = buster.assert;
refute = buster.refute;
var base = require('../../../network/strategy/base'),
mockApi = {
isPropagating: function () { return true; },
isHandled: function () { return false; }
};
buster.testCase('cola/network/strategy/base', {
'should return function': function () {
assert.isFunction(base());
},
'should execute method on dest adapter': function () {
var spy, strategy, dest;
spy = this.spy();
strategy = base();
dest = {
anyEvent: spy
};
strategy(null, dest, {}, 'anyEvent', mockApi);
assert.calledOnce(spy);
},
'should not execute method on dest adapter if method doesn\'t exist': function () {
var spy, strategy, dest;
spy = this.spy();
strategy = base();
dest = {};
strategy(null, dest, {}, 'anyEvent', mockApi);
refute.calledOnce(spy);
},
'should throw if non-method with event name exists on dest adapter': function () {
var spy, strategy, dest;
spy = this.spy();
strategy = base();
dest = {
anyProp: 1
};
try {
strategy(null, dest, {}, 'anyProp', mockApi);
refute(true);
}
catch (ex) {
assert(true);
}
}
});
})( require('buster'), require );
(function (buster, require) {
var assert, refute, compose, mockApi, undef;
assert = buster.assert;
refute = buster.refute;
compose = require('../../../network/strategy/compose');
mockApi = {
isCanceled: function () { return this.canceled; },
cancel: function () { this.canceled = true; },
isHandled: function () { return this.handled; },
handle: function () { this.handled = true; }
};
buster.testCase('cola/network/strategy/compose', {
'should return function': function () {
assert.isFunction(compose([]));
},
'should call each of the strategies': function () {
var strategies;
strategies = [
this.spy(),
this.spy(),
this.spy()
];
compose(strategies)({}, {}, {}, '', Object.create(mockApi));
assert.called(strategies[0]);
assert.called(strategies[1]);
assert.called(strategies[2]);
},
'should call the strategies in order': function () {
var strategies;
strategies = [
this.spy(),
this.spy(),
this.spy()
];
compose(strategies)({}, {}, {}, '', Object.create(mockApi));
assert.callOrder(strategies[0], strategies[1], strategies[2]);
},
'should not proceed past strategy that cancels': function () {
var strategies;
strategies = [
this.spy(),
function (src, dst, data, type, api) { api.cancel(); },
this.spy()
];
compose(strategies)({}, {}, {}, '', Object.create(mockApi));
assert.called(strategies[0]);
refute.called(strategies[2]);
}
});
})( require('buster'), require );
(function (buster, require) {
var assert, refute, undef;
assert = buster.assert;
refute = buster.refute;
var def = require('../../../network/strategy/default');
buster.testCase('cola/network/strategy/default', {
'should return function': function () {
assert.isFunction(def([]));
},
'// should have more tests': function () {
assert(false);
}
});
})( require('buster'), require );
(function (buster, require) {
var assert, refute;
assert = buster.assert;
refute = buster.refute;
var syncAfterJoin = require('../../../network/strategy/syncAfterJoin'),
mockApi = {
isAfter: function () { return true; }
};
buster.testCase('cola/network/strategy/syncAfterJoin', {
'should return function': function () {
assert.isFunction(syncAfterJoin([]));
},
'should call hub\'s queueEvent': function (done) {
var qspy, api, dest, src;
qspy = this.spy();
api = Object.create(mockApi);
api.queueEvent = qspy;
src = {};
syncAfterJoin()(src, dest, {}, 'join', api);
setTimeout(function() {
assert.calledOnceWith(qspy, src, false, 'sync');
done();
}, 0);
},
'should call hub\'s queueEvent when provide is true': function (done) {
var qspy, api, dest, src;
qspy = this.spy();
api = Object.create(mockApi);
api.queueEvent = qspy;
src = {
provide: true
};
// add provider option and test for true data param
syncAfterJoin()(src, dest, {}, 'join', api);
setTimeout(function() {
// Ensure that it was called twice, *and* at least one of
// those was called with these args
assert.calledOnceWith(qspy, src, true, 'sync');
done();
}, 0);
}
});
})( require('buster'), require );
(function (buster, require) {
var assert, refute, undef;
assert = buster.assert;
refute = buster.refute;
var syncDataDirectly = require('../../../network/strategy/syncDataDirectly');
function FakeApi (phase) {
return {
phase: phase,
isBefore: function () {
return this.phase == 'before';
}
};
}
function FakeAdapter () {
return {
add: function () {},
forEach: function () {}
};
}
buster.testCase('cola/network/strategy/syncDataDirectly', {
'should return a function': function () {
assert.isFunction(syncDataDirectly());
},
'should always cancel a "sync"': function () {
var strategy = syncDataDirectly(),
api = new FakeApi('before');
api.cancel = this.spy();
strategy(new FakeAdapter(), new FakeAdapter(), {}, 'sync', api);
assert.called(api.cancel);
},
'// should have more tests': function () {
assert(false);
}
});
})( require('buster'), require );
(function (buster, require) {
var assert, refute, undef;
assert = buster.assert;
refute = buster.refute;
var targetFirstItem = require('../../../network/strategy/targetFirstItem');
buster.testCase('targetFirstItem', {
'should return function': function () {
assert.isFunction(targetFirstItem([]));
},
'should call queueEvent once': function () {
var qspy, src, data, api, strategy;
qspy = this.spy();
src = {};
data = {};
api = {
isBefore: function () { return true; },
queueEvent: qspy
};
// call twice:
strategy = targetFirstItem();
strategy(src, null, data, 'add', api);
strategy(src, null, data, 'add', api);
assert.calledOnceWith(qspy, src, data, 'target');
// call twice again after sync
qspy = api.queueEvent = this.spy();
strategy(src, null, data, 'sync', api);
strategy(src, null, data, 'add', api);
strategy(src, null, data, 'add', api);
assert.calledOnceWith(qspy, src, data, 'target');
}
});
})( require('buster'), require );
(function(buster, assign) {
"use strict";
var assert, refute;
assert = buster.assert;
refute = buster.refute;
buster.testCase('projection/assign', {
'should assign to specified property': function() {
var a = assign('test');
assert.equals(a({}, 1), { test: 1 });
},
'should return input 1': function() {
var a, input;
a = assign('test');
input = {};
assert.same(a(input, 1), input);
},
'should return unmodified input 1 if input 1 is falsey': function() {
var a, input;
a = assign('test');
assert.equals(a(input, 1), input);
}
});
})(
require('buster'),
require('../../projection/assign')
);
\ No newline at end of file
(function(buster, inherit) {
"use strict";
var assert, refute;
assert = buster.assert;
refute = buster.refute;
var input1, input2;
input1 = {
a: 1
};
input2 = {
b: 2
};
buster.testCase('projection/inherit', {
'should not modify input objects': function() {
inherit(input1, input2);
assert.equals(input1, { a: 1 });
assert(input1.hasOwnProperty('a'));
assert.equals(input2, { b: 2 });
assert(input2.hasOwnProperty('b'));
},
'should return a new object': function() {
var result = inherit(input1, input2);
refute.same(result, input1);
refute.same(result, input2);
},
'should inherit properties from input1': function() {
var result = inherit(input1, input2);
assert.equals(result.a, input1.a);
refute(result.hasOwnProperty('a'));
},
'should have own properties from input2': function() {
var result = inherit(input1, input2);
assert.equals(result.b, input2.b);
assert(result.hasOwnProperty('b'));
}
});
})(
require('buster'),
require('../../projection/inherit')
);
\ No newline at end of file
(function(buster, when, hashJoin) {
"use strict";
var assert, refute, fail;
assert = buster.assert;
refute = buster.refute;
fail = buster.assertions.fail;
function identity(x) {
return x;
}
function projectPair(left, right, key) {
return { left: left, right: right, key: key };
}
buster.testCase('relational/hashJoin', {
'leftOuterJoin': {
'should produce empty result for empty left input': function(done) {
var left, right;
left = [];
right = [1, 2, 3];
when(hashJoin.leftOuterJoin(left, identity, right, identity, identity),
function(joined) {
assert.equals(joined, []);
},
fail
).then(done, done);
},
'should contain all left items': function(done) {
var left, right;
left = [1, 2, 3];
right = [2, 4, 6];
when(hashJoin.leftOuterJoin(left, identity, right, identity, identity),
function(joined) {
assert.equals(joined, left);
},
fail
).then(done, done);
},
'should produce left input for empty right input': function(done) {
var left, right;
left = [1, 2, 3];
right = [];
when(hashJoin.leftOuterJoin(left, identity, right, identity, identity),
function(joined) {
assert.equals(joined, left);
},
fail
).then(done, done);
},
'should project all items': function(done) {
var left, right;
left = [1, 2, 3];
right = [1, 2, 3, 4, 5, 6];
when(hashJoin.leftOuterJoin(left, identity, right, identity, projectPair),
function(joined) {
assert.equals(joined.length, left.length);
for(var i = 0, len = joined.length; i < len; i++) {
assert.equals(joined[i], { left: left[i], right: right[i], key: left[i] });
}
},
fail
).then(done, done);
}
}
});
})(
require('buster'),
require('when'),
require('../../relational/hashJoin')
);
\ No newline at end of file
(function(buster, propertiesKey) {
"use strict";
var assert, refute;
assert = buster.assert;
refute = buster.refute;
buster.testCase('relational/propertiesKey', {
'should return property value for single property': function() {
var fixture, key;
fixture = { foo: 'bar' };
key = propertiesKey('foo');
assert.equals(key(fixture), 'bar');
},
'should return undefined for missing single property': function() {
var fixture, key;
fixture = { foo: 'bar' };
key = propertiesKey('missing');
refute.defined(key(fixture));
},
'should return joined values for an array of properties': function() {
var fixture, key;
fixture = { p1: 'foo', p2: 'bar' };
key = propertiesKey(['p1', 'p2']);
assert.equals(key(fixture), 'foo|bar');
},
'should use the supplied join separator': function() {
var fixture, key;
fixture = { p1: 'foo', p2: 'bar' };
key = propertiesKey(['p1', 'p2'], ',');
assert.equals(key(fixture), 'foo,bar');
},
'should only include defined and non-null values for an array of properties': function() {
var fixture, key;
fixture = { p1: 'foo', p2: 'bar' };
key = propertiesKey(['p1', 'p3', 'p2']);
assert.equals(key(fixture), 'foo|bar');
},
'should return empty string when all properties in array are missing': function() {
var fixture, key;
fixture = { p1: 'foo', p2: 'bar' };
key = propertiesKey(['p3', 'p4']);
assert.equals(key(fixture), '');
}
});
})(
require('buster'),
require('../../relational/propertiesKey')
);
\ No newline at end of file
(function(buster, createLeftOuterJoin, hashJoin) {
"use strict";
var assert, refute, origLeftOuterJoin;
assert = buster.assert;
refute = buster.refute;
function noop() {}
function fakeIterable() {
return {
forEach: noop
};
}
buster.testCase('relational/strategy/leftOuterJoin', {
setUp: function() {
origLeftOuterJoin = hashJoin.leftOuterJoin;
hashJoin.leftOuterJoin = this.spy();
},
tearDown: function() {
hashJoin.leftOuterJoin = origLeftOuterJoin;
},
'should throw if options not provided': function() {
assert.exception(function() {
createLeftOuterJoin();
});
},
'should throw if options.leftKey not provided': function() {
assert.exception(function() {
createLeftOuterJoin({});
});
},
'should return a function if options.leftKey is provided': function() {
assert.isFunction(createLeftOuterJoin({ leftKey: 'id' }));
},
'should return a function that forwards parameters to join engine': function() {
var join, left, right;
join = createLeftOuterJoin({ leftKey: noop, rightKey: noop, projection: noop, multiValue: true });
left = this.stub(fakeIterable());
right = this.stub(fakeIterable());
join(left, right);
assert.calledOnceWith(hashJoin.leftOuterJoin, left, noop, right, noop, noop, true);
}
});
})(
require('buster'),
require('../../../relational/strategy/leftOuterJoin'),
require('../../../relational/hashJoin')
);
\ No newline at end of file
(function(global, undef) {
function noop() {}
// Fake console if we need to
if (typeof global.console === undef) {
global.console = { log: noop, error: noop };
}
var doc, head, scripts, script, i, baseUrl, baseUrlSuffix,
selfName, selfRegex, loaders, loader, loaderName, loaderPath, loaderConfig;
selfName = 'test-config.js';
selfRegex = new RegExp(selfName + '$');
baseUrlSuffix = '../';
loaderPath = 'test/curl/src/curl';
function addPackage(pkgInfo) {
var cfg;
if(!loaderConfig.packages) loaderConfig.packages = [];
cfg = loaderConfig.packages;
pkgInfo.main = pkgInfo.main || pkgInfo.name;
cfg.push(pkgInfo);
}
doc = global.document;
head = doc.head || doc.getElementsByTagName('head')[0];
// Find self script tag, use it to construct baseUrl
i = 0;
scripts = head.getElementsByTagName('script');
while((script = scripts[i++]) && !baseUrl) {
if(selfRegex.test(script.src)) {
baseUrl = script.src.replace(selfName, '') + baseUrlSuffix;
}
}
// dojo configuration, in case we need it
global.djConfig = {
baseUrl: baseUrl
};
loaderConfig = global.curl = {
apiName: 'require', // friggin doh needs this
baseUrl: baseUrl,
paths: {
curl: loaderPath
},
// pluginPath: 'curl/plugin',
preload: [
]
};
addPackage({ name: 'cola', location: '.', main: 'cola' });
addPackage({ name: 'dojo', location: 'test/lib/dojo', main: 'lib/main-browser' });
// addPackage({ name: 'dijit', location: 'test/lib/dijit', main: 'lib/main' });
// addPackage({ name: 'sizzle', location: 'support/sizzle' });
// addPackage({ name: 'aop', location: 'support/aop' });
addPackage({ name: 'when', location: 'test/when', main: 'when' });
// That's right y'all, document.write FTW
doc.write('<script src="' + baseUrl + loaderPath + '.js' + '"></script>');
})(window);
\ No newline at end of file
(function(buster, compose) {
"use strict";
var assert, refute;
assert = buster.assert;
refute = buster.refute;
function addOne(x) {
return x + 1;
}
function addOneWithInverse(x) {
return addOne(x);
}
addOneWithInverse.inverse = function(x) {
return x - 1;
};
buster.testCase('transform/compose', {
'should return identity if no input transforms provided': function() {
var c = compose();
assert.equals(1, c(1));
},
'should return identity inverse if no input transforms provided': function() {
var c = compose();
assert.equals(1, c.inverse(1));
},
'should compose a single function': function() {
var c = compose(addOne);
assert.equals(1, c(0));
},
'should compose a single function with inverse': function() {
var c = compose(addOneWithInverse);
assert.equals(0, c.inverse(1));
},
'should compose argument list of function': function() {
var c = compose(addOne, addOne);
assert.equals(2, c(0));
},
'should compose array of function': function() {
var c = compose([addOne, addOne]);
assert.equals(2, c(0));
},
'should compose mixed argument list and arrays of function': function() {
var c = compose(addOne, [addOne, addOne], addOne);
assert.equals(4, c(0));
},
'should compose inverse of mixed argument list and arrays of function': function() {
var c = compose(addOneWithInverse, [addOneWithInverse, addOneWithInverse], addOneWithInverse);
assert.equals(0, c.inverse(4));
},
'should compose varargs functions': function() {
var c = compose(function(a) { return a; }, function(a, b, c) { return c; });
assert.equals(3, c(1, 2, 3));
},
'should compose varargs inverse functions': function() {
var f1, f2;
f1 = function(a) { return a; };
f1.inverse = function(a, b, c) { return c; };
f2 = function(a, b, c) { return c; };
f2.inverse = function(a) { return a; };
var c = compose(f1, f2);
assert.equals(3, c.inverse(1, 2, 3));
}
});
})(
require('buster'),
require('../../transform/compose')
);
\ No newline at end of file
(function(buster, configure) {
"use strict";
var assert, refute;
assert = buster.assert;
refute = buster.refute;
buster.testCase('transform/configure', {
'should return a function': function() {
assert.isFunction(configure(function() {}));
},
'should not return an inverse when input does not have an inverse': function() {
refute.defined(configure(function() {}).inverse);
},
'should return an inverse when input has an inverse': function() {
function t() {}
t.inverse = function() {};
assert.isFunction(configure(t).inverse);
},
'should pass all configured parameters through to resulting function': function() {
var t, c;
t = this.spy();
c = configure(t, 1, 2, 3);
c('a', 'b', 'c');
assert.calledOnceWith(t, 'a', 'b', 'c', 1, 2, 3);
},
'should pass all configured parameters through to resulting inverse': function() {
function t() {}
t.inverse = this.spy();
var c = configure(t, 1, 2, 3);
c.inverse('a', 'b', 'c');
assert.calledOnceWith(t.inverse, 'a', 'b', 'c', 1, 2, 3);
}
});
})(
require('buster'),
require('../../transform/configure')
);
\ No newline at end of file
(function(buster, createEnum) {
"use strict";
var assert, refute;
assert = buster.assert;
refute = buster.refute;
buster.testCase('transform/createEnum', {
'should return a function': function() {
assert.isFunction(createEnum({}));
},
'should return an inverse function': function() {
assert.isFunction(createEnum({}).inverse);
},
'transform': {
'should return an empty set when configured with empty input map': function() {
var e = createEnum({});
assert.equals(e('test'), {});
},
'should return an empty set with non-existent input': function() {
var e = createEnum({ foo: 'bar' });
assert.equals(e('test'), {});
},
'should return corresponding set values': function() {
var e = createEnum({
a: 'a1',
b: 'b1'
});
var result = e('a');
assert(result.a1);
refute(result.b1);
},
'should return corresponding set values when multi-value': function() {
var e = createEnum({
a: 'a1',
b: 'b1',
c: 'c1'
}, { multi: true });
var result = e(['a', 'b']);
assert(result.a1);
assert(result.b1);
refute(result.c1);
}
},
'inverse': {
'should return an empty array with empty input map': function() {
var e = createEnum({});
assert.equals(e.inverse({}), []);
},
'should return an empty array with non-existent input': function() {
var e = createEnum({ foo: 'bar' });
assert.equals(e.inverse({ 'baz': true }), []);
},
'should return corresponding values': function() {
var e = createEnum({
a: 'a1',
b: 'b1'
});
assert.equals(e.inverse({ a1: true }), ['a']);
},
'should return corresponding set values when multi-value': function() {
var e = createEnum({
a: 'a1',
b: 'b1'
}, { multi: true });
assert.equals(e.inverse({ a1: true, b1: true }), ['a', 'b']);
}
}
});
})(
require('buster'),
require('../../transform/createEnum')
);
\ No newline at end of file
(function(buster, composeValidators) {
var assert, refute, fail;
assert = buster.assert;
refute = buster.refute;
fail = buster.assertions.fail;
buster.testCase('validation/composeValidators', {
'should call each validator': function() {
var v1, v2, v3, object;
v1 = this.spy();
v2 = this.spy();
v3 = this.spy();
object = {};
composeValidators([v1, v2, v3])(object);
assert.calledOnceWith(v1, object);
assert.calledOnceWith(v2, object);
assert.calledOnceWith(v3, object);
},
'should merge errors': function() {
var v1, v2, v3, result;
v1 = this.stub().returns({ valid: true });
v2 = this.stub().returns({ valid: false, errors: [1] });
v3 = this.stub().returns({ valid: false, errors: [2] });
result = composeValidators([v1, v2, v3])({});
assert.equals(result, { valid: false, errors: [1, 2] });
},
'should pass when all validators pass': function() {
var v1, v2, result;
v1 = this.stub().returns({ valid: true });
v2 = this.stub().returns({ valid: true });
result = composeValidators([v1, v2])({});
assert.equals(result, { valid: true });
},
'should fail when at least one validator fails': function() {
var v1, v2, v3, result;
v1 = this.stub().returns({ valid: true });
v2 = this.stub().returns({ valid: false });
v3 = this.stub().returns({ valid: false });
result = composeValidators([v1, v2, v3])({});
assert.equals(result, { valid: false });
}
});
})(
require('buster'),
require('../../validation/composeValidators')
);
(function(buster, createFormValidationHandler) {
"use strict";
var assert, refute, fail;
assert = buster.assert;
refute = buster.refute;
fail = buster.assertions.fail;
function createFakeNode() {
return {
className: ''
};
}
function createForm() {
return {
elements: {},
className: ''
};
}
var validationObjectWithErrors;
validationObjectWithErrors = {
valid: false,
errors: [
{ property: 'test', code: 'test', message: 'test' },
{ property: 'test2', code: 'test2', className: 'class', message: 'test2' }
]
};
buster.testCase('validation/form/formValidationHandler', {
'should add invalid class to form': function() {
var formValidationHandler, form;
form = createForm();
formValidationHandler = createFormValidationHandler(form);
formValidationHandler({ valid: false });
assert.match(form.className, /\binvalid\b/);
},
'should add default and custom classes to associated node': function() {
var formValidationHandler, form, node, node2;
form = createForm();
node = createFakeNode();
node2 = createFakeNode();
formValidationHandler = createFormValidationHandler(
form, { findNode: function(f, name) { return name == 'test' ? node : node2; } });
formValidationHandler(validationObjectWithErrors);
assert.match(node.className, /\binvalid\b/);
assert.match(node2.className, /\binvalid\b/);
assert.match(node.className, /\btest\b/);
assert.match(node2.className, /\bclass\b/);
},
'should remove classes from form when it becomes valid': function() {
var formValidationHandler, form, node;
form = createForm();
node = createFakeNode();
formValidationHandler = createFormValidationHandler(
form, { findNode: function() { return node; } });
formValidationHandler(validationObjectWithErrors);
assert.match(form.className, /\binvalid\b/);
formValidationHandler({ valid: true });
refute.match(form.className, /\binvalid\b/);
},
'should remove classes from associated node when it becomes valid': function() {
var formValidationHandler, form, node, node2;
form = createForm();
node = createFakeNode();
node2 = createFakeNode();
formValidationHandler = createFormValidationHandler(
form, { findNode: function(f, name) { return name == 'test' ? node : node2; } });
formValidationHandler(validationObjectWithErrors);
assert.match(node.className, /\binvalid\b/);
assert.match(node.className, /\btest\b/);
assert.match(node2.className, /\bclass\b/);
formValidationHandler({ valid: true });
refute.match(node.className, /\binvalid\b/);
refute.match(node.className, /\btest\b/);
refute.match(node2.className, /\bclass\b/);
}
});
})(
require('buster'),
require('../../../validation/form/formValidationHandler')
);
......@@ -20,6 +20,14 @@ Helpful link for updating submodules:
What's New?
=======
* 0.6.6
* Fix for Safari 6's strict treatment of string properties in un-compiled
files (paths were broken -- thanks Tiago!)
* 0.6.5
* better support when unning under RingoJS and node.js (still experimental)
* fixed bugs with apiContext/apiName or defineContext/defineName
* added package.json
* configuration can be overridden by successive calls: `curl({})`
* 0.6.4
* curl now restores any previous curl() or define() if the dev reassigns
either using apiContext/apiName or defineContext/defineName
......
#!/bin/sh
# run a file through google closure compiler
# TODO: start using a js_externs parameter:
# paths and other config params
# full promise api (for communicating with plugins)
# -d js_externs=promise.then=function(cb,eb){};promise.resolve=function(val){};promise.reject=function(ex){};
curl \
--data-urlencode "js_code@$1" \
-d compilation_level=$2 \
-d output_info=compiled_code \
-d output_format=text \
http://closure-compiler.appspot.com/compile
#!/bin/sh
# make simple, compiled curl.js
./make.sh ../dist/curl/curl.js ../src/curl.js
# make other versions of curl
./make.sh ../dist/curl-with-js-and-domReady/curl.js ../src/curl.js ../src/curl/domReady.js ../src/curl/plugin/js.js ../src/curl/plugin/domReady.js
./make.sh ../dist/curl-for-dojo1.6/curl.js ../src/curl.js ../src/curl/domReady.js ../src/curl/shim/dojo16.js ../src/curl/plugin/domReady.js
./make.sh ../dist/curl-kitchen-sink/curl.js ../src/curl.js ../src/curl/domReady.js ../src/curl/shim/dojo16.js ../src/curl/plugin/js.js ../src/curl/plugin/text.js ../src/curl/plugin/async.js ../src/curl/plugin/css.js ../src/curl/plugin/link.js ../src/curl/plugin/domReady.js ../src/curl/loader/cjsm11.js ../src/curl/shim/ssjs.js
./make.sh ../dist/curl-for-jQuery/curl.js ../src/curl.js ../src/curl/domReady.js ../src/curl/plugin/js.js ../src/curl/plugin/link.js ../src/curl/plugin/domReady.js
#make minimally-compressed ssjs
./make.sh --NONE ../dist/curl-for-ssjs/curl.js ../src/curl.js ../src/curl/loader/cjsm11.js ../src/curl/shim/ssjs.js
#!/bin/sh
# get optional optimization instruction
opt=$1
if [ "${opt:0:2}" = "--" ]; then
opt=${opt:2}
shift
else
opt=ADVANCED_OPTIMIZATIONS
fi
# grab the output file
out=$1
tmpfile=$(mktemp -t cram.XXXXXX)
# use all of the remaining parameters as files to be concatenated
shift
echo "making $out"
echo "optimization level is $opt"
# concatenate all of the files to a temp file
cat $@ | sed -e "s:\/\*==::g" -e "s:==\*\/::g" > "$tmpfile"
if [ "$opt" = "NONE" ]; then
# cat files to the output file
cat "$tmpfile" > "$out"
else
# compile files to the output file
./compile.sh "$tmpfile" "$opt" > "$out"
fi
# remove the temporary concatenated file
rm "$tmpfile"
echo "created $out"
Distribution Files
==================
These are the "compiled" versions of curl.js.
Use curl/curl.js if you are only loading AMD-formatted javascript modules.
Use curl-with-js-and-domReady/curl.js if you wish to use non-AMD javascript
files and don't have an alternative domReady implementation handy.
Use curl-for-jQuery1.7 for a version of curl that has instructions for
jQuery 1.7 to register as an AMD module and has the js! and link! plugins
built in. This is an adequate configuration for many simple jQuery projects
(and some sophisticated ones, too).
curl-for-dojo1.6 has the domReady! plugin built in as well as some
compatibility shims for dojo 1.6 (which isn't officially AMD-ready).
You can build your own custom version of curl.js by using the `make.sh` script
in the /bin/ folder. You must run it from the /bin/ folder. Syntax:
./make.sh destination/curl.js ../src/curl.js [files to concat into curl.js]
The following files can be concatenated into curl.js using make.sh:
* ../src/curl/plugin/js.js (the js! plugin)
* ../src/curl/plugin/text.js (the text! plugin)
* ../src/curl/plugin/i18n.js (the i18n! plugin)
* ../src/curl/plugin/css.js (the css! plugin)
* ../src/curl/plugin/link.js (the link! plugin)
* ../src/curl/plugin/domReady.js (the domReady plugin)
* ../src/curl/domReady.js (the domReady module)
* ../src/curl/shim/dojo16.js (the dojo 1.6 compatibility shim / module)
* ../src/curl/shim/underscore.js (the underscore compatibility shim / module)
* ../src/curl/loader/cjsm11.js (the CommonJS Modules/1.1 compatibility shim / module)
* Any named AMD module (does not support anonymous modules, yet!)
* Any non-AMD javascript file
For example, to make a version of curl with the js! and text! plugins built-in:
./make.sh destination/curl.js ../src/curl.js ../src/curl/plugin/js.js ../src/curl/plugin/text.js
Note: you will need a fairly recent version of `curl` (the unix utility, not
curl.js!) to run `make.sh`. Version 7.18 or later is fine.
/*
MIT License (c) copyright B Cavalier & J Hann */
var s=!0,u=!1;
(function(g){function l(){}function v(a,b){return 0==T.call(a).indexOf("[object "+b)}function i(a){return a&&"/"==a.charAt(a.length-1)?a.substr(0,a.length-1):a}function z(a,b){var c,e,d;e=1;a=a.replace(U,function(a,b,c,h){c&&e++;d=s;return h||""});return d?(c=b.split("/"),c.splice(c.length-e,e),c.concat(a||[]).join("/")):a}function t(a){var b=a.indexOf("!");return{H:a.substr(b+1),j:0<=b&&a.substr(0,b)}}function F(){}function G(a){F.prototype=a;a=new F;F.prototype=M;return a}function w(){function a(a,b,
c){e.push([a,b,c])}function b(a,b){for(var c,d=0;c=e[d++];)(c=c[a])&&c(b)}var c,e,d;c=this;e=[];d=function(c,j){a=c?function(a){a&&a(j)}:function(a,b){b&&b(j)};d=l;b(c?0:1,j);b=l;e=m};this.X=function(b,c,e){a(b,c,e)};this.h=function(a){c.ca=a;d(s,a)};this.e=function(a){c.ba=a;d(u,a)};this.p=function(a){b(2,a)}}function p(a,b,c,e){a instanceof w?a.X(b,c,e):b(a)}function A(a,b,c){var e;return function(){0<=--a&&b&&(e=b.apply(m,arguments));0==a&&c&&c(e);return e}}function x(){function a(b,e,d){var f;
f=h.c(n,m,[].concat(b));this.then=b=function(a,b){p(f,function(b){a&&a.apply(m,b)},function(a){if(b)b(a);else throw a;});return this};this.next=function(b,c){return new a(b,c,f)};e&&b(e);p(d,function(){h.i(f)})}var b=[].slice.call(arguments);v(b[0],"Object")&&(n=h.b(b.shift()));return new a(b[0],b[1])}function H(a){var b=a.id;if(b==m)if(I!==m)I={w:"Multiple anonymous defines in url"};else if(!(b=h.S()))I=a;if(b!=m){var c=o[b];b in o||(c=h.l(b,n).b,c=o[b]=h.t(c,b));if(!(c instanceof w))throw Error("duplicate define: "+
b);c.Z=u;h.u(c,a)}}var n=g.curl,B,D,y=g.document,q=y&&(y.head||y.getElementsByTagName("head")[0]),N={},O={},P={},J={},M={},T=M.toString,m,Q={loaded:1,interactive:P,complete:1},o={},K=u,I,V=/\?/,R=/^\/|^[^:]+:\/\//,U=/(\.)(\.?)(?:$|\/([^\.\/]+.*)?)/g,W=/\/\*[\s\S]*?\*\/|(?:[^\\])\/\/.*?[\n\r]/g,X=/require\s*\(\s*["']([^"']+)["']\s*\)|(?:[^\\]?)(["'])/g,L,h;h={c:function(a,b,c,e){function d(a){return z(a,j.f)}function f(b,c){var f,k,r,C;f=c&&function(a){c.apply(m,a)};if(v(b,"String")){k=d(b);r=o[k];
C=r instanceof w&&r.a;if(!(k in o))throw Error("Module not resolved: "+k);if(f)throw Error("require(id, callback) not allowed");return C||r}p(h.i(h.c(a,j.f,b,e)),f)}var j;j=new w;j.f=j.id=b||"";j.T=e;j.v=c;j.k=f;f.toUrl=function(b){return h.l(d(b),a).url};j.Y=d;return j},t:function(a,b,c,e){var d,f,j;d=h.c(a,b,m,c);d.f=e==m?b:e;f=d.h;j=A(1,function(a){d.n=a;try{return h.L(d)}catch(b){d.e(b)}});d.h=function(a){p(c||K,function(){f(o[d.id]=j(a))})};d.z=function(a){p(c||K,function(){d.a&&(j(a),d.p(O))})};
return d},K:function(a,b,c,e){a=h.c(a,b,m,c);a.f=e;return a},R:function(a){return a.k},A:function(a){return a.a||(a.a={})},Q:function(a){var b=a.o;b||(b=a.o={id:a.id,uri:h.B(a),exports:h.A(a)},b.a=b.exports);return b},B:function(a){return a.url||(a.url=h.s(a.k.toUrl(a.id)))},b:function(a){var b,c,e;(b=a)||(a={});c=a.apiName;if((e=a.apiContext)||c?e[c]:B&&b)throw Error((c||"curl")+" already exists");(e||g)[c||"curl"]=x;B&&b&&(g.curl=B);c=a.defineName;if((e=a.defineContext)||c?e[c]:D&&b)throw Error((c||
"define")+" already exists");(e||g)[c||"define"]=c=function(){var a=h.P(arguments);H(a)};D&&b&&(g.define=D);c.amd={plugins:s,jQuery:s,curl:"0.6.4"};b&&(h.b=h.D);return h.D(a)},D:function(a){function b(b,c){var d,f,k,r,C;for(C in b){k=b[C];k.name=k.id||k.name||C;r=a;f=t(i(k.name||C));d=f.H;if(f=f.j)r=e[f],r||(r=e[f]=G(a),r.g=G(a.g),r.d=[]),delete b[C];if(c){f=k;var E=void 0;f.path=i(f.path||f.location||"");E=i(f.main)||"main";"."!=E.charAt(0)&&(E="./"+E);f.C=z(E,f.name+"/");f.V=z(E,f.path+"/");f.b=
f.config}else f={path:i(k)};f.I=d.split("/").length;d?(r.g[d]=f,r.d.push(d)):r.r=h.G(k,a)}}function c(a){var b=a.g;a.W=RegExp("^("+a.d.sort(function(a,c){return b[a].I<b[c].I}).join("|").replace(/\/|\./g,"\\$&")+")(?=\\/|$)");delete a.d}var e;a.r=a.baseUrl||"";a.F="pluginPath"in a?a.pluginPath:"curl/plugin";a.g={};e=a.plugins=a.plugins||{};a.d=[];b(a.paths,u);b(a.packages,s);for(var d in e){var f=e[d].d;f&&(e[d].d=f.concat(a.d),c(e[d]))}c(a);h.J(a);return a},J:function(a){var b;(b=a&&a.preloads)&&
0<b.length&&p(K,function(){K=h.i(h.c(a,m,b,s))})},l:function(a,b,c){var e,d,f,j;e=b.g;c&&(b.F&&0>a.indexOf("/")&&!(a in e))&&(f=a=i(b.F)+"/"+a);c=R.test(a)?a:a.replace(b.W,function(b){d=e[b]||{};j=d.b;return d.C&&b==a?(f=d.C,d.V):d.path||""});return{f:f||a,b:j||n,url:h.G(c,b)}},G:function(a,b){var c=b.r;return c&&!R.test(a)?i(c)+"/"+a:a},s:function(a){return a+(V.test(a)?"":".js")},U:function(a,b,c){var e=y.createElement("script");e.onload=e.onreadystatechange=function(c){c=c||g.event;if("load"==
c.type||Q[e.readyState])delete J[a.id],e.onload=e.onreadystatechange=e.onerror="",b()};e.onerror=function(){c(Error("Syntax or http error: "+a.url))};e.type=a.$||"text/javascript";e.charset="utf-8";e.async=!a.aa;e.src=a.url;J[a.id]=e;q.insertBefore(e,q.firstChild);return e},M:function(a){var b=[],c;("string"==typeof a?a:a.toSource?a.toSource():a.toString()).replace(W,"").replace(X,function(a,d,f){f?c=c==f?m:c:c||b.push(d);return a});return b},P:function(a){var b,c,e,d,f,j;f=a.length;e=a[f-1];d=v(e,
"Function")?e.length:-1;2==f?v(a[0],"Array")?c=a[0]:b=a[0]:3==f&&(b=a[0],c=a[1]);!c&&0<d&&(j=s,c=["require","exports","module"].slice(0,d).concat(h.M(e)));return{id:b,n:c||[],q:0<=d?e:function(){return e},m:j}},L:function(a){var b;b=a.q.apply(a.m?a.a:m,a.n);b===m&&a.a&&(b=a.o?a.a=a.o.a:a.a);return b},u:function(a,b){a.q=b.q;a.m=b.m;a.v=b.n;h.i(a)},i:function(a){function b(a,b,c){j[b]=a;c&&q(a,b)}function c(b,c){var e,d,f,j;e=A(1,function(a){d(a);k(a,c)});d=A(1,function(a){q(a,c)});f=h.N(b,a);(j=f instanceof
w&&f.a)&&d(j);p(f,e,a.e,a.a&&function(a){f.a&&(a==N?d(f.a):a==O&&e(f.a))})}function e(){a.h(j)}var d,f,j,g,i,q,k;j=[];f=a.v;g=f.length;0==f.length&&e();q=A(g,b,function(){a.z&&a.z(j)});k=A(g,b,e);for(d=0;d<g;d++)i=f[d],i in L?(k(L[i](a),d,s),a.a&&a.p(N)):i?c(i,d):k(m,d,s);return a},O:function(a){h.B(a);h.U(a,function(){var b=I;I=m;a.Z!==u&&(!b||b.w?a.e(Error(b&&b.w||"define() missing or duplicated: "+a.url)):h.u(a,b))},a.e);return a},N:function(a,b){var c,e,d,f,j,i,g,q,k;c=b.Y;e=b.T;d=t(a);i=d.H;
f=c(d.j||i);g=h.l(f,n,!!d.j);if(d.j)j=f;else if(j=g.b.moduleLoader)i=f,f=j,g=h.l(j,n);d=o[f];f in o||(d=o[f]=h.t(g.b,f,e,g.f),d.url=h.s(g.url),h.O(d));f==j&&(q=new w,k=n.plugins[j]||n,p(d,function(a){var b,d,f;f=a.dynamic;i="normalize"in a?a.normalize(i,c,k)||"":c(i);d=j+"!"+i;b=o[d];if(!(d in o)){b=h.K(k,d,e,i);f||(o[d]=b);var g=function(a){b.h(a);f||(o[d]=a)};g.resolve=g;g.reject=b.e;a.load(i,b.k,g,k)}q!=b&&p(b,q.h,q.e,q.p)},q.e));return q||d},S:function(){var a;if(!v(g.opera,"Opera"))for(var b in J)if(Q[J[b].readyState]==
P){a=b;break}return a}};L={require:h.R,exports:h.A,module:h.Q};x.version="0.6.4";"function"==typeof define&&(D=define);"function"==typeof n&&(B=n,n=u);n=h.b(n);o.curl=x;o["curl/_privileged"]={core:h,cache:o,cfg:n,_define:H,_curl:x,Promise:w}})(this);
(function(g,l){function v(){if(!l.body)return u;y||(y=l.createTextNode(""));try{return l.body.removeChild(l.body.appendChild(y)),y=D,s}catch(g){return u}}function i(){var g;g=F[l[t]]&&v();if(!p&&g){p=s;for(clearTimeout(B);H=n.pop();)H();w&&(l[t]="complete");for(var i;i=G.shift();)i()}return g}function z(){i();p||(B=setTimeout(z,A))}var t="readyState",F={loaded:1,interactive:1,complete:1},G=[],w=l&&"string"!=typeof l[t],p=u,A=10,x,H,n=[],B,D,y;x="addEventListener"in g?function(g,t){g.addEventListener(t,
i,u);return function(){g.removeEventListener(t,i,u)}}:function(g,t){g.attachEvent("on"+t,i);return function(){g.detachEvent(t,i)}};l&&!i()&&(n=[x(g,"load"),x(l,"readystatechange"),x(g,"DOMContentLoaded")],B=setTimeout(z,A));define("curl/domReady",function(){function g(i){p?i():G.push(i)}g.then=g;g.amd=s;return g})})(this,this.document);var S;
define("curl/shim/dojo16",["curl/_privileged","curl/domReady"],function(g,l){function v(g){g.ready||(g.ready=function(g){l(g)});g.nameToUrl||(g.nameToUrl=function(i,l){return g.toUrl(i+(l||""))});g.cache||(g.cache={})}var i=g._curl,z=g.core.c;v(i);"undefined"==typeof S&&(S=i);g.core.c=function(){var g=z.apply(this,arguments);v(g.k);return g};return s});define("domReady",["curl/domReady"],function(g){return{load:function(l,v,i){g(i)}}});
/*
MIT License (c) copyright B Cavalier & J Hann */
var r=!0,z=!1;
(function(l){function i(){}function t(a,b){return 0==O.call(a).indexOf("[object "+b)}function m(a){return a&&"/"==a.charAt(a.length-1)?a.substr(0,a.length-1):a}function j(a,b){var c,f,e;f=1;a=a.replace(P,function(a,b,c,k){c&&f++;e=r;return k||""});return e?(c=b.split("/"),c.splice(c.length-f,f),c.concat(a||[]).join("/")):a}function B(a){var b=a.indexOf("!");return{K:a.substr(b+1),j:0<=b&&a.substr(0,b)}}function x(){}function p(a){x.prototype=a;a=new x;x.prototype=I;return a}function A(){function a(a,b,
c){f.push([a,b,c])}function b(a,b){for(var c,e=0;c=f[e++];)(c=c[a])&&c(b)}var c,f,e;c=this;f=[];e=function(c,s){a=c?function(a){a&&a(s)}:function(a,b){b&&b(s)};e=i;b(c?0:1,s);b=i;f=u};this.$=function(b,c,f){a(b,c,f)};this.h=function(a){c.r=a;e(r,a)};this.d=function(a){c.da=a;e(z,a)};this.o=function(a){b(2,a)}}function o(a,b,c,f){a instanceof A?a.$(b,c,f):b(a)}function d(a,b,c){var f;return function(){0<=--a&&b&&(f=b.apply(u,arguments));0==a&&c&&c(f);return f}}function q(){function a(b,f,e){var g;
g=k.f(h,u,[].concat(b));this.then=b=function(a,b){o(g,function(b){a&&a.apply(u,b)},function(a){if(b)b(a);else throw a;});return this};this.next=function(b,c){return new a(b,c,g)};f&&b(f);o(e,function(){k.i(g)})}var b=[].slice.call(arguments);t(b[0],"Object")&&(h=k.b(b.shift()));return new a(b[0],b[1])}function D(a){var b=a.id;if(b==u)if(E!==u)E={z:"Multiple anonymous defines in url"};else if(!(b=k.V()))E=a;if(b!=u){var c=v[b];b in v||(c=k.k(b,h).b,c=v[b]=k.u(c,b));if(!(c instanceof A))throw Error("duplicate define: "+
b);c.ca=z;k.v(c,a)}}var h=l.curl,w,C,y=l.document,n=y&&(y.head||y.getElementsByTagName("head")[0]),J={},K={},L={},F={},I={},O=I.toString,u,M={loaded:1,interactive:L,complete:1},v={},G=z,E,Q=/\?/,N=/^\/|^[^:]+:\/\//,P=/(\.)(\.?)(?:$|\/([^\.\/]+.*)?)/g,R=/\/\*[\s\S]*?\*\/|(?:[^\\])\/\/.*?[\n\r]/g,S=/require\s*\(\s*["']([^"']+)["']\s*\)|(?:[^\\]?)(["'])/g,H,k;k={f:function(a,b,c,f){function e(a){return j(a,s.e)}function g(b,c){var g,d,h,i;g=c&&function(a){c.apply(u,a)};if(t(b,"String")){d=e(b);h=v[d];
i=h instanceof A&&h.a;if(!(d in v))throw Error("Module not resolved: "+d);if(g)throw Error("require(id, callback) not allowed");return i||h}o(k.i(k.f(a,s.e,b,f)),g)}var s;s=new A;s.e=s.id=b||"";s.W=f;s.w=c;s.p=g;g.toUrl=function(b){return k.k(e(b),a).url};s.ba=e;return s},u:function(a,b,c,f){var e,g,s;e=k.f(a,b,u,c);e.e=f==u?b:f;g=e.h;s=d(1,function(a){e.m=a;try{return k.O(e)}catch(b){e.d(b)}});e.h=function(a){o(c||G,function(){g(v[e.id]=s(a))})};e.A=function(a){o(c||G,function(){e.a&&(s(a),e.o(K))})};
return e},N:function(a,b,c,f){a=k.f(a,b,u,c);a.e=f;return a},U:function(a){return a.p},B:function(a){return a.a||(a.a={})},T:function(a){var b=a.n;b||(b=a.n={id:a.id,uri:k.C(a),exports:k.B(a)},b.a=b.exports);return b},C:function(a){return a.url||(a.url=k.t(a.p.toUrl(a.id)))},b:function(a){var b,c,f;(b=a)||(a={});c=a.apiName;if((f=a.apiContext)||c?f[c]:w&&b)throw Error((c||"curl")+" already exists");(f||l)[c||"curl"]=q;w&&b&&(l.curl=w);c=a.defineName;if((f=a.defineContext)||c?f[c]:C&&b)throw Error((c||
"define")+" already exists");(f||l)[c||"define"]=c=function(){var a=k.S(arguments);D(a)};C&&b&&(l.define=C);c.amd={plugins:r,jQuery:r,curl:"0.6.4"};b&&(k.b=k.H);return k.H(a)},H:function(a){function b(b,c){var e,g,d,h,i;for(i in b){d=b[i];d.name=d.id||d.name||i;h=a;g=B(m(d.name||i));e=g.K;if(g=g.j)h=f[g],h||(h=f[g]=p(a),h.g=p(a.g),h.c=[]),delete b[i];if(c){g=d;var n=void 0;g.path=m(g.path||g.location||"");n=m(g.main)||"main";"."!=n.charAt(0)&&(n="./"+n);g.F=j(n,g.name+"/");g.X=j(n,g.path+"/");g.b=
g.config}else g={path:m(d)};g.L=e.split("/").length;e?(h.g[e]=g,h.c.push(e)):h.s=k.J(d,a)}}function c(a){var b=a.g;a.Z=RegExp("^("+a.c.sort(function(a,c){return b[a].L<b[c].L}).join("|").replace(/\/|\./g,"\\$&")+")(?=\\/|$)");delete a.c}var f;a.s=a.baseUrl||"";a.I="pluginPath"in a?a.pluginPath:"curl/plugin";a.g={};f=a.plugins=a.plugins||{};a.c=[];b(a.paths,z);b(a.packages,r);for(var e in f){var g=f[e].c;g&&(f[e].c=g.concat(a.c),c(f[e]))}c(a);k.M(a);return a},M:function(a){var b;(b=a&&a.preloads)&&
0<b.length&&o(G,function(){G=k.i(k.f(a,u,b,r))})},k:function(a,b,c){var f,e,g,d;f=b.g;c&&(b.I&&0>a.indexOf("/")&&!(a in f))&&(g=a=m(b.I)+"/"+a);c=N.test(a)?a:a.replace(b.Z,function(b){e=f[b]||{};d=e.b;return e.F&&b==a?(g=e.F,e.X):e.path||""});return{e:g||a,b:d||h,url:k.J(c,b)}},J:function(a,b){var c=b.s;return c&&!N.test(a)?m(c)+"/"+a:a},t:function(a){return a+(Q.test(a)?"":".js")},D:function(a,b,c){var f=y.createElement("script");f.onload=f.onreadystatechange=function(c){c=c||l.event;if("load"==
c.type||M[f.readyState])delete F[a.id],f.onload=f.onreadystatechange=f.onerror="",b()};f.onerror=function(){c(Error("Syntax or http error: "+a.url))};f.type=a.G||"text/javascript";f.charset="utf-8";f.async=!a.Y;f.src=a.url;F[a.id]=f;n.insertBefore(f,n.firstChild);return f},P:function(a){var b=[],c;("string"==typeof a?a:a.toSource?a.toSource():a.toString()).replace(R,"").replace(S,function(a,e,g){g?c=c==g?u:c:c||b.push(e);return a});return b},S:function(a){var b,c,f,e,g,d;g=a.length;f=a[g-1];e=t(f,
"Function")?f.length:-1;2==g?t(a[0],"Array")?c=a[0]:b=a[0]:3==g&&(b=a[0],c=a[1]);!c&&0<e&&(d=r,c=["require","exports","module"].slice(0,e).concat(k.P(f)));return{id:b,m:c||[],q:0<=e?f:function(){return f},l:d}},O:function(a){var b;b=a.q.apply(a.l?a.a:u,a.m);b===u&&a.a&&(b=a.n?a.a=a.n.a:a.a);return b},v:function(a,b){a.q=b.q;a.l=b.l;a.w=b.m;k.i(a)},i:function(a){function b(a,b,c){h[b]=a;c&&j(a,b)}function c(b,c){var f,e,g,h;f=d(1,function(a){e(a);q(a,c)});e=d(1,function(a){j(a,c)});g=k.Q(b,a);(h=g instanceof
A&&g.a)&&e(h);o(g,f,a.d,a.a&&function(a){g.a&&(a==J?e(g.a):a==K&&f(g.a))})}function f(){a.h(h)}var e,g,h,i,n,j,q;h=[];g=a.w;i=g.length;0==g.length&&f();j=d(i,b,function(){a.A&&a.A(h)});q=d(i,b,f);for(e=0;e<i;e++)n=g[e],n in H?(q(H[n](a),e,r),a.a&&a.o(J)):n?c(n,e):q(u,e,r);return a},R:function(a){k.C(a);k.D(a,function(){var b=E;E=u;a.ca!==z&&(!b||b.z?a.d(Error(b&&b.z||"define() missing or duplicated: "+a.url)):k.v(a,b))},a.d);return a},Q:function(a,b){var c,f,e,g,d,i,n,j,q;c=b.ba;f=b.W;e=B(a);i=e.K;
g=c(e.j||i);n=k.k(g,h,!!e.j);if(e.j)d=g;else if(d=n.b.moduleLoader)i=g,g=d,n=k.k(d,h);e=v[g];g in v||(e=v[g]=k.u(n.b,g,f,n.e),e.url=k.t(n.url),k.R(e));g==d&&(j=new A,q=h.plugins[d]||h,o(e,function(a){var b,e,g;g=a.dynamic;i="normalize"in a?a.normalize(i,c,q)||"":c(i);e=d+"!"+i;b=v[e];if(!(e in v)){b=k.N(q,e,f,i);g||(v[e]=b);var h=function(a){b.h(a);g||(v[e]=a)};h.resolve=h;h.reject=b.d;a.load(i,b.p,h,q)}j!=b&&o(b,j.h,j.d,j.o)},j.d));return j||e},V:function(){var a;if(!t(l.opera,"Opera"))for(var b in F)if(M[F[b].readyState]==
L){a=b;break}return a}};H={require:k.U,exports:k.B,module:k.T};q.version="0.6.4";"function"==typeof define&&(C=define);"function"==typeof h&&(w=h,h=z);h=k.b(h);v.curl=q;v["curl/_privileged"]={core:k,cache:v,cfg:h,_define:D,_curl:q,Promise:A}})(this);
(function(l,i){function t(){if(!i.body)return z;y||(y=i.createTextNode(""));try{return i.body.removeChild(i.body.appendChild(y)),y=C,r}catch(d){return z}}function m(){var d;d=x[i[B]]&&t();if(!o&&d){o=r;for(clearTimeout(w);D=h.pop();)D();A&&(i[B]="complete");for(var j;j=p.shift();)j()}return d}function j(){m();o||(w=setTimeout(j,d))}var B="readyState",x={loaded:1,interactive:1,complete:1},p=[],A=i&&"string"!=typeof i[B],o=z,d=10,q,D,h=[],w,C,y;q="addEventListener"in l?function(d,h){d.addEventListener(h,
m,z);return function(){d.removeEventListener(h,m,z)}}:function(d,h){d.attachEvent("on"+h,m);return function(){d.detachEvent(h,m)}};i&&!m()&&(h=[q(l,"load"),q(i,"readystatechange"),q(l,"DOMContentLoaded")],w=setTimeout(j,d));define("curl/domReady",function(){function d(h){o?h():p.push(h)}d.then=d;d.amd=r;return d})})(this,this.document);
(function(l,i,t){define("js",["curl/_privileged"],function(m){function j(d,i,j){function h(){o||(l<new Date?j():setTimeout(h,10))}var l,o,p;l=(new Date).valueOf()+(d.aa||3E5);j&&d.a&&setTimeout(h,10);p=m.core.D(d,function(){o=r;d.a&&(d.r=t(d.a));!d.a||d.r?i(p):j()},function(d){o=r;j(d)})}function l(d,i){j(d,function(){var j=p.shift();o=0<p.length;j&&l.apply(null,j);i.resolve(d.r||r)},function(d){i.reject(d)})}var x={},p=[],A=i&&i.createElement("script").async==r,o;return{dynamic:r,load:function(d,
i,m,h){var w,t,y,n;w=0<d.indexOf("!order");t=d.indexOf("!exports=");y=0<t&&d.substr(t+9);n="prefetch"in h?h.prefetch:r;d=w||0<t?d.substr(0,d.indexOf("!")):d;d in x?m(x[d]):(x[d]=void 0,i={name:d,url:i.toUrl(d.lastIndexOf(".")<=d.lastIndexOf("/")?d+".js":d),Y:w,a:y,aa:h.timeout},h={resolve:function(h){x[d]=h;(m.resolve||m)(h)},reject:m.reject||function(d){throw d;}},w&&!A&&o?(p.push([i,h]),n&&(i.G="text/cache",j(i,function(d){d&&d.parentNode.removeChild(d)},function(){}),i.G="")):(o=o||w,l(i,h)))}}})})(this,
this.document,function(l){try{return eval(l)}catch(i){}});(function(l){var i=l.document,t=/^\/\//,m;i&&(m=i.head||(i.head=i.getElementsByTagName("head")[0]));define("link",{load:function(j,l,x,p){j=l.toUrl(j.lastIndexOf(".")<=j.lastIndexOf("/")?j+".css":j);p=j=(p="fixSchemalessUrls"in p?p.fixSchemalessUrls:i.location.protocol)?j.replace(t,p+"//"):j;j=i.createElement("link");j.rel="stylesheet";j.type="text/css";j.href=p;m.appendChild(j);x(j.sheet||j.styleSheet)}})})(this);
define("domReady",["curl/domReady"],function(l){return{load:function(i,t,m){l(m)}}});
/*
MIT License (c) copyright B Cavalier & J Hann */
var q=!0,w=!1;
(function(n){function k(){}function y(a,b){return 0==O.call(a).indexOf("[object "+b)}function r(a){return a&&"/"==a.charAt(a.length-1)?a.substr(0,a.length-1):a}function A(a,b){var c,f,e;f=1;a=a.replace(P,function(a,b,c,i){c&&f++;e=q;return i||""});return e?(c=b.split("/"),c.splice(c.length-f,f),c.concat(a||[]).join("/")):a}function B(a){var b=a.indexOf("!");return{K:a.substr(b+1),j:0<=b&&a.substr(0,b)}}function z(){}function C(a){z.prototype=a;a=new z;z.prototype=J;return a}function x(){function a(a,b,
c){f.push([a,b,c])}function b(a,b){for(var c,e=0;c=f[e++];)(c=c[a])&&c(b)}var c,f,e;c=this;f=[];e=function(c,s){a=c?function(a){a&&a(s)}:function(a,b){b&&b(s)};e=k;b(c?0:1,s);b=k;f=t};this.$=function(b,c,f){a(b,c,f)};this.h=function(a){c.r=a;e(q,a)};this.d=function(a){c.da=a;e(w,a)};this.o=function(a){b(2,a)}}function o(a,b,c,f){a instanceof x?a.$(b,c,f):b(a)}function d(a,b,c){var f;return function(){0<=--a&&b&&(f=b.apply(t,arguments));0==a&&c&&c(f);return f}}function j(){function a(b,f,e){var g;
g=i.f(h,t,[].concat(b));this.then=b=function(a,b){o(g,function(b){a&&a.apply(t,b)},function(a){if(b)b(a);else throw a;});return this};this.next=function(b,c){return new a(b,c,g)};f&&b(f);o(e,function(){i.i(g)})}var b=[].slice.call(arguments);y(b[0],"Object")&&(h=i.b(b.shift()));return new a(b[0],b[1])}function m(a){var b=a.id;if(b==t)if(F!==t)F={z:"Multiple anonymous defines in url"};else if(!(b=i.V()))F=a;if(b!=t){var c=u[b];b in u||(c=i.k(b,h).b,c=u[b]=i.u(c,b));if(!(c instanceof x))throw Error("duplicate define: "+
b);c.ca=w;i.v(c,a)}}var h=n.curl,D,E,v=n.document,l=v&&(v.head||v.getElementsByTagName("head")[0]),p={},K={},L={},G={},J={},O=J.toString,t,M={loaded:1,interactive:L,complete:1},u={},H=w,F,Q=/\?/,N=/^\/|^[^:]+:\/\//,P=/(\.)(\.?)(?:$|\/([^\.\/]+.*)?)/g,R=/\/\*[\s\S]*?\*\/|(?:[^\\])\/\/.*?[\n\r]/g,S=/require\s*\(\s*["']([^"']+)["']\s*\)|(?:[^\\]?)(["'])/g,I,i;i={f:function(a,b,c,f){function e(a){return A(a,s.e)}function g(b,c){var g,d,h,l;g=c&&function(a){c.apply(t,a)};if(y(b,"String")){d=e(b);h=u[d];
l=h instanceof x&&h.a;if(!(d in u))throw Error("Module not resolved: "+d);if(g)throw Error("require(id, callback) not allowed");return l||h}o(i.i(i.f(a,s.e,b,f)),g)}var s;s=new x;s.e=s.id=b||"";s.W=f;s.w=c;s.p=g;g.toUrl=function(b){return i.k(e(b),a).url};s.ba=e;return s},u:function(a,b,c,f){var e,g,s;e=i.f(a,b,t,c);e.e=f==t?b:f;g=e.h;s=d(1,function(a){e.m=a;try{return i.O(e)}catch(b){e.d(b)}});e.h=function(a){o(c||H,function(){g(u[e.id]=s(a))})};e.A=function(a){o(c||H,function(){e.a&&(s(a),e.o(K))})};
return e},N:function(a,b,c,f){a=i.f(a,b,t,c);a.e=f;return a},U:function(a){return a.p},B:function(a){return a.a||(a.a={})},T:function(a){var b=a.n;b||(b=a.n={id:a.id,uri:i.C(a),exports:i.B(a)},b.a=b.exports);return b},C:function(a){return a.url||(a.url=i.t(a.p.toUrl(a.id)))},b:function(a){var b,c,f;(b=a)||(a={});c=a.apiName;if((f=a.apiContext)||c?f[c]:D&&b)throw Error((c||"curl")+" already exists");(f||n)[c||"curl"]=j;D&&b&&(n.curl=D);c=a.defineName;if((f=a.defineContext)||c?f[c]:E&&b)throw Error((c||
"define")+" already exists");(f||n)[c||"define"]=c=function(){var a=i.S(arguments);m(a)};E&&b&&(n.define=E);c.amd={plugins:q,jQuery:q,curl:"0.6.4"};b&&(i.b=i.H);return i.H(a)},H:function(a){function b(b,c){var e,g,d,h,l;for(l in b){d=b[l];d.name=d.id||d.name||l;h=a;g=B(r(d.name||l));e=g.K;if(g=g.j)h=f[g],h||(h=f[g]=C(a),h.g=C(a.g),h.c=[]),delete b[l];if(c){g=d;var p=void 0;g.path=r(g.path||g.location||"");p=r(g.main)||"main";"."!=p.charAt(0)&&(p="./"+p);g.F=A(p,g.name+"/");g.X=A(p,g.path+"/");g.b=
g.config}else g={path:r(d)};g.L=e.split("/").length;e?(h.g[e]=g,h.c.push(e)):h.s=i.J(d,a)}}function c(a){var b=a.g;a.Z=RegExp("^("+a.c.sort(function(a,c){return b[a].L<b[c].L}).join("|").replace(/\/|\./g,"\\$&")+")(?=\\/|$)");delete a.c}var f;a.s=a.baseUrl||"";a.I="pluginPath"in a?a.pluginPath:"curl/plugin";a.g={};f=a.plugins=a.plugins||{};a.c=[];b(a.paths,w);b(a.packages,q);for(var e in f){var g=f[e].c;g&&(f[e].c=g.concat(a.c),c(f[e]))}c(a);i.M(a);return a},M:function(a){var b;(b=a&&a.preloads)&&
0<b.length&&o(H,function(){H=i.i(i.f(a,t,b,q))})},k:function(a,b,c){var f,e,g,d;f=b.g;c&&(b.I&&0>a.indexOf("/")&&!(a in f))&&(g=a=r(b.I)+"/"+a);c=N.test(a)?a:a.replace(b.Z,function(b){e=f[b]||{};d=e.b;return e.F&&b==a?(g=e.F,e.X):e.path||""});return{e:g||a,b:d||h,url:i.J(c,b)}},J:function(a,b){var c=b.s;return c&&!N.test(a)?r(c)+"/"+a:a},t:function(a){return a+(Q.test(a)?"":".js")},D:function(a,b,c){var f=v.createElement("script");f.onload=f.onreadystatechange=function(c){c=c||n.event;if("load"==
c.type||M[f.readyState])delete G[a.id],f.onload=f.onreadystatechange=f.onerror="",b()};f.onerror=function(){c(Error("Syntax or http error: "+a.url))};f.type=a.G||"text/javascript";f.charset="utf-8";f.async=!a.Y;f.src=a.url;G[a.id]=f;l.insertBefore(f,l.firstChild);return f},P:function(a){var b=[],c;("string"==typeof a?a:a.toSource?a.toSource():a.toString()).replace(R,"").replace(S,function(a,e,g){g?c=c==g?t:c:c||b.push(e);return a});return b},S:function(a){var b,c,f,e,g,d;g=a.length;f=a[g-1];e=y(f,
"Function")?f.length:-1;2==g?y(a[0],"Array")?c=a[0]:b=a[0]:3==g&&(b=a[0],c=a[1]);!c&&0<e&&(d=q,c=["require","exports","module"].slice(0,e).concat(i.P(f)));return{id:b,m:c||[],q:0<=e?f:function(){return f},l:d}},O:function(a){var b;b=a.q.apply(a.l?a.a:t,a.m);b===t&&a.a&&(b=a.n?a.a=a.n.a:a.a);return b},v:function(a,b){a.q=b.q;a.l=b.l;a.w=b.m;i.i(a)},i:function(a){function b(a,b,c){h[b]=a;c&&m(a,b)}function c(b,c){var f,e,g,h;f=d(1,function(a){e(a);k(a,c)});e=d(1,function(a){m(a,c)});g=i.Q(b,a);(h=g instanceof
x&&g.a)&&e(h);o(g,f,a.d,a.a&&function(a){g.a&&(a==p?e(g.a):a==K&&f(g.a))})}function f(){a.h(h)}var e,g,h,l,j,m,k;h=[];g=a.w;l=g.length;0==g.length&&f();m=d(l,b,function(){a.A&&a.A(h)});k=d(l,b,f);for(e=0;e<l;e++)j=g[e],j in I?(k(I[j](a),e,q),a.a&&a.o(p)):j?c(j,e):k(t,e,q);return a},R:function(a){i.C(a);i.D(a,function(){var b=F;F=t;a.ca!==w&&(!b||b.z?a.d(Error(b&&b.z||"define() missing or duplicated: "+a.url)):i.v(a,b))},a.d);return a},Q:function(a,b){var c,f,e,g,d,l,p,j,m;c=b.ba;f=b.W;e=B(a);l=e.K;
g=c(e.j||l);p=i.k(g,h,!!e.j);if(e.j)d=g;else if(d=p.b.moduleLoader)l=g,g=d,p=i.k(d,h);e=u[g];g in u||(e=u[g]=i.u(p.b,g,f,p.e),e.url=i.t(p.url),i.R(e));g==d&&(j=new x,m=h.plugins[d]||h,o(e,function(a){var b,e,g;g=a.dynamic;l="normalize"in a?a.normalize(l,c,m)||"":c(l);e=d+"!"+l;b=u[e];if(!(e in u)){b=i.N(m,e,f,l);g||(u[e]=b);var h=function(a){b.h(a);g||(u[e]=a)};h.resolve=h;h.reject=b.d;a.load(l,b.p,h,m)}j!=b&&o(b,j.h,j.d,j.o)},j.d));return j||e},V:function(){var a;if(!y(n.opera,"Opera"))for(var b in G)if(M[G[b].readyState]==
L){a=b;break}return a}};I={require:i.U,exports:i.B,module:i.T};j.version="0.6.4";"function"==typeof define&&(E=define);"function"==typeof h&&(D=h,h=w);h=i.b(h);u.curl=j;u["curl/_privileged"]={core:i,cache:u,cfg:h,_define:m,_curl:j,Promise:x}})(this);
(function(n,k){function y(){if(!k.body)return w;v||(v=k.createTextNode(""));try{return k.body.removeChild(k.body.appendChild(v)),v=E,q}catch(d){return w}}function r(){var d;d=z[k[B]]&&y();if(!o&&d){o=q;for(clearTimeout(D);m=h.pop();)m();x&&(k[B]="complete");for(var p;p=C.shift();)p()}return d}function A(){r();o||(D=setTimeout(A,d))}var B="readyState",z={loaded:1,interactive:1,complete:1},C=[],x=k&&"string"!=typeof k[B],o=w,d=10,j,m,h=[],D,E,v;j="addEventListener"in n?function(d,h){d.addEventListener(h,
r,w);return function(){d.removeEventListener(h,r,w)}}:function(d,h){d.attachEvent("on"+h,r);return function(){d.detachEvent(h,r)}};k&&!r()&&(h=[j(n,"load"),j(k,"readystatechange"),j(n,"DOMContentLoaded")],D=setTimeout(A,d));define("curl/domReady",function(){function d(h){o?h():C.push(h)}d.then=d;d.amd=q;return d})})(this,this.document);
(function(n,k,y){define("js",["curl/_privileged"],function(n){function A(d,j,m){function h(){o||(k<new Date?m():setTimeout(h,10))}var k,o,v;k=(new Date).valueOf()+(d.aa||3E5);m&&d.a&&setTimeout(h,10);v=n.core.D(d,function(){o=q;d.a&&(d.r=y(d.a));!d.a||d.r?j(v):m()},function(d){o=q;m(d)})}function B(d,j){A(d,function(){var m=C.shift();o=0<C.length;m&&B.apply(null,m);j.resolve(d.r||q)},function(d){j.reject(d)})}var z={},C=[],x=k&&k.createElement("script").async==q,o;return{dynamic:q,load:function(d,
j,m,h){var k,n,r,l;k=0<d.indexOf("!order");n=d.indexOf("!exports=");r=0<n&&d.substr(n+9);l="prefetch"in h?h.prefetch:q;d=k||0<n?d.substr(0,d.indexOf("!")):d;d in z?m(z[d]):(z[d]=void 0,j={name:d,url:j.toUrl(d.lastIndexOf(".")<=d.lastIndexOf("/")?d+".js":d),Y:k,a:r,aa:h.timeout},h={resolve:function(h){z[d]=h;(m.resolve||m)(h)},reject:m.reject||function(d){throw d;}},k&&!x&&o?(C.push([j,h]),l&&(j.G="text/cache",A(j,function(d){d&&d.parentNode.removeChild(d)},function(){}),j.G="")):(o=o||k,B(j,h)))}}})})(this,
this.document,function(n){try{return eval(n)}catch(k){}});define("domReady",["curl/domReady"],function(n){return{load:function(k,y,r){n(r)}}});
/*
MIT License (c) copyright B Cavalier & J Hann */
var p=!0,t=!1;
(function(m){function I(){}function w(a,b){return 0==T.call(a).indexOf("[object "+b)}function u(a){return a&&"/"==a.charAt(a.length-1)?a.substr(0,a.length-1):a}function F(a,b){var c,e,d;e=1;a=a.replace(U,function(a,b,c,g){c&&e++;d=p;return g||""});return d?(c=b.split("/"),c.splice(c.length-e,e),c.concat(a||[]).join("/")):a}function J(a){var b=a.indexOf("!");return{H:a.substr(b+1),j:0<=b&&a.substr(0,b)}}function G(){}function K(a){G.prototype=a;a=new G;G.prototype=L;return a}function s(){function a(a,b,
c){e.push([a,b,c])}function b(a,b){for(var c,d=0;c=e[d++];)(c=c[a])&&c(b)}var c,e,d;c=this;e=[];d=function(c,h){a=c?function(a){a&&a(h)}:function(a,b){b&&b(h)};d=I;b(c?0:1,h);b=I;e=i};this.X=function(b,c,e){a(b,c,e)};this.h=function(a){c.ca=a;d(p,a)};this.d=function(a){c.ba=a;d(t,a)};this.o=function(a){b(2,a)}}function q(a,b,c,e){a instanceof s?a.X(b,c,e):b(a)}function x(a,b,c){var e;return function(){0<=--a&&b&&(e=b.apply(i,arguments));0==a&&c&&c(e);return e}}function z(){function a(b,e,d){var f;
f=g.f(j,i,[].concat(b));this.then=b=function(a,b){q(f,function(b){a&&a.apply(i,b)},function(a){if(b)b(a);else throw a;});return this};this.next=function(b,c){return new a(b,c,f)};e&&b(e);q(d,function(){g.i(f)})}var b=[].slice.call(arguments);w(b[0],"Object")&&(j=g.b(b.shift()));return new a(b[0],b[1])}function M(a){var b=a.id;if(b==i)if(y!==i)y={w:"Multiple anonymous defines in url"};else if(!(b=g.S()))y=a;if(b!=i){var c=l[b];b in l||(c=g.k(b,j).b,c=l[b]=g.t(c,b));if(!(c instanceof s))throw Error("duplicate define: "+
b);c.Z=t;g.u(c,a)}}var j=m.curl,A,B,C=m.document,N=C&&(C.head||C.getElementsByTagName("head")[0]),O={},P={},Q={},D={},L={},T=L.toString,i,R={loaded:1,interactive:Q,complete:1},l={},E=t,y,V=/\?/,S=/^\/|^[^:]+:\/\//,U=/(\.)(\.?)(?:$|\/([^\.\/]+.*)?)/g,W=/\/\*[\s\S]*?\*\/|(?:[^\\])\/\/.*?[\n\r]/g,X=/require\s*\(\s*["']([^"']+)["']\s*\)|(?:[^\\]?)(["'])/g,H,g;g={f:function(a,b,c,e){function d(a){return F(a,h.e)}function f(b,c){var f,k,n,r;f=c&&function(a){c.apply(i,a)};if(w(b,"String")){k=d(b);n=l[k];
r=n instanceof s&&n.a;if(!(k in l))throw Error("Module not resolved: "+k);if(f)throw Error("require(id, callback) not allowed");return r||n}q(g.i(g.f(a,h.e,b,e)),f)}var h;h=new s;h.e=h.id=b||"";h.T=e;h.v=c;h.p=f;f.toUrl=function(b){return g.k(d(b),a).url};h.Y=d;return h},t:function(a,b,c,e){var d,f,h;d=g.f(a,b,i,c);d.e=e==i?b:e;f=d.h;h=x(1,function(a){d.m=a;try{return g.L(d)}catch(b){d.d(b)}});d.h=function(a){q(c||E,function(){f(l[d.id]=h(a))})};d.z=function(a){q(c||E,function(){d.a&&(h(a),d.o(P))})};
return d},K:function(a,b,c,e){a=g.f(a,b,i,c);a.e=e;return a},R:function(a){return a.p},A:function(a){return a.a||(a.a={})},Q:function(a){var b=a.n;b||(b=a.n={id:a.id,uri:g.B(a),exports:g.A(a)},b.a=b.exports);return b},B:function(a){return a.url||(a.url=g.s(a.p.toUrl(a.id)))},b:function(a){var b,c,e;(b=a)||(a={});c=a.apiName;if((e=a.apiContext)||c?e[c]:A&&b)throw Error((c||"curl")+" already exists");(e||m)[c||"curl"]=z;A&&b&&(m.curl=A);c=a.defineName;if((e=a.defineContext)||c?e[c]:B&&b)throw Error((c||
"define")+" already exists");(e||m)[c||"define"]=c=function(){var a=g.P(arguments);M(a)};B&&b&&(m.define=B);c.amd={plugins:p,jQuery:p,curl:"0.6.4"};b&&(g.b=g.D);return g.D(a)},D:function(a){function b(b,c){var d,f,k,n,r;for(r in b){k=b[r];k.name=k.id||k.name||r;n=a;f=J(u(k.name||r));d=f.H;if(f=f.j)n=e[f],n||(n=e[f]=K(a),n.g=K(a.g),n.c=[]),delete b[r];if(c){f=k;var v=void 0;f.path=u(f.path||f.location||"");v=u(f.main)||"main";"."!=v.charAt(0)&&(v="./"+v);f.C=F(v,f.name+"/");f.V=F(v,f.path+"/");f.b=
f.config}else f={path:u(k)};f.I=d.split("/").length;d?(n.g[d]=f,n.c.push(d)):n.r=g.G(k,a)}}function c(a){var b=a.g;a.W=RegExp("^("+a.c.sort(function(a,c){return b[a].I<b[c].I}).join("|").replace(/\/|\./g,"\\$&")+")(?=\\/|$)");delete a.c}var e;a.r=a.baseUrl||"";a.F="pluginPath"in a?a.pluginPath:"curl/plugin";a.g={};e=a.plugins=a.plugins||{};a.c=[];b(a.paths,t);b(a.packages,p);for(var d in e){var f=e[d].c;f&&(e[d].c=f.concat(a.c),c(e[d]))}c(a);g.J(a);return a},J:function(a){var b;(b=a&&a.preloads)&&
0<b.length&&q(E,function(){E=g.i(g.f(a,i,b,p))})},k:function(a,b,c){var e,d,f,h;e=b.g;c&&(b.F&&0>a.indexOf("/")&&!(a in e))&&(f=a=u(b.F)+"/"+a);c=S.test(a)?a:a.replace(b.W,function(b){d=e[b]||{};h=d.b;return d.C&&b==a?(f=d.C,d.V):d.path||""});return{e:f||a,b:h||j,url:g.G(c,b)}},G:function(a,b){var c=b.r;return c&&!S.test(a)?u(c)+"/"+a:a},s:function(a){return a+(V.test(a)?"":".js")},U:function(a,b,c){var e=C.createElement("script");e.onload=e.onreadystatechange=function(c){c=c||m.event;if("load"==
c.type||R[e.readyState])delete D[a.id],e.onload=e.onreadystatechange=e.onerror="",b()};e.onerror=function(){c(Error("Syntax or http error: "+a.url))};e.type=a.$||"text/javascript";e.charset="utf-8";e.async=!a.aa;e.src=a.url;D[a.id]=e;N.insertBefore(e,N.firstChild);return e},M:function(a){var b=[],c;("string"==typeof a?a:a.toSource?a.toSource():a.toString()).replace(W,"").replace(X,function(a,d,f){f?c=c==f?i:c:c||b.push(d);return a});return b},P:function(a){var b,c,e,d,f,h;f=a.length;e=a[f-1];d=w(e,
"Function")?e.length:-1;2==f?w(a[0],"Array")?c=a[0]:b=a[0]:3==f&&(b=a[0],c=a[1]);!c&&0<d&&(h=p,c=["require","exports","module"].slice(0,d).concat(g.M(e)));return{id:b,m:c||[],q:0<=d?e:function(){return e},l:h}},L:function(a){var b;b=a.q.apply(a.l?a.a:i,a.m);b===i&&a.a&&(b=a.n?a.a=a.n.a:a.a);return b},u:function(a,b){a.q=b.q;a.l=b.l;a.v=b.m;g.i(a)},i:function(a){function b(a,b,c){h[b]=a;c&&o(a,b)}function c(b,c){var e,d,f,h;e=x(1,function(a){d(a);k(a,c)});d=x(1,function(a){o(a,c)});f=g.N(b,a);(h=f instanceof
s&&f.a)&&d(h);q(f,e,a.d,a.a&&function(a){f.a&&(a==O?d(f.a):a==P&&e(f.a))})}function e(){a.h(h)}var d,f,h,l,j,o,k;h=[];f=a.v;l=f.length;0==f.length&&e();o=x(l,b,function(){a.z&&a.z(h)});k=x(l,b,e);for(d=0;d<l;d++)j=f[d],j in H?(k(H[j](a),d,p),a.a&&a.o(O)):j?c(j,d):k(i,d,p);return a},O:function(a){g.B(a);g.U(a,function(){var b=y;y=i;a.Z!==t&&(!b||b.w?a.d(Error(b&&b.w||"define() missing or duplicated: "+a.url)):g.u(a,b))},a.d);return a},N:function(a,b){var c,e,d,f,h,i,m,o,k;c=b.Y;e=b.T;d=J(a);i=d.H;
f=c(d.j||i);m=g.k(f,j,!!d.j);if(d.j)h=f;else if(h=m.b.moduleLoader)i=f,f=h,m=g.k(h,j);d=l[f];f in l||(d=l[f]=g.t(m.b,f,e,m.e),d.url=g.s(m.url),g.O(d));f==h&&(o=new s,k=j.plugins[h]||j,q(d,function(a){var b,d,f;f=a.dynamic;i="normalize"in a?a.normalize(i,c,k)||"":c(i);d=h+"!"+i;b=l[d];if(!(d in l)){b=g.K(k,d,e,i);f||(l[d]=b);var j=function(a){b.h(a);f||(l[d]=a)};j.resolve=j;j.reject=b.d;a.load(i,b.p,j,k)}o!=b&&q(b,o.h,o.d,o.o)},o.d));return o||d},S:function(){var a;if(!w(m.opera,"Opera"))for(var b in D)if(R[D[b].readyState]==
Q){a=b;break}return a}};H={require:g.R,exports:g.A,module:g.Q};z.version="0.6.4";"function"==typeof define&&(B=define);"function"==typeof j&&(A=j,j=t);j=g.b(j);l.curl=z;l["curl/_privileged"]={core:g,cache:l,cfg:j,_define:M,_curl:z,Promise:s}})(this);
{
"name": "curl",
"version": "0.6.5",
"description": "A small, fast module and resource loader with dependency management. (AMD, CommonJS Modules/1.1, CSS, HTML, etc.)",
"keywords": ["curl", "cujo", "amd"],
"licenses": [
{
"type": "MIT",
"url": "http://www.opensource.org/licenses/mit-license.php"
}
],
"repositories": [
{
"type": "git",
"url": "https://github.com/cujojs/curl"
}
],
"bugs": "https://github.com/cujojs/curl/issues",
"maintainers": [
{
"name": "John Hann",
"web": "http://unscriptable.com"
},
{
"name": "Brian Cavalier",
"web": "http://hovercraftstudios.com"
}
],
"main": "./src/curl",
"directories": {
"test": "test"
}
}
......@@ -13,6 +13,7 @@
* @experimental
*/
define.amd.ssjs = true;
var require, load;
(function (freeRequire, globalLoad) {
define(/*=='curl/shim/ssjs',==*/ function (require, exports) {
"use strict";
......@@ -104,8 +105,13 @@ define(/*=='curl/shim/ssjs',==*/ function (require, exports) {
function loadScriptViaNodeHttp (def, success, fail) {
var options, source;
options = freeRequire('url').parse(def.url, false, true);
source = http.get(options, success).on('error', fail);
executeScript(source);
source = '';
http.get(options, function (response) {
response
.on('data', function (chunk) { source += chunk; })
.on('end', function () { executeScript(source); success(); })
.on('error', fail);
}).on('error', fail);
}
function failIfInvoked (def) {
......
define(function () {
function MethodSpy (method, context) {
var count, orig, spy;
count = 0;
orig = context[method];
context[method] = function () {
count++;
return orig.apply(context, arguments);
};
return {
calledNever: function () { return count == 0; },
calledOnce: function () { return count == 1; },
calledTwice: function () { return count == 2; },
calledMany: function (howMany) { return count == howMany; }
};
}
return MethodSpy;
});
<!DOCTYPE HTML>
<html>
<head>
<title>noConflict api test</title>
<script>
var curl = function () {}, orig = curl;
</script>
<script src="../src/curl.js" type="text/javascript"></script>
</head>
<body>
</body>
<script type="text/javascript">
try {
curl({
paths: {
curl: '../src/curl/'
}
}
);
write('FAILED: curl should not overwrite global curl');
}
catch (ex) {
write('SUCCESS: curl should threw when it conflicted with no recourse: ' + ex.message);
}
curl({
apiContext: this, apiName: 'curl2'
});
write((orig == curl ? 'SUCCESS' : 'FAILED') + ': curl should restore previous curl()');
write((curl2 ? 'SUCCESS' : 'FAILED') + ': curl should create non-conflicting curl2()');
function write (msg) {
document.body.appendChild(document.createElement('div')).innerHTML = msg;
}
</script>
</html>
<!DOCTYPE HTML>
<html>
<head>
<title>apiName/apiContext curl test file</title>
<script>
foo = {};
curl = {
apiName: 'bar',
apiContext: foo,
paths: {
curl: '../src/curl/'
}
};
</script>
<script src="../src/curl.js" type="text/javascript"></script>
<script type="text/javascript">
var contextifiedCurl = foo.bar;
if(typeof contextifiedCurl !== 'function') {
alert('api context foo.bar failed');
}
else {
contextifiedCurl(
[
'stuff/three',
'domReady!'
]
).then(
function (three) {
if (document.body) {
document.body.appendChild(document.createTextNode('api context foo.bar SUCCESS'));
}
}
);
}
</script>
</head>
<body>
</body>
</html>
<!DOCTYPE HTML>
<html>
<head>
<title>CommonJS Modules 1.1 loading test</title>
<script>
curl = {
paths: {
curl: '../src/curl',
commonjs: 'support/commonjs'
}
};
</script>
<script src="../src/curl.js" type="text/javascript"></script>
<script type="text/javascript">
curl(
[
// test modules:
'commonjs/exports',
'commonjs/this',
'commonjs/hybrid',
'domReady!'
]
).then(
function (exports, thisModule, hybrid) {
document.body.appendChild(document.createTextNode('A module that exports properties loaded successfully if "it works" == ' + exports.testMessage + '.'));
document.body.appendChild(document.createElement('br'));
document.body.appendChild(document.createTextNode('A module that exports as `this` loaded successfully if "it works" == ' + thisModule.testMessage + '.'));
document.body.appendChild(document.createElement('br'));
document.body.appendChild(document.createTextNode('A module that inspects `require("module")` loaded successfully if "commonjs/module" == ' + hybrid.foo.testMessage + '.'));
document.body.appendChild(document.createElement('br'));
document.body.appendChild(document.createTextNode('A module that exposes its module info loaded successfully if this "commonjs/this" == ' + thisModule._module.id + '.'));
}
);
</script>
</head>
<body>
</body>
</html>
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment