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.List;
38 public class InspectionTestUtil {
39 private InspectionTestUtil() {
42 protected static void compareWithExpected(Document expectedDoc, Document doc, boolean checkRange) throws Exception {
43 List<Element> expectedProblems = new ArrayList<Element>(expectedDoc.getRootElement().getChildren("problem"));
44 List<Element> reportedProblems = new ArrayList<Element>(doc.getRootElement().getChildren("problem"));
46 Element[] expectedArray = expectedProblems.toArray(new Element[expectedProblems.size()]);
47 boolean failed = false;
50 for (Element expectedProblem : expectedArray) {
51 Element[] reportedArrayed = reportedProblems.toArray(new Element[reportedProblems.size()]);
52 for (Element reportedProblem : reportedArrayed) {
53 if (compareProblemWithExpected(reportedProblem, expectedProblem, checkRange)) {
54 expectedProblems.remove(expectedProblem);
55 reportedProblems.remove(reportedProblem);
60 Document missing = new Document(expectedProblem.clone());
61 System.out.println("The following haven't been reported as expected: " + new String(JDOMUtil.printDocument(missing, "\n")));
65 for (Element reportedProblem : reportedProblems) {
66 Document extra = new Document(reportedProblem.clone());
67 System.out.println("The following has been unexpectedly reported: " + new String(JDOMUtil.printDocument(extra, "\n")));
71 Assert.assertFalse(failed);
74 static boolean compareProblemWithExpected(Element reportedProblem, Element expectedProblem, boolean checkRange) throws Exception {
75 if (!compareFiles(reportedProblem, expectedProblem)) return false;
76 if (!compareLines(reportedProblem, expectedProblem)) return false;
77 if (!compareDescriptions(reportedProblem, expectedProblem)) return false;
78 if (checkRange && !compareTextRange(reportedProblem, expectedProblem)) return false;
82 static boolean compareTextRange(final Element reportedProblem, final Element expectedProblem) {
83 Element reportedTextRange = reportedProblem.getChild("entry_point");
84 if (reportedTextRange == null) return false;
85 Element expectedTextRange = expectedProblem.getChild("entry_point");
86 return Comparing.equal(reportedTextRange.getAttributeValue("TYPE"), expectedTextRange.getAttributeValue("TYPE")) &&
87 Comparing.equal(reportedTextRange.getAttributeValue("FQNAME"), expectedTextRange.getAttributeValue("FQNAME"));
90 static boolean compareDescriptions(Element reportedProblem, Element expectedProblem) throws Exception {
91 String expectedDescription = expectedProblem.getChildText("description");
92 String reportedDescription = reportedProblem.getChildText("description");
93 if (expectedDescription.equals(reportedDescription)) return true;
95 StreamTokenizer tokenizer = new StreamTokenizer(new CharArrayReader(expectedDescription.toCharArray()));
96 tokenizer.quoteChar('\'');
99 while (tokenizer.nextToken() != StreamTokenizer.TT_EOF) {
101 if (tokenizer.sval != null) {
102 word = tokenizer.sval;
103 } else if (tokenizer.ttype == StreamTokenizer.TT_NUMBER) {
104 word = Double.toString(tokenizer.nval);
110 idx = reportedDescription.indexOf(word, idx);
111 if (idx == -1) return false;
112 idx += word.length();
118 static boolean compareLines(Element reportedProblem, Element expectedProblem) {
119 return Comparing.equal(reportedProblem.getChildText("line"), expectedProblem.getChildText("line"));
122 static boolean compareFiles(Element reportedProblem, Element expectedProblem) {
123 String reportedFileName = reportedProblem.getChildText("file");
124 if (reportedFileName == null) {
127 File reportedFile = new File(reportedFileName);
129 return Comparing.equal(reportedFile.getName(), expectedProblem.getChildText("file"));
132 public static void compareToolResults(@NotNull GlobalInspectionContextImpl context,
133 @NotNull InspectionToolWrapper toolWrapper,
136 final Element root = new Element("problems");
137 final Document doc = new Document(root);
138 InspectionToolPresentation presentation = context.getPresentation(toolWrapper);
140 presentation.updateContent(); //e.g. dead code need check for reachables
141 presentation.exportResults(root, x -> false, x -> false);
143 File file = new File(testDir + "/expected.xml");
145 compareWithExpected(JDOMUtil.loadDocument(file), doc, checkRange);
147 catch (Exception e) {
148 throw new RuntimeException(e);
152 public static void runTool(@NotNull InspectionToolWrapper toolWrapper,
153 @NotNull final AnalysisScope scope,
154 @NotNull final GlobalInspectionContextForTests globalContext) {
155 final String shortName = toolWrapper.getShortName();
156 final HighlightDisplayKey key = HighlightDisplayKey.find(shortName);
158 HighlightDisplayKey.register(shortName);
161 globalContext.doInspections(scope);
163 UIUtil.dispatchAllInvocationEvents();
165 while (!globalContext.isFinished());