| package junitparams.naming; |
| |
| import junitparams.internal.TestMethod; |
| import junitparams.internal.Utils; |
| |
| import java.util.Arrays; |
| import java.util.HashSet; |
| import java.util.Locale; |
| import java.util.regex.Pattern; |
| |
| public class MacroSubstitutionNamingStrategy implements TestCaseNamingStrategy { |
| private static final String MACRO_PATTERN = "\\{[^\\}]{0,50}\\}"; |
| // Pattern that keeps delimiters in split result |
| private static final Pattern MACRO_SPLIT_PATTERN = Pattern.compile(String.format("(?=%s)|(?<=%s)", MACRO_PATTERN, MACRO_PATTERN)); |
| private static final String MACRO_START = "{"; |
| private static final String MACRO_END = "}"; |
| // Android-changed: CTS and AndroidJUnitRunner rely on specific format to test names, changing |
| // them will prevent CTS and AndroidJUnitRunner from working properly; see b/36541809 |
| static final String DEFAULT_TEMPLATE = "{method}[{index}]"; |
| private TestMethod method; |
| |
| public MacroSubstitutionNamingStrategy(TestMethod testMethod) { |
| this.method = testMethod; |
| } |
| |
| @Override |
| public String getTestCaseName(int parametersIndex, Object parameters) { |
| TestCaseName testCaseName = method.getAnnotation(TestCaseName.class); |
| |
| String template = getTemplate(testCaseName); |
| String builtName = buildNameByTemplate(template, parametersIndex, parameters); |
| |
| if (builtName.trim().isEmpty()) { |
| return buildNameByTemplate(DEFAULT_TEMPLATE, parametersIndex, parameters); |
| } else { |
| return builtName; |
| } |
| } |
| |
| private String getTemplate(TestCaseName testCaseName) { |
| if (testCaseName != null) { |
| // Android-changed: CTS and AndroidJUnitRunner rely on specific format to test names, |
| // changing them will prevent CTS and AndroidJUnitRunner from working properly; |
| // see b/36541809 |
| throw new IllegalStateException( |
| "@TestCaseName not currently supported as it breaks running tests in CTS"); |
| // return testCaseName.value(); |
| } |
| |
| return DEFAULT_TEMPLATE; |
| } |
| |
| private String buildNameByTemplate(String template, int parametersIndex, Object parameters) { |
| StringBuilder nameBuilder = new StringBuilder(); |
| |
| String[] parts = MACRO_SPLIT_PATTERN.split(template); |
| |
| for (String part : parts) { |
| String transformedPart = transformPart(part, parametersIndex, parameters); |
| nameBuilder.append(transformedPart); |
| } |
| |
| return nameBuilder.toString(); |
| } |
| |
| private String transformPart(String part, int parametersIndex, Object parameters) { |
| if (isMacro(part)) { |
| return lookupMacroValue(part, parametersIndex, parameters); |
| } |
| |
| return part; |
| } |
| |
| private String lookupMacroValue(String macro, int parametersIndex, Object parameters) { |
| String macroKey = getMacroKey(macro); |
| |
| switch (Macro.parse(macroKey)) { |
| case INDEX: return String.valueOf(parametersIndex); |
| case PARAMS: return Utils.stringify(parameters); |
| case METHOD: return method.name(); |
| default: return substituteDynamicMacro(macro, macroKey, parameters); |
| } |
| } |
| |
| private String substituteDynamicMacro(String macro, String macroKey, Object parameters) { |
| if (isMethodParameterIndex(macroKey)) { |
| int index = parseIndex(macroKey); |
| return Utils.getParameterStringByIndexOrEmpty(parameters, index); |
| } |
| |
| return macro; |
| } |
| |
| private boolean isMethodParameterIndex(String macroKey) { |
| return macroKey.matches("\\d+"); |
| } |
| |
| private int parseIndex(String macroKey) { |
| return Integer.parseInt(macroKey); |
| } |
| |
| private String getMacroKey(String macro) { |
| return macro |
| .substring(MACRO_START.length(), macro.length() - MACRO_END.length()) |
| .toUpperCase(Locale.ENGLISH); |
| } |
| |
| private boolean isMacro(String part) { |
| return part.startsWith(MACRO_START) && part.endsWith(MACRO_END); |
| } |
| |
| private enum Macro { |
| INDEX, |
| PARAMS, |
| METHOD, |
| NONE; |
| |
| public static Macro parse(String value) { |
| if (macros.contains(value)) { |
| return Macro.valueOf(value); |
| } else { |
| return Macro.NONE; |
| } |
| } |
| |
| private static final HashSet<String> macros = new HashSet<String>(Arrays.asList( |
| Macro.INDEX.toString(), Macro.PARAMS.toString(), Macro.METHOD.toString()) |
| ); |
| } |
| } |