Skip to content

Commit

Permalink
Migrate to Ktor 2.0.0 (#11)
Browse files Browse the repository at this point in the history
move to ktor 2.0.0 and update dependencies, packages and testing.
  • Loading branch information
KamilKurde authored Apr 16, 2022
1 parent 1d531a1 commit 8715958
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 54 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,12 @@ repositories {
}
dependencies {
implementation 'com.github.aymanizz:ktor-i18n:1.0.0'
implementation 'com.github.aymanizz:ktor-i18n:VERSION'
}
```
where "VERSION" is dependent on the ktor version you are using.
If you are using ktor 2.0.0 or newer, use version 2.0.0.
If you are using older ktor versions, use version 1.0.0.

#### Usage Example

Expand Down
30 changes: 6 additions & 24 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,28 +1,23 @@
import org.gradle.jvm.tasks.Jar
import org.jetbrains.dokka.gradle.DokkaTask
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
kotlin("jvm") version "1.3.70"
kotlin("jvm") version "1.6.20"
`maven-publish`
id("org.jetbrains.dokka") version "0.10.1"
id("com.diffplug.gradle.spotless") version "4.4.0"
id("com.diffplug.spotless") version "6.4.2"
}

group = "com.github.aymanizz"
version = "1.0.0"
version = "2.0.0"

repositories {
mavenCentral()
maven("https://dl.bintray.com/kotlin/ktor")
maven("https://dl.bintray.com/kotlin/dokka")
}

dependencies {
implementation(kotlin("stdlib"))
implementation("io.ktor:ktor-server-core:1.3.1")
testImplementation("io.ktor:ktor-server-test-host:1.3.1")
testImplementation("org.junit.jupiter:junit-jupiter:5.6.2")
implementation("io.ktor:ktor-server-core:2.0.0")
testImplementation("io.ktor:ktor-server-test-host:2.0.0")
testImplementation("org.jetbrains.kotlin:kotlin-test:1.6.20")
}

tasks.withType<KotlinCompile>().configureEach {
Expand All @@ -34,18 +29,6 @@ tasks.test {
useJUnitPlatform()
}

tasks.getting(DokkaTask::class) {
outputFormat = "html"
outputDirectory = "$buildDir/javadoc"
}

val dokkaJar by tasks.creating(Jar::class) {
group = JavaBasePlugin.DOCUMENTATION_GROUP
description = "Assembles Kotlin docs with Dokka"
archiveClassifier.set("javadoc")
from(tasks.dokka)
}

java.withSourcesJar()

spotless {
Expand Down Expand Up @@ -78,7 +61,6 @@ publishing {
publications {
create<MavenPublication>("ktor-i18n") {
from(components["java"])
artifact(dokkaJar)
}
}
}
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-6.5-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
31 changes: 16 additions & 15 deletions src/main/kotlin/com/github/aymanizz/ktori18n/I18n.kt
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
package com.github.aymanizz.ktori18n

import com.github.aymanizz.ktori18n.I18n.Configuration
import io.ktor.application.Application
import io.ktor.application.ApplicationCall
import io.ktor.application.ApplicationCallPipeline
import io.ktor.application.ApplicationFeature
import io.ktor.application.feature
import io.ktor.features.origin
import io.ktor.http.Cookie
import io.ktor.request.acceptLanguage
import io.ktor.response.respondRedirect
import io.ktor.server.application.Application
import io.ktor.server.application.ApplicationCall
import io.ktor.server.application.ApplicationCallPipeline
import io.ktor.server.application.ApplicationCallPipeline.ApplicationPhase.Plugins
import io.ktor.server.application.BaseApplicationPlugin
import io.ktor.server.application.plugin
import io.ktor.server.plugins.origin
import io.ktor.server.request.acceptLanguage
import io.ktor.server.response.respondRedirect
import io.ktor.util.AttributeKey
import io.ktor.util.pipeline.PipelineContext
import java.util.Locale
Expand Down Expand Up @@ -87,7 +88,7 @@ class I18n private constructor(configuration: Configuration) : MessageResolver b

/**
* Exclude calls matching the [predicate] from being redirected with language prefix by this feature.
* @see io.ktor.features.HttpsRedirect for example of exclusions
* @see io.ktor.server.plugins.httpsredirect for example of exclusions
*/
fun exclude(predicate: (call: ApplicationCall) -> Boolean) {
excludePredicates.add(predicate)
Expand All @@ -109,7 +110,7 @@ class I18n private constructor(configuration: Configuration) : MessageResolver b
}
}

companion object Feature : ApplicationFeature<ApplicationCallPipeline, Configuration, I18n> {
companion object Plugin : BaseApplicationPlugin<ApplicationCallPipeline, Configuration, I18n> {

override val key = AttributeKey<I18n>("I18n")

Expand All @@ -121,27 +122,27 @@ class I18n private constructor(configuration: Configuration) : MessageResolver b
}
}

val feature = I18n(configuration)
val plugin = I18n(configuration)

if (configuration.useOfRedirection) {
pipeline.intercept(ApplicationCallPipeline.Features) { feature.intercept(this) }
pipeline.intercept(Plugins) { plugin.intercept(this) }
}

return feature
return plugin
}
}
}

val Application.i18n
get() = feature(I18n)
get() = this.plugin(I18n)

private val CallLocaleKey = AttributeKey<Locale>("CallLocale")

/**
* The locale for the current call, based on accept language header, then from the optional language cookie and finally from
* the language prefix of the request path.
*
* If there is no supported locale that matches the request accept language locales, the the default locale is returned.
* If there is no supported locale that matches the request accept language locales, the default locale is returned.
*/
val ApplicationCall.locale
get() = attributes.computeIfAbsent(CallLocaleKey) locale@{
Expand Down
35 changes: 22 additions & 13 deletions src/test/kotlin/com/github/aymanizz/ktori18n/I18nTests.kt
Original file line number Diff line number Diff line change
@@ -1,41 +1,50 @@
package com.github.aymanizz.ktori18n

import io.ktor.application.install
import io.ktor.server.testing.withTestApplication
import io.ktor.server.testing.testApplication
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows
import java.util.Locale
import kotlin.test.assertEquals

internal class I18nTests {
@Test
fun `throws when supported locales is not initialized`(): Unit = withTestApplication {
assertThrows<UninitializedPropertyAccessException> { application.install(I18n) }
fun `throws when supported locales is not initialized`() {
assertThrows<UninitializedPropertyAccessException> {
testApplication {
install(I18n)
}
}
}

@Test
fun `throws when supported locales is empty`(): Unit = withTestApplication {
fun `throws when supported locales is empty`() {
assertThrows<IllegalArgumentException> {
application.install(I18n) { supportedLocales = listOf() }
testApplication {
install(I18n) { supportedLocales = listOf() }
}
}
}

@Test
fun `throws when default locale not in supported locales`(): Unit = withTestApplication {
fun `throws when default locale not in supported locales`() {
assertThrows<IllegalArgumentException> {
application.install(I18n) {
supportedLocales = listOf("en", "de").map { Locale.forLanguageTag(it) }
defaultLocale = Locale.forLanguageTag("ar")
testApplication {
install(I18n) {
supportedLocales = listOf("en", "de").map { Locale.forLanguageTag(it) }
defaultLocale = Locale.forLanguageTag("ar")
}
}
}
}

@Test
fun `default locale defaults to the first supported locale`(): Unit = withTestApplication {
fun `default locale defaults to the first supported locale`(): Unit = testApplication {
val locales = listOf("en", "ar").map { Locale.forLanguageTag(it) }
application.install(I18n) {
install(I18n) {
supportedLocales = locales
}
assertEquals(locales[0], application.i18n.defaultLocale)
this.application {
assertEquals(locales[0], i18n.defaultLocale)
}
}
}

0 comments on commit 8715958

Please sign in to comment.