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 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 65 protected void setUp() throws Exception { 66 super.setUp(); 67 } 68 69 @Override 70 protected void tearDown() throws Exception { 71 super.tearDown(); 72 myFile = null; 73 } 74 75 protected boolean includeRanges() { 76 return false; 77 } 78 79 protected boolean skipSpaces() { 80 return false; 81 } 82 83 protected boolean checkAllPsiRoots() { 84 return true; 85 } 86 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 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 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 140 protected PsiFile createPsiFile(String name, String text) { 141 return createFile(name + "." + myFileExt, text); 142 } 143 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 150 protected PsiFile createFile(LightVirtualFile virtualFile) { 151 return ((PsiFileFactoryImpl)PsiFileFactory.getInstance(getProject())).trySetupPsiForFile( 152 virtualFile, myLanguage, true, false); 153 } 154 155 protected void checkResult(@NonNls @TestDataFile String targetDataName, final PsiFile file) throws IOException { 156 doCheckResult(myFullDataPath, file, checkAllPsiRoots(), targetDataName, skipSpaces(), includeRanges()); 157 } 158 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 180 protected void checkResult(@TestDataFile @NonNls String targetDataName, final String text) throws IOException { 181 doCheckResult(myFullDataPath, targetDataName, text); 182 } 183 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 189 protected static String toParseTreeText(final PsiElement file, boolean skipSpaces, boolean printRanges) { 190 return DebugUtil.psiToString(file, skipSpaces, printRanges); 191 } 192 193 protected String loadFile(@NonNls @TestDataFile String name) throws IOException { 194 return doLoadFile(myFullDataPath, name); 195 } 196 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 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