Skip to content
This repository was archived by the owner on Feb 12, 2022. It is now read-only.
This repository was archived by the owner on Feb 12, 2022. It is now read-only.

Processing of regex with namespace is not working right. #30

Description

@tfuda

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;
    }

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions