From 8c7c459fe7f4614444f4f9d69745164223905a18 Mon Sep 17 00:00:00 2001 From: nzakas Date: Sat, 12 Feb 2011 13:36:57 -0500 Subject: [PATCH] Cleaned up node CLI --- javascript/build-node.properties | 6 +- javascript/build/yuitest/npm/cli.js | 120 +++-------- .../build/yuitest/npm/lib/yuitest-node.js | 191 ++++++++++++++++++ .../build/yuitest/yuitest-node-debug.js | 191 ++++++++++++++++++ javascript/build/yuitest/yuitest-node-min.js | 3 +- javascript/build/yuitest/yuitest-node.js | 191 ++++++++++++++++++ javascript/src/nodejs/CLI.Logger.js | 89 ++++++++ javascript/src/nodejs/CLI.XUnit.js | 94 +++++++++ javascript/src/nodejs/Node.js | 5 + javascript/src/nodejs/cli.js | 120 +++-------- javascript/tests/asserts/AssertTests.js | 2 +- javascript/tests/asserts/ObjectAssertTests.js | 6 +- 12 files changed, 821 insertions(+), 197 deletions(-) create mode 100644 javascript/src/nodejs/CLI.Logger.js create mode 100644 javascript/src/nodejs/CLI.XUnit.js create mode 100644 javascript/src/nodejs/Node.js diff --git a/javascript/build-node.properties b/javascript/build-node.properties index e7d8b1d..926034f 100644 --- a/javascript/build-node.properties +++ b/javascript/build-node.properties @@ -31,7 +31,11 @@ component.jsfiles= core/YUITest.js, \ reporting/TestFormat.js, \ reporting/CoverageFormat.js, \ core/TestRunner.js, \ + nodejs/Node.js, \ + nodejs/CLI.Logger.js, \ + nodejs/CLI.XUnit.js, \ commonjs/Exports.js #Override -global.build.base = ${component.jsfiles.base}/../build \ No newline at end of file +global.build.base = ${component.jsfiles.base}/../build +component.logger.regex=SHOULD_MATCH_NOTHING diff --git a/javascript/build/yuitest/npm/cli.js b/javascript/build/yuitest/npm/cli.js index 1d2d258..eefe1ac 100644 --- a/javascript/build/yuitest/npm/cli.js +++ b/javascript/build/yuitest/npm/cli.js @@ -4,10 +4,11 @@ var fs = require("fs"), path = require("path"), - //YUITest = require(path.join(process.cwd(), "lib/yuitest-node.js")).YUITest, + vm = require("vm"), YUITest = require("./lib/yuitest-node.js").YUITest, TestRunner = YUITest.TestRunner, - stdout = process.stdout; + stdout = process.stdout, + stderr = process.stderr; //options collected from command line @@ -16,90 +17,7 @@ var options = { }; //----------------------------------------------------------------------------- -// Setup TestRunner -//----------------------------------------------------------------------------- - -stdout.write("YUI Test for Node.js\n"); - -//handles test runner events -function handleEvent(event){ -var message = ""; - switch(event.type){ - case TestRunner.BEGIN_EVENT: - message = "Testing began at " + (new Date()).toString() + "."; - messageType = "info"; - break; - - case TestRunner.COMPLETE_EVENT: - message = "Testing completed at " + - (new Date()).toString() + ".\n" + - "Passed:" + event.results.passed + " Failed:" + event.results.failed + - " Total:" + event.results.total + "(" + event.results.ignored + " ignored)"; - messageType = "info"; - break; - - case TestRunner.TEST_FAIL_EVENT: - message = event.testName + ": failed.\n" + event.error.getMessage(); - messageType = "fail"; - break; - - case TestRunner.TEST_IGNORE_EVENT: - message = event.testName + ": ignored."; - messageType = "ignore"; - break; - - case TestRunner.TEST_PASS_EVENT: - message = event.testName + ": passed."; - messageType = "pass"; - break; - - case TestRunner.TEST_SUITE_BEGIN_EVENT: - message = "Test suite \"" + event.testSuite.name + "\" started."; - messageType = "info"; - break; - - case TestRunner.TEST_SUITE_COMPLETE_EVENT: - message = "Testing completed at " + - (new Date()).toString() + ".\n" + - "Passed:" + event.results.passed + " Failed:" + event.results.failed + - " Total:" + event.results.total + "(" + event.results.ignored + " ignored)"; - messageType = "info"; - break; - - case TestRunner.TEST_CASE_BEGIN_EVENT: - message = "Test case \"" + event.testCase.name + "\" started."; - messageType = "info"; - break; - - case TestRunner.TEST_CASE_COMPLETE_EVENT: - message = "Testing completed at " + - (new Date()).toString() + ".\n" + - "Passed:" + event.results.passed + " Failed:" + event.results.failed + - " Total:" + event.results.total + "(" + event.results.ignored + " ignored)"; - messageType = "info"; - break; - default: - message = "Unexpected event " + event.type; - messageType = "info"; - } - - stdout.write(message + "\n"); -} - - -TestRunner.subscribe(TestRunner.BEGIN_EVENT, handleEvent) -TestRunner.subscribe(TestRunner.TEST_FAIL_EVENT, handleEvent); -TestRunner.subscribe(TestRunner.TEST_PASS_EVENT, handleEvent); -TestRunner.subscribe(TestRunner.TEST_IGNORE_EVENT, handleEvent); -TestRunner.subscribe(TestRunner.TEST_CASE_BEGIN_EVENT, handleEvent); -TestRunner.subscribe(TestRunner.TEST_CASE_COMPLETE_EVENT, handleEvent); -TestRunner.subscribe(TestRunner.TEST_SUITE_BEGIN_EVENT, handleEvent); -TestRunner.subscribe(TestRunner.TEST_SUITE_COMPLETE_EVENT, handleEvent); -TestRunner.subscribe(TestRunner.COMPLETE_EVENT, handleEvent); - - -//----------------------------------------------------------------------------- -// Function get all files in a directory +// Function to get all files in a directory //----------------------------------------------------------------------------- function getFiles(dir){ @@ -161,21 +79,33 @@ files = files.map(function(filename){ return path.join(process.cwd(), filename); }); +//----------------------------------------------------------------------------- +// Setup TestRunner +//----------------------------------------------------------------------------- + +//TODO: Other types of output +YUITest.Node.CLI.XUnit(); + //----------------------------------------------------------------------------- // Include test files //----------------------------------------------------------------------------- -var code = []; +var code = [], i, len; -files.forEach(function(filename){ +if (files.length){ + for (i=0, len=files.length; i < len; i++){ - if (options.verbose){ - stdout.write("Loading " + filename + "\n"); + if (options.verbose){ + stderr.write("Loading " + files[i] + "\n"); + } + + var output = fs.readFileSync(files[i]); + vm.runInThisContext("(function(YUITest){\n" + output + "\n})", files[i])(YUITest); + //code.push(output); } - - var output = fs.readFileSync(filename); - code.push(output); -}); +} else { + process.stdout.write("No tests to run.\n"); +} -eval(code.join("\n\n")); +//eval(code.join("\n\n")); TestRunner.run(); \ No newline at end of file diff --git a/javascript/build/yuitest/npm/lib/yuitest-node.js b/javascript/build/yuitest/npm/lib/yuitest-node.js index 0bfcc3a..8d9b20c 100644 --- a/javascript/build/yuitest/npm/lib/yuitest-node.js +++ b/javascript/build/yuitest/npm/lib/yuitest-node.js @@ -3358,6 +3358,197 @@ YUITest.CoverageFormat = { }(); +//define namespace + +YUITest.Node = { + CLI:{} +}; + + + +/** + * Console output that mimics logger output from YUI Test for YUI 2/3. + * @namespace YUITest.Node.CLI + * @class Logger + * @constructor + */ +YUITest.Node.CLI.Logger = function(){ + + var testRunner = YUITest.TestRunner; + + //handles test runner events + function handleEvent(event){ + + var message = ""; + switch(event.type){ + case testRunner.BEGIN_EVENT: + message = "Testing began at " + (new Date()).toString() + "."; + messageType = "info"; + break; + + case testRunner.COMPLETE_EVENT: + message = "Testing completed at " + + (new Date()).toString() + ".\n" + + "Passed:" + event.results.passed + " Failed:" + event.results.failed + + " Total:" + event.results.total + "(" + event.results.ignored + " ignored)"; + messageType = "info"; + break; + + case testRunner.TEST_FAIL_EVENT: + message = event.testName + ": failed.\n" + event.error.getMessage(); + messageType = "fail"; + break; + + case testRunner.TEST_IGNORE_EVENT: + message = event.testName + ": ignored."; + messageType = "ignore"; + break; + + case testRunner.TEST_PASS_EVENT: + message = event.testName + ": passed."; + messageType = "pass"; + break; + + case testRunner.TEST_SUITE_BEGIN_EVENT: + message = "Test suite \"" + event.testSuite.name + "\" started."; + messageType = "info"; + break; + + case testRunner.TEST_SUITE_COMPLETE_EVENT: + message = "Testing completed at " + + (new Date()).toString() + ".\n" + + "Passed:" + event.results.passed + " Failed:" + event.results.failed + + " Total:" + event.results.total + "(" + event.results.ignored + " ignored)"; + messageType = "info"; + break; + + case testRunner.TEST_CASE_BEGIN_EVENT: + message = "Test case \"" + event.testCase.name + "\" started."; + messageType = "info"; + break; + + case testRunner.TEST_CASE_COMPLETE_EVENT: + message = "Testing completed at " + + (new Date()).toString() + ".\n" + + "Passed:" + event.results.passed + " Failed:" + event.results.failed + + " Total:" + event.results.total + "(" + event.results.ignored + " ignored)"; + messageType = "info"; + break; + default: + message = "Unexpected event " + event.type; + messageType = "info"; + } + + process.stdout.write(message + "\n"); + } + + testRunner.subscribe(testRunner.BEGIN_EVENT, handleEvent) + testRunner.subscribe(testRunner.TEST_FAIL_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_PASS_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_IGNORE_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_CASE_BEGIN_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_CASE_COMPLETE_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_SUITE_BEGIN_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_SUITE_COMPLETE_EVENT, handleEvent); + testRunner.subscribe(testRunner.COMPLETE_EVENT, handleEvent); + +}; + + + +/** + * Console output that mimics XUnit output. + * @namespace YUITest.Node.CLI + * @class XUnit + * @constructor + */ +YUITest.Node.CLI.XUnit = function(){ + + var testRunner = YUITest.TestRunner, + stdout = process.stdout, + failures = [], + stack = []; + + //handles test runner events + function handleEvent(event){ + + var message = "", + results = event.results, + sys = require('sys'), + i, len; + + switch(event.type){ + case testRunner.BEGIN_EVENT: + message = "YUITest for Node.js\n"; + break; + + case testRunner.COMPLETE_EVENT: + message = "\nTotal tests: " + results.total + ", Failures: " + + results.failed + ", Skipped: " + results.ignored + + ", Time: " + (results.duration/1000) + " seconds\n"; + + if (failures.length){ + message += "\nTests failed:\n"; + + for (i=0,len=failures.length; i < len; i++){ + message += "\n" + (i+1) + ") " + failures[i].name + " : " + failures[i].error.getMessage() + "\n"; + //message += "Stack trace:\n" + failures[i].error.stack + "\n"; + } + + message += "\n"; + } + + message += "\n"; + break; + + case testRunner.TEST_FAIL_EVENT: + message = "F"; + failures.push({ + name: stack.concat([event.testName]).join(" > "), + error: event.error + }); + + break; + + case testRunner.TEST_IGNORE_EVENT: + message = "S"; + break; + + case testRunner.TEST_PASS_EVENT: + message = "."; + break; + + case testRunner.TEST_SUITE_BEGIN_EVENT: + stack.push(event.testSuite.name); + break; + + case testRunner.TEST_CASE_COMPLETE_EVENT: + case testRunner.TEST_SUITE_COMPLETE_EVENT: + stack.pop(); + break; + + case testRunner.TEST_CASE_BEGIN_EVENT: + stack.push(event.testCase.name); + break; + + //no default + } + + sys.print(message); + } + + testRunner.subscribe(testRunner.BEGIN_EVENT, handleEvent) + testRunner.subscribe(testRunner.TEST_FAIL_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_PASS_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_IGNORE_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_CASE_BEGIN_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_CASE_COMPLETE_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_SUITE_BEGIN_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_SUITE_COMPLETE_EVENT, handleEvent); + testRunner.subscribe(testRunner.COMPLETE_EVENT, handleEvent); + +}; + //export in CommonJS format exports.YUITest = YUITest; diff --git a/javascript/build/yuitest/yuitest-node-debug.js b/javascript/build/yuitest/yuitest-node-debug.js index 0bfcc3a..8d9b20c 100644 --- a/javascript/build/yuitest/yuitest-node-debug.js +++ b/javascript/build/yuitest/yuitest-node-debug.js @@ -3358,6 +3358,197 @@ YUITest.CoverageFormat = { }(); +//define namespace + +YUITest.Node = { + CLI:{} +}; + + + +/** + * Console output that mimics logger output from YUI Test for YUI 2/3. + * @namespace YUITest.Node.CLI + * @class Logger + * @constructor + */ +YUITest.Node.CLI.Logger = function(){ + + var testRunner = YUITest.TestRunner; + + //handles test runner events + function handleEvent(event){ + + var message = ""; + switch(event.type){ + case testRunner.BEGIN_EVENT: + message = "Testing began at " + (new Date()).toString() + "."; + messageType = "info"; + break; + + case testRunner.COMPLETE_EVENT: + message = "Testing completed at " + + (new Date()).toString() + ".\n" + + "Passed:" + event.results.passed + " Failed:" + event.results.failed + + " Total:" + event.results.total + "(" + event.results.ignored + " ignored)"; + messageType = "info"; + break; + + case testRunner.TEST_FAIL_EVENT: + message = event.testName + ": failed.\n" + event.error.getMessage(); + messageType = "fail"; + break; + + case testRunner.TEST_IGNORE_EVENT: + message = event.testName + ": ignored."; + messageType = "ignore"; + break; + + case testRunner.TEST_PASS_EVENT: + message = event.testName + ": passed."; + messageType = "pass"; + break; + + case testRunner.TEST_SUITE_BEGIN_EVENT: + message = "Test suite \"" + event.testSuite.name + "\" started."; + messageType = "info"; + break; + + case testRunner.TEST_SUITE_COMPLETE_EVENT: + message = "Testing completed at " + + (new Date()).toString() + ".\n" + + "Passed:" + event.results.passed + " Failed:" + event.results.failed + + " Total:" + event.results.total + "(" + event.results.ignored + " ignored)"; + messageType = "info"; + break; + + case testRunner.TEST_CASE_BEGIN_EVENT: + message = "Test case \"" + event.testCase.name + "\" started."; + messageType = "info"; + break; + + case testRunner.TEST_CASE_COMPLETE_EVENT: + message = "Testing completed at " + + (new Date()).toString() + ".\n" + + "Passed:" + event.results.passed + " Failed:" + event.results.failed + + " Total:" + event.results.total + "(" + event.results.ignored + " ignored)"; + messageType = "info"; + break; + default: + message = "Unexpected event " + event.type; + messageType = "info"; + } + + process.stdout.write(message + "\n"); + } + + testRunner.subscribe(testRunner.BEGIN_EVENT, handleEvent) + testRunner.subscribe(testRunner.TEST_FAIL_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_PASS_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_IGNORE_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_CASE_BEGIN_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_CASE_COMPLETE_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_SUITE_BEGIN_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_SUITE_COMPLETE_EVENT, handleEvent); + testRunner.subscribe(testRunner.COMPLETE_EVENT, handleEvent); + +}; + + + +/** + * Console output that mimics XUnit output. + * @namespace YUITest.Node.CLI + * @class XUnit + * @constructor + */ +YUITest.Node.CLI.XUnit = function(){ + + var testRunner = YUITest.TestRunner, + stdout = process.stdout, + failures = [], + stack = []; + + //handles test runner events + function handleEvent(event){ + + var message = "", + results = event.results, + sys = require('sys'), + i, len; + + switch(event.type){ + case testRunner.BEGIN_EVENT: + message = "YUITest for Node.js\n"; + break; + + case testRunner.COMPLETE_EVENT: + message = "\nTotal tests: " + results.total + ", Failures: " + + results.failed + ", Skipped: " + results.ignored + + ", Time: " + (results.duration/1000) + " seconds\n"; + + if (failures.length){ + message += "\nTests failed:\n"; + + for (i=0,len=failures.length; i < len; i++){ + message += "\n" + (i+1) + ") " + failures[i].name + " : " + failures[i].error.getMessage() + "\n"; + //message += "Stack trace:\n" + failures[i].error.stack + "\n"; + } + + message += "\n"; + } + + message += "\n"; + break; + + case testRunner.TEST_FAIL_EVENT: + message = "F"; + failures.push({ + name: stack.concat([event.testName]).join(" > "), + error: event.error + }); + + break; + + case testRunner.TEST_IGNORE_EVENT: + message = "S"; + break; + + case testRunner.TEST_PASS_EVENT: + message = "."; + break; + + case testRunner.TEST_SUITE_BEGIN_EVENT: + stack.push(event.testSuite.name); + break; + + case testRunner.TEST_CASE_COMPLETE_EVENT: + case testRunner.TEST_SUITE_COMPLETE_EVENT: + stack.pop(); + break; + + case testRunner.TEST_CASE_BEGIN_EVENT: + stack.push(event.testCase.name); + break; + + //no default + } + + sys.print(message); + } + + testRunner.subscribe(testRunner.BEGIN_EVENT, handleEvent) + testRunner.subscribe(testRunner.TEST_FAIL_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_PASS_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_IGNORE_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_CASE_BEGIN_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_CASE_COMPLETE_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_SUITE_BEGIN_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_SUITE_COMPLETE_EVENT, handleEvent); + testRunner.subscribe(testRunner.COMPLETE_EVENT, handleEvent); + +}; + //export in CommonJS format exports.YUITest = YUITest; diff --git a/javascript/build/yuitest/yuitest-node-min.js b/javascript/build/yuitest/yuitest-node-min.js index 03c0683..a0a75e5 100644 --- a/javascript/build/yuitest/yuitest-node-min.js +++ b/javascript/build/yuitest/yuitest-node-min.js @@ -2,4 +2,5 @@ var YUITest={version:"@VERSION@"};YUITest.EventTarget=function(){this._handlers= }},isInstanceOf:function(B,C,A){YUITest.Assert._increment();if(!(C instanceof B)){throw new YUITest.ComparisonFailure(YUITest.Assert._formatMessage(A,"Value isn't an instance of expected type."),B,C);}},isNumber:function(B,A){YUITest.Assert._increment();if(typeof B!="number"){throw new YUITest.UnexpectedValue(YUITest.Assert._formatMessage(A,"Value should be a number."),B);}},isObject:function(B,A){YUITest.Assert._increment();if(!B||(typeof B!="object"&&typeof B!="function")){throw new YUITest.UnexpectedValue(YUITest.Assert._formatMessage(A,"Value should be an object."),B);}},isString:function(B,A){YUITest.Assert._increment();if(typeof B!="string"){throw new YUITest.UnexpectedValue(YUITest.Assert._formatMessage(A,"Value should be a string."),B);}},isTypeOf:function(A,C,B){YUITest.Assert._increment();if(typeof C!=A){throw new YUITest.ComparisonFailure(YUITest.Assert._formatMessage(B,"Value should be of type "+A+"."),A,typeof C);}},throwsError:function(D,E,C){YUITest.Assert._increment();var A=false;try{E();}catch(B){if(typeof D=="string"){if(B.message!=D){A=true;}}else{if(typeof D=="function"){if(!(B instanceof D)){A=true;}}else{if(typeof D=="object"&&D!==null){if(!(B instanceof D.constructor)||B.message!=D.message){A=true;}}else{A=true;}}}if(A){throw new YUITest.UnexpectedError(B);}else{return;}}throw new YUITest.AssertionError(YUITest.Assert._formatMessage(C,"Error should have been thrown."));}};YUITest.ArrayAssert={_indexOf:function(B,C){if(B.indexOf){return B.indexOf(C);}else{for(var A=0;A-1){YUITest.Assert.fail(YUITest.Assert._formatMessage(A,"Value found in array ["+B+"]."));}},doesNotContainItems:function(C,D,B){YUITest.Assert._increment();for(var A=0;A-1){YUITest.Assert.fail(YUITest.Assert._formatMessage(B,"Value found in array ["+D+"]."));}}},doesNotContainMatch:function(C,B,A){YUITest.Assert._increment();if(typeof C!="function"){throw new TypeError("ArrayAssert.doesNotContainMatch(): First argument must be a function.");}if(this._some(B,C)){YUITest.Assert.fail(YUITest.Assert._formatMessage(A,"Value found in array ["+B+"]."));}},indexOf:function(E,D,A,C){YUITest.Assert._increment();for(var B=0;B0){YUITest.Assert.fail(YUITest.Assert._formatMessage(A,"Array should be empty."));}},isNotEmpty:function(B,A){YUITest.Assert._increment();if(B.length===0){YUITest.Assert.fail(YUITest.Assert._formatMessage(A,"Array should not be empty."));}},itemsAreSame:function(C,D,B){YUITest.Assert._increment();if(C.length!=D.length){YUITest.Assert.fail(YUITest.Assert._formatMessage(B,"Array should have a length of "+C.length+" but has a length of "+D.length));}for(var A=0;A=0;B--){if(D[B]===E){if(A!=B){YUITest.Assert.fail(YUITest.Assert._formatMessage(C,"Value exists at index "+B+" but should be at index "+A+"."));}return;}}YUITest.Assert.fail(YUITest.Assert._formatMessage(C,"Value doesn't exist in array."));}};YUITest.ObjectAssert={areEqual:function(C,D,B){YUITest.Assert._increment();for(var A in C){if(C.hasOwnProperty(A)){if(C[A]!=D[A]){throw new YUITest.ComparisonFailure(YUITest.Assert._formatMessage(B,"Values should be equal for property "+A),C[A],D[A]);}}}},hasKey:function(A,B,C){YUITest.ObjectAssert.ownsOrInheritsKey(A,B,C);},hasKeys:function(B,A,C){YUITest.ObjectAssert.ownsOrInheritsKeys(B,objects,C);},inheritsKey:function(A,B,C){YUITest.Assert._increment();if(!(A in B&&!B.hasOwnProperty(A))){YUITest.Assert.fail(YUITest.Assert._formatMessage(C,"Property '"+A+"' not found on object instance."));}},inheritsKeys:function(C,A,D){YUITest.Assert._increment();for(var B=0;B0){F[A]=function(){try{B.actualCallCount++;YUITest.Assert.areEqual(G.length,arguments.length,"Method "+A+"() passed incorrect number of arguments.");for(var L=0,J=G.length;L"'&]/g,function(C){switch(C){case"<":return"<"; case">":return">";case'"':return""";case"'":return"'";case"&":return"&";}});}return{JSON:function(B){return YUITest.Util.JSON.stringify(B);},XML:function(C){function B(E){var D="<"+E.type+' name="'+A(E.name)+'"';if(typeof(E.duration)=="number"){D+=' duration="'+E.duration+'"';}if(E.type=="test"){D+=' result="'+E.result+'" message="'+A(E.message)+'">';}else{D+=' passed="'+E.passed+'" failed="'+E.failed+'" ignored="'+E.ignored+'" total="'+E.total+'">';for(var F in E){if(E.hasOwnProperty(F)){if(E[F]&&typeof E[F]=="object"&&!(E[F] instanceof Array)){D+=B(E[F]);}}}}D+="";return D;}return''+B(C);},JUnitXML:function(B){function C(E){var D="";switch(E.type){case"test":if(E.result!="ignore"){D='';if(E.result=="fail"){D+='";}D+="";}break;case"testcase":D='';for(var F in E){if(E.hasOwnProperty(F)){if(E[F]&&typeof E[F]=="object"&&!(E[F] instanceof Array)){D+=C(E[F]);}}}D+="";break;case"testsuite":for(var F in E){if(E.hasOwnProperty(F)){if(E[F]&&typeof E[F]=="object"&&!(E[F] instanceof Array)){D+=C(E[F]);}}}break;case"report":D="";for(var F in E){if(E.hasOwnProperty(F)){if(E[F]&&typeof E[F]=="object"&&!(E[F] instanceof Array)){D+=C(E[F]);}}}D+="";}return D;}return''+C(B);},TAP:function(C){var D=1;function B(E){var F="";switch(E.type){case"test":if(E.result!="ignore"){F="ok "+(D++)+" - "+E.name;if(E.result=="fail"){F="not "+F+" - "+E.message;}F+="\n";}else{F="#Ignored test "+E.name+"\n";}break;case"testcase":F="#Begin testcase "+E.name+"("+E.failed+" failed of "+E.total+")\n";for(var G in E){if(E.hasOwnProperty(G)){if(E[G]&&typeof E[G]=="object"&&!(E[G] instanceof Array)){F+=B(E[G]);}}}F+="#End testcase "+E.name+"\n";break;case"testsuite":F="#Begin testsuite "+E.name+"("+E.failed+" failed of "+E.total+")\n";for(var G in E){if(E.hasOwnProperty(G)){if(E[G]&&typeof E[G]=="object"&&!(E[G] instanceof Array)){F+=B(E[G]);}}}F+="#End testsuite "+E.name+"\n";break;case"report":for(var G in E){if(E.hasOwnProperty(G)){if(E[G]&&typeof E[G]=="object"&&!(E[G] instanceof Array)){F+=B(E[G]);}}}}return F;}return"1.."+C.total+"\n"+B(C);}};}();YUITest.CoverageFormat={JSON:function(A){return YUITest.Util.JSON.stringify(A);},XdebugJSON:function(B){var A={};for(var C in B){if(B.hasOwnProperty(C)){A[C]=B[C].lines;}}return YUITest.Util.JSON.stringify(B);}};YUITest.TestRunner=function(){function B(C){this.testObject=C;this.firstChild=null;this.lastChild=null;this.parent=null;this.next=null;this.results=new YUITest.Results();if(C instanceof YUITest.TestSuite){this.results.type="testsuite";this.results.name=C.name;}else{if(C instanceof YUITest.TestCase){this.results.type="testcase";this.results.name=C.name;}}}B.prototype={appendChild:function(C){var D=new B(C);if(this.firstChild===null){this.firstChild=this.lastChild=D;}else{this.lastChild.next=D;this.lastChild=D;}D.parent=this;return D;}};function A(){YUITest.EventTarget.call(this);this.masterSuite=new YUITest.TestSuite("yuitests"+(new Date()).getTime());this._cur=null;this._root=null;this._log=true;this._waiting=false;this._running=false;this._lastResults=null;this._context=null;}A.prototype=YUITest.Util.mix(new YUITest.EventTarget(),{constructor:YUITest.TestRunner,TEST_CASE_BEGIN_EVENT:"testcasebegin",TEST_CASE_COMPLETE_EVENT:"testcasecomplete",TEST_SUITE_BEGIN_EVENT:"testsuitebegin",TEST_SUITE_COMPLETE_EVENT:"testsuitecomplete",TEST_PASS_EVENT:"pass",TEST_FAIL_EVENT:"fail",ERROR_EVENT:"error",TEST_IGNORE_EVENT:"ignore",COMPLETE_EVENT:"complete",BEGIN_EVENT:"begin",_addTestCaseToTestTree:function(D,E){var F=D.appendChild(E),G,C;for(G in E){if((G.indexOf("test")===0||G.indexOf(" ")>-1)&&typeof E[G]=="function"){F.appendChild(G);}}},_addTestSuiteToTestTree:function(C,F){var E=C.appendChild(F);for(var D=0;D "),error:J.error});break;case E.TEST_IGNORE_EVENT:I="S";break;case E.TEST_PASS_EVENT:I=".";break;case E.TEST_SUITE_BEGIN_EVENT:A.push(J.testSuite.name);break;case E.TEST_CASE_COMPLETE_EVENT:case E.TEST_SUITE_COMPLETE_EVENT:A.pop();break;case E.TEST_CASE_BEGIN_EVENT:A.push(J.testCase.name);break;}K.print(I);}E.subscribe(E.BEGIN_EVENT,C);E.subscribe(E.TEST_FAIL_EVENT,C);E.subscribe(E.TEST_PASS_EVENT,C);E.subscribe(E.TEST_IGNORE_EVENT,C);E.subscribe(E.TEST_CASE_BEGIN_EVENT,C);E.subscribe(E.TEST_CASE_COMPLETE_EVENT,C);E.subscribe(E.TEST_SUITE_BEGIN_EVENT,C);E.subscribe(E.TEST_SUITE_COMPLETE_EVENT,C);E.subscribe(E.COMPLETE_EVENT,C);};exports.YUITest=YUITest; \ No newline at end of file diff --git a/javascript/build/yuitest/yuitest-node.js b/javascript/build/yuitest/yuitest-node.js index 0bfcc3a..8d9b20c 100644 --- a/javascript/build/yuitest/yuitest-node.js +++ b/javascript/build/yuitest/yuitest-node.js @@ -3358,6 +3358,197 @@ YUITest.CoverageFormat = { }(); +//define namespace + +YUITest.Node = { + CLI:{} +}; + + + +/** + * Console output that mimics logger output from YUI Test for YUI 2/3. + * @namespace YUITest.Node.CLI + * @class Logger + * @constructor + */ +YUITest.Node.CLI.Logger = function(){ + + var testRunner = YUITest.TestRunner; + + //handles test runner events + function handleEvent(event){ + + var message = ""; + switch(event.type){ + case testRunner.BEGIN_EVENT: + message = "Testing began at " + (new Date()).toString() + "."; + messageType = "info"; + break; + + case testRunner.COMPLETE_EVENT: + message = "Testing completed at " + + (new Date()).toString() + ".\n" + + "Passed:" + event.results.passed + " Failed:" + event.results.failed + + " Total:" + event.results.total + "(" + event.results.ignored + " ignored)"; + messageType = "info"; + break; + + case testRunner.TEST_FAIL_EVENT: + message = event.testName + ": failed.\n" + event.error.getMessage(); + messageType = "fail"; + break; + + case testRunner.TEST_IGNORE_EVENT: + message = event.testName + ": ignored."; + messageType = "ignore"; + break; + + case testRunner.TEST_PASS_EVENT: + message = event.testName + ": passed."; + messageType = "pass"; + break; + + case testRunner.TEST_SUITE_BEGIN_EVENT: + message = "Test suite \"" + event.testSuite.name + "\" started."; + messageType = "info"; + break; + + case testRunner.TEST_SUITE_COMPLETE_EVENT: + message = "Testing completed at " + + (new Date()).toString() + ".\n" + + "Passed:" + event.results.passed + " Failed:" + event.results.failed + + " Total:" + event.results.total + "(" + event.results.ignored + " ignored)"; + messageType = "info"; + break; + + case testRunner.TEST_CASE_BEGIN_EVENT: + message = "Test case \"" + event.testCase.name + "\" started."; + messageType = "info"; + break; + + case testRunner.TEST_CASE_COMPLETE_EVENT: + message = "Testing completed at " + + (new Date()).toString() + ".\n" + + "Passed:" + event.results.passed + " Failed:" + event.results.failed + + " Total:" + event.results.total + "(" + event.results.ignored + " ignored)"; + messageType = "info"; + break; + default: + message = "Unexpected event " + event.type; + messageType = "info"; + } + + process.stdout.write(message + "\n"); + } + + testRunner.subscribe(testRunner.BEGIN_EVENT, handleEvent) + testRunner.subscribe(testRunner.TEST_FAIL_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_PASS_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_IGNORE_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_CASE_BEGIN_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_CASE_COMPLETE_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_SUITE_BEGIN_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_SUITE_COMPLETE_EVENT, handleEvent); + testRunner.subscribe(testRunner.COMPLETE_EVENT, handleEvent); + +}; + + + +/** + * Console output that mimics XUnit output. + * @namespace YUITest.Node.CLI + * @class XUnit + * @constructor + */ +YUITest.Node.CLI.XUnit = function(){ + + var testRunner = YUITest.TestRunner, + stdout = process.stdout, + failures = [], + stack = []; + + //handles test runner events + function handleEvent(event){ + + var message = "", + results = event.results, + sys = require('sys'), + i, len; + + switch(event.type){ + case testRunner.BEGIN_EVENT: + message = "YUITest for Node.js\n"; + break; + + case testRunner.COMPLETE_EVENT: + message = "\nTotal tests: " + results.total + ", Failures: " + + results.failed + ", Skipped: " + results.ignored + + ", Time: " + (results.duration/1000) + " seconds\n"; + + if (failures.length){ + message += "\nTests failed:\n"; + + for (i=0,len=failures.length; i < len; i++){ + message += "\n" + (i+1) + ") " + failures[i].name + " : " + failures[i].error.getMessage() + "\n"; + //message += "Stack trace:\n" + failures[i].error.stack + "\n"; + } + + message += "\n"; + } + + message += "\n"; + break; + + case testRunner.TEST_FAIL_EVENT: + message = "F"; + failures.push({ + name: stack.concat([event.testName]).join(" > "), + error: event.error + }); + + break; + + case testRunner.TEST_IGNORE_EVENT: + message = "S"; + break; + + case testRunner.TEST_PASS_EVENT: + message = "."; + break; + + case testRunner.TEST_SUITE_BEGIN_EVENT: + stack.push(event.testSuite.name); + break; + + case testRunner.TEST_CASE_COMPLETE_EVENT: + case testRunner.TEST_SUITE_COMPLETE_EVENT: + stack.pop(); + break; + + case testRunner.TEST_CASE_BEGIN_EVENT: + stack.push(event.testCase.name); + break; + + //no default + } + + sys.print(message); + } + + testRunner.subscribe(testRunner.BEGIN_EVENT, handleEvent) + testRunner.subscribe(testRunner.TEST_FAIL_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_PASS_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_IGNORE_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_CASE_BEGIN_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_CASE_COMPLETE_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_SUITE_BEGIN_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_SUITE_COMPLETE_EVENT, handleEvent); + testRunner.subscribe(testRunner.COMPLETE_EVENT, handleEvent); + +}; + //export in CommonJS format exports.YUITest = YUITest; diff --git a/javascript/src/nodejs/CLI.Logger.js b/javascript/src/nodejs/CLI.Logger.js new file mode 100644 index 0000000..5997335 --- /dev/null +++ b/javascript/src/nodejs/CLI.Logger.js @@ -0,0 +1,89 @@ + + +/** + * Console output that mimics logger output from YUI Test for YUI 2/3. + * @namespace YUITest.Node.CLI + * @class Logger + * @constructor + */ +YUITest.Node.CLI.Logger = function(){ + + var testRunner = YUITest.TestRunner; + + //handles test runner events + function handleEvent(event){ + + var message = ""; + switch(event.type){ + case testRunner.BEGIN_EVENT: + message = "Testing began at " + (new Date()).toString() + "."; + messageType = "info"; + break; + + case testRunner.COMPLETE_EVENT: + message = "Testing completed at " + + (new Date()).toString() + ".\n" + + "Passed:" + event.results.passed + " Failed:" + event.results.failed + + " Total:" + event.results.total + "(" + event.results.ignored + " ignored)"; + messageType = "info"; + break; + + case testRunner.TEST_FAIL_EVENT: + message = event.testName + ": failed.\n" + event.error.getMessage(); + messageType = "fail"; + break; + + case testRunner.TEST_IGNORE_EVENT: + message = event.testName + ": ignored."; + messageType = "ignore"; + break; + + case testRunner.TEST_PASS_EVENT: + message = event.testName + ": passed."; + messageType = "pass"; + break; + + case testRunner.TEST_SUITE_BEGIN_EVENT: + message = "Test suite \"" + event.testSuite.name + "\" started."; + messageType = "info"; + break; + + case testRunner.TEST_SUITE_COMPLETE_EVENT: + message = "Testing completed at " + + (new Date()).toString() + ".\n" + + "Passed:" + event.results.passed + " Failed:" + event.results.failed + + " Total:" + event.results.total + "(" + event.results.ignored + " ignored)"; + messageType = "info"; + break; + + case testRunner.TEST_CASE_BEGIN_EVENT: + message = "Test case \"" + event.testCase.name + "\" started."; + messageType = "info"; + break; + + case testRunner.TEST_CASE_COMPLETE_EVENT: + message = "Testing completed at " + + (new Date()).toString() + ".\n" + + "Passed:" + event.results.passed + " Failed:" + event.results.failed + + " Total:" + event.results.total + "(" + event.results.ignored + " ignored)"; + messageType = "info"; + break; + default: + message = "Unexpected event " + event.type; + messageType = "info"; + } + + process.stdout.write(message + "\n"); + } + + testRunner.subscribe(testRunner.BEGIN_EVENT, handleEvent) + testRunner.subscribe(testRunner.TEST_FAIL_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_PASS_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_IGNORE_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_CASE_BEGIN_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_CASE_COMPLETE_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_SUITE_BEGIN_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_SUITE_COMPLETE_EVENT, handleEvent); + testRunner.subscribe(testRunner.COMPLETE_EVENT, handleEvent); + +}; \ No newline at end of file diff --git a/javascript/src/nodejs/CLI.XUnit.js b/javascript/src/nodejs/CLI.XUnit.js new file mode 100644 index 0000000..96d8a5a --- /dev/null +++ b/javascript/src/nodejs/CLI.XUnit.js @@ -0,0 +1,94 @@ + + +/** + * Console output that mimics XUnit output. + * @namespace YUITest.Node.CLI + * @class XUnit + * @constructor + */ +YUITest.Node.CLI.XUnit = function(){ + + var testRunner = YUITest.TestRunner, + stdout = process.stdout, + failures = [], + stack = []; + + //handles test runner events + function handleEvent(event){ + + var message = "", + results = event.results, + sys = require('sys'), + i, len; + + switch(event.type){ + case testRunner.BEGIN_EVENT: + message = "YUITest for Node.js\n"; + break; + + case testRunner.COMPLETE_EVENT: + message = "\nTotal tests: " + results.total + ", Failures: " + + results.failed + ", Skipped: " + results.ignored + + ", Time: " + (results.duration/1000) + " seconds\n"; + + if (failures.length){ + message += "\nTests failed:\n"; + + for (i=0,len=failures.length; i < len; i++){ + message += "\n" + (i+1) + ") " + failures[i].name + " : " + failures[i].error.getMessage() + "\n"; + //message += "Stack trace:\n" + failures[i].error.stack + "\n"; + } + + message += "\n"; + } + + message += "\n"; + break; + + case testRunner.TEST_FAIL_EVENT: + message = "F"; + failures.push({ + name: stack.concat([event.testName]).join(" > "), + error: event.error + }); + + break; + + case testRunner.TEST_IGNORE_EVENT: + message = "S"; + break; + + case testRunner.TEST_PASS_EVENT: + message = "."; + break; + + case testRunner.TEST_SUITE_BEGIN_EVENT: + stack.push(event.testSuite.name); + break; + + case testRunner.TEST_CASE_COMPLETE_EVENT: + case testRunner.TEST_SUITE_COMPLETE_EVENT: + stack.pop(); + break; + + case testRunner.TEST_CASE_BEGIN_EVENT: + stack.push(event.testCase.name); + break; + + //no default + } + + sys.print(message); + } + + testRunner.subscribe(testRunner.BEGIN_EVENT, handleEvent) + testRunner.subscribe(testRunner.TEST_FAIL_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_PASS_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_IGNORE_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_CASE_BEGIN_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_CASE_COMPLETE_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_SUITE_BEGIN_EVENT, handleEvent); + testRunner.subscribe(testRunner.TEST_SUITE_COMPLETE_EVENT, handleEvent); + testRunner.subscribe(testRunner.COMPLETE_EVENT, handleEvent); + +}; \ No newline at end of file diff --git a/javascript/src/nodejs/Node.js b/javascript/src/nodejs/Node.js new file mode 100644 index 0000000..13270ec --- /dev/null +++ b/javascript/src/nodejs/Node.js @@ -0,0 +1,5 @@ +//define namespace + +YUITest.Node = { + CLI:{} +}; \ No newline at end of file diff --git a/javascript/src/nodejs/cli.js b/javascript/src/nodejs/cli.js index 1d2d258..eefe1ac 100644 --- a/javascript/src/nodejs/cli.js +++ b/javascript/src/nodejs/cli.js @@ -4,10 +4,11 @@ var fs = require("fs"), path = require("path"), - //YUITest = require(path.join(process.cwd(), "lib/yuitest-node.js")).YUITest, + vm = require("vm"), YUITest = require("./lib/yuitest-node.js").YUITest, TestRunner = YUITest.TestRunner, - stdout = process.stdout; + stdout = process.stdout, + stderr = process.stderr; //options collected from command line @@ -16,90 +17,7 @@ var options = { }; //----------------------------------------------------------------------------- -// Setup TestRunner -//----------------------------------------------------------------------------- - -stdout.write("YUI Test for Node.js\n"); - -//handles test runner events -function handleEvent(event){ -var message = ""; - switch(event.type){ - case TestRunner.BEGIN_EVENT: - message = "Testing began at " + (new Date()).toString() + "."; - messageType = "info"; - break; - - case TestRunner.COMPLETE_EVENT: - message = "Testing completed at " + - (new Date()).toString() + ".\n" + - "Passed:" + event.results.passed + " Failed:" + event.results.failed + - " Total:" + event.results.total + "(" + event.results.ignored + " ignored)"; - messageType = "info"; - break; - - case TestRunner.TEST_FAIL_EVENT: - message = event.testName + ": failed.\n" + event.error.getMessage(); - messageType = "fail"; - break; - - case TestRunner.TEST_IGNORE_EVENT: - message = event.testName + ": ignored."; - messageType = "ignore"; - break; - - case TestRunner.TEST_PASS_EVENT: - message = event.testName + ": passed."; - messageType = "pass"; - break; - - case TestRunner.TEST_SUITE_BEGIN_EVENT: - message = "Test suite \"" + event.testSuite.name + "\" started."; - messageType = "info"; - break; - - case TestRunner.TEST_SUITE_COMPLETE_EVENT: - message = "Testing completed at " + - (new Date()).toString() + ".\n" + - "Passed:" + event.results.passed + " Failed:" + event.results.failed + - " Total:" + event.results.total + "(" + event.results.ignored + " ignored)"; - messageType = "info"; - break; - - case TestRunner.TEST_CASE_BEGIN_EVENT: - message = "Test case \"" + event.testCase.name + "\" started."; - messageType = "info"; - break; - - case TestRunner.TEST_CASE_COMPLETE_EVENT: - message = "Testing completed at " + - (new Date()).toString() + ".\n" + - "Passed:" + event.results.passed + " Failed:" + event.results.failed + - " Total:" + event.results.total + "(" + event.results.ignored + " ignored)"; - messageType = "info"; - break; - default: - message = "Unexpected event " + event.type; - messageType = "info"; - } - - stdout.write(message + "\n"); -} - - -TestRunner.subscribe(TestRunner.BEGIN_EVENT, handleEvent) -TestRunner.subscribe(TestRunner.TEST_FAIL_EVENT, handleEvent); -TestRunner.subscribe(TestRunner.TEST_PASS_EVENT, handleEvent); -TestRunner.subscribe(TestRunner.TEST_IGNORE_EVENT, handleEvent); -TestRunner.subscribe(TestRunner.TEST_CASE_BEGIN_EVENT, handleEvent); -TestRunner.subscribe(TestRunner.TEST_CASE_COMPLETE_EVENT, handleEvent); -TestRunner.subscribe(TestRunner.TEST_SUITE_BEGIN_EVENT, handleEvent); -TestRunner.subscribe(TestRunner.TEST_SUITE_COMPLETE_EVENT, handleEvent); -TestRunner.subscribe(TestRunner.COMPLETE_EVENT, handleEvent); - - -//----------------------------------------------------------------------------- -// Function get all files in a directory +// Function to get all files in a directory //----------------------------------------------------------------------------- function getFiles(dir){ @@ -161,21 +79,33 @@ files = files.map(function(filename){ return path.join(process.cwd(), filename); }); +//----------------------------------------------------------------------------- +// Setup TestRunner +//----------------------------------------------------------------------------- + +//TODO: Other types of output +YUITest.Node.CLI.XUnit(); + //----------------------------------------------------------------------------- // Include test files //----------------------------------------------------------------------------- -var code = []; +var code = [], i, len; -files.forEach(function(filename){ +if (files.length){ + for (i=0, len=files.length; i < len; i++){ - if (options.verbose){ - stdout.write("Loading " + filename + "\n"); + if (options.verbose){ + stderr.write("Loading " + files[i] + "\n"); + } + + var output = fs.readFileSync(files[i]); + vm.runInThisContext("(function(YUITest){\n" + output + "\n})", files[i])(YUITest); + //code.push(output); } - - var output = fs.readFileSync(filename); - code.push(output); -}); +} else { + process.stdout.write("No tests to run.\n"); +} -eval(code.join("\n\n")); +//eval(code.join("\n\n")); TestRunner.run(); \ No newline at end of file diff --git a/javascript/tests/asserts/AssertTests.js b/javascript/tests/asserts/AssertTests.js index 118cbe0..6ff49bc 100644 --- a/javascript/tests/asserts/AssertTests.js +++ b/javascript/tests/asserts/AssertTests.js @@ -1032,7 +1032,7 @@ }, "isObject() should pass for global object": function(){ - Assert.isObject(self); + Assert.isObject((function(){ return this; })()); }, "isObject() should fail for zero numbers": function(){ diff --git a/javascript/tests/asserts/ObjectAssertTests.js b/javascript/tests/asserts/ObjectAssertTests.js index 5b6819b..29f5a3a 100644 --- a/javascript/tests/asserts/ObjectAssertTests.js +++ b/javascript/tests/asserts/ObjectAssertTests.js @@ -1,5 +1,5 @@ (function(){ - process.stdout.write("HERE"); + var Assert = YUITest.Assert, ObjectAssert = YUITest.ObjectAssert; @@ -272,6 +272,4 @@ YUITest.TestRunner.add(suite); -})(); - -process.stdout.write("THERE"); \ No newline at end of file +})(); \ No newline at end of file