blob: ccfb990ec65f5b9fd33d91034da0443bbd95e196 [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 com.android.tools.lint.detector.api.Detector;
import org.intellij.lang.annotations.Language;
/** Tests for {@link VectorDetector}. */
public class VectorDetectorTest extends AbstractCheckTest {
@Override
protected Detector getDetector() {
return new VectorDetector();
}
@Language("XML")
private static final String VECTOR =
""
+ "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
+ " android:height=\"76dp\"\n"
+ " android:width=\"76dp\"\n"
+ " android:viewportHeight=\"48\"\n"
+ " android:viewportWidth=\"48\"\n"
+ " android:autoMirrored=\"true\"\n"
+ " android:tint=\"?attr/colorControlActivated\">\n"
+ "\n"
+ " <clip-path android:pathData=\"M10,10h40v30h-40z\"/>\n"
+ "\n"
+ " <group\n"
+ " android:name=\"root\"\n"
+ " android:translateX=\"24.0\"\n"
+ " android:translateY=\"24.0\" >\n"
+ " <path\n"
+ " android:name=\"progressBar\"\n"
+ " android:fillColor=\"#00000000\"\n"
+ " android:pathData=\"M0, 0 m 0, -19 a 19,19 0 1,1 0,38 a 19,19 0 1,1 0,-38\"\n"
+ " android:strokeColor=\"@color/white\"\n"
+ " android:strokeLineCap=\"square\"\n"
+ " android:strokeLineJoin=\"miter\"\n"
+ " android:strokeWidth=\"4\"\n"
+ " android:trimPathEnd=\"0\"\n"
+ " android:trimPathOffset=\"0\"\n"
+ " android:trimPathStart=\"0\" />\n"
+ " </group>\n"
+ "\n"
+ "</vector>";
@Language("XML")
private static final String VECTOR_WITH_GRADIENT =
""
+ "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
+ " xmlns:aapt=\"http://schemas.android.com/aapt\"\n"
+ " android:height=\"76dp\"\n"
+ " android:width=\"76dp\"\n"
+ " android:viewportHeight=\"48\"\n"
+ " android:viewportWidth=\"48\"\n"
+ " android:autoMirrored=\"true\"\n"
+ " android:tint=\"?attr/colorControlActivated\">\n"
+ "\n"
+ " <clip-path android:pathData=\"M10,10h40v30h-40z\"/>\n"
+ "\n"
+ " <group\n"
+ " android:name=\"root\"\n"
+ " android:translateX=\"24.0\"\n"
+ " android:translateY=\"24.0\" >\n"
+ " <path android:pathData=\"M10,10h40v30h-40z\">\n"
+ " <aapt:attr name=\"android:fillColor\">\n"
+ " <gradient android:startY=\"10\" android:startX=\"10\" android:endY=\"40\" android:endX=\"10\">\n"
+ " <item android:offset=\"0\" android:color=\"#FFFF0000\"/>\n"
+ " <item android:offset=\"1\" android:color=\"#FFFFFF00\"/>\n"
+ " </gradient>\n"
+ " </aapt:attr>\n"
+ " </path>\n"
+ " </group>\n"
+ "\n"
+ "</vector>";
@Language("XML")
private static final String VECTOR_WITH_FILLTYPE =
""
+ "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
+ " android:height=\"76dp\"\n"
+ " android:width=\"76dp\"\n"
+ " android:viewportHeight=\"48\"\n"
+ " android:viewportWidth=\"48\"\n"
+ " android:autoMirrored=\"true\"\n"
+ " android:tint=\"?attr/colorControlActivated\">\n"
+ "\n"
+ " <clip-path android:pathData=\"M10,10h40v30h-40z\"/>\n"
+ "\n"
+ " <group\n"
+ " android:name=\"root\"\n"
+ " android:translateX=\"24.0\"\n"
+ " android:translateY=\"24.0\" >\n"
+ " <path android:pathData=\"M10,10h40v30h-40z\""
+ " android:fillColor=\"#00FF00\"\n"
+ " android:fillType=\"oddEven\"/>\n"
+ " </group>\n"
+ "\n"
+ "</vector>";
public void testWarn() {
String expected =
""
+ "src/main/res/drawable/foo.xml:6: Warning: This attribute is not supported in images generated from this vector icon for API < 21; check generated icon to make sure it looks acceptable [VectorRaster]\n"
+ " android:autoMirrored=\"true\"\n"
+ " ~~~~~~~~~~~~~~~~~~~~\n"
+ "src/main/res/drawable/foo.xml:7: Warning: Resource references will not work correctly in images generated for this vector icon for API < 21; check generated icon to make sure it looks acceptable [VectorRaster]\n"
+ " android:tint=\"?attr/colorControlActivated\">\n"
+ " ~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"
+ "src/main/res/drawable/foo.xml:9: Warning: This tag is not supported in images generated from this vector icon for API < 21; check generated icon to make sure it looks acceptable [VectorRaster]\n"
+ " <clip-path android:pathData=\"M10,10h40v30h-40z\"/>\n"
+ " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"
+ "src/main/res/drawable/foo.xml:11: Warning: Update Gradle plugin version to 1.5+ to correctly handle <group> tags in generated bitmaps [VectorRaster]\n"
+ " <group\n"
+ " ~~~~~\n"
+ "src/main/res/drawable/foo.xml:19: Warning: Resource references will not work correctly in images generated for this vector icon for API < 21; check generated icon to make sure it looks acceptable [VectorRaster]\n"
+ " android:strokeColor=\"@color/white\"\n"
+ " ~~~~~~~~~~~~\n"
+ "src/main/res/drawable/foo.xml:23: Warning: This attribute is not supported in images generated from this vector icon for API < 21; check generated icon to make sure it looks acceptable [VectorRaster]\n"
+ " android:trimPathEnd=\"0\"\n"
+ " ~~~~~~~~~~~~~~~~~~~\n"
+ "src/main/res/drawable/foo.xml:24: Warning: This attribute is not supported in images generated from this vector icon for API < 21; check generated icon to make sure it looks acceptable [VectorRaster]\n"
+ " android:trimPathOffset=\"0\"\n"
+ " ~~~~~~~~~~~~~~~~~~~~~~\n"
+ "src/main/res/drawable/foo.xml:25: Warning: This attribute is not supported in images generated from this vector icon for API < 21; check generated icon to make sure it looks acceptable [VectorRaster]\n"
+ " android:trimPathStart=\"0\" />\n"
+ " ~~~~~~~~~~~~~~~~~~~~~\n"
+ "0 errors, 8 warnings";
//noinspection all // Sample code
lint().files(
manifest().minSdk(14),
xml("src/main/res/drawable/foo.xml", VECTOR),
gradle(
""
+ "buildscript {\n"
+ " dependencies {\n"
+ " classpath 'com.android.tools.build:gradle:1.4.0-alpha2'\n"
+ " }\n"
+ "}\n"))
.run()
.expect(expected);
}
public void testNoWarningsWithMinSdk21() {
//noinspection all // Sample code
lint().files(
manifest().minSdk(21),
xml("src/main/res/drawable/foo.xml", VECTOR),
gradle(
""
+ "buildscript {\n"
+ " dependencies {\n"
+ " classpath 'com.android.tools.build:gradle:1.4.0-alpha2'\n"
+ " }\n"
+ "}\n"))
.run()
.expectClean();
}
public void testNoWarningsInV21Folder() {
lint().files(
manifest().minSdk(14),
xml("src/main/res/drawable-v21/foo.xml", VECTOR),
gradle(
""
+ "buildscript {\n"
+ " dependencies {\n"
+ " classpath 'com.android.tools.build:gradle:1.4.0-alpha2'\n"
+ " }\n"
+ "}\n"))
.run()
.expectClean();
}
public void testNoGroupWarningWithPlugin15() {
lint().files(
manifest().minSdk(14),
xml(
"src/main/res/drawable/foo.xml",
""
+ "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
+ " android:height=\"76dp\"\n"
+ " android:width=\"76dp\"\n"
+ " android:viewportHeight=\"48\"\n"
+ " android:viewportWidth=\"48\">\n"
+ "\n"
+ " <group />"
+ "\n"
+ "</vector>"
+ ""),
gradle(
""
+ "buildscript {\n"
+ " dependencies {\n"
+ " classpath 'com.android.tools.build:gradle:1.5.0-alpha1'\n"
+ " }\n"
+ "}\n"))
.run()
.expectClean();
}
public void testNoWarningsWithSupportLibVectors() {
// Regression test for https://code.google.com/p/android/issues/detail?id=206005
lint().files(
manifest().minSdk(14),
xml("src/main/res/drawable/foo.xml", VECTOR),
gradle(
""
+ "buildscript {\n"
+ " dependencies {\n"
+ " classpath 'com.android.tools.build:gradle:2.0.0'\n"
+ " }\n"
+ "}\n"
+ "android.defaultConfig.vectorDrawables.useSupportLibrary = true\n"))
.run()
.expectClean();
}
public void testWarnWithGradient() {
String expected =
""
+ "src/main/res/drawable/foo.xml:7: Warning: This attribute is not supported in images generated from this vector icon for API < 24; check generated icon to make sure it looks acceptable [VectorRaster]\n"
+ " android:autoMirrored=\"true\"\n"
+ " ~~~~~~~~~~~~~~~~~~~~\n"
+ "src/main/res/drawable/foo.xml:8: Warning: Resource references will not work correctly in images generated for this vector icon for API < 24; check generated icon to make sure it looks acceptable [VectorRaster]\n"
+ " android:tint=\"?attr/colorControlActivated\">\n"
+ " ~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"
+ "src/main/res/drawable/foo.xml:10: Warning: This tag is not supported in images generated from this vector icon for API < 24; check generated icon to make sure it looks acceptable [VectorRaster]\n"
+ " <clip-path android:pathData=\"M10,10h40v30h-40z\"/>\n"
+ " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"
+ "0 errors, 3 warnings\n";
//noinspection all // Sample code
lint().files(
manifest().minSdk(23),
xml("src/main/res/drawable/foo.xml", VECTOR_WITH_GRADIENT),
gradle(
""
+ "buildscript {\n"
+ " dependencies {\n"
+ " classpath 'com.android.tools.build:gradle:3.1.0-alpha7'\n"
+ " }\n"
+ "}\n"))
.run()
.expect(expected);
}
public void testNoWarningsWithGradientAndMinSdk24() {
//noinspection all // Sample code
lint().files(
manifest().minSdk(24),
xml("src/main/res/drawable/foo.xml", VECTOR_WITH_GRADIENT),
gradle(
""
+ "buildscript {\n"
+ " dependencies {\n"
+ " classpath 'com.android.tools.build:gradle:3.1.0-alpha7'\n"
+ " }\n"
+ "}\n"))
.run()
.expectClean();
}
public void testWarnWithFillType() {
String expected =
""
+ "src/main/res/drawable/foo.xml:6: Warning: This attribute is not supported in images generated from this vector icon for API < 24; check generated icon to make sure it looks acceptable [VectorRaster]\n"
+ " android:autoMirrored=\"true\"\n"
+ " ~~~~~~~~~~~~~~~~~~~~\n"
+ "src/main/res/drawable/foo.xml:7: Warning: Resource references will not work correctly in images generated for this vector icon for API < 24; check generated icon to make sure it looks acceptable [VectorRaster]\n"
+ " android:tint=\"?attr/colorControlActivated\">\n"
+ " ~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"
+ "src/main/res/drawable/foo.xml:9: Warning: This tag is not supported in images generated from this vector icon for API < 24; check generated icon to make sure it looks acceptable [VectorRaster]\n"
+ " <clip-path android:pathData=\"M10,10h40v30h-40z\"/>\n"
+ " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"
+ "0 errors, 3 warnings\n";
//noinspection all // Sample code
lint().files(
manifest().minSdk(23),
xml("src/main/res/drawable/foo.xml", VECTOR_WITH_FILLTYPE),
gradle(
""
+ "buildscript {\n"
+ " dependencies {\n"
+ " classpath 'com.android.tools.build:gradle:3.2.0-alpha1'\n"
+ " }\n"
+ "}\n"))
.run()
.expect(expected);
}
public void testNoWarningsWithFillTypeAndMinSdk24() {
//noinspection all // Sample code
lint().files(
manifest().minSdk(24),
xml("src/main/res/drawable/foo.xml", VECTOR_WITH_FILLTYPE),
gradle(
""
+ "buildscript {\n"
+ " dependencies {\n"
+ " classpath 'com.android.tools.build:gradle:3.2.0-alpha1'\n"
+ " }\n"
+ "}\n"))
.run()
.expectClean();
}
public void testNoWarningsWithFillTypeAndSupportLibrary() {
//noinspection all // Sample code
lint().files(
manifest().minSdk(23),
xml("src/main/res/drawable/foo.xml", VECTOR_WITH_FILLTYPE),
gradle(
""
+ "buildscript {\n"
+ " dependencies {\n"
+ " classpath 'com.android.tools.build:gradle:3.2.0-alpha1'\n"
+ " }\n"
+ "}\n"
+ "android.defaultConfig.vectorDrawables.useSupportLibrary = true\n"))
.run()
.expectClean();
}
public void testLargeIcon() {
// Regression test for https://issuetracker.google.com/112147574
// Check that images are at most 200x200
String expected =
""
+ "res/drawable/foo.xml:4: Warning: Limit vector icons sizes to 200\u00D7200 to keep icon drawing fast; see https://developer.android.com/studio/write/vector-asset-studio#when for more [VectorRaster]\n"
+ " android:width=\"276dp\"\n"
+ " ~~~~~\n"
+ "0 errors, 1 warnings";
//noinspection all // Sample code
lint().files(
manifest().minSdk(23),
xml(
"res/drawable/foo.xml",
""
+ "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
+ " xmlns:aapt=\"http://schemas.android.com/aapt\"\n"
+ " android:height=\"276dp\"\n"
+ " android:width=\"276dp\"\n"
+ " android:viewportHeight=\"48\"\n"
+ " android:viewportWidth=\"48\"\n"
+ " android:autoMirrored=\"true\"\n"
+ " android:tint=\"?attr/colorControlActivated\"/>\n"))
.run()
.expect(expected);
}
public void testLargeIconHeight() {
// Check that the height is at most 200 too
String expected =
""
+ "res/drawable/foo.xml:4: Warning: Limit vector icons sizes to 200×200 to keep icon drawing fast; see https://developer.android.com/studio/write/vector-asset-studio#when for more [VectorRaster]\n"
+ " android:height=\"276dp\"\n"
+ " ~~~~~\n"
+ "0 errors, 1 warnings";
//noinspection all // Sample code
lint().files(
manifest().minSdk(23),
xml(
"res/drawable/foo.xml",
""
+ "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
+ " xmlns:aapt=\"http://schemas.android.com/aapt\"\n"
+ " android:width=\"176dp\"\n"
+ " android:height=\"276dp\"\n"
+ " android:viewportHeight=\"48\"\n"
+ " android:viewportWidth=\"48\"\n"
+ " android:autoMirrored=\"true\"\n"
+ " android:tint=\"?attr/colorControlActivated\"/>\n"))
.run()
.expect(expected);
}
}