| /* |
| * Copyright (C) 2017 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 com.android.SdkConstants.APPCOMPAT_LIB_ARTIFACT_ID; |
| import static com.android.ide.common.fonts.FontProviderKt.GOOGLE_FONT_AUTHORITY; |
| import static com.android.ide.common.fonts.FontProviderKt.GOOGLE_FONT_CERTIFICATE; |
| import static com.android.ide.common.fonts.FontProviderKt.GOOGLE_FONT_DEVELOPMENT_CERTIFICATE; |
| import static com.android.ide.common.fonts.FontProviderKt.GOOGLE_FONT_NAME; |
| import static com.android.ide.common.fonts.FontProviderKt.GOOGLE_FONT_PACKAGE_NAME; |
| import static com.android.ide.common.fonts.FontProviderKt.GOOGLE_FONT_URL; |
| |
| import com.android.annotations.NonNull; |
| import com.android.annotations.Nullable; |
| import com.android.ide.common.fonts.FontLoader; |
| import com.android.testutils.TestUtils; |
| import com.android.tools.lint.detector.api.Context; |
| import com.android.tools.lint.detector.api.Detector; |
| import com.android.tools.lint.detector.api.Issue; |
| import com.android.tools.lint.detector.api.LintFix; |
| import com.android.tools.lint.detector.api.Location; |
| import com.android.tools.lint.detector.api.Severity; |
| import com.intellij.openapi.util.io.FileUtil; |
| import java.io.File; |
| import java.io.IOException; |
| |
| public class FontDetectorTest extends AbstractCheckTest { |
| private static File ourMockSdk; |
| |
| @Override |
| protected void setUp() throws Exception { |
| super.setUp(); |
| FontLoader.getInstance(getSdk()); |
| } |
| |
| @Override |
| protected Detector getDetector() { |
| return new FontDetector(); |
| } |
| |
| public void testBothDownloadableAndFontFamilyPresent() { |
| String expected = |
| "" |
| + "res/font/font1.xml:4: Error: A downloadable font cannot have a <font> sub tag [FontValidationError]\n" |
| + " <font\n" |
| + " ~~~~\n" |
| + "1 errors, 0 warnings"; |
| String expectedFix = |
| "" |
| + "Fix for res/font/font1.xml line 3: Delete:\n" |
| + "@@ -4 +4\n" |
| + "- <font\n" |
| + "- android:fontStyle=\"normal\"\n" |
| + "- android:fontWeight=\"400\"\n" |
| + "- android:font=\"@font/monserrat\" />\n"; |
| //noinspection all // Sample code |
| lint().files( |
| manifest().minSdk(28), |
| xml( |
| "res/font/font1.xml", |
| "" |
| + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" |
| + "<font-family xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" |
| + " android:fontProviderQuery=\"Monserrat\">\n" |
| + " <font\n" |
| + " android:fontStyle=\"normal\"\n" |
| + " android:fontWeight=\"400\"\n" |
| + " android:font=\"@font/monserrat\" />\n" |
| + "</font-family>" |
| + "\n")) |
| .run() |
| .expect(expected) |
| .expectFixDiffs(expectedFix); |
| } |
| |
| public void testAppCompatVersion() { |
| String expected = |
| "" |
| + "src/main/res/font/font1.xml:2: Error: Using version 26.0.0-alpha7 of the appcompat-v7 library. Required version for using downloadable fonts: 26.0.0 or higher. [FontValidationError]\n" |
| + "<font-family xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n" |
| + " ~~~~~~~~~~~\n" |
| + "1 errors, 0 warnings"; |
| //noinspection all // Sample code |
| lint().files( |
| manifest().minSdk(25), |
| xml( |
| "src/main/res/font/font1.xml", |
| "" |
| + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" |
| + "<font-family xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n" |
| + " app:fontProviderAuthority=\"com.google.android.gms.fonts\"\n" |
| + " app:fontProviderQuery=\"Monserrat\"\n" |
| + " app:fontProviderPackage=\"com.google.android.gms\"\n" |
| + " app:fontProviderCerts=\"@array/certs\">\n" |
| + "</font-family>" |
| + "\n"), |
| gradle( |
| "" |
| + "apply plugin: 'com.android.application'\n" |
| + "\n" |
| + "dependencies {\n" |
| + " compile 'com.android.support:appcompat-v7:26.0.0-alpha7'\n" |
| + "}")) |
| .checkMessage(this::checkReportedError) |
| .run() |
| .expect(expected); |
| } |
| |
| @Override |
| protected void checkReportedError( |
| @NonNull Context context, |
| @NonNull Issue issue, |
| @NonNull Severity severity, |
| @NonNull Location location, |
| @NonNull String message, |
| @Nullable LintFix fixData) { |
| assertTrue(fixData instanceof LintFix.DataMap); |
| LintFix.DataMap map = (LintFix.DataMap) fixData; |
| assertEquals(map.get(String.class), APPCOMPAT_LIB_ARTIFACT_ID); |
| } |
| |
| public void testAppAttributesPresentOnLaterApi() { |
| String expected = |
| "" |
| + "res/font/font1.xml:8: Warning: For minSdkVersion=" |
| + FontDetector.FUTURE_API_VERSION_WHERE_DOWNLOADABLE_FONTS_WORK_IN_FRAMEWORK |
| + " only android: attributes should be used [FontValidationWarning]\n" |
| + " app:fontProviderCerts=\"@array/certs\">\n" |
| + " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" |
| + "0 errors, 1 warnings\n"; |
| String expectedFix = |
| "" |
| + "Fix for res/font/font1.xml line 7: Delete fontProviderCerts:\n" |
| + "@@ -7 +7\n" |
| + "- android:fontProviderQuery=\"Monserrat\"\n" |
| + "- app:fontProviderCerts=\"@array/certs\" >\n" |
| + "+ android:fontProviderQuery=\"Monserrat\" >\n"; |
| //noinspection all // Sample code |
| lint().files( |
| manifest() |
| .minSdk( |
| FontDetector |
| .FUTURE_API_VERSION_WHERE_DOWNLOADABLE_FONTS_WORK_IN_FRAMEWORK), |
| xml( |
| "res/font/font1.xml", |
| "" |
| + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" |
| + "<font-family xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" |
| + " xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n" |
| + " android:fontProviderAuthority=\"com.google.android.gms.fonts\"\n" |
| + " android:fontProviderQuery=\"Monserrat\"\n" |
| + " android:fontProviderPackage=\"com.google.android.gms\"\n" |
| + " android:fontProviderCerts=\"@array/certs\"\n" |
| + " app:fontProviderCerts=\"@array/certs\">\n" |
| + "</font-family>" |
| + "\n")) |
| .run() |
| .expect(expected) |
| .expectFixDiffs(expectedFix); |
| } |
| |
| public void testAndroidAttributesPresentOnApi27() { |
| //noinspection all // Sample code |
| String expected = |
| "" |
| + "res/font/font1.xml:8: Warning: For minSdkVersion=27 only app: attributes should be used [FontValidationWarning]\n" |
| + " android:fontProviderAuthority=\"com.google.android.gms.fonts\">\n" |
| + " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" |
| + "0 errors, 1 warnings\n"; |
| String expectedFix = |
| "" |
| + "Fix for res/font/font1.xml line 7: Delete fontProviderAuthority:\n" |
| + "@@ -4 +4\n" |
| + "- android:fontProviderAuthority=\"com.google.android.gms.fonts\"\n"; |
| lint().files( |
| manifest().minSdk(27), |
| xml( |
| "res/font/font1.xml", |
| "" |
| + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" |
| + "<font-family xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" |
| + " xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n" |
| + " app:fontProviderAuthority=\"com.google.android.gms.fonts\"\n" |
| + " app:fontProviderQuery=\"Monserrat\"\n" |
| + " app:fontProviderPackage=\"com.google.android.gms\"\n" |
| + " app:fontProviderCerts=\"@array/certs\"\n" |
| + " android:fontProviderAuthority=\"com.google.android.gms.fonts\">\n" |
| + "</font-family>" |
| + "\n")) |
| .run() |
| .expect(expected) |
| .expectFixDiffs(expectedFix); |
| } |
| |
| public void testMissingAttributesOnLaterApi() { |
| //noinspection all // Sample code |
| String expected = |
| "" |
| + "res/font/font1.xml:2: Error: Missing required attributes: android:fontProviderAuthority, android:fontProviderPackage, android:fontProviderCerts [FontValidationError]\n" |
| + "<font-family xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" |
| + " ~~~~~~~~~~~\n" |
| + "1 errors, 0 warnings"; |
| String expectedFix = |
| "" |
| + "Fix for res/font/font1.xml line 1: Set fontProviderAuthority=\"com.google.android.gms.fonts\":\n" |
| + "@@ -3 +3\n" |
| + "+ android:fontProviderAuthority=\"com.google.android.gms.fonts\"\n" |
| + "+ android:fontProviderCerts=\"@array/com_google_android_gms_fonts_certs\"\n" |
| + "+ android:fontProviderPackage=\"com.google.android.gms\"\n"; |
| lint().files( |
| manifest() |
| .minSdk( |
| FontDetector |
| .FUTURE_API_VERSION_WHERE_DOWNLOADABLE_FONTS_WORK_IN_FRAMEWORK), |
| xml( |
| "res/font/font1.xml", |
| "" |
| + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" |
| + "<font-family xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" |
| + " android:fontProviderQuery=\"Monserrat\">\n" |
| + "</font-family>" |
| + "\n")) |
| .run() |
| .expect(expected) |
| .expectFixDiffs(expectedFix); |
| } |
| |
| public void testMissingAttributesOnLaterApiWithMultipleKnownProviders() throws Exception { |
| //noinspection all // Sample code |
| String expected = |
| "" |
| + "res/font/font1.xml:2: Error: Missing required attributes: android:fontProviderAuthority, android:fontProviderPackage, android:fontProviderCerts [FontValidationError]\n" |
| + "<font-family xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" |
| + " ~~~~~~~~~~~\n" |
| + "1 errors, 0 warnings"; |
| String expectedFix = |
| "" |
| + "Fix for res/font/font1.xml line 1: Set fontProviderAuthority:\n" |
| + "@@ -3 +3\n" |
| + "+ android:fontProviderAuthority=\"[TODO]|\"\n" |
| + "+ android:fontProviderCerts=\"[TODO]|\"\n" |
| + "+ android:fontProviderPackage=\"[TODO]|\"\n"; |
| lint().files( |
| manifest() |
| .minSdk( |
| FontDetector |
| .FUTURE_API_VERSION_WHERE_DOWNLOADABLE_FONTS_WORK_IN_FRAMEWORK), |
| xml( |
| "res/font/font1.xml", |
| "" |
| + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" |
| + "<font-family xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" |
| + " android:fontProviderQuery=\"Monserrat\">\n" |
| + "</font-family>" |
| + "\n")) |
| .sdkHome(getMockSdkWithFontProviders()) |
| .run() |
| .expect(expected) |
| .expectFixDiffs(expectedFix); |
| } |
| |
| public void testMissingAttributesOnApi25() { |
| //noinspection all // Sample code |
| String expected = |
| "" |
| + "res/font/font1.xml:2: Error: Missing required attributes: app:fontProviderAuthority, app:fontProviderPackage, app:fontProviderCerts [FontValidationError]\n" |
| + "<font-family xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n" |
| + " ~~~~~~~~~~~\n" |
| + "1 errors, 0 warnings"; |
| String expectedFix = |
| "" |
| + "Fix for res/font/font1.xml line 1: Set fontProviderAuthority=\"com.google.android.gms.fonts\":\n" |
| + "@@ -3 +3\n" |
| + "+ app:fontProviderAuthority=\"com.google.android.gms.fonts\"\n" |
| + "+ app:fontProviderCerts=\"@array/com_google_android_gms_fonts_certs\"\n" |
| + "+ app:fontProviderPackage=\"com.google.android.gms\"\n"; |
| lint().files( |
| manifest().minSdk(25), |
| xml( |
| "res/font/font1.xml", |
| "" |
| + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" |
| + "<font-family xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n" |
| + " app:fontProviderQuery=\"Monserrat\">\n" |
| + "</font-family>" |
| + "\n")) |
| .run() |
| .expect(expected) |
| .expectFixDiffs(expectedFix); |
| } |
| |
| public void testUnknownAuthorityOnApi25() { |
| //noinspection all // Sample code |
| String expected = |
| "" |
| + "res/font/font1.xml:3: Error: Unknown font provider authority [FontValidationError]\n" |
| + " app:fontProviderAuthority=\"com.google.android.gms.helpme\"\n" |
| + " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" |
| + "1 errors, 0 warnings"; |
| String expectedFix = |
| "" |
| + "Fix for res/font/font1.xml line 2: Replace with com.google.android.gms.fonts:\n" |
| + "@@ -3 +3\n" |
| + "- app:fontProviderAuthority=\"com.google.android.gms.helpme\"\n" |
| + "+ app:fontProviderAuthority=\"com.google.android.gms.fonts\"\n"; |
| lint().files( |
| manifest().minSdk(25), |
| xml( |
| "res/font/font1.xml", |
| "" |
| + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" |
| + "<font-family xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n" |
| + " app:fontProviderAuthority=\"com.google.android.gms.helpme\"\n" |
| + " app:fontProviderPackage=\"com.google.android.gms\"\n" |
| + " app:fontProviderCerts=\"@array/certs\"\n" |
| + " app:fontProviderQuery=\"Monserrat\">\n" |
| + "</font-family>" |
| + "\n")) |
| .run() |
| .expect(expected) |
| .expectFixDiffs(expectedFix); |
| } |
| |
| public void testUnknownAuthorityOnLaterApi() { |
| //noinspection all // Sample code |
| String expected = |
| "" |
| + "res/font/font1.xml:3: Error: Unknown font provider authority [FontValidationError]\n" |
| + " android:fontProviderAuthority=\"com.google.android.gms.helpme\"\n" |
| + " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" |
| + "1 errors, 0 warnings"; |
| String expectedFix = |
| "" |
| + "Fix for res/font/font1.xml line 2: Replace with com.google.android.gms.fonts:\n" |
| + "@@ -3 +3\n" |
| + "- android:fontProviderAuthority=\"com.google.android.gms.helpme\"\n" |
| + "+ android:fontProviderAuthority=\"com.google.android.gms.fonts\"\n"; |
| lint().files( |
| manifest() |
| .minSdk( |
| FontDetector |
| .FUTURE_API_VERSION_WHERE_DOWNLOADABLE_FONTS_WORK_IN_FRAMEWORK), |
| xml( |
| "res/font/font1.xml", |
| "" |
| + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" |
| + "<font-family xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" |
| + " android:fontProviderAuthority=\"com.google.android.gms.helpme\"\n" |
| + " android:fontProviderPackage=\"com.google.android.gms\"\n" |
| + " android:fontProviderCerts=\"@array/certs\"\n" |
| + " android:fontProviderQuery=\"Monserrat\">\n" |
| + "</font-family>" |
| + "\n")) |
| .run() |
| .expect(expected) |
| .expectFixDiffs(expectedFix); |
| } |
| |
| public void testPackageMismatchOnApi25() { |
| String expected = |
| "" |
| + "res/font/font1.xml:4: Error: Unexpected font provider package [FontValidationError]\n" |
| + " app:fontProviderPackage=\"com.google.android.gms.fonts\"\n" |
| + " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" |
| + "1 errors, 0 warnings"; |
| String expectedFix = |
| "" |
| + "Fix for res/font/font1.xml line 3: Replace with com.google.android.gms:\n" |
| + "@@ -4 +4\n" |
| + "- app:fontProviderPackage=\"com.google.android.gms.fonts\"\n" |
| + "+ app:fontProviderPackage=\"com.google.android.gms\"\n"; |
| //noinspection all // Sample code |
| lint().files( |
| manifest().minSdk(25), |
| xml( |
| "res/font/font1.xml", |
| "" |
| + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" |
| + "<font-family xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n" |
| + " app:fontProviderAuthority=\"com.google.android.gms.fonts\"\n" |
| + " app:fontProviderPackage=\"com.google.android.gms.fonts\"\n" |
| + " app:fontProviderCerts=\"@array/certs\"\n" |
| + " app:fontProviderQuery=\"Monserrat\">\n" |
| + "</font-family>" |
| + "\n")) |
| .run() |
| .expect(expected) |
| .expectFixDiffs(expectedFix); |
| } |
| |
| public void testPackageMismatchOnLaterApi() { |
| //noinspection all // Sample code |
| String expected = |
| "" |
| + "res/font/font1.xml:4: Error: Unexpected font provider package [FontValidationError]\n" |
| + " android:fontProviderPackage=\"com.google.android.gms.fonts\"\n" |
| + " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" |
| + "1 errors, 0 warnings"; |
| String expectedFix = |
| "" |
| + "Fix for res/font/font1.xml line 3: Replace with com.google.android.gms:\n" |
| + "@@ -4 +4\n" |
| + "- android:fontProviderPackage=\"com.google.android.gms.fonts\"\n" |
| + "+ android:fontProviderPackage=\"com.google.android.gms\"\n"; |
| lint().files( |
| manifest() |
| .minSdk( |
| FontDetector |
| .FUTURE_API_VERSION_WHERE_DOWNLOADABLE_FONTS_WORK_IN_FRAMEWORK), |
| xml( |
| "res/font/font1.xml", |
| "" |
| + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" |
| + "<font-family xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" |
| + " android:fontProviderAuthority=\"com.google.android.gms.fonts\"\n" |
| + " android:fontProviderPackage=\"com.google.android.gms.fonts\"\n" |
| + " android:fontProviderCerts=\"@array/certs\"\n" |
| + " android:fontProviderQuery=\"Monserrat\">\n" |
| + "</font-family>" |
| + "\n")) |
| .run() |
| .expect(expected) |
| .expectFixDiffs(expectedFix); |
| } |
| |
| public void testMissingQuery() { |
| //noinspection all // Sample code |
| String expected = |
| "" |
| + "res/font/font1.xml:6: Error: Missing provider query [FontValidationError]\n" |
| + " app:fontProviderQuery=\"\">\n" |
| + " ~~~~~~~~~~~~~~~~~~~~~~~~\n" |
| + "1 errors, 0 warnings\n"; |
| String expectedFix = |
| "" |
| + "Fix for res/font/font1.xml line 5: Set fontProviderQuery:\n" |
| + "@@ -6 +6\n" |
| + "- app:fontProviderQuery=\"\" >\n" |
| + "+ app:fontProviderQuery=\"[TODO]|\" >\n"; |
| lint().files( |
| manifest().minSdk(28), |
| xml( |
| "res/font/font1.xml", |
| "" |
| + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" |
| + "<font-family xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n" |
| + " app:fontProviderAuthority=\"com.google.android.gms.fonts\"\n" |
| + " app:fontProviderPackage=\"com.google.android.gms\"\n" |
| + " app:fontProviderCerts=\"@array/certs\"\n" |
| + " app:fontProviderQuery=\"\">\n" |
| + "</font-family>" |
| + "\n")) |
| .run() |
| .expect(expected) |
| .expectFixDiffs(expectedFix); |
| } |
| |
| public void testQueryErrorV11() { |
| //noinspection all // Sample code |
| String expected = |
| "" |
| + "res/font/font1.xml:6: Error: Unexpected keyword: size expected one of: width, weight, italic, besteffort [FontValidationError]\n" |
| + " app:fontProviderQuery=\"name=Monserrat&size=15\">\n" |
| + " ~~~~~~~~~~~~~~~~~~~~~~\n" |
| + "1 errors, 0 warnings"; |
| lint().files( |
| manifest().minSdk(28), |
| xml( |
| "res/font/font1.xml", |
| "" |
| + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" |
| + "<font-family xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n" |
| + " app:fontProviderAuthority=\"com.google.android.gms.fonts\"\n" |
| + " app:fontProviderPackage=\"com.google.android.gms\"\n" |
| + " app:fontProviderCerts=\"@array/certs\"\n" |
| + " app:fontProviderQuery=\"name=Monserrat&size=15\">\n" |
| + "</font-family>" |
| + "\n")) |
| .run() |
| .expect(expected); |
| } |
| |
| public void testQueryErrorV12() { |
| //noinspection all // Sample code |
| String expected = |
| "" |
| + "res/font/font1.xml:6: Error: Unexpected keyword: Aladin expected one of: wght, wdth, ital, bold, exact, nearest [FontValidationError]\n" |
| + " app:fontProviderQuery=\"Monserrat:300i,Aladin:200\">\n" |
| + " ~~~~~~~~~~~~~~~~~~~~~~~~~\n" |
| + "1 errors, 0 warnings"; |
| lint().files( |
| manifest().minSdk(28), |
| xml( |
| "res/font/font1.xml", |
| "" |
| + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" |
| + "<font-family xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n" |
| + " app:fontProviderAuthority=\"com.google.android.gms.fonts\"\n" |
| + " app:fontProviderPackage=\"com.google.android.gms\"\n" |
| + " app:fontProviderCerts=\"@array/certs\"\n" |
| + " app:fontProviderQuery=\"Monserrat:300i,Aladin:200\">\n" |
| + "</font-family>" |
| + "\n")) |
| .run() |
| .expect(expected); |
| } |
| |
| public void testQueryUsingUnknownFont() throws Exception { |
| //noinspection all // Sample code |
| String expected = |
| "" |
| + "res/font/font1.xml:6: Error: Unknown font: NewUnknownFontName [FontValidationError]\n" |
| + " app:fontProviderQuery=\"NewUnknownFontName\">\n" |
| + " ~~~~~~~~~~~~~~~~~~\n" |
| + "1 errors, 0 warnings"; |
| lint().files( |
| manifest().minSdk(28), |
| xml( |
| "res/font/font1.xml", |
| "" |
| + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" |
| + "<font-family xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n" |
| + " app:fontProviderAuthority=\"com.google.android.gms.fonts\"\n" |
| + " app:fontProviderPackage=\"com.google.android.gms\"\n" |
| + " app:fontProviderCerts=\"@array/certs\"\n" |
| + " app:fontProviderQuery=\"NewUnknownFontName\">\n" |
| + "</font-family>" |
| + "\n")) |
| .sdkHome(getMockSdkWithFontProviders()) |
| .run() |
| .expect(expected); |
| } |
| |
| public void testQueryNearMatchWarning() throws Exception { |
| //noinspection all // Sample code |
| String expected = |
| "" |
| + "res/font/font1.xml:6: Warning: No exact match found for: Montserrat [FontValidationWarning]\n" |
| + " app:fontProviderQuery=\"name=Montserrat&weight=600\">\n" |
| + " ~~~~~~~~~~~~~~~~~~~~~~~~~~\n" |
| + "0 errors, 1 warnings"; |
| String expectedFix = |
| "" |
| + "Fix for res/font/font1.xml line 5: Replace with closest font: name=Montserrat&weight=700:\n" |
| + "@@ -6 +6\n" |
| + "- app:fontProviderQuery=\"name=Montserrat&weight=600\" >\n" |
| + "+ app:fontProviderQuery=\"name=Montserrat&weight=700\" >\n"; |
| lint().files( |
| manifest().minSdk(28), |
| xml( |
| "res/font/font1.xml", |
| "" |
| + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" |
| + "<font-family xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n" |
| + " app:fontProviderAuthority=\"com.google.android.gms.fonts\"\n" |
| + " app:fontProviderPackage=\"com.google.android.gms\"\n" |
| + " app:fontProviderCerts=\"@array/certs\"\n" |
| + " app:fontProviderQuery=\"name=Montserrat&weight=600\">\n" |
| + "</font-family>" |
| + "\n")) |
| .sdkHome(getMockSdkWithFontProviders()) |
| .run() |
| .expect(expected) |
| .expectFixDiffs(expectedFix); |
| } |
| |
| public void testQueryNearMatchError() throws Exception { |
| //noinspection all // Sample code |
| String expected = |
| "" |
| + "res/font/font1.xml:6: Error: No exact match found for: Montserrat [FontValidationError]\n" |
| + " app:fontProviderQuery=\"name=Montserrat&weight=600&besteffort=false\">\n" |
| + " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" |
| + "1 errors, 0 warnings"; |
| String expectedFix = |
| "" |
| + "Fix for res/font/font1.xml line 5: Replace with closest font: name=Montserrat&weight=700&besteffort=false:\n" |
| + "@@ -6 +6\n" |
| + "- app:fontProviderQuery=\"name=Montserrat&weight=600&besteffort=false\" >\n" |
| + "+ app:fontProviderQuery=\"name=Montserrat&weight=700&besteffort=false\" >\n"; |
| lint().files( |
| manifest().minSdk(28), |
| xml( |
| "res/font/font1.xml", |
| "" |
| + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" |
| + "<font-family xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n" |
| + " app:fontProviderAuthority=\"com.google.android.gms.fonts\"\n" |
| + " app:fontProviderPackage=\"com.google.android.gms\"\n" |
| + " app:fontProviderCerts=\"@array/certs\"\n" |
| + " app:fontProviderQuery=\"name=Montserrat&weight=600&besteffort=false\">\n" |
| + "</font-family>" |
| + "\n")) |
| .sdkHome(getMockSdkWithFontProviders()) |
| .run() |
| .expect(expected) |
| .expectFixDiffs(expectedFix); |
| } |
| |
| private static File getMockSdkWithFontProviders() throws IOException { |
| if (ourMockSdk == null) { |
| ourMockSdk = createMockSdkWithFontProviders(); |
| } |
| return ourMockSdk; |
| } |
| |
| private static File createMockSdkWithFontProviders() throws IOException { |
| File sdkRootDir = TestUtils.createTempDirDeletedOnExit(); |
| |
| File fontDir = new File(sdkRootDir, "fonts"); |
| File providersDir = new File(fontDir, "providers"); |
| File providersFile = new File(providersDir, "provider_directory.xml"); |
| |
| FileUtil.writeToFile( |
| providersFile, |
| "" |
| + "<provider_directory>\n" |
| + " <providers>\n" |
| + " <provider name=\"Alternate\" authority=\"com.alternate.font.provider\" package=\"com.alternate.font\" url=\"\" cert=\"\" dev_cert=\"\"/>\n" |
| + " <provider name=\"" |
| + GOOGLE_FONT_NAME |
| + "\" authority=\"" |
| + GOOGLE_FONT_AUTHORITY |
| + "\" package=\"" |
| + GOOGLE_FONT_PACKAGE_NAME |
| + "\" url=\"" |
| + GOOGLE_FONT_URL |
| + "\" cert=\"" |
| + GOOGLE_FONT_CERTIFICATE |
| + "\" dev_cert=\"" |
| + GOOGLE_FONT_DEVELOPMENT_CERTIFICATE |
| + "\"/>\n" |
| + " </providers>\n" |
| + "</provider_directory>\n"); |
| |
| File googleFontDir = new File(fontDir, GOOGLE_FONT_AUTHORITY); |
| File googleDirectory = new File(googleFontDir, "directory"); |
| File googleDirectoryFile = new File(googleDirectory, "font_directory.xml"); |
| |
| FileUtil.writeToFile( |
| googleDirectoryFile, |
| "" |
| + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" |
| + "<font_directory version='1'>\n" |
| + " <families>\n" |
| + " <family name='Dosis' menu='//fonts.gstatic.com/s/dosis/v6/0bOjty8DEhwcbM3d4ICpMQ.ttf'>\n" |
| + " <font weight='200' width='100.0' italic='0.0' styleName='ExtraLight' url='//fonts.gstatic.com/s/dosis/v6/ztftab0r6hcd7AeurUGrSQ.ttf'/>\n" |
| + " <font weight='300' width='100.0' italic='0.0' styleName='Light' url='//fonts.gstatic.com/s/dosis/v6/awIB6L0h5mb0plIKorXmuA.ttf'/>\n" |
| + " <font weight='400' width='100.0' italic='0.0' styleName='Regular' url='//fonts.gstatic.com/s/dosis/v6/rJRlixu-w0JZ1MyhJpao_Q.ttf'/>\n" |
| + " <font weight='500' width='100.0' italic='0.0' styleName='Medium' url='//fonts.gstatic.com/s/dosis/v6/ruEXDOFMxDPGnjCBKRqdAQ.ttf'/>\n" |
| + " <font weight='600' width='100.0' italic='0.0' styleName='SemiBold' url='//fonts.gstatic.com/s/dosis/v6/KNAswRNwm3tfONddYyidxg.ttf'/>\n" |
| + " <font weight='700' width='100.0' italic='0.0' styleName='Bold' url='//fonts.gstatic.com/s/dosis/v6/AEEAj0ONidK8NQQMBBlSig.ttf'/>\n" |
| + " <font weight='800' width='100.0' italic='0.0' styleName='ExtraBold' url='//fonts.gstatic.com/s/dosis/v6/nlrKd8E69vvUU39XGsvR7Q.ttf'/>\n" |
| + " </family>\n" |
| + " <family name='Montserrat' menu='//fonts.gstatic.com/s/montserrat/v10/sp_E9wlxrieAFN73uHUfti3USBnSvpkopQaUR-2r7iU.ttf'>\n" |
| + " <font weight='400' width='100.0' italic='0.0' styleName='Regular' url='//fonts.gstatic.com/s/montserrat/v10/Kqy6-utIpx_30Xzecmeo8_esZW2xOQ-xsNqO47m55DA.ttf'/>\n" |
| + " <font weight='700' width='100.0' italic='0.0' styleName='Bold' url='//fonts.gstatic.com/s/montserrat/v10/IQHow_FEYlDC4Gzy_m8fcgJKKGfqHaYFsRG-T3ceEVo.ttf'/>\n" |
| + " </family>\n" |
| + " </families>\n" |
| + "</font_directory>\n"); |
| |
| File alternateFontDir = new File(fontDir, "com.alternate.font.provider"); |
| File alternateDirectory = new File(alternateFontDir, "directory"); |
| File alternateDirectoryFile = new File(alternateDirectory, "font_directory.xml"); |
| |
| FileUtil.writeToFile( |
| alternateDirectoryFile, |
| "" |
| + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" |
| + "<font_directory version='1'>\n" |
| + " <families>\n" |
| + " <family name='BioRhyme' menu='//fonts.gstatic.com/s/biorhyme/v1/S5TAweMZQtbEzQHWntc2svesZW2xOQ-xsNqO47m55DA.ttf'>\n" |
| + " <font weight='200' width='100.0' italic='0.0' styleName='ExtraLight' url='//fonts.gstatic.com/s/biorhyme/v1/bj-6g_1gJHCc9xQZtLWL36CWcynf_cDxXwCLxiixG1c.ttf'/>\n" |
| + " <font weight='300' width='100.0' italic='0.0' styleName='Light' url='//fonts.gstatic.com/s/biorhyme/v1/jWqHmLFlu30n7xp12uZd8qCWcynf_cDxXwCLxiixG1c.ttf'/>\n" |
| + " <font weight='400' width='100.0' italic='0.0' styleName='Regular' url='//fonts.gstatic.com/s/biorhyme/v1/n6v5UkVPy_CjbP3fvsu1CA.ttf'/>\n" |
| + " <font weight='700' width='100.0' italic='0.0' styleName='Bold' url='//fonts.gstatic.com/s/biorhyme/v1/36KN76U1iKt5TFDm2lBz0KCWcynf_cDxXwCLxiixG1c.ttf'/>\n" |
| + " <font weight='800' width='100.0' italic='0.0' styleName='ExtraBold' url='//fonts.gstatic.com/s/biorhyme/v1/k6bYbUnESjLYnworWvSTL6CWcynf_cDxXwCLxiixG1c.ttf'/>\n" |
| + " <font weight='200' width='125.0' italic='0.0' styleName='Expanded ExtraLight' url='//fonts.gstatic.com/s/biorhymeexpanded/v1/FKL4Vyxmq2vsiDrSOzz2sC7oxZzNh3ej55UHm-HviBI.ttf'/>\n" |
| + " <font weight='300' width='125.0' italic='0.0' styleName='Expanded Light' url='//fonts.gstatic.com/s/biorhymeexpanded/v1/FKL4Vyxmq2vsiDrSOzz2sFu4cYPPksG4MRjB5UiYPPw.ttf'/>\n" |
| + " <font weight='400' width='125.0' italic='0.0' styleName='Expanded Regular' url='//fonts.gstatic.com/s/biorhymeexpanded/v1/hgBNpgjTRZzGmZxqN5OuVjndr_hij4ilAk2n1d1AhsE.ttf'/>\n" |
| + " <font weight='700' width='125.0' italic='0.0' styleName='Expanded Bold' url='//fonts.gstatic.com/s/biorhymeexpanded/v1/FKL4Vyxmq2vsiDrSOzz2sMVisRVfPEfQ0jijOMQbr0Q.ttf'/>\n" |
| + " <font weight='800' width='125.0' italic='0.0' styleName='Expanded ExtraBold' url='//fonts.gstatic.com/s/biorhymeexpanded/v1/FKL4Vyxmq2vsiDrSOzz2sIv1v1eCT6RPbcYZYQ1T1CE.ttf'/>\n" |
| + " </family>\n" |
| + " <family name='Biryani' menu='//fonts.gstatic.com/s/biryani/v1/rW_FlEaEcKjjRYlyQSNuAg.ttf'>\n" |
| + " <font weight='200' width='100.0' italic='0.0' styleName='ExtraLight' url='//fonts.gstatic.com/s/biryani/v1/Xx38YzyTFF8n6mRS1Yd88vesZW2xOQ-xsNqO47m55DA.ttf'/>\n" |
| + " <font weight='300' width='100.0' italic='0.0' styleName='Light' url='//fonts.gstatic.com/s/biryani/v1/u-bneRbizmFMd0VQp5Ze6vesZW2xOQ-xsNqO47m55DA.ttf'/>\n" |
| + " <font weight='400' width='100.0' italic='0.0' styleName='Regular' url='//fonts.gstatic.com/s/biryani/v1/W7bfR8-IY76Xz0QoB8L2xw.ttf'/>\n" |
| + " <font weight='600' width='100.0' italic='0.0' styleName='SemiBold' url='//fonts.gstatic.com/s/biryani/v1/1EdcPCVxBR2txgjrza6_YPesZW2xOQ-xsNqO47m55DA.ttf'/>\n" |
| + " <font weight='700' width='100.0' italic='0.0' styleName='Bold' url='//fonts.gstatic.com/s/biryani/v1/qN2MTZ0j1sKSCtfXLB2dR_esZW2xOQ-xsNqO47m55DA.ttf'/>\n" |
| + " <font weight='800' width='100.0' italic='0.0' styleName='ExtraBold' url='//fonts.gstatic.com/s/biryani/v1/DJyziS7FEy441v22InYdevesZW2xOQ-xsNqO47m55DA.ttf'/>\n" |
| + " <font weight='900' width='100.0' italic='0.0' styleName='Black' url='//fonts.gstatic.com/s/biryani/v1/trcLkrIut0lM_PPSyQfAMPesZW2xOQ-xsNqO47m55DA.ttf'/>\n" |
| + " </family>\n" |
| + " </families>\n" |
| + "</font_directory>\n"); |
| |
| return sdkRootDir; |
| } |
| } |