Files
openide/platform/platform-tests/testSrc/com/intellij/util/JDOMUtilTest.kt
Mikhail Mazurkevich 0040e3f019 [workspace model] IJPL-1113 Handle IllegalNameException from XML reading
GitOrigin-RevId: 0159ed2cd99655d448d499c3134889402751a1ee
2024-07-11 18:07:25 +00:00

355 lines
13 KiB
Kotlin

// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.util
import com.intellij.openapi.application.ex.PathManagerEx
import com.intellij.openapi.util.JDOMUtil
import com.intellij.openapi.util.JDOMUtil.MergeAttribute
import com.intellij.testFramework.PlatformTestUtil
import com.intellij.testFramework.assertions.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy
import org.jdom.Element
import org.jdom.IllegalDataException
import org.jdom.JDOMException
import org.jdom.Text
import org.junit.Test
import java.awt.Dimension
import java.awt.Point
import java.awt.Rectangle
import java.io.File
import java.nio.file.Path
import java.nio.file.Paths
import kotlin.test.assertEquals
internal class JDOMUtilTest {
@Test
fun testBadHost() {
JDOMUtil.load(Paths.get(PlatformTestUtil.getPlatformTestDataPath(), "tools/badHost.xml"))
}
@Test
fun testLegalize() {
val badString = String(charArrayOf(0xffff.toChar()))
val str = "${badString}start${badString}end$badString"
checkIfBad(str)
val legalized = JDOMUtil.legalizeText(str)
Element("test").text = legalized
assertThat(legalized).isEqualTo("0xFFFFstart0xFFFFend0xFFFF")
}
@Test
fun `lt in attribute value`() {
assertThat(JDOMUtil.write(Element("test").setAttribute("hello", "dog < cat"))).isEqualTo("""<test hello="dog &lt; cat" />""")
}
@Test
fun deepMerge() {
assertThat(JDOMUtil.deepMerge(
JDOMUtil.load("""<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="f1" />
<module fileurl="f2" />
</modules>
</component>
</project>"""),
JDOMUtil.load("""<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="f3" />
<module fileurl="f4" />
</modules>
</component>
</project>""")))
.isEqualTo("""<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="f1" />
<module fileurl="f2" />
<module fileurl="f3" />
<module fileurl="f4" />
</modules>
</component>
</project>""")
}
@Test
fun `deepMerge override empty tag`() {
assertThat(JDOMUtil.deepMerge(
JDOMUtil.load("""<component name="CompilerConfiguration">
<bytecodeTargetLevel />
</component>"""),
JDOMUtil.load("""<component name="ExternalCompilerConfiguration">
<bytecodeTargetLevel>
<module name="my-app" target="1.5" />
</bytecodeTargetLevel>
</component>""")))
.isEqualTo("""
<component name="ExternalCompilerConfiguration">
<bytecodeTargetLevel>
<module name="my-app" target="1.5" />
</bytecodeTargetLevel>
</component>""")
}
@Test
fun `test reduce children`() {
val element = JDOMUtil.load("""
| <component name="CompilerConfiguration">
| <bytecodeTargetLevel target="1.7">
| <module name="module1" target="11" />
| </bytecodeTargetLevel>
| <bytecodeTargetLevel>
| <module name="module2" target="13" />
| <module name="module3" target="14" />
| </bytecodeTargetLevel>
| </component>""".trimMargin()
)
assertThat(JDOMUtil.reduceChildren("bytecodeTargetLevel", element))
.isEqualTo("""
| <bytecodeTargetLevel target="1.7">
| <module name="module1" target="11" />
| <module name="module2" target="13" />
| <module name="module3" target="14" />
| </bytecodeTargetLevel>""".trimMargin()
)
assertThat(element)
.isEqualTo("""
| <component name="CompilerConfiguration">
| <bytecodeTargetLevel target="1.7">
| <module name="module1" target="11" />
| <module name="module2" target="13" />
| <module name="module3" target="14" />
| </bytecodeTargetLevel>
| </component>""".trimMargin()
)
}
@Test
fun testBillionLaughs() {
val loaded = JDOMUtil.load(
Path.of(PlatformTestUtil.getPlatformTestDataPath() + File.separator + "tools" + File.separator + "BillionLaughs.xml"))
assertThat(JDOMUtil.write(loaded)).isEqualTo("<lolz />")
}
private fun checkIfBad(str: String) {
assertThatThrownBy {
Element("test").text = str
}.isInstanceOf(IllegalDataException::class.java)
}
@Test
fun cdata() {
val element = JDOMUtil.load("""
<boo>
<help><![CDATA[create controller name index-action-included[=1]]]></help>
</boo>
""".trimIndent().reader())
assertThat(element.content).hasSize(1)
val helpElementContent = (element.content.first() as Element).content
assertThat(helpElementContent).hasSize(1)
assertThat((helpElementContent.first() as Text).text).isEqualTo("create controller name index-action-included[=1]")
assertThat(element).isEqualTo("""
<boo>
<help>create controller name index-action-included[=1]</help>
</boo>""")
}
@Test
fun space() {
val element = JDOMUtil.load("""
<plist>
<string>&lt;fieldset id=&quot;1 / [[:alpha:]]+|() / (?1:_:\L$0)/g}&quot; 2:class = &quot; 3: }&quot;}&gt;&lt;legend&gt;1:TM_SELECTED_TEXT}&lt;/legend&gt; '$'}0&lt;/fieldset&gt;</string>
</plist>
""".trimIndent().reader())
val content = element.getChild("string").content
assertThat(content).hasSize(1)
assertThat((content[0] as Text).text).isEqualTo("""<fieldset id="1 / [[:alpha:]]+|() / (?1:_:\L${'$'}0)/g}" 2:class = " 3: }"}><legend>1:TM_SELECTED_TEXT}</legend> '${'$'}'}0</fieldset>""")
}
@Test
fun `set&get location`() {
val location = Point(1, 2)
val element = Element("state")
assertThat(JDOMUtil.setLocation(element, location)).isSameAs(element)
assertThat(JDOMUtil.getLocation(element)).isEqualTo(location).isNotSameAs(location)
assertElementText(element, """<state x="1" y="2" />""")
}
@Test
fun `set&get location with custom name`() {
val location = Point(1, 2)
val element = Element("state")
assertThat(JDOMUtil.setLocation(element, "myX", "myY", location)).isSameAs(element)
assertThat(JDOMUtil.getLocation(element, "myX", "myY")).isEqualTo(location).isNotSameAs(location)
assertElementText(element, """<state myX="1" myY="2" />""")
}
@Test
fun `set&get location with invalid attribute`() {
val element = JDOMUtil.setLocation(Element("state"), Point(1, 1))
assertThat(element.setAttribute("x", "x")).isSameAs(element)
assertThat(JDOMUtil.getBounds(element)).isNull()
assertElementText(element, """<state x="x" y="1" />""")
}
@Test
fun `set&get location without required attribute`() {
val element = JDOMUtil.setLocation(Element("state"), Point(1, 1))
assertThat(element.removeAttribute("y")).isTrue()
assertThat(JDOMUtil.getBounds(element)).isNull()
assertElementText(element, """<state x="1" />""")
}
@Test
fun `set&get size`() {
val size = Dimension(3, 4)
val element = Element("state")
assertThat(JDOMUtil.setSize(element, size)).isSameAs(element)
assertThat(JDOMUtil.getSize(element)).isEqualTo(size).isNotSameAs(size)
assertElementText(element, """<state width="3" height="4" />""")
}
@Test
fun `set&get size with custom name`() {
val size = Dimension(3, 4)
val element = Element("state")
assertThat(JDOMUtil.setSize(element, "myW", "myH", size)).isSameAs(element)
assertThat(JDOMUtil.getSize(element, "myW", "myH")).isEqualTo(size).isNotSameAs(size)
assertElementText(element, """<state myW="3" myH="4" />""")
}
@Test
fun `set&get size with invalid attribute`() {
val element = JDOMUtil.setSize(Element("state"), Dimension(1, 1))
assertThat(element.setAttribute("height", "height")).isSameAs(element)
assertThat(JDOMUtil.getSize(element)).isNull()
assertElementText(element, """<state width="1" height="height" />""")
}
@Test
fun `set&get size without required attribute`() {
val element = JDOMUtil.setSize(Element("state"), Dimension(1, 1))
assertThat(element.removeAttribute("height")).isTrue()
assertThat(JDOMUtil.getSize(element)).isNull()
assertElementText(element, """<state width="1" />""")
}
@Test
fun `set&get empty size`() {
val element = JDOMUtil.setSize(Element("state"), Dimension(0, 0))
assertThat(JDOMUtil.getSize(element)).isNull()
assertElementText(element, """<state width="0" height="0" />""")
}
@Test
fun `set&get bounds`() {
val bounds = Rectangle(1, 2, 3, 4)
val element = Element("state")
assertThat(JDOMUtil.setBounds(element, bounds)).isSameAs(element)
assertThat(JDOMUtil.getBounds(element)).isEqualTo(bounds).isNotSameAs(bounds)
assertElementText(element, """<state x="1" y="2" width="3" height="4" />""")
}
@Test
fun `set&get bounds with custom name`() {
val bounds = Rectangle(1, 2, 3, 4)
val element = Element("state")
assertThat(JDOMUtil.setBounds(element, "myX", "myY", "myW", "myH", bounds)).isSameAs(element)
assertThat(JDOMUtil.getBounds(element, "myX", "myY", "myW", "myH")).isEqualTo(bounds).isNotSameAs(bounds)
assertElementText(element, """<state myX="1" myY="2" myW="3" myH="4" />""")
}
@Test
fun `set&get bounds with invalid attribute`() {
val element = JDOMUtil.setBounds(Element("state"), Rectangle(1, 1, 1, 1))
assertThat(element.setAttribute("height", "height")).isSameAs(element)
assertThat(JDOMUtil.getBounds(element)).isNull()
assertElementText(element, """<state x="1" y="1" width="1" height="height" />""")
}
@Test
fun `set&get bounds without required attribute`() {
val element = JDOMUtil.setBounds(Element("state"), Rectangle(1, 1, 1, 1))
assertThat(element.removeAttribute("height")).isTrue()
assertThat(JDOMUtil.getBounds(element)).isNull()
assertElementText(element, """<state x="1" y="1" width="1" />""")
}
@Test
fun `set&get empty bounds`() {
val element = JDOMUtil.setBounds(Element("state"), Rectangle(1, 1, 0, 0))
assertThat(JDOMUtil.getBounds(element)).isNull()
assertElementText(element, """<state x="1" y="1" width="0" height="0" />""")
}
@Test
fun `equals and hashCode`() {
fun generateElement(data: Int): Element {
val s = Integer.toBinaryString(data).padStart(7, '0')
val element = Element("e${s.substring(0, 1)}")
val attributeName = s.substring(1, 3)
val attributeValue = s.substring(3, 5)
if (attributeName != "00" || attributeValue != "00") {
element.setAttribute("a$attributeName", if (attributeValue == "00") "" else attributeValue)
}
val subTag = s.substring(5, 7)
if (subTag == "01") {
element.addContent(Element("subTag"))
}
else if (subTag != "00") {
element.addContent(Text(subTag))
}
return element
}
for (data1 in 0 .. 31) {
val element1 = generateElement(data1)
for (data2 in 0..31) {
val element2 = generateElement(data2)
if (data1 == data2) {
assertThat(element1).isEqualTo(element2)
assertThat(JDOMUtil.hashCode(element1, false)).isEqualTo(JDOMUtil.hashCode(element2, false))
}
else {
assertThat(JDOMUtil.areElementsEqual(element1, element2)).isFalse()
}
}
}
}
@Test
fun mergeWithAttributes() {
val res = JDOMUtil.load(("<hello><data attr='1'><HiThere></HiThere></data></hello>").toByteArray())
val res2 = JDOMUtil.load(("<hello><data attr='1' additional='2'><HiThere></HiThere></data></hello>").toByteArray())
JDOMUtil.deepMergeWithAttributes(res, res2, listOf(MergeAttribute("data", "attr")))
assertEquals("""|<hello>
| <data attr="1" additional="2">
| <HiThere />
| </data>
|</hello>""".trimMargin(), JDOMUtil.write(res))
}
@Test(expected = JDOMException::class)
fun `handling of UncheckedStreamException for unsupported symbol`() {
val testRoot = File(PathManagerEx.getCommunityHomePath(), "platform/platform-tests/testData/vfs/encoding/DegreeSignWin1251.xml")
JDOMUtil.load(testRoot)
}
@Test(expected = JDOMException::class)
fun `handling of IllegalNameException for unsupported symbol`() {
JDOMUtil.load("<settings xmlns=\"\n" +
"http://maven.apache.org/SETTINGS/1.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
" xsi:schemaLocation=\"http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd\">\n" +
" <localRepository/>\n" +
"</settings>")
}
private fun assertElementText(actual: Element, expected: String) {
assertThat(JDOMUtil.writeElement(actual)).isEqualTo(expected)
}
}