From 033d47083c92bf86987c9518628ed9f75f480cdb Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Fri, 14 Feb 2020 13:10:50 -0600 Subject: [PATCH 1/2] New method of running --- CodewarsReporter.cfc | 40 +++++++++++++++++++++------------------- README.md | 4 ++-- TestRunner.cfc | 37 ------------------------------------- TestRunner.cfm | 44 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 58 deletions(-) delete mode 100644 TestRunner.cfc create mode 100644 TestRunner.cfm diff --git a/CodewarsReporter.cfc b/CodewarsReporter.cfc index a1d4c02..49da45f 100644 --- a/CodewarsReporter.cfc +++ b/CodewarsReporter.cfc @@ -5,21 +5,20 @@ component { /** - * @print a print buffer to use * @testData test results from TestBox */ - function render( print, testData ){ + function render( testData ){ for ( thisBundle in testData.bundleStats ) { // Check if the bundle threw a global exception if ( !isSimpleValue( thisBundle.globalException ) ) { var message = escapeLF( "#thisBundle.globalException.type#:#thisBundle.globalException.message#:#thisBundle.globalException.detail#" ); - print.line( prependLF( "#message#" ) ); + printLine( prependLF( "#message#" ) ); // ACF has an array for the stack trace if ( isSimpleValue( thisBundle.globalException.stacktrace ) ) { - print.line( prependLF( "#escapeLF( thisBundle.globalException.stacktrace )#" ) ); + printLine( prependLF( "#escapeLF( thisBundle.globalException.stacktrace )#" ) ); } } @@ -27,7 +26,7 @@ component { // Generate reports for each suite for ( var suiteStats in thisBundle.suiteStats ) { - genSuiteReport( suiteStats = suiteStats, bundleStats = thisBundle, print = print, debugMap = debugMap ); + genSuiteReport( suiteStats = suiteStats, bundleStats = thisBundle, debugMap = debugMap ); } } } @@ -36,28 +35,27 @@ component { * Recursive Output for suites * @suiteStats Suite stats * @bundleStats Bundle stats - * @print The print Buffer */ - function genSuiteReport( required suiteStats, required bundleStats, required print, debugMap={}, labelPrefix='' ){ + function genSuiteReport( required suiteStats, required bundleStats, debugMap={}, labelPrefix='' ){ labelPrefix &= '/' & arguments.suiteStats.name; - print.line( prependLF( "#arguments.suiteStats.name#" ) ); + printLine( prependLF( "#arguments.suiteStats.name#" ) ); for ( local.thisSpec in arguments.suiteStats.specStats ) { var thisSpecLabel = labelPrefix & '/' & local.thisSpec.name; - print.line( prependLF( "#local.thisSpec.name#" ) ); + printLine( prependLF( "#local.thisSpec.name#" ) ); if( debugMap.keyExists( thisSpecLabel ) ) { - print.line( debugMap[ thisSpecLabel ] ) + printLine( debugMap[ thisSpecLabel ] ) } if ( local.thisSpec.status == "passed" ) { - print.line( prependLF( "Test Passed" ) ); + printLine( prependLF( "Test Passed" ) ); } else if ( local.thisSpec.status == "failed" ) { - print.line( prependLF( "#escapeLF( local.thisSpec.failMessage )#" ) ); + printLine( prependLF( "#escapeLF( local.thisSpec.failMessage )#" ) ); } else if ( local.thisSpec.status == "skipped" ) { - print.line( prependLF( "Test Skipped" ) ); + printLine( prependLF( "Test Skipped" ) ); } else if ( local.thisSpec.status == "error" ) { - print.line( prependLF( "#escapeLF( local.thisSpec.error.message )#" ) ); + printLine( prependLF( "#escapeLF( local.thisSpec.error.message )#" ) ); var errorStack = []; // If there's a tag context, show the file name and line number where the error occurred @@ -78,23 +76,23 @@ component { return "at #item.template#:#item.line#"; } ) .toList( "<:LF:>" ); - print.line( prependLF( "#stacktrace#" ) ); + printLine( prependLF( "#stacktrace#" ) ); } } else { - print.line( prependLF( "Unknown test status: #local.thisSpec.status#" ) ); + printLine( prependLF( "Unknown test status: #local.thisSpec.status#" ) ); } - print.line( prependLF( "#local.thisSpec.totalDuration#" ) ); + printLine( prependLF( "#local.thisSpec.totalDuration#" ) ); } // Handle nested Suites if ( arguments.suiteStats.suiteStats.len() ) { for ( local.nestedSuite in arguments.suiteStats.suiteStats ) { - genSuiteReport( local.nestedSuite, arguments.bundleStats, print, debugMap, labelPrefix ) + genSuiteReport( local.nestedSuite, arguments.bundleStats, debugMap, labelPrefix ) } } - print.line( prependLF( "#arguments.suiteStats.totalDuration#" ) ); + printLine( prependLF( "#arguments.suiteStats.totalDuration#" ) ); } private function escapeLF( required text ){ @@ -115,4 +113,8 @@ component { } + private function printLine( string str ) { + systemoutput( str, 1 ); + } + } diff --git a/README.md b/README.md index 7940093..aa8c8de 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ## testbox-codewars - `CodewarsReporter.cfc`: Custom reporter for TestBox to produce Codewars format -- `TestRunner.cfc`: Runs TestBox tests and produces output for Codewars +- `TestRunner.cfm`: Runs TestBox tests and produces output for Codewars - `CodewarsBaseSpec.cfc`: Base tests for CFML test bundles that captures spec-level debugging output ### Usage @@ -21,5 +21,5 @@ To test locally, create a `Solution.cfc` and `SolutionTest.cfc` in the root dir. Run the task runner with the following command: ```bash -box task run TestRunner +box -clishellpath=/path/to/TestRunner.cfm ``` diff --git a/TestRunner.cfc b/TestRunner.cfc deleted file mode 100644 index 65c2246..0000000 --- a/TestRunner.cfc +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Runs TestBox test and outputs in Codewars format. - * To use, run: - * box task run TestRunner - */ -component { - - function run(){ - // Bootstrap TestBox framework - filesystemUtil.createMapping( "/testbox", resolvepath( "testbox" ) ); - - // Create TestBox and run the tests - testData = new testbox.system.TestBox( options={ coverage : { enabled : false } } ) - .runRaw( - directory = { - // Find all CFCs in this directory that ends with Test. - mapping : filesystemUtil.makePathRelative( getCWD() ), - recurse : false, - filter = function( path ){ - return path.reFindNoCase( "Test\.cfc$" ); - } - } - ) - .getMemento( includeDebugBuffer=true ); - - new CodewarsReporter().render( print, testData ); - - // Flush the buffer - print.toConsole(); - - // Set exit code to 1 on failure - if ( testData.totalFail || testData.totalError ) { - return 1; - } - } - -} diff --git a/TestRunner.cfm b/TestRunner.cfm new file mode 100644 index 0000000..ebceffd --- /dev/null +++ b/TestRunner.cfm @@ -0,0 +1,44 @@ + + + + // Bootstrap TestBox framework + currentDir = getDirectoryFrompath( getCurrentTemplatePath()); + createMapping( '/testbox', currentDir & 'testbox' ); + createMapping( '/codewarsRoot', currentDir ); + + // Create TestBox and run the tests + testData = new testbox.system.TestBox( options={ coverage : { enabled : false } } ) + .runRaw( + directory = { + // Find all CFCs in this directory that ends with Test. + mapping : '/codewarsRoot', + recurse : false, + filter = function( path ){ + return path.reFindNoCase( "Test\.cfc$" ); + } + } + ) + .getMemento( includeDebugBuffer=true ); + + new CodewarsReporter().render( testData ); + + // Set exit code to 1 on failure + if ( testData.totalFail || testData.totalError ) { + return 1; + } + + + function createMapping( mappingName, mappingPath ) { + var mappings = getApplicationSettings().mappings; + if( !structKeyExists( mappings, mappingName ) || mappings[ mappingName ] != mappingPath ) { + mappings[ mappingName ] = mappingPath; + application action='update' mappings='#mappings#'; + } + } + + + \ No newline at end of file From d1f0989f68edd0b7711dff275c9747c8a18ceb02 Mon Sep 17 00:00:00 2001 From: Brad Wood Date: Fri, 14 Feb 2020 14:33:41 -0600 Subject: [PATCH 2/2] handle exit code correctly --- TestRunner.cfm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TestRunner.cfm b/TestRunner.cfm index ebceffd..0fffc42 100644 --- a/TestRunner.cfm +++ b/TestRunner.cfm @@ -28,7 +28,7 @@ // Set exit code to 1 on failure if ( testData.totalFail || testData.totalError ) { - return 1; + createObject( 'java', 'java.lang.System' ).setProperty( 'cfml.cli.exitCode', 1 ); }