-
Notifications
You must be signed in to change notification settings - Fork 93
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
distribute core code across diff + munit
- Loading branch information
Showing
29 changed files
with
968 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package munit.internal.io | ||
|
||
import java.net.URI | ||
|
||
// obtained implementation by experimentation on the JDK. | ||
class File(path: String) { | ||
def this(parent: String, child: String) = | ||
this(parent + File.separator + child) | ||
def this(parent: File, child: String) = | ||
this(parent.getPath, child) | ||
def this(uri: URI) = | ||
this( | ||
if (uri.getScheme != "file") { | ||
throw new IllegalArgumentException("URI scheme is not \"file\"") | ||
} else { | ||
uri.getPath | ||
} | ||
) | ||
def toPath: MunitPath = | ||
MunitPath(path) | ||
def toURI: URI = { | ||
val file = getAbsoluteFile.toString | ||
val uripath = | ||
if (file.startsWith("/")) file | ||
else "/" + file.replace(File.separator, "/") | ||
val withslash = | ||
if (isDirectory && !uripath.endsWith("/")) uripath + "/" else uripath | ||
new URI("file", null, withslash, null) | ||
} | ||
def getAbsoluteFile: File = | ||
toPath.toAbsolutePath.toFile | ||
def getAbsolutePath: String = | ||
getAbsoluteFile.toString | ||
def getParentFile: File = | ||
toPath.getParent.toFile | ||
def mkdirs(): Unit = | ||
throw new UnsupportedOperationException( | ||
"mkdirs() is not supported in Scala.js" | ||
) | ||
def getPath: String = | ||
path | ||
def exists(): Boolean = | ||
JSIO.exists(path) | ||
def isFile: Boolean = | ||
JSIO.isFile(path) | ||
def isDirectory: Boolean = | ||
JSIO.isDirectory(path) | ||
override def toString: String = | ||
path | ||
} | ||
|
||
object File { | ||
def listRoots(): Array[File] = Array( | ||
new File( | ||
JSIO.path match { | ||
case Some(p) => p.parse(p.resolve()).root.asInstanceOf[String] | ||
case None => "/" | ||
} | ||
// if (JSIO.isNode) JSPath.parse(JSPath.resolve()).root | ||
// else "/" | ||
) | ||
) | ||
|
||
def separatorChar: Char = | ||
separator.charAt(0) | ||
|
||
def separator: String = | ||
JSIO.path match { | ||
case Some(p) => p.sep.asInstanceOf[String] | ||
case None => "/" | ||
} | ||
|
||
def pathSeparator: String = | ||
JSIO.path match { | ||
case Some(p) => p.delimeter.asInstanceOf[String] | ||
case None => ":" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package munit.internal.io | ||
|
||
import scala.scalajs.js | ||
import java.{util => ju} | ||
import java.nio.charset.StandardCharsets | ||
|
||
import scala.collection.JavaConverters._ | ||
|
||
object Files { | ||
def readAllLines(path: MunitPath): ju.List[String] = { | ||
val bytes = readAllBytes(path) | ||
val text = new String(bytes, StandardCharsets.UTF_8) | ||
text.linesIterator.toSeq.asJava | ||
} | ||
def readAllBytes(path: MunitPath): Array[Byte] = { | ||
val jsArray = JSIO.fs match { | ||
case Some(fs) => | ||
fs.readFileSync(path.toString).asInstanceOf[js.Array[Int]] | ||
case None => new js.Array[Int](0) | ||
} | ||
val len = jsArray.length | ||
val result = new Array[Byte](len) | ||
var curr = 0 | ||
while (curr < len) { | ||
result(curr) = jsArray(curr).toByte | ||
curr += 1 | ||
} | ||
result | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package munit.internal.io | ||
|
||
import scala.scalajs.js | ||
import scala.util.Try | ||
|
||
object JSIO { | ||
|
||
private def require(module: String): Option[js.Dynamic] = { | ||
Try(js.Dynamic.global.require(module)) // Node.js | ||
.orElse( // JSDOM | ||
Try(js.Dynamic.global.Node.constructor("return require")()(module)) | ||
) | ||
.toOption | ||
} | ||
val process: Option[js.Dynamic] = require("process") | ||
val path: Option[js.Dynamic] = require("path") | ||
val fs: Option[js.Dynamic] = require("fs") | ||
|
||
def cwd(): String = | ||
process match { | ||
case Some(p) => p.cwd().asInstanceOf[String] | ||
case None => "/" | ||
} | ||
|
||
def exists(path: String): Boolean = | ||
fs match { | ||
case Some(f) => f.existsSync(path).asInstanceOf[Boolean] | ||
case None => false | ||
} | ||
|
||
def isFile(path: String): Boolean = | ||
exists(path) && (fs match { | ||
case Some(f) => f.lstatSync(path).isFile().asInstanceOf[Boolean] | ||
case None => false | ||
}) | ||
|
||
def isDirectory(path: String): Boolean = | ||
exists(path) && (fs match { | ||
case Some(f) => f.lstatSync(path).isDirectory().asInstanceOf[Boolean] | ||
case None => false | ||
}) | ||
} |
149 changes: 149 additions & 0 deletions
149
munit/js/src/main/scala/munit/internal/io/MunitPath.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
package munit.internal.io | ||
|
||
import java.net.URI | ||
import java.util | ||
|
||
import scala.collection.JavaConverters._ | ||
|
||
// Rough implementation of java.nio.Path, should work similarly for the happy | ||
// path but has undefined behavior for error handling. | ||
case class MunitPath(filename: String) { | ||
private[this] val escapedSeparator = | ||
java.util.regex.Pattern.quote(File.separator) | ||
|
||
private def adjustIndex(idx: Int): Int = | ||
if (isAbsolute) idx + 1 else idx | ||
def subpath(beginIndex: Int, endIndex: Int): MunitPath = | ||
MunitPath( | ||
filename | ||
.split(escapedSeparator) | ||
.slice(adjustIndex(beginIndex), adjustIndex(endIndex)) | ||
.mkString | ||
) | ||
def toFile: File = | ||
new File(filename) | ||
def isAbsolute: Boolean = JSIO.path match { | ||
case Some(path) => path.isAbsolute(filename).asInstanceOf[Boolean] | ||
case None => filename.startsWith(File.separator) | ||
} | ||
def getName(index: Int): MunitPath = | ||
MunitPath( | ||
filename | ||
.split(escapedSeparator) | ||
.lift(adjustIndex(index)) | ||
.getOrElse(throw new IllegalArgumentException) | ||
) | ||
def getParent: MunitPath = | ||
JSIO.path match { | ||
case Some(path) => | ||
MunitPath(path.dirname(filename).asInstanceOf[String]) | ||
case None => | ||
throw new UnsupportedOperationException( | ||
"Path.getParent() is only supported in Node.js" | ||
) | ||
} | ||
|
||
def toAbsolutePath: MunitPath = | ||
if (isAbsolute) this | ||
else MunitPath.workingDirectory.resolve(this) | ||
def relativize(other: MunitPath): MunitPath = | ||
JSIO.path match { | ||
case Some(path) => | ||
MunitPath( | ||
path.relative(filename, other.toString()).asInstanceOf[String] | ||
) | ||
case None => | ||
throw new UnsupportedOperationException( | ||
"Path.relativize() is only supported in Node.js" | ||
) | ||
} | ||
def getNameCount: Int = { | ||
val strippeddrive = | ||
if ((filename.length > 1) && (filename(1) == ':')) filename.substring(2) | ||
else filename | ||
val (first, remaining) = | ||
strippeddrive.split(escapedSeparator + "+").span(_.isEmpty) | ||
if (remaining.isEmpty) first.length | ||
else remaining.length | ||
} | ||
def toUri: URI = toFile.toURI | ||
def getFileName(): MunitPath = | ||
JSIO.path match { | ||
case Some(path) => | ||
MunitPath(path.basename(filename).asInstanceOf[String]) | ||
case None => | ||
throw new UnsupportedOperationException( | ||
"Path.getFileName() is only supported in Node.js" | ||
) | ||
} | ||
def getRoot: MunitPath = | ||
if (!isAbsolute) null | ||
else MunitPath(File.separator) | ||
def normalize(): MunitPath = | ||
JSIO.path match { | ||
case Some(path) => | ||
MunitPath(path.normalize(filename).asInstanceOf[String]) | ||
case None => | ||
throw new UnsupportedOperationException( | ||
"Path.normalize() is only supported in Node.js" | ||
) | ||
} | ||
def endsWith(other: MunitPath): Boolean = | ||
endsWith(other.toString) | ||
def endsWith(other: String): Boolean = | ||
paths(filename).endsWith(paths(other)) | ||
// JSPath.resolve(relpath, relpath) produces an absolute path from cwd. | ||
// This method turns the generated absolute path back into a relative path. | ||
private def adjustResolvedPath(resolved: MunitPath): MunitPath = | ||
if (isAbsolute) resolved | ||
else MunitPath.workingDirectory.relativize(resolved) | ||
def resolveSibling(other: MunitPath): MunitPath = | ||
resolveSibling(other.toString) | ||
def resolveSibling(other: String): MunitPath = | ||
JSIO.path match { | ||
case Some(path) => | ||
adjustResolvedPath( | ||
MunitPath( | ||
path | ||
.resolve(path.dirname(filename).asInstanceOf[String], other) | ||
.asInstanceOf[String] | ||
) | ||
) | ||
case None => | ||
throw new UnsupportedOperationException( | ||
"Path.normalize() is only supported in Node.js" | ||
) | ||
} | ||
def resolve(other: MunitPath): MunitPath = | ||
resolve(other.toString) | ||
def resolve(other: String): MunitPath = | ||
JSIO.path match { | ||
case Some(path) => | ||
adjustResolvedPath( | ||
MunitPath(path.resolve(filename, other).asInstanceOf[String]) | ||
) | ||
case None => | ||
throw new UnsupportedOperationException( | ||
"Path.normalize() is only supported in Node.js" | ||
) | ||
} | ||
def startsWith(other: MunitPath): Boolean = | ||
startsWith(other.toString) | ||
def startsWith(other: String): Boolean = | ||
paths(filename).startsWith(paths(other)) | ||
private def paths(name: String) = | ||
name.split(escapedSeparator) | ||
override def toString: String = | ||
filename | ||
def iterator(): util.Iterator[MunitPath] = | ||
filename | ||
.split(File.separator) | ||
.iterator | ||
.map(name => MunitPath(name): MunitPath) | ||
.asJava | ||
} | ||
|
||
object MunitPath { | ||
def workingDirectory: MunitPath = | ||
MunitPath(JSIO.cwd()) | ||
} |
Oops, something went wrong.