Skip to content

Commit

Permalink
Run and test ESModule scripts as ES Modules (#1142)
Browse files Browse the repository at this point in the history
Fixes #1104
  • Loading branch information
hugo-vrijswijk authored Jun 30, 2022
1 parent a3718c9 commit 4b50db8
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 12 deletions.
18 changes: 13 additions & 5 deletions modules/build/src/main/scala/scala/build/internal/Runner.scala
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,8 @@ object Runner {
logger: Logger,
allowExecve: Boolean = false,
jsDom: Boolean = false,
sourceMap: Boolean = false
sourceMap: Boolean = false,
esModule: Boolean = false
): Process = {

import logger.{log, debug}
Expand Down Expand Up @@ -201,7 +202,10 @@ object Runner {
sys.error("should not happen")
}
else {
val inputs = Seq(Input.Script(entrypoint.toPath))
val inputs = Seq(
if (esModule) Input.ESModule(entrypoint.toPath)
else Input.Script(entrypoint.toPath)
)

val config = RunConfig().withLogger(logger.scalaJsLogger)
val processJs = envJs.start(inputs, config)
Expand Down Expand Up @@ -309,7 +313,8 @@ object Runner {
args: Seq[String],
testFrameworkOpt: Option[String],
logger: Logger,
jsDom: Boolean
jsDom: Boolean,
esModule: Boolean
): Either[TestError, Int] = either {
import org.scalajs.jsenv.Input
import org.scalajs.jsenv.nodejs.NodeJSEnv
Expand All @@ -330,8 +335,11 @@ object Runner {
.withEnv(Map.empty)
.withSourceMap(NodeJSEnv.SourceMap.Disable)
)
val adapterConfig = TestAdapter.Config().withLogger(logger.scalaJsLogger)
val inputs = Seq(Input.Script(entrypoint.toPath))
val adapterConfig = TestAdapter.Config().withLogger(logger.scalaJsLogger)
val inputs = Seq(
if (esModule) Input.ESModule(entrypoint.toPath)
else Input.Script(entrypoint.toPath)
)
var adapter: TestAdapter = null

logger.debug(s"JS tests class path: $classPath")
Expand Down
13 changes: 9 additions & 4 deletions modules/cli/src/main/scala/scala/cli/commands/Run.scala
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,11 @@ object Run extends ScalaCommand[RunOptions] {

val process = build.options.platform.value match {
case Platform.JS =>
val esModule =
build.options.scalaJsOptions.moduleKindStr.exists(m => m == "es" || m == "esmodule")

val linkerConfig = build.options.scalaJsOptions.linkerConfig(logger)
val jsDest = os.temp(prefix = "main", suffix = ".js")
val jsDest = os.temp(prefix = "main", suffix = if (esModule) ".mjs" else ".js")
val res =
Package.linkJs(
build,
Expand All @@ -240,7 +243,8 @@ object Run extends ScalaCommand[RunOptions] {
logger,
allowExecve = allowExecve,
jsDom = build.options.scalaJsOptions.dom.getOrElse(false),
sourceMap = build.options.scalaJsOptions.emitSourceMaps
sourceMap = build.options.scalaJsOptions.emitSourceMaps,
esModule = esModule
)
process.onExit().thenApply(_ => if (os.exists(jsDest)) os.remove(jsDest))
process
Expand Down Expand Up @@ -281,9 +285,10 @@ object Run extends ScalaCommand[RunOptions] {
config: ScalaJsLinkerConfig,
fullOpt: Boolean,
noOpt: Boolean,
logger: Logger
logger: Logger,
esModule: Boolean
)(f: os.Path => T): Either[BuildException, T] = {
val dest = os.temp(prefix = "main", suffix = ".js")
val dest = os.temp(prefix = "main", suffix = if (esModule) ".mjs" else ".js")
try Package.linkJs(
build,
dest,
Expand Down
10 changes: 7 additions & 3 deletions modules/cli/src/main/scala/scala/cli/commands/Test.scala
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ object Test extends ScalaCommand[TestOptions] {
build.options.platform.value match {
case Platform.JS =>
val linkerConfig = build.options.scalaJsOptions.linkerConfig(logger)
val esModule =
build.options.scalaJsOptions.moduleKindStr.exists(m => m == "es" || m == "esmodule")
value {
Run.withLinkedJs(
build,
Expand All @@ -173,7 +175,8 @@ object Test extends ScalaCommand[TestOptions] {
linkerConfig,
build.options.scalaJsOptions.fullOpt,
build.options.scalaJsOptions.noOpt.getOrElse(false),
logger
logger,
esModule
) { js =>
Runner.testJs(
build.fullClassPath.map(_.toNIO),
Expand All @@ -182,9 +185,10 @@ object Test extends ScalaCommand[TestOptions] {
args,
testFrameworkOpt,
logger,
build.options.scalaJsOptions.dom.getOrElse(false)
build.options.scalaJsOptions.dom.getOrElse(false),
esModule
)
}.flatMap(e => e)
}.flatten
}
case Platform.Native =>
value {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,34 @@ abstract class RunTestDefinitions(val scalaVersionOpt: Option[String])
simpleJsTest("--js-mode", "release")
}

test("esmodule import JS") {
val fileName = "simple.sc"
val message = "Hello"
val inputs = TestInputs(
Seq(
os.rel / fileName ->
s"""//> using jsModuleKind "es"
|import scala.scalajs.js
|import scala.scalajs.js.annotation._
|
|@js.native
|@JSImport("console", JSImport.Namespace)
|object console extends js.Object {
| def log(msg: js.Any): Unit = js.native
|}
|
|val msg = "$message"
|console.log(msg)
|""".stripMargin
)
)
inputs.fromRoot { root =>
val output = os.proc(TestUtil.cli, extraOptions, fileName, "--js")
.call(cwd = root).out.text().trim()
expect(output == message)
}
}

test("simple script JS via config file") {
val message = "Hello"
val inputs = TestInputs(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,28 @@ abstract class TestTestDefinitions(val scalaVersionOpt: Option[String])
)
)

val successfulESModuleTestInputs = TestInputs(
Seq(os.rel / "MyTests.scala" ->
"""//> using lib "org.scalameta::munit::0.7.29"
|//> using jsModuleKind "esmodule"
|import scala.scalajs.js
|import scala.scalajs.js.annotation._
|
|@js.native
|@JSImport("console", JSImport.Namespace)
|object console extends js.Object {
| def log(msg: js.Any): Unit = js.native
|}
|
|class MyTests extends munit.FunSuite {
| test("foo") {
| assert(2 + 2 == 4)
| console.log("Hello from " + "tests")
| }
|}
|""".stripMargin)
)

test("successful test") {
successfulTestInputs.fromRoot { root =>
val output = os.proc(TestUtil.cli, "test", extraOptions, ".").call(cwd = root).out.text()
Expand All @@ -187,6 +209,15 @@ abstract class TestTestDefinitions(val scalaVersionOpt: Option[String])
}
}

test("successful test esmodule import JS") {
successfulESModuleTestInputs.fromRoot { root =>
val output = os.proc(TestUtil.cli, "test", extraOptions, ".", "--js")
.call(cwd = root)
.out.text()
expect(output.contains("Hello from tests"))
}
}

def successfulNativeTest(): Unit =
successfulTestInputs.fromRoot { root =>
val output = os.proc(TestUtil.cli, "test", extraOptions, ".", "--native")
Expand Down

0 comments on commit 4b50db8

Please sign in to comment.