update copyright
[fedora-idea.git] / plugins / testng / src / com / theoryinpractice / testng / ui / TestNGConsoleView.java
blob82c285ea87cc750e076328071bdbc691aa0c1f5e
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 * Created by IntelliJ IDEA.
19 * User: amrk
20 * Date: Jul 9, 2005
21 * Time: 4:19:20 PM
23 package com.theoryinpractice.testng.ui;
25 import com.intellij.execution.configurations.ConfigurationPerRunnerSettings;
26 import com.intellij.execution.configurations.RunnerSettings;
27 import com.intellij.execution.process.ProcessHandler;
28 import com.intellij.execution.testframework.ui.BaseTestsOutputConsoleView;
29 import com.intellij.execution.testframework.ui.TestResultsPanel;
30 import com.intellij.execution.ui.ConsoleView;
31 import com.intellij.execution.ui.ConsoleViewContentType;
32 import com.intellij.openapi.application.ApplicationManager;
33 import com.theoryinpractice.testng.configuration.TestNGConfiguration;
34 import com.theoryinpractice.testng.model.TestNGConsoleProperties;
35 import com.theoryinpractice.testng.model.TestProxy;
36 import org.jetbrains.annotations.NonNls;
37 import org.testng.remote.strprotocol.TestResultMessage;
39 import javax.swing.*;
40 import java.util.ArrayList;
41 import java.util.List;
42 import java.util.regex.Matcher;
43 import java.util.regex.Pattern;
45 public class TestNGConsoleView extends BaseTestsOutputConsoleView {
46 @NonNls private static final Pattern COMPARISION_PATTERN =
47 Pattern.compile("([^\\<\\>]*)expected[^\\<\\>]*\\<([^\\<\\>]*)\\>[^\\<\\>]*\\<([^\\<\\>]*)\\>[^\\<\\>]*");
48 @NonNls private static final Pattern EXPECTED_BUT_WAS_PATTERN =
49 Pattern.compile("(.*)expected:\\<(.*)\\> but was:\\<(.*)\\>.*", Pattern.DOTALL);
50 @NonNls private static final Pattern EXPECTED_NOT_SAME_BUT_WAS_PATTERN =
51 Pattern.compile("(.*)expected not same with:\\<(.*)\\> but was:\\<(.*)\\>.*", Pattern.DOTALL);
52 private TestNGResults testNGResults;
53 private final List<Printable> currentTestOutput = new ArrayList<Printable>();
54 private final List<Printable> nonTestOutput = new ArrayList<Printable>();
56 private int myExceptionalMark = -1;
57 private final TestNGConfiguration myConfiguration;
58 private final RunnerSettings myRunnerSettings;
59 private final ConfigurationPerRunnerSettings myConfigurationPerRunnerSettings;
61 public TestNGConsoleView(TestNGConfiguration config,
62 final RunnerSettings runnerSettings,
63 final ConfigurationPerRunnerSettings configurationPerRunnerSettings) {
64 super(new TestNGConsoleProperties(config));
65 myConfiguration = config;
66 myRunnerSettings = runnerSettings;
67 myConfigurationPerRunnerSettings = configurationPerRunnerSettings;
70 protected TestResultsPanel createTestResultsPanel() {
71 testNGResults = new TestNGResults(getConsole().getComponent(), myConfiguration, this, myRunnerSettings, myConfigurationPerRunnerSettings);
72 return testNGResults;
76 @Override
77 public void dispose() {
78 super.dispose();
79 testNGResults = null;
82 public TestNGResults getResultsView() {
83 return testNGResults;
86 public void rebuildTree() {
87 if (testNGResults != null) {
88 testNGResults.rebuildTree();
92 public void addTestResult(TestResultMessage result) {
93 if (testNGResults != null) {
94 if (!testNGResults.wasTestStarted(result)) {
95 flushOutput();
97 int exceptionMark = myExceptionalMark == -1 ? 0 : myExceptionalMark;
98 final String stackTrace = result.getStackTrace();
99 if (stackTrace != null && stackTrace.length() > 10) {
100 //trim useless crud from stacktrace
101 String trimmed = trimStackTrace(stackTrace);
102 List<Printable> printables = getPrintables(result, trimmed);
103 for (Printable printable : printables) {
104 printable.print(getConsole()); //enable for root element
106 synchronized (currentTestOutput) {
107 exceptionMark = currentTestOutput.size();
108 currentTestOutput.addAll(printables);
111 testNGResults.addTestResult(result, new ArrayList<Printable>(currentTestOutput), exceptionMark);
113 myExceptionalMark = -1;
114 synchronized (currentTestOutput) {
115 currentTestOutput.clear();
120 public void testStarted(TestResultMessage result) {
121 if (testNGResults != null) {
122 flushOutput();
123 testNGResults.testStarted(result);
127 private void flushOutput() {
128 synchronized (currentTestOutput) {
129 if (!currentTestOutput.isEmpty()) { //non empty for first test only
130 nonTestOutput.addAll(currentTestOutput);
131 currentTestOutput.clear();
136 public void flush() {
137 final TestProxy failedToStart = testNGResults.getFailedToStart();
138 if (failedToStart != null) {
139 final List<Printable> output = failedToStart.getOutput();
140 if (output != null) {
141 nonTestOutput.addAll(output);
146 private static String trimStackTrace(String stackTrace) {
147 String[] lines = stackTrace.split("\n");
148 StringBuilder builder = new StringBuilder();
150 if (lines.length > 0) {
151 int i = lines.length - 1;
152 while (i >= 0) {
153 //first 4 chars are '\t at '
154 int startIndex = lines[i].indexOf('a') + 3;
155 if (lines[i].length() > 4 &&
156 (lines[i].startsWith("org.testng.", startIndex) ||
157 lines[i].startsWith("org.junit.", startIndex) ||
158 lines[i].startsWith("sun.reflect.DelegatingMethodAccessorImpl", startIndex) ||
159 lines[i].startsWith("sun.reflect.NativeMethodAccessorImpl", startIndex) ||
160 lines[i].startsWith("java.lang.reflect.Method", startIndex) ||
161 lines[i].startsWith("com.intellij.rt.execution.application.AppMain", startIndex))) {
164 else {
165 // we're done with internals, so we know the rest are ok
166 break;
168 i--;
170 for (int j = 0; j <= i; j++) {
171 builder.append(lines[j]);
172 builder.append('\n');
175 return builder.toString();
178 private List<Printable> getPrintables(final TestResultMessage result, String s) {
179 List<Printable> printables = new ArrayList<Printable>();
180 //figure out if we have a diff we need to hyperlink
181 Matcher matcher = COMPARISION_PATTERN.matcher(s);
182 if (!matcher.matches()) {
183 matcher = EXPECTED_BUT_WAS_PATTERN.matcher(s);
185 if (!matcher.matches()) {
186 matcher = EXPECTED_NOT_SAME_BUT_WAS_PATTERN.matcher(s);
188 if (matcher.matches()) {
189 printables.add(new Chunk(matcher.group(1), ConsoleViewContentType.ERROR_OUTPUT));
190 //we have an assert with expected/actual, so we parse it out and create a diff hyperlink
191 TestNGDiffHyperLink link = new TestNGDiffHyperLink(matcher.group(2), matcher.group(3), null, (TestNGConsoleProperties) myProperties) {
192 protected String getTitle() {
193 //TODO should do some more farting about to find the equality assertion that failed and show that as title
194 return result.getTestClass() + '#' + result.getMethod() + "() failed";
197 //same as junit diff view
198 printables.add(link);
199 printables.add(new Chunk(trimStackTrace(s.substring(matcher.end(3) + 1)), ConsoleViewContentType.ERROR_OUTPUT));
201 else {
202 printables.add(new Chunk(s, ConsoleViewContentType.ERROR_OUTPUT));
204 return printables;
207 public void print(String s, ConsoleViewContentType contentType) {
208 if (myExceptionalMark == -1 && contentType == ConsoleViewContentType.ERROR_OUTPUT) {
209 myExceptionalMark = currentTestOutput.size();
211 Chunk chunk = new Chunk(s, contentType);
212 synchronized (currentTestOutput) {
213 currentTestOutput.add(chunk);
217 public void reset() {
218 final List<Printable> printables = new ArrayList<Printable>();
219 printables.addAll(nonTestOutput);
220 printables.addAll(testNGResults.getRoot().getOutput());
221 printables.addAll(currentTestOutput);
222 setView(printables, 0);
225 public void attachToProcess(ProcessHandler processHandler) {
226 getConsole().attachToProcess(processHandler);
229 public void setView(final List<Printable> output, final int i) {
230 if (!ApplicationManager.getApplication().isDispatchThread()) {
231 SwingUtilities.invokeLater(new Runnable() {
232 public void run() {
233 setView(output, i);
237 else {
238 getConsole().clear();
239 int idx = 0;
240 int offset = 0;
241 for (Printable chunk : new ArrayList<Printable>(output)) {
242 chunk.print(getConsole());
243 if (idx++ < i) {
244 offset = getConsole().getContentSize();
247 getConsole().scrollTo(offset);
251 public static class Chunk implements Printable {
252 public String text;
253 public ConsoleViewContentType contentType;
255 public void print(ConsoleView console) {
256 console.print(text, contentType);
259 public Chunk(String text, ConsoleViewContentType contentType) {
260 this.text = text;
261 this.contentType = contentType;
264 public String toString() {
265 return text;