blob: ea282149c53381b56e8e79b76ec1b88b1eddc1cc [file] [log] [blame]
// Copyright (c) 2016, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.shaking;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.graph.DexAccessFlags;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.utils.InternalOptions.PackageObfuscationMode;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import org.junit.Test;
public class ProguardConfigurationParserTest extends TestBase {
private static final String VALID_PROGUARD_DIR = "src/test/proguard/valid/";
private static final String INVALID_PROGUARD_DIR = "src/test/proguard/invalid/";
private static final String PROGUARD_SPEC_FILE = VALID_PROGUARD_DIR + "proguard.flags";
private static final String MULTIPLE_NAME_PATTERNS_FILE =
VALID_PROGUARD_DIR + "multiple-name-patterns.flags";
private static final String ACCESS_FLAGS_FILE = VALID_PROGUARD_DIR + "access-flags.flags";
private static final String WHY_ARE_YOU_KEEPING_FILE =
VALID_PROGUARD_DIR + "why-are-you-keeping.flags";
private static final String ASSUME_NO_SIDE_EFFECTS =
VALID_PROGUARD_DIR + "assume-no-side-effects.flags";
private static final String ASSUME_NO_SIDE_EFFECTS_WITH_RETURN_VALUE =
VALID_PROGUARD_DIR + "assume-no-side-effects-with-return-value.flags";
private static final String ASSUME_VALUES_WITH_RETURN_VALUE =
VALID_PROGUARD_DIR + "assume-values-with-return-value.flags";
private static final String INCLUDING =
VALID_PROGUARD_DIR + "including.flags";
private static final String INVALID_INCLUDING_1 =
INVALID_PROGUARD_DIR + "including-1.flags";
private static final String INVALID_INCLUDING_2 =
INVALID_PROGUARD_DIR + "including-2.flags";
private static final String LIBRARY_JARS =
VALID_PROGUARD_DIR + "library-jars.flags";
private static final String LIBRARY_JARS_WIN =
VALID_PROGUARD_DIR + "library-jars-win.flags";
private static final String SEEDS =
VALID_PROGUARD_DIR + "seeds.flags";
private static final String SEEDS_2 =
VALID_PROGUARD_DIR + "seeds-2.flags";
private static final String VERBOSE =
VALID_PROGUARD_DIR + "verbose.flags";
private static final String KEEPDIRECTORIES =
VALID_PROGUARD_DIR + "keepdirectories.flags";
private static final String DONT_OBFUSCATE =
VALID_PROGUARD_DIR + "dontobfuscate.flags";
private static final String PACKAGE_OBFUSCATION_1 =
VALID_PROGUARD_DIR + "package-obfuscation-1.flags";
private static final String PACKAGE_OBFUSCATION_2 =
VALID_PROGUARD_DIR + "package-obfuscation-2.flags";
private static final String PACKAGE_OBFUSCATION_3 =
VALID_PROGUARD_DIR + "package-obfuscation-3.flags";
private static final String PACKAGE_OBFUSCATION_4 =
VALID_PROGUARD_DIR + "package-obfuscation-4.flags";
private static final String PACKAGE_OBFUSCATION_5 =
VALID_PROGUARD_DIR + "package-obfuscation-5.flags";
private static final String PACKAGE_OBFUSCATION_6 =
VALID_PROGUARD_DIR + "package-obfuscation-6.flags";
private static final String DONT_SHRINK =
VALID_PROGUARD_DIR + "dontshrink.flags";
private static final String DONT_SKIP_NON_PUBLIC_LIBRARY_CLASSES =
VALID_PROGUARD_DIR + "dontskipnonpubliclibraryclasses.flags";
private static final String DONT_SKIP_NON_PUBLIC_LIBRARY_CLASS_MEMBERS =
VALID_PROGUARD_DIR + "dontskipnonpubliclibraryclassmembers.flags";
private static final String OVERLOAD_AGGRESIVELY =
VALID_PROGUARD_DIR + "overloadaggressively.flags";
private static final String DONT_OPTIMIZE =
VALID_PROGUARD_DIR + "dontoptimize.flags";
private static final String DONT_OPTIMIZE_OVERRIDES_PASSES =
VALID_PROGUARD_DIR + "dontoptimize-overrides-optimizationpasses.flags";
private static final String OPTIMIZATION_PASSES =
VALID_PROGUARD_DIR + "optimizationpasses.flags";
private static final String OPTIMIZATION_PASSES_WITHOUT_N =
INVALID_PROGUARD_DIR + "optimizationpasses-without-n.flags";
private static final String SKIP_NON_PUBLIC_LIBRARY_CLASSES =
VALID_PROGUARD_DIR + "skipnonpubliclibraryclasses.flags";
private static final String PARSE_AND_SKIP_SINGLE_ARGUMENT =
VALID_PROGUARD_DIR + "parse-and-skip-single-argument.flags";
private static final String PRINT_USAGE =
VALID_PROGUARD_DIR + "printusage.flags";
private static final String PRINT_USAGE_TO_FILE =
VALID_PROGUARD_DIR + "printusage-to-file.flags";
private static final String TARGET =
VALID_PROGUARD_DIR + "target.flags";
@Test
public void parse() throws IOException, ProguardRuleParserException {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
parser.parse(Paths.get(PROGUARD_SPEC_FILE));
List<ProguardConfigurationRule> rules = parser.getConfig().getRules();
assertEquals(24, rules.size());
assertEquals(1, rules.get(0).getMemberRules().size());
}
@Test
public void parseMultipleNamePatterns() throws IOException, ProguardRuleParserException {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
parser.parse(Paths.get(MULTIPLE_NAME_PATTERNS_FILE));
List<ProguardConfigurationRule> rules = parser.getConfig().getRules();
assertEquals(1, rules.size());
ProguardConfigurationRule rule = rules.get(0);
assertEquals(1, rule.getMemberRules().size());
assertEquals("com.company.hello.**", rule.getClassNames().get(0).toString());
assertEquals("com.company.world.**", rule.getClassNames().get(1).toString());
assertEquals(ProguardKeepRuleType.KEEP, ((ProguardKeepRule) rule).getType());
assertTrue(rule.getInheritanceIsExtends());
assertEquals("some.library.Class", rule.getInheritanceClassName().toString());
ProguardMemberRule memberRule = rule.getMemberRules().iterator().next();
assertTrue(memberRule.getAccessFlags().isProtected());
assertEquals(ProguardNameMatcher.create("getContents"), memberRule.getName());
assertEquals("java.lang.Object[][]", memberRule.getType().toString());
assertEquals(ProguardMemberType.METHOD, memberRule.getRuleType());
assertEquals(0, memberRule.getArguments().size());
}
@Test
public void parseAccessFlags() throws IOException, ProguardRuleParserException {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
parser.parse(Paths.get(ACCESS_FLAGS_FILE));
List<ProguardConfigurationRule> rules = parser.getConfig().getRules();
assertEquals(1, rules.size());
ProguardConfigurationRule rule = rules.get(0);
DexAccessFlags publicAndFinalFlags = new DexAccessFlags(0);
publicAndFinalFlags.setPublic();
publicAndFinalFlags.setFinal();
assertTrue(rule.getClassAccessFlags().containsNoneOf(publicAndFinalFlags));
assertTrue(rule.getNegatedClassAccessFlags().containsAllOf(publicAndFinalFlags));
DexAccessFlags abstractFlags = new DexAccessFlags(0);
abstractFlags.setAbstract();
assertTrue(rule.getClassAccessFlags().containsAllOf(abstractFlags));
assertTrue(rule.getNegatedClassAccessFlags().containsNoneOf(abstractFlags));
for (ProguardMemberRule member : rule.getMemberRules()) {
if (member.getRuleType() == ProguardMemberType.ALL_FIELDS) {
DexAccessFlags publicFlags = new DexAccessFlags(0);
publicAndFinalFlags.setPublic();
assertTrue(member.getAccessFlags().containsAllOf(publicFlags));
assertTrue(member.getNegatedAccessFlags().containsNoneOf(publicFlags));
DexAccessFlags staticFlags = new DexAccessFlags(0);
staticFlags.setStatic();
assertTrue(member.getAccessFlags().containsNoneOf(staticFlags));
assertTrue(member.getNegatedAccessFlags().containsAllOf(staticFlags));
} else {
assertTrue(member.getRuleType() == ProguardMemberType.ALL_METHODS);
DexAccessFlags publicProtectedVolatileFlags = new DexAccessFlags(0);
publicProtectedVolatileFlags.setPublic();
publicProtectedVolatileFlags.setProtected();
publicProtectedVolatileFlags.setVolatile();
assertTrue(member.getAccessFlags().containsNoneOf(publicProtectedVolatileFlags));
assertTrue(member.getNegatedAccessFlags().containsAllOf(publicProtectedVolatileFlags));
}
}
}
@Test
public void parseWhyAreYouKeeping() throws IOException, ProguardRuleParserException {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
parser.parse(Paths.get(WHY_ARE_YOU_KEEPING_FILE));
List<ProguardConfigurationRule> rules = parser.getConfig().getRules();
assertEquals(1, rules.size());
ProguardConfigurationRule rule = rules.get(0);
assertEquals(1, rule.getClassNames().size());
assertEquals("*", rule.getClassNames().get(0).toString());
assertTrue(rule.getInheritanceIsExtends());
assertEquals("foo.bar", rule.getInheritanceClassName().toString());
}
@Test
public void parseAssumeNoSideEffects() throws IOException, ProguardRuleParserException {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
parser.parse(Paths.get(ASSUME_NO_SIDE_EFFECTS));
List<ProguardConfigurationRule> assumeNoSideEffects = parser.getConfig().getRules();
assertEquals(1, assumeNoSideEffects.size());
assumeNoSideEffects.get(0).getMemberRules().forEach(rule -> {
assertFalse(rule.hasReturnValue());
});
}
@Test
public void parseAssumeNoSideEffectsWithReturnValue()
throws IOException, ProguardRuleParserException {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
parser.parse(Paths.get(ASSUME_NO_SIDE_EFFECTS_WITH_RETURN_VALUE));
List<ProguardConfigurationRule> assumeNoSideEffects = parser.getConfig().getRules();
assertEquals(1, assumeNoSideEffects.size());
assumeNoSideEffects.get(0).getMemberRules().forEach(rule -> {
assertTrue(rule.hasReturnValue());
if (rule.getName().matches("returnsTrue") || rule.getName().matches("returnsFalse")) {
assertTrue(rule.getReturnValue().isBoolean());
assertFalse(rule.getReturnValue().isValueRange());
assertFalse(rule.getReturnValue().isField());
assertEquals(rule.getName().matches("returnsTrue"), rule.getReturnValue().getBoolean());
} else if (rule.getName().matches("returns1")) {
assertFalse(rule.getReturnValue().isBoolean());
assertTrue(rule.getReturnValue().isValueRange());
assertFalse(rule.getReturnValue().isField());
assertTrue(rule.getReturnValue().isSingleValue());
assertEquals(1, rule.getReturnValue().getValueRange().getMin());
assertEquals(1, rule.getReturnValue().getValueRange().getMax());
assertEquals(1, rule.getReturnValue().getSingleValue());
} else if (rule.getName().matches("returns2To4")) {
assertFalse(rule.getReturnValue().isBoolean());
assertTrue(rule.getReturnValue().isValueRange());
assertFalse(rule.getReturnValue().isField());
assertFalse(rule.getReturnValue().isSingleValue());
assertEquals(2, rule.getReturnValue().getValueRange().getMin());
assertEquals(4, rule.getReturnValue().getValueRange().getMax());
} else if (rule.getName().matches("returnsField")) {
assertFalse(rule.getReturnValue().isBoolean());
assertFalse(rule.getReturnValue().isValueRange());
assertTrue(rule.getReturnValue().isField());
assertEquals("com.google.C", rule.getReturnValue().getField().clazz.toString());
assertEquals("int", rule.getReturnValue().getField().type.toString());
assertEquals("X", rule.getReturnValue().getField().name.toString());
}
});
}
@Test
public void parseAssumeValuesWithReturnValue()
throws IOException, ProguardRuleParserException {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
parser.parse(Paths.get(ASSUME_VALUES_WITH_RETURN_VALUE));
List<ProguardConfigurationRule> assumeValues = parser.getConfig().getRules();
assertEquals(1, assumeValues.size());
assumeValues.get(0).getMemberRules().forEach(rule -> {
assertTrue(rule.hasReturnValue());
if (rule.getName().matches("isTrue") || rule.getName().matches("isFalse")) {
assertTrue(rule.getReturnValue().isBoolean());
assertFalse(rule.getReturnValue().isValueRange());
assertFalse(rule.getReturnValue().isField());
assertEquals(rule.getName().matches("isTrue"), rule.getReturnValue().getBoolean());
} else if (rule.getName().matches("is1")) {
assertFalse(rule.getReturnValue().isBoolean());
assertTrue(rule.getReturnValue().isValueRange());
assertFalse(rule.getReturnValue().isField());
assertTrue(rule.getReturnValue().isSingleValue());
assertEquals(1, rule.getReturnValue().getValueRange().getMin());
assertEquals(1, rule.getReturnValue().getValueRange().getMax());
assertEquals(1, rule.getReturnValue().getSingleValue());
} else if (rule.getName().matches("is2To4")) {
assertFalse(rule.getReturnValue().isBoolean());
assertTrue(rule.getReturnValue().isValueRange());
assertFalse(rule.getReturnValue().isField());
assertFalse(rule.getReturnValue().isSingleValue());
assertEquals(2, rule.getReturnValue().getValueRange().getMin());
assertEquals(4, rule.getReturnValue().getValueRange().getMax());
} else if (rule.getName().matches("isField")) {
assertFalse(rule.getReturnValue().isBoolean());
assertFalse(rule.getReturnValue().isValueRange());
assertTrue(rule.getReturnValue().isField());
assertEquals("com.google.C", rule.getReturnValue().getField().clazz.toString());
assertEquals("int", rule.getReturnValue().getField().type.toString());
assertEquals("X", rule.getReturnValue().getField().name.toString());
}
});
}
@Test
public void parseDontobfuscate() throws IOException, ProguardRuleParserException {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
parser.parse(Paths.get(DONT_OBFUSCATE));
ProguardConfiguration config = parser.getConfig();
assertFalse(config.isObfuscating());
}
@Test
public void parseRepackageClassesEmpty() throws IOException, ProguardRuleParserException {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
parser.parse(Paths.get(PACKAGE_OBFUSCATION_1));
ProguardConfiguration config = parser.getConfig();
assertEquals(PackageObfuscationMode.REPACKAGE, config.getPackageObfuscationMode());
assertNotNull(config.getPackagePrefix());
assertEquals("", config.getPackagePrefix());
}
@Test
public void parseRepackageClassesNonEmpty() throws IOException, ProguardRuleParserException {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
parser.parse(Paths.get(PACKAGE_OBFUSCATION_2));
ProguardConfiguration config = parser.getConfig();
assertEquals(PackageObfuscationMode.REPACKAGE, config.getPackageObfuscationMode());
assertNotNull(config.getPackagePrefix());
assertEquals("p.q.r", config.getPackagePrefix());
}
@Test
public void parseFlattenPackageHierarchyEmpty() throws IOException, ProguardRuleParserException {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
parser.parse(Paths.get(PACKAGE_OBFUSCATION_3));
ProguardConfiguration config = parser.getConfig();
assertEquals(PackageObfuscationMode.FLATTEN, config.getPackageObfuscationMode());
assertNotNull(config.getPackagePrefix());
assertEquals("", config.getPackagePrefix());
}
@Test
public void parseFlattenPackageHierarchyNonEmpty() throws IOException, ProguardRuleParserException {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
parser.parse(Paths.get(PACKAGE_OBFUSCATION_4));
ProguardConfiguration config = parser.getConfig();
assertEquals(PackageObfuscationMode.FLATTEN, config.getPackageObfuscationMode());
assertNotNull(config.getPackagePrefix());
assertEquals("p.q.r", config.getPackagePrefix());
}
@Test
public void flattenPackageHierarchyCannotOverrideRepackageClasses()
throws IOException, ProguardRuleParserException {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
parser.parse(Paths.get(PACKAGE_OBFUSCATION_5));
ProguardConfiguration config = parser.getConfig();
assertEquals(PackageObfuscationMode.REPACKAGE, config.getPackageObfuscationMode());
assertNotNull(config.getPackagePrefix());
assertEquals("top", config.getPackagePrefix());
}
@Test
public void repackageClassesOverridesFlattenPackageHierarchy()
throws IOException, ProguardRuleParserException {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
parser.parse(Paths.get(PACKAGE_OBFUSCATION_6));
ProguardConfiguration config = parser.getConfig();
assertEquals(PackageObfuscationMode.REPACKAGE, config.getPackageObfuscationMode());
assertNotNull(config.getPackagePrefix());
assertEquals("top", config.getPackagePrefix());
}
@Test
public void parseIncluding() throws IOException, ProguardRuleParserException {
new ProguardConfigurationParser(new DexItemFactory()).parse(Paths.get(INCLUDING));
}
@Test
public void parseInvalidIncluding1() throws IOException {
try {
new ProguardConfigurationParser(new DexItemFactory()).parse(Paths.get(INVALID_INCLUDING_1));
fail();
} catch (ProguardRuleParserException e) {
assertTrue(e.getMessage().contains("6")); // line
assertTrue(e.getMessage().contains("including-1.flags")); // file in error
assertTrue(e.getMessage().contains("does-not-exist.flags")); // missing file
}
}
@Test
public void parseInvalidIncluding2() throws IOException {
try {
new ProguardConfigurationParser(new DexItemFactory()).parse(Paths.get(INVALID_INCLUDING_2));
fail();
} catch (ProguardRuleParserException e) {
String message = e.getMessage();
assertTrue(message, message.contains("6")); // line
assertTrue(message, message.contains("including-2.flags")); // file in error
assertTrue(message, message.contains("does-not-exist.flags")); // missing file
}
}
@Test
public void parseLibraryJars() throws IOException, ProguardRuleParserException {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
if (!ToolHelper.isLinux() && !ToolHelper.isMac()) {
parser.parse(Paths.get(LIBRARY_JARS_WIN));
} else {
parser.parse(Paths.get(LIBRARY_JARS));
}
assertEquals(4, parser.getConfig().getLibraryjars().size());
}
@Test
public void parseSeeds() throws IOException, ProguardRuleParserException {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
parser.parse(Paths.get(SEEDS));
ProguardConfiguration config = parser.getConfig();
assertTrue(config.isPrintSeeds());
assertNull(config.getSeedFile());
}
@Test
public void parseSeeds2() throws IOException, ProguardRuleParserException {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
parser.parse(Paths.get(SEEDS_2));
ProguardConfiguration config = parser.getConfig();
assertTrue(config.isPrintSeeds());
assertNotNull(config.getSeedFile());
}
@Test
public void parseVerbose() throws IOException, ProguardRuleParserException {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
parser.parse(Paths.get(VERBOSE));
ProguardConfiguration config = parser.getConfig();
assertTrue(config.isVerbose());
}
@Test
public void parseKeepdirectories() throws IOException, ProguardRuleParserException {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
parser.parse(Paths.get(KEEPDIRECTORIES));
}
@Test
public void parseDontshrink() throws IOException, ProguardRuleParserException {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
parser.parse(Paths.get(DONT_SHRINK));
ProguardConfiguration config = parser.getConfig();
assertFalse(config.isShrinking());
}
@Test
public void parseDontSkipNonPublicLibraryClasses()
throws IOException, ProguardRuleParserException {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
parser.parse(Paths.get(DONT_SKIP_NON_PUBLIC_LIBRARY_CLASSES));
}
@Test
public void parseDontskipnonpubliclibraryclassmembers()
throws IOException, ProguardRuleParserException {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
parser.parse(Paths.get(DONT_SKIP_NON_PUBLIC_LIBRARY_CLASS_MEMBERS));
}
@Test
public void parseOverloadAggressively()
throws IOException, ProguardRuleParserException {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
parser.parse(Paths.get(OVERLOAD_AGGRESIVELY));
}
@Test
public void parseDontOptimize() throws IOException, ProguardRuleParserException {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
parser.parse(Paths.get(DONT_OPTIMIZE));
ProguardConfiguration config = parser.getConfig();
}
@Test
public void parseDontOptimizeOverridesPasses() throws IOException, ProguardRuleParserException {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
parser.parse(Paths.get(DONT_OPTIMIZE_OVERRIDES_PASSES));
ProguardConfiguration config = parser.getConfig();
}
@Test
public void parseOptimizationPasses() throws IOException, ProguardRuleParserException {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
parser.parse(Paths.get(OPTIMIZATION_PASSES));
ProguardConfiguration config = parser.getConfig();
}
@Test
public void parseOptimizationPassesError() throws IOException, ProguardRuleParserException {
try {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
parser.parse(Paths.get(OPTIMIZATION_PASSES_WITHOUT_N));
fail();
} catch (ProguardRuleParserException e) {
assertTrue(e.getMessage().contains("Missing n"));
}
}
@Test
public void parseSkipNonPublicLibraryClasses() throws IOException {
try {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
parser.parse(Paths.get(SKIP_NON_PUBLIC_LIBRARY_CLASSES));
fail();
} catch (ProguardRuleParserException e) {
assertTrue(e.getMessage().contains("Unsupported option: -skipnonpubliclibraryclasses"));
}
}
@Test
public void parseAndskipSingleArgument() throws IOException, ProguardRuleParserException {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
parser.parse(Paths.get(PARSE_AND_SKIP_SINGLE_ARGUMENT));
}
@Test
public void parsePrintUsage() throws IOException, ProguardRuleParserException {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
parser.parse(Paths.get(PRINT_USAGE));
ProguardConfiguration config = parser.getConfig();
assertTrue(config.isPrintUsage());
assertNull(config.getPrintUsageFile());
}
@Test
public void parsePrintUsageToFile() throws IOException, ProguardRuleParserException {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
parser.parse(Paths.get(PRINT_USAGE_TO_FILE));
ProguardConfiguration config = parser.getConfig();
assertTrue(config.isPrintUsage());
assertNotNull(config.getPrintUsageFile());
}
@Test
public void parseTarget()
throws IOException, ProguardRuleParserException {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
parser.parse(Paths.get(TARGET));
}
@Test
public void parseInvalidKeepClassOption() throws IOException, ProguardRuleParserException {
try {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
Path proguardConfig = writeTextToTempFile(
"-keepclassx public class * { ",
" native <methods>; ",
"} "
);
parser.parse(proguardConfig);
fail();
} catch (ProguardRuleParserException e) {
assertTrue(e.getMessage().contains("Unknown option at "));
}
}
@Test
public void parseCustomFlags() throws Exception {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
// Custom Proguard flags -runtype and -laststageoutput are ignored.
Path proguardConfig = writeTextToTempFile(
"-runtype FINAL ",
"-laststageoutput /some/file/name "
);
parser.parse(proguardConfig);
}
}