Uploaded image for project: 'Clover'
  1. Clover
  2. CLOV-1339

The <testmethod name=".*> does not match constructors

    XMLWordPrintable

Details

    • Our product teams collect and evaluate feedback from a number of different sources. To learn more about how we use customer feedback in the planning process, check out our new feature policy.

    Description

      Problem:

      If you declare custom test detector, for instance:

      <clover-setup>
        <testsources dir="src/test/java">
          <testclass name=".*">
            <testmethod name=".*"/>
          </testclass>
        </testsources>
      </clover-setup>
      

      Then the test detector does not match constructors. As a consequence, a class like this:

      public class SomeException extends Exception {
        public SomeException(String s) { 
          super(s); 
        }
      } 
      

      will be treated as APPLICATION not as TEST code.

      Background reason:

      public boolean isMethodMatch(SourceContext sourceContext, MethodContext methodContext) {
              final MethodSignature signature = methodContext.getSignature();
              return methodMatches(signature.getName()) &&
                      methodAnnotationMatches(signature.getModifiers()) &&
                      methodReturnPatternMatches(signature.getReturnType()) &&
                      methodTagMatches(signature.getTags());
          }
      
      public boolean methodReturnPatternMatches(String methodReturnType) {
              return methodReturnType != null &&
                      (methodReturnTypePattern == null || methodReturnTypePattern.matcher(methodReturnType).matches());
          }
      

      The methodReturnType==null for constructors, thus constructor do not match the pattern.

      Solution:

      We could rewrite check like this:

      return methodReturnTypePattern == null ||
          (methodReturnType != null && methodReturnTypePattern.matcher(methodReturnType).matches());
      

      However, this would require entirely new handling of code instrumentation for constructors. The reason is that code would be currently rewritten like:

      public SomeException(String s) {
              __CLR3_1_12_100hjv4vvu6.R.globalSliceStart(getClass().getName(), 0);
              int $CLV_p$ = 0;
              java.lang.Throwable $CLV_t$ = null;
              try {
                  __CLR3_1_12_162c4pt0(s); // <<< ORIGINAL CONSTRUCTOR
                  $CLV_p$ = 1;
              } catch (java.lang.Throwable $CLV_t2$) {
                  if ($CLV_p$ == 0 && $CLV_t$ == null) {
                      $CLV_t$ = $CLV_t2$;
                  }
                  __CLR3_1_12_100hjv4vvu6.R.rethrow($CLV_t2$);
              } finally {
                  __CLR3_1_12_100hjv4vvu6.R.globalSliceEnd(getClass().getName(), "SomeException.SomeException", 0, $CLV_p$, $CLV_t$);
              }
          }
      
          private __CLR3_1_12_162c4pt0(String s) { // << COMPILATION FAILURE, MISSING RETURN TYPE
              super(s);
              __CLR3_1_12_100hjv4vvu6.R.inc(1);
              __CLR3_1_12_100hjv4vvu6.R.inc(0);
          }
      

      Problems:

      • call to super() must be first
      • we should not move constructor body into another method

      Attachments

        Activity

          People

            Unassigned Unassigned
            mparfianowicz Marek Parfianowicz
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: