diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index a848665..5686c21 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -17,7 +17,7 @@ jobs: build: strategy: matrix: - java-version: [8, 11, 17, 21] + java-version: [ 11, 17, 20 ] os: - macos-latest - ubuntu-latest @@ -28,25 +28,27 @@ jobs: GRADLE_OPTS: "-Dorg.gradle.jvmargs=-XX:MaxMetaspaceSize=512m" steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v3 - name: Set up JDK ${{ matrix.java-version }} - uses: actions/setup-java@v4 + uses: actions/setup-java@v3 with: - distribution: "zulu" + distribution: 'zulu' java-version: ${{ matrix.java-version }} - name: Validate Gradle wrapper - uses: gradle/wrapper-validation-action@v2 + uses: gradle/wrapper-validation-action@v1 - name: Cache Kotlin Konan - uses: actions/cache@v4 + id: cache-kotlin-konan + uses: actions/cache@v3 with: - path: ~/.konan/**/* + path: | + ~/.konan/**/* key: kotlin-konan-${{ runner.os }} - - name: Set up Gradle - uses: gradle/actions/setup-gradle@v3 - - - name: Publish - run: ./gradlew check build --stacktrace -PtestsBadgeApiKey=${{ secrets.TESTS_BADGE_API_KEY }} + - name: Test with Gradle + uses: gradle/gradle-build-action@v2 + with: + gradle-home-cache-cleanup: true + arguments: build check --stacktrace -PtestsBadgeApiKey=${{ secrets.TESTS_BADGE_API_KEY }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index a930768..e89e240 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -4,41 +4,90 @@ on: workflow_dispatch: env: + JAVA_VERSION: 11 + JAVA_DISTRIBUTION: 'zulu' ORG_GRADLE_PROJECT_ossrhUsername: ${{ secrets.OSSRH_USERNAME}} ORG_GRADLE_PROJECT_ossrhPassword: ${{ secrets.OSSRH_PASSWORD}} ORG_GRADLE_PROJECT_signingKey: ${{ secrets.SIGN_SECRET_KEY }} ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.SIGN_SECRET_PWD }} -concurrency: - group: "${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}" - # Don't cancel midway through publishing if another workflow is triggered, it might cause partial publications - cancel-in-progress: false - jobs: - publish: - runs-on: macos-latest - + publish-base: + runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v3 - - name: Set up JDK - uses: actions/setup-java@v4 + - name: Set up JDK ${{ env.JAVA_VERSION }} + uses: actions/setup-java@v3 with: - java-version: "21" - distribution: "zulu" + java-version: ${{ env.JAVA_VERSION }} + distribution: ${{ env.JAVA_DISTRIBUTION }} - - name: Validate Gradle wrapper - uses: gradle/wrapper-validation-action@v2 + - uses: gradle/gradle-build-action@v2 - - name: Cache Kotlin Konan - uses: actions/cache@v4 + - name: Publish Multiplatform release + run: ./gradlew publishKotlinMultiplatformPublicationToOSSRHRepository + + - name: Publish JVM release + run: ./gradlew publishJvmPublicationToOSSRHRepository + + - name: Publish JS release + run: ./gradlew publishJsPublicationToOSSRHRepository + + publish-linux: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Set up JDK ${{ env.JAVA_VERSION }} + uses: actions/setup-java@v3 with: - path: ~/.konan/**/* - key: kotlin-konan-${{ runner.os }} + java-version: ${{ env.JAVA_VERSION }} + distribution: ${{ env.JAVA_DISTRIBUTION }} - - name: Set up Gradle - uses: gradle/actions/setup-gradle@v3 + - uses: gradle/gradle-build-action@v2 + + - name: Publish Linux x64 release + run: ./gradlew publishLinuxX64PublicationToOSSRHRepository + + publish-mac: + runs-on: macos-latest + strategy: + max-parallel: 6 + matrix: + target: + - publishMacosArm64PublicationToOSSRHRepository + - publishMacosX64PublicationToOSSRHRepository + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Set up JDK ${{ env.JAVA_VERSION }} + uses: actions/setup-java@v3 + with: + java-version: ${{ env.JAVA_VERSION }} + distribution: ${{ env.JAVA_DISTRIBUTION }} + + - uses: gradle/gradle-build-action@v2 - name: Publish - run: ./gradlew publish --no-parallel --stacktrace + run: ./gradlew ${{ matrix.target }} + + publish-windows: + runs-on: windows-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Set up JDK ${{ env.JAVA_VERSION }} + uses: actions/setup-java@v3 + with: + java-version: ${{ env.JAVA_VERSION }} + distribution: ${{ env.JAVA_DISTRIBUTION }} + + - uses: gradle/gradle-build-action@v2 + + - name: Publish MinGW x64 release + run: ./gradlew publishMingwX64PublicationToOSSRHRepository \ No newline at end of file diff --git a/README.md b/README.md index 5f3a0b6..d879d1d 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ [![License](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) -[![Kotlin](https://img.shields.io/badge/kotlin-1.6%2B-blue)](https://kotlinlang.org/) +[![Kotlin](https://img.shields.io/badge/kotlin-1.9.0-blue)](https://kotlinlang.org/) [![Nexus Snapshot](https://img.shields.io/nexus/s/net.thauvin.erik.urlencoder/urlencoder-lib?label=snapshot&server=https%3A%2F%2Foss.sonatype.org%2F)](https://oss.sonatype.org/content/repositories/snapshots/net/thauvin/erik/urlencoder/) [![Release](https://img.shields.io/github/release/ethauvin/urlencoder.svg)](https://github.com/ethauvin/urlencoder/releases/latest) [![Maven Central](https://img.shields.io/maven-central/v/net.thauvin.erik.urlencoder/urlencoder-lib)](https://central.sonatype.com/search?namespace=net.thauvin.erik.urlencoder) @@ -32,17 +32,18 @@ optimizations have a significantly beneficial impact on performance of encoding compared to other solutions like the standard `URLEncoder` in the JDK or `UriUtils` in Spring. + ## Examples (TL;DR) ```kotlin -UrlEncoderUtil.encode("a test &") // -> a%20test%20%26 -UrlEncoderUtil.encode("%#okékÉȢ smile!😁") // -> %25%23ok%C3%A9k%C3%89%C8%A2%20smile%21%F0%9F%98%81 -UrlEncoderUtil.encode("?test=a test", allow = "?=") // -> ?test=a%20test -UrlEncoderUtil.endode("foo bar", spaceToPlus = true) // -> foo+bar +UrlEncoder.encode("a test &") // -> a%20test%20%26 +UrlEncoder.encode("%#okékÉȢ smile!😁") // -> %25%23ok%C3%A9k%C3%89%C8%A2%20smile%21%F0%9F%98%81 +UrlEncoder.encode("?test=a test", allow = "?=") // -> ?test=a%20test +UrlEncoder.endode("foo bar", spaceToPlus = true) // -> foo+bar -UrlEncoderUtil.decode("a%20test%20%26") // -> a test & -UrlEncoderUtil.decode("%25%23ok%C3%A9k%C3%89%C8%A2%20smile%21%F0%9F%98%81") // -> %#okékÉȢ smile!😁 -UrlEncoderUtil.decode("foo+bar", plusToSpace = true) // -> foo bar +UrlEncoder.decode("a%20test%20%26") // -> a test & +UrlEncoder.decode("%25%23ok%C3%A9k%C3%89%C8%A2%20smile%21%F0%9F%98%81") // -> %#okékÉȢ smile!😁 +UrlEncoder.decode("foo+bar", plusToSpace = true) // -> foo bar ``` ## Gradle, Maven, etc. @@ -60,7 +61,7 @@ repositories { } dependencies { - implementation("net.thauvin.erik.urlencoder:urlencoder-lib:1.6.0") + implementation("net.thauvin.erik.urlencoder:urlencoder-lib:1.4.0") } ``` @@ -71,11 +72,11 @@ to the artifact URL. net.thauvin.erik.urlencoder urlencoder-lib-jvm - 1.6.0 + 1.4.0 ``` -Instructions for using with Ivy, etc. can be found on +Instructions for using with Ivy, etc. can be found on [Maven Central](https://central.sonatype.com/search?namespace=net.thauvin.erik.urlencoder). ## Standalone usage @@ -89,7 +90,7 @@ You have two options: The usage is as follows: -```console +``` Encode and decode URL components defensively. -e encode (default) -d decode @@ -97,7 +98,7 @@ Encode and decode URL components defensively. ### Running with Gradle -```console +```shell ./gradlew run --quiet --args="-e 'a test &'" # -> a%20test%20%26 ./gradlew run --quiet --args="%#okékÉȢ" # -> %25%23ok%C3%A9k%C3%89%C8%A2 @@ -108,13 +109,13 @@ Encode and decode URL components defensively. First build the jar file: -```console +```shell ./gradlew fatJar ``` Then run it: -```console +```shell java -jar urlencoder-app/build/libs/urlencoder-*all.jar -e "a test &" # -> a%20test%20%26 java -jar urlencoder-app/build/libs/urlencoder-*all.jar "%#okékÉȢ" # -> %25%23ok%C3%A9k%C3%89%C8%A2 diff --git a/build.gradle.kts b/build.gradle.kts index 5ccf894..a109e40 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,7 +4,7 @@ plugins { } group = "net.thauvin.erik.urlencoder" -version = "1.6.0" +version = "1.4.0" dependencies { kover(projects.urlencoderLib) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 1819780..182d281 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -3,10 +3,9 @@ plugins { } dependencies { - implementation("com.github.ben-manes:gradle-versions-plugin:0.51.0") - implementation("io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.23.7") - implementation("org.jetbrains.dokka:dokka-gradle-plugin:1.9.20") - implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.24") - implementation("org.jetbrains.kotlinx:kover-gradle-plugin:0.8.3") - implementation("org.apache.httpcomponents:httpclient:4.5.13") -} + implementation("com.github.ben-manes:gradle-versions-plugin:0.48.0") + implementation("io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.23.1") + implementation("org.jetbrains.dokka:dokka-gradle-plugin:1.9.0") + implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.0") + implementation("org.jetbrains.kotlinx:kover-gradle-plugin:0.7.3") +} \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlin-multiplatform-base.gradle.kts b/buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlin-multiplatform-base.gradle.kts index 3ceabc1..5665e86 100644 --- a/buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlin-multiplatform-base.gradle.kts +++ b/buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlin-multiplatform-base.gradle.kts @@ -3,9 +3,7 @@ package buildsrc.conventions.lang import buildsrc.utils.Rife2TestListener import org.gradle.api.tasks.testing.logging.TestExceptionFormat import org.gradle.api.tasks.testing.logging.TestLogEvent -import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi import org.jetbrains.kotlin.gradle.dsl.JvmTarget -import org.jetbrains.kotlin.gradle.dsl.KotlinVersion import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile @@ -26,31 +24,39 @@ plugins { kotlin { //jvmToolchain(11) - applyDefaultHierarchyTemplate() - - @OptIn(ExperimentalKotlinGradlePluginApi::class) - compilerOptions { - languageVersion = KotlinVersion.KOTLIN_1_6 + targets.configureEach { + compilations.configureEach { + kotlinOptions { + languageVersion = "1.6" + } + } } // configure all Kotlin/JVM Tests to use JUnit targets.withType().configureEach { testRuns.configureEach { executionTask.configure { - useJUnitPlatform() + // useJUnitPlatform() } } } + + sourceSets.configureEach { + languageSettings { + // languageVersion = + // apiVersion = + } + } } tasks { withType().configureEach { - sourceCompatibility = JavaVersion.VERSION_1_8.toString() - targetCompatibility = JavaVersion.VERSION_1_8.toString() + sourceCompatibility = JavaVersion.VERSION_11.toString() + targetCompatibility = JavaVersion.VERSION_11.toString() } withType().configureEach { - compilerOptions.jvmTarget.set(JvmTarget.JVM_1_8) + compilerOptions.jvmTarget.set(JvmTarget.JVM_11) } withType().configureEach { diff --git a/buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlin-multiplatform-js.gradle.kts b/buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlin-multiplatform-js.gradle.kts index 5474801..2a0034a 100644 --- a/buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlin-multiplatform-js.gradle.kts +++ b/buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlin-multiplatform-js.gradle.kts @@ -1,7 +1,5 @@ package buildsrc.conventions.lang -import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl - /** conventions for a Kotlin/JS subproject */ plugins { @@ -9,38 +7,12 @@ plugins { } kotlin { - js(IR) { - browser() - nodejs() - } - - @OptIn(ExperimentalWasmDsl::class) - wasmJs { - browser() - nodejs() - } - - @OptIn(ExperimentalWasmDsl::class) - wasmWasi { - nodejs() + targets { + js(IR) { + browser() + nodejs() + } } } relocateKotlinJsStore() - - -//region FIXME: WORKAROUND https://youtrack.jetbrains.com/issue/KT-65864 -rootProject.plugins.withType { - rootProject.extensions.configure { - // Use a Node.js version current enough to support Kotlin/Wasm - nodeVersion = "22.0.0-nightly2024010568c8472ed9" - logger.lifecycle("Using Node.js $nodeVersion to support Kotlin/Wasm") - nodeDownloadBaseUrl = "https://nodejs.org/download/nightly" - } -} - -rootProject.tasks.withType().configureEach { - // Prevent Yarn from complaining about newer Node.js versions. - args.add("--ignore-engines") -} -//endregion diff --git a/buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlin-multiplatform-native.gradle.kts b/buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlin-multiplatform-native.gradle.kts index 70022cc..e29ad97 100644 --- a/buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlin-multiplatform-native.gradle.kts +++ b/buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlin-multiplatform-native.gradle.kts @@ -7,26 +7,94 @@ plugins { } kotlin { + + // Native targets all extend commonMain and commonTest. + // + // Some targets (ios, tvos, watchos) are shortcuts provided by the Kotlin DSL, that + // provide additional targets, except for 'simulators' which must be defined manually. + // https://kotlinlang.org/docs/multiplatform-share-on-platforms.html#use-target-shortcuts + // + // common/ + // └── native/ + // ├── linuxX64 + // ├── mingwX64 + // ├── macosX64 + // ├── macosArm64 + // ├── ios/ (shortcut) + // │ ├── iosArm64 + // │ ├── iosX64 + // │ └── iosSimulatorArm64 + // ├── tvos/ (shortcut) + // │ ├── tvosArm64 + // │ ├── tvosX64 + // │ └── tvosSimulatorArm64Main + // └── watchos/ (shortcut) + // ├── watchosArm32 + // ├── watchosArm64 + // ├── watchosX64 + // └── watchosSimulatorArm64Main + linuxX64() mingwX64() - linuxArm64() - macosX64() macosArm64() - iosArm64() - iosX64() + // https://kotlinlang.org/docs/multiplatform-share-on-platforms.html#use-target-shortcuts + ios() // iosArm64, iosX64 + watchos() // watchosArm32, watchosArm64, watchosX64 + tvos() // tvosArm64, tvosX64 + iosSimulatorArm64() - - watchosArm32() - watchosArm64() - watchosX64() - watchosSimulatorArm64() - watchosDeviceArm64() - - tvosArm64() - tvosX64() tvosSimulatorArm64() + watchosSimulatorArm64() + + @Suppress("UNUSED_VARIABLE") + sourceSets { + val commonMain by getting {} + val commonTest by getting {} + + val nativeMain by creating { dependsOn(commonMain) } + val nativeTest by creating { dependsOn(commonTest) } + + // Linux + val linuxX64Main by getting { dependsOn(nativeMain) } + val linuxX64Test by getting { dependsOn(nativeTest) } + + // Windows - MinGW + val mingwX64Main by getting { dependsOn(nativeMain) } + val mingwX64Test by getting { dependsOn(nativeTest) } + + // Apple - macOS + val macosArm64Main by getting { dependsOn(nativeMain) } + val macosArm64Test by getting { dependsOn(nativeTest) } + + val macosX64Main by getting { dependsOn(nativeMain) } + val macosX64Test by getting { dependsOn(nativeTest) } + + // Apple - iOS + val iosMain by getting { dependsOn(nativeMain) } + val iosTest by getting { dependsOn(nativeTest) } + + // val iosSimulatorArm64Main by getting { dependsOn(iosMain) } + // val iosSimulatorArm64Test by getting { dependsOn(iosTest) } + + // // Apple - tvOS + // val tvosMain by getting { dependsOn(nativeMain) } + // val tvosTest by getting { dependsOn(nativeTest) } + + // val tvosSimulatorArm64Main by getting { dependsOn(tvosMain) } + // val tvosSimulatorArm64Test by getting { dependsOn(tvosTest) } + + // // Apple - watchOS + // val watchosMain by getting { dependsOn(nativeMain) } + // val watchosTest by getting { dependsOn(nativeTest) } + + // val watchosSimulatorArm64Main by getting { dependsOn(watchosMain) } + // val watchosSimulatorArm64Test by getting { dependsOn(watchosTest) } + + // val iosArm32Main by getting { dependsOn(desktopMain) } + // val iosArm32Test by getting { dependsOn(nativeTest) } + } } diff --git a/buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlinJsExtensions.kt b/buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlinJsExtensions.kt index 8525916..eefdc94 100644 --- a/buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlinJsExtensions.kt +++ b/buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlinJsExtensions.kt @@ -10,9 +10,9 @@ import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension * version catalog. */ internal fun Project.relocateKotlinJsStore() { - afterEvaluate { - rootProject.extensions.configure { - lockFileDirectory = project.rootDir.resolve("gradle/kotlin-js-store") - } - } + afterEvaluate { + rootProject.extensions.configure { + lockFileDirectory = project.rootDir.resolve("gradle/kotlin-js-store") + } + } } diff --git a/buildSrc/src/main/kotlin/buildsrc/conventions/publishing.gradle.kts b/buildSrc/src/main/kotlin/buildsrc/conventions/publishing.gradle.kts index 6afd9e1..660d4b1 100644 --- a/buildSrc/src/main/kotlin/buildsrc/conventions/publishing.gradle.kts +++ b/buildSrc/src/main/kotlin/buildsrc/conventions/publishing.gradle.kts @@ -1,3 +1,19 @@ +/* + * Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com) + * Copyright 2022-2023 Erik C. Thauvin (erik@thauvin.net) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package buildsrc.conventions plugins { @@ -82,11 +98,9 @@ signing { }) } -tasks { - withType().configureEach { - val signingRequiredPredicate = provider { signing.isRequired } - onlyIf { signingRequiredPredicate.get() } - } +tasks.withType().configureEach { + val signingRequiredPredicate = provider { signing.isRequired } + onlyIf { signingRequiredPredicate.get() } } // https://youtrack.jetbrains.com/issue/KT-46466 diff --git a/buildSrc/src/main/kotlin/buildsrc/utils/Rife2TestListener.kt b/buildSrc/src/main/kotlin/buildsrc/utils/Rife2TestListener.kt index 59df2bd..748b064 100644 --- a/buildSrc/src/main/kotlin/buildsrc/utils/Rife2TestListener.kt +++ b/buildSrc/src/main/kotlin/buildsrc/utils/Rife2TestListener.kt @@ -1,11 +1,12 @@ /* - * Copyright 2001-2024 the original author or authors. + * Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com) + * Copyright 2022-2023 Erik C. Thauvin (erik@thauvin.net) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * https://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -16,13 +17,14 @@ package buildsrc.utils -import org.apache.http.client.methods.HttpPost -import org.apache.http.impl.client.HttpClients -import org.apache.http.util.EntityUtils import org.gradle.api.provider.Provider import org.gradle.api.tasks.testing.TestDescriptor import org.gradle.api.tasks.testing.TestListener import org.gradle.api.tasks.testing.TestResult +import java.net.URI +import java.net.http.HttpClient +import java.net.http.HttpRequest +import java.net.http.HttpResponse class Rife2TestListener( private val testBadgeApiKey: Provider @@ -40,23 +42,23 @@ class Rife2TestListener( if (apiKey != null) { println(apiKey) - val url = "https://rife2.com/tests-badge/update/net.thauvin.erik/urlencoder?" + - "apiKey=$apiKey&" + - "passed=$passed&" + - "failed=$failed&" + - "skipped=$skipped" - - val client = HttpClients.createDefault() - val post = HttpPost(url) - - val response = client.execute(post) - val entity = response.entity - - val statusCode = response.statusLine.statusCode - val responseBody = EntityUtils.toString(entity, "UTF-8") - - println("RESPONSE: $statusCode") - println(responseBody) + val response: HttpResponse = HttpClient.newHttpClient() + .send( + HttpRequest.newBuilder() + .uri( + URI( + "https://rife2.com/tests-badge/update/net.thauvin.erik/urlencoder?" + + "apiKey=$apiKey&" + + "passed=$passed&" + + "failed=$failed&" + + "skipped=$skipped" + ) + ) + .POST(HttpRequest.BodyPublishers.noBody()) + .build(), HttpResponse.BodyHandlers.ofString() + ) + println("RESPONSE: ${response.statusCode()}") + println(response.body()) } } } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index a4b76b9..7f93135 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index df97d72..ac72c34 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index f5feea6..0adc8e1 100755 --- a/gradlew +++ b/gradlew @@ -15,8 +15,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # -# SPDX-License-Identifier: Apache-2.0 -# ############################################################################## # @@ -57,7 +55,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -86,8 +84,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s -' "$PWD" ) || exit +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -148,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 + # shellcheck disable=SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -156,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 + # shellcheck disable=SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -205,11 +202,11 @@ fi # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' -# Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, -# and any embedded shellness will be escaped. -# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be -# treated as '${Hostname}' itself on the command line. +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ diff --git a/gradlew.bat b/gradlew.bat index 9d21a21..93e3f59 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,8 +13,6 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem -@rem SPDX-License-Identifier: Apache-2.0 -@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -45,11 +43,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. 1>&2 -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. goto fail @@ -59,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. 1>&2 -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. goto fail diff --git a/settings.gradle.kts b/settings.gradle.kts index 9e70d32..03ddb65 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,90 +1,82 @@ rootProject.name = "urlencoder" pluginManagement { - repositories { - mavenCentral() - gradlePluginPortal() - } + repositories { + mavenCentral() + gradlePluginPortal() + } } @Suppress("UnstableApiUsage") dependencyResolutionManagement { - repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) + repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) - repositories { - mavenCentral() - maven("https://oss.sonatype.org/content/repositories/snapshots") { - name = "Sonatype Snapshots" - mavenContent { snapshotsOnly() } - } - - // Declare the Node.js & Yarn download repositories - exclusiveContent { - forRepositories( - ivy("https://nodejs.org/dist/") { - name = "Node Distributions at $url" - patternLayout { artifact("v[revision]/[artifact](-v[revision]-[classifier]).[ext]") } - metadataSources { artifact() } - }, - ivy("https://nodejs.org/download/v8-canary/") { - name = "Node Canary Distributions at $url" - patternLayout { artifact("v[revision]/[artifact](-v[revision]-[classifier]).[ext]") } - metadataSources { artifact() } - }, - ivy("https://nodejs.org/download/nightly/") { - name = "Node Nightly Distributions at $url" - patternLayout { artifact("v[revision]/[artifact](-v[revision]-[classifier]).[ext]") } - metadataSources { artifact() } - }, - ) - filter { includeGroup("org.nodejs") } - } - - exclusiveContent { - forRepository { - ivy("https://github.com/yarnpkg/yarn/releases/download") { - name = "Yarn Distributions at $url" - patternLayout { artifact("v[revision]/[artifact](-v[revision]).[ext]") } - metadataSources { artifact() } - } - } - filter { includeGroup("com.yarnpkg") } - } - - // workaround for https://youtrack.jetbrains.com/issue/KT-51379 - exclusiveContent { - forRepository { - ivy("https://download.jetbrains.com/kotlin/native/builds") { - name = "Kotlin Native" - patternLayout { - // example download URLs: - // https://download.jetbrains.com/kotlin/native/builds/releases/1.7.20/linux-x86_64/kotlin-native-prebuilt-linux-x86_64-1.7.20.tar.gz - // https://download.jetbrains.com/kotlin/native/builds/releases/1.7.20/windows-x86_64/kotlin-native-prebuilt-windows-x86_64-1.7.20.zip - // https://download.jetbrains.com/kotlin/native/builds/releases/1.7.20/macos-x86_64/kotlin-native-prebuilt-macos-x86_64-1.7.20.tar.gz - listOf( - "macos-x86_64", - "macos-aarch64", - "osx-x86_64", - "osx-aarch64", - "linux-x86_64", - "windows-x86_64", - ).forEach { os -> - listOf("dev", "releases").forEach { stage -> - artifact("$stage/[revision]/$os/[artifact]-[revision].[ext]") - } - } - } - metadataSources { artifact() } - } - } - filter { includeModuleByRegex(".*", ".*kotlin-native-prebuilt.*") } - } + repositories { + mavenCentral() + maven("https://oss.sonatype.org/content/repositories/snapshots") { + name = "Sonatype Snapshots" + mavenContent { snapshotsOnly() } } + + // Declare the Node.js & Yarn download repositories + exclusiveContent { + forRepository { + ivy("https://nodejs.org/dist/") { + name = "Node Distributions at $url" + patternLayout { artifact("v[revision]/[artifact](-v[revision]-[classifier]).[ext]") } + metadataSources { artifact() } + content { includeModule("org.nodejs", "node") } + } + } + filter { includeGroup("org.nodejs") } + } + + exclusiveContent { + forRepository { + ivy("https://github.com/yarnpkg/yarn/releases/download") { + name = "Yarn Distributions at $url" + patternLayout { artifact("v[revision]/[artifact](-v[revision]).[ext]") } + metadataSources { artifact() } + content { includeModule("com.yarnpkg", "yarn") } + } + } + filter { includeGroup("com.yarnpkg") } + } + + // workaround for https://youtrack.jetbrains.com/issue/KT-51379 + exclusiveContent { + forRepository { + ivy("https://download.jetbrains.com/kotlin/native/builds") { + name = "Kotlin Native" + patternLayout { + // example download URLs: + // https://download.jetbrains.com/kotlin/native/builds/releases/1.7.20/linux-x86_64/kotlin-native-prebuilt-linux-x86_64-1.7.20.tar.gz + // https://download.jetbrains.com/kotlin/native/builds/releases/1.7.20/windows-x86_64/kotlin-native-prebuilt-windows-x86_64-1.7.20.zip + // https://download.jetbrains.com/kotlin/native/builds/releases/1.7.20/macos-x86_64/kotlin-native-prebuilt-macos-x86_64-1.7.20.tar.gz + listOf( + "macos-x86_64", + "macos-aarch64", + "osx-x86_64", + "osx-aarch64", + "linux-x86_64", + "windows-x86_64", + ).forEach { os -> + listOf("dev", "releases").forEach { stage -> + artifact("$stage/[revision]/$os/[artifact]-[revision].[ext]") + } + } + } + metadataSources { artifact() } + } + } + filter { includeModuleByRegex(".*", ".*kotlin-native-prebuilt.*") } + } + } } enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") include( - ":urlencoder-app", - ":urlencoder-lib", + ":urlencoder-app", + ":urlencoder-lib", ) diff --git a/urlencoder-app/build.gradle.kts b/urlencoder-app/build.gradle.kts index c3fc159..93a9789 100644 --- a/urlencoder-app/build.gradle.kts +++ b/urlencoder-app/build.gradle.kts @@ -1,21 +1,17 @@ import org.jetbrains.dokka.gradle.DokkaTask -import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi plugins { buildsrc.conventions.lang.`kotlin-multiplatform-jvm` +// buildsrc.conventions.lang.`kotlin-multiplatform-js` +// buildsrc.conventions.lang.`kotlin-multiplatform-native` buildsrc.conventions.publishing + id("application") id("com.github.ben-manes.versions") } val urlEncoderMainClass = "net.thauvin.erik.urlencoder.UrlEncoder" kotlin { - jvm { - @OptIn(ExperimentalKotlinGradlePluginApi::class) - mainRun { - mainClass.set(urlEncoderMainClass) - } - } sourceSets { commonMain { dependencies { @@ -36,6 +32,10 @@ base { archivesName.set(rootProject.name) } +application { + mainClass.set(urlEncoderMainClass) +} + tasks { jvmJar { manifest { @@ -45,13 +45,14 @@ tasks { val fatJar by registering(Jar::class) { group = LifecycleBasePlugin.BUILD_GROUP + dependsOn.addAll(listOf("compileJava", "compileKotlinJvm", "processResources")) archiveClassifier.set("all") duplicatesStrategy = DuplicatesStrategy.EXCLUDE - manifest { attributes(mapOf("Main-Class" to urlEncoderMainClass)) } - from(sourceSets.main.map { it.output }) + manifest { attributes(mapOf("Main-Class" to application.mainClass)) } + from(sourceSets.main.get().output) dependsOn(configurations.jvmRuntimeClasspath) from(configurations.jvmRuntimeClasspath.map { classpath -> - classpath.filter { it.name.endsWith(".jar") }.map { zipTree(it) } + classpath.incoming.artifacts.artifactFiles.files.filter { it.name.endsWith("jar") }.map { zipTree(it) } }) } diff --git a/urlencoder-app/src/commonMain/kotlin/net/thauvin/erik/urlencoder/UrlEncoder.kt b/urlencoder-app/src/commonMain/kotlin/net/thauvin/erik/urlencoder/UrlEncoder.kt index 2c8ff60..df89c28 100644 --- a/urlencoder-app/src/commonMain/kotlin/net/thauvin/erik/urlencoder/UrlEncoder.kt +++ b/urlencoder-app/src/commonMain/kotlin/net/thauvin/erik/urlencoder/UrlEncoder.kt @@ -1,5 +1,5 @@ /* - * Copyright 2001-2024 the original author or authors. + * Copyright 2001-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/urlencoder-app/src/commonTest/kotlin/net/thauvin/erik/urlencoder/UrlEncoderTest.kt b/urlencoder-app/src/commonTest/kotlin/net/thauvin/erik/urlencoder/UrlEncoderTest.kt index ecf9356..1b159ed 100644 --- a/urlencoder-app/src/commonTest/kotlin/net/thauvin/erik/urlencoder/UrlEncoderTest.kt +++ b/urlencoder-app/src/commonTest/kotlin/net/thauvin/erik/urlencoder/UrlEncoderTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2001-2024 the original author or authors. + * Copyright 2001-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,7 +29,7 @@ class UrlEncoderTest { val validMap = listOf( "a test &" to "a%20test%20%26", "!abcdefghijklmnopqrstuvwxyz%%ABCDEFGHIJKLMNOPQRSTUVQXYZ0123456789-_.~=" to - "%21abcdefghijklmnopqrstuvwxyz%25%25ABCDEFGHIJKLMNOPQRSTUVQXYZ0123456789-_.%7E%3D", + "%21abcdefghijklmnopqrstuvwxyz%25%25ABCDEFGHIJKLMNOPQRSTUVQXYZ0123456789-_.%7E%3D", "%#okékÉȢ smile!😁" to "%25%23ok%C3%A9k%C3%89%C8%A2%20smile%21%F0%9F%98%81", "\uD808\uDC00\uD809\uDD00\uD808\uDF00\uD808\uDD00" to "%F0%92%80%80%F0%92%94%80%F0%92%8C%80%F0%92%84%80", ) diff --git a/urlencoder-lib/src/commonMain/kotlin/net/thauvin/erik/urlencoder/Character.kt b/urlencoder-lib/src/commonMain/kotlin/net/thauvin/erik/urlencoder/Character.kt index e4b4286..1ea0db9 100644 --- a/urlencoder-lib/src/commonMain/kotlin/net/thauvin/erik/urlencoder/Character.kt +++ b/urlencoder-lib/src/commonMain/kotlin/net/thauvin/erik/urlencoder/Character.kt @@ -1,5 +1,5 @@ /* - * Copyright 2001-2024 the original author or authors. + * Copyright 2001-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -59,15 +59,15 @@ internal object Character { internal fun lowSurrogateOf(codePoint: Int): Char = ((codePoint and 0x3FF) + MIN_LOW_SURROGATE.code).toChar() - // private const val MIN_CODE_POINT: Int = 0x000000 +// private const val MIN_CODE_POINT: Int = 0x000000 private const val MAX_CODE_POINT: Int = 0x10FFFF private const val MIN_SUPPLEMENTARY_CODE_POINT: Int = 0x10000 private const val SURROGATE_DECODE_OFFSET: Int = MIN_SUPPLEMENTARY_CODE_POINT - - (MIN_HIGH_SURROGATE.code shl 10) - - MIN_LOW_SURROGATE.code + (MIN_HIGH_SURROGATE.code shl 10) - + MIN_LOW_SURROGATE.code private const val HIGH_SURROGATE_ENCODE_OFFSET: Char = MIN_HIGH_SURROGATE - (MIN_SUPPLEMENTARY_CODE_POINT ushr 10) } diff --git a/urlencoder-lib/src/commonMain/kotlin/net/thauvin/erik/urlencoder/UrlEncoderUtil.kt b/urlencoder-lib/src/commonMain/kotlin/net/thauvin/erik/urlencoder/UrlEncoderUtil.kt index 7da63d1..0f45bc6 100644 --- a/urlencoder-lib/src/commonMain/kotlin/net/thauvin/erik/urlencoder/UrlEncoderUtil.kt +++ b/urlencoder-lib/src/commonMain/kotlin/net/thauvin/erik/urlencoder/UrlEncoderUtil.kt @@ -1,5 +1,5 @@ /* - * Copyright 2001-2024 the original author or authors. + * Copyright 2001-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/urlencoder-lib/src/commonTest/kotlin/net/thauvin/erik/urlencoder/TestData.kt b/urlencoder-lib/src/commonTest/kotlin/net/thauvin/erik/urlencoder/TestData.kt deleted file mode 100644 index 6cbf139..0000000 --- a/urlencoder-lib/src/commonTest/kotlin/net/thauvin/erik/urlencoder/TestData.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2001-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.thauvin.erik.urlencoder - -import kotlin.jvm.JvmField - -const val standardContent = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVQXYZ0123456789-_." - -val invalidContent = listOf("sdkjfh%", "sdkjfh%6", "sdkjfh%xx", "sdfjfh%-1") - -/** - * List of unencoded content paired with the encoded content. - */ -val decodedToEncoded = listOf( - TestData("a test &", "a%20test%20%26"), - TestData( - "!abcdefghijklmnopqrstuvwxyz%%ABCDEFGHIJKLMNOPQRSTUVQXYZ0123456789-_.~=", - "%21abcdefghijklmnopqrstuvwxyz%25%25ABCDEFGHIJKLMNOPQRSTUVQXYZ0123456789-_.%7E%3D" - ), - TestData("%#okékÉȢ smile!😁", "%25%23ok%C3%A9k%C3%89%C8%A2%20smile%21%F0%9F%98%81"), - TestData("\uD808\uDC00\uD809\uDD00\uD808\uDF00\uD808\uDD00", "%F0%92%80%80%F0%92%94%80%F0%92%8C%80%F0%92%84%80"), -) - -data class TestData( - @JvmField - val unencoded: String, - @JvmField - val encoded: String, -) diff --git a/urlencoder-lib/src/commonTest/kotlin/net/thauvin/erik/urlencoder/UrlEncoderUtilTest.kt b/urlencoder-lib/src/commonTest/kotlin/net/thauvin/erik/urlencoder/UrlEncoderUtilTest.kt index 102bbfa..f6b67de 100644 --- a/urlencoder-lib/src/commonTest/kotlin/net/thauvin/erik/urlencoder/UrlEncoderUtilTest.kt +++ b/urlencoder-lib/src/commonTest/kotlin/net/thauvin/erik/urlencoder/UrlEncoderUtilTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2001-2024 the original author or authors. + * Copyright 2001-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,17 +23,30 @@ import kotlin.test.DefaultAsserter.assertEquals import kotlin.test.DefaultAsserter.assertSame class UrlEncoderUtilTest { + private val same = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVQXYZ0123456789-_." + + companion object { + val invalid = listOf("sdkjfh%", "sdkjfh%6", "sdkjfh%xx", "sdfjfh%-1") + + val validMap = listOf( + "a test &" to "a%20test%20%26", + "!abcdefghijklmnopqrstuvwxyz%%ABCDEFGHIJKLMNOPQRSTUVQXYZ0123456789-_.~=" to + "%21abcdefghijklmnopqrstuvwxyz%25%25ABCDEFGHIJKLMNOPQRSTUVQXYZ0123456789-_.%7E%3D", + "%#okékÉȢ smile!😁" to "%25%23ok%C3%A9k%C3%89%C8%A2%20smile%21%F0%9F%98%81", + "\uD808\uDC00\uD809\uDD00\uD808\uDF00\uD808\uDD00" to "%F0%92%80%80%F0%92%94%80%F0%92%8C%80%F0%92%84%80", + ) + } @Test fun decodeURL() { - for ((unencoded, encoded) in decodedToEncoded) { - assertEquals(unencoded, decode(encoded)) + for (m in validMap) { + assertEquals(m.first, decode(m.second)) } } @Test fun decodeWithException() { - for (source in invalidContent) { + for (source in invalid) { assertFailsWith( message = "decode($source)", block = { decode(source) } @@ -43,7 +56,7 @@ class UrlEncoderUtilTest { @Test fun decodeWhenNoneNeeded() { - assertSame(standardContent, decode(standardContent)) + assertSame(same, decode(same)) assertEquals("decode('')", decode(""), "") assertEquals("decode(' ')", decode(" "), " ") } @@ -59,8 +72,8 @@ class UrlEncoderUtilTest { @Test fun encodeURL() { - for ((unencoded, encoded) in decodedToEncoded) { - assertEquals(encoded, encode(unencoded)) + for (m in validMap) { + assertEquals(m.second, encode(m.first)) } } @@ -73,8 +86,8 @@ class UrlEncoderUtilTest { @Test fun encodeWhenNoneNeeded() { - assertSame(encode(standardContent), standardContent) - assertSame("with empty allow", encode(standardContent, allow = ""), standardContent) + assertSame(encode(same), same) + assertSame("with empty allow", encode(same, allow = ""), same) } @Test diff --git a/urlencoder-lib/src/jvmTest/java/net/thauvin/erik/urlencoder/UrlEncoderJavaTest.java b/urlencoder-lib/src/jvmTest/java/net/thauvin/erik/urlencoder/UrlEncoderJavaTest.java deleted file mode 100644 index 8fa9561..0000000 --- a/urlencoder-lib/src/jvmTest/java/net/thauvin/erik/urlencoder/UrlEncoderJavaTest.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2001-2024 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.thauvin.erik.urlencoder; - -import org.junit.jupiter.api.Test; - -import static net.thauvin.erik.urlencoder.TestDataKt.getDecodedToEncoded; -import static net.thauvin.erik.urlencoder.UrlEncoderUtil.decode; -import static net.thauvin.erik.urlencoder.UrlEncoderUtil.encode; -import static org.junit.jupiter.api.Assertions.assertAll; -import static org.junit.jupiter.api.Assertions.assertEquals; - -class UrlEncoderJavaTest { - - @Test - public void decodeURL() { - assertAll( - getDecodedToEncoded() - .stream() - .map(data -> - () -> assertEquals(data.unencoded, decode(data.encoded)) - ) - ); - } - - @Test - public void encodeURL() { - assertAll( - getDecodedToEncoded() - .stream() - .map(data -> - () -> assertEquals(data.encoded, encode(data.unencoded)) - ) - ); - } -}