From 1feb4a6e186f6c34957a2b478004ef4a362e584c Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Thu, 27 Feb 2020 15:57:35 -0600 Subject: [PATCH 01/17] bump --- box.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/box.json b/box.json index 3890a40e..3a158168 100644 --- a/box.json +++ b/box.json @@ -1,6 +1,6 @@ { "name":"TestBox", - "version":"3.2.0", + "version":"3.3.0", "location":"https://downloads.ortussolutions.com/ortussolutions/testbox/@build.version@/testbox-@build.version@.zip", "author":"Ortus Solutions ", "slug":"testbox", From 607dbdd9c784d6d64b7853bcfeb352c66eff5bab Mon Sep 17 00:00:00 2001 From: Zac Spitzer Date: Thu, 19 Mar 2020 12:09:01 +0100 Subject: [PATCH 02/17] spellling --- system/Assertion.cfc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/Assertion.cfc b/system/Assertion.cfc index 2ce44da3..bb66e9fa 100644 --- a/system/Assertion.cfc +++ b/system/Assertion.cfc @@ -523,7 +523,7 @@ component { if ( typeMatches && regexMatches ) { return this; } - // diff messsage types + // diff message types arguments.message = ( len( arguments.message ) ? arguments.message : "The incoming function threw exception [#e.type#] [#e.message#] [#e.detail#] different than expected params type=[#arguments.type#], regex=[#arguments.regex#]" ); From a7c42ff80f243aca5e52d267a0fea68a0a613d45 Mon Sep 17 00:00:00 2001 From: Zac Spitzer Date: Thu, 19 Mar 2020 12:12:43 +0100 Subject: [PATCH 03/17] more spelling fixes --- system/BaseSpec.cfc | 12 ++++++------ system/CollectionExpectation.cfc | 2 +- system/MockBox.cfc | 2 +- system/TestResult.cfc | 4 ++-- system/compat/framework/TestCase.cfc | 10 +++++----- system/coverage/CoverageService.cfc | 2 +- system/coverage/data/CoverageGenerator.cfc | 10 +++++----- system/coverage/data/PathPatternMatcher.cfc | 4 ++-- system/coverage/sonarQube/SonarQube.cfc | 2 +- system/mockutils/MockGenerator.cfc | 4 ++-- system/reports/ConsoleReporter.cfc | 2 +- system/reports/DocReporter.cfc | 2 +- system/reports/DotReporter.cfc | 2 +- system/reports/IReporter.cfc | 2 +- system/reports/JSONReporter.cfc | 2 +- system/reports/JUnitReporter.cfc | 2 +- system/reports/MinReporter.cfc | 2 +- system/reports/MinTextReporter.cfc | 2 +- system/reports/RawReporter.cfc | 2 +- system/reports/SimpleReporter.cfc | 2 +- system/reports/TapReporter.cfc | 2 +- system/reports/TextReporter.cfc | 2 +- system/reports/XMLReporter.cfc | 2 +- system/runners/BaseRunner.cfc | 4 ++-- system/runners/UnitRunner.cfc | 2 +- .../resources/coldbox/system/FrameworkSupertype.cfc | 2 +- .../coldbox/system/cache/ICacheProvider.cfc | 6 +++--- 27 files changed, 46 insertions(+), 46 deletions(-) diff --git a/system/BaseSpec.cfc b/system/BaseSpec.cfc index 78179454..8b026eab 100644 --- a/system/BaseSpec.cfc +++ b/system/BaseSpec.cfc @@ -179,7 +179,7 @@ component { parent : "", // the parent ref parentRef : "", - // hiearachy slug + // hierarchy slug slug : "" }; @@ -204,7 +204,7 @@ component { suite.parent = this.$suiteContext; suite.parentRef = this.$suitesReverseLookup[ this.$suiteContext ]; - // Build hiearachy slug separated by / + // Build hierarchy slug separated by / suite.slug = this.$suitesReverseLookup[ this.$suiteContext ].slug & "/" & this.$suiteContext; if ( left( suite.slug, 1 ) != "/" ) { suite.slug = "/" & suite.slug; @@ -503,7 +503,7 @@ component { order : this.$specOrderIndex++, // the data binding data : arguments.data - }; + }; // skip constraint for suite as a closure if ( isClosure( arguments.skip ) || isCustomFunction( arguments.skip ) ) { @@ -737,8 +737,8 @@ component { } /** - * Start a collection expectation expression. This returns an instance of CollectionExpection - * so you can work with its collection-unrolling matches (delegating to Expection). + * Start a collection expectation expression. This returns an instance of CollectionExpectation + * so you can work with its collection-unrolling matches (delegating to Expectation). * @actual The actual value, it should be an array or a struct. */ CollectionExpectation function expectAll( required any actual ){ @@ -1367,7 +1367,7 @@ component { } /** - * First line are the query columns separated by commas. Then do a consecuent rows separated by line breaks separated by | to denote columns. + * First line are the query columns separated by commas. Then do a consequent rows separated by line breaks separated by | to denote columns. */ function querySim( required queryData ){ return this.$mockBox.querySim( arguments.queryData ); diff --git a/system/CollectionExpectation.cfc b/system/CollectionExpectation.cfc index 0d2b690c..792f25f4 100644 --- a/system/CollectionExpectation.cfc +++ b/system/CollectionExpectation.cfc @@ -32,7 +32,7 @@ component accessors="true" { function onMissingMethod( string missingMethodName, any missingMethodArguments ){ if ( isArray( variables.actual ) ) { for ( var e in variables.actual ) { - // Using evaluate since invoke looses track of positiona argument collections + // Using evaluate since invoke looses track of positional argument collections evaluate( "variables.spec.expect( e ).#arguments.missingMethodName#( argumentCollection=arguments.missingMethodArguments )" ); diff --git a/system/MockBox.cfc b/system/MockBox.cfc index 32e4e91f..965bfaba 100644 --- a/system/MockBox.cfc +++ b/system/MockBox.cfc @@ -581,7 +581,7 @@ Description : obj._mockGenerationPath = getGenerationPath(); // Original Metadata obj._mockOriginalMD = getMetadata(obj); - // Chanining Properties + // Chaining Properties obj._mockCurrentMethod = ""; obj._mockCurrentArgsHash = ""; // Mock Method diff --git a/system/TestResult.cfc b/system/TestResult.cfc index 2bd011e2..1092161a 100644 --- a/system/TestResult.cfc +++ b/system/TestResult.cfc @@ -38,10 +38,10 @@ component accessors="true" { /** * Constructor * @bundleCount.hint the count to init the results for - * @labels.hint The lables to use + * @labels.hint The labels to use * @testBundles.hint The test bundles that should execute ONLY * @testSuites.hint The test suites that should execute ONLY - * @testSpecs.hint The test specs that should execut ONLY + * @testSpecs.hint The test specs that should execute ONLY */ TestResult function init( numeric bundleCount = 0, diff --git a/system/compat/framework/TestCase.cfc b/system/compat/framework/TestCase.cfc index e80aa2a1..9c5ee6c1 100644 --- a/system/compat/framework/TestCase.cfc +++ b/system/compat/framework/TestCase.cfc @@ -47,7 +47,7 @@ component extends="testbox.system.BaseSpec"{ /** * Utility for dynamically adding assertion behaviors at runtime - * @decoratorName.hint The fully qualied name of the assertion component to add; e.g., org.mycompany.MyAssertionComponent + * @decoratorName.hint The fully qualified name of the assertion component to add; e.g., org.mycompany.MyAssertionComponent */ function addAssertDecorator( required string decoratorName ){ var oDecorator = new "#arguments.decoratorName#"(); @@ -208,7 +208,7 @@ component extends="testbox.system.BaseSpec"{ } /** - * Assert that an expected and actual objec is NOT the same instance + * Assert that an expected and actual object is NOT the same instance * This only works on objects that are passed by reference, please remember that in Lucee * arrays pass by reference and in Adobe CF they pass by value. */ @@ -224,7 +224,7 @@ component extends="testbox.system.BaseSpec"{ } /** - * Assert that an expected and actual objec is the same instance + * Assert that an expected and actual object is the same instance * This only works on objects that are passed by reference, please remember that in Lucee * arrays pass by reference and in Adobe CF they pass by value. */ @@ -268,14 +268,14 @@ component extends="testbox.system.BaseSpec"{ } /** - * Assert something is of a certrain object type + * Assert something is of a certain object type */ function assertIsTypeOf( required actual, required typeName, message="" ){ this.$assert.instanceOf( arguments.actual, arguments.typeName, arguments.message ); } /** - * Assert something is of a certrain object type without any inheritance lookup + * Assert something is of a certain object type without any inheritance lookup */ function assertIsExactTypeOf( required o, required type, message="" ){ this.$assert.isEqual( arguments.type, getMetadata( arguments.o ).name, arguments.message ); diff --git a/system/coverage/CoverageService.cfc b/system/coverage/CoverageService.cfc index bc324836..501f17d9 100644 --- a/system/coverage/CoverageService.cfc +++ b/system/coverage/CoverageService.cfc @@ -32,7 +32,7 @@ component accessors="true" { property name="coverageGenerator" type="any"; /** - * Boostrap the Code Coverage service and decide if we'll be enabled or not + * Bootstrap the Code Coverage service and decide if we'll be enabled or not * * @coverageOptions struct of options to initialize with */ diff --git a/system/coverage/data/CoverageGenerator.cfc b/system/coverage/data/CoverageGenerator.cfc index 6daff053..b0b90757 100644 --- a/system/coverage/data/CoverageGenerator.cfc +++ b/system/coverage/data/CoverageGenerator.cfc @@ -78,9 +78,9 @@ component accessors=true { } /** - * @pathToCapture The full path to a folder of code. Searched recursivley - * @whitelist Comma-delimeted list or array of file paths to include - * @blacklist Comma-delimeted list or array of file paths to exclude + * @pathToCapture The full path to a folder of code. Searched recursively + * @whitelist Comma-delimited list or array of file paths to include + * @blacklist Comma-delimited list or array of file paths to exclude * * @Returns query of data */ @@ -160,7 +160,7 @@ component accessors=true { var lineMetric = lineMetricMap.get( javaCast( 'int', currentLineNum ) ); var covered = lineMetric.getCount(); - // Overrides for bugginess ************************************************************************ + // Overrides for buggyiness ************************************************************************ // On Adobe, the first line of CFCs seems to always report as being executable but not running whether it's a comment or a component declaration @@ -222,7 +222,7 @@ component accessors=true { if( strFiledata.numExecutableLines ) { strFiledata.percCoverage = strFiledata.numCoveredLines/strFiledata.numExecutableLines; } else { - // If there's no executable lines in the file, show it as 100% even thoguh we can't divide by zero + // If there's no executable lines in the file, show it as 100% even though we can't divide by zero strFiledata.percCoverage = 1; } queryAddRow( qryData, strFiledata ); diff --git a/system/coverage/data/PathPatternMatcher.cfc b/system/coverage/data/PathPatternMatcher.cfc index 414f400a..dfcbe819 100644 --- a/system/coverage/data/PathPatternMatcher.cfc +++ b/system/coverage/data/PathPatternMatcher.cfc @@ -32,7 +32,7 @@ component accessors="true" singleton { /** * Match a single path to a single pattern. Returns true if the path matches the pattern, otherwise false. * @pattern.hint The pattern to match against the path - * @path.hint The file system path to test. Can be a file or directory. Direcories MUST end with a trailing slash + * @path.hint The file system path to test. Can be a file or directory. Directories MUST end with a trailing slash */ boolean function matchPattern( required string pattern, required string path ) { // Normalize slashes @@ -77,7 +77,7 @@ component accessors="true" singleton { /** * Match an array of patterns against a single path. Returns true if at least one pattern matches, otherwise false. * @patterns.hint An array of patterns to match against the path - * @path.hint The file system path to test. Can be a file or directory. Direcories MUST end with a trailing slash + * @path.hint The file system path to test. Can be a file or directory. Directories MUST end with a trailing slash */ boolean function matchPatterns( required array patterns, required string path ){ for( var pattern in arguments.patterns ) { diff --git a/system/coverage/sonarQube/SonarQube.cfc b/system/coverage/sonarQube/SonarQube.cfc index 3cc6ab77..87268259 100644 --- a/system/coverage/sonarQube/SonarQube.cfc +++ b/system/coverage/sonarQube/SonarQube.cfc @@ -14,7 +14,7 @@ component accessors=true { function init() { - // This transformation will format an XML documente to be indented with line breaks for readability + // This transformation will format an XML document to be indented with line breaks for readability variables.xlt = ' diff --git a/system/mockutils/MockGenerator.cfc b/system/mockutils/MockGenerator.cfc index bbb5f080..94e10210 100644 --- a/system/mockutils/MockGenerator.cfc +++ b/system/mockutils/MockGenerator.cfc @@ -158,7 +158,7 @@ Description : // Returns Something according to metadata? if ( fncMD["returntype"] neq "void" ){ - /* Results Recyling Code, basically, state machine code */ + /* Results Recycling Code, basically, state machine code */ udfOut.append(' if( resultsLen neq 0 ) { if( internalCounter gt resultsLen ) { @@ -190,7 +190,7 @@ Description : stubCode = trim( udfOUt.toString() ); tmpFile = hash( stubCode ) & ".cfm"; - // This is neccessary for methods named after CF keywords like "contains" + // This is necessary for methods named after CF keywords like "contains" var tmpMethodName = 'tmp_#arguments.method#_' & hash( stubCode ); stubCode = replaceNoCase( stubCode, '@@tmpMethodName@@', tmpMethodName, 'all' ); diff --git a/system/reports/ConsoleReporter.cfc b/system/reports/ConsoleReporter.cfc index becda50b..e8115950 100644 --- a/system/reports/ConsoleReporter.cfc +++ b/system/reports/ConsoleReporter.cfc @@ -21,7 +21,7 @@ component extends="BaseReporter"{ /** * Do the reporting thing here using the incoming test results * The report should return back in whatever format they desire and should set any - * Specifc browser types if needed. + * Specific browser types if needed. * @results.hint The instance of the TestBox TestResult object to build a report on * @testbox.hint The TestBox core object * @options.hint A structure of options this reporter needs to build the report with diff --git a/system/reports/DocReporter.cfc b/system/reports/DocReporter.cfc index 8e9a2be8..27ab98f8 100644 --- a/system/reports/DocReporter.cfc +++ b/system/reports/DocReporter.cfc @@ -20,7 +20,7 @@ component extends="BaseReporter"{ /** * Do the reporting thing here using the incoming test results * The report should return back in whatever format they desire and should set any - * Specifc browser types if needed. + * Specific browser types if needed. * @results.hint The instance of the TestBox TestResult object to build a report on * @testbox.hint The TestBox core object * @options.hint A structure of options this reporter needs to build the report with diff --git a/system/reports/DotReporter.cfc b/system/reports/DotReporter.cfc index 5dd01028..817ccc1f 100644 --- a/system/reports/DotReporter.cfc +++ b/system/reports/DotReporter.cfc @@ -20,7 +20,7 @@ component extends="BaseReporter"{ /** * Do the reporting thing here using the incoming test results * The report should return back in whatever format they desire and should set any - * Specifc browser types if needed. + * Specific browser types if needed. * @results.hint The instance of the TestBox TestResult object to build a report on * @testbox.hint The TestBox core object * @options.hint A structure of options this reporter needs to build the report with diff --git a/system/reports/IReporter.cfc b/system/reports/IReporter.cfc index 37e6ba28..3ac2bbbc 100644 --- a/system/reports/IReporter.cfc +++ b/system/reports/IReporter.cfc @@ -14,7 +14,7 @@ interface{ /** * Do the reporting thing here using the incoming test results * The report should return back in whatever format they desire and should set any - * Specifc browser types if needed. + * Specific browser types if needed. * @results.hint The instance of the TestBox TestResult object to build a report on * @testbox.hint The TestBox core object * @options.hint A structure of options this reporter needs to build the report with diff --git a/system/reports/JSONReporter.cfc b/system/reports/JSONReporter.cfc index ab421cd3..090b0246 100644 --- a/system/reports/JSONReporter.cfc +++ b/system/reports/JSONReporter.cfc @@ -18,7 +18,7 @@ component extends="BaseReporter"{ /** * Do the reporting thing here using the incoming test results * The report should return back in whatever format they desire and should set any - * Specifc browser types if needed. + * Specific browser types if needed. * @results.hint The instance of the TestBox TestResult object to build a report on * @testbox.hint The TestBox core object * @options.hint A structure of options this reporter needs to build the report with diff --git a/system/reports/JUnitReporter.cfc b/system/reports/JUnitReporter.cfc index 7c4ea80f..b721cf54 100644 --- a/system/reports/JUnitReporter.cfc +++ b/system/reports/JUnitReporter.cfc @@ -18,7 +18,7 @@ component extends="BaseReporter"{ /** * Do the reporting thing here using the incoming test results * The report should return back in whatever format they desire and should set any - * Specifc browser types if needed. + * Specific browser types if needed. * @results.hint The instance of the TestBox TestResult object to build a report on * @testbox.hint The TestBox core object * @options.hint A structure of options this reporter needs to build the report with diff --git a/system/reports/MinReporter.cfc b/system/reports/MinReporter.cfc index de793da3..661d638d 100644 --- a/system/reports/MinReporter.cfc +++ b/system/reports/MinReporter.cfc @@ -20,7 +20,7 @@ component extends="BaseReporter"{ /** * Do the reporting thing here using the incoming test results * The report should return back in whatever format they desire and should set any - * Specifc browser types if needed. + * Specific browser types if needed. * @results.hint The instance of the TestBox TestResult object to build a report on * @testbox.hint The TestBox core object * @options.hint A structure of options this reporter needs to build the report with diff --git a/system/reports/MinTextReporter.cfc b/system/reports/MinTextReporter.cfc index 6c41f348..5fe2d0b7 100644 --- a/system/reports/MinTextReporter.cfc +++ b/system/reports/MinTextReporter.cfc @@ -20,7 +20,7 @@ component extends="BaseReporter"{ /** * Do the reporting thing here using the incoming test results * The report should return back in whatever format they desire and should set any - * Specifc browser types if needed. + * Specific browser types if needed. * @results.hint The instance of the TestBox TestResult object to build a report on * @testbox.hint The TestBox core object * @options.hint A structure of options this reporter needs to build the report with diff --git a/system/reports/RawReporter.cfc b/system/reports/RawReporter.cfc index e39b4edb..dc8430b8 100644 --- a/system/reports/RawReporter.cfc +++ b/system/reports/RawReporter.cfc @@ -18,7 +18,7 @@ component extends="BaseReporter"{ /** * Do the reporting thing here using the incoming test results * The report should return back in whatever format they desire and should set any - * Specifc browser types if needed. + * Specific browser types if needed. * @results.hint The instance of the TestBox TestResult object to build a report on * @testbox.hint The TestBox core object * @options.hint A structure of options this reporter needs to build the report with diff --git a/system/reports/SimpleReporter.cfc b/system/reports/SimpleReporter.cfc index 867569f8..de1de438 100644 --- a/system/reports/SimpleReporter.cfc +++ b/system/reports/SimpleReporter.cfc @@ -20,7 +20,7 @@ component extends="BaseReporter"{ /** * Do the reporting thing here using the incoming test results * The report should return back in whatever format they desire and should set any - * Specifc browser types if needed. + * Specific browser types if needed. * @results.hint The instance of the TestBox TestResult object to build a report on * @testbox.hint The TestBox core object * @options.hint A structure of options this reporter needs to build the report with diff --git a/system/reports/TapReporter.cfc b/system/reports/TapReporter.cfc index f25ccaf8..06b6a369 100644 --- a/system/reports/TapReporter.cfc +++ b/system/reports/TapReporter.cfc @@ -20,7 +20,7 @@ component extends="BaseReporter"{ /** * Do the reporting thing here using the incoming test results * The report should return back in whatever format they desire and should set any - * Specifc browser types if needed. + * Specific browser types if needed. * @results.hint The instance of the TestBox TestResult object to build a report on * @testbox.hint The TestBox core object * @options.hint A structure of options this reporter needs to build the report with diff --git a/system/reports/TextReporter.cfc b/system/reports/TextReporter.cfc index c3d11793..593c6bb0 100644 --- a/system/reports/TextReporter.cfc +++ b/system/reports/TextReporter.cfc @@ -20,7 +20,7 @@ component extends="BaseReporter"{ /** * Do the reporting thing here using the incoming test results * The report should return back in whatever format they desire and should set any - * Specifc browser types if needed. + * Specific browser types if needed. * @results.hint The instance of the TestBox TestResult object to build a report on * @testbox.hint The TestBox core object * @options.hint A structure of options this reporter needs to build the report with diff --git a/system/reports/XMLReporter.cfc b/system/reports/XMLReporter.cfc index 562787f0..e37283e4 100644 --- a/system/reports/XMLReporter.cfc +++ b/system/reports/XMLReporter.cfc @@ -21,7 +21,7 @@ component extends="BaseReporter"{ /** * Do the reporting thing here using the incoming test results * The report should return back in whatever format they desire and should set any - * Specifc browser types if needed. + * Specific browser types if needed. * @results.hint The instance of the TestBox TestResult object to build a report on * @testbox.hint The TestBox core object * @options.hint A structure of options this reporter needs to build the report with diff --git a/system/runners/BaseRunner.cfc b/system/runners/BaseRunner.cfc index d66ae1ca..2279200f 100644 --- a/system/runners/BaseRunner.cfc +++ b/system/runners/BaseRunner.cfc @@ -102,7 +102,7 @@ component{ // Go downstream little fish, check if you have children suites that are focused if( arguments.checkChildren ){ for( var thisSuite in arguments.suite.suites ){ - // go down the rabitt hole + // go down the rabbit hole if( isSuiteFocused( suite=thisSuite, target=arguments.target, checkParent=false ) ){ return true; } @@ -143,7 +143,7 @@ component{ // Verify nested if no match, maybe it is an embedded suite that is trying to execute. if( results == false && arrayLen( arguments.suite.suites ) ){ for( var thisSuite in arguments.suite.suites ){ - // go down the rabitt hole + // go down the rabbit hole if( canRunSuite( thisSuite, arguments.testResults, arguments.target ) ){ return true; } diff --git a/system/runners/UnitRunner.cfc b/system/runners/UnitRunner.cfc index 91ebfc96..4a95312f 100644 --- a/system/runners/UnitRunner.cfc +++ b/system/runners/UnitRunner.cfc @@ -243,7 +243,7 @@ component extends="testbox.system.runners.BaseRunner" implements="testbox.system /** * Get all the test suites in the passed in bundle * @target.hint The target to get the suites from - * @targetMD.hint The metdata of the target + * @targetMD.hint The metadata of the target * @testResults.hint The test results object */ private array function getTestSuites( diff --git a/tests/resources/coldbox/system/FrameworkSupertype.cfc b/tests/resources/coldbox/system/FrameworkSupertype.cfc index b6281c44..3ce99d23 100644 --- a/tests/resources/coldbox/system/FrameworkSupertype.cfc +++ b/tests/resources/coldbox/system/FrameworkSupertype.cfc @@ -47,7 +47,7 @@ component serializable="false" accessors="true"{ /** * Populate a model object from the request Collection - * @model.hint The name of the model to get and populate or the acutal model object. If you already have an instance of a model, then use the populateBean() method + * @model.hint The name of the model to get and populate or the actual model object. If you already have an instance of a model, then use the populateBean() method * @scope.hint Use scope injection instead of setters population. Ex: scope=variables.instance. * @trustedSetter.hint If set to true, the setter method will be called even if it does not exist in the object * @include.hint A list of keys to include in the population diff --git a/tests/resources/coldbox/system/cache/ICacheProvider.cfc b/tests/resources/coldbox/system/cache/ICacheProvider.cfc index 25119ef3..0a962f93 100644 --- a/tests/resources/coldbox/system/cache/ICacheProvider.cfc +++ b/tests/resources/coldbox/system/cache/ICacheProvider.cfc @@ -68,7 +68,7 @@ Description : - + @@ -104,7 +104,7 @@ Description : - + @@ -166,7 +166,7 @@ Description : - + From 9945047517afb65358de9fee776f1feb7da4a0ee Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Thu, 16 Apr 2020 08:06:51 -0500 Subject: [PATCH 04/17] formatting updates --- .cfformat.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.cfformat.json b/.cfformat.json index 1831cd3d..ff8178cc 100644 --- a/.cfformat.json +++ b/.cfformat.json @@ -44,6 +44,7 @@ "max_columns": 120, "metadata.multiline.element_count": 3, "metadata.multiline.min_length": 40, + "newline":"\n", "property.multiline.element_count": 3, "property.multiline.min_length": 40, "parentheses.padding": true, From 6ad5475f6ff0994733fbf152e68be866101974fa Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Thu, 16 Apr 2020 08:12:54 -0500 Subject: [PATCH 05/17] TESTBOX-273 #resolve Drop old mxunit decorator for ORM Transaction Decorator --- system/decorators/ORMTransactionRollback.cfc | 24 -------------------- 1 file changed, 24 deletions(-) delete mode 100644 system/decorators/ORMTransactionRollback.cfc diff --git a/system/decorators/ORMTransactionRollback.cfc b/system/decorators/ORMTransactionRollback.cfc deleted file mode 100644 index 6eec0455..00000000 --- a/system/decorators/ORMTransactionRollback.cfc +++ /dev/null @@ -1,24 +0,0 @@ -/** -* Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp -* www.ortussolutions.com -* --- -* Wraps tests in Base ORM services transaction blocks so you can automatically rollback -*/ -component extends="mxunit.framework.TestDecorator" { - - function invokeTestMethod(required methodName, args={}){ - var results = ""; - - transaction action="begin"{ - // mark ColdBox ORM transaction - request[ "cbox_aop_transaction" ] = true; - // execute test - results = getTarget().invokeTestMethod( arguments.methodName, arguments.args ); - // rollback - transactionRollback(); - }; - - if( !isNull( "results" ) ){ return results; } - } - -} \ No newline at end of file From b6fbaa64a47ee5600dae5f3f3710ced0f1676f78 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Thu, 16 Apr 2020 08:15:43 -0500 Subject: [PATCH 06/17] TESTBOX-271 #resolve Drop ACF11 Support --- .travis.yml | 1 - box.json | 12 +++++++----- server-adobe@11.json | 15 --------------- 3 files changed, 7 insertions(+), 21 deletions(-) delete mode 100644 server-adobe@11.json diff --git a/.travis.yml b/.travis.yml index f6db0f27..e7dd30df 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,6 @@ notifications: env: matrix: - ENGINE=lucee@5 - - ENGINE=adobe@11 - ENGINE=adobe@2016 - ENGINE=adobe@2018 diff --git a/box.json b/box.json index 3a158168..b5f1dd41 100644 --- a/box.json +++ b/box.json @@ -1,6 +1,6 @@ { "name":"TestBox", - "version":"3.3.0", + "version":"4.0.0", "location":"https://downloads.ortussolutions.com/ortussolutions/testbox/@build.version@/testbox-@build.version@.zip", "author":"Ortus Solutions ", "slug":"testbox", @@ -36,12 +36,14 @@ "watchDelay":"250" }, "dependencies":{ - "cbstreams":"^1.5.0" + "cbstreams":"^1.5.0", + "mockdatacfc":"^3.3.0+22" }, "installPaths":{ - "cbstreams":"system/modules/cbstreams/" - }, - "scripts":{ + "cbstreams":"system/modules/cbstreams/", + "mockdatacfc":"system/modules/mockdatacfc/mockdatacfc/" + }, + "scripts":{ "format":"cfformat run system/**/*.cfc,test-harness/**/*.cfc,tests/specs/**/*.cfc,*.cfc --overwrite", "format:check":"cfformat run system/**/*.cfc,test-harness/**/*.cfc,tests/specs/**/*.cfc,*.cfc --check" } diff --git a/server-adobe@11.json b/server-adobe@11.json deleted file mode 100644 index 6ea9083b..00000000 --- a/server-adobe@11.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name":"testbox-adobe@11", - "force":true, - "openbrowser":"false", - "web":{ - "directoryBrowsing": true, - "http":{ - "port":"49616" - } - }, - "app":{ - "cfengine":"adobe@11", - "serverHomeDirectory":".engine/adobe11" - } -} From cce5ae68b2b11fc8b7d497f1825c06170c99f400 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Thu, 16 Apr 2020 08:26:09 -0500 Subject: [PATCH 07/17] TESTBOX-276 #resolve MockdataCFC is now a first class module in TestBox TESTBOX-277 #resolve New mockData() method in your base specs so you can mock any type of data --- system/BaseSpec.cfc | 13 ++++++++++++- tests/specs/BDDTest.cfc | 8 ++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/system/BaseSpec.cfc b/system/BaseSpec.cfc index 8b026eab..f109a1b7 100644 --- a/system/BaseSpec.cfc +++ b/system/BaseSpec.cfc @@ -11,6 +11,8 @@ component { // MockBox mocking framework variables.$mockBox = this.$mockBox = new testbox.system.MockBox(); + // MockData CFC framework + variables.$mockData = this.$mockData = new testbox.system.modules.mockdatacfc.models.MockData(); // Assertions object variables.$assert = this.$assert = new testbox.system.Assertion(); // Custom Matchers @@ -503,7 +505,7 @@ component { order : this.$specOrderIndex++, // the data binding data : arguments.data - }; + }; // skip constraint for suite as a closure if ( isClosure( arguments.skip ) || isCustomFunction( arguments.skip ) ) { @@ -1373,6 +1375,15 @@ component { return this.$mockBox.querySim( arguments.queryData ); } + /** + * Use MockDataCFC to mock whatever data you want. This funnles to MocData.mock() + * + * @return The mock data you desire sir! + */ + function mockData(){ + retur this.$mockData.mock( argumentCollection=arguments ); + } + /** * Get a reference to the MockBox engine * @generationPath The path to generate the mocks if passed, else uses default location. diff --git a/tests/specs/BDDTest.cfc b/tests/specs/BDDTest.cfc index de1df07c..888858ed 100644 --- a/tests/specs/BDDTest.cfc +++ b/tests/specs/BDDTest.cfc @@ -336,6 +336,14 @@ component extends="testbox.system.BaseSpec"{ exxpect(); }); + it( "can mock any type of data", function(){ + var data = mockData( + "name" : "name", + "age" : "age" + ); + expect( data ).notToBeEmpty(); + }); + }); } From 6417c89effb67f80a7b0c8b310ea7cea1b7f32f0 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Thu, 16 Apr 2020 08:27:50 -0500 Subject: [PATCH 08/17] automated formmating FTW! --- Application.cfc | 18 +- system/Application.cfc | 18 +- system/Assertion.cfc | 186 ++- system/BaseSpec.cfc | 126 +- system/CollectionExpectation.cfc | 6 +- system/Expectation.cfc | 81 +- system/MockBox.cfc | 1469 ++++++++++------- system/TestBox.cfc | 521 +++--- system/TestResult.cfc | 35 +- system/compat/framework/Results.cfc | 76 +- system/compat/framework/TestCase.cfc | 484 ++++-- system/compat/framework/TestSuite.cfc | 50 +- system/compat/runner/DirectoryTestSuite.cfc | 75 +- system/compat/runner/Results.cfc | 81 +- system/coverage/CoverageService.cfc | 280 ++-- system/coverage/browser/CodeBrowser.cfc | 70 +- system/coverage/data/CoverageGenerator.cfc | 256 +-- system/coverage/data/PathPatternMatcher.cfc | 136 +- .../coverage/data/TemplateCompiler_Adobe.cfc | 30 +- .../coverage/data/TemplateCompiler_Lucee.cfc | 269 +-- system/coverage/sonarQube/SonarQube.cfc | 108 +- system/coverage/stats/CoverageStats.cfc | 103 +- system/mockutils/MockGenerator.cfc | 619 ++++--- system/mockutils/Stub.cfc | 4 +- system/reports/ANTJUnitReporter.cfc | 217 ++- system/reports/BaseReporter.cfc | 30 +- system/reports/CodexWikiReporter.cfc | 76 +- system/reports/ConsoleReporter.cfc | 48 +- system/reports/DocReporter.cfc | 60 +- system/reports/DotReporter.cfc | 60 +- system/reports/IReporter.cfc | 39 +- system/reports/JSONReporter.cfc | 42 +- system/reports/JUnitReporter.cfc | 238 +-- system/reports/MinReporter.cfc | 76 +- system/reports/MinTextReporter.cfc | 57 +- system/reports/RawReporter.cfc | 42 +- system/reports/SimpleReporter.cfc | 62 +- system/reports/TapReporter.cfc | 36 +- system/reports/TextReporter.cfc | 43 +- system/reports/XMLReporter.cfc | 44 +- system/runners/BDDRunner.cfc | 291 ++-- system/runners/BaseRunner.cfc | 177 +- system/runners/IRunner.cfc | 36 +- system/runners/UnitRunner.cfc | 356 ++-- system/util/MixerUtil.cfc | 315 ++-- system/util/Util.cfc | 168 +- system/util/XMLConverter.cfc | 642 ++++--- test-harness/Application.cfc | 17 +- test-harness/specs/BDDTest.cfc | 133 +- tests/specs/AssertionsTest.cfc | 48 +- tests/specs/Assertionscf9Test.cfc | 258 +-- tests/specs/BDDInheritanceTest.cfc | 111 +- tests/specs/BDDLifecycleAnnotationsTest.cfc | 33 +- tests/specs/BDDLifecycleTest.cfc | 64 +- tests/specs/BDDTest.cfc | 534 +++--- tests/specs/BaseTest.cfc | 6 +- tests/specs/CustomAssertions.cfc | 31 +- tests/specs/DebugTests.cfc | 74 +- tests/specs/EdgeCases.cfc | 111 +- tests/specs/ExcludesTest.cfc | 46 +- tests/specs/FocusedSpecs.cfc | 86 +- tests/specs/GivenWhenThenTest.cfc | 20 +- tests/specs/InjectTests.cfc | 29 +- tests/specs/LabelsTest.cfc | 74 +- tests/specs/MXUnitCompatTest.cfc | 136 +- tests/specs/NestedAroundEachTest.cfc | 36 +- tests/specs/NestedDescribeTest.cfc | 89 +- tests/specs/SpecDataTests.cfc | 30 +- tests/specs/ThreadCollisions.cfc | 31 +- tests/specs/interfaces/IReporter.cfc | 39 +- tests/specs/mockbox/MockBoxTest.cfc | 857 ++++++---- tests/specs/more/EmbedTest.cfc | 5 +- 72 files changed, 6556 insertions(+), 4598 deletions(-) diff --git a/Application.cfc b/Application.cfc index 552a823f..4fc639ce 100644 --- a/Application.cfc +++ b/Application.cfc @@ -1,11 +1,13 @@ /** -* Copyright Since 2005 Ortus Solutions, Corp -* www.ortussolutions.com -************************************************************************************** -*/ -component{ - this.name = "TestBox Development Suite " & hash( getCurrentTemplatePath() ); - this.sessionManagement = true; + * Copyright Since 2005 Ortus Solutions, Corp + * www.ortussolutions.com + ************************************************************************************** + */ +component { + + this.name = "TestBox Development Suite " & hash( getCurrentTemplatePath() ); + this.sessionManagement = true; // Local mappings this.mappings[ "/testbox" ] = getDirectoryFromPath( getCurrentTemplatePath() ); -} \ No newline at end of file + +} diff --git a/system/Application.cfc b/system/Application.cfc index 64eb74cc..c0091c74 100644 --- a/system/Application.cfc +++ b/system/Application.cfc @@ -1,10 +1,12 @@ /** -* Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp -* www.ortussolutions.com -* --- -* This is the base Application.cfc for the TestBox testing suite -* Whenever you are running tests from within TestBox Core -*/ -component{ + * Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + * This is the base Application.cfc for the TestBox testing suite + * Whenever you are running tests from within TestBox Core + */ +component { + this.name = "TestBox Testing Suite"; -} \ No newline at end of file + +} diff --git a/system/Assertion.cfc b/system/Assertion.cfc index bb66e9fa..55b86f28 100644 --- a/system/Assertion.cfc +++ b/system/Assertion.cfc @@ -14,7 +14,11 @@ component { */ function fail( message = "", detail = "" ){ arguments.message = ( len( arguments.message ) ? arguments.message : "A test failure occurred" ); - throw( type = "TestBox.AssertionFailed", message = arguments.message, detail = arguments.detail ); + throw( + type = "TestBox.AssertionFailed", + message = arguments.message, + detail = arguments.detail + ); } /** @@ -58,7 +62,11 @@ component { * @actual The actual data to test * @message The message to send in the failure */ - function isEqual( any expected, any actual, message = "" ){ + function isEqual( + any expected, + any actual, + message = "" + ){ // validate equality if ( equalize( argumentCollection = arguments ) ) { return this; @@ -76,7 +84,11 @@ component { * @actual The actual data to test * @message The message to send in the failure */ - function isNotEqual( any expected, any actual, message = "" ){ + function isNotEqual( + any expected, + any actual, + message = "" + ){ arguments.message = ( len( arguments.message ) ? arguments.message & ". Expected [#getStringName( arguments.expected )#] Actual [#getStringName( arguments.actual )#]" : "Expected [#getStringName( arguments.expected )#] to not be [#getStringName( arguments.actual )#]" ); @@ -94,7 +106,11 @@ component { * @actual The actual data to test * @message The message to send in the failure */ - function isSameInstance( required any expected, required any actual, message = "" ){ + function isSameInstance( + required any expected, + required any actual, + message = "" + ){ var expectedIdentityHashCode = getIdentityHashCode( arguments.expected ); var actualIdentityHashCode = getIdentityHashCode( arguments.actual ); @@ -115,7 +131,11 @@ component { * @actual The actual data to test * @message The message to send in the failure */ - function isNotSameInstance( required any expected, required any actual, message = "" ){ + function isNotSameInstance( + required any expected, + required any actual, + message = "" + ){ var expectedIdentityHashCode = getIdentityHashCode( arguments.expected ); var actualIdentityHashCode = getIdentityHashCode( arguments.actual ); @@ -136,7 +156,11 @@ component { * @actual The actual data to test * @message The message to send in the failure */ - function isEqualWithCase( string expected, string actual, message = "" ){ + function isEqualWithCase( + string expected, + string actual, + message = "" + ){ arguments.message = ( len( arguments.message ) ? arguments.message : "Expected [#getStringName( arguments.expected )#] but received [#getStringName( arguments.actual )#]" ); @@ -196,7 +220,11 @@ component { * @actual The actual data to check * @message The message to send in the failure */ - function typeOf( required string type, required any actual, message = "" ){ + function typeOf( + required string type, + required any actual, + message = "" + ){ arguments.message = ( len( arguments.message ) ? arguments.message : "Actual data [#getStringName( arguments.actual )#] is not of this type: [#arguments.type#]" ); @@ -212,7 +240,11 @@ component { * @actual The actual data to check * @message The message to send in the failure */ - function notTypeOf( required string type, required any actual, message = "" ){ + function notTypeOf( + required string type, + required any actual, + message = "" + ){ arguments.message = ( len( arguments.message ) ? arguments.message : "Actual data [#getStringName( arguments.actual )#] is actually of this type: [#arguments.type#]" ); @@ -228,7 +260,11 @@ component { * @typeName The typename to check * @message The message to send in the failure */ - function instanceOf( required any actual, required string typeName, message = "" ){ + function instanceOf( + required any actual, + required string typeName, + message = "" + ){ arguments.message = ( len( arguments.message ) ? arguments.message : "The actual data is not of type [#arguments.typeName#]" ); @@ -244,7 +280,11 @@ component { * @typeName The typename to check * @message The message to send in the failure */ - function notInstanceOf( required any actual, required string typeName, message = "" ){ + function notInstanceOf( + required any actual, + required string typeName, + message = "" + ){ arguments.message = ( len( arguments.message ) ? arguments.message : "The actual data is actually of type [#arguments.typeName#]" ); @@ -260,7 +300,11 @@ component { * @regex The regex to check with * @message The message to send in the failure */ - function match( required string actual, required string regex, message = "" ){ + function match( + required string actual, + required string regex, + message = "" + ){ arguments.message = ( len( arguments.message ) ? arguments.message : "The actual [#arguments.actual.toString()#] does not match [#arguments.regex#]" ); @@ -276,7 +320,11 @@ component { * @regex The regex to check with * @message The message to send in the failure */ - function matchWithCase( required string actual, required string regex, message = "" ){ + function matchWithCase( + required string actual, + required string regex, + message = "" + ){ arguments.message = ( len( arguments.message ) ? arguments.message : "The actual [#arguments.actual.toString()#] does not match [#arguments.regex#]" ); @@ -292,7 +340,11 @@ component { * @regex The regex to check with * @message The message to send in the failure */ - function notMatchWithCase( required string actual, required string regex, message = "" ){ + function notMatchWithCase( + required string actual, + required string regex, + message = "" + ){ arguments.message = ( len( arguments.message ) ? arguments.message : "The actual [#arguments.actual.toString()#] does not match [#arguments.regex#]" ); @@ -308,7 +360,11 @@ component { * @regex The regex to check with * @message The message to send in the failure */ - function notMatch( required string actual, required string regex, message = "" ){ + function notMatch( + required string actual, + required string regex, + message = "" + ){ arguments.message = ( len( arguments.message ) ? arguments.message : "The actual [#arguments.actual.toString()#] actually matches [#arguments.regex#]" ); @@ -325,20 +381,24 @@ component { * @key The key to check for existence * @message The message to send in the failure */ - function key( required any target, required string key, message = "" ){ + function key( + required any target, + required string key, + message = "" + ){ arguments.message = ( len( arguments.message ) ? arguments.message : "The key(s) [#arguments.key#] does not exist in the target object. Found keys are [#structKeyArray( arguments.target ).toString()#]" ); // Inflate Key and process - if( + if ( arguments.key .listToArray() .filter( function( thisKey ){ return structKeyExists( target, arguments.thisKey ); } ) .len() != listLen( arguments.key ) - ){ + ) { fail( arguments.message ); } return this; @@ -350,7 +410,11 @@ component { * @key The key to check for existence * @message The message to send in the failure */ - function notKey( required any target, required string key, message = "" ){ + function notKey( + required any target, + required string key, + message = "" + ){ arguments.message = ( len( arguments.message ) ? arguments.message : "The key [#arguments.key#] exists in the target object. Found keys are [#structKeyArray( arguments.target ).toString()#]" ); @@ -360,14 +424,14 @@ component { } // Inflate Key and process - if( + if ( arguments.key .listToArray() .filter( function( thisKey ){ return structKeyExists( target, arguments.thisKey ); } ) .len() > 0 - ){ + ) { fail( arguments.message ); } } @@ -378,7 +442,11 @@ component { * @key The key to check for existence anywhere in the nested structure * @message The message to send in the failure */ - function deepKey( required struct target, required string key, message = "" ){ + function deepKey( + required struct target, + required string key, + message = "" + ){ arguments.message = ( len( arguments.message ) ? arguments.message : "The key [#arguments.key#] does not exist anywhere in the target object." ); @@ -394,7 +462,11 @@ component { * @key The key to check for existence anywhere in the nested structure * @message The message to send in the failure */ - function notDeepKey( required struct target, required string key, message = "" ){ + function notDeepKey( + required struct target, + required string key, + message = "" + ){ var results = structFindKey( arguments.target, arguments.key ); // check if not found? if ( arrayLen( results ) EQ 0 ) { @@ -413,7 +485,11 @@ component { * @length The length to check * @message The message to send in the failure */ - function lengthOf( required any target, required string length, message = "" ){ + function lengthOf( + required any target, + required string length, + message = "" + ){ var aLength = getTargetLength( arguments.target ); // validate it if ( aLength eq arguments.length ) { @@ -433,7 +509,11 @@ component { * @length The length to check * @message The message to send in the failure */ - function notLengthOf( required any target, required string length, message = "" ){ + function notLengthOf( + required any target, + required string length, + message = "" + ){ var aLength = getTargetLength( arguments.target ); // validate it if ( aLength neq arguments.length ) { @@ -612,7 +692,15 @@ component { fail( "The passed in datepart [#arguments.datepart#] is not valid." ); } - if ( abs( dateDiff( arguments.datePart, arguments.actual, arguments.expected ) ) lt arguments.delta ) { + if ( + abs( + dateDiff( + arguments.datePart, + arguments.actual, + arguments.expected + ) + ) lt arguments.delta + ) { return this; } } @@ -673,7 +761,11 @@ component { * @needle The substring to find in a string or the value to find in an array * @message The message to send in the failure */ - function includes( required any target, required any needle, message = "" ){ + function includes( + required any target, + required any needle, + message = "" + ){ arguments.message = ( len( arguments.message ) ? arguments.message : "The needle [#arguments.needle#] was not found in [#arguments.target.toString()#]" ); @@ -696,7 +788,11 @@ component { * @needle The substring to find in a string or the value to find in an array * @message The message to send in the failure */ - function includesWithCase( required any target, required any needle, message = "" ){ + function includesWithCase( + required any target, + required any needle, + message = "" + ){ arguments.message = ( len( arguments.message ) ? arguments.message : "The needle [#arguments.needle#] was not found in [#arguments.target.toString()#]" ); @@ -719,7 +815,11 @@ component { * @needle The substring to find in a string or the value to find in an array * @message The message to send in the failure */ - function notIncludesWithCase( required any target, required any needle, message = "" ){ + function notIncludesWithCase( + required any target, + required any needle, + message = "" + ){ arguments.message = ( len( arguments.message ) ? arguments.message : "The needle [#arguments.needle#] was found in [#arguments.target.toString()#]" ); @@ -742,7 +842,11 @@ component { * @needle The substring to find in a string or the value to find in an array * @message The message to send in the failure */ - function notIncludes( required any target, required any needle, message = "" ){ + function notIncludes( + required any target, + required any needle, + message = "" + ){ arguments.message = ( len( arguments.message ) ? arguments.message : "The needle [#arguments.needle#] was found in [#arguments.target.toString()#]" ); @@ -765,7 +869,11 @@ component { * @target The target value * @message The message to send in the failure */ - function isGT( required any actual, required any target, message = "" ){ + function isGT( + required any actual, + required any target, + message = "" + ){ arguments.message = ( len( arguments.message ) ? arguments.message : "The actual [#arguments.actual#] is not greater than [#arguments.target#]" ); @@ -783,7 +891,11 @@ component { * @target The target value * @message The message to send in the failure */ - function isGTE( required any actual, required any target, message = "" ){ + function isGTE( + required any actual, + required any target, + message = "" + ){ arguments.message = ( len( arguments.message ) ? arguments.message : "The actual [#arguments.actual#] is not greater than or equal to [#arguments.target#]" ); @@ -801,7 +913,11 @@ component { * @target The target value * @message The message to send in the failure */ - function isLT( required any actual, required any target, message = "" ){ + function isLT( + required any actual, + required any target, + message = "" + ){ arguments.message = ( len( arguments.message ) ? arguments.message : "The actual [#arguments.actual#] is not less than [#arguments.target#]" ); @@ -819,7 +935,11 @@ component { * @target The target value * @message The message to send in the failure */ - function isLTE( required any actual, required any target, message = "" ){ + function isLTE( + required any actual, + required any target, + message = "" + ){ arguments.message = ( len( arguments.message ) ? arguments.message : "The actual [#arguments.actual#] is not less than or equal to [#arguments.target#]" ); diff --git a/system/BaseSpec.cfc b/system/BaseSpec.cfc index f109a1b7..a0a84f87 100644 --- a/system/BaseSpec.cfc +++ b/system/BaseSpec.cfc @@ -12,7 +12,7 @@ component { // MockBox mocking framework variables.$mockBox = this.$mockBox = new testbox.system.MockBox(); // MockData CFC framework - variables.$mockData = this.$mockData = new testbox.system.modules.mockdatacfc.models.MockData(); + variables.$mockData = this.$mockData = new testbox.system.modules.mockdatacfc.models.MockData(); // Assertions object variables.$assert = this.$assert = new testbox.system.Assertion(); // Custom Matchers @@ -36,10 +36,7 @@ component { // Current Executing Spec this.$currentExecutingSpec = ""; // Focused Structures - this.$focusedTargets = { - "suites" : [], - "specs" : [] - }; + this.$focusedTargets = { "suites" : [], "specs" : [] }; /************************************** BDD & EXPECTATIONS METHODS *********************************************/ @@ -126,7 +123,7 @@ component { any skip = false ){ arguments.focused = true; - return this.describe( argumentCollection=arguments ); + return this.describe( argumentCollection = arguments ); } /** @@ -145,7 +142,7 @@ component { any labels = [], boolean asyncAll = false, any skip = false, - boolean focused = false + boolean focused = false ){ // closure checks if ( !isClosure( arguments.body ) && !isCustomFunction( arguments.body ) ) { @@ -237,7 +234,7 @@ component { } // Are we focused? - if( arguments.focused ){ + if ( arguments.focused ) { arrayAppend( this.$focusedTargets.suites, suite.slug & "/" & suite.name ); } @@ -454,7 +451,7 @@ component { struct data = {} ){ arguments.focused = true; - return this.it( argumentCollection=arguments ); + return this.it( argumentCollection = arguments ); } /** @@ -470,9 +467,9 @@ component { any function it( required string title, required any body, - any labels = [], - any skip = false, - struct data = {}, + any labels = [], + any skip = false, + struct data = {}, boolean focused = false ){ // closure checks @@ -521,7 +518,7 @@ component { arrayAppend( this.$suitesReverseLookup[ this.$suiteContext ].specs, spec ); // Are we focused? - if( arguments.focused ){ + if ( arguments.focused ) { var thisSuite = this.$suitesReverseLookup[ this.$suiteContext ]; arrayAppend( this.$focusedTargets.specs, thisSuite.slug & "/" & thisSuite.name & "/" & spec.name ); } @@ -719,7 +716,11 @@ component { */ Expectation function expect( any actual ){ // build an expectation - var oExpectation = new Expectation( spec = this, assertions = this.$assert, mockbox = this.$mockbox ); + var oExpectation = new Expectation( + spec = this, + assertions = this.$assert, + mockbox = this.$mockbox + ); // Store the actual data if ( !isNull( arguments.actual ) ) { @@ -744,7 +745,11 @@ component { * @actual The actual value, it should be an array or a struct. */ CollectionExpectation function expectAll( required any actual ){ - return new CollectionExpectation( spec = this, assertions = this.$assert, collection = arguments.actual ); + return new CollectionExpectation( + spec = this, + assertions = this.$assert, + collection = arguments.actual + ); } /** @@ -755,7 +760,11 @@ component { // register structure if ( isStruct( arguments.matchers ) ) { // register the custom matchers with override - structAppend( this.$customMatchers, arguments.matchers, true ); + structAppend( + this.$customMatchers, + arguments.matchers, + true + ); return this; } @@ -789,7 +798,11 @@ component { // register structure if ( isStruct( arguments.assertions ) ) { // register the custom matchers with override - structAppend( this.$assert, arguments.assertions, true ); + structAppend( + this.$assert, + arguments.assertions, + true + ); return this; } @@ -829,9 +842,7 @@ component { string testSuites = "", string reporter = "simple", string labels = "" - ) - output=true - { + ) output=true{ // content type defaulted, to avoid dreaded wddx default getPageContext().getResponse().setContentType( "text/html" ); // run tests @@ -889,7 +900,11 @@ component { arrayLen( this.$focusedTargets.specs ) && arrayFindNoCase( this.$focusedTargets.specs, name ) || // Are we in the focused Suite? - arrayLen( this.$focusedTargets.suites ) && runner.isSuiteFocused( suite=suite, target=this, checkChildren=false ) + arrayLen( this.$focusedTargets.suites ) && runner.isSuiteFocused( + suite = suite, + target = this, + checkChildren = false + ) ) ); }; @@ -972,14 +987,23 @@ component { while ( !isSimpleValue( parentSuite ) ) { arrayAppend( reverseTree, - { beforeEach : parentSuite.beforeEach, beforeEachData : parentSuite.beforeEachData } + { + beforeEach : parentSuite.beforeEach, + beforeEachData : parentSuite.beforeEachData + } ); parentSuite = parentSuite.parentRef; } // Incorporate annotated methods arrayEach( this.$utility.getAnnotatedMethods( annotation = "beforeEach", metadata = getMetadata( this ) ), function( item ){ - arrayAppend( reverseTree, { beforeEach : this[ arguments.item.name ], beforeEachData : {} } ); + arrayAppend( + reverseTree, + { + beforeEach : this[ arguments.item.name ], + beforeEachData : {} + } + ); } ); // sort tree backwards @@ -1089,7 +1113,11 @@ component { // Return the closure of execution for a single spec ONLY return function(){ // Execute the body of the spec - nextClosure.body( spec = thread.spec, suite = thread.suite, data = nextClosure.data ); + nextClosure.body( + spec = thread.spec, + suite = thread.suite, + data = nextClosure.data + ); }; } @@ -1134,7 +1162,11 @@ component { } arrayEach( this.$utility.getAnnotatedMethods( annotation = "afterEach", metadata = getMetadata( this ) ), function( item ){ - invoke( this, item.name, { currentSpec : spec.name, data : {} } ); + invoke( + this, + item.name, + { currentSpec : spec.name, data : {} } + ); } ); return this; @@ -1193,7 +1225,13 @@ component { rethrow; } // if not the expected exception, then fail it - if ( !isExpectedException( e, arguments.spec.name, arguments.runner ) ) { + if ( + !isExpectedException( + e, + arguments.spec.name, + arguments.runner + ) + ) { $assert.fail( "Method did not throw expected exception: [#this.$expectedException.toString()#], actual exception [type:#e.type#][message:#e.message#]" ); @@ -1252,7 +1290,11 @@ component { * @top Apply a top to the dump, by default it does 9999 levels */ any function console( required var, top = 9999 ){ - writeDump( var = arguments.var, output = "console", top = arguments.top ); + writeDump( + var = arguments.var, + output = "console", + top = arguments.top + ); return this; } @@ -1339,7 +1381,11 @@ component { * @method The private method to expose * @newName If passed, it will expose the method with this name, else just uses the same name */ - any function makePublic( required any target, required string method, string newName = "" ){ + any function makePublic( + required any target, + required string method, + string newName = "" + ){ // decorate it this.$utility.getMixerUtil().start( arguments.target ); // expose it @@ -1381,7 +1427,7 @@ component { * @return The mock data you desire sir! */ function mockData(){ - retur this.$mockData.mock( argumentCollection=arguments ); + retur this.$mockData.mock( argumentCollection = arguments ); } /** @@ -1401,7 +1447,11 @@ component { * @object The object to mock, already instantiated * @callLogging Add method call logging for all mocked methods. Defaults to true */ - function createEmptyMock( string className, any object, boolean callLogging = true ){ + function createEmptyMock( + string className, + any object, + boolean callLogging = true + ){ return this.$mockBox.createEmptyMock( argumentCollection = arguments ); } @@ -1416,7 +1466,7 @@ component { string className, any object, boolean clearMethods = false - boolean callLogging =true + boolean callLogging =true ){ return this.$mockBox.createMock( argumentCollection = arguments ); } @@ -1436,7 +1486,11 @@ component { * @extends Make the stub extend from certain CFC * @implements Make the stub adhere to an interface */ - function createStub( boolean callLogging = true, string extends = "", string implements = "" ){ + function createStub( + boolean callLogging = true, + string extends = "", + string implements = "" + ){ return this.$mockBox.createStub( argumentCollection = arguments ); } @@ -1473,7 +1527,11 @@ component { /** * Check if the incoming exception is expected or not. */ - boolean function isExpectedException( required exception, required specName, required runner ){ + boolean function isExpectedException( + required exception, + required specName, + required runner + ){ var results = false; // normalize expected exception @@ -1502,4 +1560,4 @@ component { return results; } -} \ No newline at end of file +} diff --git a/system/CollectionExpectation.cfc b/system/CollectionExpectation.cfc index 792f25f4..3ab671f8 100644 --- a/system/CollectionExpectation.cfc +++ b/system/CollectionExpectation.cfc @@ -21,7 +21,11 @@ component accessors="true" { * @assertions The assertions library * @collection The collection target */ - function init( required spec, required any assertions, required collection ){ + function init( + required spec, + required any assertions, + required collection + ){ variables.actual = arguments.collection; variables.spec = arguments.spec; variables.assert = arguments.assertions; diff --git a/system/Expectation.cfc b/system/Expectation.cfc index f1c60715..44f69d22 100644 --- a/system/Expectation.cfc +++ b/system/Expectation.cfc @@ -28,7 +28,11 @@ component accessors="true" { * @assertions The TestBox assertions object: testbox.system.Assertion * @mockbox A reference to MockBox */ - function init( required any spec, required any assertions, required any mockBox ){ + function init( + required any spec, + required any assertions, + required any mockBox + ){ variables.spec = arguments.spec; variables.mockBox = arguments.mockbox; variables.assert = arguments.assertions; @@ -73,11 +77,14 @@ component accessors="true" { this.isNot = true; // execute the dynamic method - var results = invoke( this, arguments.missingMethodName, arguments.missingMethodArguments ); + var results = invoke( + this, + arguments.missingMethodName, + arguments.missingMethodArguments + ); if ( !isNull( results ) ) { return results; - } - else { + } else { return; } } @@ -103,7 +110,11 @@ component accessors="true" { } // throw exception - throw(type="InvalidMethod", message="The dynamic/static method: #arguments.missingMethodName# does not exist in this CFC", detail="Available methods are #structKeyArray( this ).toString()#"); + throw( + type = "InvalidMethod", + message = "The dynamic/static method: #arguments.missingMethodName# does not exist in this CFC", + detail = "Available methods are #structKeyArray( this ).toString()#" + ); } /** @@ -333,7 +344,11 @@ component accessors="true" { * @regex Match this regex against the message of the exception * @message The message to send in the failure */ - function toThrow( type = "", regex = ".*", message = "" ){ + function toThrow( + type = "", + regex = ".*", + message = "" + ){ arguments.target = this.actual; if ( this.isNot ) { variables.assert.notThrows( argumentCollection = arguments ); @@ -379,7 +394,11 @@ component accessors="true" { * @max The expected max number or date * @message The message to send in the failure */ - function toBeBetween( required any min, required any max, message = "" ){ + function toBeBetween( + required any min, + required any max, + message = "" + ){ arguments.actual = this.actual; if ( this.isNot ) { try { @@ -438,9 +457,17 @@ component accessors="true" { len( arguments.message ) ? arguments.message : "The actual [#this.actual#] is not greater than [#arguments.target#]" ); if ( this.isNot ) { - variables.assert.isLTE( this.actual, arguments.target, arguments.message ); + variables.assert.isLTE( + this.actual, + arguments.target, + arguments.message + ); } else { - variables.assert.isGT( this.actual, arguments.target, arguments.message ); + variables.assert.isGT( + this.actual, + arguments.target, + arguments.message + ); } return this; } @@ -455,9 +482,17 @@ component accessors="true" { len( arguments.message ) ? arguments.message : "The actual [#this.actual#] is not greater than or equal to [#arguments.target#]" ); if ( this.isNot ) { - variables.assert.isLT( this.actual, arguments.target, arguments.message ); + variables.assert.isLT( + this.actual, + arguments.target, + arguments.message + ); } else { - variables.assert.isGTE( this.actual, arguments.target, arguments.message ); + variables.assert.isGTE( + this.actual, + arguments.target, + arguments.message + ); } return this; } @@ -472,9 +507,17 @@ component accessors="true" { len( arguments.message ) ? arguments.message : "The actual [#this.actual#] is not less than [#arguments.target#]" ); if ( this.isNot ) { - variables.assert.isGTE( this.actual, arguments.target, arguments.message ); + variables.assert.isGTE( + this.actual, + arguments.target, + arguments.message + ); } else { - variables.assert.isLT( this.actual, arguments.target, arguments.message ); + variables.assert.isLT( + this.actual, + arguments.target, + arguments.message + ); } return this; } @@ -489,9 +532,17 @@ component accessors="true" { len( arguments.message ) ? arguments.message : "The actual [#this.actual#] is not less than or equal to [#arguments.target#]" ); if ( this.isNot ) { - variables.assert.isGT( this.actual, arguments.target, arguments.message ); + variables.assert.isGT( + this.actual, + arguments.target, + arguments.message + ); } else { - variables.assert.isLTE( this.actual, arguments.target, arguments.message ); + variables.assert.isLTE( + this.actual, + arguments.target, + arguments.message + ); } return this; } diff --git a/system/MockBox.cfc b/system/MockBox.cfc index 965bfaba..1a0fd1c8 100644 --- a/system/MockBox.cfc +++ b/system/MockBox.cfc @@ -3,619 +3,946 @@ Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp www.ortussolutions.com ******************************************************************************** -Author : Luis Majano -Date : April 20, 2009 +Author : Luis Majano +Date : April 20, 2009 Description : - The Official ColdBox Mocking Factory +The Official ColdBox Mocking Factory -----------------------------------------------------------------------> - - - - - - var tempDir = "/testbox/system/stubs"; + + + + + var tempDir = "/testbox/system/stubs"; - variables.instance = structnew(); + variables.instance = structNew(); - // Setup the generation Path - if( len(trim(arguments.generationPath)) neq 0 ){ - // Default to coldbox tmp path - instance.generationPath = arguments.generationPath; - } - else{ - instance.generationPath = tempDir; - } + // Setup the generation Path + if ( len( trim( arguments.generationPath ) ) neq 0 ) { + // Default to coldbox tmp path + instance.generationPath = arguments.generationPath; + } else { + instance.generationPath = tempDir; + } - // Cleanup of paths. - if( right(instance.generationPath,1) neq "/" ){ - instance.generationPath = instance.generationPath & "/"; - } + // Cleanup of paths. + if ( right( instance.generationPath, 1 ) neq "/" ) { + instance.generationPath = instance.generationPath & "/"; + } - instance.mockGenerator = createObject("component","testbox.system.mockutils.MockGenerator").init( this, false ); + instance.mockGenerator = createObject( "component", "testbox.system.mockutils.MockGenerator" ).init( + this, + false + ); - return this; - - + return this; + + - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - var obj = 0; - - // class to mock - if ( structKeyExists(arguments, "className") ){ - obj = createObject("component",arguments.className); - } - else if ( structKeyExists(arguments, "object") ){ - // Object to Mock - obj = arguments.object; - } - else{ - throw( type="mock.invalidArguments", message="Invalid mocking arguments: className or object not found"); - } - - // Clear up Mock object? - if( arguments.clearMethods ){ - structClear(obj); - } - // Decorate Mock - decorateMock(obj); - - // Call Logging Global Flag - if( arguments.callLogging ){ obj._mockCallLoggingActive = true; } - - // Return Mock - return obj; - - - - - - - - - - - if ( structKeyExists( arguments.object, "mockbox" ) ) { - return arguments.object; - } - return createMock(object=arguments.object); - - - - - - - - - - // No implements or inheritance - if( NOT len( trim( arguments.implements ) ) AND NOT len( trim( arguments.extends ) ) ){ - return createMock(className="testbox.system.mockutils.Stub", callLogging=arguments.callLogging); - } - // Generate the CFC + Create it + Remove it - return prepareMock( instance.mockGenerator.generateCFC(argumentCollection=arguments) ); - - + + + + + + + + + + + + + + + + + + + + + var obj = 0; + + // class to mock + if ( structKeyExists( arguments, "className" ) ) { + obj = createObject( "component", arguments.className ); + } else if ( structKeyExists( arguments, "object" ) ) { + // Object to Mock + obj = arguments.object; + } else { + throw( + type = "mock.invalidArguments", + message = "Invalid mocking arguments: className or object not found" + ); + } + + // Clear up Mock object? + if ( arguments.clearMethods ) { + structClear( obj ); + } + // Decorate Mock + decorateMock( obj ); + + // Call Logging Global Flag + if ( arguments.callLogging ) { + obj._mockCallLoggingActive = true; + } + + // Return Mock + return obj; + + + + + + + + + + + if ( structKeyExists( arguments.object, "mockbox" ) ) { + return arguments.object; + } + return createMock( object = arguments.object ); + + + + + + + + + + // No implements or inheritance + if ( NOT len( trim( arguments.implements ) ) AND NOT len( trim( arguments.extends ) ) ) { + return createMock( className = "testbox.system.mockutils.Stub", callLogging = arguments.callLogging ); + } + // Generate the CFC + Create it + Remove it + return prepareMock( instance.mockGenerator.generateCFC( argumentCollection = arguments ) ); + + - - - - - - - - - "#arguments.propertyScope#.#arguments.propertyName#" = arguments.mock; - return this; - - - - - - - - - - var thisScope = evaluate( "#arguments.scope#" ); + + + + + + + + + "#arguments.propertyScope#.#arguments.propertyName#" = arguments.mock; + return this; + + + + + + + + + + var thisScope = evaluate( "#arguments.scope#" ); - if( structKeyExists( thisScope, arguments.name ) ){ - return thisScope[ arguments.name ]; - } + if ( structKeyExists( thisScope, arguments.name ) ) { + return thisScope[ arguments.name ]; + } - if( structKeyExists( arguments, "default" ) ){ - return arguments.default; - } - - - + if ( structKeyExists( arguments, "default" ) ) { + return arguments.default; + } + + + + + + + + + var key = ""; + var totalCount = 0; - - - + // If method name used? Count only this method signatures + if ( len( arguments.methodName ) ) { + if ( structKeyExists( this._mockMethodCallCounters, arguments.methodName ) ) { + return this._mockMethodCallCounters[ arguments.methodName ]; + } + return -1; + } + + // All Calls + for ( key in this._mockMethodCallCounters ) { + totalCount = totalCount + this._mockMethodCallCounters[ key ]; + } + return totalCount; + + + + + + + + + return ( this.$count( argumentCollection = arguments ) eq arguments.count ); + + + + + + + + if ( this.$count( arguments.methodName ) EQ 0 ) { + return true; + } + return false; + + + + + + + + + return ( this.$count( argumentCollection = arguments ) GTE arguments.minNumberOfInvocations ); + + + + + + + + return ( this.$count( argumentCollection = arguments ) EQ 1 ); + + + + + + + + + return ( this.$count( argumentCollection = arguments ) LTE arguments.maxNumberOfInvocations ); + + + + + + + - var key = ""; - var totalCount = 0; - - // If method name used? Count only this method signatures - if( len(arguments.methodName) ){ - if( structKeyExists(this._mockMethodCallCounters, arguments.methodName) ){ - return this._mockMethodCallCounters[arguments.methodName]; - } - return -1; - } + // Check if arguments hash is set + if ( len( this._mockCurrentArgsHash ) ) { + this._mockArgResults[ this._mockCurrentArgsHash ] = arguments; + } else { + // Save incoming results array + this._mockResults[ this._mockCurrentMethod ] = arguments; + } - // All Calls - for( key in this._mockMethodCallCounters ){ - totalCount = totalCount + this._mockMethodCallCounters[key]; - } - return totalCount; - - + // Cleanup + this._mockCurrentMethod = ""; + this._mockCurrentArgsHash = ""; - - - - - - return (this.$count(argumentCollection=arguments) eq arguments.count ); + return this; - - - - - + + + + + + + + + + + - if( this.$count(arguments.methodName) EQ 0 ){ return true; } - return false; - - + // Check if arguments hash is set + if ( len( this._mockCurrentArgsHash ) ) { + this._mockArgResults[ this._mockCurrentArgsHash ] = { + type : "callback", + target : arguments.target + }; + } else { + // Save incoming callback as what it should return + this._mockCallbacks[ this._mockCurrentMethod ][ 1 ] = arguments.target; + } - - - - - - return (this.$count(argumentCollection=arguments) GTE arguments.minNumberOfInvocations); - - + // Cleanup + this._mockCurrentMethod = ""; + this._mockCurrentArgsHash = ""; - - - - - return (this.$count(argumentCollection=arguments) EQ 1); + return this; - - - - - - - - return (this.$count(argumentCollection=arguments) LTE arguments.maxNumberOfInvocations); - - - - - - - - - // Check if arguments hash is set - if( len( this._mockCurrentArgsHash ) ){ - this._mockArgResults[ this._mockCurrentArgsHash ] = arguments; - } - else{ - // Save incoming results array - this._mockResults[ this._mockCurrentMethod ] = arguments; - } - - // Cleanup - this._mockCurrentMethod = ""; - this._mockCurrentArgsHash = ""; - - return this; - - - - - - - - - - - - - - // Check if arguments hash is set - if( len( this._mockCurrentArgsHash ) ){ - this._mockArgResults[ this._mockCurrentArgsHash ] = { type="callback", target=arguments.target }; - } - else{ - // Save incoming callback as what it should return - this._mockCallbacks[ this._mockCurrentMethod ][ 1 ] = arguments.target; - } - - // Cleanup - this._mockCurrentMethod = ""; - this._mockCurrentArgsHash = ""; - - return this; - - - - - - - - - - if( len( this._mockCurrentMethod ) ){ - var args = arguments; - return this.$callback( function(){ - throw( - type = structKeyExists( args, "type" ) ? args.type : "", - message = structKeyExists( args, "message" ) ? args.message : "", - detail = structKeyExists( args, "detail" ) ? args.detail : "", - errorCode = structKeyExists( args, "errorCode" ) ? args.errorCode : "0" - ); - } ); - } - + + + + + + + + + if ( len( this._mockCurrentMethod ) ) { + var args = arguments; + return this.$callback( function(){ throw( - type = "MockFactory.IllegalStateException", - message = "No current method name set", - detail = "This method was probably called without chaining it to a $() call. Ex: obj.$().$throws(), or obj.$('method').$args().$throws()" + type = structKeyExists( args, "type" ) ? args.type : "", + message = structKeyExists( args, "message" ) ? args.message : "", + detail = structKeyExists( args, "detail" ) ? args.detail : "", + errorCode = structKeyExists( args, "errorCode" ) ? args.errorCode : "0" ); - - - - - - - - // check if method is set on concat - if( len(this._mockCurrentMethod) ){ - - // argument Hash Signature - this._mockCurrentArgsHash = this._mockCurrentMethod & "|" & this.mockBox.normalizeArguments(arguments); - - // concat this - return this; - } - - - - - - - - - - - - - - - - - - - - - - - var fncMD = structnew(); - var genFile = ""; - var oMockGenerator = this.MockBox.getmockGenerator(); - - // Check if the method is existent in public scope - if ( structKeyExists(this,arguments.method) ){ - fncMD = getMetadata(this[arguments.method]); - } - // Else check in private scope - else if( structKeyExists(variables,arguments.method) ){ - fncMD = getMetadata(variables[arguments.method]); - } - - // Prepare Metadata Existence, works on virtual methods also - if ( not structKeyExists(fncMD,"returntype") ){ - fncMD["returntype"] = "any"; - } - if ( not structKeyExists(fncMD,"access") ){ - fncMD["access"] = "public"; - } - if( not structKeyExists(fncMD,"output") ){ - fncMD["output"] = true; - } - // Preserve Return Type? - if( NOT arguments.preserveReturnType ){ - fncMD["returntype"] = "any"; - } - - // Remove Method From Object - structDelete( this,arguments.method ); - structDelete( variables,arguments.method ); - - // Generate Mock Method - arguments.metadata = fncMD; - arguments.targetObject = this; - oMockGenerator.generate( argumentCollection=arguments ); - - // Results Setup For No Argument Definitions or base results - if( structKeyExists( arguments, "returns" ) ){ - this._mockResults[ arguments.method ] = ArrayNew( 1 ); - this._mockResults[ arguments.method ][ 1 ] = arguments.returns; - } - else{ - this._mockResults[ arguments.method ] = ArrayNew( 1 ); - } - - // Callbacks Setup For No Argument Definitions or base results - if( structKeyExists( arguments, "callback" ) ){ - this._mockCallbacks[ arguments.method ] = ArrayNew( 1 ); - this._mockCallbacks[ arguments.method ][ 1 ] = arguments.callback; - } - else{ - this._mockCallbacks[ arguments.method ] = ArrayNew( 1 ); - } - - // Create Mock Call Counters - this._mockMethodCallCounters[ "#arguments.method#" ] = 0; - - // Save method name for concatenation - this._mockCurrentMethod = arguments.method; - this._mockCurrentArgsHash = ""; - - // Create Call Loggers, just in case - this._mockCallLoggers[arguments.method] = arrayNew(1); - - return this; - - - - - - - - - - + } ); + } + + throw( + type = "MockFactory.IllegalStateException", + message = "No current method name set", + detail = "This method was probably called without chaining it to a $() call. Ex: obj.$().$throws(), or obj.$('method').$args().$throws()" + ); + + + + + - var rtn = structnew(); - rtn.mockResults = this._mockResults; - rtn.mockCallBacks = this._mockCallbacks; - rtn.mockArgResults = this._mockArgResults; - rtn.mockMethodCallCounters = this._mockMethodCallCounters; - rtn.mockCallLoggingActive = this._mockCallLoggingActive; - rtn.mockCallLoggers = this._mockCallLoggers; - rtn.mockGenerationPath = this._mockGenerationPath; - rtn.mockOriginalMD = this._mockOriginalMD; - return rtn; + // check if method is set on concat + if ( len( this._mockCurrentMethod ) ) { + // argument Hash Signature + this._mockCurrentArgsHash = this._mockCurrentMethod & "|" & this.mockBox.normalizeArguments( + arguments + ); + + // concat this + return this; + } - - - - - for( var item in this._mockMethodCallCounters ){ - this._mockMethodCallCounters[ item ] = 0; - this._mockCallLoggers[ item ] = []; - } - return this; - - + + + + + + + + + + + + + + + + + + + + var fncMD = structNew(); + var genFile = ""; + var oMockGenerator = this.MockBox.getmockGenerator(); + + // Check if the method is existent in public scope + if ( structKeyExists( this, arguments.method ) ) { + fncMD = getMetadata( this[ arguments.method ] ); + } + // Else check in private scope + else if ( structKeyExists( variables, arguments.method ) ) { + fncMD = getMetadata( variables[ arguments.method ] ); + } + + // Prepare Metadata Existence, works on virtual methods also + if ( not structKeyExists( fncMD, "returntype" ) ) { + fncMD[ "returntype" ] = "any"; + } + if ( not structKeyExists( fncMD, "access" ) ) { + fncMD[ "access" ] = "public"; + } + if ( not structKeyExists( fncMD, "output" ) ) { + fncMD[ "output" ] = true; + } + // Preserve Return Type? + if ( NOT arguments.preserveReturnType ) { + fncMD[ "returntype" ] = "any"; + } + + // Remove Method From Object + structDelete( this, arguments.method ); + structDelete( variables, arguments.method ); + + // Generate Mock Method + arguments.metadata = fncMD; + arguments.targetObject = this; + oMockGenerator.generate( argumentCollection = arguments ); + + // Results Setup For No Argument Definitions or base results + if ( structKeyExists( arguments, "returns" ) ) { + this._mockResults[ arguments.method ] = arrayNew( 1 ); + this._mockResults[ arguments.method ][ 1 ] = arguments.returns; + } else { + this._mockResults[ arguments.method ] = arrayNew( 1 ); + } + + // Callbacks Setup For No Argument Definitions or base results + if ( structKeyExists( arguments, "callback" ) ) { + this._mockCallbacks[ arguments.method ] = arrayNew( 1 ); + this._mockCallbacks[ arguments.method ][ 1 ] = arguments.callback; + } else { + this._mockCallbacks[ arguments.method ] = arrayNew( 1 ); + } + + // Create Mock Call Counters + this._mockMethodCallCounters[ "#arguments.method#" ] = 0; + + // Save method name for concatenation + this._mockCurrentMethod = arguments.method; + this._mockCurrentArgsHash = ""; + + // Create Call Loggers, just in case + this._mockCallLoggers[ arguments.method ] = arrayNew( 1 ); + + return this; + + + + + + + + + + + + var rtn = structNew(); + rtn.mockResults = this._mockResults; + rtn.mockCallBacks = this._mockCallbacks; + rtn.mockArgResults = this._mockArgResults; + rtn.mockMethodCallCounters = this._mockMethodCallCounters; + rtn.mockCallLoggingActive = this._mockCallLoggingActive; + rtn.mockCallLoggers = this._mockCallLoggers; + rtn.mockGenerationPath = this._mockGenerationPath; + rtn.mockOriginalMD = this._mockOriginalMD; + return rtn; + + + + + + + for ( var item in this._mockMethodCallCounters ) { + this._mockMethodCallCounters[ item ] = 0; + this._mockCallLoggers[ item ] = []; + } + return this; + + - - - - - /** - * Accepts a specifically formatted chunk of text, and returns it as a query object. - * v2 rewrite by Jamie Jackson - * v3 rewrite by James Davis - * - * @param queryData Specifically format chunk of text to convert to a query. (Required) - * @return Returns a query object. - * @author Bert Dawson (bert@redbanner.com) - * @version 3, June 25, 2013 - * - */ - var fieldsDelimiter="|"; - var listOfColumns=""; - var tmpQuery=""; - var cellValues=""; - var lineDelimiter=chr(10) & chr(13); - var lineNum=0; - var colPosition=0; - var queryRows = ""; - var columnArray = ''; - - // the first line is the column list, eg "column1,column2,column3" - listOfColumns = Trim(ListFirst(queryData, lineDelimiter)); - columnArray = ListToArray(listOfColumns); - - // create a temporary Query - tmpQuery = QueryNew(listOfColumns); - - // Array of rows (ignoring empty rows) - queryRows = ListToArray(queryData,lineDelimiter); - - // loop though the queryData starting at the second line - for(lineNum=2; lineNum <= ArrayLen(queryRows); lineNum = lineNum + 1) { - cellValues = ListToArray(queryRows[lineNum], fieldsDelimiter, true); // Array of cell values, not ignoring empty values. - if (ArrayLen(cellValues) == listLen(listOfColumns)) { - QueryAddRow(tmpQuery); - for (colPosition=1; colPosition <= ArrayLen(cellValues); colPosition++){ - QuerySetCell(tmpQuery,Trim(columnArray[colPosition]), Trim(cellValues[colPosition])); - } + + + + + /** + * Accepts a specifically formatted chunk of text, and returns it as a query object. + * v2 rewrite by Jamie Jackson + * v3 rewrite by James Davis + * + * @param queryData Specifically format chunk of text to convert to a query. (Required) + * @return Returns a query object. + * @author Bert Dawson (bert@redbanner.com) + * @version 3, June 25, 2013 + * + */ + var fieldsDelimiter = "|"; + var listOfColumns = ""; + var tmpQuery = ""; + var cellValues = ""; + var lineDelimiter = chr( 10 ) & chr( 13 ); + var lineNum = 0; + var colPosition = 0; + var queryRows = ""; + var columnArray = ""; + + // the first line is the column list, eg "column1,column2,column3" + listOfColumns = trim( listFirst( queryData, lineDelimiter ) ); + columnArray = listToArray( listOfColumns ); + + // create a temporary Query + tmpQuery = queryNew( listOfColumns ); + + // Array of rows (ignoring empty rows) + queryRows = listToArray( queryData, lineDelimiter ); + + // loop though the queryData starting at the second line + for ( lineNum = 2; lineNum <= arrayLen( queryRows ); lineNum = lineNum + 1 ) { + cellValues = listToArray( + queryRows[ lineNum ], + fieldsDelimiter, + true + ); // Array of cell values, not ignoring empty values. + if ( arrayLen( cellValues ) == listLen( listOfColumns ) ) { + queryAddRow( tmpQuery ); + for ( colPosition = 1; colPosition <= arrayLen( cellValues ); colPosition++ ) { + querySetCell( + tmpQuery, + trim( columnArray[ colPosition ] ), + trim( cellValues[ colPosition ] ) + ); } } + } - return( tmpQuery ); - - - - - - - - // TreeMap will give us arguments in a consistent order, but we can't rely on Java to serialize argument values in the same way ColdFusion will - var argOrderedTree = createObject( "java", "java.util.TreeMap" ).init( arguments.args ); - var serializedArgs = ""; - - for( var arg in argOrderedTree ){ - if( NOT structKeyExists( argOrderedTree, arg ) ){ - /* we aren't going to be able to serialize an undefined variable, this might occur if an arguments structure - * containing optional parameters is passed by argumentCollection=arguments to the mocked method. - */ - continue; - } - else if( isSimpleValue( argOrderedTree[ arg ] ) ){ - /* toString() works best for simple values. It is equivalent in the following scenario - * i = 1; - * j = i; j++; j--; - * toString(i) eq toString(j); - * This works around the ColdFusion bug (9.0.2 at least) where an integer variable is converted to a real number by the ++ or -- operators. - * serializeJSON and other Java methods of stringifying don't work around that issue. - * - * Strangely, it converts a literal real number 1.0 to the string "1.0". - */ - serializedArgs &= toString( argOrderedTree[ arg ] ); - } - else if( - isObject( argOrderedTree[ arg ] ) and - // Find out if object, sometimes of course, on Adobe, is instance does not work, so sucky - ( isInstanceOf( argOrderedTree[ arg ], "Component" ) OR structKeyExists( getMetadata( argOrderedTree[ arg ] ), "extends" ) ) - ){ - // If an object and CFC, just use serializeJSON - serializedArgs &= serializeJSON( getMetadata( argOrderedTree[ arg ] ) ); - } - else{ - // Get obj rep - try{ - serializedArgs &= argOrderedTree[ arg ].toString(); - }catch( any e ){ - // Fallback - serializedArgs &= serializeJSON( argOrderedTree[ arg ] ); - } - } - - } - /* ColdFusion isn't case sensitive, so case of string values shouldn't matter. We do it after serializing all args - * to catch any values deep in complex variables. + return ( tmpQuery ); + + + + + + + + // TreeMap will give us arguments in a consistent order, but we can't rely on Java to serialize argument values in the same way ColdFusion will + var argOrderedTree = createObject( "java", "java.util.TreeMap" ).init( arguments.args ); + var serializedArgs = ""; + + for ( var arg in argOrderedTree ) { + if ( NOT structKeyExists( argOrderedTree, arg ) ) { + /* we aren't going to be able to serialize an undefined variable, this might occur if an arguments structure + * containing optional parameters is passed by argumentCollection=arguments to the mocked method. */ - return hash( lcase( serializedArgs ) ); - - + continue; + } else if ( isSimpleValue( argOrderedTree[ arg ] ) ) { + /* toString() works best for simple values. It is equivalent in the following scenario + * i = 1; + * j = i; j++; j--; + * toString(i) eq toString(j); + * This works around the ColdFusion bug (9.0.2 at least) where an integer variable is converted to a real number by the ++ or -- operators. + * serializeJSON and other Java methods of stringifying don't work around that issue. + * + * Strangely, it converts a literal real number 1.0 to the string "1.0". + */ + serializedArgs &= toString( argOrderedTree[ arg ] ); + } else if ( + isObject( argOrderedTree[ arg ] ) and + // Find out if object, sometimes of course, on Adobe, is instance does not work, so sucky + ( + isInstanceOf( argOrderedTree[ arg ], "Component" ) OR structKeyExists( + getMetadata( argOrderedTree[ arg ] ), + "extends" + ) + ) + ) { + // If an object and CFC, just use serializeJSON + serializedArgs &= serializeJSON( getMetadata( argOrderedTree[ arg ] ) ); + } else { + // Get obj rep + try { + serializedArgs &= argOrderedTree[ arg ].toString(); + } catch ( any e ) { + // Fallback + serializedArgs &= serializeJSON( argOrderedTree[ arg ] ); + } + } + } + /* ColdFusion isn't case sensitive, so case of string values shouldn't matter. We do it after serializing all args + * to catch any values deep in complex variables. + */ + return hash( lCase( serializedArgs ) ); + + - - - - - var obj = target; - - // Mock Method Results Holder - obj._mockResults = structnew(); - obj._mockCallbacks = structnew(); - obj._mockArgResults = structnew(); - // Call Counters - obj._mockMethodCallCounters = structnew(); - // Call Logging - obj._mockCallLoggingActive = false; - // Mock Method Call Logger - obj._mockCallLoggers = structnew(); - // Mock Generation Path - obj._mockGenerationPath = getGenerationPath(); - // Original Metadata - obj._mockOriginalMD = getMetadata(obj); - // Chaining Properties - obj._mockCurrentMethod = ""; - obj._mockCurrentArgsHash = ""; - // Mock Method - obj.$ = variables.$; - // Mock Property - obj.$property = variables.$property; - obj.$getProperty = variables.$getProperty; - // Mock Results - obj.$results = variables.$results; - obj.$throws = variables.$throws; - obj.$callback = variables.$callback; - // Mock Arguments - obj.$args = variables.$args; - // CallLog - obj.$callLog = variables.$callLog; - // Verify Call Counts - obj.$count = variables.$count; - obj.$times = variables.$times; - obj.$never = variables.$never; - obj.$verifyCallCount = variables.$times; - obj.$atLeast = variables.$atLeast; - obj.$once = variables.$once; - obj.$atMost = variables.$atMost; - // Debug - obj.$debug = variables.$debug; - obj.$reset = variables.$reset; - // Mock Box - obj.mockBox = this; - - - - - - - - - \ No newline at end of file + + + + + var obj = target; + + // Mock Method Results Holder + obj._mockResults = structNew(); + obj._mockCallbacks = structNew(); + obj._mockArgResults = structNew(); + // Call Counters + obj._mockMethodCallCounters = structNew(); + // Call Logging + obj._mockCallLoggingActive = false; + // Mock Method Call Logger + obj._mockCallLoggers = structNew(); + // Mock Generation Path + obj._mockGenerationPath = getGenerationPath(); + // Original Metadata + obj._mockOriginalMD = getMetadata( obj ); + // Chaining Properties + obj._mockCurrentMethod = ""; + obj._mockCurrentArgsHash = ""; + // Mock Method + obj.$ = variables.$; + // Mock Property + obj.$property = variables.$property; + obj.$getProperty = variables.$getProperty; + // Mock Results + obj.$results = variables.$results; + obj.$throws = variables.$throws; + obj.$callback = variables.$callback; + // Mock Arguments + obj.$args = variables.$args; + // CallLog + obj.$callLog = variables.$callLog; + // Verify Call Counts + obj.$count = variables.$count; + obj.$times = variables.$times; + obj.$never = variables.$never; + obj.$verifyCallCount = variables.$times; + obj.$atLeast = variables.$atLeast; + obj.$once = variables.$once; + obj.$atMost = variables.$atMost; + // Debug + obj.$debug = variables.$debug; + obj.$reset = variables.$reset; + // Mock Box + obj.mockBox = this; + + + + + + + + diff --git a/system/TestBox.cfc b/system/TestBox.cfc index 1b78aef2..2ce9db73 100644 --- a/system/TestBox.cfc +++ b/system/TestBox.cfc @@ -1,11 +1,11 @@ /** -* Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp -* www.ortussolutions.com -* --- -* Welcome to the next generation of BDD and xUnit testing for CFML applications -* The TestBox core class allows you to execute all kinds of test bundles, directories and more. -*/ -component accessors="true"{ + * Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + * Welcome to the next generation of BDD and xUnit testing for CFML applications + * The TestBox core class allows you to execute all kinds of test bundles, directories and more. + */ +component accessors="true" { // The version property name="version"; @@ -16,8 +16,8 @@ component accessors="true"{ // The CFC bundles to test property name="bundles"; // The labels used for the testing - property name="labels"; - // The labels excluded from testing + property name="labels"; + // The labels excluded from testing property name="excludes"; // The reporter attached to this runner property name="reporter"; @@ -39,21 +39,20 @@ component accessors="true"{ * @options A structure of configuration options that are optionally used to configure a runner. */ any function init( - any bundles=[], - any directory={}, - any directories={}, - any reporter="simple", - any labels=[], - any excludes=[], - struct options={} + any bundles = [], + any directory = {}, + any directories = {}, + any reporter = "simple", + any labels = [], + any excludes = [], + struct options = {} ){ - // TestBox version - variables.version = "@build.version@+@build.number@"; - variables.codename = ""; + variables.version = "@build.version@+@build.number@"; + variables.codename = ""; // init util - variables.utility = new testbox.system.util.Util(); - if( !structKeyExists( arguments.options, 'coverage' ) ) { + variables.utility = new testbox.system.util.Util(); + if ( !structKeyExists( arguments.options, "coverage" ) ) { arguments.options.coverage = {}; } variables.coverageService = new testbox.system.coverage.CoverageService( arguments.options.coverage ); @@ -61,13 +60,13 @@ component accessors="true"{ // reporter variables.reporter = arguments.reporter; // options - variables.options = arguments.options; + variables.options = arguments.options; // Empty bundles to start - variables.bundles = []; + variables.bundles = []; // inflate labels - inflateLabels( arguments.labels ); - // inflate excludes + inflateLabels( arguments.labels ); + // inflate excludes inflateExcludes( arguments.excludes ); // add bundles addBundles( arguments.bundles ); @@ -80,17 +79,20 @@ component accessors="true"{ } /** - * Constructor - * @directory A directory to test which can be a simple mapping path or a struct with the following options: [ mapping = the path to the directory using dot notation (myapp.testing.specs), recurse = boolean, filter = closure that receives the path of the CFC found, it must return true to process or false to continue process ] - */ - any function addDirectory( required any directory, boolean recurse=true ) { + * Constructor + * @directory A directory to test which can be a simple mapping path or a struct with the following options: [ mapping = the path to the directory using dot notation (myapp.testing.specs), recurse = boolean, filter = closure that receives the path of the CFC found, it must return true to process or false to continue process ] + */ + any function addDirectory( required any directory, boolean recurse = true ){ // inflate directory? - if( isSimpleValue( arguments.directory ) ) { - arguments.directory = { mapping=arguments.directory, recurse=arguments.recurse }; + if ( isSimpleValue( arguments.directory ) ) { + arguments.directory = { + mapping : arguments.directory, + recurse : arguments.recurse + }; } // directory passed? - if( !structIsEmpty( arguments.directory ) ){ - for( var bundle in getSpecPaths( arguments.directory ) ){ + if ( !structIsEmpty( arguments.directory ) ) { + for ( var bundle in getSpecPaths( arguments.directory ) ) { arrayAppend( variables.bundles, bundle ); } } @@ -98,28 +100,28 @@ component accessors="true"{ } /** - * Constructor - * @directories A set of directories to test which can be a list of simple mapping paths or an array of structs with the following options: [ mapping = the path to the directory using dot notation (myapp.testing.specs), recurse = boolean, filter = closure that receives the path of the CFC found, it must return true to process or false to continue process ] - */ - any function addDirectories( required any directories, boolean recurse=true ){ - if( isSimpleValue( arguments.directories ) ){ + * Constructor + * @directories A set of directories to test which can be a list of simple mapping paths or an array of structs with the following options: [ mapping = the path to the directory using dot notation (myapp.testing.specs), recurse = boolean, filter = closure that receives the path of the CFC found, it must return true to process or false to continue process ] + */ + any function addDirectories( required any directories, boolean recurse = true ){ + if ( isSimpleValue( arguments.directories ) ) { arguments.directories = listToArray( arguments.directories ); } - for( var dir in arguments.directories ) { + for ( var dir in arguments.directories ) { addDirectory( dir, arguments.recurse ); } return this; } /** - * Constructor - * @directory A directory to test which can be a simple mapping path or a struct with the following options: [ mapping = the path to the directory using dot notation (myapp.testing.specs), recurse = boolean, filter = closure that receives the path of the CFC found, it must return true to process or false to continue process ] - */ - any function addBundles(required any bundles) { - if( isSimpleValue( arguments.bundles ) ){ + * Constructor + * @directory A directory to test which can be a simple mapping path or a struct with the following options: [ mapping = the path to the directory using dot notation (myapp.testing.specs), recurse = boolean, filter = closure that receives the path of the CFC found, it must return true to process or false to continue process ] + */ + any function addBundles( required any bundles ){ + if ( isSimpleValue( arguments.bundles ) ) { arguments.bundles = listToArray( arguments.bundles ); } - for( var bundle in arguments.bundles ){ + for ( var bundle in arguments.bundles ) { arrayAppend( variables.bundles, bundle ); } return this; @@ -133,7 +135,7 @@ component accessors="true"{ * @directory The directory to test which can be a simple mapping path or a struct with the following options: [ mapping = the path to the directory using dot notation (myapp.testing.specs), recurse = boolean, filter = closure that receives the path of the CFC found, it must return true to process or false to continue process ] * @reporter The type of reporter to use for the results, by default is uses our 'simple' report. You can pass in a core reporter string type or an instance of a testbox.system.reports.IReporter. You can also pass a struct if the reporter requires options: {type="", options={}} * @labels The list or array of labels that a suite or spec must have in order to execute. - * @excludes The list or array of labels that a suite or spec must not have in order to execute. + * @excludes The list or array of labels that a suite or spec must not have in order to execute. * @options A structure of configuration options that are optionally used to configure a runner. * @testBundles A list or array of bundle names that are the ones that will be executed ONLY! * @testSuites A list or array of suite names that are the ones that will be executed ONLY! @@ -145,20 +147,21 @@ component accessors="true"{ any bundles, any directory, any reporter, - any labels, - any excludes, + any labels, + any excludes, struct options, - any testBundles=[], - any testSuites=[], - any testSpecs=[], - any callbacks={}, - boolean eagerFailure=false + any testBundles = [], + any testSuites = [], + any testSpecs = [], + any callbacks = {}, + boolean eagerFailure = false ){ - // reporter passed? - if( !isNull( arguments.reporter ) ){ variables.reporter = arguments.reporter; } + if ( !isNull( arguments.reporter ) ) { + variables.reporter = arguments.reporter; + } // run it and get results - var results = runRaw( argumentCollection=arguments ); + var results = runRaw( argumentCollection = arguments ); // store latest results variables.result = results; // return report @@ -185,53 +188,71 @@ component accessors="true"{ any labels, any excludes, struct options, - any testBundles=[], - any testSuites=[], - any testSpecs=[], - any callbacks={}, - boolean eagerFailure=false + any testBundles = [], + any testSuites = [], + any testSpecs = [], + any callbacks = {}, + boolean eagerFailure = false ){ - // inflate options if passed - if( !isNull( arguments.options ) ){ variables.options = arguments.options; } + if ( !isNull( arguments.options ) ) { + variables.options = arguments.options; + } // inflate directory? - if( !isNull( arguments.directory ) && isSimpleValue( arguments.directory ) ){ arguments.directory = { mapping=arguments.directory, recurse=true }; } + if ( !isNull( arguments.directory ) && isSimpleValue( arguments.directory ) ) { + arguments.directory = { + mapping : arguments.directory, + recurse : true + }; + } // inflate test bundles, suites and specs from incoming variables. - arguments.testBundles = ( isSimpleValue( arguments.testBundles ) ? listToArray( arguments.testBundles ) : arguments.testBundles ); - arguments.testSuites = ( isSimpleValue( arguments.testSuites ) ? listToArray( arguments.testSuites ) : arguments.testSuites ); - arguments.testSpecs = ( isSimpleValue( arguments.testSpecs ) ? listToArray( arguments.testSpecs ) : arguments.testSpecs ); + arguments.testBundles = ( + isSimpleValue( arguments.testBundles ) ? listToArray( arguments.testBundles ) : arguments.testBundles + ); + arguments.testSuites = ( + isSimpleValue( arguments.testSuites ) ? listToArray( arguments.testSuites ) : arguments.testSuites + ); + arguments.testSpecs = ( + isSimpleValue( arguments.testSpecs ) ? listToArray( arguments.testSpecs ) : arguments.testSpecs + ); // Verify URL conventions for bundle, suites and specs exclusions. - if( !isNull( url.testBundles) ){ + if ( !isNull( url.testBundles ) ) { testBundles.addAll( listToArray( url.testBundles ) ); } - if( !isNull( url.testSuites) ){ + if ( !isNull( url.testSuites ) ) { arguments.testSuites.addAll( listToArray( url.testSuites ) ); } - if( !isNull( url.testSpecs) ){ + if ( !isNull( url.testSpecs ) ) { arguments.testSpecs.addAll( listToArray( url.testSpecs ) ); } - if( !isNull( url.testMethod) ){ + if ( !isNull( url.testMethod ) ) { arguments.testSpecs.addAll( listToArray( url.testMethod ) ); } // Using a directory runner? - if( !isNull( arguments.directory ) && !structIsEmpty( arguments.directory ) ){ + if ( !isNull( arguments.directory ) && !structIsEmpty( arguments.directory ) ) { arguments.bundles = getSpecPaths( arguments.directory ); } // Inflate labels if passed - if( !isNull( arguments.labels ) ){ inflateLabels( arguments.labels ); } - // Inflate excludes if passed - if( !isNull( arguments.excludes ) ){ inflateExcludes( arguments.excludes ); } + if ( !isNull( arguments.labels ) ) { + inflateLabels( arguments.labels ); + } + // Inflate excludes if passed + if ( !isNull( arguments.excludes ) ) { + inflateExcludes( arguments.excludes ); + } // If bundles passed, inflate those as the target - if( !isNull( arguments.bundles ) ){ inflateBundles( arguments.bundles ); } + if ( !isNull( arguments.bundles ) ) { + inflateBundles( arguments.bundles ); + } - // create results object + // create results object var results = new testbox.system.TestResult( bundleCount = arrayLen( variables.bundles ), - labels = variables.labels, - excludes = variables.excludes, + labels = variables.labels, + excludes = variables.excludes, testBundles = arguments.testBundles, testSuites = arguments.testSuites, testSpecs = arguments.testSpecs @@ -240,9 +261,9 @@ component accessors="true"{ coverageService.beginCapture(); // iterate and run the test bundles - for( var thisBundlePath in variables.bundles ){ + for ( var thisBundlePath in variables.bundles ) { // Skip interfaces, they are not testable - if( getComponentMetadata( thisBundlePath ).type eq "interface" ){ + if ( getComponentMetadata( thisBundlePath ).type eq "interface" ) { continue; } // Execute Bundle @@ -253,8 +274,9 @@ component accessors="true"{ ); // Eager Failures on Bundle? - if( arguments.eagerFailure ){ - var failuresDetected = results.getBundleStats() + if ( arguments.eagerFailure ) { + var failuresDetected = results + .getBundleStats() // Get stats for running bundle .filter( function( item ){ return ( item.path == thisBundlePath ? true : false ); @@ -263,7 +285,7 @@ component accessors="true"{ return ( item.totalError + item.totalFail ) > 0; }, false ); - if( failuresDetected ){ + if ( failuresDetected ) { // Hard skip iterations break; } @@ -273,7 +295,7 @@ component accessors="true"{ // mark end of testing bundles results.end(); - coverageService.processCoverage( results=results, testbox=this ); + coverageService.processCoverage( results = results, testbox = this ); coverageService.endCapture( true ); @@ -296,65 +318,68 @@ component accessors="true"{ * @testSuites A list of suite names that are the ones that will be executed ONLY! * @testSpecs A list of test names that are the ones that will be executed ONLY! * @eagerFailure If this boolean is set to true, then execution of more bundle tests will stop once the first failure/error is detected. By default this is false. - */ + */ remote function runRemote( string bundles, string directory, - boolean recurse=true, - string reporter="simple", - string reporterOptions="{}", - string labels="", - string excludes="", + boolean recurse = true, + string reporter = "simple", + string reporterOptions = "{}", + string labels = "", + string excludes = "", string options, - string testBundles="", - string testSuites="", - string testSpecs="", - boolean eagerFailure=false - ) output=true { + string testBundles = "", + string testSuites = "", + string testSpecs = "", + boolean eagerFailure = false + ) output=true{ // local init init(); // simple to complex - arguments.labels = listToArray( arguments.labels ); - arguments.excludes = listToArray( arguments.excludes ); - arguments.testBundles = listToArray( arguments.testBundles ); - arguments.testSuites = listToArray( arguments.testSuites ); - arguments.testSpecs = listToArray( arguments.testSpecs ); + arguments.labels = listToArray( arguments.labels ); + arguments.excludes = listToArray( arguments.excludes ); + arguments.testBundles = listToArray( arguments.testBundles ); + arguments.testSuites = listToArray( arguments.testSuites ); + arguments.testSpecs = listToArray( arguments.testSpecs ); // options inflate from JSON - if( !isNull( arguments.options ) and isJSON( arguments.options ) ){ + if ( !isNull( arguments.options ) and isJSON( arguments.options ) ) { arguments.options = deserializeJSON( arguments.options ); - } - else{ + } else { arguments.options = {}; } // Inflate directory? - if( !isNull( arguments.directory ) and len( arguments.directory ) ){ - arguments.directory = { mapping = arguments.directory, recurse = arguments.recurse }; + if ( !isNull( arguments.directory ) and len( arguments.directory ) ) { + arguments.directory = { + mapping : arguments.directory, + recurse : arguments.recurse + }; } // reporter options inflate from JSON - if( !isNull( arguments.reporterOptions ) and isJSON( arguments.reporterOptions ) ){ + if ( !isNull( arguments.reporterOptions ) and isJSON( arguments.reporterOptions ) ) { arguments.reporterOptions = deserializeJSON( arguments.reporterOptions ); - } - else{ + } else { arguments.reporterOptions = {}; } // setup reporter - if( !isNull( arguments.reporter ) and len( arguments.reporter ) ){ - variables.reporter = { type = arguments.reporter, options = arguments.reporterOptions }; + if ( !isNull( arguments.reporter ) and len( arguments.reporter ) ) { + variables.reporter = { + type : arguments.reporter, + options : arguments.reporterOptions + }; } // run it and get results - var results = runRaw( argumentCollection=arguments ); + var results = runRaw( argumentCollection = arguments ); // check if reporter is "raw" and if raw, just return it - if( variables.reporter.type == "raw" ){ + if ( variables.reporter.type == "raw" ) { return produceReport( results ); - } - else{ + } else { // return report writeOutput( produceReport( results ) ); } @@ -364,25 +389,26 @@ component accessors="true"{ } /** - * Send some status headers - */ + * Send some status headers + */ private function sendStatusHeaders( required results ){ - - try{ + try { var response = getPageContext().getResponse(); - response.addHeader( "x-testbox-totalDuration", javaCast( "string", results.getTotalDuration() ) ); - response.addHeader( "x-testbox-totalBundles", javaCast( "string", results.getTotalBundles() ) ); - response.addHeader( "x-testbox-totalSuites", javaCast( "string", results.getTotalSuites() ) ); - response.addHeader( "x-testbox-totalSpecs", javaCast( "string", results.getTotalSpecs() ) ); - response.addHeader( "x-testbox-totalPass", javaCast( "string", results.getTotalPass() ) ); - response.addHeader( "x-testbox-totalFail", javaCast( "string", results.getTotalFail() ) ); - response.addHeader( "x-testbox-totalError", javaCast( "string", results.getTotalError() ) ); - response.addHeader( "x-testbox-totalSkipped", javaCast( "string", results.getTotalSkipped() ) ); - } catch( Any e ){ - writeLog( type="error", - text="Error sending TestBox headers: #e.message# #e.detail# #e.stackTrace#", - file="testbox.log" ); + response.addHeader( "x-testbox-totalDuration", javacast( "string", results.getTotalDuration() ) ); + response.addHeader( "x-testbox-totalBundles", javacast( "string", results.getTotalBundles() ) ); + response.addHeader( "x-testbox-totalSuites", javacast( "string", results.getTotalSuites() ) ); + response.addHeader( "x-testbox-totalSpecs", javacast( "string", results.getTotalSpecs() ) ); + response.addHeader( "x-testbox-totalPass", javacast( "string", results.getTotalPass() ) ); + response.addHeader( "x-testbox-totalFail", javacast( "string", results.getTotalFail() ) ); + response.addHeader( "x-testbox-totalError", javacast( "string", results.getTotalError() ) ); + response.addHeader( "x-testbox-totalSkipped", javacast( "string", results.getTotalSkipped() ) ); + } catch ( Any e ) { + writeLog( + type = "error", + text = "Error sending TestBox headers: #e.message# #e.detail# #e.stackTrace#", + file = "testbox.log" + ); } return this; @@ -391,54 +417,91 @@ component accessors="true"{ /************************************** REPORTING COMMON METHODS *********************************************/ /** - * Build a report according to this runner's setup reporter, which can be anything. - * @results The results object to use to produce a report - */ + * Build a report according to this runner's setup reporter, which can be anything. + * @results The results object to use to produce a report + */ private any function produceReport( required results ){ - var iData = { type="", options={} }; + var iData = { type : "", options : {} }; // If the type is a simple value then inflate it - if( isSimpleValue( variables.reporter ) ){ - iData = { type=buildReporter( variables.reporter ), options={} }; + if ( isSimpleValue( variables.reporter ) ) { + iData = { + type : buildReporter( variables.reporter ), + options : {} + }; } // If the incoming reporter is an object. - else if ( isObject( variables.reporter ) ){ - iData = { type=variables.reporter, options={} }; + else if ( isObject( variables.reporter ) ) { + iData = { + type : variables.reporter, + options : {} + }; } // Do we have reporter type and options - else if ( isStruct( variables.reporter ) ){ + else if ( isStruct( variables.reporter ) ) { iData.type = buildReporter( variables.reporter.type ); - if( structKeyExists( variables.reporter, "options" ) ){ + if ( structKeyExists( variables.reporter, "options" ) ) { iData.options = variables.reporter.options; } } // build the report from the reporter - return iData.type.runReport( arguments.results, this, iData.options ); + return iData.type.runReport( + arguments.results, + this, + iData.options + ); } /** - * Build a reporter according to passed in reporter type or class path - * @reporter The reporter type to build. - */ + * Build a reporter according to passed in reporter type or class path + * @reporter The reporter type to build. + */ private any function buildReporter( required reporter ){ - - switch( arguments.reporter ){ - case "json" : { return new "testbox.system.reports.JSONReporter"(); } - case "xml" : { return new "testbox.system.reports.XMLReporter"(); } - case "raw" : { return new "testbox.system.reports.RawReporter"(); } - case "simple" : { return new "testbox.system.reports.SimpleReporter"(); } - case "dot" : { return new "testbox.system.reports.DotReporter"(); } - case "text" : { return new "testbox.system.reports.TextReporter"(); } - case "junit" : { return new "testbox.system.reports.JUnitReporter"(); } - case "antjunit" : { return new "testbox.system.reports.ANTJUnitReporter"(); } - case "console" : { return new "testbox.system.reports.ConsoleReporter"(); } - case "min" : { return new "testbox.system.reports.MinReporter"(); } - case "mintext" : { return new "testbox.system.reports.MinTextReporter"(); } - case "tap" : { return new "testbox.system.reports.TapReporter"(); } - case "doc" : { return new "testbox.system.reports.DocReporter"(); } - case "codexwiki" : { return new "testbox.system.reports.CodexWikiReporter"(); } + switch ( arguments.reporter ) { + case "json": { + return new "testbox.system.reports.JSONReporter"( ); + } + case "xml": { + return new "testbox.system.reports.XMLReporter"( ); + } + case "raw": { + return new "testbox.system.reports.RawReporter"( ); + } + case "simple": { + return new "testbox.system.reports.SimpleReporter"( ); + } + case "dot": { + return new "testbox.system.reports.DotReporter"( ); + } + case "text": { + return new "testbox.system.reports.TextReporter"( ); + } + case "junit": { + return new "testbox.system.reports.JUnitReporter"( ); + } + case "antjunit": { + return new "testbox.system.reports.ANTJUnitReporter"( ); + } + case "console": { + return new "testbox.system.reports.ConsoleReporter"( ); + } + case "min": { + return new "testbox.system.reports.MinReporter"( ); + } + case "mintext": { + return new "testbox.system.reports.MinTextReporter"( ); + } + case "tap": { + return new "testbox.system.reports.TapReporter"( ); + } + case "doc": { + return new "testbox.system.reports.DocReporter"( ); + } + case "codexwiki": { + return new "testbox.system.reports.CodexWikiReporter"( ); + } default: { - return new "#arguments.reporter#"(); + return new "#arguments.reporter#"( ); } } } @@ -457,32 +520,36 @@ component accessors="true"{ required testResults, required callbacks ){ - // create new target bundle and get its metadata var target = getBundle( arguments.bundlePath ); // verify call backs - if( structKeyExists( arguments.callbacks, "onBundleStart" ) ){ + if ( structKeyExists( arguments.callbacks, "onBundleStart" ) ) { arguments.callbacks.onBundleStart( target, testResults ); } - try{ + try { // Discover type? - if( structKeyExists( target, "run" ) ){ + if ( structKeyExists( target, "run" ) ) { // Run via BDD Style - new testbox.system.runners.BDDRunner( options=variables.options, testbox=this ) - .run( target, arguments.testResults, arguments.callbacks ); - } - else{ + new testbox.system.runners.BDDRunner( options = variables.options, testbox = this ).run( + target, + arguments.testResults, + arguments.callbacks + ); + } else { // Run via xUnit Style - new testbox.system.runners.UnitRunner( options=variables.options,testbox=this ) - .run( target, arguments.testResults, arguments.callbacks ); + new testbox.system.runners.UnitRunner( options = variables.options, testbox = this ).run( + target, + arguments.testResults, + arguments.callbacks + ); } - } catch( Any e ){ + } catch ( Any e ) { throw( message = "Error executing bundle - #arguments.bundlePath# message: #e.message# #e.detail#", detail = e.stackTrace, - type = "BundleRunnerMajorException" + type = "BundleRunnerMajorException" ); } @@ -490,7 +557,7 @@ component accessors="true"{ arguments.testResults.storeDebugBuffer( target.getDebugBuffer() ); // verify call backs - if( structKeyExists( arguments.callbacks, "onBundleEnd" ) ){ + if ( structKeyExists( arguments.callbacks, "onBundleEnd" ) ) { arguments.callbacks.onBundleEnd( target, testResults ); } @@ -498,29 +565,29 @@ component accessors="true"{ } /** - * Creates and returns a bundle CFC with spec capabilities if not inherited. - * @bundlePath The path to the Bundle CFC - */ + * Creates and returns a bundle CFC with spec capabilities if not inherited. + * @bundlePath The path to the Bundle CFC + */ private any function getBundle( required bundlePath ){ - var bundle = createObject( "component", "#arguments.bundlePath#" ); - var familyPath = "testbox.system.BaseSpec"; + var bundle = createObject( "component", "#arguments.bundlePath#" ); + var familyPath = "testbox.system.BaseSpec"; // check if base spec assigned - if( isInstanceOf( bundle, familyPath ) ){ + if ( isInstanceOf( bundle, familyPath ) ) { return bundle; } // Else virtualize it - var baseObject = new testbox.system.BaseSpec(); - var excludedProperties = ""; + var baseObject = new testbox.system.BaseSpec(); + var excludedProperties = ""; // Mix it up baby variables.utility.getMixerUtil().start( bundle ); // Mix in the virtual methods - for( var key in baseObject ){ + for ( var key in baseObject ) { // If target has overriden method, then don't override it with mixin, simulated inheritance - if( NOT structKeyExists( bundle, key ) AND NOT listFindNoCase( excludedProperties, key ) ){ + if ( NOT structKeyExists( bundle, key ) AND NOT listFindNoCase( excludedProperties, key ) ) { bundle.injectMixin( key, baseObject[ key ] ); } } @@ -532,34 +599,66 @@ component accessors="true"{ } /** - * Get an array of spec paths from a directory - * @directory The directory information struct to test: [ mapping = the path to the directory using dot notation (myapp.testing.specs), recurse = boolean, filter = closure that receives the path of the CFC found, it must return true to process or false to continue process ] - */ + * Get an array of spec paths from a directory + * @directory The directory information struct to test: [ mapping = the path to the directory using dot notation (myapp.testing.specs), recurse = boolean, filter = closure that receives the path of the CFC found, it must return true to process or false to continue process ] + */ private function getSpecPaths( required directory ){ var results = []; // recurse default - arguments.directory.recurse = ( structKeyExists( arguments.directory, "recurse" ) ? arguments.directory.recurse : true ); + arguments.directory.recurse = ( + structKeyExists( arguments.directory, "recurse" ) ? arguments.directory.recurse : true + ); // clean up paths - var bundleExpandedPath = expandPath( "/" & replace( arguments.directory.mapping, ".", "/", "all" ) ); - bundleExpandedPath = replace( bundleExpandedPath, "\", "/", "all" ); + var bundleExpandedPath = expandPath( + "/" & replace( + arguments.directory.mapping, + ".", + "/", + "all" + ) + ); + bundleExpandedPath = replace( bundleExpandedPath, "\", "/", "all" ); // search directory with filters - var bundlesFound = directoryList( bundleExpandedPath, arguments.directory.recurse, "path", "*.cfc", "asc" ); + var bundlesFound = directoryList( + bundleExpandedPath, + arguments.directory.recurse, + "path", + "*.cfc", + "asc" + ); // cleanup paths and store them for usage - for( var x=1; x lte arrayLen( bundlesFound ); x++ ){ - + for ( var x = 1; x lte arrayLen( bundlesFound ); x++ ) { // filter closure exists and the filter does not match the path - if( structKeyExists( arguments.directory, "filter" ) && !arguments.directory.filter( bundlesFound[ x ] ) ){ + if ( + structKeyExists( arguments.directory, "filter" ) && !arguments.directory.filter( + bundlesFound[ x ] + ) + ) { continue; } // standardize paths - bundlesFound[ x ] = rereplace( replaceNoCase( bundlesFound[ x ], ".cfc", "" ) , "(\\|/)", "/", "all" ); + bundlesFound[ x ] = reReplace( + replaceNoCase( bundlesFound[ x ], ".cfc", "" ), + "(\\|/)", + "/", + "all" + ); // clean base out of them - bundlesFound[ x ] = replace( bundlesFound[ x ], bundleExpandedPath, "" ); + bundlesFound[ x ] = replace( + bundlesFound[ x ], + bundleExpandedPath, + "" + ); // Clean out slashes and append the mapping. - bundlesFound[ x ] = arguments.directory.mapping & rereplace( bundlesFound[ x ], "(\\|/)", ".", "all" ); + bundlesFound[ x ] = arguments.directory.mapping & reReplace( + bundlesFound[ x ], + "(\\|/)", + ".", + "all" + ); arrayAppend( results, bundlesFound[ x ] ); } @@ -568,23 +667,25 @@ component accessors="true"{ } /** - * Inflate incoming labels from a simple string as a standard array - */ - private function inflateLabels(required any labels){ + * Inflate incoming labels from a simple string as a standard array + */ + private function inflateLabels( required any labels ){ variables.labels = ( isSimpleValue( arguments.labels ) ? listToArray( arguments.labels ) : arguments.labels ); - } + } - /** - * Inflate incoming excludes from a simple string as a standard array - */ - private function inflateExcludes(required any excludes){ - variables.excludes = ( isSimpleValue( arguments.excludes ) ? listToArray( arguments.excludes ) : arguments.excludes ); + /** + * Inflate incoming excludes from a simple string as a standard array + */ + private function inflateExcludes( required any excludes ){ + variables.excludes = ( + isSimpleValue( arguments.excludes ) ? listToArray( arguments.excludes ) : arguments.excludes + ); } /** - * Inflate incoming bundles from a simple string as a standard array - */ - private function inflateBundles(required any bundles){ + * Inflate incoming bundles from a simple string as a standard array + */ + private function inflateBundles( required any bundles ){ variables.bundles = ( isSimpleValue( arguments.bundles ) ? listToArray( arguments.bundles ) : arguments.bundles ); } diff --git a/system/TestResult.cfc b/system/TestResult.cfc index 1092161a..533a6f5b 100644 --- a/system/TestResult.cfc +++ b/system/TestResult.cfc @@ -7,32 +7,32 @@ component accessors="true" { // Global Durations - property name="startTime" type="numeric"; - property name="endTime" type="numeric"; + property name="startTime" type="numeric"; + property name="endTime" type="numeric"; property name="totalDuration" type="numeric"; // Global Stats property name="totalBundles" type="numeric"; - property name="totalSuites" type="numeric"; - property name="totalSpecs" type="numeric"; - property name="totalPass" type="numeric"; - property name="totalFail" type="numeric"; - property name="totalError" type="numeric"; + property name="totalSuites" type="numeric"; + property name="totalSpecs" type="numeric"; + property name="totalPass" type="numeric"; + property name="totalFail" type="numeric"; + property name="totalError" type="numeric"; property name="totalSkipped" type="numeric"; - property name="labels" type="array"; - property name="excludes" type="array"; + property name="labels" type="array"; + property name="excludes" type="array"; // bundle stats property name="bundleStats" type="struct"; // bundles, suites and specs only values that can execute property name="testBundles" type="array"; - property name="testSuites" type="array"; - property name="testSpecs" type="array"; + property name="testSuites" type="array"; + property name="testSpecs" type="array"; // Code Coverage property name="coverageEnabled" type="boolean"; - property name="coverageData" type="struct"; + property name="coverageData" type="struct"; /** @@ -251,7 +251,11 @@ component accessors="true" { * @bundleStats.hint The bundle stats reference this belongs to. * @parentStats.hint If passed, the parent stats this suite belongs to */ - struct function startSuiteStats( required string name, required struct bundleStats, struct parentStats = {} ){ + struct function startSuiteStats( + required string name, + required struct bundleStats, + struct parentStats = {} + ){ lock name="tb-results-#variables.resultsID#" type="exclusive" timeout="10" { // setup stats data for incoming suite var stats = { @@ -422,7 +426,10 @@ component accessors="true" { } } - result.coverage = { "enabled" : coverageEnabled, "data" : {} }; + result.coverage = { + "enabled" : coverageEnabled, + "data" : {} + }; if ( coverageEnabled ) { result.coverage.data = { diff --git a/system/compat/framework/Results.cfc b/system/compat/framework/Results.cfc index 757a5f07..ce36f9c4 100644 --- a/system/compat/framework/Results.cfc +++ b/system/compat/framework/Results.cfc @@ -1,44 +1,52 @@ /** -* Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp -* www.ortussolutions.com -* --- -* A compat class for MXUnit Directory Test Suite -*/ -component{ + * Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + * A compat class for MXUnit Directory Test Suite + */ +component { /** - * Constructor - * @bundles - * @testSpecs - */ - function init( - required bundles, - testSpecs="" - ){ - - for( var thisArg in arguments ){ + * Constructor + * @bundles + * @testSpecs + */ + function init( required bundles, testSpecs = "" ){ + for ( var thisArg in arguments ) { variables[ thisArg ] = arguments[ thisArg ]; - } - + } + return this; - } - - /** - * Get the results output in a specific mode - * @mode The mode of the output - */ - any function getResultsOutput( mode="simple" ){ + } - switch( arguments.mode ){ - case "junitxml" : { arguments.mode = "junit"; break; } - case "query" : case "array" : { arguments.mode = "raw"; break; } - case "html" : case "rawhtml" : { arguments.mode = "simple"; break; } - default : { arguments.mode = "simple"; } + /** + * Get the results output in a specific mode + * @mode The mode of the output + */ + any function getResultsOutput( mode = "simple" ){ + switch ( arguments.mode ) { + case "junitxml": { + arguments.mode = "junit"; + break; + } + case "query": + case "array": { + arguments.mode = "raw"; + break; + } + case "html": + case "rawhtml": { + arguments.mode = "simple"; + break; + } + default: { + arguments.mode = "simple"; + } } - var tb = new testbox.system.TestBox( bundles=variables.bundles ); - - return tb.run( testSpecs=variables.testSpecs, reporter=arguments.mode ); + var tb = new testbox.system.TestBox( bundles = variables.bundles ); + + return tb.run( testSpecs = variables.testSpecs, reporter = arguments.mode ); } -} \ No newline at end of file +} diff --git a/system/compat/framework/TestCase.cfc b/system/compat/framework/TestCase.cfc index 9c5ee6c1..31eb91da 100644 --- a/system/compat/framework/TestCase.cfc +++ b/system/compat/framework/TestCase.cfc @@ -1,64 +1,85 @@ /** -* Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp -* www.ortussolutions.com -* --- -* This is the TestBox MXUnit compatible object. You can use this object as a direct replacement -* To MXUnit BaseTest Case. -* All assertions found in this object delegate to our core Assertion object. -*/ -component extends="testbox.system.BaseSpec"{ + * Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + * This is the TestBox MXUnit compatible object. You can use this object as a direct replacement + * To MXUnit BaseTest Case. + * All assertions found in this object delegate to our core Assertion object. + */ +component extends="testbox.system.BaseSpec" { // ExpectedException Annotation - this.$exceptionAnnotation = "mxunit:expectedException"; + this.$exceptionAnnotation = "mxunit:expectedException"; -/*********************************** LIFE-CYCLE Methods ***********************************/ + /*********************************** LIFE-CYCLE Methods ***********************************/ // Added signatures for backwards compat - function init(){ return this; } - function setup(){} - function teardown(){} - function afterTests(){} - function beforeTests(){} + function init(){ + return this; + } + function setup(){ + } + function teardown(){ + } + function afterTests(){ + } + function beforeTests(){ + } -/*********************************** RUNNER Methods ***********************************/ + /*********************************** RUNNER Methods ***********************************/ /** - * Run a test remotely like MXUnit - * @testMethod.hint A list or array of test names that are the ones that will be executed ONLY! - * @debug.hint Show debug output on the reports or not - * @output.hint The type of reporter to run the test with - */ - remote function runTestRemote(any testMethod="", boolean debug=false, output="simple") output=true{ - - switch( arguments.output ){ - case "junitxml" : { arguments.output = "junit"; break; } - case "query" : case "array" : { arguments.output = "raw"; break; } - case "html" : { arguments.output = "simple"; break; } - default : { arguments.output = "simple"; } + * Run a test remotely like MXUnit + * @testMethod.hint A list or array of test names that are the ones that will be executed ONLY! + * @debug.hint Show debug output on the reports or not + * @output.hint The type of reporter to run the test with + */ + remote function runTestRemote( + any testMethod = "", + boolean debug = false, + output = "simple" + ) output=true{ + switch ( arguments.output ) { + case "junitxml": { + arguments.output = "junit"; + break; + } + case "query": + case "array": { + arguments.output = "raw"; + break; + } + case "html": { + arguments.output = "simple"; + break; + } + default: { + arguments.output = "simple"; + } } - var runner = new testbox.system.TestBox( bundles="#getMetadata( this ).name#", reporter=arguments.output ); + var runner = new testbox.system.TestBox( bundles = "#getMetadata( this ).name#", reporter = arguments.output ); // Produce report - writeOutput( runner.run( testSpecs=arguments.testMethod ) ); + writeOutput( runner.run( testSpecs = arguments.testMethod ) ); } -/*********************************** UTILITY Methods ***********************************/ + /*********************************** UTILITY Methods ***********************************/ /** - * Utility for dynamically adding assertion behaviors at runtime - * @decoratorName.hint The fully qualified name of the assertion component to add; e.g., org.mycompany.MyAssertionComponent - */ + * Utility for dynamically adding assertion behaviors at runtime + * @decoratorName.hint The fully qualified name of the assertion component to add; e.g., org.mycompany.MyAssertionComponent + */ function addAssertDecorator( required string decoratorName ){ - var oDecorator = new "#arguments.decoratorName#"(); + var oDecorator = new "#arguments.decoratorName#"( ); var aFunctions = getMetadata( oDecorator ).functions; // iterate and add - for( var x=1; x lte arrayLen( aFunctions ); x++ ){ + for ( var x = 1; x lte arrayLen( aFunctions ); x++ ) { var thisFunction = aFunctions[ x ]; - if( !structKeyExists( thisFunction, "access" ) or thisFunction.access eq "public" ){ - variables[ thisFunction.name ] = oDecorator[ thisFunction.name ]; - this[ thisFunction.name ] = oDecorator[ thisFunction.name ]; + if ( !structKeyExists( thisFunction, "access" ) or thisFunction.access eq "public" ) { + variables[ thisFunction.name ] = oDecorator[ thisFunction.name ]; + this[ thisFunction.name ] = oDecorator[ thisFunction.name ]; } } @@ -78,262 +99,379 @@ component extends="testbox.system.BaseSpec"{ } /** - * MXUnit style debug - * @var.hint The variable to debug - * @label.hint The label to add to the debug entry - */ - function debug( required var, string label="" ){ + * MXUnit style debug + * @var.hint The variable to debug + * @label.hint The label to add to the debug entry + */ + function debug( required var, string label = "" ){ arguments.deepCopy = true; - super.debug( argumentCollection=arguments ); + super.debug( argumentCollection = arguments ); } /** - * Expect an exception from the testing spec - * @expectedExceptionType.hint the type to expect - * @expectedExceptionMessage.hint Optional exception message - */ - function expectException( expectedExceptionType, expectedExceptionMessage=".*" ){ + * Expect an exception from the testing spec + * @expectedExceptionType.hint the type to expect + * @expectedExceptionMessage.hint Optional exception message + */ + function expectException( expectedExceptionType, expectedExceptionMessage = ".*" ){ super.expectedException( arguments.expectedExceptionType, arguments.expectedExceptionMessage ); } /** - * Injects properties into the receiving object - */ + * Injects properties into the receiving object + */ any function injectProperty( required any receiver, required string propertyName, required any propertyValue, - string scope="variables" + string scope = "variables" ){ // Mock it baby - getMockBox().prepareMock( arguments.receiver ) - .$property( propertyName=arguments.propertyName, - propertyScope=arguments.scope, - mock=arguments.propertyValue ); + getMockBox() + .prepareMock( arguments.receiver ) + .$property( + propertyName = arguments.propertyName, + propertyScope = arguments.scope, + mock = arguments.propertyValue + ); return arguments.receiver; } /** - * injects the method from giver into receiver. This is helpful for quick and dirty mocking - */ + * injects the method from giver into receiver. This is helpful for quick and dirty mocking + */ any function injectMethod( required any receiver, required any giver, required string functionName, - string functionNameInReceiver="#arguments.functionName#" + string functionNameInReceiver = "#arguments.functionName#" ){ // Mock it baby getMockBox().prepareMock( arguments.giver ); getMockBox().prepareMock( arguments.receiver ); // inject it. - if( structkeyexists( arguments.giver, arguments.functionName ) ){ + if ( structKeyExists( arguments.giver, arguments.functionName ) ) { arguments.receiver.$property( - propertyName = arguments.functionNameInReceiver, - propertyScope = "this", - mock = arguments.giver.$getProperty( name=arguments.functionName, scope="this" ) + propertyName = arguments.functionNameInReceiver, + propertyScope = "this", + mock = arguments.giver.$getProperty( name = arguments.functionName, scope = "this" ) ); arguments.receiver.$property( - propertyName = arguments.functionNameInReceiver, - propertyScope = "variables", - mock = arguments.giver.$getProperty( name=arguments.functionName, scope="this" ) + propertyName = arguments.functionNameInReceiver, + propertyScope = "variables", + mock = arguments.giver.$getProperty( name = arguments.functionName, scope = "this" ) ); } else { arguments.receiver.$property( - propertyName = arguments.functionNameInReceiver, - propertyScope = "this", - mock = arguments.giver.$getProperty( name=arguments.functionName, scope="variables" ) + propertyName = arguments.functionNameInReceiver, + propertyScope = "this", + mock = arguments.giver.$getProperty( name = arguments.functionName, scope = "variables" ) ); arguments.receiver.$property( - propertyName = arguments.functionNameInReceiver, - propertyScope = "variables", - mock = arguments.giver.$getProperty( name=arguments.functionName, scope="variables" ) + propertyName = arguments.functionNameInReceiver, + propertyScope = "variables", + mock = arguments.giver.$getProperty( name = arguments.functionName, scope = "variables" ) ); } return arguments.receiver; } -/*********************************** ASSERTION METHODS ***********************************/ + /*********************************** ASSERTION METHODS ***********************************/ /** - * Fail assertion - * @message.hint The message to fail with - */ - function fail( message="", detail="" ){ - this.$assert.fail( argumentCollection=arguments ); + * Fail assertion + * @message.hint The message to fail with + */ + function fail( message = "", detail = "" ){ + this.$assert.fail( argumentCollection = arguments ); } /** - * Assert that the passed expression is true - */ - function assert( required string condition, message="" ){ + * Assert that the passed expression is true + */ + function assert( required string condition, message = "" ){ this.$assert.isTrue( arguments.condition, arguments.message ); } /** - * Compares two arrays, element by element, and fails if differences exist - */ - function assertArrayEquals( required array expected, required array actual, message="" ){ - this.$assert.isEqual( arguments.expected, arguments.actual, arguments.message ); + * Compares two arrays, element by element, and fails if differences exist + */ + function assertArrayEquals( + required array expected, + required array actual, + message = "" + ){ + this.$assert.isEqual( + arguments.expected, + arguments.actual, + arguments.message + ); } /** - * Core assertion that compares the values the EXPECTED and ACTUAL parameters - */ - function assertEquals( required any expected, required any actual, message="" ){ - this.$assert.isEqual( arguments.expected, arguments.actual, arguments.message ); + * Core assertion that compares the values the EXPECTED and ACTUAL parameters + */ + function assertEquals( + required any expected, + required any actual, + message = "" + ){ + this.$assert.isEqual( + arguments.expected, + arguments.actual, + arguments.message + ); } /** - * Core assertion that compares the values the EXPECTED and ACTUAL parameters with case-sensitivity - */ - function assertEqualsCase( required any expected, required any actual, message="" ){ - this.$assert.isEqualWithCase( arguments.expected, arguments.actual, arguments.message ); + * Core assertion that compares the values the EXPECTED and ACTUAL parameters with case-sensitivity + */ + function assertEqualsCase( + required any expected, + required any actual, + message = "" + ){ + this.$assert.isEqualWithCase( + arguments.expected, + arguments.actual, + arguments.message + ); } /** - * Assert something is false - */ - function assertFalse( required string condition, message="" ){ + * Assert something is false + */ + function assertFalse( required string condition, message = "" ){ this.$assert.isFalse( arguments.condition, arguments.message ); } /** - * Core assertion that compares the values the EXPECTED and ACTUAL parameters to NOT be equal - */ - function assertNotEquals( required any expected, required any actual, message="" ){ - this.$assert.isNotEqual( arguments.expected, arguments.actual, arguments.message ); + * Core assertion that compares the values the EXPECTED and ACTUAL parameters to NOT be equal + */ + function assertNotEquals( + required any expected, + required any actual, + message = "" + ){ + this.$assert.isNotEqual( + arguments.expected, + arguments.actual, + arguments.message + ); } /** - * Assert that an expected and actual object is NOT the same instance - * This only works on objects that are passed by reference, please remember that in Lucee - * arrays pass by reference and in Adobe CF they pass by value. - */ - function assertNotSame( required expected, required actual, message="" ){ - this.$assert.isNotSameInstance( arguments.expected, arguments.actual, arguments.message ); + * Assert that an expected and actual object is NOT the same instance + * This only works on objects that are passed by reference, please remember that in Lucee + * arrays pass by reference and in Adobe CF they pass by value. + */ + function assertNotSame( + required expected, + required actual, + message = "" + ){ + this.$assert.isNotSameInstance( + arguments.expected, + arguments.actual, + arguments.message + ); } /** - * Compares 2 queries, cell by cell, and fails if differences exist - */ - function assertQueryEquals( required query expected, required query actual, message="" ){ - this.$assert.isEqual( arguments.expected, arguments.actual, arguments.message ); + * Compares 2 queries, cell by cell, and fails if differences exist + */ + function assertQueryEquals( + required query expected, + required query actual, + message = "" + ){ + this.$assert.isEqual( + arguments.expected, + arguments.actual, + arguments.message + ); } /** - * Assert that an expected and actual object is the same instance - * This only works on objects that are passed by reference, please remember that in Lucee - * arrays pass by reference and in Adobe CF they pass by value. - */ - function assertSame( required expected, required actual, message="" ){ - this.$assert.isSameInstance( arguments.expected, arguments.actual, arguments.message ); + * Assert that an expected and actual object is the same instance + * This only works on objects that are passed by reference, please remember that in Lucee + * arrays pass by reference and in Adobe CF they pass by value. + */ + function assertSame( + required expected, + required actual, + message = "" + ){ + this.$assert.isSameInstance( + arguments.expected, + arguments.actual, + arguments.message + ); } /** - * Compares two structures, key by key, and fails if differences exist - */ - function assertStructEquals( required struct expected, required struct actual, message="" ){ - this.$assert.isEqual( arguments.expected, arguments.actual, arguments.message ); + * Compares two structures, key by key, and fails if differences exist + */ + function assertStructEquals( + required struct expected, + required struct actual, + message = "" + ){ + this.$assert.isEqual( + arguments.expected, + arguments.actual, + arguments.message + ); } /** - * Assert something is true - */ - function assertTrue( required string condition, message="" ){ + * Assert something is true + */ + function assertTrue( required string condition, message = "" ){ this.$assert.isTrue( arguments.condition, arguments.message ); } /** - * Assert something is array - */ - function assertIsArray( required a, message="" ){ - this.$assert.typeOf( "array", arguments.a, arguments.message ); + * Assert something is array + */ + function assertIsArray( required a, message = "" ){ + this.$assert.typeOf( + "array", + arguments.a, + arguments.message + ); } /** - * Assert something is query - */ - function assertIsQuery( required q, message="" ){ - this.$assert.typeOf( "query", arguments.q, arguments.message ); + * Assert something is query + */ + function assertIsQuery( required q, message = "" ){ + this.$assert.typeOf( + "query", + arguments.q, + arguments.message + ); } /** - * Assert something is struct - */ - function assertIsStruct( required actual, message="" ){ - this.$assert.typeOf( "struct", arguments.actual, arguments.message ); + * Assert something is struct + */ + function assertIsStruct( required actual, message = "" ){ + this.$assert.typeOf( + "struct", + arguments.actual, + arguments.message + ); } /** - * Assert something is of a certain object type - */ - function assertIsTypeOf( required actual, required typeName, message="" ){ - this.$assert.instanceOf( arguments.actual, arguments.typeName, arguments.message ); + * Assert something is of a certain object type + */ + function assertIsTypeOf( + required actual, + required typeName, + message = "" + ){ + this.$assert.instanceOf( + arguments.actual, + arguments.typeName, + arguments.message + ); } /** - * Assert something is of a certain object type without any inheritance lookup - */ - function assertIsExactTypeOf( required o, required type, message="" ){ - this.$assert.isEqual( arguments.type, getMetadata( arguments.o ).name, arguments.message ); + * Assert something is of a certain object type without any inheritance lookup + */ + function assertIsExactTypeOf( + required o, + required type, + message = "" + ){ + this.$assert.isEqual( + arguments.type, + getMetadata( arguments.o ).name, + arguments.message + ); } /** - * Assert something is defined or not - */ - function assertIsDefined( required o, message="" ){ - this.$assert.isTrue( isDefined( evaluate( "arguments.o" ) ) , arguments.message ); + * Assert something is defined or not + */ + function assertIsDefined( required o, message = "" ){ + this.$assert.isTrue( isDefined( evaluate( "arguments.o" ) ), arguments.message ); } /** - * Assert something is an XMLDoc - */ - function assertIsXMLDoc( required xml, message="Passed in xml is not a valid XML Object" ){ + * Assert something is an XMLDoc + */ + function assertIsXMLDoc( required xml, message = "Passed in xml is not a valid XML Object" ){ this.$assert.isTrue( isXMLDoc( arguments.xml ), arguments.message ); } /** - * Assert array is empty - */ - function assertIsEmptyArray( required a, message="" ){ - this.$assert.isEqual( 0, arrayLen( arguments.a ), arguments.message ); + * Assert array is empty + */ + function assertIsEmptyArray( required a, message = "" ){ + this.$assert.isEqual( + 0, + arrayLen( arguments.a ), + arguments.message + ); } /** - * Assert query is empty - */ - function assertIsEmptyQuery( required q, message="" ){ - this.$assert.isEqual( 0, arguments.q.recordcount, arguments.message ); + * Assert query is empty + */ + function assertIsEmptyQuery( required q, message = "" ){ + this.$assert.isEqual( + 0, + arguments.q.recordcount, + arguments.message + ); } /** - * Assert struct is empty - */ - function assertIsEmptyStruct( required struct, message="" ){ - this.$assert.isEqual( 0, structCount( arguments.struct ), arguments.message ); + * Assert struct is empty + */ + function assertIsEmptyStruct( required struct, message = "" ){ + this.$assert.isEqual( + 0, + structCount( arguments.struct ), + arguments.message + ); } /** - * Assert string is empty - */ - function assertIsEmpty( required o, message="" ){ - this.$assert.isEqual( 0, len( arguments.o ) , arguments.message ); + * Assert string is empty + */ + function assertIsEmpty( required o, message = "" ){ + this.$assert.isEqual( + 0, + len( arguments.o ), + arguments.message + ); } /** - * Assert that the passed in actual number or date is expected to be close to it within +/- a passed delta and optional datepart - */ + * Assert that the passed in actual number or date is expected to be close to it within +/- a passed delta and optional datepart + */ function assertEqualsWithTolerance( required expected, required actual, required numeric tolerance, - datePart="", - message="" + datePart = "", + message = "" ){ - this.$assert.closeTo( arguments.expected, arguments.actual, arguments.tolerance, arguments.datePart, arguments.message ); + this.$assert.closeTo( + arguments.expected, + arguments.actual, + arguments.tolerance, + arguments.datePart, + arguments.message + ); } -} \ No newline at end of file +} diff --git a/system/compat/framework/TestSuite.cfc b/system/compat/framework/TestSuite.cfc index c3b7a9f0..8ea3c1e8 100644 --- a/system/compat/framework/TestSuite.cfc +++ b/system/compat/framework/TestSuite.cfc @@ -1,19 +1,19 @@ /** -* Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp -* www.ortussolutions.com -* --- -* MXUnit compatibility for Test Suites -*/ -component accessors="true"{ + * Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + * MXUnit compatibility for Test Suites + */ +component accessors="true" { property name="bundles"; property name="testSpecs"; - + // constructor function testSuite(){ - variables.bundles = []; + variables.bundles = []; variables.testSpecs = []; - + return this; } @@ -22,36 +22,40 @@ component accessors="true"{ variables.testSpecs.addAll( listToArray( arguments.method ) ); return this; } - + remote function add( required componentName, required methods ){ arrayAppend( variables.bundles, arguments.componentName ); variables.testSpecs.addAll( listToArray( arguments.methods ) ); return this; } - + remote function addAll( required componentName ){ - arrayAppend( variables.bundles, arguments.componentName ); + arrayAppend( variables.bundles, arguments.componentName ); return this; } - remote function run( testMethod="" ){ - if( len( arguments.testMethod ) ){ + remote function run( testMethod = "" ){ + if ( len( arguments.testMethod ) ) { variables.testSpecs.addAll( listToArray( arguments.testMethod ) ); } return new Results( variables.bundles, variables.testSpecs ); } /** - * Run a test remotely like MXUnit - * @testMethod.hint A list or array of test names that are the ones that will be executed ONLY! - * @debug.hint Show debug output on the reports or not - * @output.hint The type of reporter to run the test with - */ - remote function runTestRemote(any testMethod="", boolean debug=false, output="simple") output=true{ - var runner = new testbox.system.TestBox( bundles="#getMetadata(this).name#", reporter=arguments.output ); + * Run a test remotely like MXUnit + * @testMethod.hint A list or array of test names that are the ones that will be executed ONLY! + * @debug.hint Show debug output on the reports or not + * @output.hint The type of reporter to run the test with + */ + remote function runTestRemote( + any testMethod = "", + boolean debug = false, + output = "simple" + ) output=true{ + var runner = new testbox.system.TestBox( bundles = "#getMetadata( this ).name#", reporter = arguments.output ); // Produce report - writeOutput( runner.run( testSpecs=arguments.testMethod ) ); + writeOutput( runner.run( testSpecs = arguments.testMethod ) ); } -} \ No newline at end of file +} diff --git a/system/compat/runner/DirectoryTestSuite.cfc b/system/compat/runner/DirectoryTestSuite.cfc index faafbe8b..11fcbce1 100644 --- a/system/compat/runner/DirectoryTestSuite.cfc +++ b/system/compat/runner/DirectoryTestSuite.cfc @@ -1,36 +1,60 @@ - - - - - + + + + - if( NOT len( arguments.componentPath ) ){ - arguments.componentPath = getComponentPath( arguments.directory ); - } - return new Results( argumentCollection=arguments ); + if ( NOT len( arguments.componentPath ) ) { + arguments.componentPath = getComponentPath( arguments.directory ); + } + return new Results( argumentCollection = arguments ); - - - - + + + - var explorer = createObject( "component", "CFIDE.componentutils.cfcexplorer" ); - var target = explorer.normalizePath( arguments.path ); - var cfcs = explorer.getcfcs( true ); //true == refresh cache - var package = ""; + var explorer = createObject( "component", "CFIDE.componentutils.cfcexplorer" ); + var target = explorer.normalizePath( arguments.path ); + var cfcs = explorer.getcfcs( true ); // true == refresh cache + var package = ""; - for( var i = 1; i lte arraylen( cfcs ); i++ ){ - var cfc = cfcs[ i ]; - //Assumes that CF always stores path info with fwd slash - //and strip last element to get path. - var cfcpath = ListDeleteAt( cfc.path, listlen( cfc.path, "/" ), "/" ); + for ( var i = 1; i lte arrayLen( cfcs ); i++ ) { + var cfc = cfcs[ i ]; + // Assumes that CF always stores path info with fwd slash + // and strip last element to get path. + var cfcpath = listDeleteAt( + cfc.path, + listLen( cfc.path, "/" ), + "/" + ); - //Array of structs. Doesn't seem possible to do binary search - if( cfcpath eq target ){ + // Array of structs. Doesn't seem possible to do binary search + if ( cfcpath eq target ) { package = cfc.package; break; } @@ -39,5 +63,4 @@ return package; - - \ No newline at end of file + diff --git a/system/compat/runner/Results.cfc b/system/compat/runner/Results.cfc index 5949bd68..97eec8a9 100644 --- a/system/compat/runner/Results.cfc +++ b/system/compat/runner/Results.cfc @@ -1,56 +1,69 @@ /** -* Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp -* www.ortussolutions.com -* --- -* A compat class for MXUnit Directory Test Suite -*/ -component{ - - function init( + * Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + * A compat class for MXUnit Directory Test Suite + */ +component { + + function init( required directory, - componentPath="", - boolean recurse=true, - excludes="" + componentPath = "", + boolean recurse = true, + excludes = "" ){ - - for( var thisArg in arguments ){ + for ( var thisArg in arguments ) { variables[ thisArg ] = arguments[ thisArg ]; - } - + } + return this; - } - - any function getResultsOutput( mode="simple" ){ + } + + any function getResultsOutput( mode = "simple" ){ var dir = { - recurse = variables.recurse, - mapping = variables.componentPath, - filter = variables.filterExcludes + recurse : variables.recurse, + mapping : variables.componentPath, + filter : variables.filterExcludes }; - switch( arguments.mode ){ - case "junitxml" : { arguments.mode = "junit"; break; } - case "query" : case "array" : { arguments.mode = "raw"; break; } - case "html" : case "rawhtml" : { arguments.mode = "simple"; break; } - default : { arguments.mode = "simple"; } + switch ( arguments.mode ) { + case "junitxml": { + arguments.mode = "junit"; + break; + } + case "query": + case "array": { + arguments.mode = "raw"; + break; + } + case "html": + case "rawhtml": { + arguments.mode = "simple"; + break; + } + default: { + arguments.mode = "simple"; + } } - var tb = new testbox.system.TestBox( directory=dir, - reporter=arguments.mode, - options={ excludes=variables.excludes } ); - + var tb = new testbox.system.TestBox( + directory = dir, + reporter = arguments.mode, + options = { excludes : variables.excludes } + ); + return tb.run(); } /** - * This will execute within the context of TestBox, it is not a closure as to remain cf9 compat - */ + * This will execute within the context of TestBox, it is not a closure as to remain cf9 compat + */ private function filterExcludes( required path ){ var excludes = getOptions().excludes; var cfcName = listFirst( getFileFromPath( arguments.path ), "." ); return ( listFindNoCase( excludes, cfcName ) ? false : true ); - } -} \ No newline at end of file +} diff --git a/system/coverage/CoverageService.cfc b/system/coverage/CoverageService.cfc index 501f17d9..e5432828 100644 --- a/system/coverage/CoverageService.cfc +++ b/system/coverage/CoverageService.cfc @@ -1,19 +1,19 @@ /** -* ******************************************************************************** -* Copyright Ortus Solutions, Corp -* www.ortussolutions.com -* ******************************************************************************** -* -* I handle capturing line coverage data. I can accept the following options: -* -* enabled - Boolean to turn coverage on or off -* sonarQube.XMLOutputPath Absolute XML file path to write XML sunarQube file -* browser.outputDir Absolute directory path to create html code coverage browser -* pathToCapture Absolute path to root folder to capture coverage. Typically your web root -* whitelist A comma-delimited list of file globbing paths relative to your pathToCapture of the ONLY files to match. When emtpy, everything is matched by default -* blacklist A comma-delimited list of file globbing paths relative to your pathToCapture of files to ignore -* -*/ + * ******************************************************************************** + * Copyright Ortus Solutions, Corp + * www.ortussolutions.com + * ******************************************************************************** + * + * I handle capturing line coverage data. I can accept the following options: + * + * enabled - Boolean to turn coverage on or off + * sonarQube.XMLOutputPath Absolute XML file path to write XML sunarQube file + * browser.outputDir Absolute directory path to create html code coverage browser + * pathToCapture Absolute path to root folder to capture coverage. Typically your web root + * whitelist A comma-delimited list of file globbing paths relative to your pathToCapture of the ONLY files to match. When emtpy, everything is matched by default + * blacklist A comma-delimited list of file globbing paths relative to your pathToCapture of files to ignore + * + */ component accessors="true" { /** @@ -36,26 +36,25 @@ component accessors="true" { * * @coverageOptions struct of options to initialize with */ - function init( coverageOptions={} ) { + function init( coverageOptions = {} ){ + // Default options + variables.coverageOptions = setDefaultOptions( coverageOptions ); + variables.coverageEnabled = coverageOptions.enabled; - // Default options - variables.coverageOptions = setDefaultOptions( coverageOptions ); - variables.coverageEnabled = coverageOptions.enabled; - - // If disabled in config, go no further - if( coverageEnabled ) { + // If disabled in config, go no further + if ( coverageEnabled ) { variables.coverageGenerator = new data.CoverageGenerator(); - variables.coverageEnabled = coverageGenerator.configure(); + variables.coverageEnabled = coverageGenerator.configure(); } return this; } /** - * Reset system for a new test. Turns on line coverage and resets in-memory statistics - */ - CoverageService function beginCapture() { - if( coverageEnabled ) { + * Reset system for a new test. Turns on line coverage and resets in-memory statistics + */ + CoverageService function beginCapture(){ + if ( coverageEnabled ) { coverageGenerator.beginCapture(); } @@ -67,8 +66,8 @@ component accessors="true" { * * @leaveLineProfilingOn Set to true to leave line profiling enabled on the server */ - CoverageService function endCapture( leaveLineProfilingOn=false ) { - if( coverageEnabled ){ + CoverageService function endCapture( leaveLineProfilingOn = false ){ + if ( coverageEnabled ) { coverageGenerator.endCapture( leaveLineProfilingOn ); } @@ -76,48 +75,49 @@ component accessors="true" { } /** - * Process Code Coverage if enabled and set results inside the TestResult object - * - * @results.hint The instance of the TestBox TestResult object to build a report on - * @testbox.hint The TestBox core object - */ + * Process Code Coverage if enabled and set results inside the TestResult object + * + * @results.hint The instance of the TestBox TestResult object to build a report on + * @testbox.hint The TestBox core object + */ CoverageService function processCoverage( required testbox.system.TestResult results, required testbox.system.TestBox testbox ){ - - if( getCoverageEnabled() ) { - - // Prepare coverage data - var qryCoverageData = generateCoverageData( getCoverageOptions() ); - - // SonarQube Integration - var sonarQubeResults = processSonarQube( qryCoverageData, getCoverageOptions() ); - - // Generate Stats - var stats = processStats( qryCoverageData ); - - // Generate code browser - var browserResults = processCodeBrowser( qryCoverageData, stats, getCoverageOptions() ); - - results.setCoverageEnabled( true ); - results.setCoverageData( { - 'qryData' : qryCoverageData, - 'stats' : stats, - 'sonarQubeResults' : sonarQubeResults, - 'browserResults' : browserResults + if ( getCoverageEnabled() ) { + // Prepare coverage data + var qryCoverageData = generateCoverageData( getCoverageOptions() ); + + // SonarQube Integration + var sonarQubeResults = processSonarQube( qryCoverageData, getCoverageOptions() ); + + // Generate Stats + var stats = processStats( qryCoverageData ); + + // Generate code browser + var browserResults = processCodeBrowser( + qryCoverageData, + stats, + getCoverageOptions() + ); + + results.setCoverageEnabled( true ); + results.setCoverageData( { + "qryData" : qryCoverageData, + "stats" : stats, + "sonarQubeResults" : sonarQubeResults, + "browserResults" : browserResults } ); - } return this; } /** - * Render HTML representation of statistics - */ - function renderStats( required struct coverageData, boolean fullPage=true ) { - var stats = coverageData.stats; + * Render HTML representation of statistics + */ + function renderStats( required struct coverageData, boolean fullPage = true ){ + var stats = coverageData.stats; var pathToCapture = getCoverageOptions().pathToCapture; var codeBrowser = new browser.CodeBrowser( getCoverageOptions().coverageTresholds ); @@ -134,71 +134,93 @@ component accessors="true" { * * @opts The options to default and check */ - private function setDefaultOptions( struct opts={} ) { - - if( isNull( opts.enabled ) ) { opts.enabled = true; } + private function setDefaultOptions( struct opts = {} ){ + if ( isNull( opts.enabled ) ) { + opts.enabled = true; + } - if( isNull( opts.sonarQube ) ) { opts.sonarQube = {}; } - if( isNull( opts.sonarQube.XMLOutputPath ) ) { opts.sonarQube.XMLOutputPath = ''; } + if ( isNull( opts.sonarQube ) ) { + opts.sonarQube = {}; + } + if ( isNull( opts.sonarQube.XMLOutputPath ) ) { + opts.sonarQube.XMLOutputPath = ""; + } - if( isNull( opts.browser ) ) { opts.browser = {}; } - if( isNull( opts.browser.outputDir ) ) { opts.browser.outputDir = ''; } + if ( isNull( opts.browser ) ) { + opts.browser = {}; + } + if ( isNull( opts.browser.outputDir ) ) { + opts.browser.outputDir = ""; + } // Clean up the browser output dir if it is set - if( len( opts.browser.outputDir ) ) { - + if ( len( opts.browser.outputDir ) ) { // Expand the output dir if it looks like it needs it - if( !directoryExists( opts.browser.outputDir ) && directoryExists( expandPath( opts.browser.outputDir ) ) ) { + if ( !directoryExists( opts.browser.outputDir ) && directoryExists( expandPath( opts.browser.outputDir ) ) ) { opts.browser.outputDir = expandPath( opts.browser.outputDir ); } - + opts.browser.outputDir = normalizeSlashes( opts.browser.outputDir ); - - if ( !opts.browser.outputDir.endsWith( '/' ) ) { - opts.browser.outputDir = opts.browser.outputDir & '/'; + + if ( !opts.browser.outputDir.endsWith( "/" ) ) { + opts.browser.outputDir = opts.browser.outputDir & "/"; } } - if( isNull( opts.coverageTresholds ) ) { opts.coverageTresholds = {}; } - if( isNull( opts.coverageTresholds.good ) ) { opts.coverageTresholds.good = 85; } - if( isNull( opts.coverageTresholds.bad ) ) { opts.coverageTresholds.bad = 50; } + if ( isNull( opts.coverageTresholds ) ) { + opts.coverageTresholds = {}; + } + if ( isNull( opts.coverageTresholds.good ) ) { + opts.coverageTresholds.good = 85; + } + if ( isNull( opts.coverageTresholds.bad ) ) { + opts.coverageTresholds.bad = 50; + } - if( isNull( opts.pathToCapture ) ) { opts.pathToCapture = ''; } - if( isNull( opts.whitelist ) ) { opts.whitelist = ''; } - if( isNull( opts.blacklist ) ) { opts.blacklist = ''; } + if ( isNull( opts.pathToCapture ) ) { + opts.pathToCapture = ""; + } + if ( isNull( opts.whitelist ) ) { + opts.whitelist = ""; + } + if ( isNull( opts.blacklist ) ) { + opts.blacklist = ""; + } // If no path provided to capture - if( !len( opts.pathToCapture ) ) { - + if ( !len( opts.pathToCapture ) ) { // Look for a /root mapping which is a common ColdBox convention - if( !isNull( getApplicationMetadata().mappings ) ) { + if ( !isNull( getApplicationMetadata().mappings ) ) { var mappings = getApplicationMetadata().mappings; } else { - var mappings = {}; + var mappings = {}; } - if( mappings.keyExists( '/root' ) ) { - opts.pathToCapture = expandPath( '/root' ); - // And default to entire web root + if ( mappings.keyExists( "/root" ) ) { + opts.pathToCapture = expandPath( "/root" ); + // And default to entire web root } else { - opts.pathToCapture = expandPath( '/' ); + opts.pathToCapture = expandPath( "/" ); } - } else if( !directoryExists( opts.pathToCapture ) && directoryExists( expandPath( opts.pathToCapture ) ) ) { + } else if ( !directoryExists( opts.pathToCapture ) && directoryExists( expandPath( opts.pathToCapture ) ) ) { opts.pathToCapture = expandPath( opts.pathToCapture ); } - + opts.pathToCapture = normalizeSlashes( opts.pathToCapture ); - if ( !opts.pathToCapture.endsWith( '/' ) ) { - opts.pathToCapture = opts.pathToCapture & '/'; + if ( !opts.pathToCapture.endsWith( "/" ) ) { + opts.pathToCapture = opts.pathToCapture & "/"; } - + // Bypass validation if not enabled - if( !opts.enabled ) { + if ( !opts.enabled ) { return opts; } - if( !directoryExists( opts.pathToCapture ) ) { - throw( message='Coverage option [pathToCapture] does not point to a real and absolute directory path.', detail=opts.pathToCapture ); + if ( !directoryExists( opts.pathToCapture ) ) { + throw( + message = "Coverage option [pathToCapture] does not point to a real and absolute directory path.", + detail = opts.pathToCapture + ); } return opts; @@ -207,7 +229,7 @@ component accessors="true" { /** * Interface with FusionReactor to build coverage data */ - private function generateCoverageData( required struct opts ) { + private function generateCoverageData( required struct opts ){ return coverageGenerator.generateData( opts.pathToCapture, opts.whitelist, @@ -216,10 +238,10 @@ component accessors="true" { } /** - * Write out SonarQube generic coverage XML file - */ - private function processSonarQube( required query qryCoverageData, required struct opts ) { - if( len( opts.sonarQube.XMLOutputPath ) ) { + * Write out SonarQube generic coverage XML file + */ + private function processSonarQube( required query qryCoverageData, required struct opts ){ + if ( len( opts.sonarQube.XMLOutputPath ) ) { // Create XML generator var sonarQube = new sonarqube.SonarQube(); // Prettify output @@ -227,44 +249,48 @@ component accessors="true" { // Generate XML (writes file and returns string sonarQube.generateXML( qryCoverageData, opts.sonarQube.XMLOutputPath ); - return opts.sonarQube.XMLOutputPath; - } - return ''; + return opts.sonarQube.XMLOutputPath; + } + return ""; } /** - * Generate statistics from the coverage data - */ - private function processStats( required query qryCoverageData ) { - var coverageStats = new stats.CoverageStats(); - return coverageStats.generateStats( qryCoverageData ); + * Generate statistics from the coverage data + */ + private function processStats( required query qryCoverageData ){ + var coverageStats = new stats.CoverageStats(); + return coverageStats.generateStats( qryCoverageData ); } /** - * Generate code browser - */ - private function processCodeBrowser( qryCoverageData, stats, opts ) { + * Generate code browser + */ + private function processCodeBrowser( qryCoverageData, stats, opts ){ // Only generate browser if there's a generation path specified - if( len( opts.browser.outputDir ) ) { - var codeBrowser = new browser.CodeBrowser( opts.coverageTresholds ); - codeBrowser.generateBrowser( qryCoverageData, stats, opts.browser.outputDir ); - return opts.browser.outputDir; + if ( len( opts.browser.outputDir ) ) { + var codeBrowser = new browser.CodeBrowser( opts.coverageTresholds ); + codeBrowser.generateBrowser( + qryCoverageData, + stats, + opts.browser.outputDir + ); + return opts.browser.outputDir; } - return ''; + return ""; } - + /* - * Turns all slashes in a path to forward slashes except for \\ in a Windows UNC network share - * Also changes double slashes to a single slash - */ - function normalizeSlashes( string path ) { - if( path.left( 2 ) == '\\' ) { - path = '\\' & path.replace( '\', '/', 'all' ).right( len( path ) - 2 ); - return path.replace( '//', '/', 'all' ); + * Turns all slashes in a path to forward slashes except for \\ in a Windows UNC network share + * Also changes double slashes to a single slash + */ + function normalizeSlashes( string path ){ + if ( path.left( 2 ) == "\\" ) { + path = "\\" & path.replace( "\", "/", "all" ).right( len( path ) - 2 ); + return path.replace( "//", "/", "all" ); } else { - return path.replace( '\', '/', 'all' ).replace( '//', '/', 'all' ); + return path.replace( "\", "/", "all" ).replace( "//", "/", "all" ); } } -} \ No newline at end of file +} diff --git a/system/coverage/browser/CodeBrowser.cfc b/system/coverage/browser/CodeBrowser.cfc index 2742e418..7f44d044 100644 --- a/system/coverage/browser/CodeBrowser.cfc +++ b/system/coverage/browser/CodeBrowser.cfc @@ -5,7 +5,7 @@ * ******************************************************************************** * I generate a code browser to see file-level coverage statistics */ -component accessors = true { +component accessors=true { // Location of all assets in TestBox variables.ASSETS_DIR = expandPath( "/testbox/system/reports/assets" ); @@ -15,8 +15,8 @@ component accessors = true { * * @coverageTresholds Options for threshold */ - function init( required struct coverageTresholds ) { - variables.streamBuilder = new testbox.system.modules.cbstreams.models.StreamBuilder(); + function init( required struct coverageTresholds ){ + variables.streamBuilder = new testbox.system.modules.cbstreams.models.StreamBuilder(); variables.coverageTresholds = arguments.coverageTresholds; return this; @@ -31,8 +31,7 @@ component accessors = true { required query qryCoverageData, required struct stats, required string browserOutputDir - ) { - + ){ // wipe old files if ( directoryExists( browserOutputDir ) ) { try { @@ -46,23 +45,27 @@ component accessors = true { // Create it fresh if ( !directoryExists( browserOutputDir ) ) { directoryCreate( browserOutputDir ); - directoryCopy( "#variables.ASSETS_DIR#", "#browserOutputDir#/assets", true ); + directoryCopy( + "#variables.ASSETS_DIR#", + "#browserOutputDir#/assets", + true + ); } // Create index - savecontent variable = "local.index" { + savecontent variable="local.index" { include "templates/index.cfm"; } - fileWrite( browserOutputDir & '/index.html', local.index ); + fileWrite( browserOutputDir & "/index.html", local.index ); // Create directory skeletons var dataStream = variables.streamBuilder .new() .rangeClosed( 1, qryCoverageData.recordcount ) - .map( function ( index ) { + .map( function( index ){ return qryCoverageData.getRow( index ); } ) - .peek( function ( item ) { + .peek( function( item ){ var theContainerDirectory = getDirectoryFromPath( "#browserOutputDir & item.relativeFilePath#" ); if ( !directoryExists( theContainerDirectory ) ) { @@ -75,31 +78,30 @@ component accessors = true { var fileStream = variables.streamBuilder.new( dataStream ); // Don't use parallel if in Adobe, it sucks! - if( server.keyExists( "lucee" ) ){ + if ( server.keyExists( "lucee" ) ) { fileStream.parallel(); } - fileStream - .forEach( function ( fileData ) { - // Coverage files are named after "real" files - var theFile = "#browserOutputDir & fileData.relativeFilePath#.html"; - - var lineNumbersBGColors = fileData.lineData.map( function ( key, value ) { - return ( value > 0 ) ? "success" : "danger"; - } ); - var percentage = numberFormat( fileData.percCoverage * 100, '9.9' ); - var lineNumbersBGColorsJSON = SerializeJSON( lineNumbersBGColors ); - var fileContents = fileRead( fileData.filePath ); - var levelsFromRoot = fileData.relativeFilePath.listLen( "/" ); - var relPathToRoot = RepeatString( "../", levelsFromRoot - 1 ); - var brush = right( fileData.relativeFilePath, 4 ) == ".cfm" ? "coldfusion" : "javascript"; - - savecontent variable = "local.fileTemplate" { - include "templates/file.cfm"; - } + fileStream.forEach( function( fileData ){ + // Coverage files are named after "real" files + var theFile = "#browserOutputDir & fileData.relativeFilePath#.html"; - fileWrite( theFile, local.fileTemplate ); + var lineNumbersBGColors = fileData.lineData.map( function( key, value ){ + return ( value > 0 ) ? "success" : "danger"; } ); + var percentage = numberFormat( fileData.percCoverage * 100, "9.9" ); + var lineNumbersBGColorsJSON = serializeJSON( lineNumbersBGColors ); + var fileContents = fileRead( fileData.filePath ); + var levelsFromRoot = fileData.relativeFilePath.listLen( "/" ); + var relPathToRoot = repeatString( "../", levelsFromRoot - 1 ); + var brush = right( fileData.relativeFilePath, 4 ) == ".cfm" ? "coldfusion" : "javascript"; + + savecontent variable="local.fileTemplate" { + include "templates/file.cfm"; + } + + fileWrite( theFile, local.fileTemplate ); + } ); } /** @@ -108,14 +110,14 @@ component accessors = true { * * @percentage The percentage to get a color on */ - function percentToContextualClass( required percentage ) { + function percentToContextualClass( required percentage ){ percentage = percentage; if ( percentage > variables.coverageTresholds.bad && percentage < variables.coverageTresholds.good ) { - return 'warning'; + return "warning"; } else if ( percentage >= variables.coverageTresholds.good ) { - return 'success'; + return "success"; } else if ( percentage <= variables.coverageTresholds.bad ) { - return 'danger'; + return "danger"; } } diff --git a/system/coverage/data/CoverageGenerator.cfc b/system/coverage/data/CoverageGenerator.cfc index b0b90757..81b6dd7e 100644 --- a/system/coverage/data/CoverageGenerator.cfc +++ b/system/coverage/data/CoverageGenerator.cfc @@ -1,39 +1,39 @@ /** -* ******************************************************************************** -* Copyright Ortus Solutions, Corp -* www.ortussolutions.com -* ******************************************************************************** -* I collect code coverage data for a directory of files and generate -* a query of data that can be consumed by different reporting interfaces. -*/ + * ******************************************************************************** + * Copyright Ortus Solutions, Corp + * www.ortussolutions.com + * ******************************************************************************** + * I collect code coverage data for a directory of files and generate + * a query of data that can be consumed by different reporting interfaces. + */ component accessors=true { /** * Constructor */ - function init() { - variables.CR = chr( 13 ); - variables.LF = chr( 10 ); + function init(){ + variables.CR = chr( 13 ); + variables.LF = chr( 10 ); variables.CRLF = CR & LF; return this; } /** - * Configure the main data collection class. - * - * @returns true if enabled, false if disabled - */ - boolean function configure() { + * Configure the main data collection class. + * + * @returns true if enabled, false if disabled + */ + boolean function configure(){ try { - variables.fragentClass = createObject( 'java', 'com.intergral.fusionreactor.agent.Agent' ); + variables.fragentClass = createObject( "java", "com.intergral.fusionreactor.agent.Agent" ); // Do a quick test to ensure the line performance instrumentation is loaded. This will return null for non-supported versions of FR - var instrumentation = fragentClass.getAgentInstrumentation().get( "cflpi" ); - } catch( Any e ) { + var instrumentation = fragentClass.getAgentInstrumentation().get( "cflpi" ); + } catch ( Any e ) { return false; } - if( isNull( instrumentation ) ) { + if ( isNull( instrumentation ) ) { return false; } @@ -41,7 +41,7 @@ component accessors=true { variables.pathPatternMatcher = new PathPatternMatcher(); // Detect server - if( listFindNoCase( "Railo,Lucee", server.coldfusion.productname ) ) { + if ( listFindNoCase( "Railo,Lucee", server.coldfusion.productname ) ) { variables.templateCompiler = new TemplateCompiler_Lucee(); } else { variables.templateCompiler = new TemplateCompiler_Adobe(); @@ -53,153 +53,191 @@ component accessors=true { /** * Reset system for a new test. Turns on line coverage and resets in-memory statistics */ - CoverageGenerator function beginCapture() { + CoverageGenerator function beginCapture(){ // Turn on line profiling - fragentClass.getAgentInstrumentation().get( "cflpi" ).setActive( true ); + fragentClass + .getAgentInstrumentation() + .get( "cflpi" ) + .setActive( true ); // Clear any data in memory - fragentClass.getAgentInstrumentation().get( "cflpi" ).reset(); + fragentClass + .getAgentInstrumentation() + .get( "cflpi" ) + .reset(); return this; } /** - * End the capture of data. Clears up memory and optionally turns off line profiling - * @leaveLineProfilingOn Set to true to leave line profiling enabled on the server - */ - CoverageGenerator function endCapture( leaveLineProfilingOn=false ) { + * End the capture of data. Clears up memory and optionally turns off line profiling + * @leaveLineProfilingOn Set to true to leave line profiling enabled on the server + */ + CoverageGenerator function endCapture( leaveLineProfilingOn = false ){ // Turn off line profiling - if( !leaveLineProfilingOn ) { - fragentClass.getAgentInstrumentation().get( "cflpi" ).setActive( false ); + if ( !leaveLineProfilingOn ) { + fragentClass + .getAgentInstrumentation() + .get( "cflpi" ) + .setActive( false ); } // Clear any data in memory - fragentClass.getAgentInstrumentation().get( "cflpi" ).reset(); + fragentClass + .getAgentInstrumentation() + .get( "cflpi" ) + .reset(); return this; } /** - * @pathToCapture The full path to a folder of code. Searched recursively - * @whitelist Comma-delimited list or array of file paths to include - * @blacklist Comma-delimited list or array of file paths to exclude - * - * @Returns query of data - */ + * @pathToCapture The full path to a folder of code. Searched recursively + * @whitelist Comma-delimited list or array of file paths to include + * @blacklist Comma-delimited list or array of file paths to exclude + * + * @Returns query of data + */ query function generateData( required string pathToCapture, - any whitelist='', - any blacklist='' - ) { + any whitelist = "", + any blacklist = "" + ){ // Convert lists to an array. - if( isSimpleValue( arguments.whitelist ) ) { arguments.whitelist = arguments.whitelist.listToArray(); } - if( isSimpleValue( arguments.blacklist ) ) { arguments.blacklist = arguments.blacklist.listToArray(); } + if ( isSimpleValue( arguments.whitelist ) ) { + arguments.whitelist = arguments.whitelist.listToArray(); + } + if ( isSimpleValue( arguments.blacklist ) ) { + arguments.blacklist = arguments.blacklist.listToArray(); + } // Get a recursive list of all CFM and CFC files in project root. - var fileList = directoryList( arguments.pathToCapture, true, "path", "*.cf?"); + var fileList = directoryList( + arguments.pathToCapture, + true, + "path", + "*.cf?" + ); // start data structure - var qryData = queryNew( "filePath,relativeFilePath,filePathHash,numLines,numCoveredLines,numExecutableLines,percCoverage,lineData", - "varchar,varchar,varchar,integer,integer,integer,decimal,object" ); + var qryData = queryNew( + "filePath,relativeFilePath,filePathHash,numLines,numCoveredLines,numExecutableLines,percCoverage,lineData", + "varchar,varchar,varchar,integer,integer,integer,decimal,object" + ); - for( var theFile in fileList ) { - theFile=theFile.replace("\","/","all"); + for ( var theFile in fileList ) { + theFile = theFile.replace( "\", "/", "all" ); - var relativeFilePath = replaceNoCase( theFile, arguments.pathToCapture, '' ); + var relativeFilePath = replaceNoCase( theFile, arguments.pathToCapture, "" ); // Skip this file if it doesn't match our patterns // Pass a path relative to our root folder - if( !isPathAllowed( relativeFilePath, arguments.whitelist, arguments.blacklist ) ) { + if ( + !isPathAllowed( + relativeFilePath, + arguments.whitelist, + arguments.blacklist + ) + ) { continue; } var fileContents = fileRead( theFile ); // Replace Windows CRLF with CR - fileContents = replaceNoCase( fileContents, CRLF, CR, 'all' ); + fileContents = replaceNoCase( fileContents, CRLF, CR, "all" ); // Replace lone LF with CR - fileContents = replaceNoCase( fileContents, LF, CR, 'all' ); + fileContents = replaceNoCase( fileContents, LF, CR, "all" ); // Break on CR, keeping empty lines - var fileLines = fileContents.listToArray( CR, true ); + var fileLines = fileContents.listToArray( CR, true ); // new file: theFile var strFiledata = { - filePath = theFile, - relativeFilePath = relativeFilePath, - numLines = arrayLen( fileLines ), - numCoveredLines = 0, - numExecutableLines = 0, - percCoverage = 0, - filePathHash = hash( theFile ) + filePath : theFile, + relativeFilePath : relativeFilePath, + numLines : arrayLen( fileLines ), + numCoveredLines : 0, + numExecutableLines : 0, + percCoverage : 0, + filePathHash : hash( theFile ) }; // Add this to query later - var lineData = createObject( 'java', 'java.util.LinkedHashMap' ).init(); - - var jFile = createObject( 'java', 'java.io.File' ).init( theFile ); - var lineMetricMap = fragentClass.getAgentInstrumentation().get("cflpi").getLineMetrics( jFile.getCanonicalPath() ); - if( isNull( lineMetricMap ) ) { + var lineData = createObject( "java", "java.util.LinkedHashMap" ).init(); + + var jFile = createObject( "java", "java.io.File" ).init( theFile ); + var lineMetricMap = fragentClass + .getAgentInstrumentation() + .get( "cflpi" ) + .getLineMetrics( jFile.getCanonicalPath() ); + if ( isNull( lineMetricMap ) ) { lineMetricMap = {}; } var noDataForFile = false; // If we don't have any metrics for this file, and we're on Railo or Lucee, attempt to force the file to load. - if( !structCount( lineMetricMap ) ) { + if ( !structCount( lineMetricMap ) ) { // Force the engine to compile and load the file even though it was never run. templateCompiler.compileAndLoad( theFile ); // Check for metrics again - lineMetricMap = fragentClass.getAgentInstrumentation().get("cflpi").getLineMetrics( theFile ); + lineMetricMap = fragentClass + .getAgentInstrumentation() + .get( "cflpi" ) + .getLineMetrics( theFile ); - if( isNull( lineMetricMap ) ) { - lineMetricMap = structNew(); + if ( isNull( lineMetricMap ) ) { + lineMetricMap = structNew(); var noDataForFile = true; } - } - var currentLineNum=0; - var previousLineRan=0; + var currentLineNum = 0; + var previousLineRan = 0; - for( var line in fileLines ) { + for ( var line in fileLines ) { currentLineNum++; - if( structCount( lineMetricMap ) && lineMetricMap.containsKey( javaCast( 'int', currentLineNum ) ) ) { - var lineMetric = lineMetricMap.get( javaCast( 'int', currentLineNum ) ); - var covered = lineMetric.getCount(); + if ( structCount( lineMetricMap ) && lineMetricMap.containsKey( javacast( "int", currentLineNum ) ) ) { + var lineMetric = lineMetricMap.get( javacast( "int", currentLineNum ) ); + var covered = lineMetric.getCount(); // Overrides for buggyiness ************************************************************************ // On Adobe, the first line of CFCs seems to always report as being executable but not running whether it's a comment or a component declaration - if( theFile.right( 4 ) == '.cfc' && currentLineNum == 1 && !covered && line.startsWith( '/' & '*' ) ) { + if ( theFile.right( 4 ) == ".cfc" && currentLineNum == 1 && !covered && line.startsWith( "/" & "*" ) ) { continue; } // On Adobe, the first line of CFCs seems to always report as being executable but not running whether it's a comment or a component declaration - if( theFile.right( 4 ) == '.cfc' && currentLineNum == 1 && !covered && line.startsWith( 'component' ) ) { - covered=1; + if ( + theFile.right( 4 ) == ".cfc" && currentLineNum == 1 && !covered && line.startsWith( + "component" + ) + ) { + covered = 1; } // Ignore any tag based comments. Some are reporting as covered, others aren't. They really all should be ignored. - if( reFindNoCase( '^$', trim( line) ) ) { + if ( reFindNoCase( "^$", trim( line ) ) ) { continue; } // Ignore any CFscript tags. They don't consistently report and they aren't really executable in themselves - if( reFindNoCase( '<(\/)?cfscript>', trim( line) )) { + if ( reFindNoCase( "<(\/)?cfscript>", trim( line ) ) ) { continue; } // Count as covered any closing CF tags where the previous line ran. Ending tags don't always seem to get picked up. - if( !covered && previousLineRan && reFindNoCase( '<\/cf.*>', trim( line) ) ) { + if ( !covered && previousLineRan && reFindNoCase( "<\/cf.*>", trim( line ) ) ) { covered = previousLineRan; } // Count as covered any closing script braces where the previous line ran. E.x, I've seen trailing } in a switch statement not picked up - if( !covered && previousLineRan && trim( line ) == '}' ) { + if ( !covered && previousLineRan && trim( line ) == "}" ) { covered = previousLineRan; } // Count as covered any closing parenthesis where the previous line ran. - if( !covered && previousLineRan && ( trim( line ) == ');' || trim( line ) == ')' ) ) { + if ( !covered && previousLineRan && ( trim( line ) == ");" || trim( line ) == ")" ) ) { covered = previousLineRan; } // Count as covered any cffunction or cfargument tag where the previous line ran. - if( !covered && reFindNoCase( '^ 0 ); } /** - * Match an array of patterns against a single path. Returns true if at least one pattern matches, otherwise false. - * @patterns.hint An array of patterns to match against the path - * @path.hint The file system path to test. Can be a file or directory. Directories MUST end with a trailing slash - */ + * Match an array of patterns against a single path. Returns true if at least one pattern matches, otherwise false. + * @patterns.hint An array of patterns to match against the path + * @path.hint The file system path to test. Can be a file or directory. Directories MUST end with a trailing slash + */ boolean function matchPatterns( required array patterns, required string path ){ - for( var pattern in arguments.patterns ) { - if( matchPattern( pattern, arguments.path ) ) { + for ( var pattern in arguments.patterns ) { + if ( matchPattern( pattern, arguments.path ) ) { return true; } } return false; } -} \ No newline at end of file +} diff --git a/system/coverage/data/TemplateCompiler_Adobe.cfc b/system/coverage/data/TemplateCompiler_Adobe.cfc index c2662744..f02d4f10 100644 --- a/system/coverage/data/TemplateCompiler_Adobe.cfc +++ b/system/coverage/data/TemplateCompiler_Adobe.cfc @@ -1,21 +1,21 @@ /** -* ******************************************************************************** -* Copyright Ortus Solutions, Corp -* www.ortussolutions.com -* ******************************************************************************** -* I contain the logic to force a compilation on Adobe ColdFusion. -*/ + * ******************************************************************************** + * Copyright Ortus Solutions, Corp + * www.ortussolutions.com + * ******************************************************************************** + * I contain the logic to force a compilation on Adobe ColdFusion. + */ component accessors=true { - - function init() { + + function init(){ return this; } - - /** - * Call me to force a .cfm or .cfc to be compiled and the class loaded into memory - */ - function compileAndLoad( required filePath ) { + + /** + * Call me to force a .cfm or .cfc to be compiled and the class loaded into memory + */ + function compileAndLoad( required filePath ){ // I'm so lonely... please implement me! } - -} \ No newline at end of file + +} diff --git a/system/coverage/data/TemplateCompiler_Lucee.cfc b/system/coverage/data/TemplateCompiler_Lucee.cfc index 3b4868f0..e4d427f4 100644 --- a/system/coverage/data/TemplateCompiler_Lucee.cfc +++ b/system/coverage/data/TemplateCompiler_Lucee.cfc @@ -1,155 +1,168 @@ /** -* ******************************************************************************** -* Copyright Ortus Solutions, Corp -* www.ortussolutions.com -* ******************************************************************************** -* I contain the logic to force a compilation on Railo/Lucee. -* I will not compile on Adobe ColdFusion, so I require my own CFC. -*/ + * ******************************************************************************** + * Copyright Ortus Solutions, Corp + * www.ortussolutions.com + * ******************************************************************************** + * I contain the logic to force a compilation on Railo/Lucee. + * I will not compile on Adobe ColdFusion, so I require my own CFC. + */ component accessors=true { - - function init() { + + function init(){ // Create this class for some static helper methods - variables.PageSourceImpl = createObject( 'java', 'lucee.runtime.PageSourceImpl' ); + variables.PageSourceImpl = createObject( "java", "lucee.runtime.PageSourceImpl" ); return this; } - - /** - * Call me to force a .cfm or .cfc to be compiled and the class loaded into memory - */ - function compileAndLoad( required filePath ) { + + /** + * Call me to force a .cfm or .cfc to be compiled and the class loaded into memory + */ + function compileAndLoad( required filePath ){ // Attempt to compile and load the class - PageSourceImpl.best( getPageContext().getPageSources( makePathRelative( arguments.filePath ) ) ).loadPage( getPageContext(), true ); - } - - /** - * Accepts an absolute path and returns a relative path - * Does NOT apply any canonicalization - */ - string function makePathRelative( required string absolutePath ) { - - - // If one of the folders has a period, we've got to do something special. - // C:/users/brad.development/foo.cfc turns into /C__users_brad_development/foo.cfc - if( getDirectoryFromPath( arguments.absolutePath ) contains '.' ) { - var leadingSlash = arguments.absolutePath.startsWith( '/' ); - var UNC = arguments.absolutePath.startsWith( '\\' ); - var mappingPath = getDirectoryFromPath( arguments.absolutePath ); - mappingPath = mappingPath.replace( '\', '/', 'all' ); - mappingPath = mappingPath.listChangeDelims( '/', '/' ); - - var mappingName = mappingPath.replace( ':', '_', 'all' ); - mappingName = mappingName.replace( '.', '_', 'all' ); - mappingName = mappingName.replace( '/', '_', 'all' ); - mappingName = '/' & mappingName; + PageSourceImpl + .best( getPageContext().getPageSources( makePathRelative( arguments.filePath ) ) ) + .loadPage( getPageContext(), true ); + } + + /** + * Accepts an absolute path and returns a relative path + * Does NOT apply any canonicalization + */ + string function makePathRelative( required string absolutePath ){ + // If one of the folders has a period, we've got to do something special. + // C:/users/brad.development/foo.cfc turns into /C__users_brad_development/foo.cfc + if ( getDirectoryFromPath( arguments.absolutePath ) contains "." ) { + var leadingSlash = arguments.absolutePath.startsWith( "/" ); + var UNC = arguments.absolutePath.startsWith( "\\" ); + var mappingPath = getDirectoryFromPath( arguments.absolutePath ); + mappingPath = mappingPath.replace( "\", "/", "all" ); + mappingPath = mappingPath.listChangeDelims( "/", "/" ); + + var mappingName = mappingPath.replace( ":", "_", "all" ); + mappingName = mappingName.replace( ".", "_", "all" ); + mappingName = mappingName.replace( "/", "_", "all" ); + mappingName = "/" & mappingName; // *nix needs this - if( leadingSlash ) { - mappingPath = '/' & mappingPath; + if ( leadingSlash ) { + mappingPath = "/" & mappingPath; } // UNC network paths - if( UNC ) { + if ( UNC ) { var mapping = locateUNCMapping( mappingPath ); - return mapping & '/' & getFileFromPath( arguments.absolutePath ); + return mapping & "/" & getFileFromPath( arguments.absolutePath ); } else { createMapping( mappingName, mappingPath ); - return mappingName & '/' & getFileFromPath( arguments.absolutePath ); + return mappingName & "/" & getFileFromPath( arguments.absolutePath ); } } - - // *nix needs to include first folder due to Lucee bug. - // So /usr/brad/foo.cfc becomes /usr - if( !isWindows() ) { - var firstFolder = listFirst( arguments.absolutePath, '/' ); - var path = listRest( arguments.absolutePath, '/' ); - var mapping = locateUnixDriveMapping( firstFolder ); - return mapping & '/' & path; - } - + + // *nix needs to include first folder due to Lucee bug. + // So /usr/brad/foo.cfc becomes /usr + if ( !isWindows() ) { + var firstFolder = listFirst( arguments.absolutePath, "/" ); + var path = listRest( arguments.absolutePath, "/" ); + var mapping = locateUnixDriveMapping( firstFolder ); + return mapping & "/" & path; + } + // UNC network path. - if( arguments.absolutePath.left( 2 ) == '\\' ) { + if ( arguments.absolutePath.left( 2 ) == "\\" ) { // Strip the \\ arguments.absolutePath = arguments.absolutePath.right( -2 ); - if( arguments.absolutePath.listLen( '/\' ) < 2 ) { - throw( 'Can''t make relative path for [#absolutePath#]. A mapping must point ot a share name, not the root of the server name.' ); + if ( arguments.absolutePath.listLen( "/\" ) < 2 ) { + throw( + "Can't make relative path for [#absolutePath#]. A mapping must point ot a share name, not the root of the server name." + ); } - + // server/share - var UNCShare = listFirst( arguments.absolutePath, '/\' ) & '/' & listGetAt( arguments.absolutePath, 2, '/\' ); - // everything after server/share - var path = arguments.absolutePath.listDeleteAt( 1, '/\' ).listDeleteAt( 1, '/\' ); - var mapping = locateUNCMapping( UNCShare ); - return mapping & '/' & path; - - // Otherwise, do the "normal" way that re-uses top level drive mappings - // C:/users/brad/foo.cfc turns into /C_Drive/users/brad/foo.cfc - } else { - var driveLetter = listFirst( arguments.absolutePath, ':' ); - var path = listRest( arguments.absolutePath, ':' ); - var mapping = locateDriveMapping( driveLetter ); - return mapping & path; - } - } - - /** - * Accepts a Windows drive letter and returns a CF Mapping - * Creates the mapping if it doesn't exist - */ - string function locateDriveMapping( required string driveLetter ) { - var mappingName = '/' & arguments.driveLetter & '_drive'; - var mappingPath = arguments.driveLetter & ':/'; - createMapping( mappingName, mappingPath ); - return mappingName; - } - - /** - * Accepts a Unix root folder and returns a CF Mapping - * Creates the mapping if it doesn't exist - */ - string function locateUnixDriveMapping( required string rootFolder ) { - var mappingName = '/' & arguments.rootFolder & '_root'; - var mappingPath = '/' & arguments.rootFolder & '/'; - createMapping( mappingName, mappingPath ); - return mappingName; - } - - /** - * Accepts a Windows UNC network share and returns a CF Mapping - * Creates the mapping if it doesn't exist - */ - string function locateUNCMapping( required string UNCShare ) { - var mappingName = '/' & arguments.UNCShare.replace( '/', '_' ).replace( '.', '_', 'all' ) & '_UNC'; - var mappingPath = '\\' & arguments.UNCShare & '/'; - createMapping( mappingName, mappingPath ); - return mappingName; - } - - function createMapping( mappingName, mappingPath ) { - var mappings = getApplicationSettings().mappings; - if( !structKeyExists( mappings, mappingName ) || mappings[ mappingName ] != mappingPath ) { - mappings[ mappingName ] = mappingPath; - application action='update' mappings='#mappings#'; - } - } - + var UNCShare = listFirst( arguments.absolutePath, "/\" ) & "/" & listGetAt( + arguments.absolutePath, + 2, + "/\" + ); + // everything after server/share + var path = arguments.absolutePath + .listDeleteAt( 1, "/\" ) + .listDeleteAt( 1, "/\" ); + var mapping = locateUNCMapping( UNCShare ); + return mapping & "/" & path; + + // Otherwise, do the "normal" way that re-uses top level drive mappings + // C:/users/brad/foo.cfc turns into /C_Drive/users/brad/foo.cfc + } else { + var driveLetter = listFirst( arguments.absolutePath, ":" ); + var path = listRest( arguments.absolutePath, ":" ); + var mapping = locateDriveMapping( driveLetter ); + return mapping & path; + } + } + + /** + * Accepts a Windows drive letter and returns a CF Mapping + * Creates the mapping if it doesn't exist + */ + string function locateDriveMapping( required string driveLetter ){ + var mappingName = "/" & arguments.driveLetter & "_drive"; + var mappingPath = arguments.driveLetter & ":/"; + createMapping( mappingName, mappingPath ); + return mappingName; + } + + /** + * Accepts a Unix root folder and returns a CF Mapping + * Creates the mapping if it doesn't exist + */ + string function locateUnixDriveMapping( required string rootFolder ){ + var mappingName = "/" & arguments.rootFolder & "_root"; + var mappingPath = "/" & arguments.rootFolder & "/"; + createMapping( mappingName, mappingPath ); + return mappingName; + } + + /** + * Accepts a Windows UNC network share and returns a CF Mapping + * Creates the mapping if it doesn't exist + */ + string function locateUNCMapping( required string UNCShare ){ + var mappingName = "/" & arguments.UNCShare + .replace( "/", "_" ) + .replace( ".", "_", "all" ) & "_UNC"; + var mappingPath = "\\" & arguments.UNCShare & "/"; + createMapping( mappingName, mappingPath ); + return mappingName; + } + + function createMapping( mappingName, mappingPath ){ + var mappings = getApplicationSettings().mappings; + if ( !structKeyExists( mappings, mappingName ) || mappings[ mappingName ] != mappingPath ) { + mappings[ mappingName ] = mappingPath; + application action ="update" mappings="#mappings#"; + } + } + /* - * Turns all slashes in a path to forward slashes except for \\ in a Windows UNC network share - * Also changes double slashes to a single slash - */ - function normalizeSlashes( string path ) { - if( path.left( 2 ) == '\\' ) { - return '\\' & path.replace( '\', '/', 'all' ).right( -2 ); + * Turns all slashes in a path to forward slashes except for \\ in a Windows UNC network share + * Also changes double slashes to a single slash + */ + function normalizeSlashes( string path ){ + if ( path.left( 2 ) == "\\" ) { + return "\\" & path.replace( "\", "/", "all" ).right( -2 ); } else { - return path.replace( '\', '/', 'all' ).replace( '//', '/', 'all' ); + return path.replace( "\", "/", "all" ).replace( "//", "/", "all" ); } } - - /** - * Detect if OS is Windows - */ + + /** + * Detect if OS is Windows + */ private boolean function isWindows(){ - return createObject( "java", "java.lang.System" ).getProperty( "os.name" ).toLowerCase().contains( "win" ); + return createObject( "java", "java.lang.System" ) + .getProperty( "os.name" ) + .toLowerCase() + .contains( "win" ); } - -} \ No newline at end of file + +} diff --git a/system/coverage/sonarQube/SonarQube.cfc b/system/coverage/sonarQube/SonarQube.cfc index 87268259..bc4ddc19 100644 --- a/system/coverage/sonarQube/SonarQube.cfc +++ b/system/coverage/sonarQube/SonarQube.cfc @@ -1,78 +1,72 @@ /** -* ******************************************************************************** -* Copyright Ortus Solutions, Corp -* www.ortussolutions.com -* ******************************************************************************** -* I turn a query of coverage data into an XML document for import into SonarQube's Generic Code Coverage plugin. -*/ + * ******************************************************************************** + * Copyright Ortus Solutions, Corp + * www.ortussolutions.com + * ******************************************************************************** + * I turn a query of coverage data into an XML document for import into SonarQube's Generic Code Coverage plugin. + */ component accessors=true { - + /** - * If set to true, the XML document will be formatted for human readability - */ + * If set to true, the XML document will be formatted for human readability + */ property name="formatXML" default="false"; - - function init() { - + + function init(){ // This transformation will format an XML document to be indented with line breaks for readability - variables.xlt = ' - - - - '; - + variables.xlt = " + + + + "; + return this; } - + /** - * @qryCoverageData A query object containing coverage data - * @XMLOutputPath Full path to write XML file to - * - * @Returns generated XML string - */ - string function generateXML( - required query qryCoverageData, - string XMLOutputPath='' - ) { - var coverageXML = XMLNew(); - var rootNode = XMLElemNew( coverageXML, 'coverage' ); - rootNode.XMLAttributes[ 'version' ] = 1; - + * @qryCoverageData A query object containing coverage data + * @XMLOutputPath Full path to write XML file to + * + * @Returns generated XML string + */ + string function generateXML( required query qryCoverageData, string XMLOutputPath = "" ){ + var coverageXML = xmlNew(); + var rootNode = xmlElemNew( coverageXML, "coverage" ); + rootNode.XMLAttributes[ "version" ] = 1; + // Loop over each file - for( var row in qryCoverageData ) { - - var fileNode = XMLElemNew( coverageXML, 'file' ); - fileNode.XMLAttributes[ 'path' ] = row.filePath; - - for( var line in row.lineData ) { - var covered = ( row.lineData[ line ] > 0 ? 'true' : 'false' ); - var lineNode = XMLElemNew( coverageXML, 'lineToCover' ); - lineNode.XMLAttributes[ 'lineNumber' ] = line; - lineNode.XMLAttributes[ 'covered' ] = covered; + for ( var row in qryCoverageData ) { + var fileNode = xmlElemNew( coverageXML, "file" ); + fileNode.XMLAttributes[ "path" ] = row.filePath; + + for ( var line in row.lineData ) { + var covered = ( row.lineData[ line ] > 0 ? "true" : "false" ); + var lineNode = xmlElemNew( coverageXML, "lineToCover" ); + lineNode.XMLAttributes[ "lineNumber" ] = line; + lineNode.XMLAttributes[ "covered" ] = covered; fileNode.XMLChildren.append( lineNode ); } rootNode.XMLChildren.append( fileNode ); } - - coverageXML.xmlRoot = rootNode; - //coverageXML.XMLChildren.append( rootNode ); - - if( getFormatXML() ) { + + coverageXML.xmlRoot = rootNode; + // coverageXML.XMLChildren.append( rootNode ); + + if ( getFormatXML() ) { // Clean up formatting on XML doc and convert to string - coverageXML = XmlTransform( coverageXML, variables.xlt ); - } - + coverageXML = xmlTransform( coverageXML, variables.xlt ); + } + // Convert to string - var coverageXMLString = toString( coverageXML ); - + var coverageXMLString = toString( coverageXML ); + // If there is an output path, write it to a file - if( len( XMLOutputPath ) ) { + if ( len( XMLOutputPath ) ) { fileWrite( arguments.XMLOutputPath, coverageXMLString ); } - + // Return the XML string return coverageXMLString; - } - -} \ No newline at end of file + +} diff --git a/system/coverage/stats/CoverageStats.cfc b/system/coverage/stats/CoverageStats.cfc index c5f3330d..b77aa95e 100644 --- a/system/coverage/stats/CoverageStats.cfc +++ b/system/coverage/stats/CoverageStats.cfc @@ -1,81 +1,94 @@ /** -* ******************************************************************************** -* Copyright Ortus Solutions, Corp -* www.ortussolutions.com -* ******************************************************************************** -* I turn a query of coverage data into stats -*/ + * ******************************************************************************** + * Copyright Ortus Solutions, Corp + * www.ortussolutions.com + * ******************************************************************************** + * I turn a query of coverage data into stats + */ component accessors=true { - - - function init() { + + function init(){ return this; } - + /** - * @qryCoverageData A query object containing coverage data - * - * @Returns struct of stats - */ - struct function generateStats( - required query qryCoverageData - ) { + * @qryCoverageData A query object containing coverage data + * + * @Returns struct of stats + */ + struct function generateStats( required query qryCoverageData ){ var stats = { - numFiles=qryCoverageData.recordCount, - percTotalCoverage=0, - totalExecutableLines=0, - totalCoveredLines=0, - qryFilesWorstCoverage='', - qryFilesBestCoverage='' + numFiles : qryCoverageData.recordCount, + percTotalCoverage : 0, + totalExecutableLines : 0, + totalCoveredLines : 0, + qryFilesWorstCoverage : "", + qryFilesBestCoverage : "" }; - + // Remove the lineData column so it doesn't confuse the QofQ engine. - var qryData = queryExecute( ' + var qryData = queryExecute( + " SELECT filePath, relativeFilePath, filePathHash, numLines, numCoveredLines, numExecutableLines, percCoverage FROM qryCoverageData - ', {}, { dbtype='query' } ); - + ", + {}, + { dbtype : "query" } + ); + // Get totals across all files - var qryPerc = queryExecute( ' + var qryPerc = queryExecute( + " SELECT sum( numCoveredLines ) as sumCoveredLines , sum( numExecutableLines ) as sumExecutableLines FROM qryData - ', {}, { dbtype='query' } ); - - if( qryPerc.recordCount ) { + ", + {}, + { dbtype : "query" } + ); + + if ( qryPerc.recordCount ) { stats.totalExecutableLines += qryPerc.sumExecutableLines; stats.totalCoveredLines += qryPerc.sumCoveredLines; } - + // Avoid divide-by-zero errors on the % calculation - if( stats.totalExecutableLines ) { + if ( stats.totalExecutableLines ) { stats.percTotalCoverage = stats.totalCoveredLines / stats.totalExecutableLines; } // Get files with best coverage - var qryBest = queryExecute( ' + var qryBest = queryExecute( + " SELECT * FROM qryData WHERE percCoverage > 0 ORDER BY percCoverage DESC, filePath - ', {}, { dbtype='query', maxRows=10 } ); - + ", + {}, + { dbtype : "query", maxRows : 10 } + ); + stats.qryFilesBestCoverage = qryBest; - var listBestFilePathHashes = "'" & ValueList(qryBest.filePathHash, "','") & "'"; - + var listBestFilePathHashes = "'" & valueList( qryBest.filePathHash, "','" ) & "'"; + // Get files with worst coverage (exclude files already listed under "best" coverage) - var qryWorst = queryExecute( ' + var qryWorst = queryExecute( + " SELECT * FROM qryData - WHERE filePathHash NOT IN ( #PreserveSingleQuotes( listBestFilePathHashes )# ) + WHERE filePathHash NOT IN ( #preserveSingleQuotes( listBestFilePathHashes )# ) AND percCoverage < 1 ORDER BY percCoverage ASC, filePath - ', {}, { dbtype='query', maxRows=10 } ); - + ", + {}, + { dbtype : "query", maxRows : 10 } + ); + stats.qryFilesWorstCoverage = qryWorst; - + return stats; } - -} \ No newline at end of file + +} diff --git a/system/mockutils/MockGenerator.cfc b/system/mockutils/MockGenerator.cfc index 94e10210..6cc3c60a 100644 --- a/system/mockutils/MockGenerator.cfc +++ b/system/mockutils/MockGenerator.cfc @@ -3,126 +3,188 @@ Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp www.ortussolutions.com ******************************************************************************** -Author : Luis Majano -Date : April 20, 2009 +Author : Luis Majano +Date : April 20, 2009 Description : - A mock generator +A mock generator -----------------------------------------------------------------------> - - variables.instance = structnew(); + variables.instance = structNew(); - instance.lb = "#chr(13)##chr(10)#"; - instance.mockBox = arguments.mockBox; - instance.removeStubs = arguments.removeStubs; + instance.lb = "#chr( 13 )##chr( 10 )#"; + instance.mockBox = arguments.mockBox; + instance.removeStubs = arguments.removeStubs; - return this; + return this; - + - - - - - - - - - - - - - + + + + + + + + + + + + + - var udfOut = createObject( "java", "java.lang.StringBuilder" ).init( '' ); - var genPath = expandPath( instance.mockBox.getGenerationPath() ); - var tmpFile = ""; - var fncMD = arguments.metadata; - var isReservedName = false; - var safeMethodName = arguments.method; - var stubCode = ""; - - // Check reserved list and if so, rename it so we can include it, stupid CF - if( structKeyExists( getFunctionList(), arguments.method ) ){ - isReservedName = true; - safeMethodName = "$reserved_#arguments.method#"; - } - - // Create Method Signature - udfOut.append(' - variables[ "#safeMethodName#" ] = variables[ "@@tmpMethodName@@" ]; - this[ "#safeMethodName#" ] = variables[ "@@tmpMethodName@@" ]; + var udfOut = createObject( "java", "java.lang.StringBuilder" ).init( "" ); + var genPath = expandPath( instance.mockBox.getGenerationPath() ); + var tmpFile = ""; + var fncMD = arguments.metadata; + var isReservedName = false; + var safeMethodName = arguments.method; + var stubCode = ""; + + // Check reserved list and if so, rename it so we can include it, stupid CF + if ( structKeyExists( getFunctionList(), arguments.method ) ) { + isReservedName = true; + safeMethodName = "$reserved_#arguments.method#"; + } + + // Create Method Signature + udfOut.append( + " + variables[ ""#safeMethodName#"" ] = variables[ ""@@tmpMethodName@@"" ]; + this[ ""#safeMethodName#"" ] = variables[ ""@@tmpMethodName@@"" ]; // Clean up - structDelete( variables, "@@tmpMethodName@@" ); - structDelete( this, "@@tmpMethodName@@" ); - - #fncMD.access# #fncMD.returntype# function @@tmpMethodName@@( #instance.lb#'); - - // Create Arguments Signature - if( structKeyExists( fncMD, "parameters" ) AND arguments.preserveArguments ){ - for( var x=1; x lte arrayLen( fncMD.parameters ); x++ ){ - var thisParam = fncMD.parameters[ x ]; - udfOut.append(' '); - if( !isNull( thisParam.required ) && thisParam.required ) { - udfOut.append( 'required ' ); - } - if( !isNull( thisParam.type ) && len( thisParam.required ) ) { - udfOut.append( thisParam.type & ' ' ); - } - udfOut.append( thisParam.name & ' ' ); - if( !isNull( thisParam.default ) && thisParam.default != '[runtime expression]' ) { - udfOut.append( '= ' & outputQuotedValue( thisParam.default ) & ' ' ); - } - // Remove these standard keys - structDelete( thisParam, 'required' ); - structDelete( thisParam, 'type' ); - structDelete( thisParam, 'name' ); - structDelete( thisParam, 'default' ); - // Just loop over the rest and output them - for( var thisParamProp in thisParam ) { - udfOut.append( thisParamProp & ' = ' & outputQuotedValue( thisParam[ thisParamProp ] ) & ' ' ); - } - if( x < arrayLen( fncMD.parameters ) ) { - udfOut.append(','); - } - udfOut.append('#instance.lb#'); + structDelete( variables, ""@@tmpMethodName@@"" ); + structDelete( this, ""@@tmpMethodName@@"" ); + + #fncMD.access# #fncMD.returntype# function @@tmpMethodName@@( #instance.lb#" + ); + + // Create Arguments Signature + if ( structKeyExists( fncMD, "parameters" ) AND arguments.preserveArguments ) { + for ( var x = 1; x lte arrayLen( fncMD.parameters ); x++ ) { + var thisParam = fncMD.parameters[ x ]; + udfOut.append( " " ); + if ( !isNull( thisParam.required ) && thisParam.required ) { + udfOut.append( "required " ); + } + if ( !isNull( thisParam.type ) && len( thisParam.required ) ) { + udfOut.append( thisParam.type & " " ); + } + udfOut.append( thisParam.name & " " ); + if ( !isNull( thisParam.default ) && thisParam.default != "[runtime expression]" ) { + udfOut.append( "= " & outputQuotedValue( thisParam.default ) & " " ); + } + // Remove these standard keys + structDelete( thisParam, "required" ); + structDelete( thisParam, "type" ); + structDelete( thisParam, "name" ); + structDelete( thisParam, "default" ); + // Just loop over the rest and output them + for ( var thisParamProp in thisParam ) { + udfOut.append( thisParamProp & " = " & outputQuotedValue( thisParam[ thisParamProp ] ) & " " ); } + if ( x < arrayLen( fncMD.parameters ) ) { + udfOut.append( "," ); + } + udfOut.append( "#instance.lb#" ); } - - udfOut.append(' - ) output=#fncMD.output# {#instance.lb# '); - - // Continue Method Generation - udfOut.append(' - var results = this._mockResults; - var resultsKey = "#arguments.method#"; - var resultsCounter = 0; + } + + udfOut.append( + " + ) output=#fncMD.output# {#instance.lb# " + ); + + // Continue Method Generation + udfOut.append( + " + var results = this._mockResults; + var resultsKey = ""#arguments.method#""; + var resultsCounter = 0; var internalCounter = 0; - var resultsLen = 0; - var callbackLen = 0; - var argsHashKey = resultsKey & "|" & this.mockBox.normalizeArguments( arguments ); - var fCallBack = ""; + var resultsLen = 0; + var callbackLen = 0; + var argsHashKey = resultsKey & ""|"" & this.mockBox.normalizeArguments( arguments ); + var fCallBack = """"; // If Method & argument Hash Results, switch the results struct if( structKeyExists( this._mockArgResults, argsHashKey ) ) { // Check if it is a callback if( isStruct( this._mockArgResults[ argsHashKey ] ) && - structKeyExists( this._mockArgResults[ argsHashKey ], "type" ) && - structKeyExists( this._mockArgResults[ argsHashKey ], "target" ) ) { + structKeyExists( this._mockArgResults[ argsHashKey ], ""type"" ) && + structKeyExists( this._mockArgResults[ argsHashKey ], ""target"" ) ) { fCallBack = this._mockArgResults[ argsHashKey ].target; } else { // switch context and key - results = this._mockArgResults; + results = this._mockArgResults; resultsKey = argsHashKey; } } @@ -138,28 +200,32 @@ Description : } // Log the Method Call - this._mockMethodCallCounters[ listFirst( resultsKey, "|" ) ] = this._mockMethodCallCounters[ listFirst( resultsKey, "|" ) ] + 1; + this._mockMethodCallCounters[ listFirst( resultsKey, ""|"" ) ] = this._mockMethodCallCounters[ listFirst( resultsKey, ""|"" ) ] + 1; // Get the CallCounter Reference - internalCounter = this._mockMethodCallCounters[listFirst(resultsKey,"|")]; - '); - - // Call Logging argument or Global Flag - if( arguments.callLogging OR arguments.targetObject._mockCallLoggingActive ){ - udfOut.append('arrayAppend(this._mockCallLoggers["#arguments.method#"], arguments);#instance.lb#'); - } - - // Exceptions? To Throw - if( arguments.throwException ){ - udfOut.append(' - - throw( #outputQuotedValue( arguments.throwMessage )#, #outputQuotedValue( arguments.throwType )#, #outputQuotedValue( arguments.throwDetail )#, #outputQuotedValue( arguments.throwErrorCode )# );#instance.lb#'); - } - - // Returns Something according to metadata? - if ( fncMD["returntype"] neq "void" ){ - /* Results Recycling Code, basically, state machine code */ - udfOut.append(' + internalCounter = this._mockMethodCallCounters[listFirst(resultsKey,""|"")]; + " + ); + + // Call Logging argument or Global Flag + if ( arguments.callLogging OR arguments.targetObject._mockCallLoggingActive ) { + udfOut.append( "arrayAppend(this._mockCallLoggers[""#arguments.method#""], arguments);#instance.lb#" ); + } + + // Exceptions? To Throw + if ( arguments.throwException ) { + udfOut.append( + " + + throw( #outputQuotedValue( arguments.throwMessage )#, #outputQuotedValue( arguments.throwType )#, #outputQuotedValue( arguments.throwDetail )#, #outputQuotedValue( arguments.throwErrorCode )# );#instance.lb#" + ); + } + + // Returns Something according to metadata? + if ( fncMD[ "returntype" ] neq "void" ) { + /* Results Recycling Code, basically, state machine code */ + udfOut.append( + " if( resultsLen neq 0 ) { if( internalCounter gt resultsLen ) { resultsCounter = internalCounter - ( resultsLen*fix( (internalCounter-1)/resultsLen ) ); @@ -168,78 +234,92 @@ Description : return results[resultsKey][internalCounter]; } } - '); - // Callback Single - udfOut.append(' + " + ); + // Callback Single + udfOut.append( + " if( callbackLen neq 0 ) { fCallBack = this._mockCallbacks[ resultsKey ][ 1 ]; return fCallBack( argumentCollection = arguments ); } - '); - // Callback Args - udfOut.append(' + " + ); + // Callback Args + udfOut.append( + " if( not isSimpleValue( fCallBack ) ){ return fCallBack( argumentCollection = arguments ); } - '); + " + ); + } + udfOut.append( "}#instance.lb#" ); + udfOut.append( "" ); + + // Write it out + stubCode = trim( udfOUt.toString() ); + tmpFile = hash( stubCode ) & ".cfm"; + + // This is necessary for methods named after CF keywords like "contains" + var tmpMethodName = "tmp_#arguments.method#_" & hash( stubCode ); + stubCode = replaceNoCase( + stubCode, + "@@tmpMethodName@@", + tmpMethodName, + "all" + ); + + if ( !fileExists( genPath & tmpFile ) ) { + writeStub( genPath & tmpFile, stubCode ); + } + + // Mix In Stub + try { + // include it + arguments.targetObject.$include = variables.$include; + arguments.targetObject.$include( instance.mockBox.getGenerationPath() & tmpFile ); + structDelete( arguments.targetObject, "$include" ); + + // reserved rename to original + if ( isReservedName ) { + arguments.targetObject[ arguments.method ] = arguments.targetObject[ safeMethodName ]; } - udfOut.append('}#instance.lb#'); - udfOut.append(''); - - // Write it out - stubCode = trim( udfOUt.toString() ); - tmpFile = hash( stubCode ) & ".cfm"; - - // This is necessary for methods named after CF keywords like "contains" - var tmpMethodName = 'tmp_#arguments.method#_' & hash( stubCode ); - stubCode = replaceNoCase( stubCode, '@@tmpMethodName@@', tmpMethodName, 'all' ); - - if( !FileExists( genPath & tmpFile ) ) { - writeStub( genPath & tmpFile, stubCode ); - } - - // Mix In Stub - try{ - // include it - arguments.targetObject.$include = variables.$include; - arguments.targetObject.$include( instance.mockBox.getGenerationPath() & tmpFile ); - structDelete( arguments.targetObject, "$include" ); - - // reserved rename to original - if( isReservedName ){ - arguments.targetObject[ arguments.method ] = arguments.targetObject[ safeMethodName ]; - } - // Remove Stub - removeStub( genPath & tmpFile ); - } - catch(Any e){ - // Remove Stub - removeStub( genPath & tmpFile); - rethrow; - } + // Remove Stub + removeStub( genPath & tmpFile ); + } catch ( Any e ) { + // Remove Stub + removeStub( genPath & tmpFile ); + rethrow; + } - + - - + + - - + - + @@ -248,126 +328,147 @@ Description : - - - + + + - var udfOut = createObject("java","java.lang.StringBuilder").init(''); - var genPath = expandPath( instance.mockBox.getGenerationPath() ); - var tmpFile = ""; - var cfcPath = ""; - var oStub = ""; - var local = {}; - var stubCode = ""; - - // Create CFC Signature - udfOut.append('#instance.lb#'); - - // iterate over implementations - for( local.x=1; local.x lte listLen( arguments.implements ); local.x++ ){ - // generate interface methods - generateMethodsFromMD( udfOut, getComponentMetadata( listGetAt( arguments.implements, x) ) ); - } - - // close it - udfOut.append(''); - - // Write it out - stubCode = udfOUt.toString(); - tmpFile = hash(stubCode) & ".cfc"; - if( !FileExists(genPath & tmpFile) ) { - writeStub(genPath & tmpFile, stubCode); - } - - try{ - // create stub + clean first . if found. - cfcPath = replace( instance.mockBox.getGenerationPath(), "/", ".", "all" ) & listFirst( tmpFile, "." ); - cfcPath = reReplace( cfcPath, "^\.", "" ); - oStub = createObject( "component", cfcPath ); - // Remove Stub - removeStub(genPath & tmpFile); - // Return it - return oStub; - } - catch(Any e){ - // Remove Stub - removeStub( genPath & tmpFile ); - rethrow; - } + var udfOut = createObject( "java", "java.lang.StringBuilder" ).init( "" ); + var genPath = expandPath( instance.mockBox.getGenerationPath() ); + var tmpFile = ""; + var cfcPath = ""; + var oStub = ""; + var local = {}; + var stubCode = ""; + + // Create CFC Signature + udfOut.append( "#instance.lb#" ); + + // iterate over implementations + for ( local.x = 1; local.x lte listLen( arguments.implements ); local.x++ ) { + // generate interface methods + generateMethodsFromMD( udfOut, getComponentMetadata( listGetAt( arguments.implements, x ) ) ); + } + + // close it + udfOut.append( "" ); + + // Write it out + stubCode = udfOUt.toString(); + tmpFile = hash( stubCode ) & ".cfc"; + if ( !fileExists( genPath & tmpFile ) ) { + writeStub( genPath & tmpFile, stubCode ); + } + + try { + // create stub + clean first . if found. + cfcPath = replace( + instance.mockBox.getGenerationPath(), + "/", + ".", + "all" + ) & listFirst( tmpFile, "." ); + cfcPath = reReplace( cfcPath, "^\.", "" ); + oStub = createObject( "component", cfcPath ); + // Remove Stub + removeStub( genPath & tmpFile ); + // Return it + return oStub; + } catch ( Any e ) { + // Remove Stub + removeStub( genPath & tmpFile ); + rethrow; + } - - - + + + - var local = {}; - var udfOut = arguments.buffer; - - // local functions if they exist - local.oMD = []; - if( structKeyExists( arguments.md, "functions" ) ){ - local.oMD = arguments.md.functions; - } - - // iterate and create functions - for( local.x = 1; local.x lte arrayLen( local.oMD ); local.x++ ){ - // start function tag - udfOut.append('#instance.lb#'); - - // Do parameters if they exist - for( local.y=1; local.y lte arrayLen( local.oMD[ x ].parameters ); local.y++ ){ - // start argument - udfOut.append('#instance.lb#'); + } + // close function start tag + udfOut.append( ">#instance.lb#" ); + + // Do parameters if they exist + for ( local.y = 1; local.y lte arrayLen( local.oMD[ x ].parameters ); local.y++ ) { + // start argument + udfOut.append( "#instance.lb#"); + // close argument + udfOut.append( ">#instance.lb#" ); } - // Check extends and recurse - if( structKeyExists( arguments.md, "extends") ){ - for( var thisKey in arguments.md.extends ){ - generateMethodsFromMD( udfOut, arguments.md.extends[ thisKey ] ); - } + // close full function + udfOut.append( "#instance.lb#" ); + } + + // Check extends and recurse + if ( structKeyExists( arguments.md, "extends" ) ) { + for ( var thisKey in arguments.md.extends ) { + generateMethodsFromMD( udfOut, arguments.md.extends[ thisKey ] ); } + } - + - diff --git a/system/mockutils/Stub.cfc b/system/mockutils/Stub.cfc index 35bd36f7..0d660418 100644 --- a/system/mockutils/Stub.cfc +++ b/system/mockutils/Stub.cfc @@ -3,8 +3,8 @@ Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp www.ortussolutions.com ******************************************************************************** -Author : Luis Majano +Author : Luis Majano Description : A stub object ----------------------------------------------------------------------> - \ No newline at end of file + diff --git a/system/reports/ANTJUnitReporter.cfc b/system/reports/ANTJUnitReporter.cfc index 66447794..aa7ad805 100644 --- a/system/reports/ANTJUnitReporter.cfc +++ b/system/reports/ANTJUnitReporter.cfc @@ -1,32 +1,34 @@ /** -* Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp -* www.ortussolutions.com -* --- -* A JUnit reporter for use with the ANT junitreport task, which uses an old version of JUnit formatting. -*/ -component extends="BaseReporter"{ - - function init(){ return this; } + * Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + * A JUnit reporter for use with the ANT junitreport task, which uses an old version of JUnit formatting. + */ +component extends="BaseReporter" { + + function init(){ + return this; + } /** - * Get the name of the reporter - */ + * Get the name of the reporter + */ function getName(){ return "ANTJUnit"; } /** - * Do the reporting thing here using the incoming test results - * The report should return back in whatever format they desire and should set any - * Specifc browser types if needed. - * @results.hint The instance of the TestBox TestResult object to build a report on - * @testbox.hint The TestBox core object - * @options.hint A structure of options this reporter needs to build the report with - */ + * Do the reporting thing here using the incoming test results + * The report should return back in whatever format they desire and should set any + * Specifc browser types if needed. + * @results.hint The instance of the TestBox TestResult object to build a report on + * @testbox.hint The TestBox core object + * @options.hint A structure of options this reporter needs to build the report with + */ any function runReport( required testbox.system.TestResult results, required testbox.system.TestBox testbox, - struct options={} + struct options = {} ){ getPageContextResponse().setContentType( "application/xml" ); @@ -34,43 +36,55 @@ component extends="BaseReporter"{ } private function toJUnit( required results ){ - var buffer = createObject("java", "java.lang.StringBuilder").init(''); - var r = arguments.results; + var buffer = createObject( "java", "java.lang.StringBuilder" ).init( "" ); + var r = arguments.results; // build top level test suites container - buffer.append(''); + buffer.append( "" ); // iterate over bundles var bundlestats = r.getBundleStats(); - for( var thisBundle in bundleStats ){ + for ( var thisBundle in bundleStats ) { // excluding "empty" test suites - if (structKeyExists(url, 'testBundles') AND len( url.testBundles ) and !listFindNoCase( url.testBundles, thisBundle.path )){ + if ( + structKeyExists( url, "testBundles" ) AND len( url.testBundles ) and !listFindNoCase( + url.testBundles, + thisBundle.path + ) + ) { continue; } // build test suite header - buffer.append(''); + buffer.append( + "" + ); // build out properties buildProperties( buffer ); // build out tests, even if nested, treat as single threaded - buildTestSuites( buffer, r, thisBundle, thisBundle.suiteStats ); + buildTestSuites( + buffer, + r, + thisBundle, + thisBundle.suiteStats + ); // close header - buffer.append(""); + buffer.append( "" ); } - buffer.append(''); + buffer.append( "" ); return buffer.toString(); } @@ -80,101 +94,130 @@ component extends="BaseReporter"{ required results, required bundleStats, required suiteStats, - parentName="" + parentName = "" ){ - - var r = arguments.results; - var out = arguments.buffer; - var stats = arguments.suiteStats; - var index = 1; + var r = arguments.results; + var out = arguments.buffer; + var stats = arguments.suiteStats; + var index = 1; // iterate over - for( var thisSuite in arguments.suiteStats ){ + for ( var thisSuite in arguments.suiteStats ) { // build out full suite name var fullName = xmlFormat( arguments.parentName & thisSuite.name ); // build out test cases - for( var thisSpecStat in thisSuite.specStats ){ - buildTestCase( out, r, thisSpecStat, arguments.bundleStats, fullName ); + for ( var thisSpecStat in thisSuite.specStats ) { + buildTestCase( + out, + r, + thisSpecStat, + arguments.bundleStats, + fullName + ); } // Check embedded suites - if( arrayLen( thisSuite.suiteStats ) ){ - buildTestSuites( out, r, arguments.bundlestats, thisSuite.suiteStats, xmlFormat( fullName & " " ) ); + if ( arrayLen( thisSuite.suiteStats ) ) { + buildTestSuites( + out, + r, + arguments.bundlestats, + thisSuite.suiteStats, + xmlFormat( fullName & " " ) + ); } } - } - private function buildTestCase( required buffer, required results, required specStats, required bundleStats, required fullName ){ - var r = arguments.results; - var out = arguments.buffer; - var stats = arguments.specStats; + private function buildTestCase( + required buffer, + required results, + required specStats, + required bundleStats, + required fullName + ){ + var r = arguments.results; + var out = arguments.buffer; + var stats = arguments.specStats; // build test case - out.append(''); - - switch( stats.status ){ - case "failed" : { - out.append('" + ); + + switch ( stats.status ) { + case "failed": { + out.append( + "'); + ]]>" + ); break; } - case "skipped" : { - out.append(''); + case "skipped": { + out.append( "" ); break; } - case "error" : { - out.append(''); + ]]>" + ); break; } } - out.append(''); + out.append( "" ); } private function buildProperties( required buffer ){ - var out = arguments.buffer; + var out = arguments.buffer; - out.append(""); + out.append( "" ); genPropsFromCollection( out, server.coldfusion ); genPropsFromCollection( out, server.os ); - if( structKeyExists( server, "lucee" ) ){ + if ( structKeyExists( server, "lucee" ) ) { genPropsFromCollection( out, server.lucee ); } genPropsFromCollection( out, cgi ); - out.append(""); + out.append( "" ); } - private function genPropsFromCollection(required buffer, required collection ){ - for( var thisProp in arguments.collection ){ - //null check - if( isNull( arguments.collection[ thisProp ] ) ){ + private function genPropsFromCollection( required buffer, required collection ){ + for ( var thisProp in arguments.collection ) { + // null check + if ( isNull( arguments.collection[ thisProp ] ) ) { continue; } - if( isSimpleValue( arguments.collection[ thisProp ] ) ){ - // This is for a nasty Lucee regression where server.os.MacAddress is null, yet isNull() checks say it isn't. + if ( isSimpleValue( arguments.collection[ thisProp ] ) ) { + // This is for a nasty Lucee regression where server.os.MacAddress is null, yet isNull() checks say it isn't. // Try/catch is the only way to detect this right now :/ // Regression known to exist in Lucee 5.2.8.50 try { - arguments.buffer.append( '' ); - } catch( any e ) { - arguments.buffer.append( '' ); + arguments.buffer.append( + "" + ); + } catch ( any e ) { + arguments.buffer.append( + "" + ); } - } - else if( isArray( arguments.collection[ thisProp ] ) OR - isStruct( arguments.collection[ thisProp ] ) OR - isQuery( arguments.collection[ thisProp ] ) ){ - arguments.buffer.append( '' ); + } else if ( + isArray( arguments.collection[ thisProp ] ) OR + isStruct( arguments.collection[ thisProp ] ) OR + isQuery( arguments.collection[ thisProp ] ) + ) { + arguments.buffer.append( + "" + ); } } } diff --git a/system/reports/BaseReporter.cfc b/system/reports/BaseReporter.cfc index 81668e99..3085ddfd 100644 --- a/system/reports/BaseReporter.cfc +++ b/system/reports/BaseReporter.cfc @@ -1,20 +1,20 @@ /** -* Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp -* www.ortussolutions.com -* --- -* A Base reporter class -*/ -component{ + * Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + * A Base reporter class + */ +component { /** * Helper method to deal with ACF2016's overload of the page context response, come on Adobe, get your act together! */ function getPageContextResponse(){ - if ( structKeyExists( server, "lucee" ) ) { - return getPageContext().getResponse(); - } else { - return getPageContext().getResponse().getResponse(); - } + if ( structKeyExists( server, "lucee" ) ) { + return getPageContext().getResponse(); + } else { + return getPageContext().getResponse().getResponse(); + } } /** @@ -22,12 +22,12 @@ component{ */ function resetHTMLResponse(){ // reset cfhtmlhead from integration tests - if( structKeyExists( server, "lucee" ) ){ - try{ + if ( structKeyExists( server, "lucee" ) ) { + try { getPageContext().getOut().resetHTMLHead(); - }catch( any e ){ + } catch ( any e ) { // don't care, that lucee version doesn't support it. - writedump( var="resetHTMLHead() not supported #e.message#", output="console" ); + writeDump( var = "resetHTMLHead() not supported #e.message#", output = "console" ); } } // reset cfheader from integration tests diff --git a/system/reports/CodexWikiReporter.cfc b/system/reports/CodexWikiReporter.cfc index 5bf107ce..226a71fd 100644 --- a/system/reports/CodexWikiReporter.cfc +++ b/system/reports/CodexWikiReporter.cfc @@ -1,58 +1,70 @@ /** -* Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp -* www.ortussolutions.com -* --- -* A simple Documentation style reporter -*/ -component extends="BaseReporter"{ - - function init(){ - return this; + * Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + * A simple Documentation style reporter + */ +component extends="BaseReporter" { + + function init(){ + return this; } /** - * Get the name of the reporter - */ + * Get the name of the reporter + */ function getName(){ return "CodexWiki"; } /** - * Do the reporting thing here using the incoming test results - * The report should return back in whatever format they desire and should set any - * Specifc browser types if needed. - * @results.hint The instance of the TestBox TestResult object to build a report on - * @testbox.hint The TestBox core object - * @options.hint A structure of options this reporter needs to build the report with - */ - any function runReport( + * Do the reporting thing here using the incoming test results + * The report should return back in whatever format they desire and should set any + * Specifc browser types if needed. + * @results.hint The instance of the TestBox TestResult object to build a report on + * @testbox.hint The TestBox core object + * @options.hint A structure of options this reporter needs to build the report with + */ + any function runReport( required testbox.system.TestResult results, required testbox.system.TestBox testbox, - struct options={} + struct options = {} ){ // content type getPageContextResponse().setContentType( "text/text" ); - + // bundle stats variables.bundleStats = arguments.results.getBundleStats(); - + // prepare base links variables.baseURL = "?"; - if( structKeyExists( url, "method") ){ variables.baseURL &= "method=#URLEncodedFormat( url.method )#"; } - if( structKeyExists( url, "output") ){ variables.baseURL &= "output=#URLEncodedFormat( url.output )#"; } + if ( structKeyExists( url, "method" ) ) { + variables.baseURL &= "method=#urlEncodedFormat( url.method )#"; + } + if ( structKeyExists( url, "output" ) ) { + variables.baseURL &= "output=#urlEncodedFormat( url.output )#"; + } // prepare incoming params - if( !structKeyExists( url, "testMethod") ){ url.testMethod = ""; } - if( !structKeyExists( url, "testSpecs") ){ url.testSpecs = ""; } - if( !structKeyExists( url, "testSuites") ){ url.testSuites = ""; } - if( !structKeyExists( url, "testBundles") ){ url.testBundles = ""; } + if ( !structKeyExists( url, "testMethod" ) ) { + url.testMethod = ""; + } + if ( !structKeyExists( url, "testSpecs" ) ) { + url.testSpecs = ""; + } + if ( !structKeyExists( url, "testSuites" ) ) { + url.testSuites = ""; + } + if ( !structKeyExists( url, "testBundles" ) ) { + url.testBundles = ""; + } // prepare the report - savecontent variable="local.report"{ + savecontent variable="local.report" { include "assets/codexwiki.cfm"; } - + return local.report; } - -} \ No newline at end of file + +} diff --git a/system/reports/ConsoleReporter.cfc b/system/reports/ConsoleReporter.cfc index e8115950..76f508e6 100644 --- a/system/reports/ConsoleReporter.cfc +++ b/system/reports/ConsoleReporter.cfc @@ -1,43 +1,43 @@ /** -* Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp -* www.ortussolutions.com -* --- -* A text reporter -*/ -component extends="BaseReporter"{ + * Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + * A text reporter + */ +component extends="BaseReporter" { - function init(){ - variables.out = createObject("Java", "java.lang.System").out; - return this; + function init(){ + variables.out = createObject( "Java", "java.lang.System" ).out; + return this; } /** - * Get the name of the reporter - */ + * Get the name of the reporter + */ function getName(){ return "Console"; } /** - * Do the reporting thing here using the incoming test results - * The report should return back in whatever format they desire and should set any - * Specific browser types if needed. - * @results.hint The instance of the TestBox TestResult object to build a report on - * @testbox.hint The TestBox core object - * @options.hint A structure of options this reporter needs to build the report with - */ - any function runReport( + * Do the reporting thing here using the incoming test results + * The report should return back in whatever format they desire and should set any + * Specific browser types if needed. + * @results.hint The instance of the TestBox TestResult object to build a report on + * @testbox.hint The TestBox core object + * @options.hint A structure of options this reporter needs to build the report with + */ + any function runReport( required testbox.system.TestResult results, required testbox.system.TestBox testbox, - struct options={} + struct options = {} ){ // content type getPageContextResponse().setContentType( "text/plain" ); // bundle stats variables.bundleStats = arguments.results.getBundleStats(); - + // prepare the report - savecontent variable="local.report"{ + savecontent variable="local.report" { include "assets/text.cfm"; } @@ -46,5 +46,5 @@ component extends="BaseReporter"{ return "Report Sent To Console"; } - -} \ No newline at end of file + +} diff --git a/system/reports/DocReporter.cfc b/system/reports/DocReporter.cfc index 27ab98f8..066c816e 100644 --- a/system/reports/DocReporter.cfc +++ b/system/reports/DocReporter.cfc @@ -1,34 +1,34 @@ /** -* Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp -* www.ortussolutions.com -* --- -* A simple Documentation style reporter -*/ -component extends="BaseReporter"{ + * Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + * A simple Documentation style reporter + */ +component extends="BaseReporter" { function init(){ return this; } /** - * Get the name of the reporter - */ + * Get the name of the reporter + */ function getName(){ return "Doc"; } /** - * Do the reporting thing here using the incoming test results - * The report should return back in whatever format they desire and should set any - * Specific browser types if needed. - * @results.hint The instance of the TestBox TestResult object to build a report on - * @testbox.hint The TestBox core object - * @options.hint A structure of options this reporter needs to build the report with - */ + * Do the reporting thing here using the incoming test results + * The report should return back in whatever format they desire and should set any + * Specific browser types if needed. + * @results.hint The instance of the TestBox TestResult object to build a report on + * @testbox.hint The TestBox core object + * @options.hint A structure of options this reporter needs to build the report with + */ any function runReport( required testbox.system.TestResult results, required testbox.system.TestBox testbox, - struct options={} + struct options = {} ){ // content type getPageContextResponse().setContentType( "text/html" ); @@ -38,20 +38,32 @@ component extends="BaseReporter"{ // prepare base links variables.baseURL = "?"; - if( structKeyExists( url, "method") ){ variables.baseURL &= "method=#URLEncodedFormat( url.method )#"; } - if( structKeyExists( url, "output") ){ variables.baseURL &= "output=#URLEncodedFormat( url.output )#"; } + if ( structKeyExists( url, "method" ) ) { + variables.baseURL &= "method=#urlEncodedFormat( url.method )#"; + } + if ( structKeyExists( url, "output" ) ) { + variables.baseURL &= "output=#urlEncodedFormat( url.output )#"; + } // prepare incoming params - if( !structKeyExists( url, "testMethod") ){ url.testMethod = ""; } - if( !structKeyExists( url, "testSpecs") ){ url.testSpecs = ""; } - if( !structKeyExists( url, "testSuites") ){ url.testSuites = ""; } - if( !structKeyExists( url, "testBundles") ){ url.testBundles = ""; } + if ( !structKeyExists( url, "testMethod" ) ) { + url.testMethod = ""; + } + if ( !structKeyExists( url, "testSpecs" ) ) { + url.testSpecs = ""; + } + if ( !structKeyExists( url, "testSuites" ) ) { + url.testSuites = ""; + } + if ( !structKeyExists( url, "testBundles" ) ) { + url.testBundles = ""; + } // prepare the report - savecontent variable="local.report"{ + savecontent variable="local.report" { include "assets/doc.cfm"; } return local.report; } -} \ No newline at end of file +} diff --git a/system/reports/DotReporter.cfc b/system/reports/DotReporter.cfc index 817ccc1f..071c5fc7 100644 --- a/system/reports/DotReporter.cfc +++ b/system/reports/DotReporter.cfc @@ -1,55 +1,67 @@ /** -* Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp -* www.ortussolutions.com -* --- -* A dot matrix reporter -*/ -component extends="BaseReporter"{ + * Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + * A dot matrix reporter + */ +component extends="BaseReporter" { function init(){ return this; } /** - * Get the name of the reporter - */ + * Get the name of the reporter + */ function getName(){ return "Dot"; } /** - * Do the reporting thing here using the incoming test results - * The report should return back in whatever format they desire and should set any - * Specific browser types if needed. - * @results.hint The instance of the TestBox TestResult object to build a report on - * @testbox.hint The TestBox core object - * @options.hint A structure of options this reporter needs to build the report with - */ + * Do the reporting thing here using the incoming test results + * The report should return back in whatever format they desire and should set any + * Specific browser types if needed. + * @results.hint The instance of the TestBox TestResult object to build a report on + * @testbox.hint The TestBox core object + * @options.hint A structure of options this reporter needs to build the report with + */ any function runReport( required testbox.system.TestResult results, required testbox.system.TestBox testbox, - struct options={} + struct options = {} ){ // bundle stats variables.bundleStats = arguments.results.getBundleStats(); // prepare base links variables.baseURL = "?"; - if( structKeyExists( url, "method") ){ variables.baseURL &= "method=#URLEncodedFormat( url.method )#"; } - if( structKeyExists( url, "output") ){ variables.baseURL &= "output=#URLEncodedFormat( url.output )#"; } + if ( structKeyExists( url, "method" ) ) { + variables.baseURL &= "method=#urlEncodedFormat( url.method )#"; + } + if ( structKeyExists( url, "output" ) ) { + variables.baseURL &= "output=#urlEncodedFormat( url.output )#"; + } // prepare incoming params - if( !structKeyExists( url, "testMethod") ){ url.testMethod = ""; } - if( !structKeyExists( url, "testSpecs") ){ url.testSpecs = ""; } - if( !structKeyExists( url, "testSuites") ){ url.testSuites = ""; } - if( !structKeyExists( url, "testBundles") ){ url.testBundles = ""; } + if ( !structKeyExists( url, "testMethod" ) ) { + url.testMethod = ""; + } + if ( !structKeyExists( url, "testSpecs" ) ) { + url.testSpecs = ""; + } + if ( !structKeyExists( url, "testSuites" ) ) { + url.testSuites = ""; + } + if ( !structKeyExists( url, "testBundles" ) ) { + url.testBundles = ""; + } // prepare the report - savecontent variable="local.report"{ + savecontent variable="local.report" { include "assets/dot.cfm"; } return local.report; } -} \ No newline at end of file +} diff --git a/system/reports/IReporter.cfc b/system/reports/IReporter.cfc index 3ac2bbbc..44699a70 100644 --- a/system/reports/IReporter.cfc +++ b/system/reports/IReporter.cfc @@ -1,27 +1,28 @@ /** -* Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp -* www.ortussolutions.com -* --- -* The TestBox main reporting interface for producing awesome testing reports -*/ -interface{ + * Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + * The TestBox main reporting interface for producing awesome testing reports + */ +interface { /** - * Get the name of the reporter - */ + * Get the name of the reporter + */ function getName(); /** - * Do the reporting thing here using the incoming test results - * The report should return back in whatever format they desire and should set any - * Specific browser types if needed. - * @results.hint The instance of the TestBox TestResult object to build a report on - * @testbox.hint The TestBox core object - * @options.hint A structure of options this reporter needs to build the report with - */ - any function runReport( + * Do the reporting thing here using the incoming test results + * The report should return back in whatever format they desire and should set any + * Specific browser types if needed. + * @results.hint The instance of the TestBox TestResult object to build a report on + * @testbox.hint The TestBox core object + * @options.hint A structure of options this reporter needs to build the report with + */ + any function runReport( required testbox.system.TestResult results, required testbox.system.TestBox testbox, - struct options={} ); - -} \ No newline at end of file + struct options = {} + ); + +} diff --git a/system/reports/JSONReporter.cfc b/system/reports/JSONReporter.cfc index 090b0246..620a5d53 100644 --- a/system/reports/JSONReporter.cfc +++ b/system/reports/JSONReporter.cfc @@ -1,36 +1,38 @@ /** -* Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp -* www.ortussolutions.com -* --- -* A JSON reporter -*/ -component extends="BaseReporter"{ + * Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + * A JSON reporter + */ +component extends="BaseReporter" { - function init(){ return this; } + function init(){ + return this; + } /** - * Get the name of the reporter - */ + * Get the name of the reporter + */ function getName(){ return "JSON"; } /** - * Do the reporting thing here using the incoming test results - * The report should return back in whatever format they desire and should set any - * Specific browser types if needed. - * @results.hint The instance of the TestBox TestResult object to build a report on - * @testbox.hint The TestBox core object - * @options.hint A structure of options this reporter needs to build the report with - */ - any function runReport( + * Do the reporting thing here using the incoming test results + * The report should return back in whatever format they desire and should set any + * Specific browser types if needed. + * @results.hint The instance of the TestBox TestResult object to build a report on + * @testbox.hint The TestBox core object + * @options.hint A structure of options this reporter needs to build the report with + */ + any function runReport( required testbox.system.TestResult results, required testbox.system.TestBox testbox, - struct options={} + struct options = {} ){ resetHTMLResponse(); getPageContextResponse().setContentType( "application/json" ); return serializeJSON( arguments.results.getMemento() ); } - -} \ No newline at end of file + +} diff --git a/system/reports/JUnitReporter.cfc b/system/reports/JUnitReporter.cfc index b721cf54..e008fa27 100644 --- a/system/reports/JUnitReporter.cfc +++ b/system/reports/JUnitReporter.cfc @@ -1,32 +1,34 @@ /** -* Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp -* www.ortussolutions.com -* --- -* A JUnit reporter -*/ -component extends="BaseReporter"{ - - function init(){ return this; } + * Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + * A JUnit reporter + */ +component extends="BaseReporter" { + + function init(){ + return this; + } /** - * Get the name of the reporter - */ + * Get the name of the reporter + */ function getName(){ return "JUnit"; } /** - * Do the reporting thing here using the incoming test results - * The report should return back in whatever format they desire and should set any - * Specific browser types if needed. - * @results.hint The instance of the TestBox TestResult object to build a report on - * @testbox.hint The TestBox core object - * @options.hint A structure of options this reporter needs to build the report with - */ + * Do the reporting thing here using the incoming test results + * The report should return back in whatever format they desire and should set any + * Specific browser types if needed. + * @results.hint The instance of the TestBox TestResult object to build a report on + * @testbox.hint The TestBox core object + * @options.hint A structure of options this reporter needs to build the report with + */ any function runReport( required testbox.system.TestResult results, required testbox.system.TestBox testbox, - struct options={} + struct options = {} ){ resetHTMLResponse(); getPageContextResponse().setContentType( "application/xml" ); @@ -35,27 +37,36 @@ component extends="BaseReporter"{ } private function toJUnit( required results ){ - var buffer = createObject("java", "java.lang.StringBuilder").init(''); + var buffer = createObject( "java", "java.lang.StringBuilder" ).init( + "" + ); var r = arguments.results; // build top level test suites container - buffer.append(''); + buffer.append( + "" + ); // iterate over bundles var bundlestats = r.getBundleStats(); - for( var thisBundle in bundleStats ){ - buildTestSuites( buffer, r, thisBundle, thisBundle.suiteStats ); + for ( var thisBundle in bundleStats ) { + buildTestSuites( + buffer, + r, + thisBundle, + thisBundle.suiteStats + ); } - buffer.append(""); + buffer.append( "" ); return buffer.toString(); } @@ -65,115 +76,152 @@ component extends="BaseReporter"{ required results, required bundleStats, required suiteStats, - parentName="" + parentName = "" ){ - - var r = arguments.results; - var out = arguments.buffer; - var stats = arguments.suiteStats; + var r = arguments.results; + var out = arguments.buffer; + var stats = arguments.suiteStats; // iterate over - for( var thisSuite in arguments.suiteStats ){ + for ( var thisSuite in arguments.suiteStats ) { // build out full suite name var fullName = xmlFormat( arguments.parentName & thisSuite.name ); // build test suite header - out.append(''); + out.append( + "" + ); // build out properties - buildProperties( out, r, thisSuite, arguments.bundleStats ); + buildProperties( + out, + r, + thisSuite, + arguments.bundleStats + ); // build out test cases - for( var thisSpecStat in thisSuite.specStats ){ - buildTestCase( out, r, thisSpecStat, arguments.bundleStats ); + for ( var thisSpecStat in thisSuite.specStats ) { + buildTestCase( + out, + r, + thisSpecStat, + arguments.bundleStats + ); } // close header - out.append(""); + out.append( "" ); // Check embedded suites - if( arrayLen( thisSuite.suiteStats ) ){ - buildTestSuites( out, r, arguments.bundlestats, thisSuite.suiteStats, xmlFormat( fullName & "##" ) ); + if ( arrayLen( thisSuite.suiteStats ) ) { + buildTestSuites( + out, + r, + arguments.bundlestats, + thisSuite.suiteStats, + xmlFormat( fullName & "##" ) + ); } } - } - private function buildTestCase( required buffer, required results, required specStats, required bundleStats ){ - var r = arguments.results; - var out = arguments.buffer; - var stats = arguments.specStats; + private function buildTestCase( + required buffer, + required results, + required specStats, + required bundleStats + ){ + var r = arguments.results; + var out = arguments.buffer; + var stats = arguments.specStats; // build test case - out.append(''); - - switch( stats.status ){ - case "failed" : { - out.append('" + ); + + switch ( stats.status ) { + case "failed": { + out.append( + "'); + ]]>" + ); break; } - case "skipped" : { - out.append(''); + case "skipped": { + out.append( "" ); break; } - case "error" : { - out.append(''); + ]]>" + ); break; } } - out.append(''); + out.append( "" ); } - private function buildProperties( required buffer, required results, required bundleStats, required suiteStats ){ - var r = arguments.results; - var out = arguments.buffer; - var stats = arguments.suiteStats; + private function buildProperties( + required buffer, + required results, + required bundleStats, + required suiteStats + ){ + var r = arguments.results; + var out = arguments.buffer; + var stats = arguments.suiteStats; - out.append(""); + out.append( "" ); genPropsFromCollection( out, server.coldfusion ); genPropsFromCollection( out, server.os ); - if( structKeyExists( server, "lucee" ) ){ + if ( structKeyExists( server, "lucee" ) ) { genPropsFromCollection( out, server.lucee ); } genPropsFromCollection( out, cgi ); - out.append(""); + out.append( "" ); } - private function genPropsFromCollection(required buffer, required collection ){ - for( var thisProp in arguments.collection ){ - //null check - if( isNull( arguments.collection[ thisProp ] ) ){ + private function genPropsFromCollection( required buffer, required collection ){ + for ( var thisProp in arguments.collection ) { + // null check + if ( isNull( arguments.collection[ thisProp ] ) ) { continue; } - if( isSimpleValue( arguments.collection[ thisProp ] ) ){ - arguments.buffer.append( '' ); - } - else if( isArray( arguments.collection[ thisProp ] ) OR - isStruct( arguments.collection[ thisProp ] ) OR - isQuery( arguments.collection[ thisProp ] ) ){ - arguments.buffer.append( '' ); + if ( isSimpleValue( arguments.collection[ thisProp ] ) ) { + arguments.buffer.append( + "" + ); + } else if ( + isArray( arguments.collection[ thisProp ] ) OR + isStruct( arguments.collection[ thisProp ] ) OR + isQuery( arguments.collection[ thisProp ] ) + ) { + arguments.buffer.append( + "" + ); } } } -} \ No newline at end of file +} diff --git a/system/reports/MinReporter.cfc b/system/reports/MinReporter.cfc index 661d638d..91fba3c3 100644 --- a/system/reports/MinReporter.cfc +++ b/system/reports/MinReporter.cfc @@ -1,58 +1,70 @@ /** -* Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp -* www.ortussolutions.com -* --- -* A minimalistic reporter -*/ -component extends="BaseReporter"{ - - function init(){ - return this; + * Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + * A minimalistic reporter + */ +component extends="BaseReporter" { + + function init(){ + return this; } /** - * Get the name of the reporter - */ + * Get the name of the reporter + */ function getName(){ return "Min"; } /** - * Do the reporting thing here using the incoming test results - * The report should return back in whatever format they desire and should set any - * Specific browser types if needed. - * @results.hint The instance of the TestBox TestResult object to build a report on - * @testbox.hint The TestBox core object - * @options.hint A structure of options this reporter needs to build the report with - */ - any function runReport( + * Do the reporting thing here using the incoming test results + * The report should return back in whatever format they desire and should set any + * Specific browser types if needed. + * @results.hint The instance of the TestBox TestResult object to build a report on + * @testbox.hint The TestBox core object + * @options.hint A structure of options this reporter needs to build the report with + */ + any function runReport( required testbox.system.TestResult results, required testbox.system.TestBox testbox, - struct options={} + struct options = {} ){ // content type getPageContextResponse().setContentType( "text/html" ); - + // bundle stats variables.bundleStats = arguments.results.getBundleStats(); - + // prepare base links variables.baseURL = "?"; - if( structKeyExists( url, "method") ){ variables.baseURL &= "method=#URLEncodedFormat( url.method )#"; } - if( structKeyExists( url, "output") ){ variables.baseURL &= "output=#URLEncodedFormat( url.output )#"; } + if ( structKeyExists( url, "method" ) ) { + variables.baseURL &= "method=#urlEncodedFormat( url.method )#"; + } + if ( structKeyExists( url, "output" ) ) { + variables.baseURL &= "output=#urlEncodedFormat( url.output )#"; + } // prepare incoming params - if( !structKeyExists( url, "testMethod") ){ url.testMethod = ""; } - if( !structKeyExists( url, "testSpecs") ){ url.testSpecs = ""; } - if( !structKeyExists( url, "testSuites") ){ url.testSuites = ""; } - if( !structKeyExists( url, "testBundles") ){ url.testBundles = ""; } + if ( !structKeyExists( url, "testMethod" ) ) { + url.testMethod = ""; + } + if ( !structKeyExists( url, "testSpecs" ) ) { + url.testSpecs = ""; + } + if ( !structKeyExists( url, "testSuites" ) ) { + url.testSuites = ""; + } + if ( !structKeyExists( url, "testBundles" ) ) { + url.testBundles = ""; + } // prepare the report - savecontent variable="local.report"{ + savecontent variable="local.report" { include "assets/min.cfm"; } - + return local.report; } - -} \ No newline at end of file + +} diff --git a/system/reports/MinTextReporter.cfc b/system/reports/MinTextReporter.cfc index 5fe2d0b7..346a414c 100644 --- a/system/reports/MinTextReporter.cfc +++ b/system/reports/MinTextReporter.cfc @@ -1,47 +1,52 @@ /** -* Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp -* www.ortussolutions.com -* --- -* A minimalistic reporter -*/ -component extends="BaseReporter"{ + * Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + * A minimalistic reporter + */ +component extends="BaseReporter" { - function init(){ - return this; + function init(){ + return this; } /** - * Get the name of the reporter - */ + * Get the name of the reporter + */ function getName(){ return "MinText"; } /** - * Do the reporting thing here using the incoming test results - * The report should return back in whatever format they desire and should set any - * Specific browser types if needed. - * @results.hint The instance of the TestBox TestResult object to build a report on - * @testbox.hint The TestBox core object - * @options.hint A structure of options this reporter needs to build the report with - */ - any function runReport( + * Do the reporting thing here using the incoming test results + * The report should return back in whatever format they desire and should set any + * Specific browser types if needed. + * @results.hint The instance of the TestBox TestResult object to build a report on + * @testbox.hint The TestBox core object + * @options.hint A structure of options this reporter needs to build the report with + */ + any function runReport( required testbox.system.TestResult results, required testbox.system.TestBox testbox, - struct options={} + struct options = {} ){ // content type getPageContextResponse().setContentType( "text/plain" ); - + // bundle stats variables.bundleStats = arguments.results.getBundleStats(); - + // prepare the report - savecontent variable="local.report"{ + savecontent variable="local.report" { include "assets/mintext.cfm"; } - - return reReplace( local.report, '[\r\n]+', chr(10), 'all' ); + + return reReplace( + local.report, + "[\r\n]+", + chr( 10 ), + "all" + ); } - -} \ No newline at end of file + +} diff --git a/system/reports/RawReporter.cfc b/system/reports/RawReporter.cfc index dc8430b8..33652f6b 100644 --- a/system/reports/RawReporter.cfc +++ b/system/reports/RawReporter.cfc @@ -1,34 +1,36 @@ /** -* Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp -* www.ortussolutions.com -* --- -* A raw reporter -*/ -component extends="BaseReporter"{ + * Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + * A raw reporter + */ +component extends="BaseReporter" { - function init(){ return this; } + function init(){ + return this; + } /** - * Get the name of the reporter - */ + * Get the name of the reporter + */ function getName(){ return "Raw"; } /** - * Do the reporting thing here using the incoming test results - * The report should return back in whatever format they desire and should set any - * Specific browser types if needed. - * @results.hint The instance of the TestBox TestResult object to build a report on - * @testbox.hint The TestBox core object - * @options.hint A structure of options this reporter needs to build the report with - */ - any function runReport( + * Do the reporting thing here using the incoming test results + * The report should return back in whatever format they desire and should set any + * Specific browser types if needed. + * @results.hint The instance of the TestBox TestResult object to build a report on + * @testbox.hint The TestBox core object + * @options.hint A structure of options this reporter needs to build the report with + */ + any function runReport( required testbox.system.TestResult results, required testbox.system.TestBox testbox, - struct options={} + struct options = {} ){ return arguments.results.getMemento(); } - -} \ No newline at end of file + +} diff --git a/system/reports/SimpleReporter.cfc b/system/reports/SimpleReporter.cfc index de1de438..c2e06ba3 100644 --- a/system/reports/SimpleReporter.cfc +++ b/system/reports/SimpleReporter.cfc @@ -1,34 +1,34 @@ /** -* Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp -* www.ortussolutions.com -* --- -* A simple HTML reporter -*/ -component extends="BaseReporter"{ + * Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + * A simple HTML reporter + */ +component extends="BaseReporter" { function init(){ return this; } /** - * Get the name of the reporter - */ + * Get the name of the reporter + */ function getName(){ return "Simple"; } /** - * Do the reporting thing here using the incoming test results - * The report should return back in whatever format they desire and should set any - * Specific browser types if needed. - * @results.hint The instance of the TestBox TestResult object to build a report on - * @testbox.hint The TestBox core object - * @options.hint A structure of options this reporter needs to build the report with - */ + * Do the reporting thing here using the incoming test results + * The report should return back in whatever format they desire and should set any + * Specific browser types if needed. + * @results.hint The instance of the TestBox TestResult object to build a report on + * @testbox.hint The TestBox core object + * @options.hint A structure of options this reporter needs to build the report with + */ any function runReport( required testbox.system.TestResult results, required testbox.system.TestBox testbox, - struct options={} + struct options = {} ){ // content type getPageContextResponse().setContentType( "text/html" ); @@ -38,18 +38,32 @@ component extends="BaseReporter"{ // prepare base links variables.baseURL = "?"; - if( structKeyExists( url, "method" ) ){ variables.baseURL&= "method=#URLEncodedFormat( url.method )#"; } - if( structKeyExists( url, "output" ) ){ variables.baseURL&= "output=#URLEncodedFormat( url.output )#"; } + if ( structKeyExists( url, "method" ) ) { + variables.baseURL &= "method=#urlEncodedFormat( url.method )#"; + } + if ( structKeyExists( url, "output" ) ) { + variables.baseURL &= "output=#urlEncodedFormat( url.output )#"; + } // prepare incoming params - if( !structKeyExists( url, "testMethod") ){ url.testMethod = ""; } - if( !structKeyExists( url, "testSpecs") ){ url.testSpecs = ""; } - if( !structKeyExists( url, "testSuites") ){ url.testSuites = ""; } - if( !structKeyExists( url, "testBundles") ){ url.testBundles = ""; } - if( !structKeyExists( url, "directory") ){ url.directory = ""; } + if ( !structKeyExists( url, "testMethod" ) ) { + url.testMethod = ""; + } + if ( !structKeyExists( url, "testSpecs" ) ) { + url.testSpecs = ""; + } + if ( !structKeyExists( url, "testSuites" ) ) { + url.testSuites = ""; + } + if ( !structKeyExists( url, "testBundles" ) ) { + url.testBundles = ""; + } + if ( !structKeyExists( url, "directory" ) ) { + url.directory = ""; + } // prepare the report - savecontent variable="local.report"{ + savecontent variable="local.report" { include "assets/simple.cfm"; } diff --git a/system/reports/TapReporter.cfc b/system/reports/TapReporter.cfc index 06b6a369..a9a3f3dd 100644 --- a/system/reports/TapReporter.cfc +++ b/system/reports/TapReporter.cfc @@ -1,34 +1,34 @@ /** -* Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp -* www.ortussolutions.com -* --- -* A tap reporter https://testanything.org/ -*/ -component extends="BaseReporter"{ + * Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + * A tap reporter https://testanything.org/ + */ +component extends="BaseReporter" { function init(){ return this; } /** - * Get the name of the reporter - */ + * Get the name of the reporter + */ function getName(){ return "Tap"; } /** - * Do the reporting thing here using the incoming test results - * The report should return back in whatever format they desire and should set any - * Specific browser types if needed. - * @results.hint The instance of the TestBox TestResult object to build a report on - * @testbox.hint The TestBox core object - * @options.hint A structure of options this reporter needs to build the report with - */ + * Do the reporting thing here using the incoming test results + * The report should return back in whatever format they desire and should set any + * Specific browser types if needed. + * @results.hint The instance of the TestBox TestResult object to build a report on + * @testbox.hint The TestBox core object + * @options.hint A structure of options this reporter needs to build the report with + */ any function runReport( required testbox.system.TestResult results, required testbox.system.TestBox testbox, - struct options={} + struct options = {} ){ // content type getPageContextResponse().setContentType( "text/plain" ); @@ -36,11 +36,11 @@ component extends="BaseReporter"{ variables.bundleStats = arguments.results.getBundleStats(); // prepare the report - savecontent variable="local.report"{ + savecontent variable="local.report" { include "assets/tap.cfm"; } return local.report; } -} \ No newline at end of file +} diff --git a/system/reports/TextReporter.cfc b/system/reports/TextReporter.cfc index 593c6bb0..d33634b5 100644 --- a/system/reports/TextReporter.cfc +++ b/system/reports/TextReporter.cfc @@ -1,34 +1,34 @@ /** -* Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp -* www.ortussolutions.com -* --- -* A text reporter -*/ -component extends="BaseReporter"{ + * Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + * A text reporter + */ +component extends="BaseReporter" { function init(){ return this; } /** - * Get the name of the reporter - */ + * Get the name of the reporter + */ function getName(){ return "Text"; } /** - * Do the reporting thing here using the incoming test results - * The report should return back in whatever format they desire and should set any - * Specific browser types if needed. - * @results.hint The instance of the TestBox TestResult object to build a report on - * @testbox.hint The TestBox core object - * @options.hint A structure of options this reporter needs to build the report with - */ + * Do the reporting thing here using the incoming test results + * The report should return back in whatever format they desire and should set any + * Specific browser types if needed. + * @results.hint The instance of the TestBox TestResult object to build a report on + * @testbox.hint The TestBox core object + * @options.hint A structure of options this reporter needs to build the report with + */ any function runReport( required testbox.system.TestResult results, required testbox.system.TestBox testbox, - struct options={} + struct options = {} ){ // content type getPageContextResponse().setContentType( "text/plain" ); @@ -36,11 +36,16 @@ component extends="BaseReporter"{ variables.bundleStats = arguments.results.getBundleStats(); // prepare the report - savecontent variable="local.report"{ + savecontent variable="local.report" { include "assets/text.cfm"; } - return reReplace( trim( local.report ), '[\r\n]+', chr(10), 'all' ); + return reReplace( + trim( local.report ), + "[\r\n]+", + chr( 10 ), + "all" + ); } -} \ No newline at end of file +} diff --git a/system/reports/XMLReporter.cfc b/system/reports/XMLReporter.cfc index e37283e4..f09569b2 100644 --- a/system/reports/XMLReporter.cfc +++ b/system/reports/XMLReporter.cfc @@ -1,39 +1,39 @@ /** -* Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp -* www.ortussolutions.com -* --- -* An XML reporter -*/ -component extends="BaseReporter"{ + * Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + * An XML reporter + */ +component extends="BaseReporter" { - function init(){ + function init(){ variables.converter = new testbox.system.util.XMLConverter(); - return this; + return this; } /** - * Get the name of the reporter - */ + * Get the name of the reporter + */ function getName(){ return "XML"; } /** - * Do the reporting thing here using the incoming test results - * The report should return back in whatever format they desire and should set any - * Specific browser types if needed. - * @results.hint The instance of the TestBox TestResult object to build a report on - * @testbox.hint The TestBox core object - * @options.hint A structure of options this reporter needs to build the report with - */ - any function runReport( + * Do the reporting thing here using the incoming test results + * The report should return back in whatever format they desire and should set any + * Specific browser types if needed. + * @results.hint The instance of the TestBox TestResult object to build a report on + * @testbox.hint The TestBox core object + * @options.hint A structure of options this reporter needs to build the report with + */ + any function runReport( required testbox.system.TestResult results, required testbox.system.TestBox testbox, - struct options={} + struct options = {} ){ resetHTMLResponse(); getPageContextResponse().setContentType( "application/xml" ); - return variables.converter.toXML( data=arguments.results.getMemento(), rootName="TestBox" ); + return variables.converter.toXML( data = arguments.results.getMemento(), rootName = "TestBox" ); } - -} \ No newline at end of file + +} diff --git a/system/runners/BDDRunner.cfc b/system/runners/BDDRunner.cfc index 8c32b808..9f9651b4 100644 --- a/system/runners/BDDRunner.cfc +++ b/system/runners/BDDRunner.cfc @@ -4,7 +4,11 @@ * --- * This TestBox runner is used to run and report on BDD style test suites. */ -component extends="testbox.system.runners.BaseRunner" implements="testbox.system.runners.IRunner" accessors="true"{ +component + extends ="testbox.system.runners.BaseRunner" + implements="testbox.system.runners.IRunner" + accessors ="true" +{ // runner options property name="options"; @@ -18,7 +22,6 @@ component extends="testbox.system.runners.BaseRunner" implements="testbox.system * @testbox The TestBox class reference */ function init( required struct options, required testBox ){ - variables.options = arguments.options; variables.testbox = arguments.testbox; @@ -37,83 +40,96 @@ component extends="testbox.system.runners.BaseRunner" implements="testbox.system required callbacks ){ // Get target metadata - var targetMD = getMetadata( arguments.target ); - var bundleName = ( structKeyExists( targetMD, "displayName" ) ? targetMD.displayname : targetMD.name ); + var targetMD = getMetadata( arguments.target ); + var bundleName = ( structKeyExists( targetMD, "displayName" ) ? targetMD.displayname : targetMD.name ); // Execute the suite descriptors - arguments.target.run( testResults=arguments.testResults, testbox=variables.testbox ); + arguments.target.run( testResults = arguments.testResults, testbox = variables.testbox ); // Discover the test suite data to use for testing - var testSuites = getTestSuites( arguments.target, targetMD ); + var testSuites = getTestSuites( arguments.target, targetMD ); var testSuitesCount = arrayLen( testSuites ); // Start recording stats for this bundle - var bundleStats = arguments.testResults.startBundleStats( bundlePath=targetMD.name, name=bundleName ); + var bundleStats = arguments.testResults.startBundleStats( + bundlePath = targetMD.name, + name = bundleName + ); // Verify we can run this bundle - if( canRunBundle( bundlePath=targetMD.name, testResults=arguments.testResults, targetMD=targetMD ) ){ - - try{ + if ( + canRunBundle( + bundlePath = targetMD.name, + testResults = arguments.testResults, + targetMD = targetMD + ) + ) { + try { // execute beforeAll() for this bundle, no matter how many suites they have. - if( structKeyExists( arguments.target, "beforeAll" ) ){ + if ( structKeyExists( arguments.target, "beforeAll" ) ) { arguments.target.beforeAll(); } // find any methods annotated 'beforeAll' and execute them - var beforeAllAnnotationMethods = variables.testbox.getUtility().getAnnotatedMethods( - annotation = "beforeAll", - metadata = getMetadata( arguments.target ) - ); + var beforeAllAnnotationMethods = variables.testbox + .getUtility() + .getAnnotatedMethods( annotation = "beforeAll", metadata = getMetadata( arguments.target ) ); - for ( var beforeAllMethod in beforeAllAnnotationMethods ){ + for ( var beforeAllMethod in beforeAllAnnotationMethods ) { invoke( arguments.target, "#beforeAllMethod.name#" ); } // Iterate over found test suites and test them, if nested suites, then this will recurse as well. - for( var thisSuite in testSuites ){ + for ( var thisSuite in testSuites ) { // verify call backs - if( structKeyExists( arguments.callbacks, "onSuiteStart" ) ){ - arguments.callbacks.onSuiteStart( arguments.target, arguments.testResults, thisSuite ); + if ( structKeyExists( arguments.callbacks, "onSuiteStart" ) ) { + arguments.callbacks.onSuiteStart( + arguments.target, + arguments.testResults, + thisSuite + ); } // Test Suite testSuite( - target=arguments.target, - suite=thisSuite, - testResults=arguments.testResults, - bundleStats=bundleStats, - callbacks=arguments.callbacks + target = arguments.target, + suite = thisSuite, + testResults = arguments.testResults, + bundleStats = bundleStats, + callbacks = arguments.callbacks ); // verify call backs - if( structKeyExists( arguments.callbacks, "onSuiteEnd" ) ){ - arguments.callbacks.onSuiteEnd( arguments.target, arguments.testResults, thisSuite ); + if ( structKeyExists( arguments.callbacks, "onSuiteEnd" ) ) { + arguments.callbacks.onSuiteEnd( + arguments.target, + arguments.testResults, + thisSuite + ); } } // execute afterAll() for this bundle, no matter how many suites they have. - if( structKeyExists( arguments.target, "afterAll" ) ){ + if ( structKeyExists( arguments.target, "afterAll" ) ) { arguments.target.afterAll(); } // find any methods annotated 'afterAll' and execute them - var afterAllAnnotationMethods = variables.testbox.getUtility().getAnnotatedMethods( - annotation = "afterAll", - metadata = getMetadata( arguments.target ) - ); + var afterAllAnnotationMethods = variables.testbox + .getUtility() + .getAnnotatedMethods( annotation = "afterAll", metadata = getMetadata( arguments.target ) ); - for ( var afterAllMethod in afterAllAnnotationMethods ){ + for ( var afterAllMethod in afterAllAnnotationMethods ) { invoke( arguments.target, "#afterAllMethod.name#" ); } - - } catch( Any e ) { + } catch ( Any e ) { bundleStats.globalException = e; // For a righteous man falls seven times, and rises (tests) again :) // The amount doesn't matter, nothing can run at this point, failure with before/after aspects that need fixing - bundleStats.totalError = 7; - arguments.testResults.incrementStat( type="error", count=bundleStats.totalError ); + bundleStats.totalError = 7; + arguments.testResults.incrementStat( type = "error", count = bundleStats.totalError ); } - - } // end if we can run bundle + } + // end if we can run bundle // finalize the bundle stats arguments.testResults.endStats( bundleStats ); @@ -124,29 +140,33 @@ component extends="testbox.system.runners.BaseRunner" implements="testbox.system /************************************** TESTING METHODS *********************************************/ /** - * Test the incoming suite definition - * @target The target bundle CFC - * @method The method definition to test - * @testResults The testing results object - * @bundleStats The bundle stats this suite belongs to - * @parentStats If this is a nested test suite, then it will have some parentStats goodness - * @callbacks The CFC or struct of callback listener methods - */ + * Test the incoming suite definition + * @target The target bundle CFC + * @method The method definition to test + * @testResults The testing results object + * @bundleStats The bundle stats this suite belongs to + * @parentStats If this is a nested test suite, then it will have some parentStats goodness + * @callbacks The CFC or struct of callback listener methods + */ private function testSuite( required target, required suite, required testResults, required bundleStats, - required parentStats={}, - required callbacks={} + required parentStats = {}, + required callbacks = {} ){ // Start suite stats - var suiteStats = arguments.testResults.startSuiteStats( arguments.suite.name, arguments.bundleStats, arguments.parentStats ); + var suiteStats = arguments.testResults.startSuiteStats( + arguments.suite.name, + arguments.bundleStats, + arguments.parentStats + ); // init consolidated spec labels var consolidatedLabels = []; // Build labels from nested suites, so suites inherit from parent suite labels - var parentSuite = arguments.suite; - while( !isSimpleValue( parentSuite ) ){ + var parentSuite = arguments.suite; + while ( !isSimpleValue( parentSuite ) ) { consolidatedLabels.addAll( parentSuite.labels ); parentSuite = parentSuite.parentref; } @@ -156,126 +176,158 @@ component extends="testbox.system.runners.BaseRunner" implements="testbox.system arguments.bundleStats.totalSpecs += suiteStats.totalSpecs; arguments.bundleStats.totalSuites++; // increment global suites + specs - arguments.testResults.incrementSuites().incrementSpecs( suiteStats.totalSpecs ); + arguments.testResults + .incrementSuites() + .incrementSpecs( suiteStats.totalSpecs ); // Verify we can execute the incoming suite via skipping or labels - if( !arguments.suite.skip && - canRunSuite( arguments.suite, arguments.testResults, arguments.target ) - ){ - + if ( + !arguments.suite.skip && + canRunSuite( + arguments.suite, + arguments.testResults, + arguments.target + ) + ) { // prepare threaded names - var threadNames = []; + var threadNames = []; // threaded variables just in case some suite is async and another is not. - thread.testResults = arguments.testResults; - thread.suiteStats = suiteStats; - thread.target = arguments.target; + thread.testResults = arguments.testResults; + thread.suiteStats = suiteStats; + thread.target = arguments.target; // iterate over suite specs and test them - for( var thisSpec in arguments.suite.specs ){ - + for ( var thisSpec in arguments.suite.specs ) { // is this async or not? - if( arguments.suite.asyncAll ){ + if ( arguments.suite.asyncAll ) { // prepare thread name - var thisThreadName = variables.testBox.getUtility().slugify( "tb-" & thisSpec.name & "-#hash( getTickCount() + randRange( 1, 10000000 ) )#" ); + var thisThreadName = variables.testBox + .getUtility() + .slugify( "tb-" & thisSpec.name & "-#hash( getTickCount() + randRange( 1, 10000000 ) )#" ); // append to used thread names arrayAppend( threadNames, thisThreadName ); // thread it - thread name="#thisThreadName#" - thisSpec="#thisSpec#" - suite="#arguments.suite#" - threadName="#thisThreadName#" - callbacks="#arguments.callbacks#"{ - + thread + name ="#thisThreadName#" + thisSpec ="#thisSpec#" + suite ="#arguments.suite#" + threadName="#thisThreadName#" + callbacks ="#arguments.callbacks#" { // verify call backs - if( structKeyExists( attributes.callbacks, "onSpecStart" ) ){ - attributes.callbacks.onSpecStart( thread.target, thread.testResults, attributes.suite, attributes.thisSpec ); + if ( structKeyExists( attributes.callbacks, "onSpecStart" ) ) { + attributes.callbacks.onSpecStart( + thread.target, + thread.testResults, + attributes.suite, + attributes.thisSpec + ); } // execute the test within the context of the spec target due to lucee closure bug, move back once it is resolved. thread.target.runSpec( - spec=attributes.thisSpec, - suite=attributes.suite, - testResults=thread.testResults, - suiteStats=thread.suiteStats, - runner=this + spec = attributes.thisSpec, + suite = attributes.suite, + testResults = thread.testResults, + suiteStats = thread.suiteStats, + runner = this ); // verify call backs - if( structKeyExists( attributes.callbacks, "onSpecEnd" ) ){ - attributes.callbacks.onSpecEnd( thread.target, thread.testResults, attributes.suite, attributes.thisSpec ); + if ( structKeyExists( attributes.callbacks, "onSpecEnd" ) ) { + attributes.callbacks.onSpecEnd( + thread.target, + thread.testResults, + attributes.suite, + attributes.thisSpec + ); } } - } else { // verify call backs - if( structKeyExists( arguments.callbacks, "onSpecStart" ) ){ - arguments.callbacks.onSpecStart( arguments.target, arguments.testResults, arguments.suite, thisSpec ); + if ( structKeyExists( arguments.callbacks, "onSpecStart" ) ) { + arguments.callbacks.onSpecStart( + arguments.target, + arguments.testResults, + arguments.suite, + thisSpec + ); } // execute the test within the context of the spec target due to lucee closure bug, move back once it is resolved. thread.target.runSpec( - spec=thisSpec, - suite=arguments.suite, - testResults=thread.testResults, - suiteStats=thread.suiteStats, - runner=this + spec = thisSpec, + suite = arguments.suite, + testResults = thread.testResults, + suiteStats = thread.suiteStats, + runner = this ); // verify call backs - if( structKeyExists( arguments.callbacks, "onSpecEnd" ) ){ - arguments.callbacks.onSpecEnd( arguments.target, arguments.testResults, arguments.suite, thisSpec ); + if ( structKeyExists( arguments.callbacks, "onSpecEnd" ) ) { + arguments.callbacks.onSpecEnd( + arguments.target, + arguments.testResults, + arguments.suite, + thisSpec + ); } } - } // end loop over specs + } + // end loop over specs // join threads if async - if( arguments.suite.asyncAll ){ thread action="join" name="#arrayToList( threadNames )#"{}; } + if ( arguments.suite.asyncAll ) { + thread action="join" name="#arrayToList( threadNames )#" { + }; + } // Do we have any internal suites? If we do, test them recursively, go down the rabbit hole - for( var thisInternalSuite in arguments.suite.suites ){ - + for ( var thisInternalSuite in arguments.suite.suites ) { // run the suite specs recursively var nestedStats = testSuite( - target=arguments.target, - suite=thisInternalSuite, - testResults=arguments.testResults, - bundleStats=arguments.bundleStats, - parentStats=suiteStats, - callbacks=arguments.callbacks + target = arguments.target, + suite = thisInternalSuite, + testResults = arguments.testResults, + bundleStats = arguments.bundleStats, + parentStats = suiteStats, + callbacks = arguments.callbacks ); // Add in nested stats to parent suite // These numbers will aggregate as we unroll the recursive calls - suiteStats.totalError = suiteStats.totalError + nestedStats.totalError; - suiteStats.totalFail = suiteStats.totalFail + nestedStats.totalFail; + suiteStats.totalError = suiteStats.totalError + nestedStats.totalError; + suiteStats.totalFail = suiteStats.totalFail + nestedStats.totalFail; suiteStats.totalSkipped = suiteStats.totalSkipped + nestedStats.totalSkipped; - suiteStats.totalPass = suiteStats.totalPass + nestedStats.totalPass; - + suiteStats.totalPass = suiteStats.totalPass + nestedStats.totalPass; } // All specs finalized, set suite status according to spec data - if( suiteStats.totalError GT 0 ){ suiteStats.status = "Error"; } - else if( suiteStats.totalFail GT 0 ){ suiteStats.status = "Failed"; } - else{ suiteStats.status = "Passed"; } + if ( suiteStats.totalError GT 0 ) { + suiteStats.status = "Error"; + } else if ( suiteStats.totalFail GT 0 ) { + suiteStats.status = "Failed"; + } else { + suiteStats.status = "Passed"; + } // Suite Skipped Status? - if( suiteStats.totalSpecs neq 0 && suiteStats.totalSpecs == suiteStats.totalSkipped ){ + if ( suiteStats.totalSpecs neq 0 && suiteStats.totalSpecs == suiteStats.totalSkipped ) { var suiteSkipped = true; // iterate over nested suites to discover if indeed skipped - for( var thisSuiteStat in suiteStats.suiteStats ){ + for ( var thisSuiteStat in suiteStats.suiteStats ) { // if not skipped, then short circuit it as not skipped - if( thisSuiteStat.status neq "Skipped" ){ + if ( thisSuiteStat.status neq "Skipped" ) { suiteSkipped = false; break; } } // mark suite skipped if indeed it was skipped. - if( suiteSkipped ){ suiteStats.status = "Skipped"; } + if ( suiteSkipped ) { + suiteStats.status = "Skipped"; + } } - - } - else{ + } else { // Record skipped stats and status suiteStats.status = "Skipped"; arguments.bundleStats.totalSkipped += suiteStats.totalSpecs; @@ -291,14 +343,11 @@ component extends="testbox.system.runners.BaseRunner" implements="testbox.system /************************************** DISCOVERY METHODS *********************************************/ /** - * Get all the test suites in the passed in bundle - * @target The target to get the suites from - * @targetMD The metdata of the target - */ - private array function getTestSuites( - required target, - required targetMD - ){ + * Get all the test suites in the passed in bundle + * @target The target to get the suites from + * @targetMD The metdata of the target + */ + private array function getTestSuites( required target, required targetMD ){ // get the spec suites return arguments.target.$suites; } diff --git a/system/runners/BaseRunner.cfc b/system/runners/BaseRunner.cfc index 2279200f..8855b1a2 100644 --- a/system/runners/BaseRunner.cfc +++ b/system/runners/BaseRunner.cfc @@ -1,48 +1,44 @@ /** -* Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp -* www.ortussolutions.com -* --- -* The TestBox main base runner which has all the common methods needed for runner implementations. -*/ -component{ + * Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + * The TestBox main base runner which has all the common methods needed for runner implementations. + */ +component { /************************************** UTILITY METHODS *********************************************/ /** - * Checks if the incoming labels are good for running - * @incomingLabels The incoming labels to test against this runner's labels. - * @testResults The testing results object - */ - boolean function canRunLabel( - required array incomingLabels, - required testResults - ){ - - var labels = arguments.testResults.getLabels(); - var excludes = arguments.testResults.getExcludes(); - - // do we have labels applied? - var canRun = true; - if( arrayLen( labels ) ){ - canRun = false; - for( var thisLabel in labels ){ + * Checks if the incoming labels are good for running + * @incomingLabels The incoming labels to test against this runner's labels. + * @testResults The testing results object + */ + boolean function canRunLabel( required array incomingLabels, required testResults ){ + var labels = arguments.testResults.getLabels(); + var excludes = arguments.testResults.getExcludes(); + + // do we have labels applied? + var canRun = true; + if ( arrayLen( labels ) ) { + canRun = false; + for ( var thisLabel in labels ) { // verify that a label exists, if it does, break, it matches the criteria, if no matches, then skip it. - if( arrayFindNoCase( incomingLabels, thisLabel ) ){ + if ( arrayFindNoCase( incomingLabels, thisLabel ) ) { // match, so we can run it. - canRun = true; + canRun = true; } } - } + } - if ( ! arrayIsEmpty( excludes ) ) { - for ( var thisExclude in excludes ) { - if ( arrayFindNoCase( incomingLabels, thisExclude ) ) { - canRun = false; - } - } - } + if ( !arrayIsEmpty( excludes ) ) { + for ( var thisExclude in excludes ) { + if ( arrayFindNoCase( incomingLabels, thisExclude ) ) { + canRun = false; + } + } + } - return canRun; + return canRun; } /** @@ -51,14 +47,11 @@ component{ * @name The spec name * @testResults The testing results object */ - boolean function canRunSpec( - required name, - required testResults - ){ + boolean function canRunSpec( required name, required testResults ){ var testSpecs = arguments.testResults.getTestSpecs(); // verify we have some? - if( arrayLen( testSpecs ) ){ + if ( arrayLen( testSpecs ) ) { return ( arrayFindNoCase( testSpecs, arguments.name ) ? true : false ); } @@ -77,14 +70,18 @@ component{ boolean function isSuiteFocused( required suite, required target, - boolean checkChildren=true, - boolean checkParent=true + boolean checkChildren = true, + boolean checkParent = true ){ // Verify Focused Targets - if( arrayLen( arguments.target.$focusedTargets.suites ) ){ - + if ( arrayLen( arguments.target.$focusedTargets.suites ) ) { // Is this suite focused - if( arrayFindNoCase( arguments.target.$focusedTargets.suites, arguments.suite.slug & "/" & arguments.suite.name ) ){ + if ( + arrayFindNoCase( + arguments.target.$focusedTargets.suites, + arguments.suite.slug & "/" & arguments.suite.name + ) + ) { return true; } @@ -92,7 +89,13 @@ component{ var parentSuite = arguments.suite.parentRef; while ( !isSimpleValue( parentSuite ) ) { // Is parent focused? - if( isSuiteFocused( suite=parentSuite, target=arguments.target, checkChildren=false ) ){ + if ( + isSuiteFocused( + suite = parentSuite, + target = arguments.target, + checkChildren = false + ) + ) { return true; } // Go on up @@ -100,10 +103,16 @@ component{ } // Go downstream little fish, check if you have children suites that are focused - if( arguments.checkChildren ){ - for( var thisSuite in arguments.suite.suites ){ + if ( arguments.checkChildren ) { + for ( var thisSuite in arguments.suite.suites ) { // go down the rabbit hole - if( isSuiteFocused( suite=thisSuite, target=arguments.target, checkParent=false ) ){ + if ( + isSuiteFocused( + suite = thisSuite, + target = arguments.target, + checkParent = false + ) + ) { return true; } } @@ -128,23 +137,28 @@ component{ required testResults, required target ){ - var testSuites = arguments.testResults.getTestSuites(); // Are we focused - if( !isSuiteFocused( arguments.suite, arguments.target ) ){ + if ( !isSuiteFocused( arguments.suite, arguments.target ) ) { return false; } // verify we have some? - if( arrayLen( testSuites ) ){ + if ( arrayLen( testSuites ) ) { var results = ( arrayFindNoCase( testSuites, arguments.suite.name ) ? true : false ); // Verify nested if no match, maybe it is an embedded suite that is trying to execute. - if( results == false && arrayLen( arguments.suite.suites ) ){ - for( var thisSuite in arguments.suite.suites ){ + if ( results == false && arrayLen( arguments.suite.suites ) ) { + for ( var thisSuite in arguments.suite.suites ) { // go down the rabbit hole - if( canRunSuite( thisSuite, arguments.testResults, arguments.target ) ){ + if ( + canRunSuite( + thisSuite, + arguments.testResults, + arguments.target + ) + ) { return true; } } @@ -152,10 +166,10 @@ component{ } // Verify hierarchy slug - if( results == false && len( arguments.suite.slug ) ){ + if ( results == false && len( arguments.suite.slug ) ) { var slugArray = listToArray( arguments.suite.slug, "/" ); - for( var thisSlug in slugArray ){ - if( arrayFindNoCase( testSuites, thisSlug ) ){ + for ( var thisSlug in slugArray ) { + if ( arrayFindNoCase( testSuites, thisSlug ) ) { return true; } } @@ -170,19 +184,19 @@ component{ } /** - * Checks if we can run the test bundle due to using testBundles arguments or incoming URL filters. - * @suite The suite definition - * @testResults The testing results object - */ + * Checks if we can run the test bundle due to using testBundles arguments or incoming URL filters. + * @suite The suite definition + * @testResults The testing results object + */ boolean function canRunBundle( required bundlePath, - required testResults, - required targetMD + required testResults, + required targetMD ){ var testBundles = arguments.testResults.getTestBundles(); // verify we have some? - if( arrayLen( testBundles ) ){ + if ( arrayLen( testBundles ) ) { return ( arrayFindNoCase( testBundles, arguments.bundlePath ) ? true : false ); } @@ -191,32 +205,35 @@ component{ } /** - * Validate the incoming method name is a valid TestBox test method name - * @methodName The method name to validate - * @target The target object - */ - boolean function isValidTestMethod( required methodName, required target ) { + * Validate the incoming method name is a valid TestBox test method name + * @methodName The method name to validate + * @target The target object + */ + boolean function isValidTestMethod( required methodName, required target ){ // True if annotation "test" exists - if( structKeyExists( getMetadata( arguments.target[ arguments.methodName ] ), "test" ) ){ + if ( structKeyExists( getMetadata( arguments.target[ arguments.methodName ] ), "test" ) ) { return true; } // All xUnit test methods must start or end with the term, "test". - return( !! reFindNoCase( "(^test|test$)", methodName ) ); + return ( !!reFindNoCase( "(^test|test$)", methodName ) ); } /** - * Get metadata from a method - * @target The target method - * @name The annotation to look for - * @defaultValue The default value to return if not found - */ - function getMethodAnnotation( required target, required name, defaultValue="" ){ + * Get metadata from a method + * @target The target method + * @name The annotation to look for + * @defaultValue The default value to return if not found + */ + function getMethodAnnotation( + required target, + required name, + defaultValue = "" + ){ var md = getMetadata( arguments.target ); - if( structKeyExists( md, arguments.name ) ){ + if ( structKeyExists( md, arguments.name ) ) { return ( len( md[ arguments.name ] ) ? md[ arguments.name ] : true ); - } - else{ + } else { return arguments.defaultValue; } } diff --git a/system/runners/IRunner.cfc b/system/runners/IRunner.cfc index 0494d051..5910b2e3 100644 --- a/system/runners/IRunner.cfc +++ b/system/runners/IRunner.cfc @@ -1,28 +1,28 @@ /** -* Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp -* www.ortussolutions.com -* --- -* This TestBox runner is used to run and report on xUnit style test suites. -*/ -interface{ + * Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + * This TestBox runner is used to run and report on xUnit style test suites. + */ +interface { /** - * Constructor - * @options The options for a runner - * @testbox The TestBox class reference - */ + * Constructor + * @options The options for a runner + * @testbox The TestBox class reference + */ function init( required struct options, required testbox ); /** - * Execute a test run on a target bundle CFC - * @target The target bundle CFC to test - * @testResults The test results object to keep track of results for this test case - * @callbacks A struct of listener callbacks or a CFC with callbacks for listening to progress of the testing: onBundleStart,onBundleEnd,onSuiteStart,onSuiteEnd,onSpecStart,onSpecEnd - */ - any function run( + * Execute a test run on a target bundle CFC + * @target The target bundle CFC to test + * @testResults The test results object to keep track of results for this test case + * @callbacks A struct of listener callbacks or a CFC with callbacks for listening to progress of the testing: onBundleStart,onBundleEnd,onSuiteStart,onSuiteEnd,onSpecStart,onSpecEnd + */ + any function run( required any target, required testbox.system.TestResult testResults, required callbacks ); - -} \ No newline at end of file + +} diff --git a/system/runners/UnitRunner.cfc b/system/runners/UnitRunner.cfc index 4a95312f..1cc60b71 100644 --- a/system/runners/UnitRunner.cfc +++ b/system/runners/UnitRunner.cfc @@ -1,10 +1,14 @@ /** -* Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp -* www.ortussolutions.com -* --- -* This TestBox runner is used to run and report on xUnit style test suites. -*/ -component extends="testbox.system.runners.BaseRunner" implements="testbox.system.runners.IRunner" accessors="true"{ + * Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + * This TestBox runner is used to run and report on xUnit style test suites. + */ +component + extends ="testbox.system.runners.BaseRunner" + implements="testbox.system.runners.IRunner" + accessors ="true" +{ // runner options property name="options"; @@ -12,12 +16,11 @@ component extends="testbox.system.runners.BaseRunner" implements="testbox.system property name="testbox"; /** - * Constructor - * @options.hint The options for this runner - * @testbox.hint The TestBox class reference - */ + * Constructor + * @options.hint The options for this runner + * @testbox.hint The TestBox class reference + */ function init( required struct options, required testBox ){ - variables.options = arguments.options; variables.testbox = arguments.testbox; @@ -25,88 +28,114 @@ component extends="testbox.system.runners.BaseRunner" implements="testbox.system } /** - * Execute a BDD test on the incoming target and store the results in the incoming test results - * @target.hint The target bundle CFC to test - * @testResults.hint The test results object to keep track of results for this test case - * @callbacks A struct of listener callbacks or a CFC with callbacks for listening to progress of the testing: onBundleStart,onBundleEnd,onSuiteStart,onSuiteEnd,onSpecStart,onSpecEnd - */ + * Execute a BDD test on the incoming target and store the results in the incoming test results + * @target.hint The target bundle CFC to test + * @testResults.hint The test results object to keep track of results for this test case + * @callbacks A struct of listener callbacks or a CFC with callbacks for listening to progress of the testing: onBundleStart,onBundleEnd,onSuiteStart,onSuiteEnd,onSpecStart,onSpecEnd + */ any function run( required any target, required testbox.system.TestResult testResults, required callbacks ){ - // Get target information - var targetMD = getMetadata( arguments.target ); - var bundleName = ( structKeyExists( targetMD, "displayName" ) ? targetMD.displayname : targetMD.name ); + var targetMD = getMetadata( arguments.target ); + var bundleName = ( structKeyExists( targetMD, "displayName" ) ? targetMD.displayname : targetMD.name ); // Discover the test suite data to use for testing - var testSuites = getTestSuites( arguments.target, targetMD, arguments.testResults ); + var testSuites = getTestSuites( + arguments.target, + targetMD, + arguments.testResults + ); var testSuitesCount = arrayLen( testSuites ); // Start recording stats for this bundle - var bundleStats = arguments.testResults.startBundleStats( bundlePath=targetMD.name, name=bundleName ); + var bundleStats = arguments.testResults.startBundleStats( + bundlePath = targetMD.name, + name = bundleName + ); // Verify we can run this bundle - if( canRunBundle( bundlePath=targetMD.name, testResults=arguments.testResults, targetMD=targetMD ) ){ - try{ + if ( + canRunBundle( + bundlePath = targetMD.name, + testResults = arguments.testResults, + targetMD = targetMD + ) + ) { + try { // execute beforeAll(), beforeTests() for this bundle, no matter how many suites they have. - if( structKeyExists( arguments.target, "beforeAll" ) ){ arguments.target.beforeAll(); } + if ( structKeyExists( arguments.target, "beforeAll" ) ) { + arguments.target.beforeAll(); + } // find any methods annotated 'beforeAll' and execute them - var beforeAllAnnotationMethods = variables.testbox.getUtility().getAnnotatedMethods( - annotation = "beforeAll", - metadata = getMetadata( arguments.target ) - ); + var beforeAllAnnotationMethods = variables.testbox + .getUtility() + .getAnnotatedMethods( annotation = "beforeAll", metadata = getMetadata( arguments.target ) ); - for ( var beforeAllMethod in beforeAllAnnotationMethods ){ + for ( var beforeAllMethod in beforeAllAnnotationMethods ) { invoke( arguments.target, "#beforeAllMethod.name#" ); } - if( structKeyExists( arguments.target, "beforeTests" ) ){ arguments.target.beforeTests(); } + if ( structKeyExists( arguments.target, "beforeTests" ) ) { + arguments.target.beforeTests(); + } // Iterate over found test suites and test them, if nested suites, then this will recurse as well. - for( var thisSuite in testSuites ){ + for ( var thisSuite in testSuites ) { // verify call backs - if( structKeyExists( arguments.callbacks, "onSuiteStart" ) ){ - arguments.callbacks.onSuiteStart( arguments.target, arguments.testResults, thisSuite ); + if ( structKeyExists( arguments.callbacks, "onSuiteStart" ) ) { + arguments.callbacks.onSuiteStart( + arguments.target, + arguments.testResults, + thisSuite + ); } // Execute Suite testSuite( - target=arguments.target, - suite=thisSuite, - testResults=arguments.testResults, - bundleStats=bundleStats, - callbacks=arguments.callbacks + target = arguments.target, + suite = thisSuite, + testResults = arguments.testResults, + bundleStats = bundleStats, + callbacks = arguments.callbacks ); // verify call backs - if( structKeyExists( arguments.callbacks, "onSuiteEnd" ) ){ - arguments.callbacks.onSuiteEnd( arguments.target, arguments.testResults, thisSuite ); + if ( structKeyExists( arguments.callbacks, "onSuiteEnd" ) ) { + arguments.callbacks.onSuiteEnd( + arguments.target, + arguments.testResults, + thisSuite + ); } } // execute afterAll(), afterTests() for this bundle, no matter how many suites they have. - if( structKeyExists( arguments.target, "afterAll" ) ){ arguments.target.afterAll(); } + if ( structKeyExists( arguments.target, "afterAll" ) ) { + arguments.target.afterAll(); + } // find any methods annotated 'afterAll' and execute them - var afterAllAnnotationMethods = variables.testbox.getUtility().getAnnotatedMethods( - annotation = "afterAll", - metadata = getMetadata( arguments.target ) - ); + var afterAllAnnotationMethods = variables.testbox + .getUtility() + .getAnnotatedMethods( annotation = "afterAll", metadata = getMetadata( arguments.target ) ); - for ( var afterAllMethod in afterAllAnnotationMethods ){ + for ( var afterAllMethod in afterAllAnnotationMethods ) { invoke( arguments.target, "#afterAllMethod.name#" ); } - if( structKeyExists( arguments.target, "afterTests" ) ){ arguments.target.afterTests(); } - } catch(Any e) { + if ( structKeyExists( arguments.target, "afterTests" ) ) { + arguments.target.afterTests(); + } + } catch ( Any e ) { bundleStats.globalException = e; // For a righteous man falls seven times, and rises (tests) again :) // The amount doesn't matter, nothing can run at this point, failure with before/after aspects that need fixing - bundleStats.totalError = 7; - arguments.testResults.incrementStat( type="error", count=bundleStats.totalError ); + bundleStats.totalError = 7; + arguments.testResults.incrementStat( type = "error", count = bundleStats.totalError ); } } @@ -119,117 +148,148 @@ component extends="testbox.system.runners.BaseRunner" implements="testbox.system /************************************** TESTING METHODS *********************************************/ /** - * Test the incoming suite definition - * @target.hint The target bundle CFC - * @method.hint The method definition to test - * @testResults.hint The testing results object - * @bundleStats.hint The bundle stats this suite belongs to - * @callbacks The CFC or struct of callback listener methods - */ + * Test the incoming suite definition + * @target.hint The target bundle CFC + * @method.hint The method definition to test + * @testResults.hint The testing results object + * @bundleStats.hint The bundle stats this suite belongs to + * @callbacks The CFC or struct of callback listener methods + */ private function testSuite( required target, required suite, required testResults, required bundleStats, - required callbacks={} + required callbacks = {} ){ - // Start suite stats - var suiteStats = arguments.testResults.startSuiteStats( arguments.suite.name, arguments.bundleStats ); + var suiteStats = arguments.testResults.startSuiteStats( + arguments.suite.name, + arguments.bundleStats + ); // Record bundle + suite + global initial stats - suiteStats.totalSpecs = arrayLen( arguments.suite.specs ); + suiteStats.totalSpecs = arrayLen( arguments.suite.specs ); arguments.bundleStats.totalSpecs += suiteStats.totalSpecs; arguments.bundleStats.totalSuites++; // increment global suites + specs - arguments.testResults.incrementSuites() + arguments.testResults + .incrementSuites() .incrementSpecs( suiteStats.totalSpecs ); // Verify we can execute the incoming suite via skipping or labels - if( !arguments.suite.skip && - canRunSuite( arguments.suite, arguments.testResults, arguments.target ) - ){ - + if ( + !arguments.suite.skip && + canRunSuite( + arguments.suite, + arguments.testResults, + arguments.target + ) + ) { // prepare threaded names - var threadNames = []; + var threadNames = []; // threaded variables just in case some suite is async and another is not. - thread.testResults = arguments.testResults; - thread.suiteStats = suiteStats; - thread.target = arguments.target; + thread.testResults = arguments.testResults; + thread.suiteStats = suiteStats; + thread.target = arguments.target; // iterate over suite specs and test them - for( var thisSpec in arguments.suite.specs ){ - + for ( var thisSpec in arguments.suite.specs ) { // is this async or not? - if( arguments.suite.asyncAll ){ + if ( arguments.suite.asyncAll ) { // prepare thread name - var thisThreadName = variables.testBox.getUtility().slugify( "tb-" & thisSpec.name & "-#hash( getTickCount() + randRange( 1, 10000000 ) )#" ); + var thisThreadName = variables.testBox + .getUtility() + .slugify( "tb-" & thisSpec.name & "-#hash( getTickCount() + randRange( 1, 10000000 ) )#" ); // append to used thread names arrayAppend( threadNames, thisThreadName ); // thread it - thread name="#thisThreadName#" - thisSpec="#thisSpec#" - suite="#arguments.suite#" - threadName="#thisThreadName#" - callbacks="#arguments.callbacks#" - { - + thread + name ="#thisThreadName#" + thisSpec ="#thisSpec#" + suite ="#arguments.suite#" + threadName="#thisThreadName#" + callbacks ="#arguments.callbacks#" { // verify call backs - if( structKeyExists( attributes.callbacks, "onSpecStart" ) ){ - attributes.callbacks.onSpecStart( thread.target, thread.testResults, thread.suiteStats, attributes.thisSpec ); + if ( structKeyExists( attributes.callbacks, "onSpecStart" ) ) { + attributes.callbacks.onSpecStart( + thread.target, + thread.testResults, + thread.suiteStats, + attributes.thisSpec + ); } // execute the test within the context of the spec target due to lucee closure bug, move back once it is resolved. thread.target.runTestMethod( - spec=attributes.thisSpec, - testResults=thread.testResults, - suiteStats=thread.suiteStats, - runner=this + spec = attributes.thisSpec, + testResults = thread.testResults, + suiteStats = thread.suiteStats, + runner = this ); // verify call backs - if( structKeyExists( attributes.callbacks, "onSpecEnd" ) ){ - attributes.callbacks.onSpecEnd( thread.target, thread.testResults, thread.suiteStats, attributes.thisSpec ); + if ( structKeyExists( attributes.callbacks, "onSpecEnd" ) ) { + attributes.callbacks.onSpecEnd( + thread.target, + thread.testResults, + thread.suiteStats, + attributes.thisSpec + ); } } - } else { // verify call backs - if( structKeyExists( arguments.callbacks, "onSpecStart" ) ){ - arguments.callbacks.onSpecStart( arguments.target, arguments.testResults, thread.suiteStats, thisSpec ); + if ( structKeyExists( arguments.callbacks, "onSpecStart" ) ) { + arguments.callbacks.onSpecStart( + arguments.target, + arguments.testResults, + thread.suiteStats, + thisSpec + ); } // execute the test within the context of the spec target due to lucee closure bug, move back once it is resolved. thread.target.runTestMethod( - spec=thisSpec, - testResults=thread.testResults, - suiteStats=thread.suiteStats, - runner=this + spec = thisSpec, + testResults = thread.testResults, + suiteStats = thread.suiteStats, + runner = this ); // verify call backs - if( structKeyExists( arguments.callbacks, "onSpecEnd" ) ){ - arguments.callbacks.onSpecEnd( arguments.target, arguments.testResults, thread.suiteStats, thisSpec ); + if ( structKeyExists( arguments.callbacks, "onSpecEnd" ) ) { + arguments.callbacks.onSpecEnd( + arguments.target, + arguments.testResults, + thread.suiteStats, + thisSpec + ); } } - - } // end loop over specs + } + // end loop over specs // join threads if async - if( arguments.suite.asyncAll ){ thread action="join" name="#arrayToList( threadNames )#"{}; } + if ( arguments.suite.asyncAll ) { + thread action="join" name="#arrayToList( threadNames )#" { + }; + } // All specs finalized, set suite status according to spec data - if( suiteStats.totalError GT 0 ){ suiteStats.status = "Error"; } - else if( suiteStats.totalFail GT 0 ){ suiteStats.status = "Failed"; } - else{ suiteStats.status = "Passed"; } + if ( suiteStats.totalError GT 0 ) { + suiteStats.status = "Error"; + } else if ( suiteStats.totalFail GT 0 ) { + suiteStats.status = "Failed"; + } else { + suiteStats.status = "Passed"; + } // Skip Checks - if( suiteStats.totalSpecs == suiteStats.totalSkipped ){ + if ( suiteStats.totalSpecs == suiteStats.totalSkipped ) { suiteStats.status = "Skipped"; } - - } - else{ + } else { // Record skipped stats and status suiteStats.status = "Skipped"; arguments.bundleStats.totalSkipped += suiteStats.totalSpecs; @@ -241,11 +301,11 @@ component extends="testbox.system.runners.BaseRunner" implements="testbox.system } /** - * Get all the test suites in the passed in bundle - * @target.hint The target to get the suites from - * @targetMD.hint The metadata of the target - * @testResults.hint The test results object - */ + * Get all the test suites in the passed in bundle + * @target.hint The target to get the suites from + * @targetMD.hint The metadata of the target + * @testResults.hint The test results object + */ private array function getTestSuites( required target, required targetMD, @@ -253,67 +313,71 @@ component extends="testbox.system.runners.BaseRunner" implements="testbox.system ){ var suite = { // suite name - name = ( structKeyExists( arguments.targetMD, "displayName" ) ? arguments.targetMD.displayname : arguments.targetMD.name ), + name : ( + structKeyExists( arguments.targetMD, "displayName" ) ? arguments.targetMD.displayname : arguments.targetMD.name + ), // async flag - asyncAll = ( structKeyExists( arguments.targetMD, "asyncAll" ) ? arguments.targetMD.asyncAll : false ), + asyncAll : ( structKeyExists( arguments.targetMD, "asyncAll" ) ? arguments.targetMD.asyncAll : false ), // skip suite testing flag - skip = ( structKeyExists( arguments.targetMD, "skip" ) ? ( len( arguments.targetMD.skip ) ? arguments.targetMD.skip : true ) : false ), + skip : ( + structKeyExists( arguments.targetMD, "skip" ) ? ( + len( arguments.targetMD.skip ) ? arguments.targetMD.skip : true + ) : false + ), // labels attached to the suite for execution - labels = ( structKeyExists( arguments.targetMD, "labels" ) ? listToArray( arguments.targetMD.labels ) : [] ), + labels : ( structKeyExists( arguments.targetMD, "labels" ) ? listToArray( arguments.targetMD.labels ) : [] ), // the specs attached to this suite. - specs = getTestMethods( arguments.target, arguments.testResults ), + specs : getTestMethods( arguments.target, arguments.testResults ), // the recursive suites - suites = [] - }; + suites : [] + }; // skip constraint for suite? - if( !isBoolean( suite.skip ) && isCustomFunction( arguments.target[ suite.skip ] ) ){ + if ( !isBoolean( suite.skip ) && isCustomFunction( arguments.target[ suite.skip ] ) ) { suite.skip = invoke( arguments.target, "#suite.skip#" ); } // check them. - if( arrayLen( arguments.testResults.getLabels() ) ) - suite.skip = ( ! canRunLabel( suite.labels, arguments.testResults ) ); + if ( arrayLen( arguments.testResults.getLabels() ) ) + suite.skip = ( !canRunLabel( suite.labels, arguments.testResults ) ); return [ suite ]; } /** - * Retrieve the testing methods/specs from a given target. - * @target.hint The target to get the methods from - */ - private array function getTestMethods( - required any target, - required any testResults - ){ - - var mResults = []; + * Retrieve the testing methods/specs from a given target. + * @target.hint The target to get the methods from + */ + private array function getTestMethods( required any target, required any testResults ){ + var mResults = []; var methodArray = structKeyArray( arguments.target ); - var index = 1; + var index = 1; - for( var thisMethod in methodArray ) { + for ( var thisMethod in methodArray ) { // only valid functions and test functions allowed - if( isCustomFunction( arguments.target[ thisMethod ] ) && - isValidTestMethod( thisMethod, arguments.target ) ) { + if ( + isCustomFunction( arguments.target[ thisMethod ] ) && + isValidTestMethod( thisMethod, arguments.target ) + ) { // Build the spec data packet var specMD = getMetadata( arguments.target[ thisMethod ] ); - var spec = { - name = specMD.name, - hint = ( structKeyExists( specMD, "hint" ) ? specMD.hint : "" ), - skip = ( structKeyExists( specMD, "skip" ) ? ( len( specMD.skip ) ? specMD.skip : true ) : false ), - labels = ( structKeyExists( specMD, "labels" ) ? listToArray( specMD.labels ) : [] ), - order = ( structKeyExists( specMD, "order" ) ? listToArray( specMD.order ) : index++ ), - expectedException = ( structKeyExists( specMD, "expectedException" ) ? specMD.expectedException : "" ) + var spec = { + name : specMD.name, + hint : ( structKeyExists( specMD, "hint" ) ? specMD.hint : "" ), + skip : ( structKeyExists( specMD, "skip" ) ? ( len( specMD.skip ) ? specMD.skip : true ) : false ), + labels : ( structKeyExists( specMD, "labels" ) ? listToArray( specMD.labels ) : [] ), + order : ( structKeyExists( specMD, "order" ) ? listToArray( specMD.order ) : index++ ), + expectedException : ( structKeyExists( specMD, "expectedException" ) ? specMD.expectedException : "" ) }; // skip constraint? - if( !isBoolean( spec.skip ) && isCustomFunction( arguments.target[ spec.skip ] ) ){ + if ( !isBoolean( spec.skip ) && isCustomFunction( arguments.target[ spec.skip ] ) ) { spec.skip = invoke( arguments.target, "#spec.skip#" ); } // do we have labels applied? - if( arrayLen( arguments.testResults.getLabels() ) ) - spec.skip = ( ! canRunLabel( spec.labels, arguments.testResults ) ); + if ( arrayLen( arguments.testResults.getLabels() ) ) + spec.skip = ( !canRunLabel( spec.labels, arguments.testResults ) ); // register spec arrayAppend( mResults, spec ); diff --git a/system/util/MixerUtil.cfc b/system/util/MixerUtil.cfc index a7a74ea8..7043771c 100644 --- a/system/util/MixerUtil.cfc +++ b/system/util/MixerUtil.cfc @@ -3,117 +3,145 @@ Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp www.ortussolutions.com ******************************************************************************** - -Author : Luis Majano +Author : Luis Majano Description : - A utility object that provides runtime mixins +A utility object that provides runtime mixins -----------------------------------------------------------------------> - - + - variables.instance = structnew(); - instance.mixins = StructNew(); - - // Place our methods on the mixins struct - instance.mixins[ "removeMixin" ] = variables.removeMixin; - instance.mixins[ "injectMixin" ] = variables.injectMixin; - instance.mixins[ "invokerMixin" ] = variables.invokerMixin; - instance.mixins[ "injectPropertyMixin" ] = variables.injectPropertyMixin; - instance.mixins[ "removePropertyMixin" ] = variables.removePropertyMixin; - instance.mixins[ "populatePropertyMixin" ] = variables.populatePropertyMixin; - instance.mixins[ "includeitMixin" ] = variables.includeitMixin; - instance.mixins[ "getPropertyMixin" ] = variables.getPropertyMixin; - instance.mixins[ "exposeMixin" ] = variables.exposeMixin; - instance.mixins[ "methodProxy" ] = variables.methodProxy; - - instance.system = createObject('java','java.lang.System'); - - return this; + variables.instance = structNew(); + instance.mixins = structNew(); + + // Place our methods on the mixins struct + instance.mixins[ "removeMixin" ] = variables.removeMixin; + instance.mixins[ "injectMixin" ] = variables.injectMixin; + instance.mixins[ "invokerMixin" ] = variables.invokerMixin; + instance.mixins[ "injectPropertyMixin" ] = variables.injectPropertyMixin; + instance.mixins[ "removePropertyMixin" ] = variables.removePropertyMixin; + instance.mixins[ "populatePropertyMixin" ] = variables.populatePropertyMixin; + instance.mixins[ "includeitMixin" ] = variables.includeitMixin; + instance.mixins[ "getPropertyMixin" ] = variables.getPropertyMixin; + instance.mixins[ "exposeMixin" ] = variables.exposeMixin; + instance.mixins[ "methodProxy" ] = variables.methodProxy; + + instance.system = createObject( "java", "java.lang.System" ); + + return this; - + - + - - - - - for( udf in instance.mixins ){ - arguments.CFC[udf] = instance.mixins[udf]; - } - arguments.CFC.$mixed = true; - - - + + + + + for ( udf in instance.mixins ) { + arguments.CFC[ udf ] = instance.mixins[ udf ]; + } + arguments.CFC.$mixed = true; + + + - + - + - for( udf in instance.mixins ){ - arguments.CFC[udf] = instance.mixins[udf]; - StructDelete(arguments.CFC, udf); - } + for ( udf in instance.mixins ) { + arguments.CFC[ udf ] = instance.mixins[ udf ]; + structDelete( arguments.CFC, udf ); + } - + - - - + + + - // get new name - if( !len( arguments.newName ) ){ - arguments.newName = arguments.method; - } - - // stash it away - if( !structKeyExists( this, "$exposedMethods") ){ - this.$exposedMethods = {}; - } - this.$exposedMethods[ arguments.method ] = variables[ arguments.method ]; - - // replace with proxy. - this[ arguments.newName ] = this.methodProxy; - - // Create alias if needed - if( arguments.newName != arguments.method ){ - this.$exposedMethods[ arguments.newName ] = this.$exposedMethods[ arguments.method ]; - } - - return this; + // get new name + if ( !len( arguments.newName ) ) { + arguments.newName = arguments.method; + } + + // stash it away + if ( !structKeyExists( this, "$exposedMethods" ) ) { + this.$exposedMethods = {}; + } + this.$exposedMethods[ arguments.method ] = variables[ arguments.method ]; + + // replace with proxy. + this[ arguments.newName ] = this.methodProxy; + + // Create alias if needed + if ( arguments.newName != arguments.method ) { + this.$exposedMethods[ arguments.newName ] = this.$exposedMethods[ arguments.method ]; + } + + return this; - var methodName = getFunctionCalledName(); - - if( !structKeyExists( this.$exposedMethods, methodName ) ){ - throw( message="The exposed method you are calling: #methodName# does not exist", - detail="Exposed methods are #structKeyList( this.$exposedMethods )#", - type="ExposedMethodProxy" ); - } - - var method = this.$exposedMethods[ methodName ]; - return method( argumentCollection=arguments ); + var methodName = getFunctionCalledName(); + + if ( !structKeyExists( this.$exposedMethods, methodName ) ) { + throw( + message = "The exposed method you are calling: #methodName# does not exist", + detail = "Exposed methods are #structKeyList( this.$exposedMethods )#", + type = "ExposedMethodProxy" + ); + } + + var method = this.$exposedMethods[ methodName ]; + return method( argumentCollection = arguments ); @@ -125,51 +153,65 @@ Description : - - + + - variables[arguments.name] = arguments.UDF; - this[arguments.name] = arguments.UDF; + variables[ arguments.name ] = arguments.UDF; + this[ arguments.name ] = arguments.UDF; - - - - + + + + - // Validate Property - if( structKeyExists(evaluate(arguments.scope),arguments.propertyName) ){ - "#arguments.scope#.#arguments.propertyName#" = arguments.propertyValue; - } + // Validate Property + if ( structKeyExists( evaluate( arguments.scope ), arguments.propertyName ) ) { + "#arguments.scope#.#arguments.propertyName#" = arguments.propertyValue; + } - - - + + + - var thisScope = variables; - if( arguments.scope eq "this"){ thisScope = this; } + var thisScope = variables; + if ( arguments.scope eq "this" ) { + thisScope = this; + } - if( NOT structKeyExists(thisScope,arguments.name) AND structKeyExists(arguments,"default")){ - return arguments.default; - } + if ( NOT structKeyExists( thisScope, arguments.name ) AND structKeyExists( arguments, "default" ) ) { + return arguments.default; + } - return thisScope[arguments.name]; + return thisScope[ arguments.name ]; - - - - + + + + - "#arguments.scope#.#arguments.propertyName#" = arguments.propertyValue; + "#arguments.scope#.#arguments.propertyName#" = arguments.propertyValue; @@ -177,51 +219,66 @@ Description : - structDelete(this, arguments.udfName); - structDelete(variables, arguments.udfName); + structDelete( this, arguments.udfName ); + structDelete( variables, arguments.udfName ); - - - + + + - structDelete(evaluate(arguments.scope),arguments.propertyName); + structDelete( evaluate( arguments.scope ), arguments.propertyName ); - - - - - - - + + + + + + + - - - - + + + + - + - + - + - - \ No newline at end of file + diff --git a/system/util/Util.cfc b/system/util/Util.cfc index 1fffb1e1..74191391 100644 --- a/system/util/Util.cfc +++ b/system/util/Util.cfc @@ -1,31 +1,33 @@ /** -* Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp -* www.ortussolutions.com -* --- -* Mail Utility library for TestBox -*/ -component{ + * Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + * Mail Utility library for TestBox + */ +component { /** - * Get the mixer utility object instance. It lazy loads into variables scope for faster execution next time. - * @return MixerUtil - */ + * Get the mixer utility object instance. It lazy loads into variables scope for faster execution next time. + * @return MixerUtil + */ function getMixerUtil(){ - if( structKeyExists( variables, "mixerUtil" ) ){ return variables.mixerUtil; } + if ( structKeyExists( variables, "mixerUtil" ) ) { + return variables.mixerUtil; + } variables.mixerUtil = new MixerUtil(); return variables.mixerUtil; } /** - * Convert an array to struct argument notation - * @input The array to convert - */ + * Convert an array to struct argument notation + * @input The array to convert + */ struct function arrayToStruct( required array input ){ - var results = structnew(); + var results = structNew(); var x = 1; - var inLen = Arraylen( arguments.input ); + var inLen = arrayLen( arguments.input ); - for( x=1; x lte inLen; x=x+1 ){ + for ( x = 1; x lte inLen; x = x + 1 ) { results[ x ] = arguments.input[ x ]; } @@ -33,116 +35,132 @@ component{ } /** - * Get the last modified date of a file - * @filename The target - * - * @return date - */ + * Get the last modified date of a file + * @filename The target + * + * @return date + */ function fileLastModified( required filename ){ - var objFile = createObject( "java", "java.io.File" ).init( javaCast( "string", getAbsolutePath( arguments.filename ) ) ); + var objFile = createObject( "java", "java.io.File" ).init( + javacast( "string", getAbsolutePath( arguments.filename ) ) + ); // Calculate adjustments fot timezone and daylightsavindtime - var offset = ( ( getTimeZoneInfo().utcHourOffset ) +1 )*-3600; + var offset = ( ( getTimezoneInfo().utcHourOffset ) + 1 ) * -3600; // Date is returned as number of seconds since 1-1-1970 - return dateAdd( 's', ( round( objFile.lastModified() / 1000 ) ) + offset, CreateDateTime( 1970, 1, 1, 0, 0, 0 ) ); + return dateAdd( + "s", + ( round( objFile.lastModified() / 1000 ) ) + offset, + createDateTime( 1970, 1, 1, 0, 0, 0 ) + ); } /** - * Rip an extension of a filename - * @filename The target - */ + * Rip an extension of a filename + * @filename The target + */ string function ripExtension( required filename ){ return reReplace( arguments.filename, "\.[^.]*$", "" ); } /** - * Turn any system path, either relative or absolute, into a fully qualified one - * @path The target - */ + * Turn any system path, either relative or absolute, into a fully qualified one + * @path The target + */ string function getAbsolutePath( required path ){ - var fileObj = createObject( "java", "java.io.File" ).init( javaCast( "String", arguments.path ) ); - if( fileObj.isAbsolute() ){ + var fileObj = createObject( "java", "java.io.File" ).init( javacast( "String", arguments.path ) ); + if ( fileObj.isAbsolute() ) { return arguments.path; } return expandPath( arguments.path ); } /** - * Check if you are in cfthread or not for any CFML Engine - */ + * Check if you are in cfthread or not for any CFML Engine + */ boolean function inThread(){ var engine = "ADOBE"; - if ( server.coldfusion.productname eq "Lucee" ){ engine = "LUCEE"; } + if ( server.coldfusion.productname eq "Lucee" ) { + engine = "LUCEE"; + } - switch( engine ){ - case "ADOBE" : { - if( findNoCase( "cfthread", createObject( "java", "java.lang.Thread" ).currentThread().getThreadGroup().getName()) ){ + switch ( engine ) { + case "ADOBE": { + if ( + findNoCase( + "cfthread", + createObject( "java", "java.lang.Thread" ) + .currentThread() + .getThreadGroup() + .getName() + ) + ) { return true; } break; } - case "LUCEE" : { + case "LUCEE": { return getPageContext().hasFamily(); } - - } //end switch statement. + } + // end switch statement. return false; } /** - * Create a URL safe slug from a string - * @str The target - * @maxLength The maximum number of characters for the slug - * @allow A regex safe list of additional characters to allow - */ - string function slugify( required string str, numeric maxLength=0, string allow="" ){ + * Create a URL safe slug from a string + * @str The target + * @maxLength The maximum number of characters for the slug + * @allow A regex safe list of additional characters to allow + */ + string function slugify( + required string str, + numeric maxLength = 0, + string allow = "" + ){ // Cleanup and slugify the string - var slug = lcase( trim( arguments.str ) ); - - slug = reReplace( slug, "[^a-z0-9-\s#arguments.allow#]", "", "all" ); - slug = trim ( reReplace( slug, "[\s-]+", " ", "all" ) ); + var slug = lCase( trim( arguments.str ) ); + + slug = reReplace( + slug, + "[^a-z0-9-\s#arguments.allow#]", + "", + "all" + ); + slug = trim( reReplace( slug, "[\s-]+", " ", "all" ) ); slug = reReplace( slug, "\s", "-", "all" ); // is there a max length restriction - if ( arguments.maxlength ){ slug = left ( slug, arguments.maxlength ); } + if ( arguments.maxlength ) { + slug = left( slug, arguments.maxlength ); + } return slug; } /** - * Find all methods on a given metadata and it's parents with a given annotation - * @annotation The annotation name to look for on methods - * @metadata The metadata to search (recursively) for the provided annotation - */ - public array function getAnnotatedMethods( - required string annotation, - required struct metadata - ) { + * Find all methods on a given metadata and it's parents with a given annotation + * @annotation The annotation name to look for on methods + * @metadata The metadata to search (recursively) for the provided annotation + */ + public array function getAnnotatedMethods( required string annotation, required struct metadata ){ var lifecycleMethods = []; - if( structKeyExists( arguments.metadata, "functions" ) ){ - - for( var thisFunction in arguments.metadata.functions ){ - if( structKeyExists( thisFunction, annotation ) ){ + if ( structKeyExists( arguments.metadata, "functions" ) ) { + for ( var thisFunction in arguments.metadata.functions ) { + if ( structKeyExists( thisFunction, annotation ) ) { arrayAppend( lifecycleMethods, thisFunction ); } } - } - if( structKeyExists( arguments.metadata, "extends" ) ){ - arrayEach( - getAnnotatedMethods( - arguments.annotation, - arguments.metadata.extends - ), - function( item ){ - arrayAppend( lifecycleMethods, arguments.item ); - } - ); + if ( structKeyExists( arguments.metadata, "extends" ) ) { + arrayEach( getAnnotatedMethods( arguments.annotation, arguments.metadata.extends ), function( item ){ + arrayAppend( lifecycleMethods, arguments.item ); + } ); } return lifecycleMethods; diff --git a/system/util/XMLConverter.cfc b/system/util/XMLConverter.cfc index 491c2174..1b61526a 100644 --- a/system/util/XMLConverter.cfc +++ b/system/util/XMLConverter.cfc @@ -5,134 +5,216 @@ www.ortussolutions.com ******************************************************************************** LICENSE Copyright 2006 Raymond Camden - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +https://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. If you find this app worthy, I have a Amazon wish list set up (www.amazon.com/o/registry/2TCL1D08EZEYE ). Gifts are always welcome. ;) - Modifications - Luis Majano - - Adaptation to using a more advanced algortithm on type detections - - Ability to nest complex variables and still convert to XML. - ----> +Luis Majano +- Adaptation to using a more advanced algortithm on type detections +- Ability to nest complex variables and still convert to XML.---> - - + - return this; + return this; - - - - - - - - - - + + + + + + + + + + - var buffer = createObject("java","java.lang.StringBuilder").init(''); + var buffer = createObject( "java", "java.lang.StringBuilder" ).init( "" ); - // Header - if( arguments.addHeader ){ - buffer.append(''); - } + // Header + if ( arguments.addHeader ) { + buffer.append( "" ); + } - // Object Check - if( isObject(arguments.data) ){ - buffer.append( objectToXML(argumentCollection=arguments) ); - } - // Struct Check? - else if( isStruct(arguments.data) ){ - buffer.append( structToXML(argumentCollection=arguments) ); - } - // Query Check? - else if( isQuery(arguments.data) ){ - buffer.append( queryToXML(argumentCollection=arguments) ); - } - // Array Check? - else if( isArray(arguments.data) ){ - buffer.append( arrayToXML(argumentCollection=arguments) ); - } - // Simple Value Check, treated as a simple array list? - else if( isSimpleValue(arguments.data) ){ - arguments.data = listToArray(arguments.data,arguments.delimiter); - buffer.append( arrayToXML(argumentCollection=arguments) ); - } + // Object Check + if ( isObject( arguments.data ) ) { + buffer.append( objectToXML( argumentCollection = arguments ) ); + } + // Struct Check? + else if ( isStruct( arguments.data ) ) { + buffer.append( structToXML( argumentCollection = arguments ) ); + } + // Query Check? + else if ( isQuery( arguments.data ) ) { + buffer.append( queryToXML( argumentCollection = arguments ) ); + } + // Array Check? + else if ( isArray( arguments.data ) ) { + buffer.append( arrayToXML( argumentCollection = arguments ) ); + } + // Simple Value Check, treated as a simple array list? + else if ( isSimpleValue( arguments.data ) ) { + arguments.data = listToArray( arguments.data, arguments.delimiter ); + buffer.append( arrayToXML( argumentCollection = arguments ) ); + } - return buffer.toString(); + return buffer.toString(); - - - - + + + + - var buffer = createObject('java','java.lang.StringBuilder').init(''); - var target = arguments.data; - var x = 1; - var dataLen = arrayLen(target); - var thisValue = ""; + var buffer = createObject( "java", "java.lang.StringBuilder" ).init( "" ); + var target = arguments.data; + var x = 1; + var dataLen = arrayLen( target ); + var thisValue = ""; var rootElement = "array"; var itemElement = "item"; // Root Name - if( len(arguments.rootName) ){ rootElement = arguments.rootName; } + if ( len( arguments.rootName ) ) { + rootElement = arguments.rootName; + } - //Create Root - buffer.append("<#rootElement#>"); + // Create Root + buffer.append( "<#rootElement#>" ); - - + - + - - + + - + - #thisValue#")> + #thisValue#" )> - ")> + " )> - - - - - - - - + + + + + + + + @@ -140,172 +222,216 @@ Modifications - + - ')> + " )> - ')> + " )> - - - - - - - - - - - "> - - #value#")> - - + + + + + + + + + + + "> + + #value#" )> + + + + - - ")> + " )> - ")> + " )> - - - - + + + + - var target = arguments.data; - var buffer = createObject("java","java.lang.StringBuilder").init(''); - var key = 0; - var thisValue = ""; - var args = structnew(); + var target = arguments.data; + var buffer = createObject( "java", "java.lang.StringBuilder" ).init( "" ); + var key = 0; + var thisValue = ""; + var args = structNew(); var rootElement = "struct"; - var objectType = ""; + var objectType = ""; // Root Element - if( len(arguments.rootName) ){ rootElement = arguments.rootName; } + if ( len( arguments.rootName ) ) { + rootElement = arguments.rootName; + } // Declare Root - if( isObject(arguments.data) ){ + if ( isObject( arguments.data ) ) { rootElement = "object"; - buffer.append('<#rootElement# type="#getMetadata(arguments.data).name#">'); - } - else{ - buffer.append("<#rootElement#>"); + buffer.append( "<#rootElement# type=""#getMetadata( arguments.data ).name#"">" ); + } else { + buffer.append( "<#rootElement#>" ); } // Content - for(key in target){ + for ( key in target ) { // Null Checks - if( NOT structKeyExists(target, key) ){ - target[key] = 'NULL'; + if ( NOT structKeyExists( target, key ) ) { + target[ key ] = "NULL"; } // Translate Value - if( NOT isSimpleValue(target[key]) ){ - thisValue = translateValue(arguments,target[key]); - } - else{ - thisValue = safeText(target[key],arguments.useCDATA); + if ( NOT isSimpleValue( target[ key ] ) ) { + thisValue = translateValue( arguments, target[ key ] ); + } else { + thisValue = safeText( target[ key ], arguments.useCDATA ); } - buffer.append("<#lcase(key)#>#thisValue#"); + buffer.append( "<#lCase( key )#>#thisValue#" ); } // End Root - buffer.append(""); + buffer.append( "" ); return buffer.toString(); - - - - + + + + - var target = arguments.data; - var buffer = createObject("java","java.lang.StringBuilder").init(''); - var md = getMetadata(target); - var rootElement = lcase( safeText( listLast( md.name, "." ) ) ); - var thisName = ""; - var thisValue = ""; - var x = 0; - var newValue = ""; + var target = arguments.data; + var buffer = createObject( "java", "java.lang.StringBuilder" ).init( "" ); + var md = getMetadata( target ); + var rootElement = lCase( safeText( listLast( md.name, "." ) ) ); + var thisName = ""; + var thisValue = ""; + var x = 0; + var newValue = ""; // Root Element Override - if( len(arguments.rootName) ){ rootElement = arguments.rootName; } + if ( len( arguments.rootName ) ) { + rootElement = arguments.rootName; + } // Declare Root - buffer.append('<#rootElement# type="#md.name#">'); + buffer.append( "<#rootElement# type=""#md.name#"">" ); // if no properties to marshall, then return blank - if( structKeyExists(md,"properties") ){ - + if ( structKeyExists( md, "properties" ) ) { // loop over properties - for(x=1; x lte ArrayLen(md.properties); x=x+1){ + for ( x = 1; x lte arrayLen( md.properties ); x = x + 1 ) { // check the property name exists and if it has a marshal annotation of false - if( structKeyExists(md.properties[x],"name") - OR NOT structKeyExists(md.properties[x],"marhsal") - OR md.properties[x]["marshal"] EQ true - ){ - thisName = md.properties[x].name; + if ( + structKeyExists( md.properties[ x ], "name" ) + OR NOT structKeyExists( md.properties[ x ], "marhsal" ) + OR md.properties[ x ][ "marshal" ] EQ true + ) { + thisName = md.properties[ x ].name; thisValue = invoke( target, "get#thisName#" ); // Value Defined? - if( not isDefined("thisValue") ){ + if ( not isDefined( "thisValue" ) ) { thisValue = ""; } // Translate Value - if( NOT isSimpleValue( thisValue ) ){ - thisValue = translateValue(arguments, thisValue); - } - else{ - thisValue = safeText(thisValue,arguments.useCDATA); + if ( NOT isSimpleValue( thisValue ) ) { + thisValue = translateValue( arguments, thisValue ); + } else { + thisValue = safeText( thisValue, arguments.useCDATA ); } - buffer.append("<#lcase(thisName)#>#thisValue#"); - - }//end if property has a name, else skip - - }// end loop over properties - - }// end if no properties detected + buffer.append( "<#lCase( thisName )#>#thisValue#" ); + } + // end if property has a name, else skip + } + // end loop over properties + } + // end if no properties detected // End Root - buffer.append(""); + buffer.append( "" ); return buffer.toString(); - + - - - + + + - var newArgs = structnew(); - newArgs.data = arguments.targetValue; - newArgs.useCDATA = arguments.args.useCDATA; - newArgs.addHeader = false; - return toXML(argumentCollection=newArgs); + var newArgs = structNew(); + newArgs.data = arguments.targetValue; + newArgs.useCDATA = arguments.args.useCDATA; + newArgs.addHeader = false; + return toXML( argumentCollection = newArgs ); - - - + + + "> @@ -314,38 +440,128 @@ Modifications - + - var string = arguments.value; - string = replaceNoCase(string,chr(8218),'&##8218;','all'); // � - string = replaceNoCase(string,chr(402),'&##402;','all'); // � - string = replaceNoCase(string,chr(8222),'&##8222;','all'); // � - string = replaceNoCase(string,chr(8230),'&##8230;','all'); // � - string = replaceNoCase(string,chr(8224),'&##8224;','all'); // � - string = replaceNoCase(string,chr(8225),'&##8225;','all'); // � - string = replaceNoCase(string,chr(710),'&##710;','all'); // � - string = replaceNoCase(string,chr(8240),'&##8240;','all'); // � - string = replaceNoCase(string,chr(352),'&##352;','all'); // � - string = replaceNoCase(string,chr(8249),'&##8249;','all'); // � - string = replaceNoCase(string,chr(338),'&##338;','all'); // � - string = replaceNoCase(string,chr(8216),'&##8216;','all'); // � - string = replaceNoCase(string,chr(8217),'&##8217;','all'); // � - string = replaceNoCase(string,chr(8220),'&##8220;','all'); // � - string = replaceNoCase(string,chr(8221),'&##8221;','all'); // � - string = replaceNoCase(string,chr(8226),'&##8226;','all'); // � - string = replaceNoCase(string,chr(8211),'&##8211;','all'); // � - string = replaceNoCase(string,chr(8212),'&##8212;','all'); // � - string = replaceNoCase(string,chr(732),'&##732;','all'); // � - string = replaceNoCase(string,chr(8482),'&##8482;','all'); // � - string = replaceNoCase(string,chr(353),'&##353;','all'); // � - string = replaceNoCase(string,chr(8250),'&##8250;','all'); // � - string = replaceNoCase(string,chr(339),'&##339;','all'); // � - string = replaceNoCase(string,chr(376),'&##376;','all'); // � - string = replaceNoCase(string,chr(376),'&##376;','all'); // � - string = replaceNoCase(string,chr(8364),'&##8364','all'); // � - return string; + var string = arguments.value; + string = replaceNoCase( + string, + chr( 8218 ), + "&##8218;", + "all" + ); // � + string = replaceNoCase( string, chr( 402 ), "&##402;", "all" ); // � + string = replaceNoCase( + string, + chr( 8222 ), + "&##8222;", + "all" + ); // � + string = replaceNoCase( + string, + chr( 8230 ), + "&##8230;", + "all" + ); // � + string = replaceNoCase( + string, + chr( 8224 ), + "&##8224;", + "all" + ); // � + string = replaceNoCase( + string, + chr( 8225 ), + "&##8225;", + "all" + ); // � + string = replaceNoCase( string, chr( 710 ), "&##710;", "all" ); // � + string = replaceNoCase( + string, + chr( 8240 ), + "&##8240;", + "all" + ); // � + string = replaceNoCase( string, chr( 352 ), "&##352;", "all" ); // � + string = replaceNoCase( + string, + chr( 8249 ), + "&##8249;", + "all" + ); // � + string = replaceNoCase( string, chr( 338 ), "&##338;", "all" ); // � + string = replaceNoCase( + string, + chr( 8216 ), + "&##8216;", + "all" + ); // � + string = replaceNoCase( + string, + chr( 8217 ), + "&##8217;", + "all" + ); // � + string = replaceNoCase( + string, + chr( 8220 ), + "&##8220;", + "all" + ); // � + string = replaceNoCase( + string, + chr( 8221 ), + "&##8221;", + "all" + ); // � + string = replaceNoCase( + string, + chr( 8226 ), + "&##8226;", + "all" + ); // � + string = replaceNoCase( + string, + chr( 8211 ), + "&##8211;", + "all" + ); // � + string = replaceNoCase( + string, + chr( 8212 ), + "&##8212;", + "all" + ); // � + string = replaceNoCase( string, chr( 732 ), "&##732;", "all" ); // � + string = replaceNoCase( + string, + chr( 8482 ), + "&##8482;", + "all" + ); // � + string = replaceNoCase( string, chr( 353 ), "&##353;", "all" ); // � + string = replaceNoCase( + string, + chr( 8250 ), + "&##8250;", + "all" + ); // � + string = replaceNoCase( string, chr( 339 ), "&##339;", "all" ); // � + string = replaceNoCase( string, chr( 376 ), "&##376;", "all" ); // � + string = replaceNoCase( string, chr( 376 ), "&##376;", "all" ); // � + string = replaceNoCase( + string, + chr( 8364 ), + "&##8364", + "all" + ); // � + return string; - - \ No newline at end of file + diff --git a/test-harness/Application.cfc b/test-harness/Application.cfc index 19fb6bfb..dc924438 100644 --- a/test-harness/Application.cfc +++ b/test-harness/Application.cfc @@ -1,10 +1,11 @@ /** -* Copyright Since 2005 Ortus Solutions, Corp -* www.ortussolutions.com -************************************************************************************** -*/ -component{ - this.name = "A TestBox Runner Suite " & hash( getCurrentTemplatePath() ); + * Copyright Since 2005 Ortus Solutions, Corp + * www.ortussolutions.com + ************************************************************************************** + */ +component { + + this.name = "A TestBox Runner Suite " & hash( getCurrentTemplatePath() ); // any other application.cfc stuff goes below: this.sessionManagement = true; @@ -15,7 +16,7 @@ component{ // request start public boolean function onRequestStart( String targetPage ){ - return true; } -} \ No newline at end of file + +} diff --git a/test-harness/specs/BDDTest.cfc b/test-harness/specs/BDDTest.cfc index f411302d..f96857f2 100644 --- a/test-harness/specs/BDDTest.cfc +++ b/test-harness/specs/BDDTest.cfc @@ -1,107 +1,116 @@ /** -* This tests the BDD functionality in TestBox. This is CF10+, Railo4+ -*/ -component extends="testbox.system.BaseSpec"{ + * This tests the BDD functionality in TestBox. This is CF10+, Railo4+ + */ +component extends="testbox.system.BaseSpec" { -/*********************************** LIFE CYCLE Methods ***********************************/ + /*********************************** LIFE CYCLE Methods ***********************************/ function beforeAll(){ application.salvador = 1; } function afterAll(){ - structClear( application ); + structClear( application ); } -/*********************************** BDD SUITES ***********************************/ + /*********************************** BDD SUITES ***********************************/ function run(){ - - /** - * describe() starts a suite group of spec tests. - * Arguments: - * @title The title of the suite, Usually how you want to name the desired behavior - * @body A closure that will resemble the tests to execute. - * @labels The list or array of labels this suite group belongs to - * @asyncAll If you want to parallelize the execution of the defined specs in this suite group. - * @skip A flag that tells TestBox to skip this suite group from testing if true - */ + /** + * describe() starts a suite group of spec tests. + * Arguments: + * @title The title of the suite, Usually how you want to name the desired behavior + * @body A closure that will resemble the tests to execute. + * @labels The list or array of labels this suite group belongs to + * @asyncAll If you want to parallelize the execution of the defined specs in this suite group. + * @skip A flag that tells TestBox to skip this suite group from testing if true + */ describe( "A spec", function(){ - // before each spec in THIS suite group - beforeEach(function(){ + beforeEach( function(){ coldbox = 0; coldbox++; - }); - + } ); + // after each spec in THIS suite group - afterEach(function(){ + afterEach( function(){ foo = 0; - }); - - /** - * it() describes a spec to test. Usually the title is prefixed with the suite name to create an expression. - * Arguments: - * @title The title of the spec - * @spec A closure that represents the test to execute - * @labels The list or array of labels this spec belongs to - * @skip A flag that tells TestBox to skip this spec from testing if true - */ - it("is just a closure so it can contain code", function(){ + } ); + + /** + * it() describes a spec to test. Usually the title is prefixed with the suite name to create an expression. + * Arguments: + * @title The title of the spec + * @spec A closure that represents the test to execute + * @labels The list or array of labels this spec belongs to + * @skip A flag that tells TestBox to skip this spec from testing if true + */ + it( "is just a closure so it can contain code", function(){ expect( coldbox ).toBe( 1 ); - }); - + } ); + // more than 1 expectation - it("can have more than one expectation test", function(){ + it( "can have more than one expectation test", function(){ coldbox = coldbox * 8; // type checks - expect( coldbox ).toBeTypeOf( 'numeric' ); + expect( coldbox ).toBeTypeOf( "numeric" ); // dynamic type methods expect( coldbox ).toBeNumeric(); // delta ranges - expect( coldbox ).toBeCloseTo( expected=10, delta=2 ); + expect( coldbox ).toBeCloseTo( expected = 10, delta = 2 ); // negations expect( coldbox ).notToBe( 4 ); - }); + } ); // negations - it("can have negative expectations", function(){ + it( "can have negative expectations", function(){ coldbox = coldbox * 8; // type checks - expect( coldbox ).notToBeTypeOf( 'usdate' ); + expect( coldbox ).notToBeTypeOf( "usdate" ); // dynamic type methods expect( coldbox ).notToBeArray(); // delta ranges - expect( coldbox ).notToBeCloseTo( expected=10, delta=2 ); - }); - + expect( coldbox ).notToBeCloseTo( expected = 10, delta = 2 ); + } ); + // xit() skips - xit("can have tests that can be skipped easily like this one", function(){ - fail( "xit() this should skip" ); - }); - + xit( "can have tests that can be skipped easily like this one", function(){ + fail( "xit() this should skip" ); + } ); + // acf dynamic skips - it( title="can have tests that execute if the right environment exists (railo only)", body=function(){ - expect( server ).toHaveKey( "railo" ); - }, skip=( !isRailo() )); + it( + title = "can have tests that execute if the right environment exists (railo only)", + body = function(){ + expect( server ).toHaveKey( "railo" ); + }, + skip = ( !isRailo() ) + ); // railo dynamic skips - it( title="can have tests that execute if the right environment exists (acf only)", body=function(){ - expect( server ).notToHaveKey( "railo" ); - }, skip=( isRailo() )); - - // specs with a random skip closure - it(title="can have a skip that is executed at runtime", body=function(){ - fail( "Skipped programmatically, this should fail" ); - },skip=function(){ return true; }); - - }); - + it( + title = "can have tests that execute if the right environment exists (acf only)", + body = function(){ + expect( server ).notToHaveKey( "railo" ); + }, + skip = ( isRailo() ) + ); + // specs with a random skip closure + it( + title = "can have a skip that is executed at runtime", + body = function(){ + fail( "Skipped programmatically, this should fail" ); + }, + skip = function(){ + return true; + } + ); + } ); } private function isRailo(){ return ( structKeyExists( server, "railo" ) ); } -} \ No newline at end of file +} diff --git a/tests/specs/AssertionsTest.cfc b/tests/specs/AssertionsTest.cfc index ed0e7845..b92ecfed 100644 --- a/tests/specs/AssertionsTest.cfc +++ b/tests/specs/AssertionsTest.cfc @@ -1,15 +1,19 @@ -component displayName="TestBox xUnit suite for cf10 and above" labels="lucee,cf" extends="Assertionscf9Test"{ +component + displayName="TestBox xUnit suite for cf10 and above" + labels ="lucee,cf" + extends ="Assertionscf9Test" +{ function beforeTests(){ super.beforeTests(); - addAssertions({ - isAwesome = function( required expected ){ - return ( arguments.expected == "Luis Majano" ? true : fail( 'not luis majano' ) ); + addAssertions( { + isAwesome : function( required expected ){ + return ( arguments.expected == "Luis Majano" ? true : fail( "not luis majano" ) ); }, - isNotAwesome = function( required expected ){ - return ( arguments.expected == "Luis Majano" ? fail( 'luis majano is always awesome' ) : true ); + isNotAwesome : function( required expected ){ + return ( arguments.expected == "Luis Majano" ? fail( "luis majano is always awesome" ) : true ); } - }); + } ); } function testFloatingPointNumberAddition(){ @@ -20,33 +24,40 @@ component displayName="TestBox xUnit suite for cf10 and above" labels="lucee,cf" } function testThrows(){ - $assert.throws(function(){ + $assert.throws( function(){ var hello = invalidFunction(); - }); + } ); } function testNotThrows(){ - $assert.notThrows(function(){ + $assert.notThrows( function(){ var hello = 1; - }); + } ); } function testThrowsDoesNotIgnoreTypeWhenRegexMatches(){ var message = "exception_message"; - var target = function() { - throw(type="actual_type", message=message); + var target = function(){ + throw( type = "actual_type", message = message ); }; var assertionFailed = false; try { - $assert.throws(target=target, type="expected_type", regex=message); // regex matches the exception message, but type does not - } catch (any e) { + $assert.throws( + target = target, + type = "expected_type", + regex = message + ); // regex matches the exception message, but type does not + } catch ( any e ) { assertionFailed = true; } - $assert.isTrue(assertionFailed, "$assert.throws() was expected to fail because the expected type ('excpected_type') did not match the actual type ('actual_type')"); + $assert.isTrue( + assertionFailed, + "$assert.throws() was expected to fail because the expected type ('excpected_type') did not match the actual type ('actual_type')" + ); } function testAwesomeCustomAssertion(){ @@ -60,8 +71,9 @@ component displayName="TestBox xUnit suite for cf10 and above" labels="lucee,cf" function testIsEmptyFunctions(){ $assert.throws( function(){ $assert.isEmpty( variables.beforeTests ); - $assert.isEmpty( function(){} ); + $assert.isEmpty( function(){ + } ); } ); } -} \ No newline at end of file +} diff --git a/tests/specs/Assertionscf9Test.cfc b/tests/specs/Assertionscf9Test.cfc index 9d336b8b..6cd2d386 100644 --- a/tests/specs/Assertionscf9Test.cfc +++ b/tests/specs/Assertionscf9Test.cfc @@ -1,6 +1,10 @@ -component displayName="TestBox xUnit suite for CF9" labels="lucee,cf" extends="testbox.system.BaseSpec"{ +component + displayName="TestBox xUnit suite for CF9" + labels ="lucee,cf" + extends ="testbox.system.BaseSpec" +{ -/*********************************** LIFE CYCLE Methods ***********************************/ + /*********************************** LIFE CYCLE Methods ***********************************/ function beforeTests(){ application.salvador = 1; @@ -18,48 +22,52 @@ component displayName="TestBox xUnit suite for CF9" labels="lucee,cf" extends="t structDelete( request, "foo" ); } -/*********************************** Test Methods ***********************************/ + /*********************************** Test Methods ***********************************/ - any function testFloatingPointNumberAddition() output="false" { + any function testFloatingPointNumberAddition() output="false"{ var sum = 196.4 + 196.4 + 180.8 + 196.4 + 196.4 + 180.8 + 609.6; // sum.toString() outputs: 1756.8000000000002 - //debug( sum ); - //$assert.isEqual( sum, 1756.8 ); + // debug( sum ); + // $assert.isEqual( sum, 1756.8 ); } function testIncludes(){ $assert.includes( "hello", "HE" ); - $assert.includes( [ "Monday", "Tuesday" ] , "monday" ); + $assert.includes( [ "Monday", "Tuesday" ], "monday" ); } function testIncludesWithCase(){ $assert.includesWithCase( "hello", "he" ); - $assert.includesWithCase( [ "Monday", "Tuesday" ] , "Monday" ); + $assert.includesWithCase( [ "Monday", "Tuesday" ], "Monday" ); } function testnotIncludesWithCase(){ $assert.notincludesWithCase( "hello", "aa" ); - $assert.notincludesWithCase( [ "Monday", "Tuesday" ] , "monday" ); + $assert.notincludesWithCase( [ "Monday", "Tuesday" ], "monday" ); } function testNotIncludes(){ $assert.notIncludes( "hello", "what" ); - $assert.notIncludes( [ "Monday", "Tuesday" ] , "Friday" ); + $assert.notIncludes( [ "Monday", "Tuesday" ], "Friday" ); } function testIsEmpty(){ $assert.isEmpty( [] ); $assert.isEmpty( {} ); $assert.isEmpty( "" ); - $assert.isEmpty( queryNew("") ); + $assert.isEmpty( queryNew( "" ) ); } function testIsNotEmpty(){ - $assert.isNotEmpty( [1,2] ); - $assert.isNotEmpty( {name="luis"} ); + $assert.isNotEmpty( [ 1, 2 ] ); + $assert.isNotEmpty( { name : "luis" } ); $assert.isNotEmpty( "HelloLuis" ); - $assert.isNotEmpty( querySim( "id, name - 1 | luis") ); + $assert.isNotEmpty( + querySim( + "id, name + 1 | luis" + ) + ); } function testSkipped() skip{ @@ -71,136 +79,155 @@ component displayName="TestBox xUnit suite for CF9" labels="lucee,cf" extends="t } function testThatShouldFail(){ - try{ + try { $assert.fail( "This Test should fail" ); - } - catch(Any e){ + } catch ( Any e ) { // should get here } } function testThatShouldFailWithShortcut(){ - try{ + try { fail( "This Test should fail" ); - } - catch(Any e){ + } catch ( Any e ) { // should get here } } - function testAssert() { + function testAssert(){ $assert.assert( application.salvador == 1 ); } - function testAssertShortcut() { + function testAssertShortcut(){ assert( application.salvador == 1 ); } - function testisTrue() { + function testisTrue(){ $assert.isTrue( 1 ); } - function testisFalse() { + function testisFalse(){ $assert.isFalse( 0 ); } // Used in testIsEqual() - function f1(){} - + function f1(){ + } - function testisEqual() { - var query = queryNew(""); - queryAddColumn(query, "id", [1,2,3,4]); - queryAddColumn(query, "data", ["tahi","rua","toru", "wha"]); - struct = {query=query}; - $assert.isEqual(struct, duplicate(struct)); + function testisEqual(){ + var query = queryNew( "" ); + queryAddColumn( query, "id", [ 1, 2, 3, 4 ] ); + queryAddColumn( + query, + "data", + [ "tahi", "rua", "toru", "wha" ] + ); + struct = { query : query }; + $assert.isEqual( struct, duplicate( struct ) ); $assert.isEqual( - [1,12], // strings - [1*1, 1*12] // doubles + [ 1, 12 ], // strings + [ 1 * 1, 1 * 12 ] // doubles ); - $assert.isEqual(f1, f1); + $assert.isEqual( f1, f1 ); $assert.isEqual( new testbox.system.MockBox(), new testbox.system.MockBox() ); - var xmlString = ''; - $assert.isEqual( XMLParse(xmlString), XMLParse(xmlString) ); + var xmlString = ""; + $assert.isEqual( xmlParse( xmlString ), xmlParse( xmlString ) ); $assert.isEqual( 0, 0 ); $assert.isEqual( "hello", "HEllO" ); $assert.isEqual( [], [] ); - $assert.isEqual( [1,2,3, {name="hello", test="this"} ], [1,2,3, {test="this", name="hello"} ] ); + $assert.isEqual( + [ + 1, + 2, + 3, + { name : "hello", test : "this" } + ], + [ + 1, + 2, + 3, + { test : "this", name : "hello" } + ] + ); } - function testIsEqualQuery() { - - var a = ''; - var b = ''; - var testQuery = queryNew("column_a,column_b"); - queryAddRow(testQuery); - querySetCell(testQuery,'column_a','1'); - querySetCell(testQuery,'column_b','2'); + function testIsEqualQuery(){ + var a = ""; + var b = ""; + var testQuery = queryNew( "column_a,column_b" ); + queryAddRow( testQuery ); + querySetCell( testQuery, "column_a", "1" ); + querySetCell( testQuery, "column_b", "2" ); a = new Query( - sql = "SELECT column_a ,column_b + sql = "SELECT column_a ,column_b FROM testQuery", - dbtype = "query", - testQuery = testQuery - ).execute().getResult(); + dbtype = "query", + testQuery = testQuery + ).execute().getResult(); b = new Query( - sql = "SELECT column_b ,column_a + sql = "SELECT column_b ,column_a FROM testQuery", - dbtype = "query", - testQuery = testQuery - ).execute().getResult(); + dbtype = "query", + testQuery = testQuery + ).execute().getResult(); - $assert.isEqual(a, b); + $assert.isEqual( a, b ); } - function testisNotEqual() { + function testisNotEqual(){ $assert.isNotEqual( this, new testbox.system.MockBox() ); $assert.isNotEqual( "hello", "test" ); $assert.isNotEqual( 1, 2 ); - $assert.isNotEqual( [], [1,3] ); + $assert.isNotEqual( [], [ 1, 3 ] ); } - function testisEqualWithCase() { + function testisEqualWithCase(){ $assert.isEqualWithCase( "hello", "hello" ); } - function testnullValue() { - $assert.null( javaCast("null", "") ); + function testnullValue(){ + $assert.null( javacast( "null", "" ) ); } - function testNotNullValue() { + function testNotNullValue(){ $assert.notNull( 44 ); } - function testTypeOf() { - $assert.typeOf( "array", [ 1,2 ] ); + function testTypeOf(){ + $assert.typeOf( "array", [ 1, 2 ] ); $assert.typeOf( "boolean", false ); $assert.typeOf( "component", this ); $assert.typeOf( "date", now() ); - $assert.typeOf( "time", timeformat( now() ) ); + $assert.typeOf( "time", timeFormat( now() ) ); $assert.typeOf( "float", 1.1 ); $assert.typeOf( "numeric", 1 ); - $assert.typeOf( "query", querySim( "id, name - 1 | luis") ); + $assert.typeOf( + "query", + querySim( + "id, name + 1 | luis" + ) + ); $assert.typeOf( "string", "hello string" ); - $assert.typeOf( "struct", { name="luis", awesome=true } ); + $assert.typeOf( "struct", { name : "luis", awesome : true } ); $assert.typeOf( "uuid", createUUID() ); $assert.typeOf( "url", "https://www.coldbox.org" ); } - function testNotTypeOf() { + function testNotTypeOf(){ $assert.notTypeOf( "array", 1 ); $assert.notTypeOf( "boolean", "hello" ); $assert.notTypeOf( "component", {} ); $assert.notTypeOf( "date", "monday" ); - $assert.notTypeOf( "time", "1"); + $assert.notTypeOf( "time", "1" ); $assert.notTypeOf( "float", "Hello" ); $assert.notTypeOf( "numeric", "eeww2" ); $assert.notTypeOf( "query", [] ); @@ -210,11 +237,11 @@ component displayName="TestBox xUnit suite for CF9" labels="lucee,cf" extends="t $assert.notTypeOf( "url", "coldbox" ); } - function testInstanceOf() { + function testInstanceOf(){ $assert.instanceOf( new testbox.system.MockBox(), "testbox.system.MockBox" ); } - function testNotInstanceOf() { + function testNotInstanceOf(){ $assert.notInstanceOf( this, "testbox.system.MockBox" ); } @@ -235,78 +262,107 @@ component displayName="TestBox xUnit suite for CF9" labels="lucee,cf" extends="t } function testKey(){ - $assert.key( {name="luis", awesome=true}, "awesome" ); + $assert.key( { name : "luis", awesome : true }, "awesome" ); } function testNotKey(){ - $assert.notKey( {name="luis", awesome=true}, "test" ); + $assert.notKey( { name : "luis", awesome : true }, "test" ); } function testDeepKey(){ - $assert.deepKey( {name="luis", awesome=true, parent = { age=70 } }, "age" ); + $assert.deepKey( + { + name : "luis", + awesome : true, + parent : { age : 70 } + }, + "age" + ); } function testNotDeepKey(){ - $assert.notDeepKey( {name="luis", awesome=true, parent = { age=70 } }, "luis" ); + $assert.notDeepKey( + { + name : "luis", + awesome : true, + parent : { age : 70 } + }, + "luis" + ); } function testLengthOf(){ $assert.lengthOf( "heelo", 5 ); - $assert.lengthOf( [1,2], 2 ); - $assert.lengthOf( {name="luis"}, 1 ); - $assert.lengthOf( querySim( "id, name - 1 | luis"), 1 ); - + $assert.lengthOf( [ 1, 2 ], 2 ); + $assert.lengthOf( { name : "luis" }, 1 ); + $assert.lengthOf( + querySim( + "id, name + 1 | luis" + ), + 1 + ); } function testNotLengthOf(){ $assert.notLengthOf( "heelo", 3 ); - $assert.notLengthOf( [1,2], 5 ); - $assert.notLengthOf( {name="luis"}, 5 ); - $assert.notLengthOf( querySim( "id, name - 1 | luis"), 0 ); + $assert.notLengthOf( [ 1, 2 ], 5 ); + $assert.notLengthOf( { name : "luis" }, 5 ); + $assert.notLengthOf( + querySim( + "id, name + 1 | luis" + ), + 0 + ); } /** - * @expectedException - */ + * @expectedException + */ function testExpectedExceptionNoValue(){ // This method should throw an invalid exception and pass - throw( type="InvalidException", message="This test method should pass with an expected exception" ); + throw( type = "InvalidException", message = "This test method should pass with an expected exception" ); } /** - * @expectedException InvalidException - */ + * @expectedException InvalidException + */ function testExpectedExceptionWithValue(){ // This method should throw an invalid exception and pass - throw( type="InvalidException", message="This test method should pass with an expected exception of type InvalidException" ); + throw( + type = "InvalidException", + message = "This test method should pass with an expected exception of type InvalidException" + ); } /** - * @expectedException InvalidException:(pass with an) - */ + * @expectedException InvalidException:(pass with an) + */ function testExpectedExceptionWithValueAndRegex(){ // This method should throw an invalid exception and pass - throw( type="InvalidException", message="This test method should pass with an expected exception of type InvalidException" ); + throw( + type = "InvalidException", + message = "This test method should pass with an expected exception of type InvalidException" + ); } function testExpectedExceptionFromMethod(){ expectedException(); // This method should throw an invalid exception and pass - throw( type="InvalidException", message="This test method should pass with an expected exception" ); + throw( type = "InvalidException", message = "This test method should pass with an expected exception" ); } function testExpectedExceptionFromMethodWithType(){ expectedException( "InvalidException" ); // This method should throw an invalid exception and pass - throw( type="InvalidException", message="This test method should pass with an expected exception" ); + throw( type = "InvalidException", message = "This test method should pass with an expected exception" ); } function testExpectedExceptionFromMethodWithTypeAndRegex(){ expectedException( "InvalidException", "(pass with an)" ); // This method should throw an invalid exception and pass - throw( type="InvalidException", message="This test method should pass with an expected exception" ); + throw( type = "InvalidException", message = "This test method should pass with an expected exception" ); } function testIsGT(){ @@ -333,14 +389,14 @@ component displayName="TestBox xUnit suite for CF9" labels="lucee,cf" extends="t $assert.isLTE( 5, 10 ); } -/*********************************** NON-RUNNABLE Methods ***********************************/ + /*********************************** NON-RUNNABLE Methods ***********************************/ - function nonStandardNamesWillNotRun() { + function nonStandardNamesWillNotRun(){ fail( "Non-test methods should not run" ); } - private function privateMethodsDontRun() { + private function privateMethodsDontRun(){ fail( "Private method don't run" ); } -} \ No newline at end of file +} diff --git a/tests/specs/BDDInheritanceTest.cfc b/tests/specs/BDDInheritanceTest.cfc index b1d5598e..0652cc6a 100644 --- a/tests/specs/BDDInheritanceTest.cfc +++ b/tests/specs/BDDInheritanceTest.cfc @@ -1,9 +1,9 @@ /** -* This tests the BDD functionality in TestBox. -*/ -component extends="testbox.system.BaseSpec"{ + * This tests the BDD functionality in TestBox. + */ +component extends="testbox.system.BaseSpec" { -/*********************************** LIFE CYCLE Methods ***********************************/ + /*********************************** LIFE CYCLE Methods ***********************************/ function beforeAll(){ application.salvador = 1; @@ -13,91 +13,100 @@ component extends="testbox.system.BaseSpec"{ structClear( application ); } -/*********************************** BDD SUITES ***********************************/ + /*********************************** BDD SUITES ***********************************/ function run(){ - /** - * describe() starts a suite group of spec tests. - * Arguments: - * @title The title of the suite, Usually how you want to name the desired behavior - * @body A closure that will resemble the tests to execute. - * @labels The list or array of labels this suite group belongs to - * @asyncAll If you want to parallelize the execution of the defined specs in this suite group. - * @skip A flag that tells TestBox to skip this suite group from testing if true - */ + * describe() starts a suite group of spec tests. + * Arguments: + * @title The title of the suite, Usually how you want to name the desired behavior + * @body A closure that will resemble the tests to execute. + * @labels The list or array of labels this suite group belongs to + * @asyncAll If you want to parallelize the execution of the defined specs in this suite group. + * @skip A flag that tells TestBox to skip this suite group from testing if true + */ describe( "A spec", function(){ - // before each spec in THIS suite group - beforeEach(function(){ + beforeEach( function(){ coldbox = 0; coldbox++; - }); + } ); // after each spec in THIS suite group - afterEach(function(){ + afterEach( function(){ foo = 0; - }); + } ); /** - * it() describes a spec to test. Usually the title is prefixed with the suite name to create an expression. - * Arguments: - * @title The title of the spec - * @spec A closure that represents the test to execute - * @labels The list or array of labels this spec belongs to - * @skip A flag that tells TestBox to skip this spec from testing if true - */ - it("is just a closure so it can contain code", function(){ + * it() describes a spec to test. Usually the title is prefixed with the suite name to create an expression. + * Arguments: + * @title The title of the spec + * @spec A closure that represents the test to execute + * @labels The list or array of labels this spec belongs to + * @skip A flag that tells TestBox to skip this spec from testing if true + */ + it( "is just a closure so it can contain code", function(){ expect( coldbox ).toBe( 1 ); - }); + } ); // more than 1 expectation - it("can have more than one expectation test", function(){ + it( "can have more than one expectation test", function(){ coldbox = coldbox * 8; // type checks - expect( coldbox ).toBeTypeOf( 'numeric' ); + expect( coldbox ).toBeTypeOf( "numeric" ); // dynamic type methods expect( coldbox ).toBeNumeric(); // delta ranges - expect( coldbox ).toBeCloseTo( expected=10, delta=2 ); + expect( coldbox ).toBeCloseTo( expected = 10, delta = 2 ); // negations expect( coldbox ).notToBe( 4 ); - }); + } ); // negations - it("can have negative expectations", function(){ + it( "can have negative expectations", function(){ coldbox = coldbox * 8; // type checks - expect( coldbox ).notToBeTypeOf( 'usdate' ); + expect( coldbox ).notToBeTypeOf( "usdate" ); // dynamic type methods expect( coldbox ).notToBeArray(); // delta ranges - expect( coldbox ).notToBeCloseTo( expected=10, delta=2 ); - }); + expect( coldbox ).notToBeCloseTo( expected = 10, delta = 2 ); + } ); // xit() skips - xit("can have tests that can be skipped easily like this one", function(){ + xit( "can have tests that can be skipped easily like this one", function(){ fail( "xit() this should skip" ); - }); + } ); // acf dynamic skips - it( title="can have tests that execute if the right environment exists (Lucee only)", body=function(){ - expect( server ).toHaveKey( "Lucee" ); - }, skip=( !isLucee() )); + it( + title = "can have tests that execute if the right environment exists (Lucee only)", + body = function(){ + expect( server ).toHaveKey( "Lucee" ); + }, + skip = ( !isLucee() ) + ); // Lucee dynamic skips - it( title="can have tests that execute if the right environment exists (acf only)", body=function(){ - expect( server ).notToHaveKey( "Lucee" ); - }, skip=( isLucee() )); + it( + title = "can have tests that execute if the right environment exists (acf only)", + body = function(){ + expect( server ).notToHaveKey( "Lucee" ); + }, + skip = ( isLucee() ) + ); // specs with a random skip closure - it(title="can have a skip that is executed at runtime", body=function(){ - fail( "Skipped programmatically, this should fail" ); - },skip=function(){ return true; }); - - }); - - + it( + title = "can have a skip that is executed at runtime", + body = function(){ + fail( "Skipped programmatically, this should fail" ); + }, + skip = function(){ + return true; + } + ); + } ); } private function isLucee(){ diff --git a/tests/specs/BDDLifecycleAnnotationsTest.cfc b/tests/specs/BDDLifecycleAnnotationsTest.cfc index 6a649c52..960a4090 100644 --- a/tests/specs/BDDLifecycleAnnotationsTest.cfc +++ b/tests/specs/BDDLifecycleAnnotationsTest.cfc @@ -1,9 +1,9 @@ /** -* This tests the BDD functionality in TestBox. -*/ -component extends="tests.utils.ExampleParentTestCase"{ + * This tests the BDD functionality in TestBox. + */ +component extends="tests.utils.ExampleParentTestCase" { -/*********************************** LIFE CYCLE Methods ***********************************/ + /*********************************** LIFE CYCLE Methods ***********************************/ function beforeAll(){ variables.counter = 0; @@ -22,29 +22,24 @@ component extends="tests.utils.ExampleParentTestCase"{ arguments.spec.body(); } -/*********************************** BDD SUITES ***********************************/ + /*********************************** BDD SUITES ***********************************/ function run(){ - describe( "Lifecycle annotations", function(){ - - it("runs lifecycle annotation hooks just as if they were in the suite", function(){ + it( "runs lifecycle annotation hooks just as if they were in the suite", function(){ expect( variables.counter ).toBe( 4 ); - }); + } ); - describe( "Lifecycle Annotation Hooks with normal Lifecycle Methods", function() { - beforeEach(function() { + describe( "Lifecycle Annotation Hooks with normal Lifecycle Methods", function(){ + beforeEach( function(){ variables.counter++; - }); + } ); - it("runs both types of methods", function() { + it( "runs both types of methods", function(){ expect( variables.counter ).toBe( 8 ); - }); - }); - - }); - - + } ); + } ); + } ); } } diff --git a/tests/specs/BDDLifecycleTest.cfc b/tests/specs/BDDLifecycleTest.cfc index 5888ad13..fe36976b 100644 --- a/tests/specs/BDDLifecycleTest.cfc +++ b/tests/specs/BDDLifecycleTest.cfc @@ -1,84 +1,74 @@ /** -* This tests the BDD functionality in TestBox. -*/ -component extends="testbox.system.BaseSpec"{ + * This tests the BDD functionality in TestBox. + */ +component extends="testbox.system.BaseSpec" { -/*********************************** LIFE CYCLE Methods ***********************************/ + /*********************************** LIFE CYCLE Methods ***********************************/ function beforeAll(){ coldbox = 0; } function afterAll(){ - } -/*********************************** BDD SUITES ***********************************/ + /*********************************** BDD SUITES ***********************************/ function run(){ - describe( "A suite", function(){ - // before each spec in THIS suite group - beforeEach(function( currentSpec ){ + beforeEach( function( currentSpec ){ coldbox++; debug( "beforeEach (A Suite) #arguments.currentSpec#" ); - }); + } ); // after each spec in THIS suite group - afterEach(function( currentSpec ){ + afterEach( function( currentSpec ){ debug( "afterEach (A Suite) #arguments.currentSpec#: coldbox = #coldbox#" ); - }); + } ); // around each spec in THIS suite group - aroundEach(function( spec ){ + aroundEach( function( spec ){ debug( "aroundEach (A Suite) #arguments.spec.name#" ); // execute the spec manually now, we can decorate things here too. spec.body(); - }); + } ); - it("before should be 1", function(){ + it( "before should be 1", function(){ expect( coldbox ).toBe( 1 ); - }); + } ); describe( "A nested suite", function(){ - // before each spec in THIS suite group - beforeEach(function( currentSpec ){ + beforeEach( function( currentSpec ){ coldbox = coldbox * 2; debug( "beforeEach (A nested suite) #arguments.currentSpec#: coldbox = #coldbox#" ); - }); + } ); // around each spec in THIS suite group - aroundEach(function( spec ){ + aroundEach( function( spec ){ debug( "aroundEach (A nested suite) #arguments.spec.name#" ); // execute the spec manually now, we can decorate things here too. spec.body(); - }); + } ); it( "before should be 4", function(){ - expect( coldbox ).toBe( 4 ); - }); + expect( coldbox ).toBe( 4 ); + } ); describe( "Another nested suite", function(){ // before each spec in THIS suite group - beforeEach(function( currentSpec ){ + beforeEach( function( currentSpec ){ coldbox++; debug( "beforeEach (Another nested suite) #arguments.currentSpec#: coldbox = #coldbox#" ); - }); + } ); it( "before should be 11", function(){ - expect( coldbox ).toBe( 11 ); - }); - }); - - }); - - - }); - - - + expect( coldbox ).toBe( 11 ); + } ); + } ); + } ); + } ); } -} \ No newline at end of file +} diff --git a/tests/specs/BDDTest.cfc b/tests/specs/BDDTest.cfc index 888858ed..276d204a 100644 --- a/tests/specs/BDDTest.cfc +++ b/tests/specs/BDDTest.cfc @@ -1,9 +1,9 @@ /** -* This tests the BDD functionality in TestBox. -*/ -component extends="testbox.system.BaseSpec"{ + * This tests the BDD functionality in TestBox. + */ +component extends="testbox.system.BaseSpec" { -/*********************************** LIFE CYCLE Methods ***********************************/ + /*********************************** LIFE CYCLE Methods ***********************************/ function beforeAll(){ // print( "

BDD Testing is Awesome!

" ); @@ -16,336 +16,348 @@ component extends="testbox.system.BaseSpec"{ structClear( application ); } -/*********************************** BDD SUITES ***********************************/ + /*********************************** BDD SUITES ***********************************/ function run(){ - /** - * describe() starts a suite group of spec tests. - * Arguments: - * @title The title of the suite, Usually how you want to name the desired behavior - * @body A closure that will resemble the tests to execute. - * @labels The list or array of labels this suite group belongs to - * @asyncAll If you want to parallelize the execution of the defined specs in this suite group. - * @skip A flag that tells TestBox to skip this suite group from testing if true - */ - describe( title="A spec", labels="luis", body=function(){ + * describe() starts a suite group of spec tests. + * Arguments: + * @title The title of the suite, Usually how you want to name the desired behavior + * @body A closure that will resemble the tests to execute. + * @labels The list or array of labels this suite group belongs to + * @asyncAll If you want to parallelize the execution of the defined specs in this suite group. + * @skip A flag that tells TestBox to skip this suite group from testing if true + */ + describe( + title = "A spec", + labels = "luis", + body = function(){ + // before each spec in THIS suite group + beforeEach( function(){ + coldbox = 0; + coldbox++; + debug( "beforeEach suite: coldbox = #coldbox#" ); + } ); + + // after each spec in THIS suite group + afterEach( function(){ + foo = 0; + } ); + + + it( "can match strings with no case sensitivity", function(){ + expect( "Luis" ).toMatch( "^luis" ); + } ); + it( "can match strings with case sensitivity", function(){ + expect( "Luis" ).notToMatchWithCase( "^luis" ); + expect( "luis" ).ToMatchWithCase( "^luis" ); + } ); + + /** + * it() describes a spec to test. Usually the title is prefixed with the suite name to create an expression. + * Arguments: + * @title The title of the spec + * @spec A closure that represents the test to execute + * @labels The list or array of labels this spec belongs to + * @skip A flag that tells TestBox to skip this spec from testing if true + */ + it( + title = "is just a closure so it can contain code", + body = function(){ + expect( coldbox ).toBe( 1 ); + }, + labels = "luis" + ); - // before each spec in THIS suite group - beforeEach(function(){ - coldbox = 0; - coldbox++; - debug( "beforeEach suite: coldbox = #coldbox#" ); - }); + it( "can satisfy truth tests", function(){ + expect( 1 ).toSatisfy( function( num ){ + return arguments.num > 0; + } ); + expect( 0 ).notToSatisfy( function( num ){ + return arguments.num > 0; + } ); + } ); + + it( "can validate json", function(){ + var data = serializeJSON( { name : "luis", when : now() } ); + expect( "luis" ).notToBeJSON(); + expect( data ).toBeJSON(); + } ); + + // more than 1 expectation + it( "can have more than one expectation test", function(){ + coldbox = coldbox * 8; + // type checks + expect( coldbox ).toBeTypeOf( "numeric" ).toBeNumeric(); + // delta ranges + expect( coldbox ).toBeCloseTo( expected = 10, delta = 2 ); + // negations + expect( coldbox ).notToBe( 4 ); + debug( " >1 expectation tests: coldbox = #coldbox#" ); + } ); - // after each spec in THIS suite group - afterEach(function(){ - foo = 0; - }); - - - it( "can match strings with no case sensitivity", function(){ - expect( "Luis" ).toMatch( "^luis" ); - }); - it( "can match strings with case sensitivity", function(){ - expect( "Luis" ).notToMatchWithCase( "^luis" ); - expect( "luis" ).ToMatchWithCase( "^luis" ); - }); - - /** - * it() describes a spec to test. Usually the title is prefixed with the suite name to create an expression. - * Arguments: - * @title The title of the spec - * @spec A closure that represents the test to execute - * @labels The list or array of labels this spec belongs to - * @skip A flag that tells TestBox to skip this spec from testing if true - */ - it(title="is just a closure so it can contain code", body=function(){ - expect( coldbox ).toBe( 1 ); - },labels="luis"); - - it( "can satisfy truth tests", function(){ - expect( 1 ).toSatisfy( function( num ){ return arguments.num > 0; } ); - expect( 0 ).notToSatisfy( function( num ){ return arguments.num > 0; } ); - }); - - it( "can validate json", function(){ - var data = serializeJSON( { name = "luis", when = now() } ); - expect( "luis" ).notToBeJSON(); - expect( data ).toBeJSON(); - }); - - // more than 1 expectation - it("can have more than one expectation test", function(){ - coldbox = coldbox * 8; - // type checks - expect( coldbox ) - .toBeTypeOf( 'numeric' ) - .toBeNumeric(); - // delta ranges - expect( coldbox ).toBeCloseTo( expected=10, delta=2 ); // negations - expect( coldbox ).notToBe( 4 ); - debug( " >1 expectation tests: coldbox = #coldbox#" ); - }); - - // negations - it("can have negative expectations", function(){ - coldbox = coldbox * 8; - // type checks - expect( coldbox ).notToBeTypeOf( 'usdate' ); - // dynamic type methods - expect( coldbox ).notToBeArray(); - // delta ranges - expect( coldbox ).notToBeCloseTo( expected=10, delta=2 ); - }); - - it( "can get private properties", function(){ - var oTest = new testbox.tests.resources.Test(); - expect( getProperty( oTest, "reload" ) ).toBeFalse(); - }); - - // xit() skips - xit("can have tests that can be skipped easily like this one", function(){ - fail( "xit() this should skip" ); - }); - - // acf dynamic skips - it( title="can have tests that execute if the right environment exists (Lucee only)", body=function(){ - expect( server ).toHaveKey( "Lucee" ); - }, skip=( !isLucee() )); - - // Lucee dynamic skips - it( title="can have tests that execute if the right environment exists (acf only)", body=function(){ - expect( server ).notToHaveKey( "Lucee" ); - }, skip=( isLucee() )); - - // specs with a random skip closure - it(title="can have a skip that is executed at runtime", body=function(){ - fail( "Skipped programmatically, this should fail" ); - },skip=function(){ return true; }); - - // null expectations - it( "can have null expectations", function(){ - expect( javaCast("null", "") ).toBeNull(); - expect( 123 ).notToBeNull(); - }); - - // discrete math - it( "can have discrete math", function(){ - expect( "d" ).toBeGT( "c" ); - expect( 4 ).toBeGT( 1 ); - - expect( 4 ).toBeGTE( 4 ); - expect( 1 ).toBeLT( 10 ); - expect( 10 ).toBeLTE( 10 ); - }); - - it( "can test a collection", function(){ - expectAll( [ 2, 4, 6, 8] ).toSatisfy( function(x){ return 0 == x%2; } ); - expectAll( { a:2, b:4, c:6} ).toSatisfy( function(x){ return 0 == x%2; } ); - // and we can chain matchers - expectAll( [ 2, 4, 6, 8 ] ) - .toBeGTE( 2 ) - .toBeLTE( 8 ); - }); - - it( "can fail any element of a collection", function() { - try{ - // we need to verify the expectation fails - expectAll( [2,4,10,8] ).toBeLT( 10 ); - fail( "expectAll() failed to detect a bad element" ); - }catch( any e ){ - expect( e.message ).toBe( "The actual [10] is not less than [10]" ); - } - }); - - - it( "can process structure key expectations", function(){ - var s = { - "data" : {}, - "error" : {}, - "name" : {}, - "age" : 0 - }; - - expect( s ).toHaveKey( "error" ); - expect( s ).notToHaveKey( "luis" ); - - // Multiple - expect( s ).toHaveKey( "data,error,name,age" ); - expect( function(){ - expect( s ).toHaveKey( "data,error,name,age2" ); - }).toThrow(); - expect( s ).notToHaveKey( "luis,joe,tom" ); - expect( function(){ - expect( s ).toHaveKey( "luis,joe,data" ); - }).toThrow(); - }); + it( "can have negative expectations", function(){ + coldbox = coldbox * 8; + // type checks + expect( coldbox ).notToBeTypeOf( "usdate" ); + // dynamic type methods + expect( coldbox ).notToBeArray(); + // delta ranges + expect( coldbox ).notToBeCloseTo( expected = 10, delta = 2 ); + } ); + + it( "can get private properties", function(){ + var oTest = new testbox.tests.resources.Test(); + expect( getProperty( oTest, "reload" ) ).toBeFalse(); + } ); + + // xit() skips + xit( "can have tests that can be skipped easily like this one", function(){ + fail( "xit() this should skip" ); + } ); + + // acf dynamic skips + it( + title = "can have tests that execute if the right environment exists (Lucee only)", + body = function(){ + expect( server ).toHaveKey( "Lucee" ); + }, + skip = ( !isLucee() ) + ); - }); + // Lucee dynamic skips + it( + title = "can have tests that execute if the right environment exists (acf only)", + body = function(){ + expect( server ).notToHaveKey( "Lucee" ); + }, + skip = ( isLucee() ) + ); - // Custom Matchers - describe("Custom Matchers", function(){ + // specs with a random skip closure + it( + title = "can have a skip that is executed at runtime", + body = function(){ + fail( "Skipped programmatically, this should fail" ); + }, + skip = function(){ + return true; + } + ); + + // null expectations + it( "can have null expectations", function(){ + expect( javacast( "null", "" ) ).toBeNull(); + expect( 123 ).notToBeNull(); + } ); + + // discrete math + it( "can have discrete math", function(){ + expect( "d" ).toBeGT( "c" ); + expect( 4 ).toBeGT( 1 ); + + expect( 4 ).toBeGTE( 4 ); + expect( 1 ).toBeLT( 10 ); + expect( 10 ).toBeLTE( 10 ); + } ); + + it( "can test a collection", function(){ + expectAll( [ 2, 4, 6, 8 ] ).toSatisfy( function( x ){ + return 0 == x % 2; + } ); + expectAll( { a : 2, b : 4, c : 6 } ).toSatisfy( function( x ){ + return 0 == x % 2; + } ); + // and we can chain matchers + expectAll( [ 2, 4, 6, 8 ] ).toBeGTE( 2 ).toBeLTE( 8 ); + } ); + + it( "can fail any element of a collection", function(){ + try { + // we need to verify the expectation fails + expectAll( [ 2, 4, 10, 8 ] ).toBeLT( 10 ); + fail( "expectAll() failed to detect a bad element" ); + } catch ( any e ) { + expect( e.message ).toBe( "The actual [10] is not less than [10]" ); + } + } ); + + + it( "can process structure key expectations", function(){ + var s = { + "data" : {}, + "error" : {}, + "name" : {}, + "age" : 0 + }; + + expect( s ).toHaveKey( "error" ); + expect( s ).notToHaveKey( "luis" ); + + // Multiple + expect( s ).toHaveKey( "data,error,name,age" ); + expect( function(){ + expect( s ).toHaveKey( "data,error,name,age2" ); + } ).toThrow(); + expect( s ).notToHaveKey( "luis,joe,tom" ); + expect( function(){ + expect( s ).toHaveKey( "luis,joe,data" ); + } ).toThrow(); + } ); + } + ); - beforeEach(function(){ + // Custom Matchers + describe( "Custom Matchers", function(){ + beforeEach( function(){ // add custom matchers - addMatchers({ - toBeReallyFalse : function( expectation, args={} ){ - expectation.message = ( structKeyExists( args, "message" ) ? args.message : "[#expectation.actual#] is not really false" ); - if( expectation.isNot ) - return ( expectation.actual eq true ); - else - return ( expectation.actual eq false ); + addMatchers( { + toBeReallyFalse : function( expectation, args = {} ){ + expectation.message = ( + structKeyExists( args, "message" ) ? args.message : "[#expectation.actual#] is not really false" + ); + if ( expectation.isNot ) return ( expectation.actual eq true ); + else return ( expectation.actual eq false ); }, - toBeReallyTrue = function( expectation, args={} ){ - expectation.message = ( structKeyExists( args, "message" ) ? args.message : "[#expectation.actual#] is not really true" ); - if( expectation.isNot ) - return ( expectation.actual eq false ); - else - return ( expectation.actual eq true ); + toBeReallyTrue : function( expectation, args = {} ){ + expectation.message = ( + structKeyExists( args, "message" ) ? args.message : "[#expectation.actual#] is not really true" + ); + if ( expectation.isNot ) return ( expectation.actual eq false ); + else return ( expectation.actual eq true ); } - }); + } ); foo = false; - }); + } ); - it("are cool and foo should be really false", function(){ + it( "are cool and foo should be really false", function(){ expect( foo ).toBeReallyFalse(); - }); + } ); - it("are still cool and the negation of foo should be really true", function(){ + it( "are still cool and the negation of foo should be really true", function(){ expect( foo ).notToBeReallyTrue(); - }); + } ); // Custom Matchers - describe("Nested suite: Testing loading via a CFC", function(){ - - beforeEach(function(){ + describe( "Nested suite: Testing loading via a CFC", function(){ + beforeEach( function(){ // add custom matcher via CFC addMatchers( new testbox.tests.resources.CustomMatcher() ); foofoo = false; - }); + } ); - it("should be awesome", function(){ + it( "should be awesome", function(){ expect( foofoo ).toBeAwesome(); debug( " foofoo should be awesome #foofoo#" ); - }); + } ); - it("should know its maker", function(){ + it( "should know its maker", function(){ expect( "Luis Majano" ).toBeLuisMajano(); - }); + } ); - describe("Yet another nested suite", function(){ - - it("should have cascaded beforeEach() call from parent", function(){ + describe( "Yet another nested suite", function(){ + it( "should have cascaded beforeEach() call from parent", function(){ expect( foofoo ).toBeAwesome(); - }); + } ); - it("should have cascaded beforeEach() call from grandparent", function(){ + it( "should have cascaded beforeEach() call from grandparent", function(){ expect( foo ).toBeFalse(); - }); - - }); - - }); + } ); + } ); + } ); // Another suite describe( "Another Nested Suite", function(){ - it( "can also be awesome", function(){ - expect( foo ).toBeFalse(); - }); - - }); - - }); + expect( foo ).toBeFalse(); + } ); + } ); + } ); // Skip by env suite - describe(title="A Lucee only suite", body=function(){ - - it("should only execute for Lucee", function(){ - expect( server ).toHaveKey( "Lucee" ); - }); - - }, skip=( !isLucee() )); + describe( + title = "A Lucee only suite", + body = function(){ + it( "should only execute for Lucee", function(){ + expect( server ).toHaveKey( "Lucee" ); + } ); + }, + skip = ( !isLucee() ) + ); // xdescribe() skips the entire suite - xdescribe("A suite that is skipped via xdescribe()", function(){ - it("will never execute this", function(){ + xdescribe( "A suite that is skipped via xdescribe()", function(){ + it( "will never execute this", function(){ fail( "This should not have executed" ); - }); - }); + } ); + } ); - describe("A calculator test suite", function(){ + describe( "A calculator test suite", function(){ // before each spec in THIS suite group - beforeEach(function(){ + beforeEach( function(){ // using request until Lucee fixes their closure bugs request.calc = calc = new testbox.tests.resources.Calculator(); - }); + } ); // after each spec in THIS suite group - afterEach(function(){ - structdelete( variables, "calc" ); - }); + afterEach( function(){ + structDelete( variables, "calc" ); + } ); - it("Can have a separate beforeEach for this suite", function(){ + it( "Can have a separate beforeEach for this suite", function(){ expect( request.calc ).toBeComponent(); - }); + } ); - xit("can add incorrectly and fail", function(){ + xit( "can add incorrectly and fail", function(){ var r = calc.add( 2, 2 ); expect( r ).toBe( 5 ); - }); + } ); - it("cannot divide by zero", function(){ + it( "cannot divide by zero", function(){ expect( function(){ request.calc.divide( 4, 0 ); - }).toThrow( regex="zero" ); - }); + } ).toThrow( regex = "zero" ); + } ); - it("cannot divide by zero with message regex", function(){ + it( "cannot divide by zero with message regex", function(){ expect( function(){ request.calc.divide( 3, 0 ); - }).toThrow( regex="zero" ); - }); + } ).toThrow( regex = "zero" ); + } ); it( "can do throws with no message", function(){ - expect( function(){ + expect( function(){ request.calc.divideNoMessage(); - } ).toThrow( type="DivideByZero" ); - }); + } ).toThrow( type = "DivideByZero" ); + } ); it( "can do throws with message and detail regex", function(){ - expect( function(){ + expect( function(){ request.calc.divideWithDetail(); - } ).toThrow( regex="(zero|impossible)" ); + } ).toThrow( regex = "(zero|impossible)" ); - expect( function(){ + expect( function(){ request.calc.divideWithDetail(); - } ).toThrow( regex="impossible" ); - }); + } ).toThrow( regex = "impossible" ); + } ); - it("can use a mocked stub", function(){ - c = createStub().$("getData", 4); + it( "can use a mocked stub", function(){ + c = createStub().$( "getData", 4 ); r = calc.add( 4, c.getData() ); expect( r ).toBe( 8 ); - expect( c.$once( "getData") ).toBeTrue(); - }); + expect( c.$once( "getData" ) ).toBeTrue(); + } ); - xit("can produce errors", function(){ + xit( "can produce errors", function(){ exxpect(); - }); + } ); it( "can mock any type of data", function(){ - var data = mockData( - "name" : "name", - "age" : "age" - ); + var data = mockData( "name" : "name", "age" : "age" ); expect( data ).notToBeEmpty(); - }); - - }); - + } ); + } ); } private function isLucee(){ diff --git a/tests/specs/BaseTest.cfc b/tests/specs/BaseTest.cfc index 67f47161..3beb7598 100644 --- a/tests/specs/BaseTest.cfc +++ b/tests/specs/BaseTest.cfc @@ -1,7 +1,7 @@ -component extends="testbox.system.compat.framework.TestCase"{ +component extends="testbox.system.compat.framework.TestCase" { function testFromInheritance(){ - assert( true, "Inheritance call passed" ); + assert( true, "Inheritance call passed" ); } -} \ No newline at end of file +} diff --git a/tests/specs/CustomAssertions.cfc b/tests/specs/CustomAssertions.cfc index 10ffa817..bbcfabdf 100644 --- a/tests/specs/CustomAssertions.cfc +++ b/tests/specs/CustomAssertions.cfc @@ -1,14 +1,14 @@ /** -* My BDD Test -*/ -component extends="testbox.system.BaseSpec"{ + * My BDD Test + */ +component extends="testbox.system.BaseSpec" { -/*********************************** LIFE CYCLE Methods ***********************************/ + /*********************************** LIFE CYCLE Methods ***********************************/ // executes before all suites+specs in the run() method function beforeAll(){ - variables.startDate = dateAdd("m",-1,Now()); - variables.endDate = Now(); + variables.startDate = dateAdd( "m", -1, now() ); + variables.endDate = now(); addAssertions( "testbox.tests.resources.CustomAsserts" ); } @@ -17,26 +17,25 @@ component extends="testbox.system.BaseSpec"{ function afterAll(){ } -/*********************************** BDD SUITES ***********************************/ + /*********************************** BDD SUITES ***********************************/ function run(){ // all your suites go here. describe( "Custom Assertions", function(){ - it( "awesome works", function(){ $assert.assertIsAwesome( true, true ); - }); + } ); it( "funky works", function(){ $assert.assertIsFunky( 200 ); - }); + } ); it( "funky can fail", function(){ - $assert.throws( function(){ $assert.assertIsFunky( 1 ); } ); - }); - - - }); + $assert.throws( function(){ + $assert.assertIsFunky( 1 ); + } ); + } ); + } ); } -} \ No newline at end of file +} diff --git a/tests/specs/DebugTests.cfc b/tests/specs/DebugTests.cfc index c461d425..c758803f 100644 --- a/tests/specs/DebugTests.cfc +++ b/tests/specs/DebugTests.cfc @@ -1,9 +1,9 @@ /** -* My BDD Test -*/ -component extends="testbox.system.BaseSpec"{ + * My BDD Test + */ +component extends="testbox.system.BaseSpec" { -/*********************************** LIFE CYCLE Methods ***********************************/ + /*********************************** LIFE CYCLE Methods ***********************************/ // executes before all suites+specs in the run() method function beforeAll(){ @@ -13,41 +13,45 @@ component extends="testbox.system.BaseSpec"{ function afterAll(){ } -/*********************************** BDD SUITES ***********************************/ + /*********************************** BDD SUITES ***********************************/ function run(){ // all your suites go here. - describe( title="Debug", body=function(){ - - it( "can have custom labels", function(){ - debug( var=[1,2,3,4], label="My Custom Label" ); - var buffer = getDebugBuffer(); - expect( buffer[ 1 ].label ).toBe( "My Custom Label" ); - }); - - it( "can have generic labels", function(){ - debug( var=[1,2,3,4] ); - var buffer = getDebugBuffer(); - expect( buffer[ 2 ].label ).toBe( "/Debug/can have generic labels" ); - }); - - it( "can do top functionality", function(){ - var nested = [ - 1, 2, 3, 4, - [ 1, 2, 3, 4, [ 1, 2, 3, 4 ] ] - ]; - debug( var=nested, top=1 ); - }); - - describe( "another Suite", function(){ - it( "can have generic labels too", function(){ - debug( var=[1,2,3,4] ); + describe( + title = "Debug", + body = function(){ + it( "can have custom labels", function(){ + debug( var = [ 1, 2, 3, 4 ], label = "My Custom Label" ); var buffer = getDebugBuffer(); - expect( buffer[ 4 ].label ).toBe( "/Debug/another Suite/can have generic labels too" ); - }); - }); + expect( buffer[ 1 ].label ).toBe( "My Custom Label" ); + } ); - }); + it( "can have generic labels", function(){ + debug( var = [ 1, 2, 3, 4 ] ); + var buffer = getDebugBuffer(); + expect( buffer[ 2 ].label ).toBe( "/Debug/can have generic labels" ); + } ); + + it( "can do top functionality", function(){ + var nested = [ + 1, + 2, + 3, + 4, + [ 1, 2, 3, 4, [ 1, 2, 3, 4 ] ] + ]; + debug( var = nested, top = 1 ); + } ); + + describe( "another Suite", function(){ + it( "can have generic labels too", function(){ + debug( var = [ 1, 2, 3, 4 ] ); + var buffer = getDebugBuffer(); + expect( buffer[ 4 ].label ).toBe( "/Debug/another Suite/can have generic labels too" ); + } ); + } ); + } + ); } -} \ No newline at end of file +} diff --git a/tests/specs/EdgeCases.cfc b/tests/specs/EdgeCases.cfc index b87406ac..be43f30b 100644 --- a/tests/specs/EdgeCases.cfc +++ b/tests/specs/EdgeCases.cfc @@ -1,88 +1,87 @@ component extends="testbox.system.BaseSpec" { function run(){ - - describe("Tests sparse array", function(){ - - it("works", function(){ - var expected = ["a"]; - expected[3] = "c"; - var actual = expected; - expect(expected).toBe(actual); // this is line 10 - }); + describe( "Tests sparse array", function(){ + it( "works", function(){ + var expected = [ "a" ]; + expected[ 3 ] = "c"; + var actual = expected; + expect( expected ).toBe( actual ); // this is line 10 + } ); it( "can handle private UDFs", variables.myFakeClosure ); it( "can handle public UDFs", variables.myFakePublicClosure ); - - }); + } ); describe( "Ability to bind data to life-cycle methods", function(){ - - var data = [ - "spec1", - "spec2" - ]; + var data = [ "spec1", "spec2" ]; - for( var thisData in data ){ + for ( var thisData in data ) { describe( "Trying #thisData#", function(){ - - beforeEach( data={ myData = thisData }, body=function( currentSpec, data ){ - targetData = arguments.data.myData; - }); - - it( title="should account for life-cycle data binding", - data={ myData = thisData}, - body=function( data ){ - expect( targetData ).toBe( data.mydata ); + beforeEach( + data = { myData : thisData }, + body = function( currentSpec, data ){ + targetData = arguments.data.myData; } ); - afterEach( data={ myData = thisData }, body=function( currentSpec, data ){ - targetData = arguments.data.myData; - }); - }); - } + it( + title = "should account for life-cycle data binding", + data = { myData : thisData }, + body = function( data ){ + expect( targetData ).toBe( data.mydata ); + } + ); - for( var thisData in data ){ + afterEach( + data = { myData : thisData }, + body = function( currentSpec, data ){ + targetData = arguments.data.myData; + } + ); + } ); + } + for ( var thisData in data ) { describe( "Trying around life-cycles with #thisData#", function(){ - - aroundEach( data={ myData = thisData }, body = function( spec, suite, data ){ - targetData = arguments.data.myData; - arguments.spec.body( data=arguments.spec.data ); - }); - - it( title="should account for life-cycle data binding", - data={ myData = thisData }, - body=function( data ){ - expect( targetData ).toBe( data.mydata ); + aroundEach( + data = { myData : thisData }, + body = function( spec, suite, data ){ + targetData = arguments.data.myData; + arguments.spec.body( data = arguments.spec.data ); } ); - - }); + it( + title = "should account for life-cycle data binding", + data = { myData : thisData }, + body = function( data ){ + expect( targetData ).toBe( data.mydata ); + } + ); + } ); } - }); + } ); describe( "When testing a key does not exists", function(){ - var data = {name="luis", awesome=true}; + var data = { name : "luis", awesome : true }; it( "should pass when the key does not exist", function(){ - expect( data ).notToHaveKey( "age" ); - }); + expect( data ).notToHaveKey( "age" ); + } ); it( "should fail when the key does exist", function(){ - expect( function(){ - expect( data ).notToHaveKey( "name" ); + expect( function(){ + expect( data ).notToHaveKey( "name" ); } ).toThrow( type = "TestBox.AssertionFailed" ); - }); - }); - + } ); + } ); } - private function myFakeClosure(){ + private function myFakeClosure(){ expect( true ).toBeTrue(); } - private function myFakePublicClosure(){ + private function myFakePublicClosure(){ expect( true ).toBeTrue(); } -} \ No newline at end of file + +} diff --git a/tests/specs/ExcludesTest.cfc b/tests/specs/ExcludesTest.cfc index 33aa9b07..b0c1f9c7 100644 --- a/tests/specs/ExcludesTest.cfc +++ b/tests/specs/ExcludesTest.cfc @@ -1,9 +1,9 @@ /** -* My BDD Test -*/ + * My BDD Test + */ component extends="testbox.system.BaseSpec" labels="luis" { -/*********************************** LIFE CYCLE Methods ***********************************/ + /*********************************** LIFE CYCLE Methods ***********************************/ // executes before all suites+specs in the run() method function beforeAll(){ @@ -12,54 +12,52 @@ component extends="testbox.system.BaseSpec" labels="luis" { // executes after all suites+specs in the run() method function afterAll(){ - if ( StructKeyExists(url, "labels") && listContains( url.labels, "luis" ) ) { + if ( structKeyExists( url, "labels" ) && listContains( url.labels, "luis" ) ) { expect( testsRan ).toBe( 8 ); - } - else if ( StructKeyExists(url, "excludes") && listContains( url.excludes, "luis" ) ) { - expect( testsRan ).toBe( 0 ); - } - else { + } else if ( structKeyExists( url, "excludes" ) && listContains( url.excludes, "luis" ) ) { + expect( testsRan ).toBe( 0 ); + } else { expect( testsRan ).toBe( 8 ); } } -/*********************************** BDD SUITES ***********************************/ + /*********************************** BDD SUITES ***********************************/ function run(){ describe( "Suite with a label", function(){ it( "should execute", function(){ testsRan++; - }); + } ); it( "should execute as well", function(){ testsRan++; - }); + } ); describe( "Nested Suite", function(){ it( "should execute as well, as nested suite is inside a label suite", function(){ testsRan++; - }); + } ); - describe( "Double Nested Suite", function() { - it( "should execute this spec as well, because a parent suite has the correct label", function() { - testsRan++; + describe( "Double Nested Suite", function(){ + it( "should execute this spec as well, because a parent suite has the correct label", function(){ + testsRan++; } ); } ); - }); - }); + } ); + } ); describe( "Suites with no labels", function(){ it( "should execute", function(){ testsRan++; - }); + } ); it( "should execute", function(){ testsRan++; - }); - }); + } ); + } ); - describe( "Suite without a label but containing a spec with a label", function() { - it( "spec with a label", function() { + describe( "Suite without a label but containing a spec with a label", function(){ + it( "spec with a label", function(){ testsRan++; } ); - it( "should execute", function() { + it( "should execute", function(){ testsRan++; } ); } ); diff --git a/tests/specs/FocusedSpecs.cfc b/tests/specs/FocusedSpecs.cfc index 1aed3046..84dcf215 100644 --- a/tests/specs/FocusedSpecs.cfc +++ b/tests/specs/FocusedSpecs.cfc @@ -1,113 +1,95 @@ /** -* My BDD Test -*/ -component extends="testbox.system.BaseSpec"{ + * My BDD Test + */ +component extends="testbox.system.BaseSpec" { -/*********************************** LIFE CYCLE Methods ***********************************/ + /*********************************** LIFE CYCLE Methods ***********************************/ // executes before all suites+specs in the run() method function beforeAll(){ - } // executes after all suites+specs in the run() method function afterAll(){ - } -/*********************************** BDD SUITES ***********************************/ + /*********************************** BDD SUITES ***********************************/ function run( testResults, testBox ){ // all your suites go here. describe( "My First Suite", function(){ - it( "A Spec that should not run", function(){ - fail( 'implement' ); - }); + fail( "implement" ); + } ); it( "A Spec that should not run", function(){ - fail( 'implement' ); - }); + fail( "implement" ); + } ); fit( "This should execute", function(){ expect( 1 ).toBeTrue(); - }); + } ); it( "A Spec that should not run", function(){ - fail( 'implement' ); - }); + fail( "implement" ); + } ); fit( "This should execute as well", function(){ expect( 1 ).toBeTrue(); - }); + } ); fdescribe( "All specs here should run", function(){ - it( "should run", function(){ - - }); + } ); it( "should run", function(){ - - }); + } ); it( "should run", function(){ - - }); + } ); } ); describe( "All specs here should NOT run", function(){ - it( "A Spec that should not run", function(){ - fail( 'implement' ); - }); + fail( "implement" ); + } ); it( "A Spec that should not run", function(){ - fail( 'implement' ); - }); + fail( "implement" ); + } ); it( "A Spec that should not run", function(){ - fail( 'implement' ); - }); - + fail( "implement" ); + } ); } ); - - }); + } ); fdescribe( "My Focused Suite", function(){ - it( "This should execute", function(){ expect( 1 ).toBeTrue(); - }); + } ); describe( "All specs here should run", function(){ - it( "should run", function(){ - - }); + } ); it( "should run", function(){ - - }); + } ); it( "should run", function(){ - - }); + } ); } ); xdescribe( "skipped suites", function(){ - it( "A Spec that should not run", function(){ - fail( 'implement' ); - }); + fail( "implement" ); + } ); it( "A Spec that should not run", function(){ - fail( 'implement' ); - }); + fail( "implement" ); + } ); it( "A Spec that should not run", function(){ - fail( 'implement' ); - }); - + fail( "implement" ); + } ); } ); - - }); + } ); } } diff --git a/tests/specs/GivenWhenThenTest.cfc b/tests/specs/GivenWhenThenTest.cfc index d4f91f5e..45c02300 100644 --- a/tests/specs/GivenWhenThenTest.cfc +++ b/tests/specs/GivenWhenThenTest.cfc @@ -1,9 +1,9 @@ /** -* My BDD Test -*/ -component extends="testbox.system.BaseSpec"{ + * My BDD Test + */ +component extends="testbox.system.BaseSpec" { -/*********************************** LIFE CYCLE Methods ***********************************/ + /*********************************** LIFE CYCLE Methods ***********************************/ // executes before all suites+specs in the run() method function beforeAll(){ @@ -13,7 +13,7 @@ component extends="testbox.system.BaseSpec"{ function afterAll(){ } -/*********************************** BDD SUITES ***********************************/ + /*********************************** BDD SUITES ***********************************/ function run(){ feature( "Given-When-Then test language support", function(){ @@ -22,11 +22,11 @@ component extends="testbox.system.BaseSpec"{ when( "I run this test suite", function(){ then( "it should be supported", function(){ expect( true ).toBe( true ); - }); - }); - }); - }); - }); + } ); + } ); + } ); + } ); + } ); } } diff --git a/tests/specs/InjectTests.cfc b/tests/specs/InjectTests.cfc index 02248d60..d298f14e 100644 --- a/tests/specs/InjectTests.cfc +++ b/tests/specs/InjectTests.cfc @@ -1,4 +1,4 @@ -component extends="testbox.system.compat.framework.TestCase"{ +component extends="testbox.system.compat.framework.TestCase" { private string function injectedPrivateMethod(){ return "injected"; @@ -10,17 +10,28 @@ component extends="testbox.system.compat.framework.TestCase"{ public function testInjectedPrivateMethod(){ var sut = New tests.resources.Sut(); - //replace privateMethod in the SUT with an injected mock method - injectMethod( sut, this, "injectedPrivateMethod", "privateMethod" ); - //The SUT should use the injected method instead of its original version - Assert( sut.returnPrivateMethod() IS "injected" ); + // replace privateMethod in the SUT with an injected mock method + injectMethod( + sut, + this, + "injectedPrivateMethod", + "privateMethod" + ); + // The SUT should use the injected method instead of its original version + assert( sut.returnPrivateMethod() IS "injected" ); } public function testInjectedPublicMethod(){ var sut = New tests.resources.Sut(); - //replace publicMethod in the SUT with an injected mock method - injectMethod( sut, this, "injectedPublicMethod", "publicMethod" ); - //The SUT should use the injected method instead of its original version - Assert( sut.returnPublicMethod() IS "injected" ); + // replace publicMethod in the SUT with an injected mock method + injectMethod( + sut, + this, + "injectedPublicMethod", + "publicMethod" + ); + // The SUT should use the injected method instead of its original version + assert( sut.returnPublicMethod() IS "injected" ); } + } diff --git a/tests/specs/LabelsTest.cfc b/tests/specs/LabelsTest.cfc index 31a8c802..3472af5f 100644 --- a/tests/specs/LabelsTest.cfc +++ b/tests/specs/LabelsTest.cfc @@ -1,9 +1,9 @@ /** -* My BDD Test -*/ -component extends="testbox.system.BaseSpec"{ + * My BDD Test + */ +component extends="testbox.system.BaseSpec" { -/*********************************** LIFE CYCLE Methods ***********************************/ + /*********************************** LIFE CYCLE Methods ***********************************/ // executes before all suites+specs in the run() method function beforeAll(){ @@ -12,54 +12,60 @@ component extends="testbox.system.BaseSpec"{ // executes after all suites+specs in the run() method function afterAll(){ - if ( StructKeyExists(url, "labels") && listContains( url.labels, "luis" ) ) { + if ( structKeyExists( url, "labels" ) && listContains( url.labels, "luis" ) ) { expect( testsRan ).toBe( 5 ); - } - else if ( StructKeyExists(url, "excludes") && listContains( url.excludes, "luis" ) ) { - expect( testsRan ).toBe( 3 ); - } - else { + } else if ( structKeyExists( url, "excludes" ) && listContains( url.excludes, "luis" ) ) { + expect( testsRan ).toBe( 3 ); + } else { expect( testsRan ).toBe( 8 ); } } -/*********************************** BDD SUITES ***********************************/ + /*********************************** BDD SUITES ***********************************/ function run(){ - describe( title="Suite with a label", labels="luis", body=function(){ - it( "should execute", function(){ - testsRan++; - }); - it( "should execute as well", function(){ - testsRan++; - }); - describe( "Nested Suite", function(){ - it( "should execute as well, as nested suite is inside a label suite", function(){ + describe( + title = "Suite with a label", + labels = "luis", + body = function(){ + it( "should execute", function(){ + testsRan++; + } ); + it( "should execute as well", function(){ testsRan++; - }); + } ); + describe( "Nested Suite", function(){ + it( "should execute as well, as nested suite is inside a label suite", function(){ + testsRan++; + } ); - describe( "Double Nested Suite", function() { - it( "should execute this spec as well, because a parent suite has the correct label", function() { - testsRan++; + describe( "Double Nested Suite", function(){ + it( "should execute this spec as well, because a parent suite has the correct label", function(){ + testsRan++; + } ); } ); } ); - }); - }); + } + ); describe( "Suites with no labels", function(){ it( "should not execute", function(){ testsRan++; - }); + } ); it( "should not execute", function(){ testsRan++; - }); - }); - - describe( "Suite without a label but containing a spec with a label", function() { - it( title="spec with a label", labels="luis", body=function() { - testsRan++; } ); - it( "should not execute", function() { + } ); + + describe( "Suite without a label but containing a spec with a label", function(){ + it( + title = "spec with a label", + labels = "luis", + body = function(){ + testsRan++; + } + ); + it( "should not execute", function(){ testsRan++; } ); } ); diff --git a/tests/specs/MXUnitCompatTest.cfc b/tests/specs/MXUnitCompatTest.cfc index 0cb5b6e7..56791b7c 100644 --- a/tests/specs/MXUnitCompatTest.cfc +++ b/tests/specs/MXUnitCompatTest.cfc @@ -1,6 +1,6 @@ component extends="BaseTest" { -/*********************************** LIFE CYCLE Methods ***********************************/ + /*********************************** LIFE CYCLE Methods ***********************************/ function beforeTests(){ addAssertDecorator( "testbox.tests.resources.CustomAsserts" ); @@ -19,7 +19,7 @@ component extends="BaseTest" { structDelete( request, "foo" ); } -/*********************************** Test Methods ***********************************/ + /*********************************** Test Methods ***********************************/ function testAddAssertDecorator(){ assertIsFunky( 100 ); @@ -27,81 +27,102 @@ component extends="BaseTest" { } function testFailsMethod(){ - try{ + try { fail( "This Test should fail" ); - } - catch( Any e ){ - if( e.message != "This Test should fail" ){ + } catch ( Any e ) { + if ( e.message != "This Test should fail" ) { rethrow; } } } - function testAssert() { + function testAssert(){ assert( application.salvador == 1 ); assertEquals( 1, request.foo ); } - function testAssertArrayEquals() { + function testAssertArrayEquals(){ var today = now(); - assertArrayEquals( [1,2,3], [1,2,3] ); - assertArrayEquals( [1,2,3, today, { name="luis", awesome=true } ], [1,2,3, today, { name="luis", awesome=true } ] ); - } - - function testAssertEquals() { - assertEquals(4, 4); - assertEquals( { name="luis", awesome=true }, { name="luis", awesome=true } ); + assertArrayEquals( [ 1, 2, 3 ], [ 1, 2, 3 ] ); + assertArrayEquals( + [ + 1, + 2, + 3, + today, + { name : "luis", awesome : true } + ], + [ + 1, + 2, + 3, + today, + { name : "luis", awesome : true } + ] + ); + } + + function testAssertEquals(){ + assertEquals( 4, 4 ); + assertEquals( { name : "luis", awesome : true }, { name : "luis", awesome : true } ); assertEquals( "hello", "Hello" ); - assertArrayEquals( [1,2,3], [1,2,3] ); + assertArrayEquals( [ 1, 2, 3 ], [ 1, 2, 3 ] ); } - function testAssertEqualsCase() { + function testAssertEqualsCase(){ assertEqualsCase( "hello", "hello" ); } - function testassertFalse() { + function testassertFalse(){ assertFalse( false ); } - function testassertNotEquals() { + function testassertNotEquals(){ assertNotEquals( "hello", "there" ); } - function testassertNotSame() { - assertNotSame( this, createObject("component", "testbox.system.MockBox") ); + function testassertNotSame(){ + assertNotSame( this, createObject( "component", "testbox.system.MockBox" ) ); // Even if the same CFC, two separate instances would be "equal" but not the "same". - assertNotSame( createObject("component", "testbox.system.MockBox"), createObject("component", "testbox.system.MockBox") ); + assertNotSame( + createObject( "component", "testbox.system.MockBox" ), + createObject( "component", "testbox.system.MockBox" ) + ); } - function testassertQueryEquals() { - var q1 = querySim( "id, name + function testassertQueryEquals(){ + var q1 = querySim( + "id, name 1 | luis majano 2 | alexia majano - 3 | lucas majano"); + 3 | lucas majano" + ); - var q2 = querySim( "id, name + var q2 = querySim( + "id, name 1 | luis majano 2 | alexia majano - 3 | lucas majano"); + 3 | lucas majano" + ); assertQueryEquals( q1, q2 ); } - function testassertStructEquals() { - assertStructEquals( { name="luis", awesome=true }, { name="luis", awesome=true } ); + function testassertStructEquals(){ + assertStructEquals( { name : "luis", awesome : true }, { name : "luis", awesome : true } ); } function testassertSame(){ assertSame( this, this ); - var data = { name="luis", awesome=true }; + var data = { name : "luis", awesome : true }; assertSame( data, data ); } - function testAssertTrue() { + function testAssertTrue(){ assertTrue( true ); } - function nonStandardNamesWillNotRun() { + function nonStandardNamesWillNotRun(){ fail( "Non-test methods should not run" ); } @@ -110,36 +131,39 @@ component extends="BaseTest" { } /** - * @mxunit:expectedException - */ + * @mxunit:expectedException + */ function testExpectedExceptionNoValue(){ // This method should throw an invalid exception and pass - throw( type="InvalidException", message="This test method should pass with an expected exception" ); + throw( type = "InvalidException", message = "This test method should pass with an expected exception" ); } /** - * @mxunit:expectedException InvalidException - */ + * @mxunit:expectedException InvalidException + */ function testExpectedExceptionWithValue(){ // This method should throw an invalid exception and pass - throw( type="InvalidException", message="This test method should pass with an expected exception of type InvalidException" ); + throw( + type = "InvalidException", + message = "This test method should pass with an expected exception of type InvalidException" + ); } function testExpectedExceptionFromMethodWithType(){ expectedException( "InvalidException" ); // This method should throw an invalid exception and pass - throw( type="InvalidException", message="This test method should pass with an expected exception" ); + throw( type = "InvalidException", message = "This test method should pass with an expected exception" ); } function testExpectedExceptionFromMethodWithTypeAndRegex(){ expectedException( "InvalidException", "(pass with an)" ); // This method should throw an invalid exception and pass - throw( type="InvalidException", message="This test method should pass with an expected exception" ); + throw( type = "InvalidException", message = "This test method should pass with an expected exception" ); } function testMakePublic(){ var t = new testbox.tests.resources.test1(); - assertTrue( makePublic( t, "aPrivateMethod").aPrivateMethod() ); + assertTrue( makePublic( t, "aPrivateMethod" ).aPrivateMethod() ); var t = new testbox.tests.resources.test1(); assertTrue( makePublic( t, "aPrivateMethod", "funkyMethod" ).funkyMethod() ); @@ -151,11 +175,11 @@ component extends="BaseTest" { function testMakePublicWithPackage(){ variables.test = new tests.resources.somepackage.ComponentInDifferentPackage(); - makepublic(variables.test, "aPackageMethod"); - assertEquals("test for this value", variables.test.aPackageMethod()); + makepublic( variables.test, "aPackageMethod" ); + assertEquals( "test for this value", variables.test.aPackageMethod() ); } - private function privateMethodsDontRun() { + private function privateMethodsDontRun(){ fail( "Private method don't run" ); } @@ -166,14 +190,14 @@ component extends="BaseTest" { } function testInjectMethod(){ - var giver = this; - var receiver = getMockBox().createStub(); + var giver = this; + var receiver = getMockBox().createStub(); injectMethod( receiver, giver, "getData" ); - assertEquals( receiver.getData(), [1,2,3] ); + assertEquals( receiver.getData(), [ 1, 2, 3 ] ); injectMethod( receiver, giver, "getData", "getIt" ); - assertEquals( receiver.getIt(), [1,2,3] ); + assertEquals( receiver.getIt(), [ 1, 2, 3 ] ); } function testIsDefined(){ @@ -193,7 +217,7 @@ component extends="BaseTest" { } function testassertIsEmptyQuery(){ - assertIsEmptyQuery( queryNew("") ); + assertIsEmptyQuery( queryNew( "" ) ); } function testassertIsEmptyArray(){ @@ -213,7 +237,7 @@ component extends="BaseTest" { } function testassertIsQuery(){ - assertIsQuery( queryNew("") ); + assertIsQuery( queryNew( "" ) ); } function testassertIsArray(){ @@ -227,20 +251,20 @@ component extends="BaseTest" { } function testRaiseException_pass(){ - expectException("MyException"); + expectException( "MyException" ); raiseExpectedException(); } - private function raiseExpectedException(){ - throw(type="MyException"); + private function raiseExpectedException(){ + throw( type = "MyException" ); } private function raiseUnexpectedException(){ - throw(type="DifferentException"); + throw( type = "DifferentException" ); } private function getData(){ - return [1,2,3]; + return [ 1, 2, 3 ]; } -} \ No newline at end of file +} diff --git a/tests/specs/NestedAroundEachTest.cfc b/tests/specs/NestedAroundEachTest.cfc index 7308a0cb..e31c8e4f 100644 --- a/tests/specs/NestedAroundEachTest.cfc +++ b/tests/specs/NestedAroundEachTest.cfc @@ -1,9 +1,9 @@ /** -* My BDD Test -*/ -component extends="testbox.system.BaseSpec"{ + * My BDD Test + */ +component extends="testbox.system.BaseSpec" { -/*********************************** LIFE CYCLE Methods ***********************************/ + /*********************************** LIFE CYCLE Methods ***********************************/ // executes before all suites+specs in the run() method function beforeAll(){ @@ -13,37 +13,37 @@ component extends="testbox.system.BaseSpec"{ function afterAll(){ } -/*********************************** BDD SUITES ***********************************/ + /*********************************** BDD SUITES ***********************************/ function run(){ variables.counter = 0; describe( "Outer describe", function(){ - aroundEach(function(spec, suite) { + aroundEach( function( spec, suite ){ counter++; spec.body(); - }); + } ); - it( "the aroundEach should be executed as normal", function() { + it( "the aroundEach should be executed as normal", function(){ expect( counter ).toBe( 1 ); - }); + } ); describe( "Inner describe", function(){ it( "the aroundEach from the parent context should be ran", function(){ expect( counter ).toBe( 2 ); - }); - }); - }); + } ); + } ); + } ); describe( "Another describe with no aroundEach", function(){ it( "can execute as normal", function(){ - expect( counter ).toBe( 2 ); - }); + expect( counter ).toBe( 2 ); + } ); describe( "with yet another describe", function(){ it( "can execute as normal", function(){ - expect( counter ).toBe( 2 ); - }); - }); - }); + expect( counter ).toBe( 2 ); + } ); + } ); + } ); } } diff --git a/tests/specs/NestedDescribeTest.cfc b/tests/specs/NestedDescribeTest.cfc index 1bd680c1..aa8e1f84 100644 --- a/tests/specs/NestedDescribeTest.cfc +++ b/tests/specs/NestedDescribeTest.cfc @@ -1,9 +1,9 @@ /** -* My BDD Test -*/ -component extends="testbox.system.BaseSpec"{ + * My BDD Test + */ +component extends="testbox.system.BaseSpec" { -/*********************************** LIFE CYCLE Methods ***********************************/ + /*********************************** LIFE CYCLE Methods ***********************************/ // executes before all suites+specs in the run() method function beforeAll(){ @@ -13,45 +13,74 @@ component extends="testbox.system.BaseSpec"{ function afterAll(){ } -/*********************************** BDD SUITES ***********************************/ + /*********************************** BDD SUITES ***********************************/ function run(){ describe( "Outer describe", function(){ - describe( "Inner describe", function(){ it( "Tests are ONLY in inner it()", function(){ expect( true ).toBe( true ); - }); - }); + } ); + } ); story( "I want pricing details", function(){ var sailingsData = [ - { name="AmaWaterways", Cruise_ID="749053", CrzCode="AM", API_Sail_ID="13732", API_Length=7, API_Port_Count=7, API_Sail_Date="10/08/2019" }, - { name="Avalon", Cruise_ID="767012", CrzCode="AV", API_Sail_ID="WDB091010APS", API_Length=7, API_Port_Count=9, API_Sail_Date="10/10/2019" }, - { name="Azamara", Cruise_ID="721541", CrzCode="AZ", API_Sail_ID="JR01191027JR07M398", API_Length=7, API_Port_Count=7, API_Sail_Date="10/27/2019" }, - { name="Celebrity", Cruise_ID="708821", CrzCode="CB", API_Sail_ID="SL01190117SL14K095", API_Length=14, API_Port_Count=9, API_Sail_Date="01/17/2019" } + { + name : "AmaWaterways", + Cruise_ID : "749053", + CrzCode : "AM", + API_Sail_ID : "13732", + API_Length : 7, + API_Port_Count : 7, + API_Sail_Date : "10/08/2019" + }, + { + name : "Avalon", + Cruise_ID : "767012", + CrzCode : "AV", + API_Sail_ID : "WDB091010APS", + API_Length : 7, + API_Port_Count : 9, + API_Sail_Date : "10/10/2019" + }, + { + name : "Azamara", + Cruise_ID : "721541", + CrzCode : "AZ", + API_Sail_ID : "JR01191027JR07M398", + API_Length : 7, + API_Port_Count : 7, + API_Sail_Date : "10/27/2019" + }, + { + name : "Celebrity", + Cruise_ID : "708821", + CrzCode : "CB", + API_Sail_ID : "SL01190117SL14K095", + API_Length : 14, + API_Port_Count : 9, + API_Sail_Date : "01/17/2019" + } ]; arrayEach( sailingsData, function( item ){ - - given( "[#item.name#] valid incoming arguments for a #item.name# sailing", function(){ - then( then="[#item.name#] I get a response with inErrorStatus=false", data=item, body=function( data ){ - - debug( "Starting to process #data.name#" ); - - sleep( randRange( 500, 2000 ) ); - - debug( "==> Finalized process #data.name#" ); - - }); - }); - - } ); - - }); - - }); + given( "[#item.name#] valid incoming arguments for a #item.name# sailing", function(){ + then( + then = "[#item.name#] I get a response with inErrorStatus=false", + data = item, + body = function( data ){ + debug( "Starting to process #data.name#" ); + + sleep( randRange( 500, 2000 ) ); + + debug( "==> Finalized process #data.name#" ); + } + ); + } ); + } ); + } ); + } ); } } diff --git a/tests/specs/SpecDataTests.cfc b/tests/specs/SpecDataTests.cfc index 480351e1..d46aa9f7 100644 --- a/tests/specs/SpecDataTests.cfc +++ b/tests/specs/SpecDataTests.cfc @@ -1,9 +1,9 @@ /** -* Test Passing of spec data -*/ -component extends="testbox.system.BaseSpec"{ - -/*********************************** LIFE CYCLE Methods ***********************************/ + * Test Passing of spec data + */ +component extends="testbox.system.BaseSpec" { + + /*********************************** LIFE CYCLE Methods ***********************************/ // executes before all suites+specs in the run() method function beforeAll(){ @@ -13,17 +13,19 @@ component extends="testbox.system.BaseSpec"{ function afterAll(){ } -/*********************************** BDD SUITES ***********************************/ + /*********************************** BDD SUITES ***********************************/ function run( testResults, testBox ){ // all your suites go here. describe( "Spec Data", function(){ - - it( title="can handle binding", body=function( data ){ - expect( data.keep ).toBeTrue(); - }, data = { keep = true } ); - - }); + it( + title = "can handle binding", + body = function( data ){ + expect( data.keep ).toBeTrue(); + }, + data = { keep : true } + ); + } ); } - -} \ No newline at end of file + +} diff --git a/tests/specs/ThreadCollisions.cfc b/tests/specs/ThreadCollisions.cfc index d4548002..966220c1 100644 --- a/tests/specs/ThreadCollisions.cfc +++ b/tests/specs/ThreadCollisions.cfc @@ -1,9 +1,9 @@ /** -* My BDD Test -*/ -component extends="testbox.system.BaseSpec"{ + * My BDD Test + */ +component extends="testbox.system.BaseSpec" { -/*********************************** LIFE CYCLE Methods ***********************************/ + /*********************************** LIFE CYCLE Methods ***********************************/ // executes before all suites+specs in the run() method function beforeAll(){ @@ -13,17 +13,22 @@ component extends="testbox.system.BaseSpec"{ function afterAll(){ } -/*********************************** BDD SUITES ***********************************/ + /*********************************** BDD SUITES ***********************************/ function run(){ // The following should NOT fail - describe("Thread Collisions", function(){ - - it("will NOT fail on the second spec due to identical spec name based thread name", function(){}); - - it("will NOT fail on the second spec due to identical spec name based thread name", function(){}); - - }, "async", true); + describe( + "Thread Collisions", + function(){ + it( "will NOT fail on the second spec due to identical spec name based thread name", function(){ + } ); + + it( "will NOT fail on the second spec due to identical spec name based thread name", function(){ + } ); + }, + "async", + true + ); } -} \ No newline at end of file +} diff --git a/tests/specs/interfaces/IReporter.cfc b/tests/specs/interfaces/IReporter.cfc index 37e6ba28..4ac8a247 100644 --- a/tests/specs/interfaces/IReporter.cfc +++ b/tests/specs/interfaces/IReporter.cfc @@ -1,27 +1,28 @@ /** -* Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp -* www.ortussolutions.com -* --- -* The TestBox main reporting interface for producing awesome testing reports -*/ -interface{ + * Copyright Since 2005 TestBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + * The TestBox main reporting interface for producing awesome testing reports + */ +interface { /** - * Get the name of the reporter - */ + * Get the name of the reporter + */ function getName(); /** - * Do the reporting thing here using the incoming test results - * The report should return back in whatever format they desire and should set any - * Specifc browser types if needed. - * @results.hint The instance of the TestBox TestResult object to build a report on - * @testbox.hint The TestBox core object - * @options.hint A structure of options this reporter needs to build the report with - */ - any function runReport( + * Do the reporting thing here using the incoming test results + * The report should return back in whatever format they desire and should set any + * Specifc browser types if needed. + * @results.hint The instance of the TestBox TestResult object to build a report on + * @testbox.hint The TestBox core object + * @options.hint A structure of options this reporter needs to build the report with + */ + any function runReport( required testbox.system.TestResult results, required testbox.system.TestBox testbox, - struct options={} ); - -} \ No newline at end of file + struct options = {} + ); + +} diff --git a/tests/specs/mockbox/MockBoxTest.cfc b/tests/specs/mockbox/MockBoxTest.cfc index 880a768b..7f367315 100755 --- a/tests/specs/mockbox/MockBoxTest.cfc +++ b/tests/specs/mockbox/MockBoxTest.cfc @@ -1,353 +1,514 @@  - - - function setup(){ - test = getMockBox().createEmptyMock( "testbox.tests.resources.Test" ); - } - - function testStubInheritedInterfaces(){ - // If this can be created, then our test has passed. - var canBeMockedOne = getMockBox().createStub( implements = "tests.resources.NestedInterface" ); - } - - function testMockRealMethods(){ - Test = getMockBox().createMock( "testbox.tests.resources.Test" ); - test.getData(); - $assert.isEqual( -1, test.$count( "getData" ) ); - test.$( "getData", 1000 ); - $assert.isEqual( 0, test.$count( "getData" ) ); - test.getData(); - test.getData(); - $assert.isEqual( 2, test.$count( "getData" ) ); - - // With DSL - test.$reset().$( "getData" ).$results( 1000 ); - $assert.isEqual( 0, test.$count( "getData" ) ); - test.getData(); - test.getData(); - $assert.isEqual( 2, test.$count( "getData" ) ); - $assert.isEqual( 1000, test.getData() ); - } - - function testVirtualMethods(){ - Test = getMockBox().createMock( "testbox.tests.resources.Test" ); - test.$( "virtualReturn" ).$results( 'Virtual Called Baby!!' ); - $assert.isEqual( 0, test.$count( "virtualReturn" ) ); - $assert.isEqual( "Virtual Called Baby!!", test.virtualReturn() ); - debug( test.$callLog() ); - $assert.isTrue( structKeyExists( test.$callLog(), "virtualReturn" ) ); - } - - function testProperties(){ - Test = getMockBox().createMock( "testbox.tests.resources.Test" ); - // reload original property value - original = test.getReload(); - test.$property( propertyName="reload", propertyScope="variables", mock=true ); - $assert.isEqual( true, test.getReload() ); - } - - function testMockPrivateMethods(){ - Test = getMockBox().createMock( "testbox.tests.resources.Test" ); - name = test.getFullName(); - debug( name ); - test.$( "getName", "Mock Ruler" ); - $assert.isEqual( "Mock Ruler", test.getFullName() ); - } - - function testSpys(){ - Test = createObject( "component", "testbox.tests.resources.Test" ); - getMockBox().prepareMock( test ); - // mock un-spy methods - $assert.isEqual( 5, test.getData() ); - $assert.isEqual( 5, test.spyTest() ); - // spy the methods - test.$( "getData" ).$results( 1000 ); - $assert.isEqual( 1000, test.getData() ); - $assert.isEqual( 0, test.spyTest() ); - } - - function testMockWithArguments(){ - Test = getMockBox().createMock( "testbox.tests.resources.Test" ); - //unmocked - $assert.isEqual( "/mockFactory", test.getSetting( "AppMapping" ) ); - $assert.isEqual( "NOT FOUND", test.getSetting( "DebugMode" ) ); - - // Mock - test.$( method='getSetting', callLogging=true ).$args( "AppMapping" ).$results( "mockbox.testing" ); - test.$( method='getSetting', callLogging=true ).$args( "DebugMode" ).$results( "true" ); - $assert.isEqual( "mockbox.testing", test.getSetting( "AppMapping" ) ); - $assert.isEqual( "true", test.getSetting( "DebugMode" ) ); - } - - function testCollaborator(){ - Test = createObject( "component", "testbox.tests.resources.Test" ); - mockCollaborator = getMockBox().createMock( className="testbox.tests.resources.Collaborator", - callLogging=true ); - - mockCollaborator.$( "getDataFromDB" ).$results( queryNew( "" ) ); - Test.setCollaborator( mockCollaborator ); - debug( mockCollaborator.$callLog() ); - $assert.isEqual( queryNew( "" ), test.displayData() ); - } - - function testStateMachineResults(){ - Test = getMockBox().createMock( "testbox.tests.resources.Test" ); - test.$( "getSetting" ).$results( "S1", "S2", "S3" ); - - $assert.isEqual( "S1", test.getSetting() ); - $assert.isEqual( "S2", test.getSetting() ); - $assert.isEqual( "S3", test.getSetting() ); - $assert.isEqual( "S1", test.getSetting() ); - $assert.isEqual( "S2", test.getSetting() ); - } - - function testStubs(){ - stub = getMockBox().createStub().$( "getName", "Luis Majano" ); - $assert.isEqual( "Luis Majano", stub.getName() ); - } - - function testVerifyOnce(){ - test.$( "displayData", queryNew( '' ) ).$( "testIt" ).$( "testNone" ); - test.testIt(); - $assert.isTrue( test.$once() ); - test.displayData(); - $assert.isTrue( test.$once( "displayData" ) ); - - $assert.isFalse( test.$once( "testNone" ) ); - } - - function testVerifyNever(){ - test.$( "displayData", queryNew( '' ) ); - test.$( "testIt" ); - $assert.isTrue( test.$never() ); - test.testIt(); - $assert.isTrue( test.$never( "displayData" ) ); - test.displayData(); - $assert.isFalse( test.$never( "displayData" ) ); - } - - function testVerifyAtMost(){ - test.$( "displayData", queryNew( '' ) ); - test.displayData(); - test.displayData(); - test.displayData(); - test.displayData(); - test.displayData(); - $assert.isFalse( test.$atMost( 3 ) ); - $assert.isTrue( test.$atMost( 5 ) ); - } - - function testVerifyAtLeast(){ - test.$( "displayData", queryNew( '' ) ); - $assert.isTrue( test.$atLeast( 0 ) ); - test.displayData(); - test.displayData(); - test.displayData(); - test.displayData(); - test.displayData(); - $assert.isTrue( test.$atLeast( 3 ) ); - } - - function testVerifyCallCount(){ - test.$( "displayData", queryNew( '' ) ); - $assert.isTrue( test.$verifyCallCount( 0 ) ); - $assert.isFalse( test.$verifyCallCount( 1 ) ); - - test.displayData(); - $assert.isEqual( true, test.$verifyCallCount( 1 ) ); - - test.displayData(); - test.displayData(); - test.displayData(); - $assert.isEqual( true, test.$verifyCallCount( 4 ) ); - $assert.isEqual( true, test.$verifyCallCount( 4, "displayData" ) ); - } - - function testMockMethodCallCount(){ - test.$( "displayData", queryNew( '' ) ); - test.$( "getLuis", 1 ); - - $assert.isEqual( 0, test.$count( "displayData" ) ); - $assert.isEqual( -1, test.$count( "displayData2" ) ); - - test.displayData(); - - $assert.isEqual( 1, test.$count( "displayData" ) ); - - test.getLuis(); - test.getLuis(); - $assert.isEqual( 3, test.$count() ); - } - - function testMethodArgumentSignatures(){ - - args = { - string = "test" // string - ,integer = 23 // integer - ,xmlDoc = xmlNew() - ,query = queryNew('') - ,datetime = now() - ,boolean = true - ,realNumber = 2.5 - ,structure = {key1 = 'value1',key2 = getMockBox().createStub()} - ,array = ['element1', getMockBox().createStub()] - ,object = getMockBox().createStub() - ,aNull = javaCast("null", "") - }; - - //1: Mock with positional and all calls should validate. - test.$( "getSetting" ) - .$args( args.string, args.integer, args.xmlDoc, args.query, args.datetime, args.boolean, args.realNumber, args.structure, args.array, args.object ) - .$results( "UnitTest" ); - - // Test positional - results = test.getSetting( args.string, args.integer, args.xmlDoc, args.query, args.datetime, args.boolean, args.realNumber, args.structure, args.array, args.object ); - $assert.isEqual( "UnitTest", results ); - // Test case sensitivity - args.string = "TEST"; - results = test.getSetting( args.string, args.integer, args.xmlDoc, args.query, args.datetime, args.boolean, args.realNumber, args.structure, args.array, args.object ); - $assert.isEqual( "UnitTest", results ); - args.string = "test"; - // Test increment/decrement value (ColdFusion bug converts integers to real numbers with increment and decrement operator) - args.integer++; args.integer--; - results = test.getSetting( args.string, args.integer, args.xmlDoc, args.query, args.datetime, args.boolean, args.realNumber, args.structure, args.array, args.object ); - $assert.isEqual( "UnitTest", results ); - args.integer = 23; - args.integer = 23; - - //2. Mock with named values and all calls should validate. - test.$( "getSetting" ).$args( string=args.string, integer = args.integer, xmlDoc = args.xmlDoc, query = args.query, datetime = args.datetime, boolean = args.boolean, realNumber = args.realNumber, struct = args.structure, array = args.array, object = args.object ).$results( "UnitTest2" ); - - // Test name-value pairs - results = test.getSetting( string=args.string, integer = args.integer, xmlDoc = args.xmlDoc, query = args.query, datetime = args.datetime, boolean = args.boolean, realNumber = args.realNumber, struct = args.structure, array = args.array, object = args.object ); - $assert.isEqual( "UnitTest2", results ); - // Test argCollection - results = test.getSetting( argumentCollection=args ); - $assert.isEqual( "UnitTest2", results ); - // Test case sensitivity - args.string = "TEST"; - results = test.getSetting( string=args.string, integer = args.integer, xmlDoc = args.xmlDoc, query = args.query, datetime = args.datetime, boolean = args.boolean, realNumber = args.realNumber, struct = args.structure, array = args.array, object = args.object ); - $assert.isEqual( "UnitTest2", results ); - args.string = "test"; - // Test increment/decrement value (ColdFusion bug converts integers to real numbers with increment and decrement operator) - args.integer++;args.integer--; - results = test.getSetting( string=args.string, integer = args.integer, xmlDoc = args.xmlDoc, query = args.query, datetime = args.datetime, boolean = args.boolean, realNumber = args.realNumber, struct = args.structure, array = args.array, object = args.object ); - $assert.isEqual( "UnitTest2", results ); - args.integer = 23; - - test.$( "getSetting" ).$args( argumentCollection=args ).$results( "UnitTest3" ); - // Test name-value pairs - results = test.getSetting( string=args.string, integer = args.integer, xmlDoc = args.xmlDoc, query = args.query, datetime = args.datetime, boolean = args.boolean, realNumber = args.realNumber, struct = args.structure, array = args.array, object = args.object ); - $assert.isEqual( "UnitTest3", results ); - // Test argCollection - results = test.getSetting( argumentCollection=args ); - $assert.isEqual( "UnitTest3", results ); - // Test case sensitivity - args.string = "TEST"; - results = test.getSetting( string=args.string, integer = args.integer, xmlDoc = args.xmlDoc, query = args.query, datetime = args.datetime, boolean = args.boolean, realNumber = args.realNumber, struct = args.structure, array = args.array, object = args.object ); - $assert.isEqual( "UnitTest3", results ); - args.string = "test"; - // Test increment/decrement value (ColdFusion bug converts integers to real numbers with increment and decrement operator) - args.integer++;args.integer--; - results = test.getSetting( string=args.string, integer = args.integer, xmlDoc = args.xmlDoc, query = args.query, datetime = args.datetime, boolean = args.boolean, realNumber = args.realNumber, struct = args.structure, array = args.array, object = args.object ); - $assert.isEqual( "UnitTest3", results ); - } - - function testGetProperty(){ - mock = getMockBox().createStub(); - mock.luis = "Majano"; - mock.$property( "cool", "variables", true ).$property( "number", "variables.instance", 7 ); - - $assert.isEqual( "Majano", mock.$getProperty( name="luis", scope="this" ) ); - $assert.isEqual( true, mock.$getProperty( name="cool" ) ); - $assert.isEqual( true, mock.$getProperty( name="cool", scope="variables" ) ); - $assert.isEqual( 7, mock.$getProperty( name="number", scope="variables.instance" ) ); - $assert.isEqual( 7, mock.$getProperty( name="number", scope="instance" ) ); - } - - function testStubWithInheritance(){ - mock = getMockBox().createStub( extends="coldbox.system.EventHandler" ); - $assert.isTrue( isInstanceOf( mock, "coldbox.system.EventHandler" ) ); - } - - function testStubWithImplements(){ - mock = getMockBox().createStub( implements="coldbox.system.cache.ICacheProvider" ); - $assert.isTrue( isInstanceOf( mock, "coldbox.system.cache.ICacheProvider" ) ); - } - - function testContainsCFKeyword(){ - test = getMockBox().createMock("testbox.tests.resources.Test"); - mockTest = getMockBox().createEmptyMock( "testbox.tests.resources.ContainsTest" ) - .$("contains", true); - $assert.isTrue( mockTest.contains() ); - } - - function testContainsClosureOrUDF(){ - mock = getMockBox().createStub(); - mock.$("mockMe", "Mocked" ); - - $assert.isEqual( "Mocked" , mock.mockMe( variables.testFunction ) ); - $assert.isEqual( "Mocked" , mock.mockMe( test = variables.testFunction ) ); - $assert.isEqual( "Mocked" , mock.mockMe( [ variables.testFunction ] ) ); - $assert.isEqual( "Mocked" , mock.mockMe( test = [ variables.testFunction ] ) ); - $assert.isEqual( "Mocked" , mock.mockMe( { mockData = variables.testFunction } ) ); - $assert.isEqual( "Mocked" , mock.mockMe( test = { mockData = variables.testFunction } ) ); - } - - function testInterfaceContracts(){ - mock = getMockBox().createMock( "testbox.tests.resources.MyInterfaceMock" ); - mock.$("testThis", "mocked!"); - - $assert.isEqual( "mocked!", mock.testThis( "name", 35 ) ); - } - - function testCFUDF(){ - var mocked = getMockBox().createStub().$( "getLocale", "en-GB" ); - $assert.isEqual( "en-GB", local.mocked.getLocale() ); - } - - function testCallbacks(){ - // shortcut - var mocked = getMockBox().createStub().$( method="getAmigo", callback=variables.testFunction ); - $assert.isEqual( mocked.getAmigo(), testFunction() ); - - // no arguments - var mocked = getMockBox().createStub().$("getAmigo").$callback( variables.testFunction ); - $assert.isEqual( mocked.getAmigo(), testFunction() ); - // test argument passing - $assert.isEqual( mocked.getAmigo( "luis" ), testFunction( "luis" ) ); - - // with arguments - var mocked = getMockBox().createStub().$("getAmigo").$args( "luis" ).$callback( variables.testFunction ); - $assert.isEqual( mocked.getAmigo( "luis" ), testFunction( "luis" ) ); - } - - function test$Throws(){ - var mocked = getMockBox() - .createStub() - .$( "dontPassThrowToMe" ) - .$args( "throw" ) - .$throws( - message = "My Custom Exception Message", - type = "MyCustomException", - detail = "A detail message here." - ); - - $assert.notThrows( - target = function() { mocked.dontPassThrowToMe(); } + function setup(){ + test = getMockBox().createEmptyMock( "testbox.tests.resources.Test" ); + } + + function testStubInheritedInterfaces(){ + // If this can be created, then our test has passed. + var canBeMockedOne = getMockBox().createStub( implements = "tests.resources.NestedInterface" ); + } + + function testMockRealMethods(){ + Test = getMockBox().createMock( "testbox.tests.resources.Test" ); + test.getData(); + $assert.isEqual( -1, test.$count( "getData" ) ); + test.$( "getData", 1000 ); + $assert.isEqual( 0, test.$count( "getData" ) ); + test.getData(); + test.getData(); + $assert.isEqual( 2, test.$count( "getData" ) ); + + // With DSL + test + .$reset() + .$( "getData" ) + .$results( 1000 ); + $assert.isEqual( 0, test.$count( "getData" ) ); + test.getData(); + test.getData(); + $assert.isEqual( 2, test.$count( "getData" ) ); + $assert.isEqual( 1000, test.getData() ); + } + + function testVirtualMethods(){ + Test = getMockBox().createMock( "testbox.tests.resources.Test" ); + test.$( "virtualReturn" ).$results( "Virtual Called Baby!!" ); + $assert.isEqual( 0, test.$count( "virtualReturn" ) ); + $assert.isEqual( "Virtual Called Baby!!", test.virtualReturn() ); + debug( test.$callLog() ); + $assert.isTrue( structKeyExists( test.$callLog(), "virtualReturn" ) ); + } + + function testProperties(){ + Test = getMockBox().createMock( "testbox.tests.resources.Test" ); + // reload original property value + original = test.getReload(); + test.$property( + propertyName = "reload", + propertyScope = "variables", + mock = true + ); + $assert.isEqual( true, test.getReload() ); + } + + function testMockPrivateMethods(){ + Test = getMockBox().createMock( "testbox.tests.resources.Test" ); + name = test.getFullName(); + debug( name ); + test.$( "getName", "Mock Ruler" ); + $assert.isEqual( "Mock Ruler", test.getFullName() ); + } + + function testSpys(){ + Test = createObject( "component", "testbox.tests.resources.Test" ); + getMockBox().prepareMock( test ); + // mock un-spy methods + $assert.isEqual( 5, test.getData() ); + $assert.isEqual( 5, test.spyTest() ); + // spy the methods + test.$( "getData" ).$results( 1000 ); + $assert.isEqual( 1000, test.getData() ); + $assert.isEqual( 0, test.spyTest() ); + } + + function testMockWithArguments(){ + Test = getMockBox().createMock( "testbox.tests.resources.Test" ); + // unmocked + $assert.isEqual( "/mockFactory", test.getSetting( "AppMapping" ) ); + $assert.isEqual( "NOT FOUND", test.getSetting( "DebugMode" ) ); + + // Mock + test + .$( method = "getSetting", callLogging = true ) + .$args( "AppMapping" ) + .$results( "mockbox.testing" ); + test + .$( method = "getSetting", callLogging = true ) + .$args( "DebugMode" ) + .$results( "true" ); + $assert.isEqual( "mockbox.testing", test.getSetting( "AppMapping" ) ); + $assert.isEqual( "true", test.getSetting( "DebugMode" ) ); + } + + function testCollaborator(){ + Test = createObject( "component", "testbox.tests.resources.Test" ); + mockCollaborator = getMockBox().createMock( + className = "testbox.tests.resources.Collaborator", + callLogging = true + ); + + mockCollaborator.$( "getDataFromDB" ).$results( queryNew( "" ) ); + Test.setCollaborator( mockCollaborator ); + debug( mockCollaborator.$callLog() ); + $assert.isEqual( queryNew( "" ), test.displayData() ); + } + + function testStateMachineResults(){ + Test = getMockBox().createMock( "testbox.tests.resources.Test" ); + test.$( "getSetting" ).$results( "S1", "S2", "S3" ); + + $assert.isEqual( "S1", test.getSetting() ); + $assert.isEqual( "S2", test.getSetting() ); + $assert.isEqual( "S3", test.getSetting() ); + $assert.isEqual( "S1", test.getSetting() ); + $assert.isEqual( "S2", test.getSetting() ); + } + + function testStubs(){ + stub = getMockBox().createStub().$( "getName", "Luis Majano" ); + $assert.isEqual( "Luis Majano", stub.getName() ); + } + + function testVerifyOnce(){ + test.$( "displayData", queryNew( "" ) ) + .$( "testIt" ) + .$( "testNone" ); + test.testIt(); + $assert.isTrue( test.$once() ); + test.displayData(); + $assert.isTrue( test.$once( "displayData" ) ); + + $assert.isFalse( test.$once( "testNone" ) ); + } + + function testVerifyNever(){ + test.$( "displayData", queryNew( "" ) ); + test.$( "testIt" ); + $assert.isTrue( test.$never() ); + test.testIt(); + $assert.isTrue( test.$never( "displayData" ) ); + test.displayData(); + $assert.isFalse( test.$never( "displayData" ) ); + } + + function testVerifyAtMost(){ + test.$( "displayData", queryNew( "" ) ); + test.displayData(); + test.displayData(); + test.displayData(); + test.displayData(); + test.displayData(); + $assert.isFalse( test.$atMost( 3 ) ); + $assert.isTrue( test.$atMost( 5 ) ); + } + + function testVerifyAtLeast(){ + test.$( "displayData", queryNew( "" ) ); + $assert.isTrue( test.$atLeast( 0 ) ); + test.displayData(); + test.displayData(); + test.displayData(); + test.displayData(); + test.displayData(); + $assert.isTrue( test.$atLeast( 3 ) ); + } + + function testVerifyCallCount(){ + test.$( "displayData", queryNew( "" ) ); + $assert.isTrue( test.$verifyCallCount( 0 ) ); + $assert.isFalse( test.$verifyCallCount( 1 ) ); + + test.displayData(); + $assert.isEqual( true, test.$verifyCallCount( 1 ) ); + + test.displayData(); + test.displayData(); + test.displayData(); + $assert.isEqual( true, test.$verifyCallCount( 4 ) ); + $assert.isEqual( true, test.$verifyCallCount( 4, "displayData" ) ); + } + + function testMockMethodCallCount(){ + test.$( "displayData", queryNew( "" ) ); + test.$( "getLuis", 1 ); + + $assert.isEqual( 0, test.$count( "displayData" ) ); + $assert.isEqual( -1, test.$count( "displayData2" ) ); + + test.displayData(); + + $assert.isEqual( 1, test.$count( "displayData" ) ); + + test.getLuis(); + test.getLuis(); + $assert.isEqual( 3, test.$count() ); + } + + function testMethodArgumentSignatures(){ + args = { + string : "test", // string + integer : 23, // integer + xmlDoc : xmlNew(), + query : queryNew( "" ), + datetime : now(), + boolean : true, + realNumber : 2.5, + structure : { + key1 : "value1", + key2 : getMockBox().createStub() + }, + array : [ + "element1", + getMockBox().createStub() + ], + object : getMockBox().createStub(), + aNull : javacast( "null", "" ) + }; + + // 1: Mock with positional and all calls should validate. + test + .$( "getSetting" ) + .$args( + args.string, + args.integer, + args.xmlDoc, + args.query, + args.datetime, + args.boolean, + args.realNumber, + args.structure, + args.array, + args.object + ) + .$results( "UnitTest" ); + + // Test positional + results = test.getSetting( + args.string, + args.integer, + args.xmlDoc, + args.query, + args.datetime, + args.boolean, + args.realNumber, + args.structure, + args.array, + args.object + ); + $assert.isEqual( "UnitTest", results ); + // Test case sensitivity + args.string = "TEST"; + results = test.getSetting( + args.string, + args.integer, + args.xmlDoc, + args.query, + args.datetime, + args.boolean, + args.realNumber, + args.structure, + args.array, + args.object + ); + $assert.isEqual( "UnitTest", results ); + args.string = "test"; + // Test increment/decrement value (ColdFusion bug converts integers to real numbers with increment and decrement operator) + args.integer++; + args.integer--; + results = test.getSetting( + args.string, + args.integer, + args.xmlDoc, + args.query, + args.datetime, + args.boolean, + args.realNumber, + args.structure, + args.array, + args.object + ); + $assert.isEqual( "UnitTest", results ); + args.integer = 23; + args.integer = 23; + + // 2. Mock with named values and all calls should validate. + test + .$( "getSetting" ) + .$args( + string = args.string, + integer = args.integer, + xmlDoc = args.xmlDoc, + query = args.query, + datetime = args.datetime, + boolean = args.boolean, + realNumber = args.realNumber, + struct = args.structure, + array = args.array, + object = args.object + ) + .$results( "UnitTest2" ); + + // Test name-value pairs + results = test.getSetting( + string = args.string, + integer = args.integer, + xmlDoc = args.xmlDoc, + query = args.query, + datetime = args.datetime, + boolean = args.boolean, + realNumber = args.realNumber, + struct = args.structure, + array = args.array, + object = args.object + ); + $assert.isEqual( "UnitTest2", results ); + // Test argCollection + results = test.getSetting( argumentCollection = args ); + $assert.isEqual( "UnitTest2", results ); + // Test case sensitivity + args.string = "TEST"; + results = test.getSetting( + string = args.string, + integer = args.integer, + xmlDoc = args.xmlDoc, + query = args.query, + datetime = args.datetime, + boolean = args.boolean, + realNumber = args.realNumber, + struct = args.structure, + array = args.array, + object = args.object + ); + $assert.isEqual( "UnitTest2", results ); + args.string = "test"; + // Test increment/decrement value (ColdFusion bug converts integers to real numbers with increment and decrement operator) + args.integer++; + args.integer--; + results = test.getSetting( + string = args.string, + integer = args.integer, + xmlDoc = args.xmlDoc, + query = args.query, + datetime = args.datetime, + boolean = args.boolean, + realNumber = args.realNumber, + struct = args.structure, + array = args.array, + object = args.object + ); + $assert.isEqual( "UnitTest2", results ); + args.integer = 23; + + test.$( "getSetting" ) + .$args( argumentCollection = args ) + .$results( "UnitTest3" ); + // Test name-value pairs + results = test.getSetting( + string = args.string, + integer = args.integer, + xmlDoc = args.xmlDoc, + query = args.query, + datetime = args.datetime, + boolean = args.boolean, + realNumber = args.realNumber, + struct = args.structure, + array = args.array, + object = args.object + ); + $assert.isEqual( "UnitTest3", results ); + // Test argCollection + results = test.getSetting( argumentCollection = args ); + $assert.isEqual( "UnitTest3", results ); + // Test case sensitivity + args.string = "TEST"; + results = test.getSetting( + string = args.string, + integer = args.integer, + xmlDoc = args.xmlDoc, + query = args.query, + datetime = args.datetime, + boolean = args.boolean, + realNumber = args.realNumber, + struct = args.structure, + array = args.array, + object = args.object + ); + $assert.isEqual( "UnitTest3", results ); + args.string = "test"; + // Test increment/decrement value (ColdFusion bug converts integers to real numbers with increment and decrement operator) + args.integer++; + args.integer--; + results = test.getSetting( + string = args.string, + integer = args.integer, + xmlDoc = args.xmlDoc, + query = args.query, + datetime = args.datetime, + boolean = args.boolean, + realNumber = args.realNumber, + struct = args.structure, + array = args.array, + object = args.object + ); + $assert.isEqual( "UnitTest3", results ); + } + + function testGetProperty(){ + mock = getMockBox().createStub(); + mock.luis = "Majano"; + mock.$property( "cool", "variables", true ).$property( "number", "variables.instance", 7 ); + + $assert.isEqual( "Majano", mock.$getProperty( name = "luis", scope = "this" ) ); + $assert.isEqual( true, mock.$getProperty( name = "cool" ) ); + $assert.isEqual( true, mock.$getProperty( name = "cool", scope = "variables" ) ); + $assert.isEqual( 7, mock.$getProperty( name = "number", scope = "variables.instance" ) ); + $assert.isEqual( 7, mock.$getProperty( name = "number", scope = "instance" ) ); + } + + function testStubWithInheritance(){ + mock = getMockBox().createStub( extends = "coldbox.system.EventHandler" ); + $assert.isTrue( isInstanceOf( mock, "coldbox.system.EventHandler" ) ); + } + + function testStubWithImplements(){ + mock = getMockBox().createStub( implements = "coldbox.system.cache.ICacheProvider" ); + $assert.isTrue( isInstanceOf( mock, "coldbox.system.cache.ICacheProvider" ) ); + } + + function testContainsCFKeyword(){ + test = getMockBox().createMock( "testbox.tests.resources.Test" ); + mockTest = getMockBox() + .createEmptyMock( "testbox.tests.resources.ContainsTest" ) + .$( "contains", true ); + $assert.isTrue( mockTest.contains() ); + } + + function testContainsClosureOrUDF(){ + mock = getMockBox().createStub(); + mock.$( "mockMe", "Mocked" ); + + $assert.isEqual( "Mocked", mock.mockMe( variables.testFunction ) ); + $assert.isEqual( "Mocked", mock.mockMe( test = variables.testFunction ) ); + $assert.isEqual( "Mocked", mock.mockMe( [ variables.testFunction ] ) ); + $assert.isEqual( "Mocked", mock.mockMe( test = [ variables.testFunction ] ) ); + $assert.isEqual( "Mocked", mock.mockMe( { mockData : variables.testFunction } ) ); + $assert.isEqual( "Mocked", mock.mockMe( test = { mockData : variables.testFunction } ) ); + } + + function testInterfaceContracts(){ + mock = getMockBox().createMock( "testbox.tests.resources.MyInterfaceMock" ); + mock.$( "testThis", "mocked!" ); + + $assert.isEqual( "mocked!", mock.testThis( "name", 35 ) ); + } + + function testCFUDF(){ + var mocked = getMockBox().createStub().$( "getLocale", "en-GB" ); + $assert.isEqual( "en-GB", local.mocked.getLocale() ); + } + + function testCallbacks(){ + // shortcut + var mocked = getMockBox().createStub().$( method = "getAmigo", callback = variables.testFunction ); + $assert.isEqual( mocked.getAmigo(), testFunction() ); + + // no arguments + var mocked = getMockBox() + .createStub() + .$( "getAmigo" ) + .$callback( variables.testFunction ); + $assert.isEqual( mocked.getAmigo(), testFunction() ); + // test argument passing + $assert.isEqual( mocked.getAmigo( "luis" ), testFunction( "luis" ) ); + + // with arguments + var mocked = getMockBox() + .createStub() + .$( "getAmigo" ) + .$args( "luis" ) + .$callback( variables.testFunction ); + $assert.isEqual( mocked.getAmigo( "luis" ), testFunction( "luis" ) ); + } + + function test$Throws(){ + var mocked = getMockBox() + .createStub() + .$( "dontPassThrowToMe" ) + .$args( "throw" ) + .$throws( + message = "My Custom Exception Message", + type = "MyCustomException", + detail = "A detail message here." ); - $assert.throws( - target = function() { mocked.dontPassThrowToMe( "throw" ); }, - type = "MyCustomException", - message = "My Custom Exception Message" - ); - } - - private function testFunction(string amigo = "Amigo"){ - return "Hola #arguments.amigo#!"; - } + $assert.notThrows( + target = function(){ + mocked.dontPassThrowToMe(); + } + ); + + $assert.throws( + target = function(){ + mocked.dontPassThrowToMe( "throw" ); + }, + type = "MyCustomException", + message = "My Custom Exception Message" + ); + } + + private function testFunction( string amigo = "Amigo" ){ + return "Hola #arguments.amigo#!"; + } - - \ No newline at end of file + diff --git a/tests/specs/more/EmbedTest.cfc b/tests/specs/more/EmbedTest.cfc index 0ee422ef..a8afc7aa 100644 --- a/tests/specs/more/EmbedTest.cfc +++ b/tests/specs/more/EmbedTest.cfc @@ -1,3 +1,4 @@ -component extends="tests.specs.AssertionsTest"{ +component extends="tests.specs.AssertionsTest" { -} \ No newline at end of file + +} From 1d2590d64ad91e9cb51f764329ce08bdf97ffe46 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Thu, 16 Apr 2020 08:49:40 -0500 Subject: [PATCH 09/17] TESTBOX-274 #resolve New testbox output utilities struct: request.testbox --- box.json | 2 +- system/BaseSpec.cfc | 13 ++++++++++++- tests/specs/BDDTest.cfc | 6 ++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/box.json b/box.json index b5f1dd41..ceccc704 100644 --- a/box.json +++ b/box.json @@ -41,7 +41,7 @@ }, "installPaths":{ "cbstreams":"system/modules/cbstreams/", - "mockdatacfc":"system/modules/mockdatacfc/mockdatacfc/" + "mockdatacfc":"system/modules/mockdatacfc/" }, "scripts":{ "format":"cfformat run system/**/*.cfc,test-harness/**/*.cfc,tests/specs/**/*.cfc,*.cfc --overwrite", diff --git a/system/BaseSpec.cfc b/system/BaseSpec.cfc index a0a84f87..8ab032af 100644 --- a/system/BaseSpec.cfc +++ b/system/BaseSpec.cfc @@ -38,6 +38,17 @@ component { // Focused Structures this.$focusedTargets = { "suites" : [], "specs" : [] }; + // Setup Request Utilities + if( !request.keyExists( "testbox" ) ){ + request.testbox = { + "console" : variables.console, + "debug" : variables.debug, + "clearDebugBuffer" : variables.clearDebugBuffer, + "print" : variables.print, + "println" : variables.println + }; + } + /************************************** BDD & EXPECTATIONS METHODS *********************************************/ /** @@ -1427,7 +1438,7 @@ component { * @return The mock data you desire sir! */ function mockData(){ - retur this.$mockData.mock( argumentCollection = arguments ); + return this.$mockData.mock( argumentCollection = arguments ); } /** diff --git a/tests/specs/BDDTest.cfc b/tests/specs/BDDTest.cfc index 276d204a..8dc1f283 100644 --- a/tests/specs/BDDTest.cfc +++ b/tests/specs/BDDTest.cfc @@ -357,6 +357,12 @@ component extends="testbox.system.BaseSpec" { var data = mockData( "name" : "name", "age" : "age" ); expect( data ).notToBeEmpty(); } ); + + + it( "can load the output utilities into request.testbox", function(){ + expect( request.testbox ) + .toHaveKey( "clearDebugBuffer,console,debug,print,println" ); + }); } ); } From b1dbf269ca4ecf4664f4e3b60391b78ead889301 Mon Sep 17 00:00:00 2001 From: mbandizzle Date: Tue, 21 Apr 2020 15:49:16 -0700 Subject: [PATCH 10/17] Fix the coverage % in HTML visualizer TESTBOX-278 https://ortussolutions.atlassian.net/browse/TESTBOX-278 The coverage percentage currently shown is hard-coded to 17.8%. --- test-visualizer/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-visualizer/index.html b/test-visualizer/index.html index 292a8243..8de7cafe 100644 --- a/test-visualizer/index.html +++ b/test-visualizer/index.html @@ -151,7 +151,7 @@

Code Coverage Stats

- 17.8% coverage + ${totalCoveragePercent}% coverage From 13e1a2f04ff3bd2f92a1531c1c5a64f6f7bb64ee Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Sat, 25 Apr 2020 17:29:31 -0500 Subject: [PATCH 11/17] TESTBOX-280 #resolve Add cfconfig.json for controlling output and consistency between testing in diff engines --- .cfconfig.json | 13 +++++++++++++ box.json | 5 ++++- 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 .cfconfig.json diff --git a/.cfconfig.json b/.cfconfig.json new file mode 100644 index 00000000..890a3856 --- /dev/null +++ b/.cfconfig.json @@ -0,0 +1,13 @@ +{ + "systemErr":"System", + "systemOut":"System", + "adminPassword" : "testbox", + "debuggingEnabled": true, + "debuggingShowDatabase":true, + "debuggingShowException":true, + "debuggingShowGeneral":true, + "ajaxDebugWindowEnabled": false, + "debuggingReportExecutionTimes": false, + "maxCFThreads":100, + "whitespaceManagement":"smart" +} \ No newline at end of file diff --git a/box.json b/box.json index ceccc704..0d4a7a08 100644 --- a/box.json +++ b/box.json @@ -45,6 +45,9 @@ }, "scripts":{ "format":"cfformat run system/**/*.cfc,test-harness/**/*.cfc,tests/specs/**/*.cfc,*.cfc --overwrite", - "format:check":"cfformat run system/**/*.cfc,test-harness/**/*.cfc,tests/specs/**/*.cfc,*.cfc --check" + "format:check":"cfformat run system/**/*.cfc,test-harness/**/*.cfc,tests/specs/**/*.cfc,*.cfc --check", + "start:lucee" : "server start serverConfigFile=server-lucee@5.json", + "start:2016" : "server start serverConfigFile=server-adobe@2016.json", + "start:2018" : "server start serverConfigFile=server-adobe@2018.json" } } From 80e726aef717b88e5c8b8cab3567995cfb8ee346 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Sat, 25 Apr 2020 17:36:12 -0500 Subject: [PATCH 12/17] acf compats --- box.json | 8 ++++---- tests/specs/BDDTest.cfc | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/box.json b/box.json index 0d4a7a08..c90b721b 100644 --- a/box.json +++ b/box.json @@ -45,9 +45,9 @@ }, "scripts":{ "format":"cfformat run system/**/*.cfc,test-harness/**/*.cfc,tests/specs/**/*.cfc,*.cfc --overwrite", - "format:check":"cfformat run system/**/*.cfc,test-harness/**/*.cfc,tests/specs/**/*.cfc,*.cfc --check", - "start:lucee" : "server start serverConfigFile=server-lucee@5.json", - "start:2016" : "server start serverConfigFile=server-adobe@2016.json", - "start:2018" : "server start serverConfigFile=server-adobe@2018.json" + "format:check":"cfformat run system/**/*.cfc,test-harness/**/*.cfc,tests/specs/**/*.cfc,*.cfc --check", + "start:lucee":"server start serverConfigFile=server-lucee@5.json", + "start:2016":"server start serverConfigFile=server-adobe@2016.json", + "start:2018":"server start serverConfigFile=server-adobe@2018.json" } } diff --git a/tests/specs/BDDTest.cfc b/tests/specs/BDDTest.cfc index 8dc1f283..06b600f9 100644 --- a/tests/specs/BDDTest.cfc +++ b/tests/specs/BDDTest.cfc @@ -354,11 +354,11 @@ component extends="testbox.system.BaseSpec" { } ); it( "can mock any type of data", function(){ - var data = mockData( "name" : "name", "age" : "age" ); + var data = mockData( name : "name", age : "age", id : "uuid" ); + debug( data ); expect( data ).notToBeEmpty(); } ); - it( "can load the output utilities into request.testbox", function(){ expect( request.testbox ) .toHaveKey( "clearDebugBuffer,console,debug,print,println" ); From 6bb4b045ee6104365928eb8998ccb10aade87098 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Tue, 28 Apr 2020 11:37:03 -0500 Subject: [PATCH 13/17] updated readme --- readme.md | 88 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 56 insertions(+), 32 deletions(-) diff --git a/readme.md b/readme.md index 5f35f802..cf804956 100755 --- a/readme.md +++ b/readme.md @@ -1,50 +1,77 @@ - -[![Build Status](https://travis-ci.org/Ortus-Solutions/TestBox.svg?branch=development)](https://travis-ci.org/Ortus-Solutions/TestBox) - -``` - _____ _ ____ - |_ _|__ ___| |_| __ ) _____ __ - | |/ _ \/ __| __| _ \ / _ \ \/ / - | | __/\__ \ |_| |_) | (_) > < - |_|\___||___/\__|____/ \___/_/\_\ -``` +

+ + +

+ +

+ Build Status + Total Downloads + Latest Stable Version + Apache2 License +

+ +

+ Copyright Since 2005 TestBox by Luis Majano and Ortus Solutions, Corp +
+ www.ortussolutions.com +

+ +---- TestBox is a Behavior Driven Development (BDD) and Test Driven Development (TDD) framework for ColdFusion (CFML). It also includes mocking and stubbing capabilities via its internal MockBox library. -## LICENSE +## License Apache License, Version 2.0. -## IMPORTANT LINKS +## Versioning + +TestBox is maintained under the Semantic Versioning guidelines as much as possible. + +Releases will be numbered with the following format: + +```html +.. +``` + +And constructed with the following guidelines: + +* Breaking backward compatibility bumps the major (and resets the minor and patch) +* New additions without breaking backward compatibility bumps the minor (and resets the patch) +* Bug fixes and misc changes bumps the patch + +## Important Links -Source +### Source Code -- https://github.com/Ortus-Solutions/TestBox +* https://github.com/Ortus-Solutions/TestBox -Bug Tracking +### Bug Tracking -- https://ortussolutions.atlassian.net/browse/TESTBOX +* https://ortussolutions.atlassian.net/browse/TESTBOX -Support Forum +### Support -- https://groups.google.com/a/ortussolutions.com/forum/#!forum/testbox +* https://groups.google.com/a/ortussolutions.com/forum/#!forum/testbox +* [Join BoxTeam Slack](https://boxteam.herokuapp.com) -Documentation +### Documentation -- https://testbox.ortusbooks.com -- https://testbox.ortusbooks.com/content/primers/bdd/index.html -- https://testbox.ortusbooks.com/content/primers/xunit/index.html +* https://testbox.ortusbooks.com +* https://testbox.ortusbooks.com/content/primers/bdd/index.html +* https://testbox.ortusbooks.com/content/primers/xunit/index.html -Official Site +### Official Site -- https://www.ortussolutions.com/products/testbox +* https://www.ortussolutions.com/products/testbox -## SYSTEM REQUIREMENTS +## Requirements -- Lucee 5+ (xUnit + BDD) -- ColdFusion 11+ (xUnit + BDD) +
+
+ -## TESTBOX INSTALLATION +## Installation You can visit the TestBox documentation page to view all of its features and capabilities. To install TestBox just drop it in your web root as `/testbox` or @@ -63,10 +90,7 @@ You can also use [CommandBox](https://www.ortussolutions.com/products/commandbox Bleeding edge builds are updated automatically as code is committed. -******************************************************************************** -Copyright Since 2005 by Luis Majano and Ortus Solutions, Corp -www.ortussolutions.com -******************************************************************************** +---- ### HONOR GOES TO GOD ABOVE ALL From f07c146ef8fa72c8bb835f3dd47ebfb7cd35f0c4 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Tue, 28 Apr 2020 11:54:40 -0500 Subject: [PATCH 14/17] TESTBOX-275 #resolve Exception in beforeTests/afterTests not reported in a meaningful way --- system/reports/ANTJUnitReporter.cfc | 19 +++++++++++++++++++ tests/specs/BDDTest.cfc | 1 + 2 files changed, 20 insertions(+) diff --git a/system/reports/ANTJUnitReporter.cfc b/system/reports/ANTJUnitReporter.cfc index aa7ad805..4943243e 100644 --- a/system/reports/ANTJUnitReporter.cfc +++ b/system/reports/ANTJUnitReporter.cfc @@ -101,6 +101,25 @@ component extends="BaseReporter" { var stats = arguments.suiteStats; var index = 1; + // Do we have a global exception? + if( !isSimpleValue( arguments.bundleStats.globalException ) ){ + // build test case + out.append( + " + + + "); + return; + } + // iterate over for ( var thisSuite in arguments.suiteStats ) { // build out full suite name diff --git a/tests/specs/BDDTest.cfc b/tests/specs/BDDTest.cfc index 06b600f9..641e9476 100644 --- a/tests/specs/BDDTest.cfc +++ b/tests/specs/BDDTest.cfc @@ -6,6 +6,7 @@ component extends="testbox.system.BaseSpec" { /*********************************** LIFE CYCLE Methods ***********************************/ function beforeAll(){ + throw(); // print( "

BDD Testing is Awesome!

" ); console( "Executed beforeAll() at #now()# " ); application.salvador = 1; From 0901c8dfb2f6cc3a37c08e2b725c842d23308636 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Tue, 28 Apr 2020 12:04:28 -0500 Subject: [PATCH 15/17] finalized more seuqence tests --- tests/specs/TestExecutionSequence.cfc | 46 +++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 tests/specs/TestExecutionSequence.cfc diff --git a/tests/specs/TestExecutionSequence.cfc b/tests/specs/TestExecutionSequence.cfc new file mode 100644 index 00000000..6cbd1e95 --- /dev/null +++ b/tests/specs/TestExecutionSequence.cfc @@ -0,0 +1,46 @@ +component extends="testbox.system.BaseSpec" { + + function beforeAll(){ + debug("1. in beforeAll()
"); + } + + function afterAll(){ + debug("8.in afterAll()
"); + } + + + function run(){ + + describe("outer describe", function(){ + + aroundEach( function( spec, suite ){ + debug("3.. top of outer aroundEach()
"); + // execute the spec + arguments.spec.body(); + debug("6.. bottom of outer aroundEach()
"); + }); + + + describe("inner describe", function(){ + + beforeEach(function(){ + debug("2... in inner describe()'s beforeEach()
"); + }); + + afterEach(function(){ + debug("7... in inner describe()'s afterEach()
"); + }); + + it("tests the negative", function(){ + debug("4.... top of inner describe()'s first it()'s callback
"); + expect(sgn(-1)).toBeLT(0); + debug("5.... bottom of inner describe()'s first it()'s callback
"); + }); + + }); + + }); + + } + +} \ No newline at end of file From 2894c1dcafab8f1a8feae9ab5eae05f771b07f02 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Tue, 28 Apr 2020 12:05:25 -0500 Subject: [PATCH 16/17] remove throw --- tests/specs/BDDTest.cfc | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/specs/BDDTest.cfc b/tests/specs/BDDTest.cfc index 641e9476..06b600f9 100644 --- a/tests/specs/BDDTest.cfc +++ b/tests/specs/BDDTest.cfc @@ -6,7 +6,6 @@ component extends="testbox.system.BaseSpec" { /*********************************** LIFE CYCLE Methods ***********************************/ function beforeAll(){ - throw(); // print( "

BDD Testing is Awesome!

" ); console( "Executed beforeAll() at #now()# " ); application.salvador = 1; From 938c4d389d43e7c0de33bb3b85383e1b101f2186 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Tue, 28 Apr 2020 12:08:06 -0500 Subject: [PATCH 17/17] updated to master recipe --- box.json | 1 + build/toMaster.boxr | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 build/toMaster.boxr diff --git a/box.json b/box.json index c90b721b..9184b231 100644 --- a/box.json +++ b/box.json @@ -44,6 +44,7 @@ "mockdatacfc":"system/modules/mockdatacfc/" }, "scripts":{ + "toMaster":"recipe build/toMaster.boxr", "format":"cfformat run system/**/*.cfc,test-harness/**/*.cfc,tests/specs/**/*.cfc,*.cfc --overwrite", "format:check":"cfformat run system/**/*.cfc,test-harness/**/*.cfc,tests/specs/**/*.cfc,*.cfc --check", "start:lucee":"server start serverConfigFile=server-lucee@5.json", diff --git a/build/toMaster.boxr b/build/toMaster.boxr new file mode 100644 index 00000000..f431e7f5 --- /dev/null +++ b/build/toMaster.boxr @@ -0,0 +1,20 @@ +# This recipe signifies a new release of the module by doing merges and bumps accordingly + +# Check out master +!git checkout -f master +!git pull +# Merge development into it +!git merge --no-ff development +# Tag the master repo with the version in box.json +!git tag v`box package show version` +# Push all branches +!git push origin --all +# Push all tags +!git push origin --tags +# Check development again +!git checkout -f development +# Bump to prepare for a new release, do minor, change if needed and don't tag +bump --minor --!tagVersion +# Send it out +!git commit -a -m "version bump" +!git push origin development \ No newline at end of file