Skip to content

New method of running #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 21 additions & 19 deletions CodewarsReporter.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,28 @@
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( "<ERROR::>#message#" ) );
printLine( prependLF( "<ERROR::>#message#" ) );

// ACF has an array for the stack trace
if ( isSimpleValue( thisBundle.globalException.stacktrace ) ) {
print.line( prependLF( "<LOG::-Stacktrace>#escapeLF( thisBundle.globalException.stacktrace )#" ) );
printLine( prependLF( "<LOG::-Stacktrace>#escapeLF( thisBundle.globalException.stacktrace )#" ) );
}
}

var debugMap = prepareDebugBuffer( thisBundle.debugBuffer );

// 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 );
}
}
}
Expand All @@ -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( "<DESCRIBE::>#arguments.suiteStats.name#" ) );
printLine( prependLF( "<DESCRIBE::>#arguments.suiteStats.name#" ) );

for ( local.thisSpec in arguments.suiteStats.specStats ) {
var thisSpecLabel = labelPrefix & '/' & local.thisSpec.name;
print.line( prependLF( "<IT::>#local.thisSpec.name#" ) );
printLine( prependLF( "<IT::>#local.thisSpec.name#" ) );

if( debugMap.keyExists( thisSpecLabel ) ) {
print.line( debugMap[ thisSpecLabel ] )
printLine( debugMap[ thisSpecLabel ] )
}

if ( local.thisSpec.status == "passed" ) {
print.line( prependLF( "<PASSED::>Test Passed" ) );
printLine( prependLF( "<PASSED::>Test Passed" ) );
} else if ( local.thisSpec.status == "failed" ) {
print.line( prependLF( "<FAILED::>#escapeLF( local.thisSpec.failMessage )#" ) );
printLine( prependLF( "<FAILED::>#escapeLF( local.thisSpec.failMessage )#" ) );
} else if ( local.thisSpec.status == "skipped" ) {
print.line( prependLF( "<FAILED::>Test Skipped" ) );
printLine( prependLF( "<FAILED::>Test Skipped" ) );
} else if ( local.thisSpec.status == "error" ) {
print.line( prependLF( "<ERROR::>#escapeLF( local.thisSpec.error.message )#" ) );
printLine( prependLF( "<ERROR::>#escapeLF( local.thisSpec.error.message )#" ) );

var errorStack = [];
// If there's a tag context, show the file name and line number where the error occurred
Expand All @@ -78,23 +76,23 @@ component {
return "at #item.template#:#item.line#";
} )
.toList( "<:LF:>" );
print.line( prependLF( "<LOG::-Stacktrace>#stacktrace#" ) );
printLine( prependLF( "<LOG::-Stacktrace>#stacktrace#" ) );
}
} else {
print.line( prependLF( "<ERROR::>Unknown test status: #local.thisSpec.status#" ) );
printLine( prependLF( "<ERROR::>Unknown test status: #local.thisSpec.status#" ) );
}

print.line( prependLF( "<COMPLETEDIN::>#local.thisSpec.totalDuration#" ) );
printLine( prependLF( "<COMPLETEDIN::>#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( "<COMPLETEDIN::>#arguments.suiteStats.totalDuration#" ) );
printLine( prependLF( "<COMPLETEDIN::>#arguments.suiteStats.totalDuration#" ) );
}

private function escapeLF( required text ){
Expand All @@ -115,4 +113,8 @@ component {

}

private function printLine( string str ) {
systemoutput( str, 1 );
}

}
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
```
37 changes: 0 additions & 37 deletions TestRunner.cfc

This file was deleted.

44 changes: 44 additions & 0 deletions TestRunner.cfm
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<cfsilent>
<!---
Runs TestBox test and outputs in Codewars format.
To use, run:
box -clishellpath=/path/to/TestRunner.cfm
--->
<cfscript>
// 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 ) {
createObject( 'java', 'java.lang.System' ).setProperty( 'cfml.cli.exitCode', 1 );
}


function createMapping( mappingName, mappingPath ) {
var mappings = getApplicationSettings().mappings;
if( !structKeyExists( mappings, mappingName ) || mappings[ mappingName ] != mappingPath ) {
mappings[ mappingName ] = mappingPath;
application action='update' mappings='#mappings#';
}
}


</cfscript></cfsilent>