blob: 9048ca784a6c6e677d02dbda7753d22479f0cf93 [file] [log] [blame]
/*
* Copyright (C) 2015 The Android Open Source Project
*
* 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.android.tools.lint.checks;
import static com.android.tools.lint.checks.AnnotationDetectorTest.SUPPORT_ANNOTATIONS_JAR_BASE64_GZIP;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.testutils.TestUtils;
import com.android.tools.lint.checks.infrastructure.LintDetectorTest;
import com.android.tools.lint.checks.infrastructure.TestIssueRegistry;
import com.android.tools.lint.checks.infrastructure.TestLintTask;
import com.android.tools.lint.detector.api.Detector;
import com.android.tools.lint.detector.api.Issue;
import com.google.common.collect.Sets;
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public abstract class AbstractCheckTest extends LintDetectorTest {
@Override
protected boolean allowAndroidBuildEnvironment() {
return false;
}
@Override
protected List<Issue> getIssues() {
return getRegisteredIssuesFromDetector();
}
@NonNull
private List<Issue> getRegisteredIssuesFromDetector() {
List<Issue> issues = new ArrayList<>();
Class<? extends Detector> detectorClass = getDetectorInstance().getClass();
// Get the list of issues from the registry and filter out others, to make sure
// issues are properly registered
List<Issue> candidates = new TestIssueRegistry().getIssues();
for (Issue issue : candidates) {
if (issue.getImplementation().getDetectorClass() == detectorClass) {
issues.add(issue);
}
}
return issues;
}
@NonNull
@Override
public InputStream getTestResource(String relativePath, boolean expectExists) {
fail("We should not be using file-based resources in the lint builtin unit tests.");
return null;
}
@Override
protected TestLintClient createClient() {
return new ToolsBaseTestLintClient();
}
static File sdk;
static {
sdk = TestUtils.getSdk();
}
@NonNull
public static File getSdk() {
return sdk;
}
@Override
@NonNull
protected TestLintTask lint() {
// instead of super.lint: don't set issues such that we can compute and compare
// detector results below
TestLintTask task = TestLintTask.lint();
task.checkMessage(
(context, issue, severity, location, message, fix) ->
AbstractCheckTest.super.checkReportedError(
context, issue, severity, location, message, fix));
// We call getIssues() instead of setting task.detector() because the above
// getIssues call will ensure that we only check issues registered in the class
task.detector(getDetectorInstance());
// Now check check the discrepancy to look for unregistered issues and
// highlight these
// TODO: Handle problems from getRegisteredIssuesFromDetector and if no fields are found
// don't assert the below. Basically, let the ISSUE field live outside the detector class
// (such as in a companion.)
List<Issue> computedIssues = getRegisteredIssuesFromDetector();
if (getIssues().equals(computedIssues)) {
Set<Issue> checkedIssues = Sets.newHashSet(task.getCheckedIssues());
Set<Issue> detectorIssues = Sets.newHashSet(computedIssues);
if (!checkedIssues.equals(detectorIssues)) {
Set<Issue> difference = Sets.symmetricDifference(checkedIssues, detectorIssues);
fail(
"Discrepancy in issues listed in detector class "
+ getDetectorInstance().getClass().getSimpleName()
+ " and issues "
+ "found in the issue registry: "
+ difference
+ ". If the issue fields "
+ "are not meant to be included in the registry, you can rename them to "
+ "begin with an underscore.");
}
}
task.issues(getIssues().toArray(new Issue[0]));
task.sdkHome(sdk);
return task;
}
/**
* Overrides TestLintClient to use the checked-in SDK that is available in the tools/base repo.
* The "real" TestLintClient is a public utility for writing lint tests, so it cannot make
* assumptions specific to tools/base.
*/
protected class ToolsBaseTestLintClient extends TestLintClient {
@Nullable
@Override
public File getSdkHome() {
return TestUtils.getSdk();
}
}
public static final String SUPPORT_JAR_PATH = "libs/support-annotations.jar";
protected TestFile SUPPORT_ANNOTATIONS_JAR =
base64gzip(SUPPORT_JAR_PATH, SUPPORT_ANNOTATIONS_JAR_BASE64_GZIP);
protected TestFile SUPPORT_ANNOTATIONS_CLASS_PATH = classpath(SUPPORT_JAR_PATH);
}