/* * Copyright 2013-2016 Sergey Ignatov, Alexander Zolotov, Florin Patan * * 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.goide.psi.legacy; import com.goide.GoCodeInsightFixtureTestCase; import com.goide.project.GoModuleLibrariesService; import com.goide.psi.GoFile; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiReference; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.FilteringProcessor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.File; public abstract class GoLegacyResolveTestBase extends GoCodeInsightFixtureTestCase { @NotNull private static final String REF_MARK = "/*ref*/"; @NotNull private static final String NO_REF_MARK = "/*no ref*/"; @NotNull private static final String DEF_MARK = "/*def*/"; @Nullable private PsiReference myReference; @Nullable private PsiElement myDefinition; private boolean myShouldBeResolved = true; @Override protected String getBasePath() { return "psi/resolve"; } protected void doFileTest() { processPsiFile((GoFile)myFixture.configureByFile(getTestName(false) + ".go")); doResolveTest(); } protected void doDirTest() { String testDataPath = getTestDataPath(); String testName = getTestName(false); File fromDir = new File(testDataPath + "/" + testName); if (!fromDir.isDirectory()) { throw new RuntimeException("Given file is not directory: " + fromDir); } //noinspection ConstantConditions for (File file : fromDir.listFiles()) { if (file.isDirectory()) { myFixture.copyDirectoryToProject(testName + "/" + file.getName(), file.getName()); } else { myFixture.copyFileToProject(testName + "/" + file.getName()); } } VirtualFile dirToTest = myFixture.getTempDirFixture().getFile("."); assertNotNull(dirToTest); GoModuleLibrariesService.getInstance(myFixture.getModule()).setLibraryRootUrls(dirToTest.getUrl()); doDirectoryTest(dirToTest); } private void doResolveTest() { if (myReference == null) fail("no reference defined in test case"); if (myShouldBeResolved && !allowNullDefinition() && myDefinition == null) fail("no definition defined in test case"); PsiElement resolve = myReference.resolve(); if (myShouldBeResolved) { assertNotNull("cannot resolve reference " + myReference.getCanonicalText(), resolve); if (myDefinition != null) { PsiElement def = PsiTreeUtil.getParentOfType(myDefinition, resolve.getClass(), false); assertSame("element resolved in non-expected element from " + getFileName(resolve) + ":\n" + resolve.getText(), def, resolve); } } else if (resolve != null) { fail("element is resolved but it wasn't should. resolved to element from " + getFileName(resolve) + ":\n" + resolve.getText()); } } @NotNull private static String getFileName(@NotNull PsiElement resolve) { return resolve instanceof PsiFile ? ((PsiFile)resolve).getName() : resolve.getContainingFile().getName(); } protected boolean allowNullDefinition() { return false; } private void processPsiFile(@NotNull GoFile file) { String fileContent = loadText(file.getVirtualFile()); String fileName = file.getName(); int refIndex = fileContent.indexOf(REF_MARK); if (refIndex != -1) { int offset = refIndex + REF_MARK.length(); myReference = findReference(file, offset); } int noRefIndex = fileContent.indexOf(NO_REF_MARK); if (noRefIndex != -1) { int offset = noRefIndex + NO_REF_MARK.length(); myReference = findReference(file, offset); myShouldBeResolved = false; } int defIndex = fileContent.indexOf(DEF_MARK); if (defIndex != -1) { if (myDefinition != null) fail("only one definition should be allowed in a resolve test case, see file: " + fileName); int offset = defIndex + DEF_MARK.length(); myDefinition = file.findElementAt(offset); if (myDefinition == null) fail("no definition was found at mark in file: " + fileName + ", offset: " + offset); } } @NotNull private PsiReference findReference(@NotNull GoFile file, int offset) { if (myReference != null) fail("only one reference should be declared in a test case, see file: " + file.getName()); PsiReference result = file.findReferenceAt(offset); if (result == null) fail("no reference was found at mark in file: " + file.getName() + ", offset: " + offset); return result; } private void doDirectoryTest(@NotNull VirtualFile file) { VfsUtilCore.processFilesRecursively(file, new FilteringProcessor<>( virtualFile -> !virtualFile.isDirectory() && virtualFile.getName().endsWith(".go"), virtualFile -> { PsiFile goFile = myFixture.getPsiManager().findFile(virtualFile); assert goFile instanceof GoFile; processPsiFile((GoFile)goFile); return true; } )); doResolveTest(); } }