package com.google.jstestdriver.idea.rt.util; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; /** * @author Sergey Simonchik */ public class TestFileScope { private static final char TEST_CASE_SEPARATOR = ';'; private static final char CASE_AND_METHOD_SEPARATOR = '.'; private static final char TEST_METHOD_SEPARATOR = ','; private final boolean myAll; private final Map<String, Set<String>> myMethodsByCaseMap; private TestFileScope(boolean all, @Nullable Map<String, Set<String>> methodsByCaseMap) { myAll = all; if (methodsByCaseMap == null) { myMethodsByCaseMap = Collections.emptyMap(); } else { myMethodsByCaseMap = methodsByCaseMap; } } public boolean containsTestCase(@NotNull String testCaseName) { return myAll || myMethodsByCaseMap.containsKey(testCaseName); } public boolean containsTestCaseAndMethod(@NotNull String testCaseName, @NotNull String testMethodName) { if (myAll) { return true; } Set<String> methods = myMethodsByCaseMap.get(testCaseName); if (methods == null) { return false; } if (methods.isEmpty()) { return true; } return methods.contains(testMethodName); } @Nullable public Map.Entry<String, Set<String>> getSingleTestCaseEntry() { if (myMethodsByCaseMap.isEmpty()) { return null; } return myMethodsByCaseMap.entrySet().iterator().next(); } @NotNull public List<String> toJstdList() { if (myAll) { return Collections.singletonList("all"); } List<String> tests = new ArrayList<>(); for (Map.Entry<String, Set<String>> entry : myMethodsByCaseMap.entrySet()) { String testCaseName = entry.getKey(); Set<String> testMethodNames = entry.getValue(); if (testMethodNames.isEmpty()) { String test = "^" + testCaseName + "#"; tests.add(test); } else { for (String testMethodName : entry.getValue()) { String test = "^" + testCaseName + "#" + testMethodName + "$"; tests.add(test); } } } return tests; } @NotNull public String toJstdStr() { List<String> tests = toJstdList(); return join(tests, ","); } @NotNull private List<String> toHumanList() { if (myAll) { return Collections.singletonList("all"); } List<String> tests = new ArrayList<>(); for (Map.Entry<String, Set<String>> entry : myMethodsByCaseMap.entrySet()) { String testCaseName = entry.getKey(); Set<String> testMethodNames = entry.getValue(); if (testMethodNames.isEmpty()) { tests.add(testCaseName); } else { for (String testMethodName : entry.getValue()) { tests.add(testCaseName + "." + testMethodName); } } } return tests; } @NotNull public String humanize() { List<String> tests = toHumanList(); return join(tests, ", "); } @NotNull private static String join(@NotNull Collection<String> collection, @NotNull String separator) { StringBuilder builder = new StringBuilder(); for (String str : collection) { if (builder.length() > 0) { builder.append(separator); } builder.append(str); } return builder.toString(); } public boolean isAll() { return myAll; } public String serialize() { if (myAll) { throw new RuntimeException("Can't serialize for all tests"); } List<String> testCaseStrings = new ArrayList<>(myMethodsByCaseMap.size()); for (Map.Entry<String, Set<String>> entry : myMethodsByCaseMap.entrySet()) { Set<String> testMethods = entry.getValue(); if (testMethods == null) { testMethods = Collections.emptySet(); } String testMethodsStr = EscapeUtils.join(testMethods, TEST_METHOD_SEPARATOR); String testCaseStr = EscapeUtils.join(Arrays.asList(entry.getKey(), testMethodsStr), CASE_AND_METHOD_SEPARATOR); if (!testCaseStr.isEmpty() && testCaseStr.charAt(testCaseStr.length() - 1) == CASE_AND_METHOD_SEPARATOR) { testCaseStr = testCaseStr.substring(0, testCaseStr.length() - 1); } testCaseStrings.add(testCaseStr); } return EscapeUtils.join(testCaseStrings, TEST_CASE_SEPARATOR); } @NotNull public static TestFileScope deserialize(@NotNull String s) { List<String> testCases = EscapeUtils.split(s, TEST_CASE_SEPARATOR); Map<String, Set<String>> methodsByCaseMap = new HashMap<>(); for (String testCase : testCases) { List<String> comps = EscapeUtils.split(testCase, CASE_AND_METHOD_SEPARATOR); if (comps.size() > 0) { String testCaseName = comps.get(0); final Set<String> methods; if (comps.size() == 1) { methods = Collections.emptySet(); } else if (comps.size() == 2) { List<String> list = EscapeUtils.split(comps.get(1), TEST_METHOD_SEPARATOR); methods = new HashSet<>(list); } else { // illegal situation throw new RuntimeException("Can't deserialize " + testCase); } methodsByCaseMap.put(testCaseName, methods); } } return new TestFileScope(false, methodsByCaseMap); } public static TestFileScope allScope() { return new TestFileScope(true, null); } public static TestFileScope customScope(@NotNull Map<String, Set<String>> methodsByCaseMap) { return new TestFileScope(false, methodsByCaseMap); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; TestFileScope that = (TestFileScope)o; if (myAll != that.myAll) return false; if (!myMethodsByCaseMap.equals(that.myMethodsByCaseMap)) return false; return true; } @Override public int hashCode() { int result = (myAll ? 1 : 0); result = 31 * result + myMethodsByCaseMap.hashCode(); return result; } }