1

我正在编写一个单元测试,我想将一些由库(KVision)生成的 HTML 与一些预期的 HTML 进行比较。

为此,我想对 HTML 进行格式化,使其布局合理,并且可以轻松比较预期的 HTML 和实际的 HTML。

不一定需要美化 HTML。如果有一些 Kotlin/JS 库可以进行 HTML 比较,以便清楚地报告差异,那就行了!

要求

  1. 为了减少维护需求,我更喜欢使用库来解决这个问题,而不是自定义代码。而且我更希望该库位于 Kotlin/JS 中,而不是包装的 NPM 依赖项
  2. 格式化程序应该是宽松的,不要试图清理无效的 HTML,这样如果提供或生成了无效的 HTML,测试可能会失败

考试

该测试生成一个 LeafletJS 映射并将其添加到根元素。(我正在为 KVision 开发一项新功能,因此下面的代码尚不可用。)

import io.kotest.matchers.shouldBe
import io.kvision.MapsModule
import io.kvision.maps.Maps
import io.kvision.panel.ContainerType
import io.kvision.panel.Root
import io.kvision.test.DomSpec
import io.kvision.utils.px
import kotlin.test.Test
import kotlin.test.assertTrue
import kotlinx.browser.document
import kotlinx.html.html
import kotlinx.html.stream.appendHTML
import kotlinx.html.unsafe
import nl.adaptivity.xmlutil.JSDomReader
import nl.adaptivity.xmlutil.serialization.DefaultXmlSerializationPolicy
import nl.adaptivity.xmlutil.serialization.XML
import nl.adaptivity.xmlutil.serialization.XmlSerializationPolicy


@Test
fun example() = run {

    val root = Root("test", containerType = ContainerType.FIXED)

    val map = Maps {
        width = 300.px
        height = 600.px

        configureMap {
            setView(LatLng(55, 33), 11)
            options.crs = CRS.Simple

            MapsModule.convertTileLayer(BaseTileLayer.EMPTY)
                .addTo(this)
        }
    }
    root.add(map)
    // 'document' is from kotlinx.browser
    val element = document.getElementById("test")!!

    val actualHtml : String = element.innerHTML
    val expectedHtml: String = """
        <div class="leaflet-container leaflet-touch leaflet-fade-anim leaflet-grab leaflet-touch-drag leaflet-touch-zoom" tabindex="0" style="width: 300px; height: 600px; position: relative;">
          <!-- some expected HTML... -->
        </div>
        """.trimIndent()

    actualHtml shouldBe expectedHtml
}

我使用Kotest进行字符串比较,因为这会在控制台中触发 IntelliJ 的“点击查看差异”链接。

控制台日志中的“单击查看差异”

比较

然而,生成的代码是紧凑的 HTML,因此无法看到预期 HTML 和实际 HTML 之间的差异。

IntelliJ 差异屏幕,显示预期的 HTML(格式漂亮)与实际的 HTML(都在一行上)

我想美化预期和实际的 HTML,以便可以轻松看到差异。

尝试

自定义字符串操作

我尝试在每个右角括号上插入换行符>,虽然一致,但这并不“正确”,并且要求 HTML 属性始终以特定顺序显示,但情况可能并非总是如此。

// condense the expected-HTML to a single line
val expectedHtmlMinified: String = expectedHtml.split("\n").joinToString("") { it.trim() }

// split up the HTML so it's easier to compare
actualHtml.replace(">", ">\n") shouldBe expectedHtmlMinified.replace(">", ">\n")

现在更容易看出差异:

IntelliJ diff 工具显示预期和实际 HTML 之间的差异,它们都是多行的,而不是压缩成单行的。 第 5-9 行突出显示了差异

XmlUtil

XmlUtil可用于 Kotlin/JS,并且提到了漂亮的打印和设置缩进,但我认为它需要设置带有注释的类,或自定义序列化策略 - 我不会为整个 HTML 模式这样做!如果 XmlUtil 可以读取 w3c DOM 文档并将其漂亮地打印出来,那就太好了。

kotlinx.html

kotlinx.html - 看起来这既不能解析 w3c DOM 文档,也不能解析 HTML 字符串。

我尝试使用该unsafe { }块(在此处记录),但是虽然使用 DSL 构造的 HTML 元素已格式化,但原始 HTML 未格式化。

val actual = buildString {
    appendHTML(prettyPrint = true).html {
        unsafe {
            raw(element.innerHTML)
        }
    }
}
4

0 回答 0