From 393db094dd089ea463bc1a215bd7971fd5feab42 Mon Sep 17 00:00:00 2001 From: Marcono1234 Date: Wed, 23 Aug 2023 01:31:56 +0200 Subject: [PATCH] Add test for unused class to shrinker-test (#2455) --- shrinker-test/common.pro | 4 ++++ .../src/main/java/com/example/UnusedClass.java | 17 +++++++++++++++++ .../java/com/google/gson/it/ShrinkingIT.java | 16 ++++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 shrinker-test/src/main/java/com/example/UnusedClass.java diff --git a/shrinker-test/common.pro b/shrinker-test/common.pro index ab45d2039a..b30faa1329 100644 --- a/shrinker-test/common.pro +++ b/shrinker-test/common.pro @@ -38,3 +38,7 @@ -keepclassmembernames class com.example.ClassWithVersionAnnotations { ; } + +# Keep the name of the class to allow using reflection to check if this class still exists +# after shrinking +-keepnames class com.example.UnusedClass diff --git a/shrinker-test/src/main/java/com/example/UnusedClass.java b/shrinker-test/src/main/java/com/example/UnusedClass.java new file mode 100644 index 0000000000..18d452f949 --- /dev/null +++ b/shrinker-test/src/main/java/com/example/UnusedClass.java @@ -0,0 +1,17 @@ +package com.example; + +import com.google.gson.annotations.SerializedName; + +/** + * Class with no-args constructor and field annotated with {@code @SerializedName}, + * but which is not actually used anywhere in the code. + * + *

The default ProGuard rules should not keep this class. + */ +public class UnusedClass { + public UnusedClass() { + } + + @SerializedName("i") + public int i; +} diff --git a/shrinker-test/src/test/java/com/google/gson/it/ShrinkingIT.java b/shrinker-test/src/test/java/com/google/gson/it/ShrinkingIT.java index d9d8d56cfb..be5a6213f7 100644 --- a/shrinker-test/src/test/java/com/google/gson/it/ShrinkingIT.java +++ b/shrinker-test/src/test/java/com/google/gson/it/ShrinkingIT.java @@ -19,7 +19,9 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertThrows; import static org.junit.Assert.fail; +import static org.junit.Assume.assumeTrue; +import com.example.UnusedClass; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.URL; @@ -248,4 +250,18 @@ public void testNoSerializedName_NoDefaultConstructor() throws Exception { } }); } + + @Test + public void testUnusedClassRemoved() throws Exception { + // For some reason this test only works for R8 but not for ProGuard; ProGuard keeps the unused class + assumeTrue(jarToTest.equals(R8_RESULT_PATH)); + + String className = UnusedClass.class.getName(); + ClassNotFoundException e = assertThrows(ClassNotFoundException.class, () -> { + runTest(className, c -> { + fail("Class should have been removed during shrinking: " + c); + }); + }); + assertThat(e).hasMessageThat().contains(className); + } }