<commit_before>package silky.persistence.file

import org.scalatest.concurrent.ScalaFutures._
import org.scalatest.fixture
import org.scalatest.time.{Millis, Seconds, Span}
import silky.persistence.Entry
import silky.persistence.FutureMatchers._

class FilePersistenceSpec extends fixture.WordSpec with fixture.TestDataFixture {
  implicit def patienceConfig = PatienceConfig(timeout = Span(2, Seconds), interval = Span(50, Millis))

  private val Seq(message1, ticket1, ticket2, ticket3, ticket4) = Seq(
    Entry("messages", "M00000001", """{ "message": "Hello World!" }"""),
    Entry("deleted",  "T00000001", """{ "quantity": 1000 }"""),
    Entry("tickets",  "T00000002", """{ "quantity": 2000 }"""),
    Entry("tickets",  "T00000003", """{ "quantity": 3000 }"""),
    Entry("incoming", "T00000004", """{ "quantity": 4000 }""")
  )

  "lastRefAcross returns the last reference across multiple contexts" in { td ⇒
    new Fixture(td.name, ticket1, ticket2, ticket3, ticket4) {
      persistence.lastRefAcross(prefix = 'T', "deleted", "incoming", "tickets") willReturn "00000004"
    }
  }

  "lastRefAcross returns '00000000' when no matching entries are found in a given set of contexts" in { td ⇒
    new Fixture(td.name, ticket1, ticket2, ticket3, ticket4) {
      persistence.lastRefAcross(prefix = 'T', "one", "two", "three") willReturn "00000000"
    }
  }

  "find returns an entry existing in a given context" in { td ⇒
    new Fixture(td.name, message1) {
      persistence.find("messages", "M00000001") willReturn message1
    }
  }

  "find returns none for a non-existent entry in a given context" in { td ⇒
    new Fixture(td.name, message1) {
      persistence.find("messages", "M00000002") willReturn None
    }
  }

  "load returns entries whose reference matches a given predicate in a given context" in { td ⇒
    new Fixture(td.name, message1, ticket1, ticket2, ticket3, ticket4) {
      persistence.load("tickets", predicate = _.startsWith("T")) will contain only (ticket2, ticket3)
    }
  }

  "move simply moves the file containing the given entry from one directory (context) to another" in { td ⇒
    new Fixture(td.name, ticket4) {
      persistence.move(ticket4.ref, ticket4.context, "tickets") willReturn ticket4.copy(context = "tickets")
    }
  }

  "move fails for a non-existent entry" in { td ⇒
    import org.scalatest.MustMatchers._
    import org.scalatest.exceptions.TestFailedException

    new Fixture(td.name, ticket4) {
      val expectedMessage = s"requirement failed: Entry 'foo' not found in 'thin-air': $baseDir/thin-air/foo.json does not exist"
      val exception = the [TestFailedException] thrownBy persistence.move("foo", "thin-air", "tickets").futureValue
      exception.getCause must have message expectedMessage
    }
  }

  abstract class Fixture(testName: String, entries: Entry*) {
    val baseDir = s"target/tests/${getClass.getPackage.getName}.$suiteName/$testName/data"
    val persistence = new FilePersistence(baseDir)(concurrent.ExecutionContext.global)
    entries map persistence.save map { _.futureValue }
  }
}<commit_msg>Assert that the entry has gone from its initial context<commit_after>package silky.persistence.file

import org.scalatest.concurrent.ScalaFutures._
import org.scalatest.fixture
import org.scalatest.time.{Millis, Seconds, Span}
import silky.persistence.Entry
import silky.persistence.FutureMatchers._

class FilePersistenceSpec extends fixture.WordSpec with fixture.TestDataFixture {
  implicit def patienceConfig = PatienceConfig(timeout = Span(2, Seconds), interval = Span(50, Millis))

  private val Seq(message1, ticket1, ticket2, ticket3, ticket4) = Seq(
    Entry("messages", "M00000001", """{ "message": "Hello World!" }"""),
    Entry("deleted",  "T00000001", """{ "quantity": 1000 }"""),
    Entry("tickets",  "T00000002", """{ "quantity": 2000 }"""),
    Entry("tickets",  "T00000003", """{ "quantity": 3000 }"""),
    Entry("incoming", "T00000004", """{ "quantity": 4000 }""")
  )

  "lastRefAcross returns the last reference across multiple contexts" in { td ⇒
    new Fixture(td.name, ticket1, ticket2, ticket3, ticket4) {
      persistence.lastRefAcross(prefix = 'T', "deleted", "incoming", "tickets") willReturn "00000004"
    }
  }

  "lastRefAcross returns '00000000' when no matching entries are found in a given set of contexts" in { td ⇒
    new Fixture(td.name, ticket1, ticket2, ticket3, ticket4) {
      persistence.lastRefAcross(prefix = 'T', "one", "two", "three") willReturn "00000000"
    }
  }

  "find returns an entry existing in a given context" in { td ⇒
    new Fixture(td.name, message1) {
      persistence.find("messages", "M00000001") willReturn message1
    }
  }

  "find returns none for a non-existent entry in a given context" in { td ⇒
    new Fixture(td.name, message1) {
      persistence.find("messages", "M00000002") willReturn None
    }
  }

  "load returns entries whose reference matches a given predicate in a given context" in { td ⇒
    new Fixture(td.name, message1, ticket1, ticket2, ticket3, ticket4) {
      persistence.load("tickets", predicate = _.startsWith("T")) will contain only (ticket2, ticket3)
    }
  }

  "move simply moves the file containing the given entry from one directory (context) to another" in { td ⇒
    new Fixture(td.name, ticket4) {
      persistence.move(ticket4.ref, ticket4.context, "tickets") willReturn ticket4.copy(context = "tickets")
      persistence.find(ticket4.context, ticket4.ref) willReturn None
    }
  }

  "move fails for a non-existent entry" in { td ⇒
    import org.scalatest.MustMatchers._
    import org.scalatest.exceptions.TestFailedException

    new Fixture(td.name, ticket4) {
      val expectedMessage = s"requirement failed: Entry 'foo' not found in 'thin-air': $baseDir/thin-air/foo.json does not exist"
      val exception = the [TestFailedException] thrownBy persistence.move("foo", "thin-air", "tickets").futureValue
      exception.getCause must have message expectedMessage
    }
  }

  abstract class Fixture(testName: String, entries: Entry*) {
    val baseDir = s"target/tests/${getClass.getPackage.getName}.$suiteName/$testName/data"
    val persistence = new FilePersistence(baseDir)(concurrent.ExecutionContext.global)
    entries map persistence.save map { _.futureValue }
  }
}
{'fraction_non_alphanumeric': 0.1264094013022074, 'fraction_numerical': 0.040654279815785295, 'mean_word_length': 4.200660611065235, 'pattern_counts': {'":': 10, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 20, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7391054', 'n_tokens_mistral': 2121, 'n_tokens_neox': 1938, 'n_words': 557}