/* * Copyright (C) 2014 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 org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import com.android.annotations.NonNull; import com.android.annotations.Nullable; import com.android.builder.model.AndroidProject; import com.android.tools.lint.detector.api.Detector; import com.android.tools.lint.detector.api.Project; import java.io.File; import java.util.Arrays; public class ResourcePrefixDetectorTest extends AbstractCheckTest { @Override protected Detector getDetector() { return new ResourcePrefixDetector(); } public void testResourceFiles() throws Exception { assertEquals("" + "res/drawable-mdpi/frame.png: Error: Resource named 'frame' does not start with the project's resource prefix 'unit_test_prefix_'; rename to 'unit_test_prefix_frame' ? [ResourceName]\n" + "res/layout/layout1.xml:2: Error: Resource named 'layout1' does not start with the project's resource prefix 'unit_test_prefix_'; rename to 'unit_test_prefix_layout1' ? [ResourceName]\n" + "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" + "^\n" + "res/menu/menu.xml:2: Error: Resource named 'menu' does not start with the project's resource prefix 'unit_test_prefix_'; rename to 'unit_test_prefix_menu' ? [ResourceName]\n" + "<menu xmlns:android=\"http://schemas.android.com/apk/res/android\" >\n" + "^\n" + "3 errors, 0 warnings\n", lintProject( "res/layout/layout1.xml", "res/menu/menu.xml", "res/layout/layout1.xml=>res/layout/unit_test_prefix_ok.xml", "res/drawable-mdpi/frame.png", "res/drawable-mdpi/frame.png=>res/drawable/unit_test_prefix_ok1.png", "res/drawable-mdpi/frame.png=>res/drawable/unit_test_prefix_ok2.9.png" )); } public void testValues() throws Exception { assertEquals("" + "res/values/customattr.xml:2: Error: Resource named 'ContentFrame' does not start with the project's resource prefix 'unit_test_prefix_'; rename to 'unit_test_prefix_ContentFrame' ? [ResourceName]\n" + " <declare-styleable name=\"ContentFrame\">\n" + " ~~~~~~~~~~~~~~~~~~~\n" + "res/values/customattr.xml:3: Error: Resource named 'content' does not start with the project's resource prefix 'unit_test_prefix_'; rename to 'unit_test_prefix_content' ? [ResourceName]\n" + " <attr name=\"content\" format=\"reference\" />\n" + " ~~~~~~~~~~~~~~\n" + "res/values/customattr.xml:4: Error: Resource named 'contentId' does not start with the project's resource prefix 'unit_test_prefix_'; rename to 'unit_test_prefix_contentId' ? [ResourceName]\n" + " <attr name=\"contentId\" format=\"reference\" />\n" + " ~~~~~~~~~~~~~~~~\n" + "res/layout/customattrlayout.xml:2: Error: Resource named 'customattrlayout' does not start with the project's resource prefix 'unit_test_prefix_'; rename to 'unit_test_prefix_customattrlayout' ? [ResourceName]\n" + "<foo.bar.ContentFrame\n" + "^\n" + "4 errors, 0 warnings\n", lintProject( "res/values/customattr.xml", "res/layout/customattrlayout.xml", "unusedR.java.txt=>gen/my/pkg/R.java", "AndroidManifest.xml")); } public void testMultiProject() throws Exception { File master = getProjectDir("MasterProject", // Master project "multiproject/main-manifest.xml=>AndroidManifest.xml", "multiproject/main.properties=>project.properties", "multiproject/MainCode.java.txt=>src/foo/main/MainCode.java" ); File library = getProjectDir("LibraryProject", // Library project "multiproject/library-manifest.xml=>AndroidManifest.xml", "multiproject/library.properties=>project.properties", "multiproject/LibraryCode.java.txt=>src/foo/library/LibraryCode.java", "multiproject/strings.xml=>res/values/strings.xml" ); assertEquals("" + "LibraryProject/res/values/strings.xml:4: Error: Resource named 'app_name' does not start with the project's resource prefix 'unit_test_prefix_'; rename to 'unit_test_prefix_app_name' ? [ResourceName]\n" + " <string name=\"app_name\">LibraryProject</string>\n" + " ~~~~~~~~~~~~~~~\n" + "LibraryProject/res/values/strings.xml:5: Error: Resource named 'string1' does not start with the project's resource prefix 'unit_test_prefix_'; rename to 'unit_test_prefix_string1' ? [ResourceName]\n" + " <string name=\"string1\">String 1</string>\n" + " ~~~~~~~~~~~~~~\n" + "LibraryProject/res/values/strings.xml:6: Error: Resource named 'string2' does not start with the project's resource prefix 'unit_test_prefix_'; rename to 'unit_test_prefix_string2' ? [ResourceName]\n" + " <string name=\"string2\">String 2</string>\n" + " ~~~~~~~~~~~~~~\n" + "LibraryProject/res/values/strings.xml:7: Error: Resource named 'string3' does not start with the project's resource prefix 'unit_test_prefix_'; rename to 'unit_test_prefix_string3' ? [ResourceName]\n" + " <string name=\"string3\">String 3</string>\n" + " ~~~~~~~~~~~~~~\n" + "4 errors, 0 warnings\n", checkLint(Arrays.asList(master, library)).replace("/TESTROOT/","")); } // TODO: Test suppressing root level tag @Override protected TestLintClient createClient() { return new TestLintClient() { @NonNull @Override protected Project createProject(@NonNull File dir, @NonNull File referenceDir) { return new Project(this, dir, referenceDir) { @Override public boolean isGradleProject() { return true; } @Nullable @Override public AndroidProject getGradleProjectModel() { AndroidProject project = mock(AndroidProject.class); when(project.getResourcePrefix()).thenReturn("unit_test_prefix_"); return project; } }; } }; } }