update ktlint
This commit is contained in:
6
.editorconfig
Normal file
6
.editorconfig
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
[*.{kt,kts}]
|
||||||
|
ktlint_code_style = ktlint_official
|
||||||
|
ktlint_standard = enabled
|
||||||
|
ktlint_experimental = enabled
|
||||||
|
ktlint_standard_string-template-indent = disabled
|
||||||
|
ktlint_standard_multiline-expression-wrapping = disabled
|
||||||
@@ -10,7 +10,9 @@ sealed interface AggregateId {
|
|||||||
|
|
||||||
@JvmInline
|
@JvmInline
|
||||||
@Serializable(with = GameIdSerializer::class)
|
@Serializable(with = GameIdSerializer::class)
|
||||||
value class GameId(override val id: UUID = UUID.randomUUID()) : AggregateId {
|
value class GameId(
|
||||||
|
override val id: UUID = UUID.randomUUID(),
|
||||||
|
) : AggregateId {
|
||||||
constructor(id: String) : this(UUID.fromString(id))
|
constructor(id: String) : this(UUID.fromString(id))
|
||||||
|
|
||||||
override fun toString(): String = id.toString()
|
override fun toString(): String = id.toString()
|
||||||
|
|||||||
@@ -8,9 +8,7 @@ data class Game(
|
|||||||
val id: GameId,
|
val id: GameId,
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
fun new(): Game {
|
fun new(): Game = Game(GameId())
|
||||||
return Game(GameId())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ import java.util.UUID
|
|||||||
|
|
||||||
@JvmInline
|
@JvmInline
|
||||||
@Serializable(with = CommandIdSerializer::class)
|
@Serializable(with = CommandIdSerializer::class)
|
||||||
value class CommandId(private val id: UUID = UUID.randomUUID()) {
|
value class CommandId(
|
||||||
|
private val id: UUID = UUID.randomUUID(),
|
||||||
|
) {
|
||||||
constructor(id: String) : this(UUID.fromString(id))
|
constructor(id: String) : this(UUID.fromString(id))
|
||||||
|
|
||||||
override fun toString(): String = id.toString()
|
override fun toString(): String = id.toString()
|
||||||
|
|||||||
@@ -18,11 +18,7 @@ class CommandStream {
|
|||||||
commands.forEach { sendRequest(it) }
|
commands.forEach { sendRequest(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun readNext(): Command? {
|
fun readNext(): Command? = commandBus.firstOrNull()
|
||||||
return commandBus.firstOrNull()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <U : Command> readNext(commandClass: Class<U>): U? {
|
fun <U : Command> readNext(commandClass: Class<U>): U? = commandBus.filterIsInstance(commandClass).firstOrNull()
|
||||||
return commandBus.filterIsInstance(commandClass).firstOrNull()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,11 +21,7 @@ class EventStream<ID : AggregateId> {
|
|||||||
fun <U : Event<ID>> read(
|
fun <U : Event<ID>> read(
|
||||||
aggregateId: ID,
|
aggregateId: ID,
|
||||||
eventClass: Class<U>,
|
eventClass: Class<U>,
|
||||||
): U? {
|
): U? = eventBus.get(aggregateId)?.filterIsInstance(eventClass)?.firstOrNull()
|
||||||
return eventBus.get(aggregateId)?.filterIsInstance(eventClass)?.firstOrNull()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <reified U : Event<ID>, ID : AggregateId> EventStream<ID>.read(aggregateId: ID): U? {
|
inline fun <reified U : Event<ID>, ID : AggregateId> EventStream<ID>.read(aggregateId: ID): U? = this.read(aggregateId, U::class.java)
|
||||||
return this.read(aggregateId, U::class.java)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -26,14 +26,20 @@ class Game(
|
|||||||
) {
|
) {
|
||||||
@Serializable
|
@Serializable
|
||||||
@Resource("card")
|
@Resource("card")
|
||||||
class Card(val game: Game) {
|
class Card(
|
||||||
|
val game: Game,
|
||||||
|
) {
|
||||||
@Serializable
|
@Serializable
|
||||||
@Resource("")
|
@Resource("")
|
||||||
class PutCard(val card: Card)
|
class PutCard(
|
||||||
|
val card: Card,
|
||||||
|
)
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@Resource("last")
|
@Resource("last")
|
||||||
class LastCard(val card: Card)
|
class LastCard(
|
||||||
|
val card: Card,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,7 +53,8 @@ fun Routing.card() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get<Game.Card.LastCard> {
|
get<Game.Card.LastCard> {
|
||||||
eventStream.read<PlayCardEvent, GameId>(it.card.game.id)
|
eventStream
|
||||||
|
.read<PlayCardEvent, GameId>(it.card.game.id)
|
||||||
?.let { it1 -> call.respond<Card>(it1.card) }
|
?.let { it1 -> call.respond<Card>(it1.card) }
|
||||||
?: call.response.status(HttpStatusCode.BadRequest)
|
?: call.response.status(HttpStatusCode.BadRequest)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,9 @@ import org.koin.ktor.ext.inject
|
|||||||
@Resource("/command")
|
@Resource("/command")
|
||||||
class CommandRoute {
|
class CommandRoute {
|
||||||
@Resource("send")
|
@Resource("send")
|
||||||
class Send(val commandRoute: CommandRoute) {
|
class Send(
|
||||||
|
val commandRoute: CommandRoute,
|
||||||
|
) {
|
||||||
@Serializable
|
@Serializable
|
||||||
data class Response(
|
data class Response(
|
||||||
val id: CommandId,
|
val id: CommandId,
|
||||||
@@ -29,7 +31,9 @@ class CommandRoute {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Resource("next")
|
@Resource("next")
|
||||||
class Next(val commandRoute: CommandRoute)
|
class Next(
|
||||||
|
val commandRoute: CommandRoute,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Routing.command() {
|
fun Routing.command() {
|
||||||
|
|||||||
@@ -20,7 +20,9 @@ fun Application.configureHTTP() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BadRequestException(val httpError: HttpErrorBadRequest) : Exception()
|
class BadRequestException(
|
||||||
|
val httpError: HttpErrorBadRequest,
|
||||||
|
) : Exception()
|
||||||
|
|
||||||
class HttpErrorBadRequest(
|
class HttpErrorBadRequest(
|
||||||
statusCode: HttpStatusCode,
|
statusCode: HttpStatusCode,
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ fun Application.configureSockets() {
|
|||||||
masking = false
|
masking = false
|
||||||
}
|
}
|
||||||
routing {
|
routing {
|
||||||
webSocket("/ws") { // websocketSession
|
webSocket("/ws") {
|
||||||
|
// websocketSession
|
||||||
for (frame in incoming) {
|
for (frame in incoming) {
|
||||||
if (frame is Frame.Text) {
|
if (frame is Frame.Text) {
|
||||||
val text = frame.readText()
|
val text = frame.readText()
|
||||||
|
|||||||
@@ -22,48 +22,48 @@ import org.koin.java.KoinJavaComponent.getKoin
|
|||||||
import org.koin.ktor.ext.inject
|
import org.koin.ktor.ext.inject
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
class CardTest : FunSpec({
|
class CardTest :
|
||||||
test("/game/{id}/card") {
|
FunSpec({
|
||||||
testApplication {
|
test("/game/{id}/card") {
|
||||||
val client = httpClient()
|
testApplication {
|
||||||
application {
|
application {
|
||||||
stopKoin()
|
stopKoin()
|
||||||
module()
|
module()
|
||||||
}
|
}
|
||||||
val id = GameId()
|
val id = GameId()
|
||||||
val card: Card = Card.Simple(1, Card.Color.Blue)
|
val card: Card = Card.Simple(1, Card.Color.Blue)
|
||||||
client.post("/game/$id/card") {
|
httpClient()
|
||||||
contentType(Json)
|
.post("/game/$id/card") {
|
||||||
accept(Json)
|
contentType(Json)
|
||||||
setBody(card)
|
accept(Json)
|
||||||
}.apply {
|
setBody(card)
|
||||||
assertEquals(HttpStatusCode.OK, status, message = bodyAsText())
|
}.apply {
|
||||||
|
assertEquals(HttpStatusCode.OK, status, message = bodyAsText())
|
||||||
|
|
||||||
val eventStream = getKoin().get<EventStream<GameId>>()
|
val eventStream = getKoin().get<EventStream<GameId>>()
|
||||||
assertEquals(PlayCardEvent(id, card), eventStream.read<PlayCardEvent, GameId>(id))
|
assertEquals(PlayCardEvent(id, card), eventStream.read<PlayCardEvent, GameId>(id))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
test("/game/{id}/card/last") {
|
test("/game/{id}/card/last") {
|
||||||
testApplication {
|
testApplication {
|
||||||
val client = httpClient()
|
val id = GameId()
|
||||||
val id = GameId()
|
val card: Card = Card.Simple(1, Card.Color.Blue)
|
||||||
val card: Card = Card.Simple(1, Card.Color.Blue)
|
application {
|
||||||
application {
|
stopKoin()
|
||||||
stopKoin()
|
module()
|
||||||
module()
|
val eventStream by inject<EventStream<GameId>>()
|
||||||
val eventStream by inject<EventStream<GameId>>()
|
eventStream.publish(
|
||||||
eventStream.publish(
|
PlayCardEvent(GameId(), Card.Simple(2, Card.Color.Yellow)),
|
||||||
PlayCardEvent(GameId(), Card.Simple(2, Card.Color.Yellow)),
|
PlayCardEvent(id, card),
|
||||||
PlayCardEvent(id, card),
|
)
|
||||||
)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
client.get("/game/$id/card/last").apply {
|
httpClient().get("/game/$id/card/last").apply {
|
||||||
assertEquals(HttpStatusCode.OK, status, message = bodyAsText())
|
assertEquals(HttpStatusCode.OK, status, message = bodyAsText())
|
||||||
assertEquals(card, this.call.body<Card>())
|
assertEquals(card, this.call.body<Card>())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
})
|
|
||||||
|
|||||||
@@ -22,47 +22,49 @@ import org.koin.java.KoinJavaComponent.getKoin
|
|||||||
import org.koin.ktor.ext.inject
|
import org.koin.ktor.ext.inject
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
class CommandTest : FunSpec({
|
class CommandTest :
|
||||||
test("/command/send") {
|
FunSpec({
|
||||||
testApplication {
|
test("/command/send") {
|
||||||
val client = httpClient()
|
testApplication {
|
||||||
application {
|
val client = httpClient()
|
||||||
stopKoin()
|
application {
|
||||||
module()
|
stopKoin()
|
||||||
}
|
module()
|
||||||
val command = PlayCardCommand(Game.new(), Card.Simple(1, Card.Color.Blue))
|
}
|
||||||
client.post("/command/send") {
|
val command = PlayCardCommand(Game.new(), Card.Simple(1, Card.Color.Blue))
|
||||||
contentType(Json)
|
client
|
||||||
accept(Json)
|
.post("/command/send") {
|
||||||
setBody(command)
|
contentType(Json)
|
||||||
}.apply {
|
accept(Json)
|
||||||
assertEquals(HttpStatusCode.OK, status, message = bodyAsText())
|
setBody(command)
|
||||||
|
}.apply {
|
||||||
|
assertEquals(HttpStatusCode.OK, status, message = bodyAsText())
|
||||||
|
|
||||||
val commandStream = getKoin().get<CommandStream>()
|
val commandStream = getKoin().get<CommandStream>()
|
||||||
assertEquals(command, commandStream.readNext())
|
assertEquals(command, commandStream.readNext())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
test("/command/next") {
|
test("/command/next") {
|
||||||
testApplication {
|
testApplication {
|
||||||
val command =
|
val command =
|
||||||
PlayCardCommand(
|
PlayCardCommand(
|
||||||
Game.new(),
|
Game.new(),
|
||||||
Card.Simple(1, Card.Color.Blue),
|
Card.Simple(1, Card.Color.Blue),
|
||||||
)
|
)
|
||||||
application {
|
application {
|
||||||
stopKoin()
|
stopKoin()
|
||||||
module()
|
module()
|
||||||
|
|
||||||
val commandStream by inject<CommandStream>()
|
val commandStream by inject<CommandStream>()
|
||||||
commandStream.sendRequest(command)
|
commandStream.sendRequest(command)
|
||||||
}
|
}
|
||||||
|
|
||||||
httpClient().get("/command/next").apply {
|
httpClient().get("/command/next").apply {
|
||||||
assertEquals(HttpStatusCode.OK, status, message = bodyAsText())
|
assertEquals(HttpStatusCode.OK, status, message = bodyAsText())
|
||||||
assertEquals(command, this.call.body<Command>())
|
assertEquals(command, this.call.body<Command>())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
})
|
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ import kotlinx.serialization.json.Json
|
|||||||
import kotlinx.serialization.modules.SerializersModule
|
import kotlinx.serialization.modules.SerializersModule
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
fun ApplicationTestBuilder.httpClient(): HttpClient {
|
fun ApplicationTestBuilder.httpClient(): HttpClient =
|
||||||
return createClient {
|
createClient {
|
||||||
install(ContentNegotiation) {
|
install(ContentNegotiation) {
|
||||||
json(
|
json(
|
||||||
Json {
|
Json {
|
||||||
@@ -22,4 +22,3 @@ fun ApplicationTestBuilder.httpClient(): HttpClient {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user