I'm seeing that the use of a regexes that looks like NAMESPACE.CLASSNAME is not working in a namespaced org. I have an org with the namespace TomPackage. I define a test class regex that looks like this "TomPackage.fflib_*Test". When I debug the code, I see this get converted into the following SOQL query:
SELECT Id , Name FROM ApexClass WHERE NamespacePrefix =null AND Name like 'TomPackage.fflib_%Test'
I debugged this and determined that ApexClassFetcherUtils.fetchApexClassesBasedOnRegex is not splitting the passed in regex on the . (period) character. It is simply passing a value of null as the namespace parameter to the QueryConstructor.generateQueryToFetchApexClassesBasedOnRegex method. Here is the offending code from ApexClassFetcherUtils:
/*
* Utility method This method returns a string array of apex test class id's
* fetched based on regex pattern given as a command line input
*
* @param connection - partnerConnection for the app to connect to the org
* using web services
*
* @param classesAsArray - Apex Class Ids passed by the calling method. The
* returned string array of classes includes classes from this array as well
*
* @param regexes - regex that is used to fetch classes from the org
*/
private static String[] fetchApexClassesBasedOnRegex(PartnerConnection connection, String[] classesAsArray,
String regex, Boolean includeTriggers) {
if (regex != null && !regex.equals(" ")) {
LOG.info("Using regex: \"" + regex + "\" to fetch apex classes");
// construct the query
String namespace = null;
String soql = QueryConstructor.generateQueryToFetchApexClassesBasedOnRegex(namespace, regex);
// fire the query using WSC and fetch the results
String[] classesAsArrayUsingWSC = constructClassIdArrayUsingWSC(connection, soql);
// if both manifest file and testClass regex expression is provided
// as command line option, combine the results
Set<String> uniqueSetOfClasses = new HashSet<String>();
ArrayList<String> duplicateList = new ArrayList<String>();
// eliminate duplicates from the given class Ids
// (just in case duplicates still exist in the class array passed
// from the calling method)
if (classesAsArray != null && classesAsArray.length > 0) {
for (int i = 0; i < classesAsArray.length; i++) {
if (!uniqueSetOfClasses.add(classesAsArray[i])) {
duplicateList.add(classesAsArray[i]);
}
}
}
// eliminate duplicates from the classes fetched using the prefix
if (classesAsArrayUsingWSC != null && classesAsArrayUsingWSC.length > 0) {
for (int i = 0; i < classesAsArrayUsingWSC.length; i++) {
if (!uniqueSetOfClasses.add(classesAsArrayUsingWSC[i])) {
duplicateList.add(classesAsArrayUsingWSC[i]);
}
}
}
//if include triggers, add triggers to duplicate list as Triggers cannot be tested on force.com
if(includeTriggers){
String soqlForTrigger = QueryConstructor.generateQueryToFetchApexTriggersBasedOnRegex(namespace, regex);
String[] triggersAsArrayUsingWSC = constructClassIdArrayUsingWSC(connection, soqlForTrigger);
if (triggersAsArrayUsingWSC != null && triggersAsArrayUsingWSC.length > 0) {
for (int i = 0; i < triggersAsArrayUsingWSC.length; i++) {
if (!uniqueSetOfClasses.add(triggersAsArrayUsingWSC[i])) {
duplicateList.add(triggersAsArrayUsingWSC[i]);
}
}
}
}
// eliminate duplicates from the triggers fetched using the prefix
String[] uniqueClassesAsArray = uniqueSetOfClasses.toArray(new String[uniqueSetOfClasses.size()]);
// log the duplicate classes/triggers found by querying the org with
// the given regex
if (duplicateList != null && !duplicateList.isEmpty()) {
String logDuplicates = "Found duplicates from the classes fetched from the regex: " + regex
+ ". Skipping multiple execution/code coverage computation of these test class/source class(es) :";
for (int i = 0; i < duplicateList.size(); i++) {
duplicateApexClassMap.put(duplicateList.get(i), apexClassMap.get(duplicateList.get(i)));
logDuplicates += " " + apexClassMap.get(duplicateList.get(i)) + ",";
}
LOG.info(logDuplicates);
}
return uniqueClassesAsArray;
}
return classesAsArray;
}
I'm seeing that the use of a regexes that looks like NAMESPACE.CLASSNAME is not working in a namespaced org. I have an org with the namespace TomPackage. I define a test class regex that looks like this "TomPackage.fflib_*Test". When I debug the code, I see this get converted into the following SOQL query:
I debugged this and determined that ApexClassFetcherUtils.fetchApexClassesBasedOnRegex is not splitting the passed in regex on the . (period) character. It is simply passing a value of null as the namespace parameter to the QueryConstructor.generateQueryToFetchApexClassesBasedOnRegex method. Here is the offending code from ApexClassFetcherUtils: