/*
 * Copyright 2014 Google Inc. All Rights Reserved.
 *
 * 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
 *
 *     http://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.
 */

package com.google.errorprone.bugpatterns;

import static com.google.errorprone.BugPattern.Category.JUNIT;
import static com.google.errorprone.BugPattern.MaturityLevel.MATURE;
import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;
import static com.google.errorprone.matchers.Description.NO_MATCH;
import static com.google.errorprone.matchers.JUnitMatchers.hasJUnit4TestCases;
import static com.google.errorprone.matchers.JUnitMatchers.isTestCaseDescendant;
import static com.google.errorprone.matchers.Matchers.allOf;

import com.google.errorprone.BugPattern;
import com.google.errorprone.VisitorState;
import com.google.errorprone.bugpatterns.BugChecker.ClassTreeMatcher;
import com.google.errorprone.matchers.Description;
import com.google.errorprone.matchers.Matcher;

import com.sun.source.tree.ClassTree;

/**
 * @author mwacker@google.com (Mike Wacker)
 */
@BugPattern(
    name = "JUnitAmbiguousTestClass",
    summary = "Test class inherits from JUnit 3's TestCase but has JUnit 4 @Test annotations.",
    explanation = "JUnit 3 uses inheritance, whereas JUnit 4 uses composition. "
        + "Mixing these two design patterns historically has been a source of test bugs and "
        + "unexpected behavior (e.g.: teardown logic and/or verification does not run). "
        + "Error Prone also cannot infer whether the test class runs with JUnit 3 or JUnit 4. "
        + "Thus, even if the test class runs with JUnit 4, Error Prone will not run "
        + "additional checks which can catch common errors with JUnit 4 test classes. "
        + "Either use only JUnit 4 and remove the inheritance from TestCase, "
        + "or use only JUnit 3 and remove the @Test annotations. ",
    category = JUNIT, maturity = MATURE, severity = WARNING)
public class JUnitAmbiguousTestClass extends BugChecker implements ClassTreeMatcher {

  private static final Matcher<ClassTree> matcher = allOf(
      isTestCaseDescendant,
      hasJUnit4TestCases);

  @Override
  public Description matchClass(ClassTree classTree, VisitorState state) {
    return matcher.matches(classTree, state) ? describeMatch(classTree) : NO_MATCH;
  }
}

@@ -1659,67 +1659,267 @@
  = %22
+For 
 JUnit
- 3 uses inheritance, whereas JUnit 4 uses composition.
+3-style tests, behavior is defined in junit.framework.TestCase and %22%0A        + %22tests add behavior by overriding methods. For JUnit4-style tests, special %22%0A        + %22behavior happens with fields and methods annotated with JUnit 4 annotations. Having
  %22%0A 
@@ -1932,41 +1932,102 @@
  + %22
-Mixing
+JUnit4-style
  t
-h
 es
-e two design patterns 
+ts extend from junit.framework.TestCase (directly or indirectly) %22%0A        + %22
 hist
@@ -2157,16 +2157,75 @@
  not run
+ because %22%0A        + %22JUnit doesn't call the inherited code
 ). %22%0A   
@@ -2523,18 +2523,41 @@
 ly JUnit
- 
 4
+ classes and annotations
  and rem
@@ -2584,18 +2584,8 @@
 from
- TestCase,
  %22%0A 
@@ -2594,16 +2594,26 @@
      + %22
+TestCase, 
 or use o
@@ -2658,16 +2658,190 @@
 ations. 
+When looking for %22%0A        + %22replacements for base test classes, consider using Rules (see the @Rule annotation and %22%0A        + %22implementations of TestRule and MethodRule).
 %22,%0A    c

Clarify the reasons not to have JUnit4-style tests extends from TestCase.