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.IDomParser; 25 import com.android.tools.lint.client.api.IJavaParser; 26 import com.android.tools.lint.client.api.LintClient; 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 33 import org.eclipse.core.resources.IProject; 34 35 import java.io.File; 36 37 @SuppressWarnings("javadoc") 38 public class ProjectLintConfigurationTest extends AdtProjectTest { testBasic()39 public void testBasic() { 40 Configuration parent = null; 41 LintClient client = new TestClient(); 42 43 File dir = getTargetDir(); 44 if (!dir.exists()) { 45 boolean ok = dir.mkdirs(); 46 assertTrue(dir.getPath(), ok); 47 } 48 Project project = client.getProject(dir, dir); 49 50 ProjectLintConfiguration config = 51 new ProjectLintConfiguration(client, project, parent, false /*fatalOnly*/); 52 53 Issue usuallyEnabledIssue = DuplicateIdDetector.WITHIN_LAYOUT; 54 Issue usuallyDisabledIssue = UnusedResourceDetector.ISSUE_IDS; 55 56 assertTrue(config.isEnabled(usuallyEnabledIssue)); 57 assertFalse(config.isEnabled(usuallyDisabledIssue)); 58 59 config.setSeverity(usuallyEnabledIssue, Severity.IGNORE); 60 config.setSeverity(usuallyDisabledIssue, Severity.ERROR); 61 assertFalse(config.isEnabled(usuallyEnabledIssue)); 62 assertTrue(config.isEnabled(usuallyDisabledIssue)); 63 64 // Make a NEW config object to ensure the state is persisted properly, not just 65 // kept on the config object! 66 config = new ProjectLintConfiguration(client, project, parent, false /*fatalOnly*/); 67 assertFalse(config.isEnabled(usuallyEnabledIssue)); 68 assertTrue(config.isEnabled(usuallyDisabledIssue)); 69 } 70 testInheritance()71 public void testInheritance() { 72 Configuration parent = null; 73 LintClient client = new TestClient(); 74 75 File dir = getTargetDir(); 76 assertTrue(dir.mkdirs()); 77 Project project = client.getProject(dir, dir); 78 79 File otherDir = new File(dir, "otherConfig"); 80 assertTrue(otherDir.mkdir()); 81 Project otherProject = client.getProject(otherDir, otherDir); 82 83 ProjectLintConfiguration otherConfig = 84 new ProjectLintConfiguration(client, otherProject, parent, false); 85 86 ProjectLintConfiguration config = 87 new ProjectLintConfiguration(client, project, otherConfig, false); 88 89 Issue usuallyEnabledIssue = DuplicateIdDetector.WITHIN_LAYOUT; 90 Issue usuallyDisabledIssue = UnusedResourceDetector.ISSUE_IDS; 91 92 assertTrue(config.isEnabled(usuallyEnabledIssue)); 93 assertFalse(config.isEnabled(usuallyDisabledIssue)); 94 95 otherConfig.setSeverity(usuallyEnabledIssue, Severity.IGNORE); 96 otherConfig.setSeverity(usuallyDisabledIssue, Severity.ERROR); 97 98 // Ensure inheritance works 99 assertFalse(config.isEnabled(usuallyEnabledIssue)); 100 assertTrue(config.isEnabled(usuallyDisabledIssue)); 101 102 // Revert 103 otherConfig.setSeverity(usuallyEnabledIssue, Severity.ERROR); 104 otherConfig.setSeverity(usuallyDisabledIssue, Severity.IGNORE); 105 assertTrue(config.isEnabled(usuallyEnabledIssue)); 106 assertFalse(config.isEnabled(usuallyDisabledIssue)); 107 108 // Now override in child 109 config.setSeverity(usuallyEnabledIssue, Severity.ERROR); 110 config.setSeverity(usuallyDisabledIssue, Severity.IGNORE); 111 assertTrue(config.isEnabled(usuallyEnabledIssue)); 112 assertFalse(config.isEnabled(usuallyDisabledIssue)); 113 114 // Now change in parent: no change in child 115 otherConfig.setSeverity(usuallyEnabledIssue, Severity.IGNORE); 116 otherConfig.setSeverity(usuallyDisabledIssue, Severity.ERROR); 117 assertTrue(config.isEnabled(usuallyEnabledIssue)); 118 assertFalse(config.isEnabled(usuallyDisabledIssue)); 119 assertFalse(otherConfig.isEnabled(usuallyEnabledIssue)); 120 assertTrue(otherConfig.isEnabled(usuallyDisabledIssue)); 121 122 // Clear override in child 123 config.setSeverity(usuallyEnabledIssue, null); 124 config.setSeverity(usuallyDisabledIssue, null); 125 assertFalse(config.isEnabled(usuallyEnabledIssue)); 126 assertTrue(config.isEnabled(usuallyDisabledIssue)); 127 } 128 testBulkEditing()129 public void testBulkEditing() { 130 Configuration parent = null; 131 LintClient client = new TestClient(); 132 133 File dir = getTargetDir(); 134 assertTrue(dir.mkdirs()); 135 Project project = client.getProject(dir, dir); 136 137 ProjectLintConfiguration config = 138 new ProjectLintConfiguration(client, project, parent, false /*fatalOnly*/); 139 140 Issue usuallyEnabledIssue = DuplicateIdDetector.WITHIN_LAYOUT; 141 Issue usuallyDisabledIssue = UnusedResourceDetector.ISSUE_IDS; 142 143 assertTrue(config.isEnabled(usuallyEnabledIssue)); 144 assertFalse(config.isEnabled(usuallyDisabledIssue)); 145 146 config.setSeverity(usuallyEnabledIssue, Severity.IGNORE); 147 assertFalse(config.isEnabled(usuallyEnabledIssue)); 148 assertFalse(config.isEnabled(usuallyDisabledIssue)); 149 150 File configFile = new File(dir, "lint.xml"); 151 assertTrue(configFile.getPath(), configFile.exists()); 152 long lastModified = configFile.lastModified(); 153 154 // We need to make sure that the timestamp of the file is a couple of seconds 155 // after the last update or we can't tell whether the file was updated or not 156 157 try { 158 Thread.sleep(1000); 159 } catch (InterruptedException e) { 160 System.err.println("Sleep interrupted, test may not work."); 161 } 162 config.startBulkEditing(); 163 assertFalse(lastModified < configFile.lastModified()); 164 assertEquals(lastModified, configFile.lastModified()); 165 config.setSeverity(usuallyDisabledIssue, Severity.ERROR); 166 config.finishBulkEditing(); 167 assertTrue(lastModified < configFile.lastModified()); 168 169 assertTrue(config.isEnabled(usuallyDisabledIssue)); 170 } 171 172 public void testPersistence() { 173 // Ensure that we use the same configuration object repeatedly for a 174 // single project, such that we don't recompute and parse XML for each and 175 // every lint run! 176 IProject project = getProject(); 177 TestClient client = new TestClient(); 178 ProjectLintConfiguration config1 = ProjectLintConfiguration.get(client, project, false); 179 ProjectLintConfiguration config2 = ProjectLintConfiguration.get(client, project, false); 180 assertSame(config1, config2); 181 } 182 183 @Override 184 protected File getTargetDir() { 185 File targetDir = new File(getTempDir(), getClass().getSimpleName() + "_" + getName()); 186 addCleanupDir(targetDir); 187 return targetDir; 188 } 189 190 private static class TestClient extends LintClient { 191 @Override 192 public void report(@NonNull Context context, @NonNull Issue issue, 193 @NonNull Severity severity, @Nullable Location location, 194 @NonNull String message, @Nullable Object data) { 195 } 196 197 @Override 198 public void log(@NonNull Severity severity, @Nullable Throwable exception, 199 @Nullable String format, @Nullable Object... args) { 200 } 201 202 @Override 203 public IDomParser getDomParser() { 204 return null; 205 } 206 207 @Override 208 public @NonNull String readFile(@NonNull File file) { 209 return null; 210 } 211 212 @Override 213 public IJavaParser getJavaParser() { 214 return null; 215 } 216 } 217 } 218