Updated Asterix SDK + Easy XDM
diff --git a/asterix-examples/src/main/resources/js/easyXDM/tests/easyTest.js b/asterix-examples/src/main/resources/js/easyXDM/tests/easyTest.js
new file mode 100644
index 0000000..1da4812
--- /dev/null
+++ b/asterix-examples/src/main/resources/js/easyXDM/tests/easyTest.js
@@ -0,0 +1,262 @@
+var easyTest = (function(){
+ var _messages;
+ var _start;
+ var MessageType = {
+ Error: 1,
+ Success: 2,
+ Info: 3
+ };
+
+ /**
+ * Logs the message to the body
+ * @param {String} msg The message to displey
+ * @param {MessageType} type The messagetype
+ */
+ function _log(msg, type){
+ var el = _messages.appendChild(document.createElement("div"));
+ el.innerHTML = msg;
+ _messages.scrollTop = _messages.scrollHeight;
+ switch (type) {
+ case MessageType.Error:
+ el.className = "easyTest_error";
+ break;
+ case MessageType.Success:
+ el.className = "easyTest_success";
+ break;
+ default:
+ el.className = "easyTest_msg";
+ break;
+ }
+ }
+
+ var Assert = {
+ // Type checks
+ isTypeOf: function(type, obj){
+ return typeof obj === type;
+ },
+ isInstanceOf: function(type, obj){
+ return obj instanceof type;
+ },
+ isString: function(obj){
+ return this.isTypeOf("string", obj);
+ },
+ isNumber: function(obj){
+ return this.isTypeOf("number", obj);
+ },
+ isObject: function(obj){
+ return this.isTypeOf("object", obj);
+ },
+ isBoolean: function(obj){
+ return this.isTypeOf("boolean", obj);
+ },
+ isFunction: function(obj){
+ return this.isTypeOf("function", obj);
+ },
+ // Equality
+ areEqual: function(a, b){
+ return a == b;
+ },
+ areNotEqual: function(a, b){
+ return a != b;
+ },
+ // Identical
+ areSame: function(a, b){
+ return a === b;
+ },
+ areNotSame: function(a, b){
+ return a !== b;
+ }
+
+ };
+
+ function Test(test, fn){
+ var _scope, _steps = test.steps, _step, _stepIndex = 0;
+ var _timer, _runStep, _startedAt, _stepStartedAt;
+
+ /**
+ * Clean up and tear down the test.<br/>
+ * Calls back to notify that the test is complete
+ */
+ function _endTest(){
+ // Tear down the test
+ if (test.tearDown) {
+ try {
+ test.tearDown.call(_scope);
+ }
+ catch (ex) {
+ _log("Teardown '" + ex.message + "(" + ex.fileName + ", " + ex.lineNumber + ")" + "'", MessageType.Error);
+ }
+ }
+ for (var key in _scope) {
+ if (_scope.hasOwnProperty(key)) {
+ delete _scope[key];
+ }
+ }
+
+ // Call back
+ fn();
+ }
+
+ /**
+ * Used to notify the framework of the result of the test
+ * @param {String} name The name of the test
+ * @param {Boolean} result The result of the test
+ * @param {String} reason An optional reason why the test returned the result
+ */
+ function _notifyResult(name, result, reason){
+ var now = new Date().getTime();
+ var testsetTime = now - _start.getTime();
+ var testTime = now - _startedAt.getTime();
+ var stepTime = now - _stepStartedAt.getTime();
+
+ var times = testsetTime + "ms, " + testTime + "ms, " + stepTime + "ms - ";
+ if (result) {
+ _log(times + name + " succeeded! " + (reason || ""), MessageType.Success);
+ }
+ else {
+ _log(times + name + " failed! " + (reason || ""), MessageType.Error);
+ if (test.failedMessage) {
+ _log(test.failedMessage, MessageType.Info);
+ }
+ }
+ // Go to next step
+ if (result) {
+ _stepIndex++;
+ window.setTimeout(function(){
+ _runStep();
+ }, 0);
+ }
+ else {
+ _endTest();
+ }
+ }
+
+
+ /**
+ * Runs through the test step
+ */
+ _runStep = function(){
+ if (_stepIndex < _steps.length) {
+ // We still have steps to run
+ _step = _steps[_stepIndex];
+ _stepStartedAt = new Date();
+ if (_step.timeout) {
+ // This an asynchronous test
+ _timer = window.setTimeout(function(){
+ _notifyResult(_step.name, false, "Failed due to timeout.");
+ }, _step.timeout);
+ try {
+ _step.run.call(_scope);
+ }
+ catch (ex) {
+ //If it fails we cancel the timeout
+ window.clearTimeout(_timer);
+ _notifyResult(_step.name, false, "'" + ex.message + "(" + ex.fileName + ", " + ex.lineNumber + ")" + "'");
+ }
+ }
+ else {
+ // This is a synchronous test
+ try {
+ var result = _step.run.call(_scope);
+ _notifyResult(_step.name, result);
+ }
+ catch (ex) {
+ _notifyResult(_step.name, false, "'" + ex.message + "(" + ex.fileName + ", " + ex.lineNumber + ")" + "'");
+ }
+ }
+ }
+ else {
+ _endTest();
+ }
+ };
+
+ return {
+ /**
+ * Runs the test.
+ * Will first try to execute the setup method before continuing the steps
+ */
+ run: function(){
+ var excuse;
+ if (test.runIf) {
+ excuse = test.runIf();
+ }
+ if (excuse) {
+ _log("Skipping test ' " + test.name + "'. " + excuse);
+ fn();
+ }
+ else {
+ _log("Running test '" + test.name + "'");
+ _scope = {
+ Assert: Assert,
+ log: _log,
+ notifyResult: function(result){
+ window.clearTimeout(_timer);
+ _notifyResult(_step.name, result);
+ }
+ };
+ if (test.setUp) {
+ // Setup the test
+ try {
+ test.setUp.call(_scope);
+ _log("Setup succeeded", MessageType.Success);
+ }
+ catch (ex) {
+ _log("Setup failed", MessageType.Error);
+ }
+ }
+ _startedAt = new Date();
+ _runStep();
+ }
+ }
+ };
+ }
+
+ return {
+ /**
+ * Runs through all the tests
+ * @param {Array} tests The tests to run
+ */
+ test: function(testset){
+ var tests = [], testConfig, i = testset.length, test;
+
+ // Prepare the messaging facilities
+ if (!_messages) {
+ _messages = document.createElement("div");
+ _messages.className = "easyTest_messages";
+ (document.getElementById("messages") || document.body).appendChild(_messages);
+ }
+ else {
+ _messages.innerHTML = "";
+ }
+
+ // Convert the testset
+ while (i--) {
+ testConfig = testset[i];
+ if (!testConfig.steps) {
+ // Convert a single step test to a proper test
+ testConfig = {
+ steps: testConfig
+ };
+ }
+
+ tests.push(new Test(testConfig, function(){
+ // Get the next test to run
+ test = tests.pop();
+ if (test) {
+ // This is needed to avoid a strange bug in Opera,
+ window.setTimeout(function(){
+ test.run();
+ }, 0);
+ }
+ else {
+ // No more tests to run
+ _log("Test run complete", MessageType.Info);
+ }
+ }));
+ }
+ // Start the first test
+ _start = new Date();
+ tests.pop().run();
+ }
+ };
+}());