diff --git a/core/src/main/scala/scommons/nodejs/FS.scala b/core/src/main/scala/scommons/nodejs/FS.scala index f99c552..b4a0999 100644 --- a/core/src/main/scala/scommons/nodejs/FS.scala +++ b/core/src/main/scala/scommons/nodejs/FS.scala @@ -26,6 +26,15 @@ trait FS { p.future } + def ftruncate(fd: Int, len: Double): Future[Unit] = { + val p = Promise[Unit]() + raw.FS.ftruncate(fd, len, { error => + if (error != null && !js.isUndefined(error)) p.failure(js.JavaScriptException(error)) + else p.success(()) + }) + p.future + } + def openSync(path: String, flags: Int): Int = raw.FS.openSync(path, flags) def closeSync(fd: Int): Unit = raw.FS.closeSync(fd) diff --git a/core/src/main/scala/scommons/nodejs/raw/FS.scala b/core/src/main/scala/scommons/nodejs/raw/FS.scala index 5f62fb5..456d54d 100644 --- a/core/src/main/scala/scommons/nodejs/raw/FS.scala +++ b/core/src/main/scala/scommons/nodejs/raw/FS.scala @@ -16,6 +16,8 @@ object FS extends js.Object { def rename(oldPath: String | URL, newPath: String | URL, callback: js.Function1[js.Error, Unit]): Unit = js.native + def ftruncate(fd: Int, len: Double, callback: js.Function1[js.Error, Unit]): Unit = js.native + def openSync(path: String | URL, flags: Int): Int = js.native def closeSync(fd: Int): Unit = js.native diff --git a/showcase/src/test/scala/scommons/nodejs/FSSpec.scala b/showcase/src/test/scala/scommons/nodejs/FSSpec.scala index 3917894..8f40539 100644 --- a/showcase/src/test/scala/scommons/nodejs/FSSpec.scala +++ b/showcase/src/test/scala/scommons/nodejs/FSSpec.scala @@ -5,11 +5,11 @@ import scommons.nodejs.raw.FSConstants._ import scommons.nodejs.raw.{FSConstants, FileOptions} import scommons.nodejs.test.AsyncTestSpec +import scala.Ordering.Double.IeeeOrdering import scala.concurrent.Future import scala.scalajs.js import scala.scalajs.js.JavaScriptException import scala.scalajs.js.typedarray.Uint8Array -import scala.Ordering.Double.IeeeOrdering class FSSpec extends AsyncTestSpec { @@ -95,6 +95,57 @@ class FSSpec extends AsyncTestSpec { } } + it should "fail if invalid fd when ftruncate" in { + //given + val tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "scommons-nodejs-")) + val file = path.join(tmpDir, "example.txt") + fs.writeFileSync(file, "hello, World!!!") + val fd = fs.openSync(file, FSConstants.O_WRONLY) + fs.closeSync(fd) + + //when + val result = fs.ftruncate(fd, 5) + + //then + result.failed.map { + case JavaScriptException(error) => + error.toString should include ("EBADF: bad file descriptor") + }.andThen { + case _ => + //cleanup + fs.unlinkSync(file) + fs.rmdirSync(tmpDir) + } + } + + it should "truncate file when ftruncate" in { + //given + val tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "scommons-nodejs-")) + val file = path.join(tmpDir, "example.txt") + fs.writeFileSync(file, "hello, World!!!") + fs.readFileSync(file, new FileOptions { + override val encoding = "utf8" + }) shouldBe "hello, World!!!" + val fd = fs.openSync(file, FSConstants.O_WRONLY) + + //when + val result = fs.ftruncate(fd, 5) + + //then + result.map { _ => + fs.closeSync(fd) + fs.lstatSync(file).size shouldBe 5 + fs.readFileSync(file, new FileOptions { + override val encoding = "utf8" + }) shouldBe "hello" + }.andThen { + case _ => + //cleanup + fs.unlinkSync(file) + fs.rmdirSync(tmpDir) + } + } + it should "return stats when lstatSync" in { //when val stats = fs.lstatSync(os.homedir())