Skip to content
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

Use default FileAlg to implement MockFileAlg, take 2 #1962

Merged
merged 2 commits into from
Feb 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@ import org.scalasteward.core.vcs.data.Repo

class BuildToolDispatcherTest extends FunSuite {
test("getDependencies") {
val repo = Repo("typelevel", "cats")
val repo = Repo("build-tool-dispatcher", "test-1")
val repoDir = config.workspace / repo.show
val files = Map(
repoDir / "project" / "build.properties" -> "sbt.version=1.2.6",
repoDir / ".scalafmt.conf" -> "version=2.0.0"
)
val initial = MockState.empty.copy(files = files)
val initial = MockState.empty
.addFiles(
repoDir / "project" / "build.properties" -> "sbt.version=1.2.6",
repoDir / ".scalafmt.conf" -> "version=2.0.0"
)
.unsafeRunSync()
val (state, deps) =
buildToolDispatcher.getDependencies(repo).run(initial).unsafeRunSync()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,23 @@ class EditAlgTest extends FunSuite {
List("git", "status", "--porcelain", "--untracked-files=no", "--ignore-submodules")

test("applyUpdate") {
val repo = Repo("fthomas", "scala-steward")
val repo = Repo("edit-alg", "test-1")
val repoDir = config.workspace / repo.show
val update = Update.Single("org.typelevel" % "cats-core" % "1.2.0", Nel.of("1.3.0"))
val file1 = repoDir / "build.sbt"
val file2 = repoDir / "project/Dependencies.scala"

val state = editAlg
.applyUpdate(repo, RepoConfig.empty, update)
.runS(MockState.empty.add(file1, """val catsVersion = "1.2.0"""").add(file2, ""))
val state = MockState.empty
.addFiles(file1 -> """val catsVersion = "1.2.0"""", file2 -> "")
.flatMap(editAlg.applyUpdate(repo, RepoConfig.empty, update).runS)
.unsafeRunSync()

val expected = MockState.empty.copy(
trace = Vector(
Cmd("test", "-f", repoDir.pathAsString),
Cmd("test", "-f", file1.pathAsString),
Cmd("read", file1.pathAsString),
Cmd("test", "-f", (repoDir / "project").pathAsString),
Cmd("test", "-f", file2.pathAsString),
Cmd("read", file2.pathAsString),
Log("Trying heuristic 'moduleId'"),
Expand All @@ -51,7 +53,7 @@ class EditAlgTest extends FunSuite {
}

test("applyUpdate with scalafmt update") {
val repo = Repo("fthomas", "scala-steward")
val repo = Repo("edit-alg", "test-2")
val repoDir = config.workspace / repo.show
val update = Update.Single("org.scalameta" % "scalafmt-core" % "2.0.0", Nel.of("2.1.0"))
val scalafmtConf = repoDir / ".scalafmt.conf"
Expand All @@ -61,13 +63,14 @@ class EditAlgTest extends FunSuite {
|""".stripMargin
val buildSbt = repoDir / "build.sbt"

val state = editAlg
.applyUpdate(repo, RepoConfig.empty, update)
.runS(MockState.empty.add(scalafmtConf, scalafmtConfContent).add(buildSbt, ""))
val state = MockState.empty
.addFiles(scalafmtConf -> scalafmtConfContent, buildSbt -> "")
.flatMap(editAlg.applyUpdate(repo, RepoConfig.empty, update).runS)
.unsafeRunSync()

val expected = MockState.empty.copy(
trace = Vector(
Cmd("test", "-f", repoDir.pathAsString),
Cmd("test", "-f", scalafmtConf.pathAsString),
Cmd("read", scalafmtConf.pathAsString),
Cmd("test", "-f", buildSbt.pathAsString),
Expand Down Expand Up @@ -107,32 +110,32 @@ class EditAlgTest extends FunSuite {
}

test("apply update to ammonite file") {
val repo = Repo("fthomas", "scala-steward")
val repo = Repo("edit-alg", "test-3")
val repoDir = config.workspace / repo.show
val update = Update.Single("org.typelevel" % "cats-core" % "1.2.0", Nel.of("1.3.0"))
val file1 = repoDir / "script.sc"
val file2 = repoDir / "build.sbt"

val state = editAlg
.applyUpdate(repo, RepoConfig.empty, update)
.runS(
MockState.empty
.add(file1, """import $ivy.`org.typelevel::cats-core:1.2.0`, cats.implicits._"""")
.add(file2, """"org.typelevel" %% "cats-core" % "1.2.0"""")
val state = MockState.empty
.addFiles(
file1 -> """import $ivy.`org.typelevel::cats-core:1.2.0`, cats.implicits._"""",
file2 -> """"org.typelevel" %% "cats-core" % "1.2.0""""
)
.flatMap(editAlg.applyUpdate(repo, RepoConfig.empty, update).runS)
.unsafeRunSync()

val expected = MockState.empty.copy(
trace = Vector(
Cmd("test", "-f", file1.pathAsString),
Cmd("read", file1.pathAsString),
Cmd("test", "-f", repoDir.pathAsString),
Cmd("test", "-f", file2.pathAsString),
Cmd("read", file2.pathAsString),
Log("Trying heuristic 'moduleId'"),
Cmd("test", "-f", file1.pathAsString),
Cmd("read", file1.pathAsString),
Cmd("write", file1.pathAsString),
Log("Trying heuristic 'moduleId'"),
Cmd("read", file2.pathAsString),
Cmd("write", file2.pathAsString),
Cmd("read", file1.pathAsString),
Cmd("write", file1.pathAsString),
Cmd(envVars ++ (repoDir.toString :: gitStatus))
),
files = Map(
Expand Down Expand Up @@ -237,9 +240,9 @@ class EditAlgTest extends FunSuite {
private def runApplyUpdate(update: Update, files: Map[String, String]): Map[String, String] = {
val repoDir = File.temp / "ws/owner/repo"
val filesInRepoDir = files.map { case (file, content) => repoDir / file -> content }
editAlg
.applyUpdate(Repo("owner", "repo"), RepoConfig.empty, update)
.runS(MockState.empty.addFiles(filesInRepoDir))
MockState.empty
.addFiles(filesInRepoDir.toSeq: _*)
.flatMap(editAlg.applyUpdate(Repo("owner", "repo"), RepoConfig.empty, update).runS)
.map(_.files)
.unsafeRunSync()
.map { case (file, content) => file.toString.replace(repoDir.toString + "/", "") -> content }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,45 +3,47 @@ package org.scalasteward.core.io
import better.files.File
import cats.data.StateT
import cats.effect.IO
import cats.syntax.all._
import fs2.Stream
import org.http4s.Uri
import org.scalasteward.core.mock.{applyPure, MockEff, MockState}
import org.scalasteward.core.io.FileAlgTest.ioFileAlg
import org.scalasteward.core.mock.{MockEff, MockState}

class MockFileAlg extends FileAlg[MockEff] {
override def deleteForce(file: File): MockEff[Unit] =
StateT.modify(_.exec(List("rm", "-rf", file.pathAsString)).rm(file))
StateT.modifyF[IO, MockState](_.exec(List("rm", "-rf", file.pathAsString)).rmFile(file))

override def ensureExists(dir: File): MockEff[File] =
applyPure(s => (s.exec(List("mkdir", "-p", dir.pathAsString)), dir))
StateT.modify[IO, MockState](_.exec(List("mkdir", "-p", dir.pathAsString))) >>
StateT.liftF(ioFileAlg.ensureExists(dir))

override def home: MockEff[File] =
StateT.pure(File.root / "tmp" / "steward")
StateT.pure(File.temp / "steward")

override def isDirectory(file: File): MockEff[Boolean] =
StateT.pure(false)
StateT.modify[IO, MockState](_.exec(List("test", "-d", file.pathAsString))) >>
StateT.liftF(ioFileAlg.isDirectory(file))

override def isRegularFile(file: File): MockEff[Boolean] =
for {
_ <- StateT.modify[IO, MockState](_.exec(List("test", "-f", file.pathAsString)))
s <- StateT.get[IO, MockState]
exists = s.files.contains(file)
} yield exists
StateT.modify[IO, MockState](_.exec(List("test", "-f", file.pathAsString))) >>
StateT.liftF(ioFileAlg.isRegularFile(file))

override def removeTemporarily[A](file: File)(fa: MockEff[A]): MockEff[A] =
for {
_ <- StateT.modify[IO, MockState](_.exec(List("rm", file.pathAsString)))
a <- fa
s1 <- StateT.get[IO, MockState]
(s2, a) <- StateT.liftF(ioFileAlg.removeTemporarily(file)(fa.run(s1)))
_ <- StateT.set[IO, MockState](s2)
_ <- StateT.modify[IO, MockState](_.exec(List("restore", file.pathAsString)))
} yield a

override def readFile(file: File): MockEff[Option[String]] =
applyPure(s => (s.exec(List("read", file.pathAsString)), s.files.get(file)))
StateT.modify[IO, MockState](_.exec(List("read", file.pathAsString))) >>
StateT.liftF(ioFileAlg.readFile(file))

override def readResource(resource: String): MockEff[String] =
for {
_ <- StateT.modify[IO, MockState](_.exec(List("read", s"classpath:$resource")))
content <- StateT.liftF(FileAlgTest.ioFileAlg.readResource(resource))
} yield content
StateT.modify[IO, MockState](_.exec(List("read", s"classpath:$resource"))) >>
StateT.liftF(ioFileAlg.readResource(resource))

override def readUri(uri: Uri): MockEff[String] =
for {
Expand All @@ -53,14 +55,15 @@ class MockFileAlg extends FileAlg[MockEff] {
})
} yield content

override def walk(dir: File): Stream[MockEff, File] = {
val dirAsString = dir.pathAsString
val state: MockEff[List[File]] = StateT.inspect {
_.files.keys.filter(_.pathAsString.startsWith(dirAsString)).toList
}
Stream.eval(state).flatMap(Stream.emits[MockEff, File])
}
override def walk(dir: File): Stream[MockEff, File] =
Stream.evals(
StateT.liftF[IO, MockState, List[File]](
ioFileAlg.walk(dir).compile.toList.map(_.sortBy(_.pathAsString))
)
)

override def writeFile(file: File, content: String): MockEff[Unit] =
StateT.modify(_.exec(List("write", file.pathAsString)).add(file, content))
StateT.modifyF[IO, MockState](
_.exec(List("write", file.pathAsString)).addFiles(file -> content)
)
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package org.scalasteward.core.mock

import better.files.File
import cats.effect.IO
import cats.syntax.all._
import org.http4s.Uri
import org.scalasteward.core.io.FileAlgTest.ioFileAlg
import org.scalasteward.core.mock.MockState.TraceEntry
import org.scalasteward.core.mock.MockState.TraceEntry.{Cmd, Log}

Expand All @@ -11,17 +14,16 @@ final case class MockState(
files: Map[File, String],
uris: Map[Uri, String]
) {
def add(file: File, content: String): MockState =
copy(files = files + (file -> content))
def addFiles(newFiles: (File, String)*): IO[MockState] =
newFiles.toList
.traverse_ { case (file, content) => ioFileAlg.writeFile(file, content) }
.as(copy(files = files ++ newFiles))

def addFiles(newFiles: Map[File, String]): MockState =
copy(files = files ++ newFiles)
def addUris(newUris: (Uri, String)*): MockState =
copy(uris = uris ++ newUris)

def addUri(uri: Uri, content: String): MockState =
copy(uris = uris + (uri -> content))

def rm(file: File): MockState =
copy(files = files - file)
def rmFile(file: File): IO[MockState] =
ioFileAlg.deleteForce(file).as(copy(files = files - file))

def exec(cmd: List[String], env: (String, String)*): MockState =
copy(trace = trace :+ Cmd(env.map { case (k, v) => s"$k=$v" }.toList ++ cmd))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import org.scalasteward.core.mock.{MockEff, MockState}
class JsonKeyValueStoreTest extends FunSuite {
test("put, get") {
val p = for {
kvStore <- JsonKeyValueStore.create[MockEff, String, String]("test", "0")
kvStore <- JsonKeyValueStore.create[MockEff, String, String]("test-1", "0")
_ <- kvStore.put("k1", "v1")
v1 <- kvStore.get("k1")
_ <- kvStore.put("k2", "v2")
Expand All @@ -19,9 +19,9 @@ class JsonKeyValueStoreTest extends FunSuite {
val (state, value) = p.run(MockState.empty).unsafeRunSync()
assertEquals(value, (Some("v1"), None))

val k1File = config.workspace / "store" / "test" / "v0" / "k1" / "test.json"
val k2File = config.workspace / "store" / "test" / "v0" / "k2" / "test.json"
val k3File = config.workspace / "store" / "test" / "v0" / "k3" / "test.json"
val k1File = config.workspace / "store" / "test-1" / "v0" / "k1" / "test-1.json"
val k2File = config.workspace / "store" / "test-1" / "v0" / "k2" / "test-1.json"
val k3File = config.workspace / "store" / "test-1" / "v0" / "k3" / "test-1.json"
val expected = MockState.empty.copy(
trace = Vector(
Cmd("write", k1File.toString),
Expand All @@ -39,15 +39,15 @@ class JsonKeyValueStoreTest extends FunSuite {

test("modifyF, get, set") {
val p = for {
kvStore <- JsonKeyValueStore.create[MockEff, String, String]("test", "0")
kvStore <- JsonKeyValueStore.create[MockEff, String, String]("test-2", "0")
_ <- kvStore.modifyF("k1")(_ => Option("v0").pure[MockEff])
v1 <- kvStore.get("k1")
_ <- kvStore.set("k1", None)
} yield v1
val (state, value) = p.run(MockState.empty).unsafeRunSync()
assertEquals(value, Some("v0"))

val k1File = config.workspace / "store" / "test" / "v0" / "k1" / "test.json"
val k1File = config.workspace / "store" / "test-2" / "v0" / "k1" / "test-2.json"
val expected = MockState.empty.copy(
trace = Vector(
Cmd("read", k1File.toString),
Expand All @@ -62,7 +62,7 @@ class JsonKeyValueStoreTest extends FunSuite {
test("cached") {
val p = for {
kvStore <- JsonKeyValueStore
.create[MockEff, String, String]("test", "0")
.create[MockEff, String, String]("test-3", "0")
.flatMap(CachingKeyValueStore.wrap(_))
_ <- kvStore.put("k1", "v1")
v1 <- kvStore.get("k1")
Expand All @@ -71,8 +71,8 @@ class JsonKeyValueStoreTest extends FunSuite {
val (state, value) = p.run(MockState.empty).unsafeRunSync()
assertEquals(value, (Some("v1"), None))

val k1File = config.workspace / "store" / "test" / "v0" / "k1" / "test.json"
val k2File = config.workspace / "store" / "test" / "v0" / "k2" / "test.json"
val k1File = config.workspace / "store" / "test-3" / "v0" / "k1" / "test-3.json"
val k2File = config.workspace / "store" / "test-3" / "v0" / "k2" / "test-3.json"
val expected = MockState.empty.copy(
trace = Vector(Cmd("write", k1File.toString), Cmd("read", k2File.toString)),
files = Map(k1File -> """"v1"""")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class RepoConfigAlgTest extends FunSuite {
|commits.message = "Update ${artifactName} from ${currentVersion} to ${nextVersion}"
|buildRoots = [ ".", "subfolder/subfolder" ]
|""".stripMargin
val initialState = MockState.empty.add(configFile, content)
val initialState = MockState.empty.addFiles(configFile -> content).unsafeRunSync()
val config = repoConfigAlg
.readRepoConfig(repo)
.flatMap(repoConfigAlg.mergeWithDefault)
Expand Down Expand Up @@ -158,7 +158,8 @@ class RepoConfigAlgTest extends FunSuite {
test("malformed config") {
val repo = Repo("fthomas", "scala-steward")
val configFile = File.temp / "ws/fthomas/scala-steward/.scala-steward.conf"
val initialState = MockState.empty.add(configFile, """updates.ignore = [ "foo """)
val initialState =
MockState.empty.addFiles(configFile -> """updates.ignore = [ "foo """).unsafeRunSync()
val (state, config) = repoConfigAlg.readRepoConfig(repo).run(initialState).unsafeRunSync()

assertEquals(config, None)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class MigrationsLoaderTest extends FunSuite {
}

test("loadAll: with extra file, without defaults") {
val initialState = mockState.addUri(migrationsUri, migrationsContent)
val initialState = mockState.addUris(migrationsUri -> migrationsContent)
val migrations = migrationsLoader
.loadAll(ScalafixCfg(List(migrationsUri), disableDefaults = true))
.runA(initialState)
Expand All @@ -57,7 +57,7 @@ class MigrationsLoaderTest extends FunSuite {
}

test("loadAll: with extra file, with defaults") {
val initialState = mockState.addUri(migrationsUri, migrationsContent)
val initialState = mockState.addUris(migrationsUri -> migrationsContent)
val migrations = migrationsLoader
.loadAll(ScalafixCfg(List(migrationsUri), disableDefaults = false))
.runA(initialState)
Expand All @@ -67,7 +67,7 @@ class MigrationsLoaderTest extends FunSuite {
}

test("loadAll: malformed extra file") {
val initialState = mockState.addUri(migrationsUri, """{"key": "i'm not a valid Migration}""")
val initialState = mockState.addUris(migrationsUri -> """{"key": "i'm not a valid Migration}""")
val migrations = migrationsLoader
.loadAll(ScalafixCfg(List(migrationsUri), disableDefaults = false))
.runA(initialState)
Expand All @@ -78,8 +78,8 @@ class MigrationsLoaderTest extends FunSuite {
}

object MigrationsLoaderTest {
val mockState: MockState = MockState.empty.addUri(
MigrationsLoader.defaultScalafixMigrationsUrl,
ioFileAlg.readResource("scalafix-migrations.conf").unsafeRunSync()
val mockState: MockState = MockState.empty.addUris(
MigrationsLoader.defaultScalafixMigrationsUrl ->
ioFileAlg.readResource("scalafix-migrations.conf").unsafeRunSync()
)
}
Loading