aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTor Norbye <tnorbye@google.com>2012-09-11 12:47:13 -0700
committerandroid code review <noreply-gerritcodereview@google.com>2012-09-11 12:47:13 -0700
commitb081e294e4b217f956b969a12400ea3f920cef41 (patch)
tree2a6da9e1b832e41874c0511a815d92d1cdfb6e39
parent89fec25870f875b9ca02677ed9070139fcfed2f0 (diff)
parentd1f0bd93d0bee5b300154719726a7353732f571f (diff)
downloadsdk-b081e294e4b217f956b969a12400ea3f920cef41.zip
sdk-b081e294e4b217f956b969a12400ea3f920cef41.tar.gz
sdk-b081e294e4b217f956b969a12400ea3f920cef41.tar.bz2
Merge "Add unit test for lint CLI"
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/client/api/IssueRegistry.java12
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/BuiltinIssueRegistry.java11
-rw-r--r--lint/libs/lint_checks/tests/src/com/android/tools/lint/MainTest.java158
-rw-r--r--lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/AbstractCheckTest.java20
4 files changed, 198 insertions, 3 deletions
diff --git a/lint/libs/lint_api/src/com/android/tools/lint/client/api/IssueRegistry.java b/lint/libs/lint_api/src/com/android/tools/lint/client/api/IssueRegistry.java
index cf45b2e..e780d79 100644
--- a/lint/libs/lint_api/src/com/android/tools/lint/client/api/IssueRegistry.java
+++ b/lint/libs/lint_api/src/com/android/tools/lint/client/api/IssueRegistry.java
@@ -18,6 +18,7 @@ package com.android.tools.lint.client.api;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
+import com.android.annotations.VisibleForTesting;
import com.android.tools.lint.detector.api.Category;
import com.android.tools.lint.detector.api.Detector;
import com.android.tools.lint.detector.api.Issue;
@@ -238,4 +239,15 @@ public abstract class IssueRegistry {
}
return sIdToIssue.get(id);
}
+
+ /**
+ * Reset the registry such that it recomputes its available issues.
+ * <p>
+ * NOTE: This is only intended for testing purposes.
+ */
+ @VisibleForTesting
+ protected static void reset() {
+ sIdToIssue = null;
+ sCategories = null;
+ }
}
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/BuiltinIssueRegistry.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/BuiltinIssueRegistry.java
index 8915e81..ca73df0 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/BuiltinIssueRegistry.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/BuiltinIssueRegistry.java
@@ -20,6 +20,7 @@ import static com.android.tools.lint.detector.api.LintUtils.assertionsEnabled;
import static com.android.tools.lint.detector.api.LintUtils.endsWith;
import com.android.annotations.NonNull;
+import com.android.annotations.VisibleForTesting;
import com.android.prefs.AndroidLocation;
import com.android.prefs.AndroidLocation.AndroidLocationException;
import com.android.tools.lint.client.api.IssueRegistry;
@@ -319,4 +320,14 @@ public class BuiltinIssueRegistry extends IssueRegistry {
return sAdtFixes.contains(issue);
}
+
+ /**
+ * Reset the registry such that it recomputes its available issues.
+ * <p>
+ * NOTE: This is only intended for testing purposes.
+ */
+ @VisibleForTesting
+ public static void reset() {
+ IssueRegistry.reset();
+ }
}
diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/MainTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/MainTest.java
index d4fd069..6b4ca31 100644
--- a/lint/libs/lint_checks/tests/src/com/android/tools/lint/MainTest.java
+++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/MainTest.java
@@ -16,10 +16,25 @@
package com.android.tools.lint;
-import junit.framework.TestCase;
+import com.android.tools.lint.checks.AbstractCheckTest;
+import com.android.tools.lint.checks.AccessibilityDetector;
+import com.android.tools.lint.checks.BuiltinIssueRegistry;
+import com.android.tools.lint.detector.api.Detector;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.PrintStream;
+import java.security.Permission;
+import java.util.List;
@SuppressWarnings("javadoc")
-public class MainTest extends TestCase {
+public class MainTest extends AbstractCheckTest {
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ BuiltinIssueRegistry.reset();
+ }
+
public void testWrap() {
String s =
"Hardcoding text attributes directly in layout files is bad for several reasons:\n" +
@@ -65,4 +80,143 @@ public class MainTest extends TestCase {
" adding new translations for existing string resources.\n",
wrapped);
}
+
+ protected String checkLint(String[] args, List<File> files) throws Exception {
+ PrintStream previousOut = System.out;
+ try {
+ final ByteArrayOutputStream output = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(output));
+
+ Main.main(args);
+
+ return output.toString();
+ } finally {
+ System.setOut(previousOut);
+ }
+ }
+
+ private void checkDriver(String expectedOutput, String expectedError, String[] args)
+ throws Exception {
+ PrintStream previousOut = System.out;
+ PrintStream previousErr = System.err;
+ try {
+ // Trap System.exit calls:
+ System.setSecurityManager(new SecurityManager() {
+ @Override
+ public void checkPermission(Permission perm)
+ {
+ // allow anything.
+ }
+ @Override
+ public void checkPermission(Permission perm, Object context)
+ {
+ // allow anything.
+ }
+ @Override
+ public void checkExit(int status) {
+ throw new ExitException();
+ }
+ });
+
+ final ByteArrayOutputStream output = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(output));
+ final ByteArrayOutputStream error = new ByteArrayOutputStream();
+ System.setErr(new PrintStream(error));
+
+ try {
+ Main.main(args);
+ } catch (ExitException e) {
+ // Allow
+ }
+
+ assertEquals(expectedError, cleanup(error.toString()));
+ assertEquals(expectedOutput, cleanup(output.toString()));
+ } finally {
+ // Re-enable system exit for unit test
+ System.setSecurityManager(null);
+
+ System.setOut(previousOut);
+ System.setErr(previousErr);
+ }
+ }
+
+
+ public void testArguments() throws Exception {
+ checkDriver(
+ // Expected output
+ "\n" +
+ "Scanning MainTest_testArguments: .\n" +
+ "res/layout/accessibility.xml:4: Warning: [Accessibility] Missing contentDescription attribute on image [ContentDescription]\n" +
+ " <ImageView android:id=\"@+id/android_logo\" android:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\" android:src=\"@drawable/android_button\" android:focusable=\"false\" android:clickable=\"false\" android:layout_weight=\"1.0\" />\n" +
+ " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" +
+ "res/layout/accessibility.xml:5: Warning: [Accessibility] Missing contentDescription attribute on image [ContentDescription]\n" +
+ " <ImageButton android:importantForAccessibility=\"yes\" android:id=\"@+id/android_logo2\" android:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\" android:src=\"@drawable/android_button\" android:focusable=\"false\" android:clickable=\"false\" android:layout_weight=\"1.0\" />\n" +
+ " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" +
+ "0 errors, 2 warnings\n",
+
+ // Expected error
+ "",
+
+ // Args
+ new String[] {
+ "--check",
+ "ContentDescription",
+ "--disable",
+ "LintError",
+ getProjectDir(null, "res/layout/accessibility.xml").getPath()
+
+ });
+ }
+
+ public void testShowDescription() throws Exception {
+ checkDriver(
+ // Expected output
+ "NewApi\n" +
+ "------\n" +
+ "Summary: Finds API accesses to APIs that are not supported in all targeted API\n" +
+ "versions\n" +
+ "\n" +
+ "Priority: 6 / 10\n" +
+ "Severity: Error\n" +
+ "Category: Correctness\n" +
+ "\n" +
+ "This check scans through all the Android API calls in the application and\n" +
+ "warns about any calls that are not available on all versions targeted by this\n" +
+ "application (according to its minimum SDK attribute in the manifest).\n" +
+ "\n" +
+ "If you really want to use this API and don't need to support older devices\n" +
+ "just set the minSdkVersion in your AndroidManifest.xml file.\n" +
+ "If your code is deliberately accessing newer APIs, and you have ensured (e.g.\n" +
+ "with conditional execution) that this code will only ever be called on a\n" +
+ "supported platform, then you can annotate your class or method with the\n" +
+ "@TargetApi annotation specifying the local minimum SDK to apply, such as\n" +
+ "@TargetApi(11), such that this check considers 11 rather than your manifest\n" +
+ "file's minimum SDK as the required API level.\n" +
+ "\n" +
+ "\n",
+
+ // Expected error
+ "",
+
+ // Args
+ new String[] {
+ "--show",
+ "NewApi"
+ });
+ }
+
+
+ @Override
+ protected Detector getDetector() {
+ // Sample issue to check by the main driver
+ return new AccessibilityDetector();
+ }
+
+ private static class ExitException extends SecurityException {
+ private static final long serialVersionUID = 1L;
+
+ private ExitException() {
+ super("Unit test");
+ }
+ }
}
diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/AbstractCheckTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/AbstractCheckTest.java
index de5b65e..8469644 100644
--- a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/AbstractCheckTest.java
+++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/AbstractCheckTest.java
@@ -188,7 +188,8 @@ public abstract class AbstractCheckTest extends TestCase {
private StringBuilder mOutput = null;
- private static File sTempDir = null;
+ protected static File sTempDir = null;
+
protected File getTempDir() {
if (sTempDir == null) {
File base = new File(System.getProperty("java.io.tmpdir")); //$NON-NLS-1$
@@ -286,6 +287,23 @@ public abstract class AbstractCheckTest extends TestCase {
return false;
}
+ protected static String cleanup(String result) throws IOException {
+ if (sTempDir != null && result.contains(sTempDir.getPath())) {
+ result = result.replace(sTempDir.getCanonicalFile().getPath(), "/TESTROOT");
+ result = result.replace(sTempDir.getAbsoluteFile().getPath(), "/TESTROOT");
+ result = result.replace(sTempDir.getPath(), "/TESTROOT");
+ }
+
+ // The output typically contains a few directory/filenames.
+ // On Windows we need to change the separators to the unix-style
+ // forward slash to make the test as OS-agnostic as possible.
+ if (File.separatorChar != '/') {
+ result = result.replace(File.separatorChar, '/');
+ }
+
+ return result;
+ }
+
public class TestLintClient extends Main {
private StringWriter mWriter = new StringWriter();