diff --git a/plugins/properties/intellij.properties.iml b/plugins/properties/intellij.properties.iml index 0dec248b0b90..907ddad6c337 100644 --- a/plugins/properties/intellij.properties.iml +++ b/plugins/properties/intellij.properties.iml @@ -21,5 +21,6 @@ + \ No newline at end of file diff --git a/plugins/properties/testSrc/com/intellij/lang/properties/PropertiesCharsetTest.java b/plugins/properties/testSrc/com/intellij/lang/properties/PropertiesCharsetTest.java new file mode 100644 index 000000000000..6667fa894641 --- /dev/null +++ b/plugins/properties/testSrc/com/intellij/lang/properties/PropertiesCharsetTest.java @@ -0,0 +1,204 @@ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.lang.properties; + +import com.intellij.codeInsight.CodeInsightTestCase; +import com.intellij.lang.properties.charset.Native2AsciiCharset; +import com.intellij.lang.properties.psi.PropertiesFile; +import com.intellij.lang.properties.psi.Property; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.vfs.CharsetToolkit; +import com.intellij.openapi.vfs.VfsUtilCore; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.encoding.EncodingManager; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.testFramework.PlatformTestCase; +import com.intellij.testFramework.PlatformTestUtil; +import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.NonNls; + +import java.nio.charset.Charset; +import java.util.List; + +/** + * @author cdr + */ +@PlatformTestCase.WrapInCommand +public class PropertiesCharsetTest extends CodeInsightTestCase { + private boolean myOldIsNative; + private Charset myOldCs; + private Charset myOldCharset; + + @Override + protected void setUp() throws Exception { + super.setUp(); + myOldIsNative = EncodingManager.getInstance().isNative2AsciiForPropertiesFiles(); + myOldCs = EncodingManager.getInstance().getDefaultCharsetForPropertiesFiles(null); + myOldCharset = EncodingManager.getInstance().getDefaultCharset(); + } + + @Override + protected void tearDown() throws Exception { + try { + EncodingManager.getInstance().setNative2AsciiForPropertiesFiles(null, myOldIsNative); + EncodingManager.getInstance().setDefaultCharsetForPropertiesFiles(null, myOldCs); + if (myOldCharset != null) { + EncodingManager.getInstance().setDefaultCharsetName(myOldCharset.name()); + } + } + finally { + super.tearDown(); + } + } + + private void configureByText(@NonNls final String text) throws Exception { + myFile = createFile(getTestName(false) + ".properties", text); + } + + public void testCharsetOn() throws Exception { + EncodingManager.getInstance().setNative2AsciiForPropertiesFiles(null, true); + + configureByText("\\u1234\\uxxxx\\n\\t\\y=\\u3210\\uzzzz\\n\\t\\y"); + List properties = ((PropertiesFile)myFile).getProperties(); + assertEquals(1, properties.size()); + final Property property = (Property)properties.get(0); + assertEquals("\u1234\\uxxxx\\n\\t\\y", property.getKey()); + assertEquals("\u3210\\uzzzz\\n\\t\\y", property.getValue()); + ApplicationManager.getApplication().runWriteAction(() -> { + property.setName("\u041f\\uyyyy\\n\\t\\y"); + }); + + FileDocumentManager.getInstance().saveAllDocuments(); + VirtualFile virtualFile = myFile.getVirtualFile(); + // copy to other file type to stop charset mingling + + VirtualFile newFile = copy(virtualFile, virtualFile.getParent(), "xxx.txt"); + myFilesToDelete.add(VfsUtilCore.virtualToIoFile(newFile)); + String chars = VfsUtilCore.loadText(newFile); + assertEquals("\\u041F\\uyyyy\\n\\t\\y=\\u3210\\uzzzz\\n\\t\\y", chars); + } + + public void testCharsetOff() { + EncodingManager.getInstance().setNative2AsciiForPropertiesFiles(null, false); + EncodingManager.getInstance().setDefaultCharsetForPropertiesFiles(null, Charset.forName("ISO-8859-1")); + + PlatformTestUtil.withEncoding("UTF-8", () -> { + configureByText("\\u1234\\uxxxx\\n\\t\\y=\\u3210\\uzzzz\\n\\t\\y"); + List properties = ((PropertiesFile)myFile).getProperties(); + assertEquals(1, properties.size()); + final Property property = (Property)properties.get(0); + assertEquals("\\u1234\\uxxxx\\n\\t\\y", property.getKey()); + assertEquals("\\u3210\\uzzzz\\n\\t\\y", property.getValue()); + ApplicationManager.getApplication().runWriteAction(() -> { + property.setName("\u041f\\uyyyy\\n\\t\\y"); + }); + + FileDocumentManager.getInstance().saveAllDocuments(); + VirtualFile virtualFile = myFile.getVirtualFile(); + // copy to other file type to stop charset mingling + VirtualFile newFile = copy(virtualFile, virtualFile.getParent(), "xxx.txt"); + myFilesToDelete.add(VfsUtilCore.virtualToIoFile(newFile)); + String chars = VfsUtilCore.loadText(newFile); + // 0x41f converted to '?' because it cannot be represented in ISO-8859-1 + assertEquals("?\\uyyyy\\n\\t\\y=\\u3210\\uzzzz\\n\\t\\y", chars); + }); + } + + public void testDefaultCharset() { + EncodingManager.getInstance().setNative2AsciiForPropertiesFiles(null, false); + EncodingManager.getInstance().setDefaultCharsetForPropertiesFiles(null, null); + EncodingManager.getInstance().setEncoding(null, CharsetToolkit.UTF8_CHARSET); + + PlatformTestUtil.withEncoding("UTF-8", () -> { + configureByText("\\u1234\\uxxxx\\n\\t\\y=\\u3210\\uzzzz\\n\\t\\y"); + List properties = ((PropertiesFile)myFile).getProperties(); + assertEquals(1, properties.size()); + final Property property = (Property)properties.get(0); + assertEquals("\\u1234\\uxxxx\\n\\t\\y", property.getKey()); + assertEquals("\\u3210\\uzzzz\\n\\t\\y", property.getValue()); + ApplicationManager.getApplication().runWriteAction(() -> { + property.setName("\u041f\\uyyyy\\n\\t\\y"); + }); + + FileDocumentManager.getInstance().saveAllDocuments(); + VirtualFile virtualFile = myFile.getVirtualFile(); + // copy to other file type to stop charset mingling + VirtualFile newFile = copy(virtualFile, virtualFile.getParent(), "xxx.txt"); + myFilesToDelete.add(VfsUtilCore.virtualToIoFile(newFile)); + String chars = VfsUtilCore.loadText(newFile); + assertEquals("\u041f\\uyyyy\\n\\t\\y=\\u3210\\uzzzz\\n\\t\\y", chars); + }); + } + + public void testCharsBelow128() throws Exception { + EncodingManager.getInstance().setNative2AsciiForPropertiesFiles(null, true); + EncodingManager.getInstance().setDefaultCharsetForPropertiesFiles(null, null); + EncodingManager.getInstance().setEncoding(null, CharsetToolkit.UTF8_CHARSET); + + configureByText("xxx=\\u3210\\uzzzz\\n\\t\\y"); + List properties = ((PropertiesFile)myFile).getProperties(); + assertEquals(1, properties.size()); + final IProperty property = properties.get(0); + ApplicationManager.getApplication().runWriteAction(() -> property.setValue("\u00e7\u007f\u0080\u00ff\u0024")); + + FileDocumentManager.getInstance().saveAllDocuments(); + VirtualFile virtualFile = myFile.getVirtualFile(); + // copy to other file type to stop charset mingling + VirtualFile newFile = copy(virtualFile, virtualFile.getParent(), "xxx.txt"); + myFilesToDelete.add(VfsUtilCore.virtualToIoFile(newFile)); + String chars = VfsUtilCore.loadText(newFile); + assertEquals("xxx=\\u00E7\u007F\\u0080\\u00FF\u0024", chars); + } + + public void testForceRefresh() throws Exception { + EncodingManager.getInstance().setNative2AsciiForPropertiesFiles(null, true); + EncodingManager.getInstance().setDefaultCharsetForPropertiesFiles(null, null); + EncodingManager.getInstance().setEncoding(null, CharsetToolkit.UTF8_CHARSET); + UIUtil.dispatchAllInvocationEvents(); + + configureByText("xxx=\\u1234"); + myEditor = createEditor(myFile.getVirtualFile()); + + List properties = ((PropertiesFile)myFile).getProperties(); + assertEquals(1, properties.size()); + IProperty property = properties.get(0); + assertEquals('\u1234' + "", property.getValue()); + + EncodingManager.getInstance().setNative2AsciiForPropertiesFiles(null, false); + UIUtil.dispatchAllInvocationEvents(); + PsiDocumentManager.getInstance(getProject()).commitAllDocuments(); + + properties = ((PropertiesFile)myFile).getProperties(); + assertEquals(1, properties.size()); + property = properties.get(0); + assertEquals("\\u1234", property.getValue()); + } + + public void testChangeEncodingMustReloadFile() throws Exception { + EncodingManager.getInstance().setNative2AsciiForPropertiesFiles(null, false); + EncodingManager.getInstance().setDefaultCharsetForPropertiesFiles(null, CharsetToolkit.UTF8_CHARSET); + UIUtil.dispatchAllInvocationEvents(); + + configureByText("xxx=\\u1234"); + assertEquals(CharsetToolkit.UTF8_CHARSET, myFile.getVirtualFile().getCharset()); + + Charset win = Charset.forName("windows-1251"); + EncodingManager.getInstance().setDefaultCharsetForPropertiesFiles(null, win); + UIUtil.dispatchAllInvocationEvents(); + + assertEquals(win, myFile.getVirtualFile().getCharset()); + } + + public void testBOMMarkedFileWithNativeConversion() throws Exception { + EncodingManager.getInstance().setNative2AsciiForPropertiesFiles(null, true); + EncodingManager.getInstance().setDefaultCharsetForPropertiesFiles(null, CharsetToolkit.UTF8_CHARSET); + UIUtil.dispatchAllInvocationEvents(); + + VirtualFile file = + createTempFile("properties", CharsetToolkit.UTF8_BOM, "general-notice=\\u062a\\u0648\\u062c\\u0647", CharsetToolkit.UTF8_CHARSET); + PropertiesFile propertiesFile = (PropertiesFile)getPsiManager().findFile(file); + assertNotNull(propertiesFile); + + assertEquals(Native2AsciiCharset.makeNative2AsciiEncodingName(CharsetToolkit.UTF8), file.getCharset().name()); + } +} diff --git a/plugins/properties/testSrc/com/intellij/lang/properties/PropertiesFileTreeStructureTest.java b/plugins/properties/testSrc/com/intellij/lang/properties/PropertiesFileTreeStructureTest.java new file mode 100644 index 000000000000..e976634832e8 --- /dev/null +++ b/plugins/properties/testSrc/com/intellij/lang/properties/PropertiesFileTreeStructureTest.java @@ -0,0 +1,87 @@ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.lang.properties; + +import com.intellij.lang.properties.structureView.GroupByWordPrefixes; +import com.intellij.lang.properties.structureView.PropertiesFileStructureViewModel; +import com.intellij.testFramework.PlatformTestUtil; +import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase; +import com.intellij.util.ui.tree.TreeUtil; + +public class PropertiesFileTreeStructureTest extends LightPlatformCodeInsightFixtureTestCase { + public void testGrouping() { + doTest("a.b.c=dddd\n" + + "a.b.d=dddd\n" + + "a.x=i\n" + + "b.n.p=ooo", + + "Test.properties\n" + + " a\n" + + " b\n" + + " c\n" + + " d\n" + + " x\n" + + " b.n.p\n"); + } + + public void testNesting() { + doTest("a=dddd\n" + + "a.b=dddd\n" + + "a.b.c=i\n" + + "a.b.c.d=ooo", + + "Test.properties\n" + + " a\n" + + " \n" + + " b\n" + + " \n" + + " c\n" + + " \n" + + " d\n"); + } + + public void testGroupSort() { + doTest("log4j.category.x=dd\n" + + "log4j.category.xdo=dd\n" + + "log4j.category.middlegen.swing.ss=dd\n" + + "log4j.category.middlegen.plugins.ss=dd\n" + + "log4j.appender.middlegen.plugins.ss=dd", + + "Test.properties\n" + + " log4j\n" + + " appender.middlegen.plugins.ss\n" + + " category\n" + + " middlegen\n" + + " plugins.ss\n" + + " swing.ss\n" + + " x\n" + + " xdo\n"); + } + + public void testFunkyGroups() { + doTest("errors.byte={0} must be a BYTE type \n" + + "errors.short={0} must be a SHORT type \n" + + "error.date={0} must be a DATE types \n" + + "error.range={0} is not between {1} and {2} \n" + + "errors.email={0} is not a valid Email Address \n" + + "errors.ipaddress={0} is not a valid IP address", + + "Test.properties\n" + + " error\n" + + " date\n" + + " range\n" + + " errors\n" + + " byte\n" + + " email\n" + + " ipaddress\n" + + " short\n"); + } + + private void doTest(String classText, String expected) { + myFixture.configureByText("Test.properties", classText); + myFixture.testStructureView(svc -> { + svc.setActionActive(GroupByWordPrefixes.ID, true); + svc.setActionActive(PropertiesFileStructureViewModel.KIND_SORTER_ID, true); + TreeUtil.expandAll(svc.getTree(), () -> PlatformTestUtil.assertTreeStructureEquals(svc.getTree().getModel(), expected)); + }); + } +}