| package org.testng.internal; |
| |
| import javax.xml.parsers.ParserConfigurationException; |
| |
| import org.testng.xml.Parser; |
| import org.testng.xml.XmlClass; |
| import org.testng.xml.XmlInclude; |
| import org.testng.xml.XmlPackage; |
| import org.testng.xml.XmlSuite; |
| import org.testng.xml.XmlTest; |
| import org.xml.sax.SAXException; |
| import org.yaml.snakeyaml.Loader; |
| import org.yaml.snakeyaml.TypeDescription; |
| import org.yaml.snakeyaml.constructor.Constructor; |
| |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileNotFoundException; |
| import java.io.IOException; |
| import java.lang.reflect.Method; |
| import java.util.Collection; |
| import java.util.List; |
| import java.util.Map; |
| |
| /** |
| * YAML support for TestNG. |
| * |
| * @author cbeust |
| */ |
| public class Yaml { |
| |
| private static void addToMap(Map suite, String name, Map target) { |
| List<Map<String, String>> parameters = (List<Map<String, String>>) suite.get(name); |
| if (parameters != null) { |
| for (Map<String, String> parameter : parameters) { |
| for (Map.Entry p : parameter.entrySet()) { |
| target.put(p.getKey(), p.getValue().toString()); |
| } |
| } |
| } |
| } |
| |
| private static void addToList(Map suite, String name, List target) { |
| List<Map<String, String>> parameters = (List<Map<String, String>>) suite.get(name); |
| if (parameters != null) { |
| for (Map<String, String> parameter : parameters) { |
| for (Map.Entry p : parameter.entrySet()) { |
| target.add(p.getValue().toString()); |
| } |
| } |
| } |
| } |
| |
| public static XmlSuite parse(String filePath) throws FileNotFoundException { |
| Constructor constructor = new Constructor(XmlSuite.class); |
| { |
| TypeDescription suiteDescription = new TypeDescription(XmlSuite.class); |
| suiteDescription.putListPropertyType("packages", XmlPackage.class); |
| suiteDescription.putListPropertyType("listeners", String.class); |
| suiteDescription.putListPropertyType("tests", XmlTest.class); |
| suiteDescription.putListPropertyType("method-selectors", XmlMethodSelector.class); |
| constructor.addTypeDescription(suiteDescription); |
| } |
| |
| { |
| TypeDescription testDescription = new TypeDescription(XmlTest.class); |
| testDescription.putListPropertyType("classes", XmlClass.class); |
| testDescription.putMapPropertyType("metaGroups", String.class, List.class); |
| constructor.addTypeDescription(testDescription); |
| } |
| |
| Loader loader = new Loader(constructor); |
| |
| org.yaml.snakeyaml.Yaml y = new org.yaml.snakeyaml.Yaml(loader); |
| XmlSuite result = (XmlSuite) y.load(new FileInputStream(new File(filePath))); |
| // DEBUG |
| // System.out.println("[Yaml] " + result.toXml()); |
| |
| // Adjust XmlTest parents |
| for (XmlTest t : result.getTests()) { |
| t.setSuite(result); |
| } |
| return result; |
| |
| // Map o = (Map) y.load(new FileInputStream(new File(filePath))); |
| // |
| // return parse(o); |
| } |
| |
| private static void setField(Object xml, Map<?, ?> map, String key, String methodName, |
| Class<?> parameter) { |
| Object o = map.get(key); |
| if (o != null) { |
| Method m; |
| try { |
| m = xml.getClass().getMethod(methodName, parameter); |
| m.invoke(xml, o); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| } |
| } |
| |
| private static void maybeAdd(StringBuilder sb, String key, Object value, Object def) { |
| maybeAdd(sb, "", key, value, def); |
| } |
| |
| private static void maybeAdd(StringBuilder sb, String sp, String key, Object value, Object def) { |
| if (value != null && ! value.equals(def)) { |
| sb.append(sp).append(key).append(": ").append(value.toString()).append("\n"); |
| } |
| } |
| |
| public static StringBuilder toYaml(XmlSuite suite) { |
| StringBuilder result = new StringBuilder(); |
| |
| maybeAdd(result, "name", suite.getName(), null); |
| maybeAdd(result, "junit", suite.isJUnit(), XmlSuite.DEFAULT_JUNIT); |
| maybeAdd(result, "verbose", suite.getVerbose(), XmlSuite.DEFAULT_VERBOSE); |
| maybeAdd(result, "threadCount", suite.getThreadCount(), XmlSuite.DEFAULT_THREAD_COUNT); |
| maybeAdd(result, "timeOut", suite.getTimeOut(), null); |
| maybeAdd(result, "parallel", suite.getParallel(), XmlSuite.DEFAULT_PARALLEL); |
| maybeAdd(result, "skipFailedInvocationCounts", suite.skipFailedInvocationCounts(), |
| XmlSuite.DEFAULT_SKIP_FAILED_INVOCATION_COUNTS); |
| |
| toYaml(result, "parameters", "", suite.getParameters()); |
| if (suite.getPackages().size() > 0) { |
| result.append("packages:\n"); |
| toYaml(result, suite.getPackages()); |
| } |
| toYaml(result, "listeners", suite.getListeners()); |
| if (suite.getTests().size() > 0) { |
| result.append("tests:\n"); |
| for (XmlTest t : suite.getTests()) { |
| toYaml(result, " ", t); |
| } |
| } |
| // (test|method-selectors|suite-files)* > |
| return result; |
| } |
| |
| private static void toYaml(StringBuilder result, String sp, XmlTest t) { |
| String sp2 = sp + " "; |
| result.append(sp).append("- name: ").append(t.getName()).append("\n"); |
| |
| maybeAdd(result, "junit", sp2, t.isJUnit(), XmlSuite.DEFAULT_JUNIT); |
| maybeAdd(result, "verbose", sp2, t.getVerbose(), XmlSuite.DEFAULT_VERBOSE); |
| maybeAdd(result, "timeOut", sp2, t.getTimeOut(), null); |
| maybeAdd(result, "parallel", sp2, t.getParallel(), XmlSuite.DEFAULT_PARALLEL); |
| maybeAdd(result, "skipFailedInvocationCounts", t.skipFailedInvocationCounts(), |
| XmlSuite.DEFAULT_SKIP_FAILED_INVOCATION_COUNTS); |
| |
| maybeAdd(result, "preserveOrder", sp2, t.getPreserveOrder(), XmlTest.DEFAULT_PRESERVE_ORDER); |
| |
| toYaml(result, "parameters", sp2, t.getTestParameters()); |
| |
| if (t.getIncludedGroups().size() > 0) { |
| result.append(sp2).append("includedGroups: [ ") |
| .append(Utils.join(t.getIncludedGroups(), ",")) |
| .append(" ]\n"); |
| } |
| |
| if (t.getExcludedGroups().size() > 0) { |
| result.append(sp2).append("excludedGroups: [ ") |
| .append(Utils.join(t.getExcludedGroups(), ",")) |
| .append(" ]\n"); |
| } |
| |
| if (t.getXmlClasses().size() > 0) { |
| result.append(sp2).append("classes:\n"); |
| for (XmlClass xc : t.getXmlClasses()) { |
| toYaml(result, sp2 + " ", xc); |
| } |
| } |
| |
| if (t.getXmlPackages().size() > 0) { |
| result.append(sp2).append("xmlPackages:\n"); |
| for (XmlPackage xp : t.getXmlPackages()) { |
| toYaml(result, sp2 + " - ", xp); |
| } |
| } |
| |
| Map<String, List<String>> mg = t.getMetaGroups(); |
| if (mg.size() > 0) { |
| result.append(sp2).append("metaGroups: { "); |
| boolean first = true; |
| for (String group : mg.keySet()) { |
| if (! first) result.append(", "); |
| result.append(group).append(": [ ") |
| .append(Utils.join(mg.get(group), ",")).append(" ] "); |
| first = false; |
| } |
| result.append(" }\n"); |
| } |
| |
| result.append("\n"); |
| } |
| |
| private static void toYaml(StringBuilder result, String sp2, XmlClass xc) { |
| result.append(sp2).append("- name: ").append(xc.getName()).append("\n"); |
| if (xc.getIncludedMethods().size() > 0) { |
| result.append(sp2 + " includedMethods:\n"); |
| for (XmlInclude xi : xc.getIncludedMethods()) { |
| toYaml(result, sp2 + " ", xi); |
| } |
| } |
| |
| if (xc.getExcludedMethods().size() > 0) { |
| result.append(sp2 + " excludedMethods:\n"); |
| toYaml(result, sp2 + " ", xc.getExcludedMethods()); |
| } |
| } |
| |
| private static void toYaml(StringBuilder result, String sp2, XmlInclude xi) { |
| result.append(sp2 + "- " + xi.getName()).append("\n"); |
| } |
| |
| private static void toYaml(StringBuilder result, String sp, List<String> strings) { |
| for (String l : strings) { |
| result.append(sp).append("- ").append(l).append("\n"); |
| } |
| } |
| |
| private static final String SP = " "; |
| |
| private static void toYaml(StringBuilder sb, List<XmlPackage> packages) { |
| for (XmlPackage p : packages) { |
| toYaml(sb, " ", p); |
| } |
| } |
| |
| private static void toYaml(StringBuilder sb, String sp, XmlPackage p) { |
| sb.append(sp).append("name: ").append(p.getName()).append("\n"); |
| |
| generateIncludeExclude(sb, sp, "includes", p.getInclude()); |
| generateIncludeExclude(sb, sp, "excludes", p.getExclude()); |
| } |
| |
| private static void generateIncludeExclude(StringBuilder sb, String sp, |
| String key, List<String> includes) { |
| if (includes.size() > 0) { |
| sb.append(sp).append(" ").append(key).append("\n"); |
| for (String inc : includes) { |
| sb.append(sp).append(" ").append(inc); |
| } |
| } |
| } |
| |
| private static void mapToYaml(Map<String, String> map, StringBuilder out) { |
| if (map.size() > 0) { |
| out.append("{ "); |
| boolean first = true; |
| for (Map.Entry<String, String> e : map.entrySet()) { |
| if (! first) out.append(", "); |
| first = false; |
| out.append(e.getKey() + ": " + e.getValue()); |
| } |
| out.append(" }\n"); |
| } |
| } |
| |
| private static void toYaml(StringBuilder sb, String key, String sp, |
| Map<String, String> parameters) { |
| if (parameters.size() > 0) { |
| sb.append(sp).append(key).append(": "); |
| mapToYaml(parameters, sb); |
| } |
| } |
| |
| public static void main(String[] args) |
| throws FileNotFoundException, ParserConfigurationException, SAXException, IOException { |
| Collection<XmlSuite> s = |
| new Parser("/Users/cbeust/java/testng/src/test/resources/testng.xml").parse(); |
| System.out.println(Yaml.toYaml(s.iterator().next())); |
| } |
| } |