Newer
Older
komp / src / jsTest / kotlin / nl / astraeus / komp / TestUpdate.kt
rnentjes on 5 Apr 2021 2 KB VDom implementation
package nl.astraeus.komp

import kotlinx.html.*
import kotlinx.html.js.onClickFunction
import org.w3c.dom.Element
import org.w3c.dom.HTMLElement
import org.w3c.dom.get
import kotlin.test.Test
import kotlin.test.assertTrue

fun nodesEqual(element: Element, vdom: VDOMElement): Boolean {
  if (element.childNodes.length != vdom.childNodes.size) {
    return false
  }
  if (element.attributes.length != vdom.attributes.size) {
    return false
  }
  for ((name, value) in vdom.attributes) {
    if (value != element.getAttribute(name)) {
      return false
    }
  }
  for ((index, child) in vdom.childNodes.withIndex()) {
    if (index < element.childNodes.length) {
      val elementChild = element.childNodes[index]

      if (child.type == VDOMElementType.TAG) {
        if (!nodesEqual(elementChild as HTMLElement, child)) {
          return false
        }
      } else if (child.type == VDOMElementType.TEXT) {
        if (child.content != element.textContent) {
          return false
        }
      }
    } else {
      return false
    }
  }

  return true
}

class TestUpdate {

  @Test
  fun testCompare() {
    val dom1 = HtmlBuilder.create {
      div {
        div(classes = "bla") {
          span {
            +" Some Text "
          }
          table {
            tr {
              td {
                +"Table column"
              }
            }
          }
        }
      }
    }

    val dom2 = HtmlBuilder.create {
      div {
        span {
          id = "123"

          +"New dom!"
        }
        input {
          value = "bla"
        }
      }
    }

    var element = dom1.createElement()

    assertTrue(nodesEqual(element as Element, dom1), "Created dom not equal to original")

    element = DiffPatch.updateNode(element, dom1, dom2) as HTMLElement

    assertTrue(nodesEqual(element, dom2), "Updated dom not equal to original")
  }

  @Test
  fun testCompare2() {
    val dom1 = HtmlBuilder.create {
      div {
        div(classes = "bla") {
          span {
            +" Some Text "
          }
          table {
            tr {
              th {
                +"Header"
              }
            }
            tr {
              td {
                +"Table column"
              }
            }
          }
        }
      }
    }

    val dom2 = HtmlBuilder.create {
      div {
        div {
          span {
            +"Other text"
          }
        }
        span {
          id = "123"

          +"New dom!"
        }
        input {
          value = "bla"

          onClickFunction = {
            println("Clickerdyclick!")
          }
        }
      }
    }

    Komponent.logRenderEvent = true

    var element = dom1.createElement()

    assertTrue(nodesEqual(element as Element, dom1), "Created dom not equal to original")

    element = DiffPatch.updateNode(element, dom1, dom2) as HTMLElement

    assertTrue(nodesEqual(element, dom2), "Updated dom not equal to original")
  }

}