Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mountInto extension #347

Closed
wants to merge 5 commits into from
Closed

Conversation

gmkumar2005
Copy link
Contributor

The mountInto extension is similar to renderInto. However, it creates a Resource that can be evaluated and safely disposed of immediately, making it useful for scenarios such as unit testing.

On the other hand, renderInto is used to evaluate a resource and then keep it open indefinitely. This is typically used for mounting the application in the browser.

Example usage in Unit testing

test("renders empty elements") {
    val empty_div: Resource[IO, Element[IO]] = div("")
    empty_div.mountInto(rootElement).surround {
      IO {
        val expectedEl = document.createElement("div")
        val actual = dom.document.querySelector("#app > div")
        assert(actual != null, "querySelector returned null check if the query is correct")
        assertEquals(actual.outerHTML, expectedEl.outerHTML)
      }
    }
}

@gmkumar2005
Copy link
Contributor Author

All review suggestions done.

@armanbilge
Copy link
Owner

Sorry, I'm looking again and I don't really understand how this is different from renderInto?

On the other hand, renderInto is used to evaluate a resource and then keep it open indefinitely.

It doesn't keep it open indefinitely.

def renderInto(root: fs2.dom.Node[F])(using Functor[F], Dom[F]): Resource[F, Unit] =
component.flatMap { e => Resource.make(root.appendChild(e))(_ => root.removeChild(e)) }

@gmkumar2005
Copy link
Contributor Author

Agree, My original comment is not accurate. The only difference is type of the first parameter.

@armanbilge
Copy link
Owner

Thanks for clarifying! I'm not sure about introducing this new method then. It's not really clear why one is "rendering" and the other is "mounting" and what the difference is. Instead I think doing something like this makes it more clear what is happening:

rootElement.toResource.flatMap(empty_div.renderInto(_))

Since you are in the context of a Munit test suite, maybe you want to use a fixture? Then you could shorten it to something like this:

empty_div.renderInto(root())

@gmkumar2005
Copy link
Contributor Author

Primary use case of this PR is unit testing. It can be solved using fixture as below.

package basic

import calico.*
import calico.syntax.*
import calico.html.io.*
import calico.html.io.given
import cats.effect.IO
import cats.effect.Resource
import domutils.CalicoSuite
import fs2.dom.Element
import fs2.dom.Node
import munit.CatsEffectSuite
import munit.catseffect.IOFixture
import org.scalajs.dom
import org.scalajs.dom.document

class BasicSuite extends CalicoSuite {
  val mainApp: IOFixture[Node[IO]] = ResourceSuiteLocalFixture(
    "main-app",
    Resource.eval(rootElement)
  )

  override def munitFixtures = List(mainApp)

  test("renders empty elements") {
    val empty_div: Resource[IO, Element[IO]] = div("")
    empty_div.renderInto(mainApp()).surround {
      IO {
        val expectedEl = document.createElement("div")
        val actual = dom.document.querySelector("#app > div")
        assert(actual != null, "querySelector returned null check if the query is correct")
        assertEquals(actual.outerHTML, expectedEl.outerHTML)
      }
    } *> {
      val empty_span: Resource[IO, Element[IO]] = span("")
      empty_span.renderInto(mainApp()).surround {
        IO {
          val expectedEl = document.createElement("span")
          val actual = dom.document.querySelector("#app > span")
          assert(actual != null, "querySelector returned null check if the query is correct")
          assertEquals(actual.outerHTML, expectedEl.outerHTML)
        }
      }
    }
  }
}

Above code uses renderInto hence there is no need of mountInto
Closing this PR

@gmkumar2005 gmkumar2005 deleted the mountinto_syntax branch January 30, 2024 06:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants