Skip to content

Commit

Permalink
WIP: refs #16 testkitサブモジュールを作成
Browse files Browse the repository at this point in the history
  • Loading branch information
averak committed Nov 9, 2023
1 parent 9321c10 commit dd87820
Show file tree
Hide file tree
Showing 22 changed files with 463 additions and 28 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ SPANNER_DATABASE_ID=gsync

.PHONY: build
build:
./gradlew build -x test
./gradlew quarkusBuild

.PHONY: build_native
build_native:
Expand Down
30 changes: 12 additions & 18 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
plugins {
kotlin("jvm") version libs.versions.kotlin
kotlin("plugin.allopen") version libs.versions.kotlin

alias(libs.plugins.versions)
alias(libs.plugins.version.catalog.update)
Expand All @@ -17,15 +16,8 @@ plugins {
idea
}

buildscript {
dependencies {
classpath("com.github.ben-manes:gradle-versions-plugin:0.47.0")
}
}

repositories {
mavenCentral()
mavenLocal()
gradlePluginPortal()
}

Expand Down Expand Up @@ -55,27 +47,28 @@ dependencies {
implementation(libs.jackson.module.kotlin)

// Test Framework & utils
testImplementation(project(":testkit"))
testImplementation(libs.quarkus.junit5)
testImplementation(libs.spock.core)
testImplementation(libs.spock.junit4)
testImplementation(libs.groovy)
testImplementation(libs.groovy.sql)
testImplementation(libs.easy.random)
}

java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}

kotlin {
jvmToolchain(17)
}

allOpen {
annotation("jakarta.ws.rs.Path")
annotation("jakarta.enterprise.context.ApplicationScoped")
annotation("io.quarkus.test.junit.QuarkusTest")
sourceSets {
all {
languageSettings {
languageVersion = "2.0"
}
}
}
}

spotless {
Expand All @@ -93,6 +86,7 @@ sonar {
property("sonar.projectKey", "averak_gsync")
property("sonar.organization", "averak")
property("sonar.host.url", "https://sonarcloud.io")
property("sonar.exclusions", "testkit/**")
}
}

Expand Down
4 changes: 2 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
[versions]
easy-random = "6.2.1"
groovy = "4.0.7"
kotlin = "1.9.10"
kotlin = "1.9.20"
quarkus = "3.5.0"
spock = "2.4-M1-groovy-4.0"

[libraries]
commons-lang3 = "org.apache.commons:commons-lang3:3.13.0"
easy-random = { module = "io.github.dvgaba:easy-random-core", version.ref = "easy-random" }
groovy = { module = "org.apache.groovy:groovy", version.ref = "groovy" }
groovy-sql = { module = "org.apache.groovy:groovy-sql", version.ref = "groovy" }
Expand All @@ -23,7 +24,6 @@ quarkus-logging-json = { module = "io.quarkus:quarkus-logging-json", version.ref
quarkus-resteasy-reactive = { module = "io.quarkus:quarkus-resteasy-reactive", version.ref = "quarkus" }
quarkus-resteasy-reactive-jackson = { module = "io.quarkus:quarkus-resteasy-reactive-jackson", version.ref = "quarkus" }
spock-core = { module = "org.spockframework:spock-core", version.ref = "spock" }
spock-junit4 = { module = "org.spockframework:spock-junit4", version.ref = "spock" }

[plugins]
gradle-git-properties = "com.gorylenko.gradle-git-properties:2.4.1"
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
1 change: 1 addition & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
rootProject.name = "gsync"
include(":testkit")
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import net.averak.gsync.core.exception.ErrorCode

data class ErrorResponse(
val code: String,
val description: String,
val summary: String,
) {
constructor(errorCode: ErrorCode) : this(errorCode.name, errorCode.description)
constructor(errorCode: ErrorCode) : this(errorCode.name, errorCode.summary)
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
package net.averak.gsync.adapter.handler.exception

import jakarta.ws.rs.NotFoundException
import jakarta.ws.rs.core.MediaType
import jakarta.ws.rs.core.Response
import jakarta.ws.rs.ext.ExceptionMapper
import jakarta.ws.rs.ext.Provider
import net.averak.gsync.core.exception.ErrorCode
import org.apache.http.HttpStatus

@Provider
class NotFoundExceptionMapper : ExceptionMapper<NotFoundException> {
override fun toResponse(exception: NotFoundException?): Response {
return Response.status(HttpStatus.SC_NOT_FOUND).entity(ErrorResponse(ErrorCode.NOT_FOUND_API)).build()
return Response
.status(Response.Status.NOT_FOUND)
.type(MediaType.APPLICATION_JSON_TYPE)
.entity(ErrorResponse(ErrorCode.NOT_FOUND_API))
.build()
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package net.averak.gsync.core.exception

enum class ErrorCode(val description: String) {
enum class ErrorCode(val summary: String) {
// 400 Bad Request
VALIDATION_ERROR("Request validation exception was thrown."),
INVALID_REQUEST_PARAMETERS("Request parameters is invalid."),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package net.averak.gsync.core.exception

class GsyncException(val errorCode: ErrorCode, val causedBy: Throwable?) : RuntimeException(errorCode.summary, causedBy) {
constructor(errorCode: ErrorCode) : this(errorCode, null)
}
16 changes: 16 additions & 0 deletions src/main/kotlin/net/averak/gsync/domain/model/Echo.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package net.averak.gsync.domain.model

import net.averak.gsync.domain.primitive.common.ID
import java.time.LocalDateTime

data class Echo(
val id: ID,
val message: String,
val timestamp: LocalDateTime,
) {
constructor(message: String) : this(
ID(),
message,
LocalDateTime.now(),
)
}
17 changes: 17 additions & 0 deletions src/main/kotlin/net/averak/gsync/domain/primitive/common/ID.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package net.averak.gsync.domain.primitive.common

import net.averak.gsync.core.exception.ErrorCode
import net.averak.gsync.core.exception.GsyncException
import java.util.UUID

data class ID(val value: String) {
init {
try {
UUID.fromString(value)
} catch (_: IllegalArgumentException) {
throw GsyncException(ErrorCode.ID_FORMAT_IS_INVALID)
}
}

constructor() : this(UUID.randomUUID().toString())
}
11 changes: 11 additions & 0 deletions src/main/kotlin/net/averak/gsync/usecase/EchoUsecase.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package net.averak.gsync.usecase

import jakarta.inject.Singleton
import net.averak.gsync.domain.model.Echo

@Singleton
class EchoUsecase {
fun echo(message: String): Echo {
return Echo(message)
}
}
23 changes: 23 additions & 0 deletions src/test/groovy/net/averak/gsync/AbstractSpec.groovy
Original file line number Diff line number Diff line change
@@ -1,8 +1,31 @@
package net.averak.gsync

import io.quarkus.arc.All
import io.quarkus.test.junit.QuarkusTest
import jakarta.annotation.PostConstruct
import jakarta.inject.Inject
import net.averak.gsync.core.exception.GsyncException
import net.averak.gsync.testkit.Faker
import net.averak.gsync.testkit.IRandomizer
import spock.lang.Specification

@QuarkusTest
abstract class AbstractSpec extends Specification {

@Inject
@All
List<IRandomizer> randomizers

@PostConstruct
void init() {
Faker.init(randomizers)
}

/**
* 例外を検証
*/
static void verify(final GsyncException actual, final GsyncException expected) {
assert actual.errorCode == expected.errorCode
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ package net.averak.gsync.adapter.handler.controller

import net.averak.gsync.AbstractSpec

class AbstractController_IT extends AbstractSpec {
abstract class AbstractController_IT extends AbstractSpec {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package net.averak.gsync.domain.primitive.common

import net.averak.gsync.AbstractSpec
import net.averak.gsync.core.exception.ErrorCode
import net.averak.gsync.core.exception.GsyncException
import net.averak.gsync.testkit.Faker

class ID_UT extends AbstractSpec {

def "constructor: 正常に作成できる"() {
when:
new ID(value)

then:
noExceptionThrown()

where:
value << [
Faker.uuidv4(),
Faker.uuidv5("1"),
]
}

def "ID: 制約違反の場合は例外を返す"() {
when:
new ID(value)

then:
final exception = thrown(GsyncException)
verify(exception, new GsyncException(ErrorCode.ID_FORMAT_IS_INVALID))

where:
value << [
Faker.alphanumeric(36),
Faker.uuidv4() + "A",
]
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package net.averak.gsync.randomizer.domain.primitive.common

import net.averak.gsync.domain.primitive.common.ID
import net.averak.gsync.testkit.IRandomizer

@Singleton
class IDRandomizer implements IRandomizer {

final Class typeToGenerate = ID.class

@Override
Object getRandomValue() {
return new ID()
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package net.averak.gsync.usecase

import net.averak.gsync.AbstractSpec

abstract class AbstractUsecase_UT extends AbstractSpec {
}
21 changes: 21 additions & 0 deletions src/test/groovy/net/averak/gsync/usecase/EchoUsecase_UT.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package net.averak.gsync.usecase

import jakarta.inject.Inject
import net.averak.gsync.testkit.Faker

class EchoUsecase_Echo_UT extends AbstractUsecase_UT {

@Inject
EchoUsecase sut

def "echo: 正常系 Echoを作成できる"() {
given:
final message = Faker.alphanumeric()

when:
final result = sut.echo(message)

then:
result.message == message
}
}
24 changes: 24 additions & 0 deletions testkit/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
plugins {
kotlin("jvm") version libs.versions.kotlin
}

repositories {
mavenCentral()
}

dependencies {
implementation(libs.groovy.sql)
implementation(libs.easy.random)
implementation(libs.commons.lang3)
implementation(libs.guava)
}

kotlin {
sourceSets {
all {
languageSettings {
languageVersion = "2.0"
}
}
}
}
Loading

0 comments on commit dd87820

Please sign in to comment.