Skip to content

Add support for JSDOM JSEnv #456

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

Merged
merged 11 commits into from
May 29, 2022
Merged
4 changes: 3 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ lazy val sharedSettings = List(
scalacOptions.value
}
},
libraryDependencies += "org.scalameta" %% "munit" % munitVersion % Test
libraryDependencies += "org.scalameta" %%% "munit" % munitVersion % Test
)

lazy val root = Project("scalac-scoverage", file("."))
Expand Down Expand Up @@ -113,6 +113,8 @@ lazy val runtime = CrossProject(
)
.jsSettings(
scalaJSStage := FastOptStage
// Uncomment to test JSDOM
// jsEnv := new org.scalajs.jsenv.jsdomnodejs.JSDOMNodeJSEnv()
)

lazy val `runtimeJVM` = runtime.jvm
Expand Down
2 changes: 2 additions & 0 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.5.10")
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.6")

addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.9.33")

libraryDependencies += "org.scala-js" %% "scalajs-env-jsdom-nodejs" % "1.1.0"
8 changes: 8 additions & 0 deletions runtime/js/src/main/scala/scalajssupport/File.scala
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,14 @@ object File {
RhinoFile
else if (globalObject.hasOwnProperty("callPhantom").asInstanceOf[Boolean])
PhantomFile
else if (
globalObject
.hasOwnProperty("navigator")
.asInstanceOf[Boolean] && globalObject.navigator.userAgent
.asInstanceOf[js.UndefOr[String]]
.exists(_.contains("jsdom"))
)
JSDOMFile
else
NodeFile
// Factorize this
Expand Down
45 changes: 28 additions & 17 deletions runtime/js/src/main/scala/scalajssupport/NodeFile.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,23 @@ package scalajssupport

import scala.scalajs.js

class NodeFile(path: String) extends JsFile {
def this(path: String, child: String) = {
this(NodeFile.nodePath.join(path, child))
class NodeFile(path: String)(implicit fs: FS, nodePath: NodePath)
extends JsFile {
def this(path: String, child: String)(implicit fs: FS, nodePath: NodePath) = {
this(nodePath.join(path, child))
}

def delete(): Unit = {
if (isDirectory()) NodeFile.fs.rmdirSync(path)
else NodeFile.fs.unlinkSync(path)
if (isDirectory()) fs.rmdirSync(path)
else fs.unlinkSync(path)
}

def getAbsolutePath(): String = {
NodeFile.fs.realpathSync(path)
fs.realpathSync(path)
}

def getName(): String = {
NodeFile.nodePath.basename(path)
nodePath.basename(path)
}

def getPath(): String = {
Expand All @@ -26,7 +27,7 @@ class NodeFile(path: String) extends JsFile {

def isDirectory(): Boolean = {
try {
NodeFile.fs.lstatSync(path).isDirectory()
fs.lstatSync(path).isDirectory()
} catch {
// return false if the file does not exist
case e: Exception => false
Expand All @@ -37,9 +38,9 @@ class NodeFile(path: String) extends JsFile {
path
.split("/")
.foldLeft("")((acc: String, x: String) => {
val new_acc = NodeFile.nodePath.join(acc, x)
val new_acc = nodePath.join(acc, x)
try {
NodeFile.fs.mkdirSync(new_acc)
fs.mkdirSync(new_acc)
} catch {
case e: Exception =>
}
Expand All @@ -48,16 +49,16 @@ class NodeFile(path: String) extends JsFile {
}

def listFiles(): Array[File] = {
val files = NodeFile.fs.readdirSync(path)
val files = fs.readdirSync(path)
val filesArray = new Array[File](files.length)
for ((item, i) <- filesArray.zipWithIndex) {
filesArray(i) = new File(NodeFile.nodePath.join(this.getPath(), files(i)))
filesArray(i) = new File(nodePath.join(this.getPath(), files(i)))
}
filesArray
}

def readFile(): String = {
NodeFile.fs.readFileSync(path, js.Dynamic.literal(encoding = "utf-8"))
fs.readFileSync(path, js.Dynamic.literal(encoding = "utf-8"))
}

}
Expand Down Expand Up @@ -91,10 +92,12 @@ trait NodePath extends js.Object {
def join(paths: String*): String = js.native
}

private[scalajssupport] object NodeFile extends JsFileObject {
val fs: FS = js.Dynamic.global.require("fs").asInstanceOf[FS]
val nodePath: NodePath =
js.Dynamic.global.require("path").asInstanceOf[NodePath]
private[scalajssupport] trait NodeLikeFile extends JsFileObject {
def require: js.Dynamic

implicit lazy val fs: FS = require("fs").asInstanceOf[FS]
implicit lazy val nodePath: NodePath = require("path").asInstanceOf[NodePath]

def write(path: String, data: String, mode: String = "a") = {
fs.writeFileSync(path, data, js.Dynamic.literal(flag = mode))
}
Expand All @@ -107,3 +110,11 @@ private[scalajssupport] object NodeFile extends JsFileObject {
new NodeFile(path)
}
}

private[scalajssupport] object NodeFile extends NodeLikeFile {
lazy val require = js.Dynamic.global.require
}

private[scalajssupport] object JSDOMFile extends NodeLikeFile {
lazy val require = js.Dynamic.global.Node.constructor("return require")()
}