<commit_before><cfcomponent hint="automatic test suite runner">

	<cfset this.s_results = StructNew()>
	<cfset this.s_results.Errors = StructNew()>
	<cfset sep = createObject("java","java.lang.System").getProperty("file.separator")>

	<cffunction name="run" access="public" hint="runs a directory of tests" returntype="any" output="false">
		<cfargument name="directory" required="true" hint="directory of tests to run">
		<cfargument name="componentPath" required="false" hint="the component path to put in front of all tests found (i.e. 'com.blah'). If no path is passed, we'll attempt to discover it ourselves" default="">
		<cfargument name="recurse" required="false" type="boolean" default="true" hint="whether to recurse down the directory tree">
		<cfargument name="excludes" required="false" default="" hint="list of Tests, in cfc notation, to exclude. uses ListContains so it's as greedy as possible. Currently does not support ant-style syntax or whole-directory filtering">
		<cfargument name="refreshCache" required="false" default="false" hint="flag to indicate whether or not to refresh the CF cache of CFCs. Maybe needed if any of the tests in the directory have not yet been compiled - to do: prove" />

		<cfset var testResult = "">
		<cfset var files = "">
		<cfset var suite = createObject("component","mxunit.framework.TestSuite")>
		<cfset var i = 1>

		<cfset arguments.directory = normalizeDirectory(arguments.directory)>

		<cfif NOT len(arguments.componentPath)>
			<cfset arguments.componentPath = getComponentPath(arguments.directory, arguments.refreshCache)>
		</cfif>

		<cfset files = getTests(arguments.directory,arguments.componentPath,arguments.recurse,trim(arguments.excludes)) />

		<cfloop from="1" to="#ArrayLen(files)#" index="i">
			<cftry>
				<cfset suite.addAll(files[i])>

				<cfcatch>
					<cfset this.s_results.Errors[files[i]] = cfcatch>
				</cfcatch>
			</cftry>
		</cfloop>

		<cfset testResult = suite.run()>

		<cfset testResult.mergeErrorsIntoTestResult(this.s_results.Errors)>

		<cfreturn testResult>
	</cffunction>

	<cffunction name="getTests" access="private" output="false">
		<cfargument name="directory" required="true" hint="directory of tests to run">
		<cfargument name="componentPath" required="true" hint="the component path to put in front of all tests found (i.e. 'com.blah')">
		<cfargument name="recurse" required="false" default="true" type="boolean" hint="whether to recurse down the directory tree">
		<cfargument name="excludes" required="false" default="" hint="ant-style syntax for excluding single files or directories">
		<cfset var q_tests = getDirectoryQuery(directory,recurse)>
		<cfset var a_tests = ArrayNew(1)>
		<cfset var testPath = "">

		<cfloop query="q_tests">
			<cfset testPath = formatTestPath(arguments.directory, q_tests.directory & sep & q_tests.Name,arguments.componentPath)>

			<cfif accept(testPath,arguments.excludes)>
				<cftry>
					<!---
					  Compile first. This ensures that any new tests NOT found in the server cache get added.
					  This may actually be quicker than searching the array and then conditionally compiling.
					  Appears not to have much overhead, but, we should monitor anyway for large test runs.
					 --->
					<cfset createObject("component","#testPath#") />
				<cfcatch type="any"><!--- no worries ---></cfcatch>
			</cftry>
				<cfset ArrayAppend(a_tests,testPath)><commit_msg>Made getTests public because why not?<commit_after><cfcomponent hint="automatic test suite runner">

	<cfset this.s_results = StructNew()>
	<cfset this.s_results.Errors = StructNew()>
	<cfset sep = createObject("java","java.lang.System").getProperty("file.separator")>

	<cffunction name="run" access="public" hint="runs a directory of tests" returntype="any" output="false">
		<cfargument name="directory" required="true" hint="directory of tests to run">
		<cfargument name="componentPath" required="false" hint="the component path to put in front of all tests found (i.e. 'com.blah'). If no path is passed, we'll attempt to discover it ourselves" default="">
		<cfargument name="recurse" required="false" type="boolean" default="true" hint="whether to recurse down the directory tree">
		<cfargument name="excludes" required="false" default="" hint="list of Tests, in cfc notation, to exclude. uses ListContains so it's as greedy as possible. Currently does not support ant-style syntax or whole-directory filtering">
		<cfargument name="refreshCache" required="false" default="false" hint="flag to indicate whether or not to refresh the CF cache of CFCs. Maybe needed if any of the tests in the directory have not yet been compiled - to do: prove" />

		<cfset var testResult = "">
		<cfset var files = "">
		<cfset var suite = createObject("component","mxunit.framework.TestSuite")>
		<cfset var i = 1>

		<cfset arguments.directory = normalizeDirectory(arguments.directory)>

		<cfif NOT len(arguments.componentPath)>
			<cfset arguments.componentPath = getComponentPath(arguments.directory, arguments.refreshCache)>
		</cfif>

		<cfset files = getTests(arguments.directory,arguments.componentPath,arguments.recurse,trim(arguments.excludes)) />

		<cfloop from="1" to="#ArrayLen(files)#" index="i">
			<cftry>
				<cfset suite.addAll(files[i])>

				<cfcatch>
					<cfset this.s_results.Errors[files[i]] = cfcatch>
				</cfcatch>
			</cftry>
		</cfloop>

		<cfset testResult = suite.run()>

		<cfset testResult.mergeErrorsIntoTestResult(this.s_results.Errors)>

		<cfreturn testResult>
	</cffunction>

	<cffunction name="getTests" access="public" output="false">
		<cfargument name="directory" required="true" hint="directory of tests to run">
		<cfargument name="componentPath" required="true" hint="the component path to put in front of all tests found (i.e. 'com.blah')">
		<cfargument name="recurse" required="false" default="true" type="boolean" hint="whether to recurse down the directory tree">
		<cfargument name="excludes" required="false" default="" hint="ant-style syntax for excluding single files or directories">
		<cfset var q_tests = getDirectoryQuery(directory,recurse)>
		<cfset var a_tests = ArrayNew(1)>
		<cfset var testPath = "">

		<cfloop query="q_tests">
			<cfset testPath = formatTestPath(arguments.directory, q_tests.directory & sep & q_tests.Name,arguments.componentPath)>

			<cfif accept(testPath,arguments.excludes)>
				<cftry>
					<!---
					  Compile first. This ensures that any new tests NOT found in the server cache get added.
					  This may actually be quicker than searching the array and then conditionally compiling.
					  Appears not to have much overhead, but, we should monitor anyway for large test runs.
					 --->
					<cfset createObject("component","#testPath#") />
				<cfcatch type="any"><!--- no worries ---></cfcatch>
			</cftry>
				<cfset ArrayAppend(a_tests,testPath)>
{'fraction_non_alphanumeric': 0.1283773915583467, 'fraction_numerical': 0.0008762961881115817, 'mean_word_length': 5.007017543859649, 'pattern_counts': {'":': 0, '<': 103, '<?xml version=': 0, '>': 103, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6248779', 'n_tokens_mistral': 2241, 'n_tokens_neox': 1995, 'n_words': 632}