com.intellij.execution.testframework.export.TestResultsXmlFormatter.java Source code

Java tutorial

Introduction

Here is the source code for com.intellij.execution.testframework.export.TestResultsXmlFormatter.java

Source

/*
 * Copyright 2000-2010 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.intellij.execution.testframework.export;

import com.intellij.execution.ExecutionBundle;
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.execution.filters.*;
import com.intellij.execution.testframework.AbstractTestProxy;
import com.intellij.execution.testframework.Printable;
import com.intellij.execution.testframework.Printer;
import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;

import java.text.SimpleDateFormat;
import java.util.*;

public class TestResultsXmlFormatter {

    private static final String ELEM_RUN = "testrun";
    private static final String ELEM_TEST = "test";
    private static final String ELEM_SUITE = "suite";
    private static final String ATTR_NAME = "name";
    private static final String ATTR_DURATION = "duration";
    private static final String ELEM_COUNT = "count";
    private static final String ATTR_VALUE = "value";
    private static final String ELEM_OUTPUT = "output";
    private static final String ATTR_OUTPUT_TYPE = "type";
    private static final String ATTR_STATUS = "status";
    private static final String TOTAL_STATUS = "total";
    private static final String ATTR_FOORTER_TEXT = "footerText";

    private final RunConfiguration myRuntimeConfiguration;
    private final ContentHandler myResultHandler;
    private final AbstractTestProxy myTestRoot;

    public static void execute(AbstractTestProxy root, RunConfiguration runtimeConfiguration,
            ContentHandler resultHandler) throws SAXException {
        new TestResultsXmlFormatter(root, runtimeConfiguration, resultHandler).execute();
    }

    private TestResultsXmlFormatter(AbstractTestProxy root, RunConfiguration runtimeConfiguration,
            ContentHandler resultHandler) {
        myRuntimeConfiguration = runtimeConfiguration;
        myTestRoot = root;
        myResultHandler = resultHandler;
    }

    private void execute() throws SAXException {
        myResultHandler.startDocument();

        TreeMap<String, Integer> counts = new TreeMap<String, Integer>(new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                if (TOTAL_STATUS.equals(o1) && !TOTAL_STATUS.equals(o2))
                    return -1;
                if (TOTAL_STATUS.equals(o2) && !TOTAL_STATUS.equals(o1))
                    return 1;
                return o1.compareTo(o2);
            }
        });
        for (AbstractTestProxy node : myTestRoot.getAllTests()) {
            if (!node.isLeaf())
                continue;
            String status = getStatusString(node);
            increment(counts, status);
            increment(counts, TOTAL_STATUS);
        }

        Map<String, String> runAttrs = new HashMap<String, String>();
        runAttrs.put(ATTR_NAME, myRuntimeConfiguration.getName());
        String footerText = ExecutionBundle.message("export.test.results.footer",
                ApplicationNamesInfo.getInstance().getFullProductName(), new SimpleDateFormat().format(new Date()));
        runAttrs.put(ATTR_FOORTER_TEXT, footerText);
        Long duration = myTestRoot.getDuration();
        if (duration != null) {
            runAttrs.put(ATTR_DURATION, String.valueOf(duration));
        }
        startElement(ELEM_RUN, runAttrs);

        for (Map.Entry<String, Integer> entry : counts.entrySet()) {
            Map<String, String> a = new HashMap<String, String>();
            a.put(ATTR_NAME, entry.getKey());
            a.put(ATTR_VALUE, String.valueOf(entry.getValue()));
            startElement(ELEM_COUNT, a);
            endElement(ELEM_COUNT);
        }

        CompositeFilter f = new CompositeFilter(myRuntimeConfiguration.getProject());
        for (ConsoleFilterProvider eachProvider : Extensions
                .getExtensions(ConsoleFilterProvider.FILTER_PROVIDERS)) {
            Filter[] filters = eachProvider.getDefaultFilters(myRuntimeConfiguration.getProject());
            for (Filter filter : filters) {
                f.addFilter(filter);
            }
        }

        if (myTestRoot.shouldSkipRootNodeForExport()) {
            for (AbstractTestProxy node : myTestRoot.getChildren()) {
                processNode(node, f);
            }
        } else {
            processNode(myTestRoot, f);
        }
        endElement(ELEM_RUN);
        myResultHandler.endDocument();
    }

    private static void increment(Map<String, Integer> counts, String status) {
        Integer count = counts.get(status);
        counts.put(status, count != null ? count + 1 : 1);
    }

    private void processNode(AbstractTestProxy node, final Filter filter) throws SAXException {
        Map<String, String> attrs = new HashMap<String, String>();
        attrs.put(ATTR_NAME, node.getName());
        attrs.put(ATTR_STATUS, getStatusString(node));
        Long duration = node.getDuration();
        if (duration != null) {
            attrs.put(ATTR_DURATION, String.valueOf(duration));
        }
        String elemName = node.isLeaf() ? ELEM_TEST : ELEM_SUITE;
        startElement(elemName, attrs);
        if (node.isLeaf()) {
            final StringBuilder buffer = new StringBuilder();
            final Ref<ConsoleViewContentType> lastType = new Ref<ConsoleViewContentType>();
            final Ref<SAXException> error = new Ref<SAXException>();

            node.printOn(new Printer() {
                @Override
                public void print(String text, ConsoleViewContentType contentType) {
                    if (contentType != lastType.get()) {
                        if (buffer.length() > 0) {
                            try {
                                writeOutput(lastType.get(), buffer, filter);
                            } catch (SAXException e) {
                                error.set(e);
                            }
                        }
                        lastType.set(contentType);
                    }
                    buffer.append(text);
                }

                @Override
                public void onNewAvailable(@NotNull Printable printable) {
                }

                @Override
                public void printHyperlink(String text, HyperlinkInfo info) {
                }

                @Override
                public void mark() {
                }
            });
            if (!error.isNull()) {
                throw error.get();
            }
            if (buffer.length() > 0) {
                writeOutput(lastType.get(), buffer, filter);
            }
        } else {
            for (AbstractTestProxy child : node.getChildren()) {
                processNode(child, filter);
            }
        }
        endElement(elemName);
    }

    private void writeOutput(ConsoleViewContentType type, StringBuilder text, Filter filter) throws SAXException {
        StringBuilder output = new StringBuilder();
        StringTokenizer t = new StringTokenizer(text.toString(), "\n");
        while (t.hasMoreTokens()) {
            String line = StringUtil.escapeXml(t.nextToken()) + "\n";
            Filter.Result result = null;//filter.applyFilter(line, line.length());
            if (result != null && result.hyperlinkInfo instanceof OpenFileHyperlinkInfo) {
                output.append(line.substring(0, result.highlightStartOffset));
                OpenFileDescriptor descriptor = ((OpenFileHyperlinkInfo) result.hyperlinkInfo).getDescriptor();
                output.append("<a href=\"javascript://\" onclick=\"Activator.doOpen('file?file=");
                output.append(descriptor.getFile().getPresentableUrl());
                output.append("&line=");
                output.append(descriptor.getLine());
                output.append("')\">");
                output.append(line.substring(result.highlightStartOffset, result.highlightEndOffset));
                output.append("</a>");
                output.append(line.substring(result.highlightEndOffset));
            } else {
                output.append(line);
            }
        }

        Map<String, String> a = new HashMap<String, String>();
        a.put(ATTR_OUTPUT_TYPE, getTypeString(type));
        startElement(ELEM_OUTPUT, a);
        writeText(output.toString());
        text.delete(0, text.length());
        endElement(ELEM_OUTPUT);
    }

    private static String getTypeString(ConsoleViewContentType type) {
        return type == ConsoleViewContentType.ERROR_OUTPUT ? "stderr" : "stdout";
    }

    private static String getStatusString(AbstractTestProxy node) {
        int magnitude = node.getMagnitude();
        // TODO enumeration!
        switch (magnitude) {
        case 0:
            return "skipped";
        case 5:
            return "ignored";
        case 1:
            return "passed";
        case 6:
            return "failed";
        case 8:
            return "error";
        default:
            return node.isPassed() ? "passed" : "failed";
        }
    }

    private void startElement(String name, Map<String, String> attributes) throws SAXException {
        AttributesImpl attrs = new AttributesImpl();
        for (Map.Entry<String, String> entry : attributes.entrySet()) {
            attrs.addAttribute("", entry.getKey(), entry.getKey(), "CDATA", entry.getValue());
        }
        myResultHandler.startElement("", name, name, attrs);
    }

    private void endElement(String name) throws SAXException {
        myResultHandler.endElement("", name, name);
    }

    private void writeText(String text) throws SAXException {
        final char[] chars = text.toCharArray();
        myResultHandler.characters(chars, 0, chars.length);
    }
}