1 /* 2 * Copyright 2000-2014 JetBrains s.r.o. 3 * 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 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 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. 15 */ 16 17 package org.jf.smalidea; 18 19 import com.intellij.lang.Language; 20 import com.intellij.openapi.fileEditor.impl.LoadTextUtil; 21 import com.intellij.openapi.util.io.FileUtil; 22 import com.intellij.openapi.vfs.CharsetToolkit; 23 import com.intellij.psi.*; 24 import com.intellij.psi.impl.DebugUtil; 25 import com.intellij.psi.impl.PsiFileFactoryImpl; 26 import com.intellij.psi.impl.source.PsiFileImpl; 27 import com.intellij.psi.stubs.SerializationManagerImpl; 28 import com.intellij.psi.stubs.SerializerNotFoundException; 29 import com.intellij.psi.stubs.StubTree; 30 import com.intellij.testFramework.LightVirtualFile; 31 import com.intellij.testFramework.TestDataFile; 32 import com.intellij.testFramework.UsefulTestCase; 33 import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; 34 import org.jetbrains.annotations.NonNls; 35 import org.jetbrains.annotations.NotNull; 36 37 import java.io.ByteArrayInputStream; 38 import java.io.ByteArrayOutputStream; 39 import java.io.File; 40 import java.io.IOException; 41 import java.util.Set; 42 43 /** 44 * A test case for parsing tests. 45 * 46 * This was originally based on com.intellij.testFramework.ParsingTestCase, but was modified 47 * to use the LightCodeInsightFixtureTestCase base class, which provides more functionality 48 */ 49 public abstract class LightCodeInsightParsingTestCase extends LightCodeInsightFixtureTestCase { 50 protected final String myFilePrefix = ""; 51 protected final String myFileExt; 52 @NonNls protected final String myFullDataPath; 53 protected final Language myLanguage; 54 55 protected PsiFile myFile; 56 LightCodeInsightParsingTestCase(@onNls @otNull String dataPath, @NotNull String fileExt, @NotNull Language language)57 public LightCodeInsightParsingTestCase(@NonNls @NotNull String dataPath, @NotNull String fileExt, 58 @NotNull Language language) { 59 myLanguage = language; 60 myFullDataPath = getTestDataPath() + "/" + dataPath; 61 myFileExt = fileExt; 62 } 63 64 @Override setUp()65 protected void setUp() throws Exception { 66 super.setUp(); 67 } 68 69 @Override tearDown()70 protected void tearDown() throws Exception { 71 super.tearDown(); 72 myFile = null; 73 } 74 includeRanges()75 protected boolean includeRanges() { 76 return false; 77 } 78 skipSpaces()79 protected boolean skipSpaces() { 80 return false; 81 } 82 checkAllPsiRoots()83 protected boolean checkAllPsiRoots() { 84 return true; 85 } 86 doTest(boolean checkResult)87 protected void doTest(boolean checkResult) { 88 String name = getTestName(false); 89 try { 90 String text = loadFile(name + "." + myFileExt); 91 PsiFile f = createPsiFile(name, text); 92 93 if (f instanceof PsiFileImpl) { 94 // Also want to test stub serialization/deserialization 95 StubTree stubTree = ((PsiFileImpl)f).calcStubTree(); 96 97 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 98 SerializationManagerImpl.getInstanceEx().serialize(stubTree.getRoot(), baos); 99 ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); 100 SerializationManagerImpl.getInstanceEx().deserialize(bais); 101 } 102 103 ensureParsed(f); 104 assertEquals("light virtual file text mismatch", text, 105 ((LightVirtualFile)f.getVirtualFile()).getContent().toString()); 106 assertEquals("virtual file text mismatch", text, LoadTextUtil.loadText(f.getVirtualFile())); 107 assertEquals("doc text mismatch", text, f.getViewProvider().getDocument().getText()); 108 assertEquals("psi text mismatch", text, f.getText()); 109 if (checkResult){ 110 checkResult(name, f); 111 } 112 else{ 113 toParseTreeText(f, skipSpaces(), includeRanges()); 114 } 115 } 116 catch (IOException e) { 117 throw new RuntimeException(e); 118 } catch (SerializerNotFoundException e) { 119 throw new RuntimeException(e); 120 } 121 } 122 doTest(String suffix)123 protected void doTest(String suffix) throws IOException { 124 String name = getTestName(false); 125 String text = loadFile(name + "." + myFileExt); 126 myFile = createPsiFile(name, text); 127 ensureParsed(myFile); 128 assertEquals(text, myFile.getText()); 129 checkResult(name + suffix, myFile); 130 } 131 doCodeTest(String code)132 protected void doCodeTest(String code) throws IOException { 133 String name = getTestName(false); 134 myFile = createPsiFile("a", code); 135 ensureParsed(myFile); 136 assertEquals(code, myFile.getText()); 137 checkResult(myFilePrefix + name, myFile); 138 } 139 createPsiFile(String name, String text)140 protected PsiFile createPsiFile(String name, String text) { 141 return createFile(name + "." + myFileExt, text); 142 } 143 createFile(@onNls String name, String text)144 protected PsiFile createFile(@NonNls String name, String text) { 145 LightVirtualFile virtualFile = new LightVirtualFile(name, myLanguage, text); 146 virtualFile.setCharset(CharsetToolkit.UTF8_CHARSET); 147 return createFile(virtualFile); 148 } 149 createFile(LightVirtualFile virtualFile)150 protected PsiFile createFile(LightVirtualFile virtualFile) { 151 return ((PsiFileFactoryImpl)PsiFileFactory.getInstance(getProject())).trySetupPsiForFile( 152 virtualFile, myLanguage, true, false); 153 } 154 checkResult(@onNls @estDataFile String targetDataName, final PsiFile file)155 protected void checkResult(@NonNls @TestDataFile String targetDataName, final PsiFile file) throws IOException { 156 doCheckResult(myFullDataPath, file, checkAllPsiRoots(), targetDataName, skipSpaces(), includeRanges()); 157 } 158 doCheckResult(String myFullDataPath, PsiFile file, boolean checkAllPsiRoots, String targetDataName, boolean skipSpaces, boolean printRanges)159 public static void doCheckResult(String myFullDataPath, 160 PsiFile file, 161 boolean checkAllPsiRoots, 162 String targetDataName, 163 boolean skipSpaces, 164 boolean printRanges) throws IOException { 165 FileViewProvider provider = file.getViewProvider(); 166 Set<Language> languages = provider.getLanguages(); 167 168 if (!checkAllPsiRoots || languages.size() == 1) { 169 doCheckResult(myFullDataPath, targetDataName + ".txt", toParseTreeText(file, skipSpaces, printRanges).trim()); 170 return; 171 } 172 173 for (Language language : languages) { 174 PsiFile root = provider.getPsi(language); 175 String expectedName = targetDataName + "." + language.getID() + ".txt"; 176 doCheckResult(myFullDataPath, expectedName, toParseTreeText(root, skipSpaces, printRanges).trim()); 177 } 178 } 179 checkResult(@estDataFile @onNls String targetDataName, final String text)180 protected void checkResult(@TestDataFile @NonNls String targetDataName, final String text) throws IOException { 181 doCheckResult(myFullDataPath, targetDataName, text); 182 } 183 doCheckResult(String fullPath, String targetDataName, String text)184 public static void doCheckResult(String fullPath, String targetDataName, String text) throws IOException { 185 String expectedFileName = fullPath + File.separatorChar + targetDataName; 186 UsefulTestCase.assertSameLinesWithFile(expectedFileName, text); 187 } 188 toParseTreeText(final PsiElement file, boolean skipSpaces, boolean printRanges)189 protected static String toParseTreeText(final PsiElement file, boolean skipSpaces, boolean printRanges) { 190 return DebugUtil.psiToString(file, skipSpaces, printRanges); 191 } 192 loadFile(@onNls @estDataFile String name)193 protected String loadFile(@NonNls @TestDataFile String name) throws IOException { 194 return doLoadFile(myFullDataPath, name); 195 } 196 doLoadFile(String myFullDataPath, String name)197 private static String doLoadFile(String myFullDataPath, String name) throws IOException { 198 return FileUtil.loadFile(new File(myFullDataPath, name), CharsetToolkit.UTF8, true).trim(); 199 } 200 ensureParsed(PsiFile file)201 public static void ensureParsed(PsiFile file) { 202 file.accept(new PsiElementVisitor() { 203 @Override 204 public void visitElement(PsiElement element) { 205 element.acceptChildren(this); 206 } 207 }); 208 } 209 } 210