1package org.testng.reporters.jq;
2
3import org.testng.ISuite;
4import org.testng.ITestNGMethod;
5import org.testng.ITestResult;
6import org.testng.collections.Maps;
7import org.testng.reporters.XMLStringBuffer;
8
9import java.util.Collections;
10import java.util.Comparator;
11import java.util.List;
12import java.util.Map;
13
14public class TimesPanel extends BaseMultiSuitePanel {
15  private Map<String, Long> m_totalTime = Maps.newHashMap();
16
17  public TimesPanel(Model model) {
18    super(model);
19  }
20
21
22  @Override
23  public String getPrefix() {
24    return "times-";
25  }
26
27  @Override
28  public String getHeader(ISuite suite) {
29    return "Times for " + suite.getName();
30  }
31
32  private String js(ISuite suite) {
33    String functionName = "tableData_" + suiteToTag(suite);
34    StringBuilder result = new StringBuilder(
35        "suiteTableInitFunctions.push('" + functionName + "');\n"
36          + "function " + functionName + "() {\n"
37          + "var data = new google.visualization.DataTable();\n"
38          + "data.addColumn('number', 'Number');\n"
39          + "data.addColumn('string', 'Method');\n"
40          + "data.addColumn('string', 'Class');\n"
41          + "data.addColumn('number', 'Time (ms)');\n");
42
43    List<ITestResult> allTestResults = getModel().getAllTestResults(suite);
44    result.append(
45      "data.addRows(" + allTestResults.size() + ");\n");
46
47    Collections.sort(allTestResults, new Comparator<ITestResult>() {
48      @Override
49      public int compare(ITestResult o1, ITestResult o2) {
50        long t1 = o1.getEndMillis() - o1.getStartMillis();
51        long t2 = o2.getEndMillis() - o2.getStartMillis();
52        return (int) (t2 - t1);
53      }
54    });
55
56    int index = 0;
57    for (ITestResult tr : allTestResults) {
58      ITestNGMethod m = tr.getMethod();
59      long time = tr.getEndMillis() - tr.getStartMillis();
60      result
61          .append("data.setCell(" + index + ", "
62              + "0, " + index + ")\n")
63          .append("data.setCell(" + index + ", "
64              + "1, '" + m.getMethodName() + "')\n")
65          .append("data.setCell(" + index + ", "
66              + "2, '" + m.getTestClass().getName() + "')\n")
67          .append("data.setCell(" + index + ", "
68              + "3, " + time + ");\n");
69      Long total = m_totalTime.get(suite.getName());
70      if (total == null) {
71        total = 0L;
72      }
73      m_totalTime.put(suite.getName(), total + time);
74      index++;
75    }
76
77    result.append(
78        "window.suiteTableData['" + suiteToTag(suite) + "']" +
79        		"= { tableData: data, tableDiv: 'times-div-" + suiteToTag(suite) + "'}\n"
80        + "return data;\n" +
81        "}\n");
82
83    return result.toString();
84  }
85
86  @Override
87  public String getContent(ISuite suite, XMLStringBuffer main) {
88    XMLStringBuffer xsb = new XMLStringBuffer(main.getCurrentIndent());
89    xsb.push(D, C, "times-div");
90    xsb.push("script", "type", "text/javascript");
91    xsb.addString(js(suite));
92    xsb.pop("script");
93    Long time = m_totalTime.get(suite.getName());
94    if (time != null) {
95      xsb.addRequired(S, String.format("Total running time: %s", prettyDuration(time)),
96          C, "suite-total-time");
97    }
98    xsb.push(D, "id", "times-div-" + suiteToTag(suite));
99    xsb.pop(D);
100    xsb.pop(D);
101    return xsb.toXML();
102  }
103
104  private String prettyDuration(long totalTime) {
105    String result;
106    if (totalTime < 1000) {
107      result = totalTime + " ms";
108    } else if (totalTime < 1000 * 60) {
109      result = (totalTime / 1000) + " seconds";
110    } else if (totalTime < 1000 * 60 * 60) {
111      result = (totalTime / 1000 / 60) + " minutes";
112    } else {
113      result = (totalTime / 1000 / 60 / 60) + " hours";
114    }
115    return result;
116  }
117
118  @Override
119  public String getNavigatorLink(ISuite suite) {
120    return "Times";
121  }
122}
123