/* * Copyright 2013-2016 consulo.io * * 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 consulo.testFramework; import consulo.testFramework.util.TestPathUtil; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.CharsetToolkit; import com.intellij.psi.*; import com.intellij.testFramework.LightPlatformCodeInsightTestCase; import com.intellij.testFramework.VfsTestUtil; import com.intellij.util.FileComparisonFailure; import com.intellij.util.Function; import com.intellij.util.containers.LinkedMultiMap; import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import consulo.annotations.RequiredReadAction; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Arrays; import java.util.Collection; import java.util.Map; /** * @author VISTALL * @since 06.04.2016 */ public class ResolvingTestCase extends LightPlatformCodeInsightTestCase { protected String myExtension; @NonNls protected final String myFullDataPath; public ResolvingTestCase(@NonNls @NotNull String dataPath, @NotNull String ext) { myFullDataPath = TestPathUtil.getTestDataPath(dataPath); if (!StringUtil.endsWithChar(dataPath, '/')) { throw new IllegalArgumentException("directory required endWiths '/'"); } myExtension = ext; } @NotNull @Override protected String getTestDataPath() { return myFullDataPath; } @Override @RequiredReadAction protected void runTestInternal() throws Throwable { String testName = getTestName(false); checkResult(testName + "." + myExtension); } @RequiredReadAction private void checkResult(@NotNull String filePath) throws Exception { configureByFile(filePath); PsiFile file = myFile; final MultiMap<PsiReference, ResolveResult> refs = new LinkedMultiMap<PsiReference, ResolveResult>(); file.accept(new PsiRecursiveElementVisitor() { @Override public void visitElement(final PsiElement element) { super.visitElement(element); PsiReference[] references = element.getReferences(); for (final PsiReference reference : references) { final ResolveResult[] resolveResults; if (reference instanceof PsiPolyVariantReference) { resolveResults = ((PsiPolyVariantReference)reference).multiResolve(false); } else { resolveResults = new ResolveResult[]{new ResolveResult() { @Nullable @Override public PsiElement getElement() { return reference.resolve(); } @Override public boolean isValidResult() { return true; } }}; } refs.putValues(reference, Arrays.asList(resolveResults)); } } }); StringBuilder builder = new StringBuilder(); for (Map.Entry<PsiReference, Collection<ResolveResult>> entry : refs.entrySet()) { PsiReference reference = entry.getKey(); Collection<ResolveResult> results = entry.getValue(); PsiElement element = reference.getElement(); builder.append(element.getText()).append(element.getTextRange()).append(": "); if (results.isEmpty()) { builder.append("empty"); } else { builder.append(StringUtil.join(results, new Function<ResolveResult, String>() { @Override @RequiredReadAction public String fun(ResolveResult resolveResult) { return buildReferenceResultText(resolveResult); } }, ", ")); } builder.append("\n"); } doCheckResult(getTestDataPath() + filePath + ".txt", builder.toString()); } private static void doCheckResult(String path, String text) throws IOException { text = text.trim(); if (OVERWRITE_TESTDATA) { VfsTestUtil.overwriteTestData(path, text); System.out.println("File " + path + " created."); } try { String expectedText = doLoadFile(path); if (!Comparing.equal(expectedText, text)) { throw new FileComparisonFailure(path, expectedText, text, path); } } catch (FileNotFoundException e) { VfsTestUtil.overwriteTestData(path, text); fail("No output text found. File " + path + " created."); } } private static String doLoadFile(String path) throws IOException { File file = new File(path); String text = FileUtil.loadFile(file, CharsetToolkit.UTF8).trim(); text = StringUtil.convertLineSeparators(text); return text; } @NotNull @RequiredReadAction private String buildReferenceResultText(@NotNull ResolveResult resolveResult) { PsiElement element = resolveResult.getElement(); if (element == null) { return "null-element"; } return createReferenceResultBuilder().fun(resolveResult); } @NotNull protected Function<ResolveResult, String> createReferenceResultBuilder() { return new Function<ResolveResult, String>() { @Override public String fun(ResolveResult resolveResult) { PsiElement element = resolveResult.getElement(); assert element != null; throw new UnsupportedOperationException("Please override 'getReferenceResultBuilder()' argument type: " + element.getClass()); } }; } }