2 * Copyright 2000-2016 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.
16 package com.intellij.testFramework;
18 import com.intellij.analysis.AnalysisScope;
19 import com.intellij.codeInsight.daemon.HighlightDisplayKey;
20 import com.intellij.codeInspection.ex.GlobalInspectionContextImpl;
21 import com.intellij.codeInspection.ex.InspectionToolWrapper;
22 import com.intellij.codeInspection.ui.InspectionToolPresentation;
23 import com.intellij.openapi.util.Comparing;
24 import com.intellij.openapi.util.JDOMUtil;
25 import com.intellij.testFramework.fixtures.impl.GlobalInspectionContextForTests;
26 import com.intellij.util.ui.UIUtil;
27 import org.jdom.Document;
28 import org.jdom.Element;
29 import org.jetbrains.annotations.NotNull;
30 import org.junit.Assert;
32 import java.io.CharArrayReader;
34 import java.io.StreamTokenizer;
35 import java.util.ArrayList;
36 import java.util.Collections;
37 import java.util.List;
39 public class InspectionTestUtil {
40 private InspectionTestUtil() {
43 protected static void compareWithExpected(Document expectedDoc, Document doc, boolean checkRange) throws Exception {
44 List<Element> expectedProblems = new ArrayList<Element>(expectedDoc.getRootElement().getChildren("problem"));
45 List<Element> reportedProblems = new ArrayList<Element>(doc.getRootElement().getChildren("problem"));
47 Element[] expectedArray = expectedProblems.toArray(new Element[expectedProblems.size()]);
48 boolean failed = false;
51 for (Element expectedProblem : expectedArray) {
52 Element[] reportedArrayed = reportedProblems.toArray(new Element[reportedProblems.size()]);
53 for (Element reportedProblem : reportedArrayed) {
54 if (compareProblemWithExpected(reportedProblem, expectedProblem, checkRange)) {
55 expectedProblems.remove(expectedProblem);
56 reportedProblems.remove(reportedProblem);
61 Document missing = new Document(expectedProblem.clone());
62 System.out.println("The following haven't been reported as expected: " + new String(JDOMUtil.printDocument(missing, "\n")));
66 for (Element reportedProblem : reportedProblems) {
67 Document extra = new Document(reportedProblem.clone());
68 System.out.println("The following has been unexpectedly reported: " + new String(JDOMUtil.printDocument(extra, "\n")));
72 Assert.assertFalse(failed);
75 static boolean compareProblemWithExpected(Element reportedProblem, Element expectedProblem, boolean checkRange) throws Exception {
76 if (!compareFiles(reportedProblem, expectedProblem)) return false;
77 if (!compareLines(reportedProblem, expectedProblem)) return false;
78 if (!compareDescriptions(reportedProblem, expectedProblem)) return false;
79 if (checkRange && !compareTextRange(reportedProblem, expectedProblem)) return false;
83 static boolean compareTextRange(final Element reportedProblem, final Element expectedProblem) {
84 Element reportedTextRange = reportedProblem.getChild("entry_point");
85 if (reportedTextRange == null) return false;
86 Element expectedTextRange = expectedProblem.getChild("entry_point");
87 return Comparing.equal(reportedTextRange.getAttributeValue("TYPE"), expectedTextRange.getAttributeValue("TYPE")) &&
88 Comparing.equal(reportedTextRange.getAttributeValue("FQNAME"), expectedTextRange.getAttributeValue("FQNAME"));
91 static boolean compareDescriptions(Element reportedProblem, Element expectedProblem) throws Exception {
92 String expectedDescription = expectedProblem.getChildText("description");
93 String reportedDescription = reportedProblem.getChildText("description");
94 if (expectedDescription.equals(reportedDescription)) return true;
96 StreamTokenizer tokenizer = new StreamTokenizer(new CharArrayReader(expectedDescription.toCharArray()));
97 tokenizer.quoteChar('\'');
100 while (tokenizer.nextToken() != StreamTokenizer.TT_EOF) {
102 if (tokenizer.sval != null) {
103 word = tokenizer.sval;
104 } else if (tokenizer.ttype == StreamTokenizer.TT_NUMBER) {
105 word = Double.toString(tokenizer.nval);
111 idx = reportedDescription.indexOf(word, idx);
112 if (idx == -1) return false;
113 idx += word.length();
119 static boolean compareLines(Element reportedProblem, Element expectedProblem) {
120 return Comparing.equal(reportedProblem.getChildText("line"), expectedProblem.getChildText("line"));
123 static boolean compareFiles(Element reportedProblem, Element expectedProblem) {
124 String reportedFileName = reportedProblem.getChildText("file");
125 if (reportedFileName == null) {
128 File reportedFile = new File(reportedFileName);
130 return Comparing.equal(reportedFile.getName(), expectedProblem.getChildText("file"));
133 public static void compareToolResults(@NotNull GlobalInspectionContextImpl context,
134 @NotNull InspectionToolWrapper toolWrapper,
137 final Element root = new Element("problems");
138 final Document doc = new Document(root);
139 InspectionToolPresentation presentation = context.getPresentation(toolWrapper);
141 presentation.updateContent(); //e.g. dead code need check for reachables
142 presentation.exportResults(root, Collections.emptySet(), Collections.emptySet());
144 File file = new File(testDir + "/expected.xml");
146 compareWithExpected(JDOMUtil.loadDocument(file), doc, checkRange);
148 catch (Exception e) {
149 throw new RuntimeException(e);
153 public static void runTool(@NotNull InspectionToolWrapper toolWrapper,
154 @NotNull final AnalysisScope scope,
155 @NotNull final GlobalInspectionContextForTests globalContext) {
156 final String shortName = toolWrapper.getShortName();
157 final HighlightDisplayKey key = HighlightDisplayKey.find(shortName);
159 HighlightDisplayKey.register(shortName);
162 globalContext.doInspections(scope);
164 UIUtil.dispatchAllInvocationEvents();
166 while (!globalContext.isFinished());