tenderowls / moorka

ABANDONED
21 stars 5 forks source link

DataRepeat doesn't append children to DOM #47

Closed vsuharnikov closed 9 years ago

vsuharnikov commented 9 years ago

A test case that reproduces the problem:

package moorka.testkit

import moorka.rx.base.Var
import moorka.rx.{Rx, ToRxSeqOps}
import moorka.ui.components.base.DataRepeat
import moorka.ui.components.html._
import moorka.ui.element.ElementBase
import moorka.ui.switch
import utest._
import utest.framework.TestSuite

import scala.concurrent.{Promise, Future}
import scala.concurrent.duration._
import scalajs.concurrent.JSExecutionContext.Implicits.runNow
import scalajs.js

object DataRepeatSuite extends TestSuite {

  implicit val timeout = 10.seconds // Timeout for every test

  val tests = TestSuite {
    "it should immediately add elements to the DOM if the buffer is stateful" - MoorkaUiTest { app ⇒
      val source = Var(Seq("foo", "bar", "baz"))
      val data = source.toBuffer

      for {
        el ← app.insertHtmlElement(div {
          DataRepeat(
            data,
            factory
          )
        })
        _ ← sleep(3.seconds) // Not necessary, but we do
      } yield {
        println(s"children count: ${el.children.length }")
        println(s"outerHTML: ${el.outerHTML }")
        assert(el.children.length > 0)
      }
    }
  }

  private def factory(input: Rx[String]): ElementBase =
    div(switch {
      input.map(div(_))
    })

  private def sleep(duration: Duration): Future[Unit] = {
    var p = Promise[Unit]()
    js.Dynamic.global.setTimeout({ () ⇒
      p.success(())
    }, duration.toMillis)

    p.future
  }

}

Something interesting happens, when we change the test:

val tests = TestSuite {
  "it should immediately add elements to the DOM if the buffer is stateful" - MoorkaUiTest { app ⇒
    val source = Var(Seq("foo", "bar", "baz"))
    val data = source.toBuffer

    for {
      el ← app.insertHtmlElement(div {
        DataRepeat(
          data,
          factory
        )
      })
      _ = source.pull(Var(Seq("foo", "bar", "baz", "quux"))) // <-- Changes
    } yield {
      println(s"children count: ${el.children.length }")
      println(s"outerHTML: ${el.outerHTML }")
      assert(el.children.length > 0)
    }
  }
}

We'll see:

children count: 1
outerHTML: <div id="5fac16ca-b198-42de-955d-060bc8bcf090" name="1g0th46"><div id="3e2be78b-ef4d-427f-8486-a76863857f86"><div id="84fb3d91-3bc2-4c2e-9d28-373d64e0db72">quux</div></div></div>

Only one item is added (quux), so it might be a problem in BufferView.