Skip to content

Commit

Permalink
Add end2end KxS tests for a basic OpenAPI
Browse files Browse the repository at this point in the history
  • Loading branch information
ulrikandersen committed Oct 17, 2024
1 parent 11e46f4 commit ad489c7
Show file tree
Hide file tree
Showing 4 changed files with 301 additions and 0 deletions.
71 changes: 71 additions & 0 deletions end2end-tests/models-kotlinx/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
val fabrikt: Configuration by configurations.creating

val generationDir = "$buildDir/generated"
val apiFile = "$projectDir/openapi/api.yaml"

sourceSets {
main { java.srcDirs("$generationDir/src/main/kotlin") }
test { java.srcDirs("$generationDir/src/test/kotlin") }
}

plugins {
id("org.jetbrains.kotlin.jvm") version "1.8.20" // Apply the Kotlin JVM plugin to add support for Kotlin.
kotlin("plugin.serialization") version "1.8.20"
}

java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}

val jacksonVersion: String by rootProject.extra
val junitVersion: String by rootProject.extra

dependencies {
implementation("jakarta.validation:jakarta.validation-api:3.0.2")
implementation("javax.validation:validation-api:2.0.1.Final")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin:$jacksonVersion")
implementation("com.fasterxml.jackson.core:jackson-databind:$jacksonVersion")
implementation("com.fasterxml.jackson.core:jackson-core:$jacksonVersion")
implementation("com.fasterxml.jackson.core:jackson-annotations:$jacksonVersion")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3")

testImplementation("org.junit.jupiter:junit-jupiter-api:$junitVersion")
testImplementation("org.junit.jupiter:junit-jupiter-engine:$junitVersion")
testImplementation("org.junit.jupiter:junit-jupiter-params:$junitVersion")
testImplementation("org.assertj:assertj-core:3.24.2")
}

tasks {

val generateCode by creating(JavaExec::class) {
inputs.files(apiFile)
outputs.dir(generationDir)
outputs.cacheIf { true }
classpath = rootProject.files("./build/libs/fabrikt-${rootProject.version}.jar")
mainClass.set("com.cjbooms.fabrikt.cli.CodeGen")
args = listOf(
"--output-directory", generationDir,
"--base-package", "com.example",
"--api-file", apiFile,
"--validation-library", "NO_VALIDATION",
"--targets", "http_models",
"--serialization-library", "KOTLINX_SERIALIZATION",
"--http-model-opts", "SEALED_INTERFACES_FOR_ONE_OF",
)
dependsOn(":jar")
dependsOn(":shadowJar")
}

withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
kotlinOptions.jvmTarget = "17"
dependsOn(generateCode)
}


withType<Test> {
useJUnitPlatform()
jvmArgs = listOf("--add-opens=java.base/java.lang=ALL-UNNAMED", "--add-opens=java.base/java.util=ALL-UNNAMED")

}
}
133 changes: 133 additions & 0 deletions end2end-tests/models-kotlinx/openapi/api.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
openapi: "3.0.0"
info:
version: 1.0.0
title: Swagger Petstore
license:
name: MIT
servers:
- url: http://petstore.swagger.io/v1
paths:
/pets:
get:
summary: List all pets
operationId: listPets
tags:
- pets
parameters:
- name: limit
in: query
description: How many items to return at one time (max 100)
required: false
schema:
type: integer
maximum: 100
format: int32
responses:
'200':
description: A paged array of pets
headers:
x-next:
description: A link to the next page of responses
schema:
type: string
content:
application/json:
schema:
$ref: "#/components/schemas/Pets"
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
post:
summary: Create a pet
operationId: createPets
tags:
- pets
responses:
'201':
description: Null response
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/pets/{petId}:
get:
summary: Info for a specific pet
operationId: showPetById
tags:
- pets
parameters:
- name: petId
in: path
required: true
description: The id of the pet to retrieve
schema:
type: string
responses:
'200':
description: Expected response to a valid request
content:
application/json:
schema:
$ref: "#/components/schemas/Pet"
components:
schemas:
Pet:
type: object
required:
- id
- name
properties:
id:
type: integer
format: int64
name:
type: string
tag:
type: string
Pets:
type: array
maxItems: 100
items:
$ref: "#/components/schemas/Pet"
Phone:
oneOf:
- $ref: "#/components/schemas/LandlinePhone"
- $ref: "#/components/schemas/MobilePhone"
discriminator:
propertyName: type
mapping:
landline: '#/components/schemas/LandlinePhone'
mobile: '#/components/schemas/MobilePhone'
LandlinePhone:
type: object
required:
- number
- area_code
properties:
number:
type: string
area_code:
type: string
MobilePhone:
type: object
required:
- number
properties:
number:
type: string
Error:
type: object
required:
- code
- message
properties:
code:
type: integer
format: int32
message:
type: string
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.cjbooms.fabrikt.models.kotlinx

import com.example.models.LandlinePhone
import com.example.models.Phone
import kotlinx.serialization.encodeToString
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test

class KotlinxSerializationOneOfPolymorphicTest {

@Test
fun `must serialize Phone with type info`() {
val phone: Phone = LandlinePhone(number = "1234567890", areaCode = "123")
val json = kotlinx.serialization.json.Json.encodeToString(phone)

// Note that "type" is added because we are serializing a subtype of Phone
// (See https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/polymorphism.md#sealed-classes)
assertThat(json).isEqualTo("""
{"type":"landline","number":"1234567890","area_code":"123"}
""".trimIndent())
}

@Test
fun `must serialize LandlinePhone without type info`() {
val phone: LandlinePhone = LandlinePhone(number = "1234567890", areaCode = "123")
val json = kotlinx.serialization.json.Json.encodeToString(phone)

// Note that "type" is not added because we are serializing the specific class LandlinePhone
// (See https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/polymorphism.md#sealed-classes)
assertThat(json).isEqualTo("""
{"number":"1234567890","area_code":"123"}
""".trimIndent())
}

@Test
fun `must deserialize Phone into LandlinePhone`() {
val json = """
{"type":"landline","number":"1234567890","area_code":"123"}
""".trimIndent()
val phone: Phone = kotlinx.serialization.json.Json.decodeFromString(json)
assertThat(phone).isEqualTo(LandlinePhone(number = "1234567890", areaCode = "123"))
}

@Test
fun `must deserialize LandlinePhone specific class`() {
val json = """
{"number":"1234567890","area_code":"123"}
""".trimIndent()
val phone: LandlinePhone = kotlinx.serialization.json.Json.decodeFromString(json)
assertThat(phone).isEqualTo(LandlinePhone(number = "1234567890", areaCode = "123"))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.cjbooms.fabrikt.models.kotlinx

import com.example.models.Pet
import kotlinx.serialization.encodeToString
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test

class KotlinxSerializationSimpleTest {

@Test
fun `must serialize Pet`() {
val pet = Pet(id = 1, name = "Fido", tag = "dog")
val json = kotlinx.serialization.json.Json.encodeToString(pet)
assertThat(json).isEqualTo("""
{"id":1,"name":"Fido","tag":"dog"}
""".trimIndent())
}

@Test
fun `must deserialize Pet`() {
val json = """
{"id": 1, "name": "Fido", "tag": "dog"}
""".trimIndent()
val pet: Pet = kotlinx.serialization.json.Json.decodeFromString(json)
assertThat(pet).isEqualTo(Pet(id = 1, name = "Fido", tag = "dog"))
}

@Test
fun `must serialize Pet with no tag`() {
val pet = Pet(id = 1, name = "Whiskers")
val json = kotlinx.serialization.json.Json.encodeToString(pet)
assertThat(json).isEqualTo("""
{"id":1,"name":"Whiskers"}
""".trimIndent())
}

@Test
fun `must deserialize Pet with no tag`() {
val json = """
{"id": 1, "name": "Whiskers"}
""".trimIndent()
val pet: Pet = kotlinx.serialization.json.Json.decodeFromString(json)
assertThat(pet).isEqualTo(Pet(id = 1, name = "Whiskers"))
}
}

0 comments on commit ad489c7

Please sign in to comment.