From 4d29302632a07fd04ddb0a51cc609738f2f85aab Mon Sep 17 00:00:00 2001 From: James Roper Date: Mon, 23 Jun 2014 15:12:34 +1000 Subject: [PATCH] Fixed scripted newer command The scripted newer command was effectively a noop, it always passed because it returned false instead of throwing an exception when it failed. Implemented specs for most of the scripted file commands as well. --- project/Sbt.scala | 2 +- .../main/scala/xsbt/test/FileCommands.scala | 5 +- .../scala/xsbt/test/FileCommandsSpec.scala | 134 ++++++++++++++++++ 3 files changed, 139 insertions(+), 2 deletions(-) create mode 100644 scripted/base/src/test/scala/xsbt/test/FileCommandsSpec.scala diff --git a/project/Sbt.scala b/project/Sbt.scala index 48e3dc07b..3f7cf689e 100644 --- a/project/Sbt.scala +++ b/project/Sbt.scala @@ -161,7 +161,7 @@ object Sbt extends Build { compileIncrementalSub, compilerSub, compilePersistSub, apiSub, classfileSub) lazy val compilerIvySub = baseProject(compilePath / "ivy", "Compiler Ivy Integration") dependsOn (ivySub, compilerSub) - lazy val scriptedBaseSub = baseProject(scriptedPath / "base", "Scripted Framework") dependsOn (ioSub, processSub) settings (scalaParsers) + lazy val scriptedBaseSub = testedBaseProject(scriptedPath / "base", "Scripted Framework") dependsOn (ioSub, processSub) settings (scalaParsers) lazy val scriptedSbtSub = baseProject(scriptedPath / "sbt", "Scripted sbt") dependsOn (ioSub, logSub, processSub, scriptedBaseSub, launchInterfaceSub % "provided") lazy val scriptedPluginSub = baseProject(scriptedPath / "plugin", "Scripted Plugin") dependsOn (sbtSub, classpathSub) diff --git a/scripted/base/src/main/scala/xsbt/test/FileCommands.scala b/scripted/base/src/main/scala/xsbt/test/FileCommands.scala index c9dc92efb..d9b0ae395 100644 --- a/scripted/base/src/main/scala/xsbt/test/FileCommands.scala +++ b/scripted/base/src/main/scala/xsbt/test/FileCommands.scala @@ -53,7 +53,10 @@ class FileCommands(baseDirectory: File) extends BasicStatementHandler { { val pathA = fromString(a) val pathB = fromString(b) - pathA.exists && (!pathB.exists || pathA.lastModified > pathB.lastModified) + val isNewer = pathA.exists && (!pathB.exists || pathA.lastModified > pathB.lastModified) + if (!isNewer) { + scriptError(s"$pathA is not newer than $pathB") + } } def exists(paths: List[String]) { val notPresent = fromStrings(paths).filter(!_.exists) diff --git a/scripted/base/src/test/scala/xsbt/test/FileCommandsSpec.scala b/scripted/base/src/test/scala/xsbt/test/FileCommandsSpec.scala new file mode 100644 index 000000000..bfaeec1d7 --- /dev/null +++ b/scripted/base/src/test/scala/xsbt/test/FileCommandsSpec.scala @@ -0,0 +1,134 @@ +package xsbt.test + +import java.io.File +import org.specs2.mutable.Specification +import org.specs2.matcher.FileMatchers +import sbt._ +import sbt.Path._ + +object FileCommandsSpec extends Specification with FileMatchers { + + "The touch command" should { + "touch a file that doesn't exist" in withTmpDir { dir => + fileCommands(dir)("touch", List("foo")) + dir / "foo" must exist + } + "update the timestamp of a file that does exist" in withTmpDir { dir => + val file = dir / "foo" + IO.write(file, "x") + file.setLastModified(1000L) + + fileCommands(dir)("touch", List("foo")) + file.lastModified() must beGreaterThan(1000L) + } + } + + "The delete command" should { + "delete a file" in withTmpDir { dir => + IO.write(dir / "foo", "x") + fileCommands(dir)("delete", List("foo")) + dir / "foo" must not(exist) + } + "delete a directory" in withTmpDir { dir => + IO.write(dir / "foo" / "bar", "x") + fileCommands(dir)("delete", List("foo")) + dir / "foo" must not(exist) + } + } + + "The exists command" should { + "succeed if a file exists" in withTmpDir { dir => + IO.write(dir / "foo", "x") + fileCommands(dir)("exists", List("foo")) + ok + } + "fail if a file doesn't exist" in withTmpDir { dir => + fileCommands(dir)("exists", List("foo")) must throwAn[Exception] + } + } + + "The mkdir command" should { + "make a directory" in withTmpDir { dir => + fileCommands(dir)("mkdir", List("foo")) + dir / "foo" must beADirectory + } + "make all directories" in withTmpDir { dir => + fileCommands(dir)("mkdir", List("foo/bar")) + dir / "foo" / "bar" must beADirectory + } + } + + "The absent command" should { + "succeed if a file is absent" in withTmpDir { dir => + fileCommands(dir)("absent", List("foo")) + ok + } + "fail if a file is not absent" in withTmpDir { dir => + IO.write(dir / "foo", "x") + fileCommands(dir)("absent", List("foo")) must throwAn[Exception] + } + } + + "The newer command" should { + "succeed if a file is newer" in withTmpDir { dir => + val file1 = dir / "foo" + IO.write(file1, "x") + file1.setLastModified(1000L) + val file2 = dir / "bar" + IO.write(file2, "x") + file2.setLastModified(2000L) + + fileCommands(dir)("newer", List("bar", "foo")) + ok + } + "fail if a file is not newer" in withTmpDir { dir => + val file1 = dir / "foo" + IO.write(file1, "x") + file1.setLastModified(1000L) + val file2 = dir / "bar" + IO.write(file2, "x") + file2.setLastModified(2000L) + + fileCommands(dir)("newer", List("foo", "bar")) must throwAn[Exception] + } + "fail if the tested file doesn't exist" in withTmpDir { dir => + val file1 = dir / "foo" + IO.write(file1, "x") + file1.setLastModified(1000L) + + fileCommands(dir)("newer", List("bar", "foo")) must throwAn[Exception] + } + "succeed if the target file doesn't exist" in withTmpDir { dir => + val file1 = dir / "foo" + IO.write(file1, "x") + file1.setLastModified(1000L) + + fileCommands(dir)("newer", List("foo", "bar")) + ok + } + } + + "The copy-file command" should { + "copy a file" in withTmpDir { dir => + IO.write(dir / "foo", "x") + fileCommands(dir)("copy-file", List("foo", "bar")) + dir / "bar" must exist + IO.read(dir / "bar") must_== "x" + + } + } + + def fileCommands(dir: File) = new FileCommands(dir) + + def withTmpDir[A](block: File => A): A = { + val tmpDir = File.createTempFile("filecommands", "") + try { + tmpDir.delete() + tmpDir.mkdir() + block(tmpDir) + } finally { + IO.delete(tmpDir) + } + + } +}