Format
This commit is contained in:
parent
310b3961ad
commit
c1099c97f9
|
@ -13,35 +13,27 @@ case class Error(error: String)
|
||||||
type WriterTF[F[_], L] = [A] =>> WriterT[F, L, A]
|
type WriterTF[F[_], L] = [A] =>> WriterT[F, L, A]
|
||||||
case class LogEmbed[F[_], A](value: WriterT[WriterTF[WriterTF[F, Vector[Debug]], Vector[Info]], Vector[Error], A])
|
case class LogEmbed[F[_], A](value: WriterT[WriterTF[WriterTF[F, Vector[Debug]], Vector[Info]], Vector[Error], A])
|
||||||
|
|
||||||
/**
|
/** I. Продвинутый логгер
|
||||||
* I. Продвинутый логгер
|
*
|
||||||
*
|
* В этом задании вам предстоит реализовать логгер, имеющий 3 уровня записей - Debug, Info и Error. Структура лога
|
||||||
* В этом задании вам предстоит реализовать логгер, имеющий 3 уровня записей - Debug, Info и Error.
|
* LogEmbed описана выше, от вас же требуется реализовать функции для удобного создания логов
|
||||||
* Структура лога LogEmbed описана выше, от вас же требуется реализовать функции для удобного создания логов
|
*/
|
||||||
*
|
|
||||||
*/
|
|
||||||
final case class Logger[F[_]: Monad]():
|
final case class Logger[F[_]: Monad]():
|
||||||
/**
|
/** I.1) Реализовать функцию debug
|
||||||
* I.1) Реализовать функцию debug
|
*
|
||||||
*
|
* Функция должна принимать сообщение уровня debug и возвращать лог, содержащий только это сообщение на правильном
|
||||||
* Функция должна принимать сообщение уровня debug и возвращать лог,
|
* уровне
|
||||||
* содержащий только это сообщение на правильном уровне
|
*/
|
||||||
*
|
|
||||||
*/
|
|
||||||
def debug(debug: String): LogEmbed[F, Unit] = ???
|
def debug(debug: String): LogEmbed[F, Unit] = ???
|
||||||
|
|
||||||
/**
|
/** I.1) Реализовать функцию info
|
||||||
* I.1) Реализовать функцию info
|
*
|
||||||
*
|
* Функция аналогична предыдущей за исключением того, что уровень лога меняется на Info
|
||||||
* Функция аналогична предыдущей за исключением того, что уровень лога меняется на Info
|
*/
|
||||||
*
|
|
||||||
*/
|
|
||||||
def info(info: String): LogEmbed[F, Unit] = ???
|
def info(info: String): LogEmbed[F, Unit] = ???
|
||||||
|
|
||||||
/**
|
/** I.1) Реализовать функцию error
|
||||||
* I.1) Реализовать функцию error
|
*
|
||||||
*
|
* Функция-аналог предыдущих двух для уровня Error
|
||||||
* Функция-аналог предыдущих двух для уровня Error
|
*/
|
||||||
*
|
|
||||||
*/
|
|
||||||
def error(error: String): LogEmbed[F, Unit] = ???
|
def error(error: String): LogEmbed[F, Unit] = ???
|
||||||
|
|
|
@ -4,33 +4,26 @@ import cats.Monad
|
||||||
import cats.data.{Reader, ReaderT}
|
import cats.data.{Reader, ReaderT}
|
||||||
import cats.syntax.applicative.*
|
import cats.syntax.applicative.*
|
||||||
|
|
||||||
/**
|
/** II. Интерфейс Ask
|
||||||
* II. Интерфейс Ask
|
*
|
||||||
*
|
* Теперь от вас требуется реализовать несколько интерфейсов Ask для некоторых монад. Интерфейс служит для получения
|
||||||
* Теперь от вас требуется реализовать несколько интерфейсов Ask для некоторых монад.
|
* контекстной информации, хранящейся в монаде (подробнее о данной монаде можно прочить на сайте библиотеки cats, а в
|
||||||
* Интерфейс служит для получения контекстной информации, хранящейся в монаде
|
* одном из следующих заданий будут примеры применения)
|
||||||
* (подробнее о данной монаде можно прочить на сайте библиотеки cats,
|
*/
|
||||||
* а в одном из следующих заданий будут примеры применения)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
trait Ask[F[_], R]:
|
trait Ask[F[_], R]:
|
||||||
def ask: F[R]
|
def ask: F[R]
|
||||||
|
|
||||||
object Ask:
|
object Ask:
|
||||||
def apply[F[_], R](using ask: Ask[F, R]): Ask[F, R] = ask
|
def apply[F[_], R](using ask: Ask[F, R]): Ask[F, R] = ask
|
||||||
|
|
||||||
/**
|
/** II.1) Интерфейс Ask для монады Reader
|
||||||
* II.1) Интерфейс Ask для монады Reader
|
*
|
||||||
*
|
* Реализуйте описанный выше интерфейс, возвращающий контекст, содержащийся в монаде Reader
|
||||||
* Реализуйте описанный выше интерфейс, возвращающий контекст, содержащийся в монаде Reader
|
*/
|
||||||
*
|
|
||||||
*/
|
|
||||||
given [R]: Ask[Reader[R, *], R] = ???
|
given [R]: Ask[Reader[R, *], R] = ???
|
||||||
|
|
||||||
/**
|
/** II.2) Интерфейс Ask для трансформера ReaderT
|
||||||
* II.2) Интерфейс Ask для трансформера ReaderT
|
*
|
||||||
*
|
* Реализуйте описанный выше интерфейс, возвращающий контекст, содержащийся в трансформере ReaderT
|
||||||
* Реализуйте описанный выше интерфейс, возвращающий контекст, содержащийся в трансформере ReaderT
|
*/
|
||||||
*
|
|
||||||
*/
|
|
||||||
given [F[_]: Monad, R]: Ask[ReaderT[F, R, *], R] = ???
|
given [F[_]: Monad, R]: Ask[ReaderT[F, R, *], R] = ???
|
||||||
|
|
|
@ -4,31 +4,25 @@ import cats.{Monad, Monoid}
|
||||||
import cats.data.{Writer, WriterT}
|
import cats.data.{Writer, WriterT}
|
||||||
import cats.syntax.applicative.*
|
import cats.syntax.applicative.*
|
||||||
|
|
||||||
/**
|
/** III. Интерфейс Tell
|
||||||
* III. Интерфейс Tell
|
*
|
||||||
*
|
* Данное задание очень похоже на предыдущее, только наш интерфейс будет не возвращать контекст, а, наоборот, отдавать
|
||||||
* Данное задание очень похоже на предыдущее, только наш интерфейс будет не возвращать контекст,
|
* дополнительную информацию во вне
|
||||||
* а, наоборот, отдавать дополнительную информацию во вне
|
*/
|
||||||
*
|
|
||||||
*/
|
|
||||||
trait Tell[F[_], W]:
|
trait Tell[F[_], W]:
|
||||||
def tell(log: W): F[Unit]
|
def tell(log: W): F[Unit]
|
||||||
|
|
||||||
object Tell:
|
object Tell:
|
||||||
def apply[F[_], W](using tell: Tell[F, W]): Tell[F, W] = tell
|
def apply[F[_], W](using tell: Tell[F, W]): Tell[F, W] = tell
|
||||||
|
|
||||||
/**
|
/** III.1) Интерфейс Tell для Writer
|
||||||
* III.1) Интерфейс Tell для Writer
|
*
|
||||||
*
|
* Реализуйте интерфейс Tell так, чтобы полученное сообщение добавлялось в лог монады
|
||||||
* Реализуйте интерфейс Tell так, чтобы полученное сообщение добавлялось в лог монады
|
*/
|
||||||
*
|
|
||||||
*/
|
|
||||||
given [W: Monoid]: Tell[Writer[W, *], W] = ???
|
given [W: Monoid]: Tell[Writer[W, *], W] = ???
|
||||||
|
|
||||||
/**
|
/** III.2) Интерфейс Tell для WriterT
|
||||||
* III.2) Интерфейс Tell для WriterT
|
*
|
||||||
*
|
* Реализуйте интерфейс Tell так, чтобы полученное сообщение добавлялось в лог трансформера
|
||||||
* Реализуйте интерфейс Tell так, чтобы полученное сообщение добавлялось в лог трансформера
|
*/
|
||||||
*
|
|
||||||
*/
|
|
||||||
given [F[_]: Monad, W: Monoid]: Tell[WriterT[F, W, *], W] = ???
|
given [F[_]: Monad, W: Monoid]: Tell[WriterT[F, W, *], W] = ???
|
||||||
|
|
|
@ -13,8 +13,8 @@ object UserName:
|
||||||
type Age = Age.T
|
type Age = Age.T
|
||||||
object Age:
|
object Age:
|
||||||
opaque type T <: Byte = Byte
|
opaque type T <: Byte = Byte
|
||||||
val Adult: Age = 18.toByte
|
val Adult: Age = 18.toByte
|
||||||
def apply(v: Byte): Age = v
|
def apply(v: Byte): Age = v
|
||||||
|
|
||||||
final case class User(id: UserId, name: UserName, age: Age, friends: Set[UserId]):
|
final case class User(id: UserId, name: UserName, age: Age, friends: Set[UserId]):
|
||||||
def isAdult: Boolean = age >= Age.Adult
|
def isAdult: Boolean = age >= Age.Adult
|
||||||
|
|
|
@ -2,4 +2,4 @@ package hw.user
|
||||||
|
|
||||||
object UserErrors:
|
object UserErrors:
|
||||||
case class UserAlreadyExists(name: UserName) extends Throwable
|
case class UserAlreadyExists(name: UserName) extends Throwable
|
||||||
case class UserDoesNotExists(id: UserId) extends Throwable
|
case class UserDoesNotExists(id: UserId) extends Throwable
|
||||||
|
|
|
@ -12,7 +12,9 @@ case class Config(chunkSize: Int)
|
||||||
|
|
||||||
trait UserRepositoryDao:
|
trait UserRepositoryDao:
|
||||||
def findAll(config: Config): List[User]
|
def findAll(config: Config): List[User]
|
||||||
def create(name: UserName, age: Age, friends: Set[UserId] = Set.empty)(config: Config): Either[UserAlreadyExists, User]
|
def create(name: UserName, age: Age, friends: Set[UserId] = Set.empty)(
|
||||||
|
config: Config
|
||||||
|
): Either[UserAlreadyExists, User]
|
||||||
def delete(userId: UserId)(config: Config): Either[UserDoesNotExists, Unit]
|
def delete(userId: UserId)(config: Config): Either[UserDoesNotExists, Unit]
|
||||||
def update(user: User)(config: Config): Either[UserDoesNotExists, Unit]
|
def update(user: User)(config: Config): Either[UserDoesNotExists, Unit]
|
||||||
|
|
||||||
|
@ -22,51 +24,38 @@ trait UserRepository[F[_]]:
|
||||||
def delete(userId: UserId): F[Unit]
|
def delete(userId: UserId): F[Unit]
|
||||||
def update(user: User): F[Unit]
|
def update(user: User): F[Unit]
|
||||||
|
|
||||||
/**
|
/** IV. Обёртка для работы с базой данных
|
||||||
* IV. Обёртка для работы с базой данных
|
*
|
||||||
*
|
* В последнем задании рассмотрим более практичный пример: пусть есть интерфейс UserRepositoryDao, который обеспечивает
|
||||||
* В последнем задании рассмотрим более практичный пример:
|
* работу с базой данных, обновляя данные о пользователях (модель пользователей и операции, проводимые с ними,
|
||||||
* пусть есть интерфейс UserRepositoryDao, который обеспечивает работу с базой данных, обновляя данные о пользователях
|
* описываются кодом в данном файле и в User.scala, UserErrors.scala). От вас требуется сделать обёртку над данным
|
||||||
* (модель пользователей и операции, проводимые с ними, описываются кодом в данном файле и в User.scala, UserErrors.scala).
|
* интерфейсом, чтобы его "грязные" функции можно было бы использовать в коде в функциональном стиле. При написании
|
||||||
* От вас требуется сделать обёртку над данным интерфейсом, чтобы его "грязные" функции можно было бы использовать
|
* используйте интерфейсы MonadThrow и Ask - такой подход часто называется Tagless final
|
||||||
* в коде в функциональном стиле.
|
*/
|
||||||
* При написании используйте интерфейсы MonadThrow и Ask - такой подход часто называется Tagless final
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
object UserRepositoryDao:
|
object UserRepositoryDao:
|
||||||
def apply[F[_]: MonadThrow](dao: UserRepositoryDao)(using Ask[F, Config]): UserRepository[F] = new UserRepository[F]:
|
def apply[F[_]: MonadThrow](dao: UserRepositoryDao)(using Ask[F, Config]): UserRepository[F] = new UserRepository[F]:
|
||||||
/**
|
/** IV.1) Фукнция findAll
|
||||||
* IV.1) Фукнция findAll
|
*
|
||||||
*
|
* Для данной функции требуется, используя интерфейс Ask из библиотеки Cats (полностью аналогичный варианту из
|
||||||
* Для данной функции требуется, используя интерфейс Ask из библиотеки Cats
|
* предыдущего задания), получить конфиг, хранящийся в монаде F, и вернуть значение, обёрнутое в монаду
|
||||||
* (полностью аналогичный варианту из предыдущего задания), получить конфиг, хранящийся в монаде F,
|
*/
|
||||||
* и вернуть значение, обёрнутое в монаду
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
override def findAll: F[List[User]] = ???
|
override def findAll: F[List[User]] = ???
|
||||||
|
|
||||||
/**
|
/** IV.2) Фукнция create
|
||||||
* IV.2) Фукнция create
|
*
|
||||||
*
|
* Для этой функции аналогично нужно получить конфиг, а так же дополнительно обработать возможные ошибки при помощи
|
||||||
* Для этой функции аналогично нужно получить конфиг,
|
* интерфейса MonadThrow (примеры использования можно найти на сайте cats)
|
||||||
* а так же дополнительно обработать возможные ошибки при помощи интерфейса MonadThrow
|
*/
|
||||||
* (примеры использования можно найти на сайте cats)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
override def create(name: UserName, age: Age, friends: Set[UserId]): F[User] = ???
|
override def create(name: UserName, age: Age, friends: Set[UserId]): F[User] = ???
|
||||||
|
|
||||||
/**
|
/** IV.3) Функция delete
|
||||||
* IV.3) Функция delete
|
*
|
||||||
*
|
* Данная функция аналогично требует получения конфига и обработки ошибки
|
||||||
* Данная функция аналогично требует получения конфига и обработки ошибки
|
*/
|
||||||
*
|
|
||||||
*/
|
|
||||||
override def delete(userId: UserId): F[Unit] = ???
|
override def delete(userId: UserId): F[Unit] = ???
|
||||||
|
|
||||||
/**
|
/** IV.4) Функция update
|
||||||
* IV.4) Функция update
|
*
|
||||||
*
|
* Для последней функции задание аналогично
|
||||||
* Для последней функции задание аналогично
|
*/
|
||||||
*
|
|
||||||
*/
|
|
||||||
override def update(user: User): F[Unit] = ???
|
override def update(user: User): F[Unit] = ???
|
||||||
|
|
|
@ -8,7 +8,9 @@ import scala.util.{Success, Try}
|
||||||
|
|
||||||
class Tests extends AnyFlatSpec with Matchers:
|
class Tests extends AnyFlatSpec with Matchers:
|
||||||
def logEmbed(debug: Vector[String], info: Vector[String], error: Vector[String]): LogEmbed[Try, Unit] =
|
def logEmbed(debug: Vector[String], info: Vector[String], error: Vector[String]): LogEmbed[Try, Unit] =
|
||||||
LogEmbed(WriterT(WriterT(WriterT(Success((debug.map(Debug.apply), (info.map(Info.apply), (error.map(Error.apply), ()))))))))
|
LogEmbed(
|
||||||
|
WriterT(WriterT(WriterT(Success((debug.map(Debug.apply), (info.map(Info.apply), (error.map(Error.apply), ())))))))
|
||||||
|
)
|
||||||
|
|
||||||
it should "info log" in {
|
it should "info log" in {
|
||||||
val logger = Logger[Try]()
|
val logger = Logger[Try]()
|
||||||
|
@ -32,4 +34,4 @@ class Tests extends AnyFlatSpec with Matchers:
|
||||||
_ <- logger.debug("debug").value
|
_ <- logger.debug("debug").value
|
||||||
_ <- logger.error("error").value
|
_ <- logger.error("error").value
|
||||||
} yield ()) shouldBe logEmbed(Vector("debug"), Vector("info"), Vector("error")).value
|
} yield ()) shouldBe logEmbed(Vector("debug"), Vector("info"), Vector("error")).value
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,4 +11,4 @@ class AskTests extends AnyFlatSpec with Matchers:
|
||||||
|
|
||||||
it should "create Ask[ReaderT] instance" in {
|
it should "create Ask[ReaderT] instance" in {
|
||||||
Ask[ReaderT[Option, Int, *], Int].ask.run(42) shouldBe Some(42)
|
Ask[ReaderT[Option, Int, *], Int].ask.run(42) shouldBe Some(42)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,4 +11,4 @@ class TellTests extends AnyFlatSpec with Matchers:
|
||||||
|
|
||||||
it should "create Tell[WriterT] instance" in {
|
it should "create Tell[WriterT] instance" in {
|
||||||
Tell[WriterT[Option, Int, *], Int].tell(42).run shouldBe Some((42, ()))
|
Tell[WriterT[Option, Int, *], Int].tell(42).run shouldBe Some((42, ()))
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,10 +25,11 @@ object TestsData:
|
||||||
lastConfig = Right(config)
|
lastConfig = Right(config)
|
||||||
usersList.toList
|
usersList.toList
|
||||||
|
|
||||||
override def create(name: UserName, age: Age, friends: Set[UserId])(config: Config): Either[UserAlreadyExists, User] =
|
override def create(name: UserName, age: Age, friends: Set[UserId])(
|
||||||
|
config: Config
|
||||||
|
): Either[UserAlreadyExists, User] =
|
||||||
lastConfig = Right(config)
|
lastConfig = Right(config)
|
||||||
if (usersList.exists(_.name == name))
|
if (usersList.exists(_.name == name)) Left(UserAlreadyExists(name))
|
||||||
Left(UserAlreadyExists(name))
|
|
||||||
else
|
else
|
||||||
val user = User(UserId(usersList.size), name, age, friends)
|
val user = User(UserId(usersList.size), name, age, friends)
|
||||||
usersList += user
|
usersList += user
|
||||||
|
@ -39,8 +40,7 @@ object TestsData:
|
||||||
if (usersList.exists(_.id == userId))
|
if (usersList.exists(_.id == userId))
|
||||||
usersList -= usersList.find(_.id == userId).get
|
usersList -= usersList.find(_.id == userId).get
|
||||||
Right(())
|
Right(())
|
||||||
else
|
else Left(UserDoesNotExists(userId))
|
||||||
Left(UserDoesNotExists(userId))
|
|
||||||
|
|
||||||
override def update(user: User)(config: Config): Either[UserDoesNotExists, Unit] =
|
override def update(user: User)(config: Config): Either[UserDoesNotExists, Unit] =
|
||||||
lastConfig = Right(config)
|
lastConfig = Right(config)
|
||||||
|
@ -48,24 +48,25 @@ object TestsData:
|
||||||
usersList -= usersList.find(_.id == user.id).get
|
usersList -= usersList.find(_.id == user.id).get
|
||||||
usersList += user
|
usersList += user
|
||||||
Right(())
|
Right(())
|
||||||
else
|
else Left(UserDoesNotExists(user.id))
|
||||||
Left(UserDoesNotExists(user.id))
|
|
||||||
|
|
||||||
type M = [A] =>> Config => Either[Throwable, A]
|
type M = [A] =>> Config => Either[Throwable, A]
|
||||||
|
|
||||||
object M:
|
object M:
|
||||||
given MonadThrow[M] = new MonadError[M, Throwable]:
|
given MonadThrow[M] = new MonadError[M, Throwable]:
|
||||||
override def pure[A](x: A): M[A] = _ => Right(x)
|
override def pure[A](x: A): M[A] = _ => Right(x)
|
||||||
override def flatMap[A, B](fa: M[A])(f: A => M[B]): M[B] = c => fa(c).flatMap(a => f(a)(c))
|
override def flatMap[A, B](fa: M[A])(f: A => M[B]): M[B] = c => fa(c).flatMap(a => f(a)(c))
|
||||||
override def tailRecM[A, B](a: A)(f: A => M[Either[A, B]]): M[B] =
|
override def tailRecM[A, B](a: A)(f: A => M[Either[A, B]]): M[B] =
|
||||||
c => f(a)(c) match
|
c =>
|
||||||
case Left(e) => Left(e)
|
f(a)(c) match
|
||||||
case Right(Left(a)) => tailRecM(a)(f)(c)
|
case Left(e) => Left(e)
|
||||||
case Right(Right(b)) => Right(b)
|
case Right(Left(a)) => tailRecM(a)(f)(c)
|
||||||
|
case Right(Right(b)) => Right(b)
|
||||||
override def raiseError[A](e: Throwable): M[A] = _ => Left(e)
|
override def raiseError[A](e: Throwable): M[A] = _ => Left(e)
|
||||||
override def handleErrorWith[A](fa: M[A])(f: Throwable => M[A]): M[A] = c => fa(c) match
|
override def handleErrorWith[A](fa: M[A])(f: Throwable => M[A]): M[A] = c =>
|
||||||
case Left(e) => f(e)(c)
|
fa(c) match
|
||||||
case Right(a) => Right(a)
|
case Left(e) => f(e)(c)
|
||||||
|
case Right(a) => Right(a)
|
||||||
|
|
||||||
given Ask[M, Config] = new Ask[M, Config]:
|
given Ask[M, Config] = new Ask[M, Config]:
|
||||||
override def applicative: Applicative[M] = MonadThrow[M]
|
override def applicative: Applicative[M] = MonadThrow[M]
|
||||||
|
@ -78,41 +79,41 @@ class Tests extends AnyFlatSpec with Matchers:
|
||||||
|
|
||||||
it should "correct findAll config propagation" in {
|
it should "correct findAll config propagation" in {
|
||||||
val repository = UserRepositoryDao[M](dao(List.empty))
|
val repository = UserRepositoryDao[M](dao(List.empty))
|
||||||
val config = Config(42)
|
val config = Config(42)
|
||||||
repository.findAll(config)
|
repository.findAll(config)
|
||||||
lastConfig shouldBe Right(Config(42))
|
lastConfig shouldBe Right(Config(42))
|
||||||
}
|
}
|
||||||
|
|
||||||
it should "correct create config propagation" in {
|
it should "correct create config propagation" in {
|
||||||
val repository = UserRepositoryDao[M](dao(List.empty))
|
val repository = UserRepositoryDao[M](dao(List.empty))
|
||||||
val config = Config(43)
|
val config = Config(43)
|
||||||
repository.create(UserName("Subject #0"), Age(0), Set.empty)(config)
|
repository.create(UserName("Subject #0"), Age(0), Set.empty)(config)
|
||||||
lastConfig shouldBe Right(Config(43))
|
lastConfig shouldBe Right(Config(43))
|
||||||
}
|
}
|
||||||
|
|
||||||
it should "correct delete config propagation" in {
|
it should "correct delete config propagation" in {
|
||||||
val repository = UserRepositoryDao[M](dao(List.empty))
|
val repository = UserRepositoryDao[M](dao(List.empty))
|
||||||
val config = Config(44)
|
val config = Config(44)
|
||||||
repository.delete(UserId(0))(config)
|
repository.delete(UserId(0))(config)
|
||||||
lastConfig shouldBe Right(Config(44))
|
lastConfig shouldBe Right(Config(44))
|
||||||
}
|
}
|
||||||
|
|
||||||
it should "correct update config propagation" in {
|
it should "correct update config propagation" in {
|
||||||
val repository = UserRepositoryDao[M](dao(List.empty))
|
val repository = UserRepositoryDao[M](dao(List.empty))
|
||||||
val config = Config(45)
|
val config = Config(45)
|
||||||
repository.update(User(UserId(0), UserName("Subject #0"), Age(0), Set.empty))(config)
|
repository.update(User(UserId(0), UserName("Subject #0"), Age(0), Set.empty))(config)
|
||||||
lastConfig shouldBe Right(Config(45))
|
lastConfig shouldBe Right(Config(45))
|
||||||
}
|
}
|
||||||
|
|
||||||
it should "correct return all users" in {
|
it should "correct return all users" in {
|
||||||
val repository = UserRepositoryDao[M](dao(sampleUsers))
|
val repository = UserRepositoryDao[M](dao(sampleUsers))
|
||||||
val config = Config(46)
|
val config = Config(46)
|
||||||
repository.findAll(config) shouldBe Right(sampleUsers.toSet.toList)
|
repository.findAll(config) shouldBe Right(sampleUsers.toSet.toList)
|
||||||
}
|
}
|
||||||
|
|
||||||
it should "correct create new user" in {
|
it should "correct create new user" in {
|
||||||
val repository = UserRepositoryDao[M](dao(sampleUsers))
|
val repository = UserRepositoryDao[M](dao(sampleUsers))
|
||||||
val config = Config(46)
|
val config = Config(46)
|
||||||
repository.create(UserName("New subject"), Age(0), Set.empty)(config) shouldBe Right(
|
repository.create(UserName("New subject"), Age(0), Set.empty)(config) shouldBe Right(
|
||||||
User(UserId(5), UserName("New subject"), Age(0), Set.empty)
|
User(UserId(5), UserName("New subject"), Age(0), Set.empty)
|
||||||
)
|
)
|
||||||
|
@ -120,30 +121,31 @@ class Tests extends AnyFlatSpec with Matchers:
|
||||||
|
|
||||||
it should "not create user more than once" in {
|
it should "not create user more than once" in {
|
||||||
val repository = UserRepositoryDao[M](dao(sampleUsers))
|
val repository = UserRepositoryDao[M](dao(sampleUsers))
|
||||||
val config = Config(46)
|
val config = Config(46)
|
||||||
repository.create(UserName("Subject #2"), Age(0), Set.empty)(config) shouldBe a [Left[Throwable, User]]
|
repository.create(UserName("Subject #2"), Age(0), Set.empty)(config) shouldBe a[Left[Throwable, User]]
|
||||||
}
|
}
|
||||||
|
|
||||||
it should "delete existing user" in {
|
it should "delete existing user" in {
|
||||||
val repository = UserRepositoryDao[M](dao(sampleUsers))
|
val repository = UserRepositoryDao[M](dao(sampleUsers))
|
||||||
val config = Config(46)
|
val config = Config(46)
|
||||||
repository.delete(UserId(2))(config) shouldBe Right(())
|
repository.delete(UserId(2))(config) shouldBe Right(())
|
||||||
}
|
}
|
||||||
|
|
||||||
it should "not delete nonexistent user" in {
|
it should "not delete nonexistent user" in {
|
||||||
val repository = UserRepositoryDao[M](dao(sampleUsers))
|
val repository = UserRepositoryDao[M](dao(sampleUsers))
|
||||||
val config = Config(46)
|
val config = Config(46)
|
||||||
repository.delete(UserId(42))(config) shouldBe a [Left[Throwable, Unit]]
|
repository.delete(UserId(42))(config) shouldBe a[Left[Throwable, Unit]]
|
||||||
}
|
}
|
||||||
|
|
||||||
it should "update existing user" in {
|
it should "update existing user" in {
|
||||||
val repository = UserRepositoryDao[M](dao(sampleUsers))
|
val repository = UserRepositoryDao[M](dao(sampleUsers))
|
||||||
val config = Config(46)
|
val config = Config(46)
|
||||||
repository.update(User(UserId(2), UserName("Subject #2"), Age(42), Set.empty))(config) shouldBe Right(())
|
repository.update(User(UserId(2), UserName("Subject #2"), Age(42), Set.empty))(config) shouldBe Right(())
|
||||||
}
|
}
|
||||||
|
|
||||||
it should "not update nonexistent user" in {
|
it should "not update nonexistent user" in {
|
||||||
val repository = UserRepositoryDao[M](dao(sampleUsers))
|
val repository = UserRepositoryDao[M](dao(sampleUsers))
|
||||||
val config = Config(46)
|
val config = Config(46)
|
||||||
repository.update(User(UserId(22), UserName("Subject #22"), Age(42), Set.empty))(config) shouldBe a [Left[Throwable, Unit]]
|
repository
|
||||||
|
.update(User(UserId(22), UserName("Subject #22"), Age(42), Set.empty))(config) shouldBe a[Left[Throwable, Unit]]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue