1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Eclipse Public License, Version 1.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.eclipse.org/org/documents/epl-v10.php 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.ide.eclipse.adt.internal.lint; 17 18 import com.android.annotations.NonNull; 19 import com.android.annotations.Nullable; 20 import com.android.ide.eclipse.adt.internal.editors.layout.refactoring.AdtProjectTest; 21 import com.android.tools.lint.checks.DuplicateIdDetector; 22 import com.android.tools.lint.checks.UnusedResourceDetector; 23 import com.android.tools.lint.client.api.Configuration; 24 import com.android.tools.lint.client.api.JavaParser; 25 import com.android.tools.lint.client.api.LintClient; 26 import com.android.tools.lint.client.api.XmlParser; 27 import com.android.tools.lint.detector.api.Context; 28 import com.android.tools.lint.detector.api.Issue; 29 import com.android.tools.lint.detector.api.Location; 30 import com.android.tools.lint.detector.api.Project; 31 import com.android.tools.lint.detector.api.Severity; 32 import com.android.tools.lint.detector.api.TextFormat; 33 34 import org.eclipse.core.resources.IProject; 35 36 import java.io.File; 37 38 @SuppressWarnings("javadoc") 39 public class ProjectLintConfigurationTest extends AdtProjectTest { testBasic()40 public void testBasic() { 41 Configuration parent = null; 42 LintClient client = new TestClient(); 43 44 File dir = getTargetDir(); 45 if (!dir.exists()) { 46 boolean ok = dir.mkdirs(); 47 assertTrue(dir.getPath(), ok); 48 } 49 Project project = client.getProject(dir, dir); 50 51 ProjectLintConfiguration config = 52 new ProjectLintConfiguration(client, project, parent, false /*fatalOnly*/); 53 54 Issue usuallyEnabledIssue = DuplicateIdDetector.WITHIN_LAYOUT; 55 Issue usuallyDisabledIssue = UnusedResourceDetector.ISSUE_IDS; 56 57 assertTrue(config.isEnabled(usuallyEnabledIssue)); 58 assertFalse(config.isEnabled(usuallyDisabledIssue)); 59 60 config.setSeverity(usuallyEnabledIssue, Severity.IGNORE); 61 config.setSeverity(usuallyDisabledIssue, Severity.ERROR); 62 assertFalse(config.isEnabled(usuallyEnabledIssue)); 63 assertTrue(config.isEnabled(usuallyDisabledIssue)); 64 65 // Make a NEW config object to ensure the state is persisted properly, not just 66 // kept on the config object! 67 config = new ProjectLintConfiguration(client, project, parent, false /*fatalOnly*/); 68 assertFalse(config.isEnabled(usuallyEnabledIssue)); 69 assertTrue(config.isEnabled(usuallyDisabledIssue)); 70 } 71 testInheritance()72 public void testInheritance() { 73 Configuration parent = null; 74 LintClient client = new TestClient(); 75 76 File dir = getTargetDir(); 77 assertTrue(dir.mkdirs()); 78 Project project = client.getProject(dir, dir); 79 80 File otherDir = new File(dir, "otherConfig"); 81 assertTrue(otherDir.mkdir()); 82 Project otherProject = client.getProject(otherDir, otherDir); 83 84 ProjectLintConfiguration otherConfig = 85 new ProjectLintConfiguration(client, otherProject, parent, false); 86 87 ProjectLintConfiguration config = 88 new ProjectLintConfiguration(client, project, otherConfig, false); 89 90 Issue usuallyEnabledIssue = DuplicateIdDetector.WITHIN_LAYOUT; 91 Issue usuallyDisabledIssue = UnusedResourceDetector.ISSUE_IDS; 92 93 assertTrue(config.isEnabled(usuallyEnabledIssue)); 94 assertFalse(config.isEnabled(usuallyDisabledIssue)); 95 96 otherConfig.setSeverity(usuallyEnabledIssue, Severity.IGNORE); 97 otherConfig.setSeverity(usuallyDisabledIssue, Severity.ERROR); 98 99 // Ensure inheritance works 100 assertFalse(config.isEnabled(usuallyEnabledIssue)); 101 assertTrue(config.isEnabled(usuallyDisabledIssue)); 102 103 // Revert 104 otherConfig.setSeverity(usuallyEnabledIssue, Severity.ERROR); 105 otherConfig.setSeverity(usuallyDisabledIssue, Severity.IGNORE); 106 assertTrue(config.isEnabled(usuallyEnabledIssue)); 107 assertFalse(config.isEnabled(usuallyDisabledIssue)); 108 109 // Now override in child 110 config.setSeverity(usuallyEnabledIssue, Severity.ERROR); 111 config.setSeverity(usuallyDisabledIssue, Severity.IGNORE); 112 assertTrue(config.isEnabled(usuallyEnabledIssue)); 113 assertFalse(config.isEnabled(usuallyDisabledIssue)); 114 115 // Now change in parent: no change in child 116 otherConfig.setSeverity(usuallyEnabledIssue, Severity.IGNORE); 117 otherConfig.setSeverity(usuallyDisabledIssue, Severity.ERROR); 118 assertTrue(config.isEnabled(usuallyEnabledIssue)); 119 assertFalse(config.isEnabled(usuallyDisabledIssue)); 120 assertFalse(otherConfig.isEnabled(usuallyEnabledIssue)); 121 assertTrue(otherConfig.isEnabled(usuallyDisabledIssue)); 122 123 // Clear override in child 124 config.setSeverity(usuallyEnabledIssue, null); 125 config.setSeverity(usuallyDisabledIssue, null); 126 assertFalse(config.isEnabled(usuallyEnabledIssue)); 127 assertTrue(config.isEnabled(usuallyDisabledIssue)); 128 } 129 testBulkEditing()130 public void testBulkEditing() { 131 Configuration parent = null; 132 LintClient client = new TestClient(); 133 134 File dir = getTargetDir(); 135 assertTrue(dir.mkdirs()); 136 Project project = client.getProject(dir, dir); 137 138 ProjectLintConfiguration config = 139 new ProjectLintConfiguration(client, project, parent, false /*fatalOnly*/); 140 141 Issue usuallyEnabledIssue = DuplicateIdDetector.WITHIN_LAYOUT; 142 Issue usuallyDisabledIssue = UnusedResourceDetector.ISSUE_IDS; 143 144 assertTrue(config.isEnabled(usuallyEnabledIssue)); 145 assertFalse(config.isEnabled(usuallyDisabledIssue)); 146 147 config.setSeverity(usuallyEnabledIssue, Severity.IGNORE); 148 assertFalse(config.isEnabled(usuallyEnabledIssue)); 149 assertFalse(config.isEnabled(usuallyDisabledIssue)); 150 151 File configFile = new File(dir, "lint.xml"); 152 assertTrue(configFile.getPath(), configFile.exists()); 153 long lastModified = configFile.lastModified(); 154 155 // We need to make sure that the timestamp of the file is a couple of seconds 156 // after the last update or we can't tell whether the file was updated or not 157 158 try { 159 Thread.sleep(1000); 160 } catch (InterruptedException e) { 161 System.err.println("Sleep interrupted, test may not work."); 162 } 163 config.startBulkEditing(); 164 assertFalse(lastModified < configFile.lastModified()); 165 assertEquals(lastModified, configFile.lastModified()); 166 config.setSeverity(usuallyDisabledIssue, Severity.ERROR); 167 config.finishBulkEditing(); 168 assertTrue(lastModified < configFile.lastModified()); 169 170 assertTrue(config.isEnabled(usuallyDisabledIssue)); 171 } 172 173 public void testPersistence() { 174 // Ensure that we use the same configuration object repeatedly for a 175 // single project, such that we don't recompute and parse XML for each and 176 // every lint run! 177 IProject project = getProject(); 178 TestClient client = new TestClient(); 179 ProjectLintConfiguration config1 = ProjectLintConfiguration.get(client, project, false); 180 ProjectLintConfiguration config2 = ProjectLintConfiguration.get(client, project, false); 181 assertSame(config1, config2); 182 } 183 184 @Override 185 protected File getTargetDir() { 186 File targetDir = new File(getTempDir(), getClass().getSimpleName() + "_" + getName()); 187 addCleanupDir(targetDir); 188 return targetDir; 189 } 190 191 private static class TestClient extends LintClient { 192 @Override 193 public void report(@NonNull Context context, @NonNull Issue issue, 194 @NonNull Severity severity, @Nullable Location location, 195 @NonNull String message, @NonNull TextFormat format) { 196 } 197 198 @Override 199 public void log(@NonNull Severity severity, @Nullable Throwable exception, 200 @Nullable String format, @Nullable Object... args) { 201 } 202 203 @Override 204 public XmlParser getXmlParser() { 205 return null; 206 } 207 208 @Override 209 public @NonNull String readFile(@NonNull File file) { 210 return null; 211 } 212 213 @Override 214 public JavaParser getJavaParser(@Nullable Project project) { 215 return null; 216 } 217 } 218 } 219