blob: 30ccd554e5b7e91eced6871c7aeab559f6072cc2 [file] [log] [blame]
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* 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.intellij.openapi.fileTypes.impl;
import com.intellij.ide.highlighter.ModuleFileType;
import com.intellij.ide.highlighter.ProjectFileType;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileTypes.*;
import com.intellij.openapi.fileTypes.ex.FileTypeManagerEx;
import com.intellij.openapi.util.io.ByteSequence;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiBinaryFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.PsiPlainTextFile;
import com.intellij.psi.impl.PsiManagerEx;
import com.intellij.testFramework.PlatformTestCase;
import com.intellij.util.PatternUtil;
import com.intellij.util.ui.UIUtil;
import junit.framework.TestCase;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.regex.Pattern;
public class FileTypesTest extends PlatformTestCase {
private FileTypeManagerImpl myFileTypeManager;
private String myOldIgnoredFilesList;
@Override
protected void setUp() throws Exception {
super.setUp();
myFileTypeManager = (FileTypeManagerImpl)FileTypeManagerEx.getInstanceEx();
myOldIgnoredFilesList = myFileTypeManager.getIgnoredFilesList();
myFileTypeManager.reDetectAsync(true);
}
@Override
protected void tearDown() throws Exception {
myFileTypeManager.reDetectAsync(false);
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
myFileTypeManager.setIgnoredFilesList(myOldIgnoredFilesList);
}
});
super.tearDown();
}
public void testMaskExclude() {
final String pattern1 = "a*b.c?d";
final String pattern2 = "xxx";
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
myFileTypeManager.setIgnoredFilesList(pattern1 + ";" + pattern2);
}
});
checkIgnored("ab.cxd");
checkIgnored("axb.cxd");
checkIgnored("xxx");
checkNotIgnored("ax.cxx");
checkNotIgnored("ab.cd");
checkNotIgnored("ab.c__d");
checkNotIgnored("xx" + "xx");
checkNotIgnored("xx");
assertTrue(myFileTypeManager.isIgnoredFilesListEqualToCurrent(pattern2 + ";" + pattern1));
assertFalse(myFileTypeManager.isIgnoredFilesListEqualToCurrent(pattern2 + ";" + "ab.c*d"));
}
public void testExcludePerformance() {
runPerformanceTest(true);
}
public void testMaskToPattern() {
for (char i = 0; i < 256; i++) {
if (i == '?' || i == '*') continue;
String str = "x" + i + "y";
assertTrue("char: " + i + "(" + (int)i + ")", PatternUtil.fromMask(str).matcher(str).matches());
}
String allSymbols = "+.\\*/^?$[]()";
assertTrue(PatternUtil.fromMask(allSymbols).matcher(allSymbols).matches());
Pattern pattern = PatternUtil.fromMask("?\\?/*");
assertTrue(pattern.matcher("a\\b/xyz").matches());
assertFalse(pattern.matcher("x/a\\b").matches());
}
public void testAddNewExtension() throws Exception {
FileTypeAssocTable<FileType> associations = new FileTypeAssocTable<FileType>();
associations.addAssociation(FileTypeManager.parseFromString("*.java"), FileTypes.ARCHIVE);
associations.addAssociation(FileTypeManager.parseFromString("*.xyz"), StdFileTypes.XML);
associations.addAssociation(FileTypeManager.parseFromString("SomeSpecial*.java"), StdFileTypes.XML); // patterns should have precedence over extensions
assertEquals(StdFileTypes.XML, associations.findAssociatedFileType("sample.xyz"));
assertEquals(StdFileTypes.XML, associations.findAssociatedFileType("SomeSpecialFile.java"));
checkNotAssociated(StdFileTypes.XML, "java", associations);
checkNotAssociated(StdFileTypes.XML, "iws", associations);
}
public void testIgnoreOrder() {
final FileTypeManagerEx manager = FileTypeManagerEx.getInstanceEx();
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
manager.setIgnoredFilesList("a;b;");
}
});
assertEquals("a;b;", manager.getIgnoredFilesList());
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
manager.setIgnoredFilesList("b;a;");
}
});
assertEquals("b;a;", manager.getIgnoredFilesList());
}
public void testIgnoredFiles() throws IOException {
File file = createTempFile(".svn", "");
VirtualFile vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file);
assertTrue(FileTypeManager.getInstance().isFileIgnored(vFile));
vFile.delete(this);
file = createTempFile("a.txt", "");
vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file);
assertFalse(FileTypeManager.getInstance().isFileIgnored(vFile));
}
@SuppressWarnings("deprecation")
private static void checkNotAssociated(FileType fileType, String extension, FileTypeAssocTable<FileType> associations) {
assertFalse(Arrays.asList(associations.getAssociatedExtensions(fileType)).contains(extension));
}
private void checkNotIgnored(String fileName) {
assertFalse(myFileTypeManager.isFileIgnored(fileName));
}
private void checkIgnored(String fileName) {
assertTrue(myFileTypeManager.isFileIgnored(fileName));
}
private void runPerformanceTest(boolean rerunOnOvertime) {
long startTime = System.currentTimeMillis();
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
myFileTypeManager.setIgnoredFilesList("1*2;3*4;5*6;7*8;9*0;*1;*3;*5;*6;7*;*8*");
}
});
for (int i = 0; i < 100; i++) {
String name = String.valueOf((i%10)*10 + (i*100) + i + 1);
myFileTypeManager.isFileIgnored(name + name + name + name);
}
long time = System.currentTimeMillis() - startTime;
if (time > 700) {
if (rerunOnOvertime) runPerformanceTest(false);
else fail("Time=" + time);
}
}
public void testAutoDetected() throws IOException {
File dir = createTempDirectory();
File file = FileUtil.createTempFile(dir, "x", "xxx_xx_xx", true);
FileUtil.writeToFile(file, "xxx xxx xxx xxx");
VirtualFile virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file);
assertNotNull(virtualFile);
PsiFile psi = getPsiManager().findFile(virtualFile);
assertTrue(psi instanceof PsiPlainTextFile);
assertEquals(FileTypes.PLAIN_TEXT, virtualFile.getFileType());
}
public void testAutoDetectedWhenDocumentWasCreated() throws IOException {
File dir = createTempDirectory();
File file = FileUtil.createTempFile(dir, "x", "xxx_xx_xx", true);
FileUtil.writeToFile(file, "xxx xxx xxx xxx");
VirtualFile virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file);
assertNotNull(virtualFile);
Document document = FileDocumentManager.getInstance().getDocument(virtualFile);
assertNotNull(document);
assertEquals(FileTypes.PLAIN_TEXT, virtualFile.getFileType());
}
public void testAutoDetectionShouldNotBeOverEager() throws IOException {
File dir = createTempDirectory();
File file = FileUtil.createTempFile(dir, "x", "xxx_xx_xx", true);
FileUtil.writeToFile(file, "xxx xxx xxx xxx");
VirtualFile virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file);
assertNotNull(virtualFile);
TestCase.assertEquals(PlainTextFileType.INSTANCE, virtualFile.getFileType());
}
public void testAutoDetectEmptyFile() throws IOException {
File dir = createTempDirectory();
File file = FileUtil.createTempFile(dir, "x", "xxx_xx_xx", true);
VirtualFile virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file);
assertNotNull(virtualFile);
assertEquals(FileTypes.UNKNOWN, virtualFile.getFileType());
PsiFile psi = getPsiManager().findFile(virtualFile);
assertTrue(psi instanceof PsiBinaryFile);
assertEquals(FileTypes.UNKNOWN, virtualFile.getFileType());
virtualFile.setBinaryContent("xxxxxxx".getBytes(CharsetToolkit.UTF8_CHARSET));
assertEquals(FileTypes.PLAIN_TEXT, virtualFile.getFileType());
PsiFile after = getPsiManager().findFile(virtualFile);
assertNotSame(psi, after);
assertFalse(psi.isValid());
assertTrue(after.isValid());
assertTrue(after instanceof PsiPlainTextFile);
}
public void testAutoDetectTextFileFromContents() throws IOException {
File dir = createTempDirectory();
VirtualFile vDir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(dir);
VirtualFile vFile = vDir.createChildData(this, "test.xxxxxxxx");
VfsUtil.saveText(vFile, "text");
assertEquals(PlainTextFileType.INSTANCE, vFile.getFileType()); // type autodetected during indexing
PsiFile psiFile = ((PsiManagerEx)PsiManager.getInstance(getProject())).getFileManager().findFile(vFile); // autodetect text file if needed
assertNotNull(psiFile);
assertEquals(PlainTextFileType.INSTANCE, psiFile.getFileType());
}
public void testAutoDetectTextFileEvenOutsideTheProject() throws IOException {
File d = createTempDirectory();
File f = new File(d, "xx.asfdasdfas");
FileUtil.writeToFile(f, "asdasdasdfafds");
VirtualFile vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(f);
assertEquals(PlainTextFileType.INSTANCE, vFile.getFileType());
}
public void test7BitBinaryIsNotText() throws IOException {
File d = createTempDirectory();
File f = new File(d, "xx.asfdasdfas");
byte[] bytes = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'x', 'a', 'b'};
assertEquals(new CharsetToolkit(bytes).guessFromContent(bytes.length), CharsetToolkit.GuessedEncoding.BINARY);
FileUtil.writeToFile(f, bytes);
VirtualFile vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(f);
assertEquals(UnknownFileType.INSTANCE, vFile.getFileType());
}
public void test7BitIsText() throws IOException {
File d = createTempDirectory();
File f = new File(d, "xx.asfdasdfas");
byte[] bytes = {9, 10, 13, 'x', 'a', 'b'};
assertEquals(new CharsetToolkit(bytes).guessFromContent(bytes.length), CharsetToolkit.GuessedEncoding.SEVEN_BIT);
FileUtil.writeToFile(f, bytes);
VirtualFile vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(f);
assertEquals(PlainTextFileType.INSTANCE, vFile.getFileType());
}
public void testReDetectOnContentsChange() throws IOException {
FileType fileType = FileTypeRegistry.getInstance().getFileTypeByFileName("x" + ModuleFileType.DOT_DEFAULT_EXTENSION);
assertTrue(fileType.toString(), fileType instanceof ModuleFileType);
fileType = FileTypeRegistry.getInstance().getFileTypeByFileName("x" + ProjectFileType.DOT_DEFAULT_EXTENSION);
assertTrue(fileType.toString(), fileType instanceof ProjectFileType);
FileTypeRegistry.FileTypeDetector detector = new FileTypeRegistry.FileTypeDetector() {
@Nullable
@Override
public FileType detect(@NotNull VirtualFile file, @NotNull ByteSequence firstBytes, @Nullable CharSequence firstCharsIfText) {
String text = firstCharsIfText.toString();
if (text.startsWith("TYPE:")) return FileTypeRegistry.getInstance().findFileTypeByName(StringUtil.trimStart(text, "TYPE:"));
return null;
}
@Override
public int getVersion() {
return 0;
}
};
Extensions.getRootArea().getExtensionPoint(FileTypeRegistry.FileTypeDetector.EP_NAME).registerExtension(detector);
try {
File d = createTempDirectory();
File f = new File(d, "xx.asfdasdfas");
FileUtil.writeToFile(f, "akjdhfksdjgf");
VirtualFile vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(f);
assertTrue(vFile.getFileType().toString(), vFile.getFileType() instanceof PlainTextFileType);
VfsUtil.saveText(vFile, "TYPE:IDEA_MODULE");
UIUtil.dispatchAllInvocationEvents();
myFileTypeManager.drainReDetectQueue();
UIUtil.dispatchAllInvocationEvents();
assertTrue(vFile.getFileType().toString(), vFile.getFileType() instanceof ModuleFileType);
VfsUtil.saveText(vFile, "TYPE:IDEA_PROJECT");
UIUtil.dispatchAllInvocationEvents();
myFileTypeManager.drainReDetectQueue();
UIUtil.dispatchAllInvocationEvents();
assertTrue(vFile.getFileType().toString(), vFile.getFileType() instanceof ProjectFileType);
}
finally {
Extensions.getRootArea().getExtensionPoint(FileTypeRegistry.FileTypeDetector.EP_NAME).unregisterExtension(detector);
}
}
}