Skip to content

Instantly share code, notes, and snippets.

View brianhsu's full-sized avatar

Brian Hsu brianhsu

View GitHub Profile
abstract class UseCaseExecutor {
def execute[T](useCase: UseCase[T]): Try[T] = {
Try {
useCase.validate().foreach { error => throw error }
val result = useCase.execute()
useCase.journal.foreach(appendJournal)
result
}
object UseCaseExecutor {
type Presenter[T, R] = (Try[T] => R)
}
abstract class UseCaseExecutor {
import UseCaseExecutor.Presenter
def execute[T, R](useCase: UseCase[T])(presenter: Presenter[T, R]): R = {
object InMemoryUser {
def makeInMemoryUser: UserRepo = {
val inMemory = new InMemoryUserReadable with InMemoryUserWritable
UserRepo(inMemory, inMemory)
}
trait InMemoryUserBase {
protected var userList: List[User] = Nil
}
case class UserRepo(read: UserReadable, write: UserWritable)
trait UserReadable {
def find(email: String): Option[User]
}
trait UserWritable {
def insert(user: User): Unit
}
trait DynamicDataGenerator {
def randomUUID: UUIDGenerator
def currentTime: CurrentTimeGenerator
}
trait UUIDGenerator {
def uuid: UUID
}
trait CurrentTimeGenerator {
object CreateUser {
case class Request(email: String, name: String)
}
class CreateUser(request: CreateUser.Request)
(implicit val userRepo: UserRepo, implicit val generator: DynamicDataGenerator) extends UseCase[User] {
private lazy val uuid = generator.randomUUID.uuid
private lazy val nowTime = generator.currentTime.time
private lazy val user = User(uuid, request.email, request.name, nowTime, nowTime)
trait UseCase[T] {
def execute(): T
def validate(): Option[ValidationError]
def journal: Option[Journal]
}
@brianhsu
brianhsu / Entity.scala
Last active April 8, 2018 02:11
Entity
trait Entity
case class Stuff(
uuid: UUID, userUUID: UUID,
title: String, description: String,
createTime: LocalDateTime, updateTime: LocalDateTime,
isTrash: Boolean = false) extends Entity
case class User(
uuid: UUID, email: String, name: String,
@brianhsu
brianhsu / CreateUserSpec.scala
Created April 8, 2018 01:48
建立使用者的單元測試,Pending 版
class CreateUserSpec extends fixture.WordSpec with Matchers with OptionValues {
"CreateUser" when {
"validate request" should {
"return an exception if email is empty" in { fixture =>
pending
}
"return an exception if email is effectively empty" in { fixture =>
package moe.brianhsu.gtd.usecase
import moe.brianhsu.gtd.journal.Journal
import scala.util._
object UseCaseExecutor {
type Presenter[T, R] = (Try[T] => R)
}