From 545c90e88e9bffb76640b8d38600026e7f5c2bcc Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Thu, 30 May 2024 23:12:55 +0800 Subject: [PATCH 1/5] . --- os/test/src-jvm/ExampleTests.scala | 283 --------- .../{src-jvm => src}/ExampleResourcess.scala | 0 os/test/src/ExampleTests.scala | 564 ++++++++++++++++++ .../ProcessPipelineTests.scala | 0 .../SpawningSubprocessesTests.scala | 18 +- 5 files changed, 573 insertions(+), 292 deletions(-) delete mode 100644 os/test/src-jvm/ExampleTests.scala rename os/test/{src-jvm => src}/ExampleResourcess.scala (100%) create mode 100644 os/test/src/ExampleTests.scala rename os/test/{src-jvm => src}/ProcessPipelineTests.scala (100%) rename os/test/{src-jvm => src}/SpawningSubprocessesTests.scala (93%) diff --git a/os/test/src-jvm/ExampleTests.scala b/os/test/src-jvm/ExampleTests.scala deleted file mode 100644 index fbb2335e..00000000 --- a/os/test/src-jvm/ExampleTests.scala +++ /dev/null @@ -1,283 +0,0 @@ -package test.os - -import java.nio.file.attribute.{GroupPrincipal, FileTime} - -import utest._ -object ExampleTests extends TestSuite { - - val tests = Tests { - test("splash") - TestUtil.prep { wd => - if (Unix()) { - // Make sure working directory exists and is empty - val wd = os.pwd / "out" / "splash" - os.remove.all(wd) - os.makeDir.all(wd) - - os.write(wd / "file.txt", "hello") - os.read(wd / "file.txt") ==> "hello" - - os.copy(wd / "file.txt", wd / "copied.txt") - os.list(wd) ==> Seq(wd / "copied.txt", wd / "file.txt") - - val invoked = os.proc("cat", wd / "file.txt", wd / "copied.txt").call(cwd = wd) - invoked.out.trim() ==> "hellohello" - } - } - - test("concatTxt") - TestUtil.prep { wd => - // Find and concatenate all .txt files directly in the working directory - os.write( - wd / "all.txt", - os.list(wd).filter(_.ext == "txt").map(os.read) - ) - - os.read(wd / "all.txt") ==> - """I am cowI am cow - |Hear me moo - |I weigh twice as much as you - |And I look good on the barbecue""".stripMargin - } - - test("subprocessConcat") - TestUtil.prep { wd => - val catCmd = if (scala.util.Properties.isWin) "type" else "cat" - // Find and concatenate all .txt files directly in the working directory - TestUtil.proc(catCmd, os.list(wd).filter(_.ext == "txt")) - .call(stdout = wd / "all.txt") - - os.read(wd / "all.txt") ==> - """I am cowI am cow - |Hear me moo - |I weigh twice as much as you - |And I look good on the barbecue""".stripMargin - } - - test("curlToTempFile") - TestUtil.prep { wd => - if (Unix()) { - // Curl to temporary file - val temp = os.temp() - os.proc("curl", "-L", ExampleResourcess.RemoteReadme.url) - .call(stdout = temp) - - os.size(temp) ==> ExampleResourcess.RemoteReadme.size - - // Curl to temporary file - val temp2 = os.temp() - val proc = os.proc("curl", "-L", ExampleResourcess.RemoteReadme.url).spawn() - - os.write.over(temp2, proc.stdout) - os.size(temp2) ==> ExampleResourcess.RemoteReadme.size - - assert(os.size(temp) == os.size(temp2)) - } - } - - test("lineCount") - TestUtil.prep { wd => - // Line-count of all .txt files recursively in wd - val lineCount = os.walk(wd) - .filter(_.ext == "txt") - .map(os.read.lines) - .map(_.size) - .sum - - lineCount ==> 9 - } - - test("largestThree") - TestUtil.prep { wd => - // Find the largest three files in the given folder tree - val largestThree = os.walk(wd) - .filter(os.isFile(_, followLinks = false)) - .map(x => os.size(x) -> x).sortBy(-_._1) - .take(3) - - // on unix it is 81 bytes, win adds 3 bytes (3 \r characters) - val multilineSizes = Set[Long](81, 84) - assert(multilineSizes contains os.stat(wd / "Multi Line.txt").size) - - // ignore multiline (second file) because its size varies - largestThree.filterNot(_._2.last == "Multi Line.txt") ==> Seq( - (711, wd / "misc" / "binary.png"), - (22, wd / "folder1" / "one.txt") - ) - } - - test("moveOut") - TestUtil.prep { wd => - // Move all files inside the "misc" folder out of it - import os.{GlobSyntax, /} - os.list(wd / "misc").map(os.move.matching { case p / "misc" / x => p / x }) - } - - test("frequency") - TestUtil.prep { wd => - // Calculate the word frequency of all the text files in the folder tree - def txt = os.walk(wd).filter(_.ext == "txt").map(os.read) - def freq(s: Seq[String]) = s.groupBy(x => x).mapValues(_.length).toSeq - val map = freq(txt.flatMap(_.split("[^a-zA-Z0-9_]"))).sortBy(-_._2) - map - } - test("comparison") { - - os.remove.all(os.pwd / "out" / "scratch" / "folder" / "thing" / "file") - os.write( - os.pwd / "out" / "scratch" / "folder" / "thing" / "file", - "Hello!", - createFolders = true - ) - - def removeAll(path: String) = { - def getRecursively(f: java.io.File): Seq[java.io.File] = { - f.listFiles.filter(_.isDirectory).flatMap(getRecursively) ++ f.listFiles - } - getRecursively(new java.io.File(path)).foreach { f => - println(f) - if (!f.delete()) - throw new RuntimeException("Failed to delete " + f.getAbsolutePath) - } - new java.io.File(path).delete - } - removeAll("out/scratch/folder/thing") - - assert(os.list(os.pwd / "out" / "scratch" / "folder").toSeq == Nil) - - os.write( - os.pwd / "out" / "scratch" / "folder" / "thing" / "file", - "Hello!", - createFolders = true - ) - - os.remove.all(os.pwd / "out" / "scratch" / "folder" / "thing") - assert(os.list(os.pwd / "out" / "scratch" / "folder").toSeq == Nil) - } - - test("constructingPaths") { - - // Get the process' Current Working Directory. As a convention - // the directory that "this" code cares about (which may differ - // from the pwd) is called `wd` - val wd = os.pwd - - // A path nested inside `wd` - wd / "folder" / "file" - - // A path starting from the root - os.root / "folder" / "file" - - // A path with spaces or other special characters - wd / "My Folder" / "My File.txt" - - // Up one level from the wd - wd / os.up - - // Up two levels from the wd - wd / os.up / os.up - } - test("newPath") { - - val target = os.pwd / "out" / "scratch" - } - test("relPaths") { - - // The path "folder/file" - val rel1 = os.rel / "folder" / "file" - val rel2 = os.rel / "folder" / "file" - - // The relative difference between two paths - val target = os.pwd / "out" / "scratch" / "file" - assert((target relativeTo os.pwd) == os.rel / "out" / "scratch" / "file") - - // `up`s get resolved automatically - val minus = os.pwd relativeTo target - val ups = os.up / os.up / os.up - assert(minus == ups) - ( - rel1: os.RelPath, - rel2: os.RelPath - ) - } - test("subPaths") { - - // The path "folder/file" - val sub1 = os.sub / "folder" / "file" - val sub2 = os.sub / "folder" / "file" - - // The relative difference between two paths - val target = os.pwd / "out" / "scratch" / "file" - assert((target subRelativeTo os.pwd) == os.sub / "out" / "scratch" / "file") - - // Converting os.RelPath to os.SubPath - val rel3 = os.rel / "folder" / "file" - val sub3 = rel3.asSubPath - - // `up`s are not allowed in sub paths - intercept[Exception](os.pwd subRelativeTo target) - } - test("relSubPathEquality") { - assert( - (os.sub / "hello" / "world") == (os.rel / "hello" / "world"), - os.sub == os.rel - ) - } - test("relPathCombine") { - val target = os.pwd / "out" / "scratch" / "file" - val rel = target relativeTo os.pwd - val newBase = os.root / "code" / "server" - assert(newBase / rel == os.root / "code" / "server" / "out" / "scratch" / "file") - } - test("subPathCombine") { - val target = os.pwd / "out" / "scratch" / "file" - val sub = target subRelativeTo os.pwd - val newBase = os.root / "code" / "server" - assert( - newBase / sub == os.root / "code" / "server" / "out" / "scratch" / "file", - sub / sub == os.sub / "out" / "scratch" / "file" / "out" / "scratch" / "file" - ) - } - test("pathUp") { - val target = os.root / "out" / "scratch" / "file" - assert(target / os.up == os.root / "out" / "scratch") - } - test("relPathUp") { - val target = os.rel / "out" / "scratch" / "file" - assert(target / os.up == os.rel / "out" / "scratch") - } - test("relPathUp") { - val target = os.sub / "out" / "scratch" / "file" - assert(target / os.up == os.sub / "out" / "scratch") - } - test("canonical") { - if (Unix()) { - - assert((os.root / "folder" / "file" / os.up).toString == "/folder") - // not "/folder/file/.." - - assert((os.rel / "folder" / "file" / os.up).toString == "folder") - // not "folder/file/.." - } - } - test("findWc") { - - val wd = os.pwd / "os" / "test" / "resources" / "test" - - // find . -name '*.txt' | xargs wc -l - val lines = os.walk(wd) - .filter(_.ext == "txt") - .map(os.read.lines) - .map(_.length) - .sum - - assert(lines == 9) - } - - test("rename") { -// val d1/"omg"/x1 = wd -// val d2/"omg"/x2 = wd -// ls! wd |? (_.ext == "scala") | (x => mv! x ! x.pref) - } - test("allSubpathsResolveCorrectly") { - - for (abs <- os.walk(os.pwd)) { - val rel = abs.relativeTo(os.pwd) - assert(rel.ups == 0) - assert(os.pwd / rel == abs) - } - } - } -} diff --git a/os/test/src-jvm/ExampleResourcess.scala b/os/test/src/ExampleResourcess.scala similarity index 100% rename from os/test/src-jvm/ExampleResourcess.scala rename to os/test/src/ExampleResourcess.scala diff --git a/os/test/src/ExampleTests.scala b/os/test/src/ExampleTests.scala new file mode 100644 index 00000000..0b6e0f2f --- /dev/null +++ b/os/test/src/ExampleTests.scala @@ -0,0 +1,564 @@ +import utest.* + +import java.nio.file.attribute.{FileTime, GroupPrincipal} +object package test.os + +import java.nio.file.attribute.{GroupPrincipal, FileTime} + +import utest._ +object ExampleTests extends TestSuite { + + val tests = Tests { + test("splash") - TestUtil.prep { wd => + if (Unix()) { + // Make sure working directory exists and is empty + val wd = os.pwd / "out" / "splash" + os.remove.all(wd) + os.makeDir.all(wd) + + os.write(wd / "file.txt", "hello") + os.read(wd / "file.txt") ==> "hello" + + os.copy(wd / "file.txt", wd / "copied.txt") + os.list(wd) ==> Seq(wd / "copied.txt", wd / "file.txt") + + val invoked = os.proc("cat", wd / "file.txt", wd / "copied.txt").call(cwd = wd) + invoked.out.trim() ==> "hellohello" + } + } + + test("concatTxt") - TestUtil.prep { wd => + // Find and concatenate all .txt files directly in the working directory + os.write( + wd / "all.txt", + os.list(wd).filter(_.ext == "txt").map(os.read) + ) + + os.read(wd / "all.txt") ==> + """I am cowI am cow + |Hear me moo + |I weigh twice as much as you + |And I look good on the barbecue""".stripMargin + } + + test("subprocessConcat") - TestUtil.prep { wd => + val catCmd = if (scala.util.Properties.isWin) "type" else "cat" + // Find and concatenate all .txt files directly in the working directory + TestUtil.proc(catCmd, os.list(wd).filter(_.ext == "txt")) + .call(stdout = wd / "all.txt") + + os.read(wd / "all.txt") ==> + """I am cowI am cow + |Hear me moo + |I weigh twice as much as you + |And I look good on the barbecue""".stripMargin + } + + test("curlToTempFile") - TestUtil.prep { wd => + if (Unix()) { + // Curl to temporary file + val temp = os.temp() + os.proc("curl", "-L", ExampleResourcess.RemoteReadme.url) + .call(stdout = temp) + + os.size(temp) ==> ExampleResourcess.RemoteReadme.size + + // Curl to temporary file + val temp2 = os.temp() + val proc = os.proc("curl", "-L", ExampleResourcess.RemoteReadme.url).spawn() + + os.write.over(temp2, proc.stdout) + os.size(temp2) ==> ExampleResourcess.RemoteReadme.size + + assert(os.size(temp) == os.size(temp2)) + } + } + + test("lineCount") - TestUtil.prep { wd => + // Line-count of all .txt files recursively in wd + val lineCount = os.walk(wd) + .filter(_.ext == "txt") + .map(os.read.lines) + .map(_.size) + .sum + + lineCount ==> 9 + } + + test("largestThree") - TestUtil.prep { wd => + // Find the largest three files in the given folder tree + val largestThree = os.walk(wd) + .filter(os.isFile(_, followLinks = false)) + .map(x => os.size(x) -> x).sortBy(-_._1) + .take(3) + + // on unix it is 81 bytes, win adds 3 bytes (3 \r characters) + val multilineSizes = Set[Long](81, 84) + assert(multilineSizes contains os.stat(wd / "Multi Line.txt").size) + + // ignore multiline (second file) because its size varies + largestThree.filterNot(_._2.last == "Multi Line.txt") ==> Seq( + (711, wd / "misc" / "binary.png"), + (22, wd / "folder1" / "one.txt") + ) + } + + test("moveOut") - TestUtil.prep { wd => + // Move all files inside the "misc" folder out of it + import os.{GlobSyntax, /} + os.list(wd / "misc").map(os.move.matching { case p / "misc" / x => p / x }) + } + + test("frequency") - TestUtil.prep { wd => + // Calculate the word frequency of all the text files in the folder tree + def txt = os.walk(wd).filter(_.ext == "txt").map(os.read) + def freq(s: Seq[String]) = s.groupBy(x => x).mapValues(_.length).toSeq + val map = freq(txt.flatMap(_.split("[^a-zA-Z0-9_]"))).sortBy(-_._2) + map + } + test("comparison") { + + os.remove.all(os.pwd / "out" / "scratch" / "folder" / "thing" / "file") + os.write( + os.pwd / "out" / "scratch" / "folder" / "thing" / "file", + "Hello!", + createFolders = true + ) + + def removeAll(path: String) = { + def getRecursively(f: java.io.File): Seq[java.io.File] = { + f.listFiles.filter(_.isDirectory).flatMap(getRecursively) ++ f.listFiles + } + getRecursively(new java.io.File(path)).foreach { f => + println(f) + if (!f.delete()) + throw new RuntimeException("Failed to delete " + f.getAbsolutePath) + } + new java.io.File(path).delete + } + removeAll("out/scratch/folder/thing") + + assert(os.list(os.pwd / "out" / "scratch" / "folder").toSeq == Nil) + + os.write( + os.pwd / "out" / "scratch" / "folder" / "thing" / "file", + "Hello!", + createFolders = true + ) + + os.remove.all(os.pwd / "out" / "scratch" / "folder" / "thing") + assert(os.list(os.pwd / "out" / "scratch" / "folder").toSeq == Nil) + } + + test("constructingPaths") { + + // Get the process' Current Working Directory. As a convention + // the directory that "this" code cares about (which may differ + // from the pwd) is called `wd` + val wd = os.pwd + + // A path nested inside `wd` + wd / "folder" / "file" + + // A path starting from the root + os.root / "folder" / "file" + + // A path with spaces or other special characters + wd / "My Folder" / "My File.txt" + + // Up one level from the wd + wd / os.up + + // Up two levels from the wd + wd / os.up / os.up + } + test("newPath") { + + val target = os.pwd / "out" / "scratch" + } + test("relPaths") { + + // The path "folder/file" + val rel1 = os.rel / "folder" / "file" + val rel2 = os.rel / "folder" / "file" + + // The relative difference between two paths + val target = os.pwd / "out" / "scratch" / "file" + assert((target relativeTo os.pwd) == os.rel / "out" / "scratch" / "file") + + // `up`s get resolved automatically + val minus = os.pwd relativeTo target + val ups = os.up / os.up / os.up + assert(minus == ups) + ( + rel1: os.RelPath, + rel2: os.RelPath + ) + } + test("subPaths") { + + // The path "folder/file" + val sub1 = os.sub / "folder" / "file" + val sub2 = os.sub / "folder" / "file" + + // The relative difference between two paths + val target = os.pwd / "out" / "scratch" / "file" + assert((target subRelativeTo os.pwd) == os.sub / "out" / "scratch" / "file") + + // Converting os.RelPath to os.SubPath + val rel3 = os.rel / "folder" / "file" + val sub3 = rel3.asSubPath + + // `up`s are not allowed in sub paths + intercept[Exception](os.pwd subRelativeTo target) + } + test("relSubPathEquality") { + assert( + (os.sub / "hello" / "world") == (os.rel / "hello" / "world"), + os.sub == os.rel + ) + } + test("relPathCombine") { + val target = os.pwd / "out" / "scratch" / "file" + val rel = target relativeTo os.pwd + val newBase = os.root / "code" / "server" + assert(newBase / rel == os.root / "code" / "server" / "out" / "scratch" / "file") + } + test("subPathCombine") { + val target = os.pwd / "out" / "scratch" / "file" + val sub = target subRelativeTo os.pwd + val newBase = os.root / "code" / "server" + assert( + newBase / sub == os.root / "code" / "server" / "out" / "scratch" / "file", + sub / sub == os.sub / "out" / "scratch" / "file" / "out" / "scratch" / "file" + ) + } + test("pathUp") { + val target = os.root / "out" / "scratch" / "file" + assert(target / os.up == os.root / "out" / "scratch") + } + test("relPathUp") { + val target = os.rel / "out" / "scratch" / "file" + assert(target / os.up == os.rel / "out" / "scratch") + } + test("relPathUp") { + val target = os.sub / "out" / "scratch" / "file" + assert(target / os.up == os.sub / "out" / "scratch") + } + test("canonical") { + if (Unix()) { + + assert((os.root / "folder" / "file" / os.up).toString == "/folder") + // not "/folder/file/.." + + assert((os.rel / "folder" / "file" / os.up).toString == "folder") + // not "folder/file/.." + } + } + test("findWc") { + + val wd = os.pwd / "os" / "test" / "resources" / "test" + + // find . -name '*.txt' | xargs wc -l + val lines = os.walk(wd) + .filter(_.ext == "txt") + .map(os.read.lines) + .map(_.length) + .sum + + assert(lines == 9) + } + + test("rename") { + // val d1/"omg"/x1 = wd + // val d2/"omg"/x2 = wd + // ls! wd |? (_.ext == "scala") | (x => mv! x ! x.pref) + } + test("allSubpathsResolveCorrectly") { + + for (abs <- os.walk(os.pwd)) { + val rel = abs.relativeTo(os.pwd) + assert(rel.ups == 0) + assert(os.pwd / rel == abs) + } + } + } +} +ExampleTests extends TestSuite { + + val tests = Tests { + test("splash") - TestUtil.prep { wd => + if (Unix()) { + // Make sure working directory exists and is empty + val wd = os.pwd / "out" / "splash" + os.remove.all(wd) + os.makeDir.all(wd) + + os.write(wd / "file.txt", "hello") + os.read(wd / "file.txt") ==> "hello" + + os.copy(wd / "file.txt", wd / "copied.txt") + os.list(wd) ==> Seq(wd / "copied.txt", wd / "file.txt") + + val invoked = os.proc("cat", wd / "file.txt", wd / "copied.txt").call(cwd = wd) + invoked.out.trim() ==> "hellohello" + } + } + + test("concatTxt") - TestUtil.prep { wd => + // Find and concatenate all .txt files directly in the working directory + os.write( + wd / "all.txt", + os.list(wd).filter(_.ext == "txt").map(os.read) + ) + + os.read(wd / "all.txt") ==> + """I am cowI am cow + |Hear me moo + |I weigh twice as much as you + |And I look good on the barbecue""".stripMargin + } + + test("subprocessConcat") - TestUtil.prep { wd => + val catCmd = if (scala.util.Properties.isWin) "type" else "cat" + // Find and concatenate all .txt files directly in the working directory + TestUtil.proc(catCmd, os.list(wd).filter(_.ext == "txt")) + .call(stdout = wd / "all.txt") + + os.read(wd / "all.txt") ==> + """I am cowI am cow + |Hear me moo + |I weigh twice as much as you + |And I look good on the barbecue""".stripMargin + } + + test("curlToTempFile") - TestUtil.prep { wd => + if (Unix()) { + // Curl to temporary file + val temp = os.temp() + os.proc("curl", "-L", ExampleResourcess.RemoteReadme.url) + .call(stdout = temp) + + os.size(temp) ==> ExampleResourcess.RemoteReadme.size + + // Curl to temporary file + val temp2 = os.temp() + val proc = os.proc("curl", "-L", ExampleResourcess.RemoteReadme.url).spawn() + + os.write.over(temp2, proc.stdout) + os.size(temp2) ==> ExampleResourcess.RemoteReadme.size + + assert(os.size(temp) == os.size(temp2)) + } + } + + test("lineCount") - TestUtil.prep { wd => + // Line-count of all .txt files recursively in wd + val lineCount = os.walk(wd) + .filter(_.ext == "txt") + .map(os.read.lines) + .map(_.size) + .sum + + lineCount ==> 9 + } + + test("largestThree") - TestUtil.prep { wd => + // Find the largest three files in the given folder tree + val largestThree = os.walk(wd) + .filter(os.isFile(_, followLinks = false)) + .map(x => os.size(x) -> x).sortBy(-_._1) + .take(3) + + // on unix it is 81 bytes, win adds 3 bytes (3 \r characters) + val multilineSizes = Set[Long](81, 84) + assert(multilineSizes contains os.stat(wd / "Multi Line.txt").size) + + // ignore multiline (second file) because its size varies + largestThree.filterNot(_._2.last == "Multi Line.txt") ==> Seq( + (711, wd / "misc" / "binary.png"), + (22, wd / "folder1" / "one.txt") + ) + } + + test("moveOut") - TestUtil.prep { wd => + // Move all files inside the "misc" folder out of it + import os.{/, GlobSyntax} + os.list(wd / "misc").map(os.move.matching { case p / "misc" / x => p / x }) + } + + test("frequency") - TestUtil.prep { wd => + // Calculate the word frequency of all the text files in the folder tree + def txt = os.walk(wd).filter(_.ext == "txt").map(os.read) + def freq(s: Seq[String]) = s.groupBy(x => x).mapValues(_.length).toSeq + val map = freq(txt.flatMap(_.split("[^a-zA-Z0-9_]"))).sortBy(-_._2) + map + } + test("comparison") { + + os.remove.all(os.pwd / "out" / "scratch" / "folder" / "thing" / "file") + os.write( + os.pwd / "out" / "scratch" / "folder" / "thing" / "file", + "Hello!", + createFolders = true + ) + + def removeAll(path: String) = { + def getRecursively(f: java.io.File): Seq[java.io.File] = { + f.listFiles.filter(_.isDirectory).flatMap(getRecursively) ++ f.listFiles + } + getRecursively(new java.io.File(path)).foreach { f => + println(f) + if (!f.delete()) + throw new RuntimeException("Failed to delete " + f.getAbsolutePath) + } + new java.io.File(path).delete + } + removeAll("out/scratch/folder/thing") + + assert(os.list(os.pwd / "out" / "scratch" / "folder").toSeq == Nil) + + os.write( + os.pwd / "out" / "scratch" / "folder" / "thing" / "file", + "Hello!", + createFolders = true + ) + + os.remove.all(os.pwd / "out" / "scratch" / "folder" / "thing") + assert(os.list(os.pwd / "out" / "scratch" / "folder").toSeq == Nil) + } + + test("constructingPaths") { + + // Get the process' Current Working Directory. As a convention + // the directory that "this" code cares about (which may differ + // from the pwd) is called `wd` + val wd = os.pwd + + // A path nested inside `wd` + wd / "folder" / "file" + + // A path starting from the root + os.root / "folder" / "file" + + // A path with spaces or other special characters + wd / "My Folder" / "My File.txt" + + // Up one level from the wd + wd / os.up + + // Up two levels from the wd + wd / os.up / os.up + } + test("newPath") { + + val target = os.pwd / "out" / "scratch" + } + test("relPaths") { + + // The path "folder/file" + val rel1 = os.rel / "folder" / "file" + val rel2 = os.rel / "folder" / "file" + + // The relative difference between two paths + val target = os.pwd / "out" / "scratch" / "file" + assert((target relativeTo os.pwd) == os.rel / "out" / "scratch" / "file") + + // `up`s get resolved automatically + val minus = os.pwd relativeTo target + val ups = os.up / os.up / os.up + assert(minus == ups) + ( + rel1: os.RelPath, + rel2: os.RelPath + ) + } + test("subPaths") { + + // The path "folder/file" + val sub1 = os.sub / "folder" / "file" + val sub2 = os.sub / "folder" / "file" + + // The relative difference between two paths + val target = os.pwd / "out" / "scratch" / "file" + assert((target subRelativeTo os.pwd) == os.sub / "out" / "scratch" / "file") + + // Converting os.RelPath to os.SubPath + val rel3 = os.rel / "folder" / "file" + val sub3 = rel3.asSubPath + + // `up`s are not allowed in sub paths + intercept[Exception](os.pwd subRelativeTo target) + } + test("relSubPathEquality") { + assert( + (os.sub / "hello" / "world") == (os.rel / "hello" / "world"), + os.sub == os.rel + ) + } + test("relPathCombine") { + val target = os.pwd / "out" / "scratch" / "file" + val rel = target relativeTo os.pwd + val newBase = os.root / "code" / "server" + assert(newBase / rel == os.root / "code" / "server" / "out" / "scratch" / "file") + } + test("subPathCombine") { + val target = os.pwd / "out" / "scratch" / "file" + val sub = target subRelativeTo os.pwd + val newBase = os.root / "code" / "server" + assert( + newBase / sub == os.root / "code" / "server" / "out" / "scratch" / "file", + sub / sub == os.sub / "out" / "scratch" / "file" / "out" / "scratch" / "file" + ) + } + test("pathUp") { + val target = os.root / "out" / "scratch" / "file" + assert(target / os.up == os.root / "out" / "scratch") + } + test("relPathUp") { + val target = os.rel / "out" / "scratch" / "file" + assert(target / os.up == os.rel / "out" / "scratch") + } + test("relPathUp") { + val target = os.sub / "out" / "scratch" / "file" + assert(target / os.up == os.sub / "out" / "scratch") + } + test("canonical") { + if (Unix()) { + + assert((os.root / "folder" / "file" / os.up).toString == "/folder") + // not "/folder/file/.." + + assert((os.rel / "folder" / "file" / os.up).toString == "folder") + // not "folder/file/.." + } + } + test("findWc") { + + val wd = os.pwd / "os" / "test" / "resources" / "test" + + // find . -name '*.txt' | xargs wc -l + val lines = os.walk(wd) + .filter(_.ext == "txt") + .map(os.read.lines) + .map(_.length) + .sum + + assert(lines == 9) + } + + test("rename") { +// val d1/"omg"/x1 = wd +// val d2/"omg"/x2 = wd +// ls! wd |? (_.ext == "scala") | (x => mv! x ! x.pref) + } + test("allSubpathsResolveCorrectly") { + + for (abs <- os.walk(os.pwd)) { + val rel = abs.relativeTo(os.pwd) + assert(rel.ups == 0) + assert(os.pwd / rel == abs) + } + } + } +} diff --git a/os/test/src-jvm/ProcessPipelineTests.scala b/os/test/src/ProcessPipelineTests.scala similarity index 100% rename from os/test/src-jvm/ProcessPipelineTests.scala rename to os/test/src/ProcessPipelineTests.scala diff --git a/os/test/src-jvm/SpawningSubprocessesTests.scala b/os/test/src/SpawningSubprocessesTests.scala similarity index 93% rename from os/test/src-jvm/SpawningSubprocessesTests.scala rename to os/test/src/SpawningSubprocessesTests.scala index 70140316..5e96544e 100644 --- a/os/test/src-jvm/SpawningSubprocessesTests.scala +++ b/os/test/src/SpawningSubprocessesTests.scala @@ -103,12 +103,12 @@ object SpawningSubprocessesTests extends TestSuite { if (TestUtil.isInstalled("python") && Unix()) { // Start a long-lived python process which you can communicate with val sub = os.proc( - "python", - "-u", - "-c", - if (TestUtil.isPython3()) "while True: print(eval(input()))" - else "while True: print(eval(raw_input()))" - ) + "python", + "-u", + "-c", + if (TestUtil.isPython3()) "while True: print(eval(input()))" + else "while True: print(eval(raw_input()))" + ) .spawn(cwd = wd) // Sending some text to the subprocess @@ -135,9 +135,9 @@ object SpawningSubprocessesTests extends TestSuite { test("spawn curl") { if ( Unix() && // shasum seems to not accept stdin on Windows - TestUtil.isInstalled("curl") && - TestUtil.isInstalled("gzip") && - TestUtil.isInstalled("shasum") + TestUtil.isInstalled("curl") && + TestUtil.isInstalled("gzip") && + TestUtil.isInstalled("shasum") ) { // You can chain multiple subprocess' stdin/stdout together val curl = From 8e74ac34fe85956b013dbdd538190611d2a2afb1 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Thu, 30 May 2024 23:14:12 +0800 Subject: [PATCH 2/5] . --- os/test/src/ExampleTests.scala | 283 +-------------------------------- 1 file changed, 1 insertion(+), 282 deletions(-) diff --git a/os/test/src/ExampleTests.scala b/os/test/src/ExampleTests.scala index 0b6e0f2f..924feaba 100644 --- a/os/test/src/ExampleTests.scala +++ b/os/test/src/ExampleTests.scala @@ -1,7 +1,4 @@ -import utest.* - -import java.nio.file.attribute.{FileTime, GroupPrincipal} -object package test.os +package test.os import java.nio.file.attribute.{GroupPrincipal, FileTime} @@ -284,281 +281,3 @@ object ExampleTests extends TestSuite { } } } -ExampleTests extends TestSuite { - - val tests = Tests { - test("splash") - TestUtil.prep { wd => - if (Unix()) { - // Make sure working directory exists and is empty - val wd = os.pwd / "out" / "splash" - os.remove.all(wd) - os.makeDir.all(wd) - - os.write(wd / "file.txt", "hello") - os.read(wd / "file.txt") ==> "hello" - - os.copy(wd / "file.txt", wd / "copied.txt") - os.list(wd) ==> Seq(wd / "copied.txt", wd / "file.txt") - - val invoked = os.proc("cat", wd / "file.txt", wd / "copied.txt").call(cwd = wd) - invoked.out.trim() ==> "hellohello" - } - } - - test("concatTxt") - TestUtil.prep { wd => - // Find and concatenate all .txt files directly in the working directory - os.write( - wd / "all.txt", - os.list(wd).filter(_.ext == "txt").map(os.read) - ) - - os.read(wd / "all.txt") ==> - """I am cowI am cow - |Hear me moo - |I weigh twice as much as you - |And I look good on the barbecue""".stripMargin - } - - test("subprocessConcat") - TestUtil.prep { wd => - val catCmd = if (scala.util.Properties.isWin) "type" else "cat" - // Find and concatenate all .txt files directly in the working directory - TestUtil.proc(catCmd, os.list(wd).filter(_.ext == "txt")) - .call(stdout = wd / "all.txt") - - os.read(wd / "all.txt") ==> - """I am cowI am cow - |Hear me moo - |I weigh twice as much as you - |And I look good on the barbecue""".stripMargin - } - - test("curlToTempFile") - TestUtil.prep { wd => - if (Unix()) { - // Curl to temporary file - val temp = os.temp() - os.proc("curl", "-L", ExampleResourcess.RemoteReadme.url) - .call(stdout = temp) - - os.size(temp) ==> ExampleResourcess.RemoteReadme.size - - // Curl to temporary file - val temp2 = os.temp() - val proc = os.proc("curl", "-L", ExampleResourcess.RemoteReadme.url).spawn() - - os.write.over(temp2, proc.stdout) - os.size(temp2) ==> ExampleResourcess.RemoteReadme.size - - assert(os.size(temp) == os.size(temp2)) - } - } - - test("lineCount") - TestUtil.prep { wd => - // Line-count of all .txt files recursively in wd - val lineCount = os.walk(wd) - .filter(_.ext == "txt") - .map(os.read.lines) - .map(_.size) - .sum - - lineCount ==> 9 - } - - test("largestThree") - TestUtil.prep { wd => - // Find the largest three files in the given folder tree - val largestThree = os.walk(wd) - .filter(os.isFile(_, followLinks = false)) - .map(x => os.size(x) -> x).sortBy(-_._1) - .take(3) - - // on unix it is 81 bytes, win adds 3 bytes (3 \r characters) - val multilineSizes = Set[Long](81, 84) - assert(multilineSizes contains os.stat(wd / "Multi Line.txt").size) - - // ignore multiline (second file) because its size varies - largestThree.filterNot(_._2.last == "Multi Line.txt") ==> Seq( - (711, wd / "misc" / "binary.png"), - (22, wd / "folder1" / "one.txt") - ) - } - - test("moveOut") - TestUtil.prep { wd => - // Move all files inside the "misc" folder out of it - import os.{/, GlobSyntax} - os.list(wd / "misc").map(os.move.matching { case p / "misc" / x => p / x }) - } - - test("frequency") - TestUtil.prep { wd => - // Calculate the word frequency of all the text files in the folder tree - def txt = os.walk(wd).filter(_.ext == "txt").map(os.read) - def freq(s: Seq[String]) = s.groupBy(x => x).mapValues(_.length).toSeq - val map = freq(txt.flatMap(_.split("[^a-zA-Z0-9_]"))).sortBy(-_._2) - map - } - test("comparison") { - - os.remove.all(os.pwd / "out" / "scratch" / "folder" / "thing" / "file") - os.write( - os.pwd / "out" / "scratch" / "folder" / "thing" / "file", - "Hello!", - createFolders = true - ) - - def removeAll(path: String) = { - def getRecursively(f: java.io.File): Seq[java.io.File] = { - f.listFiles.filter(_.isDirectory).flatMap(getRecursively) ++ f.listFiles - } - getRecursively(new java.io.File(path)).foreach { f => - println(f) - if (!f.delete()) - throw new RuntimeException("Failed to delete " + f.getAbsolutePath) - } - new java.io.File(path).delete - } - removeAll("out/scratch/folder/thing") - - assert(os.list(os.pwd / "out" / "scratch" / "folder").toSeq == Nil) - - os.write( - os.pwd / "out" / "scratch" / "folder" / "thing" / "file", - "Hello!", - createFolders = true - ) - - os.remove.all(os.pwd / "out" / "scratch" / "folder" / "thing") - assert(os.list(os.pwd / "out" / "scratch" / "folder").toSeq == Nil) - } - - test("constructingPaths") { - - // Get the process' Current Working Directory. As a convention - // the directory that "this" code cares about (which may differ - // from the pwd) is called `wd` - val wd = os.pwd - - // A path nested inside `wd` - wd / "folder" / "file" - - // A path starting from the root - os.root / "folder" / "file" - - // A path with spaces or other special characters - wd / "My Folder" / "My File.txt" - - // Up one level from the wd - wd / os.up - - // Up two levels from the wd - wd / os.up / os.up - } - test("newPath") { - - val target = os.pwd / "out" / "scratch" - } - test("relPaths") { - - // The path "folder/file" - val rel1 = os.rel / "folder" / "file" - val rel2 = os.rel / "folder" / "file" - - // The relative difference between two paths - val target = os.pwd / "out" / "scratch" / "file" - assert((target relativeTo os.pwd) == os.rel / "out" / "scratch" / "file") - - // `up`s get resolved automatically - val minus = os.pwd relativeTo target - val ups = os.up / os.up / os.up - assert(minus == ups) - ( - rel1: os.RelPath, - rel2: os.RelPath - ) - } - test("subPaths") { - - // The path "folder/file" - val sub1 = os.sub / "folder" / "file" - val sub2 = os.sub / "folder" / "file" - - // The relative difference between two paths - val target = os.pwd / "out" / "scratch" / "file" - assert((target subRelativeTo os.pwd) == os.sub / "out" / "scratch" / "file") - - // Converting os.RelPath to os.SubPath - val rel3 = os.rel / "folder" / "file" - val sub3 = rel3.asSubPath - - // `up`s are not allowed in sub paths - intercept[Exception](os.pwd subRelativeTo target) - } - test("relSubPathEquality") { - assert( - (os.sub / "hello" / "world") == (os.rel / "hello" / "world"), - os.sub == os.rel - ) - } - test("relPathCombine") { - val target = os.pwd / "out" / "scratch" / "file" - val rel = target relativeTo os.pwd - val newBase = os.root / "code" / "server" - assert(newBase / rel == os.root / "code" / "server" / "out" / "scratch" / "file") - } - test("subPathCombine") { - val target = os.pwd / "out" / "scratch" / "file" - val sub = target subRelativeTo os.pwd - val newBase = os.root / "code" / "server" - assert( - newBase / sub == os.root / "code" / "server" / "out" / "scratch" / "file", - sub / sub == os.sub / "out" / "scratch" / "file" / "out" / "scratch" / "file" - ) - } - test("pathUp") { - val target = os.root / "out" / "scratch" / "file" - assert(target / os.up == os.root / "out" / "scratch") - } - test("relPathUp") { - val target = os.rel / "out" / "scratch" / "file" - assert(target / os.up == os.rel / "out" / "scratch") - } - test("relPathUp") { - val target = os.sub / "out" / "scratch" / "file" - assert(target / os.up == os.sub / "out" / "scratch") - } - test("canonical") { - if (Unix()) { - - assert((os.root / "folder" / "file" / os.up).toString == "/folder") - // not "/folder/file/.." - - assert((os.rel / "folder" / "file" / os.up).toString == "folder") - // not "folder/file/.." - } - } - test("findWc") { - - val wd = os.pwd / "os" / "test" / "resources" / "test" - - // find . -name '*.txt' | xargs wc -l - val lines = os.walk(wd) - .filter(_.ext == "txt") - .map(os.read.lines) - .map(_.length) - .sum - - assert(lines == 9) - } - - test("rename") { -// val d1/"omg"/x1 = wd -// val d2/"omg"/x2 = wd -// ls! wd |? (_.ext == "scala") | (x => mv! x ! x.pref) - } - test("allSubpathsResolveCorrectly") { - - for (abs <- os.walk(os.pwd)) { - val rel = abs.relativeTo(os.pwd) - assert(rel.ups == 0) - assert(os.pwd / rel == abs) - } - } - } -} From a29490ead9f4dd7b7d2a9195e71cec535b0d94b3 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Thu, 30 May 2024 23:15:19 +0800 Subject: [PATCH 3/5] . --- os/test/src/ExampleTests.scala | 6 +++--- os/test/src/SpawningSubprocessesTests.scala | 18 +++++++++--------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/os/test/src/ExampleTests.scala b/os/test/src/ExampleTests.scala index 924feaba..fbb2335e 100644 --- a/os/test/src/ExampleTests.scala +++ b/os/test/src/ExampleTests.scala @@ -267,9 +267,9 @@ object ExampleTests extends TestSuite { } test("rename") { - // val d1/"omg"/x1 = wd - // val d2/"omg"/x2 = wd - // ls! wd |? (_.ext == "scala") | (x => mv! x ! x.pref) +// val d1/"omg"/x1 = wd +// val d2/"omg"/x2 = wd +// ls! wd |? (_.ext == "scala") | (x => mv! x ! x.pref) } test("allSubpathsResolveCorrectly") { diff --git a/os/test/src/SpawningSubprocessesTests.scala b/os/test/src/SpawningSubprocessesTests.scala index 5e96544e..70140316 100644 --- a/os/test/src/SpawningSubprocessesTests.scala +++ b/os/test/src/SpawningSubprocessesTests.scala @@ -103,12 +103,12 @@ object SpawningSubprocessesTests extends TestSuite { if (TestUtil.isInstalled("python") && Unix()) { // Start a long-lived python process which you can communicate with val sub = os.proc( - "python", - "-u", - "-c", - if (TestUtil.isPython3()) "while True: print(eval(input()))" - else "while True: print(eval(raw_input()))" - ) + "python", + "-u", + "-c", + if (TestUtil.isPython3()) "while True: print(eval(input()))" + else "while True: print(eval(raw_input()))" + ) .spawn(cwd = wd) // Sending some text to the subprocess @@ -135,9 +135,9 @@ object SpawningSubprocessesTests extends TestSuite { test("spawn curl") { if ( Unix() && // shasum seems to not accept stdin on Windows - TestUtil.isInstalled("curl") && - TestUtil.isInstalled("gzip") && - TestUtil.isInstalled("shasum") + TestUtil.isInstalled("curl") && + TestUtil.isInstalled("gzip") && + TestUtil.isInstalled("shasum") ) { // You can chain multiple subprocess' stdin/stdout together val curl = From b11bb09b041d919bdec713b9c7a069b34d69383d Mon Sep 17 00:00:00 2001 From: Lorenzo Gabriele Date: Mon, 10 Jun 2024 16:59:55 +0200 Subject: [PATCH 4/5] Update Scala Native to 0.5.3 --- build.sc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sc b/build.sc index 21834e14..c4d09436 100644 --- a/build.sc +++ b/build.sc @@ -130,7 +130,7 @@ object os extends Module { object native extends Cross[OsNativeModule](scalaVersions) trait OsNativeModule extends OsModule with ScalaNativeModule { - def scalaNativeVersion = "0.5.2" + def scalaNativeVersion = "0.5.3" object test extends ScalaNativeTests with OsLibTestModule { def nativeLinkStubs = true } From bc5cc4c549e1ec89d955b8f8b0261c0a20a5c546 Mon Sep 17 00:00:00 2001 From: Lorenzo Gabriele Date: Tue, 25 Jun 2024 14:58:52 +0200 Subject: [PATCH 5/5] Update Scala Native to 0.5.4 --- build.sc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sc b/build.sc index c4d09436..92a2896b 100644 --- a/build.sc +++ b/build.sc @@ -130,7 +130,7 @@ object os extends Module { object native extends Cross[OsNativeModule](scalaVersions) trait OsNativeModule extends OsModule with ScalaNativeModule { - def scalaNativeVersion = "0.5.3" + def scalaNativeVersion = "0.5.4" object test extends ScalaNativeTests with OsLibTestModule { def nativeLinkStubs = true }