<commit_before>package howitworks.macwiree

class HelloMacWire extends wp.Spec {

  "let it wire" in {
    val module = new UserModule {}
    module.usr.readStats mustBe "(1) Stats for Sarah Kerrigan: -> .... <stats>"
  }

  "let it override wires" in {
    val module = new UserModule {
      import Types._
      override lazy val da: DatabaseAccess = new DatabaseAccess {
        override def getUserFromDB(id: Id): Option[(Id, Name, Surname)] = Some((1L, "Infested", "Kerrigan"))
      }
    }
    module.usr.readStats mustBe "(1) Stats for Infested Kerrigan: -> .... <stats>"
    module.usr.readStats mustBe "(2) Stats for Infested Kerrigan: -> .... <stats>"
  }

  "many module instances" in {
    val m1 = new UserModule {}
    val m2 = new UserModule {}
    m1.usr.readStats mustBe "(1) Stats for Sarah Kerrigan: -> .... <stats>"
    m1.usr.readStats mustBe "(2) Stats for Sarah Kerrigan: -> .... <stats>"
    m1.usr.readStats mustBe "(3) Stats for Sarah Kerrigan: -> .... <stats>"

    m2.usr.readStats mustBe "(1) Stats for Sarah Kerrigan: -> .... <stats>"
    // So m1 and m2 have their own instances ...
  }

}


object Types {
  type Id = Long
  type Name = String
  type Surname = String
}
class DatabaseAccess() {
  import Types._

  private var persons: Map[Id, (Id, Name, Surname)] = Map[Id, (Id, Name, Surname)](
    0L -> (0L, "Jim", "Raynor"),
    1L -> (1L, "Sarah", "Kerrigan"),
    2L -> (2L, "Arcturus", "Mengsk")
  )

  def getUserFromDB(id: Id): Option[(Id, Name, Surname)] = persons.get(id)
}

class SecurityFilter(classified: List[Types.Id]) {
  def isClassified(id: Types.Id): Boolean = classified.contains(id)
}

class UserFinder(da: DatabaseAccess, sf: SecurityFilter) {
  import Types._

  val particularUser:Id = 1L

  def findUser(): Option[(Id, Name, Surname)] = if(sf.isClassified(particularUser)) None else da.getUserFromDB(particularUser)
}

class UserStatsReader(uf: UserFinder) {
  var counter: Int = 0
  def readStats: String = {
    uf.findUser() match {
      case Some ((id, name, surname)) =>
        counter = counter + 1
        s"($counter) Stats for $name $surname: -> .... <stats>"
      case None =>
        counter = counter + 1
        s"Sorry, user classified or not found"
    }
  }
}

trait UserModule {
  import Types._
  import com.softwaremill.macwire._

  lazy val da = wire[DatabaseAccess]
  lazy val classified: List[Id] = List(2)
  lazy val sf = wire[SecurityFilter]
  lazy val uf = wire[UserFinder]
  lazy val usr = wire[UserStatsReader]
}<commit_msg>@Module<commit_after>package howitworks.macwiree

import com.softwaremill.macwire._

class HelloMacWire extends wp.Spec {

  "let it wire" in {
    val module = new UserModule {}
    module.usr.readStats mustBe "(1) Stats for Sarah Kerrigan: -> .... <stats>"
  }

  "let it override wires" in {
    val module = new UserModule {
      import Types._
      override lazy val da: DatabaseAccess = new DatabaseAccess {
        override def getUserFromDB(id: Id): Option[(Id, Name, Surname)] = Some((1L, "Infested", "Kerrigan"))
      }
    }
    module.usr.readStats mustBe "(1) Stats for Infested Kerrigan: -> .... <stats>"
    module.usr.readStats mustBe "(2) Stats for Infested Kerrigan: -> .... <stats>"
  }

  "many module instances" in {
    val m1 = new UserModule {}
    val m2 = new UserModule {}
    m1.usr.readStats mustBe "(1) Stats for Sarah Kerrigan: -> .... <stats>"
    m1.usr.readStats mustBe "(2) Stats for Sarah Kerrigan: -> .... <stats>"
    m1.usr.readStats mustBe "(3) Stats for Sarah Kerrigan: -> .... <stats>"

    m2.usr.readStats mustBe "(1) Stats for Sarah Kerrigan: -> .... <stats>"
    // So m1 and m2 have their own instances ...
  }

  "@Module" in {
    //UModule must be a class, it's not allowed to pass trait here
    val module = wire[UModule]
    module.usr.readStats mustBe "(1) Stats for Sarah Kerrigan: -> .... <stats>"
  }
}


object Types {
  type Id = Long
  type Name = String
  type Surname = String
}
class DatabaseAccess() {
  import Types._

  private var persons: Map[Id, (Id, Name, Surname)] = Map[Id, (Id, Name, Surname)](
    0L -> (0L, "Jim", "Raynor"),
    1L -> (1L, "Sarah", "Kerrigan"),
    2L -> (2L, "Arcturus", "Mengsk")
  )

  def getUserFromDB(id: Id): Option[(Id, Name, Surname)] = persons.get(id)
}

class SecurityFilter(classified: List[Types.Id]) {
  def isClassified(id: Types.Id): Boolean = classified.contains(id)
}

class UserFinder(da: DatabaseAccess, sf: SecurityFilter) {
  import Types._

  val particularUser:Id = 1L

  def findUser(): Option[(Id, Name, Surname)] = if(sf.isClassified(particularUser)) None else da.getUserFromDB(particularUser)
}

class UserStatsReader(uf: UserFinder) {
  var counter: Int = 0
  def readStats: String = {
    uf.findUser() match {
      case Some ((id, name, surname)) =>
        counter = counter + 1
        s"($counter) Stats for $name $surname: -> .... <stats>"
      case None =>
        counter = counter + 1
        s"Sorry, user classified or not found"
    }
  }
}

trait UserModule {
  import Types._

  lazy val da = wire[DatabaseAccess]
  lazy val classified: List[Id] = List(2)
  lazy val sf = wire[SecurityFilter]
  lazy val uf = wire[UserFinder]
  lazy val usr = wire[UserStatsReader]
}

@Module
class UModule extends UserModule
{'fraction_non_alphanumeric': 0.14190729483282674, 'fraction_numerical': 0.010448328267477203, 'mean_word_length': 3.0221543162719633, 'pattern_counts': {'":': 0, '<': 20, '<?xml version=': 0, '>': 47, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, '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': '6615357', 'n_tokens_mistral': 1822, 'n_tokens_neox': 1721, 'n_words': 538}