Compare commits

...

34 commits

Author SHA1 Message Date
b882d68d4c
Removed git-cliff configuration and script 2024-10-20 18:24:53 -07:00
9e60b31f9e
Version 1.6.0 2024-10-19 09:01:36 -07:00
c69d7b7076
Added git-cliff configuration and script 2024-10-18 16:23:04 -07:00
742c221a20
Revert "Set Kotlin's language version to Java 8"
This reverts commit 0b6e55b338.
2024-10-16 12:13:00 -07:00
0b6e55b338
Set Kotlin's language version to Java 8 2024-10-16 11:17:34 -07:00
09b44d53e8
Compile public version with Java 21 2024-10-16 11:15:39 -07:00
df7482c3a0
Version 1.6.0-SNAPSHOT 2024-10-15 13:00:33 -07:00
3e36e389fb
Bumped Gradle to version 8.10.2 2024-10-15 12:43:53 -07:00
d66fdb12e6
Updated dependencies
Bumped Detekt to version 1.23.7
Bumped Kover to version 0.8.3
Bumped Kotlin to version 1.9.24
2024-10-15 12:43:01 -07:00
Ronny Bräunlich
6f33f9c2a9
feat: Java 8 compatibility (#19)
Closes #18

Co-authored-by: Ronny Bräunlich <ronny.braeunlich@cbc.de>
2024-10-15 12:03:54 -07:00
dd3d500496
Version 1.5.0 2024-03-27 21:44:29 -07:00
Adam
c801a9703f
Tidy publishing config (#17)
* remove custom POM location (Gradle gets confused)

* - update GitHub actions
- use new `gradle/actions/setup-gradle`
- block cancel-in-progress for publish.yml
2024-03-27 10:54:49 -07:00
1ef2045b32
Reworked GitHub workflows 2024-03-26 22:14:18 -07:00
Adam
d03c61cb92
bump version to 1.5.0-SNAPSHOT (#16) 2024-03-26 21:38:50 -07:00
a689c56e1e
Bumped Gradle to version 8.7 2024-03-26 14:14:08 -07:00
b59d01ec6d
Bumped Dokka to version 1.9.20 2024-03-26 14:13:32 -07:00
Adam
8890fef665
bump Kotlin to 1.9.23, enable additional Kotlin Multiplatform targets (#15)
* bump Kotlin to 1.9.23, enable additional Kotlin Multiplatform targets

* replace soon-to-be-deprecated kotlinOptions with newer compilerOptions
2024-03-26 13:52:11 -07:00
Adam
171570159e
add Java tests for verifying @JvmStatic (#14) 2024-02-25 04:17:08 -08:00
61137e0878 Updated copyright 2024-02-24 22:21:30 -08:00
f3fc266c6f Bumped dependencies 2024-02-24 22:21:17 -08:00
7817198be1 Removed JDK 20 deprecation reference 2023-11-17 08:56:40 -08:00
b9791dc507 Added java.net.URLEncoder deprecation reference 2023-11-01 00:52:22 -07:00
ee35984130 Added pom.xml generation 2023-10-18 21:04:08 -07:00
05d4a52240 Updated dependencies 2023-10-18 20:16:44 -07:00
8ebc178474 Revert "Added codecov"
This reverts commit 404ca93137.
2023-09-29 00:32:01 -07:00
404ca93137 Added codecov 2023-09-29 00:19:35 -07:00
2523b31073 Remove iOS X64 simulator 2023-09-25 01:50:45 -07:00
6acf3417e5 Added iOS simulator target 2023-09-24 21:53:27 -07:00
f711cf719f Try using iOS target shortcut 2023-09-24 13:08:56 -07:00
ebdc9ceef8 Added iOS publish workflow 2023-09-24 12:41:46 -07:00
9f3803bdcd Added iOS publications 2023-09-24 12:12:01 -07:00
5b46ff448c Updated Kotlin badge 2023-09-22 04:41:04 -07:00
d790a02365 Fixed examples 2023-09-21 22:04:34 -07:00
7ea75e30e7 Fixed Kotlin badge 2023-09-21 19:28:03 -07:00
24 changed files with 361 additions and 382 deletions

View file

@ -17,7 +17,7 @@ jobs:
build: build:
strategy: strategy:
matrix: matrix:
java-version: [ 11, 17, 20 ] java-version: [8, 11, 17, 21]
os: os:
- macos-latest - macos-latest
- ubuntu-latest - ubuntu-latest
@ -28,27 +28,25 @@ jobs:
GRADLE_OPTS: "-Dorg.gradle.jvmargs=-XX:MaxMetaspaceSize=512m" GRADLE_OPTS: "-Dorg.gradle.jvmargs=-XX:MaxMetaspaceSize=512m"
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Set up JDK ${{ matrix.java-version }} - name: Set up JDK ${{ matrix.java-version }}
uses: actions/setup-java@v3 uses: actions/setup-java@v4
with: with:
distribution: 'zulu' distribution: "zulu"
java-version: ${{ matrix.java-version }} java-version: ${{ matrix.java-version }}
- name: Validate Gradle wrapper - name: Validate Gradle wrapper
uses: gradle/wrapper-validation-action@v1 uses: gradle/wrapper-validation-action@v2
- name: Cache Kotlin Konan - name: Cache Kotlin Konan
id: cache-kotlin-konan uses: actions/cache@v4
uses: actions/cache@v3
with: with:
path: | path: ~/.konan/**/*
~/.konan/**/*
key: kotlin-konan-${{ runner.os }} key: kotlin-konan-${{ runner.os }}
- name: Test with Gradle - name: Set up Gradle
uses: gradle/gradle-build-action@v2 uses: gradle/actions/setup-gradle@v3
with:
gradle-home-cache-cleanup: true - name: Publish
arguments: build check --stacktrace -PtestsBadgeApiKey=${{ secrets.TESTS_BADGE_API_KEY }} run: ./gradlew check build --stacktrace -PtestsBadgeApiKey=${{ secrets.TESTS_BADGE_API_KEY }}

View file

@ -4,90 +4,41 @@ on:
workflow_dispatch: workflow_dispatch:
env: env:
JAVA_VERSION: 11
JAVA_DISTRIBUTION: 'zulu'
ORG_GRADLE_PROJECT_ossrhUsername: ${{ secrets.OSSRH_USERNAME}} ORG_GRADLE_PROJECT_ossrhUsername: ${{ secrets.OSSRH_USERNAME}}
ORG_GRADLE_PROJECT_ossrhPassword: ${{ secrets.OSSRH_PASSWORD}} ORG_GRADLE_PROJECT_ossrhPassword: ${{ secrets.OSSRH_PASSWORD}}
ORG_GRADLE_PROJECT_signingKey: ${{ secrets.SIGN_SECRET_KEY }} ORG_GRADLE_PROJECT_signingKey: ${{ secrets.SIGN_SECRET_KEY }}
ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.SIGN_SECRET_PWD }} 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: jobs:
publish-base: publish:
runs-on: ubuntu-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 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:
java-version: ${{ env.JAVA_VERSION }}
distribution: ${{ env.JAVA_DISTRIBUTION }}
- uses: gradle/gradle-build-action@v2
- name: Publish Linux x64 release
run: ./gradlew publishLinuxX64PublicationToOSSRHRepository
publish-mac:
runs-on: macos-latest runs-on: macos-latest
strategy:
max-parallel: 6
matrix:
target:
- publishMacosArm64PublicationToOSSRHRepository
- publishMacosX64PublicationToOSSRHRepository
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v4
- name: Set up JDK ${{ env.JAVA_VERSION }} - name: Set up JDK
uses: actions/setup-java@v3 uses: actions/setup-java@v4
with: with:
java-version: ${{ env.JAVA_VERSION }} java-version: "21"
distribution: ${{ env.JAVA_DISTRIBUTION }} distribution: "zulu"
- uses: gradle/gradle-build-action@v2 - name: Validate Gradle wrapper
uses: gradle/wrapper-validation-action@v2
- name: Cache Kotlin Konan
uses: actions/cache@v4
with:
path: ~/.konan/**/*
key: kotlin-konan-${{ runner.os }}
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v3
- name: Publish - name: Publish
run: ./gradlew ${{ matrix.target }} run: ./gradlew publish --no-parallel --stacktrace
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

View file

@ -1,5 +1,5 @@
[![License](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![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.9.0-blue)](https://kotlinlang.org/) [![Kotlin](https://img.shields.io/badge/kotlin-1.6%2B-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/) [![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) [![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) [![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,18 +32,17 @@ optimizations have a significantly beneficial impact on performance of encoding
compared to other solutions like the standard `URLEncoder` in the JDK or compared to other solutions like the standard `URLEncoder` in the JDK or
`UriUtils` in Spring. `UriUtils` in Spring.
## Examples (TL;DR) ## Examples (TL;DR)
```kotlin ```kotlin
UrlEncoder.encode("a test &") // -> a%20test%20%26 UrlEncoderUtil.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 UrlEncoderUtil.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 UrlEncoderUtil.encode("?test=a test", allow = "?=") // -> ?test=a%20test
UrlEncoder.endode("foo bar", spaceToPlus = true) // -> foo+bar UrlEncoderUtil.endode("foo bar", spaceToPlus = true) // -> foo+bar
UrlEncoder.decode("a%20test%20%26") // -> a test & UrlEncoderUtil.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!😁 UrlEncoderUtil.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 UrlEncoderUtil.decode("foo+bar", plusToSpace = true) // -> foo bar
``` ```
## Gradle, Maven, etc. ## Gradle, Maven, etc.
@ -61,7 +60,7 @@ repositories {
} }
dependencies { dependencies {
implementation("net.thauvin.erik.urlencoder:urlencoder-lib:1.4.0") implementation("net.thauvin.erik.urlencoder:urlencoder-lib:1.6.0")
} }
``` ```
@ -72,11 +71,11 @@ to the artifact URL.
<dependency> <dependency>
<groupId>net.thauvin.erik.urlencoder</groupId> <groupId>net.thauvin.erik.urlencoder</groupId>
<artifactId>urlencoder-lib-jvm</artifactId> <artifactId>urlencoder-lib-jvm</artifactId>
<version>1.4.0</version> <version>1.6.0</version>
</dependency> </dependency>
``` ```
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). [Maven Central](https://central.sonatype.com/search?namespace=net.thauvin.erik.urlencoder).
## Standalone usage ## Standalone usage
@ -90,7 +89,7 @@ You have two options:
The usage is as follows: The usage is as follows:
``` ```console
Encode and decode URL components defensively. Encode and decode URL components defensively.
-e encode (default) -e encode (default)
-d decode -d decode
@ -98,7 +97,7 @@ Encode and decode URL components defensively.
### Running with Gradle ### Running with Gradle
```shell ```console
./gradlew run --quiet --args="-e 'a test &'" # -> a%20test%20%26 ./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 ./gradlew run --quiet --args="%#okékÉȢ" # -> %25%23ok%C3%A9k%C3%89%C8%A2
@ -109,13 +108,13 @@ Encode and decode URL components defensively.
First build the jar file: First build the jar file:
```shell ```console
./gradlew fatJar ./gradlew fatJar
``` ```
Then run it: Then run it:
```shell ```console
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 -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 java -jar urlencoder-app/build/libs/urlencoder-*all.jar "%#okékÉȢ" # -> %25%23ok%C3%A9k%C3%89%C8%A2

View file

@ -4,7 +4,7 @@ plugins {
} }
group = "net.thauvin.erik.urlencoder" group = "net.thauvin.erik.urlencoder"
version = "1.4.0" version = "1.6.0"
dependencies { dependencies {
kover(projects.urlencoderLib) kover(projects.urlencoderLib)

View file

@ -3,9 +3,10 @@ plugins {
} }
dependencies { dependencies {
implementation("com.github.ben-manes:gradle-versions-plugin:0.48.0") implementation("com.github.ben-manes:gradle-versions-plugin:0.51.0")
implementation("io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.23.1") implementation("io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.23.7")
implementation("org.jetbrains.dokka:dokka-gradle-plugin:1.9.0") implementation("org.jetbrains.dokka:dokka-gradle-plugin:1.9.20")
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.0") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.24")
implementation("org.jetbrains.kotlinx:kover-gradle-plugin:0.7.3") implementation("org.jetbrains.kotlinx:kover-gradle-plugin:0.8.3")
} implementation("org.apache.httpcomponents:httpclient:4.5.13")
}

View file

@ -3,7 +3,9 @@ package buildsrc.conventions.lang
import buildsrc.utils.Rife2TestListener import buildsrc.utils.Rife2TestListener
import org.gradle.api.tasks.testing.logging.TestExceptionFormat import org.gradle.api.tasks.testing.logging.TestExceptionFormat
import org.gradle.api.tasks.testing.logging.TestLogEvent 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.JvmTarget
import org.jetbrains.kotlin.gradle.dsl.KotlinVersion
import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
@ -24,39 +26,31 @@ plugins {
kotlin { kotlin {
//jvmToolchain(11) //jvmToolchain(11)
targets.configureEach { applyDefaultHierarchyTemplate()
compilations.configureEach {
kotlinOptions { @OptIn(ExperimentalKotlinGradlePluginApi::class)
languageVersion = "1.6" compilerOptions {
} languageVersion = KotlinVersion.KOTLIN_1_6
}
} }
// configure all Kotlin/JVM Tests to use JUnit // configure all Kotlin/JVM Tests to use JUnit
targets.withType<KotlinJvmTarget>().configureEach { targets.withType<KotlinJvmTarget>().configureEach {
testRuns.configureEach { testRuns.configureEach {
executionTask.configure { executionTask.configure {
// useJUnitPlatform() useJUnitPlatform()
} }
} }
} }
sourceSets.configureEach {
languageSettings {
// languageVersion =
// apiVersion =
}
}
} }
tasks { tasks {
withType<JavaCompile>().configureEach { withType<JavaCompile>().configureEach {
sourceCompatibility = JavaVersion.VERSION_11.toString() sourceCompatibility = JavaVersion.VERSION_1_8.toString()
targetCompatibility = JavaVersion.VERSION_11.toString() targetCompatibility = JavaVersion.VERSION_1_8.toString()
} }
withType<KotlinJvmCompile>().configureEach { withType<KotlinJvmCompile>().configureEach {
compilerOptions.jvmTarget.set(JvmTarget.JVM_11) compilerOptions.jvmTarget.set(JvmTarget.JVM_1_8)
} }
withType<Test>().configureEach { withType<Test>().configureEach {

View file

@ -1,5 +1,7 @@
package buildsrc.conventions.lang package buildsrc.conventions.lang
import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl
/** conventions for a Kotlin/JS subproject */ /** conventions for a Kotlin/JS subproject */
plugins { plugins {
@ -7,12 +9,38 @@ plugins {
} }
kotlin { kotlin {
targets { js(IR) {
js(IR) { browser()
browser() nodejs()
nodejs() }
}
@OptIn(ExperimentalWasmDsl::class)
wasmJs {
browser()
nodejs()
}
@OptIn(ExperimentalWasmDsl::class)
wasmWasi {
nodejs()
} }
} }
relocateKotlinJsStore() relocateKotlinJsStore()
//region FIXME: WORKAROUND https://youtrack.jetbrains.com/issue/KT-65864
rootProject.plugins.withType<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin> {
rootProject.extensions.configure<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension> {
// 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<org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinNpmInstallTask>().configureEach {
// Prevent Yarn from complaining about newer Node.js versions.
args.add("--ignore-engines")
}
//endregion

View file

@ -7,94 +7,26 @@ plugins {
} }
kotlin { 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() linuxX64()
mingwX64() mingwX64()
linuxArm64()
macosX64() macosX64()
macosArm64() macosArm64()
// https://kotlinlang.org/docs/multiplatform-share-on-platforms.html#use-target-shortcuts iosArm64()
ios() // iosArm64, iosX64 iosX64()
watchos() // watchosArm32, watchosArm64, watchosX64
tvos() // tvosArm64, tvosX64
iosSimulatorArm64() iosSimulatorArm64()
tvosSimulatorArm64()
watchosArm32()
watchosArm64()
watchosX64()
watchosSimulatorArm64() watchosSimulatorArm64()
watchosDeviceArm64()
@Suppress("UNUSED_VARIABLE") tvosArm64()
sourceSets { tvosX64()
val commonMain by getting {} tvosSimulatorArm64()
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) }
}
} }

View file

@ -10,9 +10,9 @@ import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension
* version catalog. * version catalog.
*/ */
internal fun Project.relocateKotlinJsStore() { internal fun Project.relocateKotlinJsStore() {
afterEvaluate { afterEvaluate {
rootProject.extensions.configure<YarnRootExtension> { rootProject.extensions.configure<YarnRootExtension> {
lockFileDirectory = project.rootDir.resolve("gradle/kotlin-js-store") lockFileDirectory = project.rootDir.resolve("gradle/kotlin-js-store")
} }
} }
} }

View file

@ -1,19 +1,3 @@
/*
* 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 package buildsrc.conventions
plugins { plugins {
@ -98,9 +82,11 @@ signing {
}) })
} }
tasks.withType<Sign>().configureEach { tasks {
val signingRequiredPredicate = provider { signing.isRequired } withType<Sign>().configureEach {
onlyIf { signingRequiredPredicate.get() } val signingRequiredPredicate = provider { signing.isRequired }
onlyIf { signingRequiredPredicate.get() }
}
} }
// https://youtrack.jetbrains.com/issue/KT-46466 // https://youtrack.jetbrains.com/issue/KT-46466

View file

@ -1,12 +1,11 @@
/* /*
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com) * Copyright 2001-2024 the original author or authors.
* Copyright 2022-2023 Erik C. Thauvin (erik@thauvin.net)
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * https://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
@ -17,14 +16,13 @@
package buildsrc.utils 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.provider.Provider
import org.gradle.api.tasks.testing.TestDescriptor import org.gradle.api.tasks.testing.TestDescriptor
import org.gradle.api.tasks.testing.TestListener import org.gradle.api.tasks.testing.TestListener
import org.gradle.api.tasks.testing.TestResult 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( class Rife2TestListener(
private val testBadgeApiKey: Provider<String> private val testBadgeApiKey: Provider<String>
@ -42,23 +40,23 @@ class Rife2TestListener(
if (apiKey != null) { if (apiKey != null) {
println(apiKey) println(apiKey)
val response: HttpResponse<String> = HttpClient.newHttpClient() val url = "https://rife2.com/tests-badge/update/net.thauvin.erik/urlencoder?" +
.send( "apiKey=$apiKey&" +
HttpRequest.newBuilder() "passed=$passed&" +
.uri( "failed=$failed&" +
URI( "skipped=$skipped"
"https://rife2.com/tests-badge/update/net.thauvin.erik/urlencoder?" +
"apiKey=$apiKey&" + val client = HttpClients.createDefault()
"passed=$passed&" + val post = HttpPost(url)
"failed=$failed&" +
"skipped=$skipped" val response = client.execute(post)
) val entity = response.entity
)
.POST(HttpRequest.BodyPublishers.noBody()) val statusCode = response.statusLine.statusCode
.build(), HttpResponse.BodyHandlers.ofString() val responseBody = EntityUtils.toString(entity, "UTF-8")
)
println("RESPONSE: ${response.statusCode()}") println("RESPONSE: $statusCode")
println(response.body()) println(responseBody)
} }
} }
} }

Binary file not shown.

View file

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

21
gradlew vendored
View file

@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
# #
# SPDX-License-Identifier: Apache-2.0
#
############################################################################## ##############################################################################
# #
@ -55,7 +57,7 @@
# Darwin, MinGW, and NonStop. # Darwin, MinGW, and NonStop.
# #
# (3) This script is generated from the Groovy template # (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project. # within the Gradle project.
# #
# You can find Gradle at https://github.com/gradle/gradle/. # You can find Gradle at https://github.com/gradle/gradle/.
@ -84,7 +86,8 @@ done
# shellcheck disable=SC2034 # shellcheck disable=SC2034
APP_BASE_NAME=${0##*/} APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum MAX_FD=maximum
@ -145,7 +148,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #( case $MAX_FD in #(
max*) max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045 # shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) || MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit" warn "Could not query maximum file descriptor limit"
esac esac
@ -153,7 +156,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
'' | soft) :;; #( '' | soft) :;; #(
*) *)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045 # shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" || ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD" warn "Could not set maximum file descriptor limit to $MAX_FD"
esac esac
@ -202,11 +205,11 @@ fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. # 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"' DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command; # Collect all arguments for the java command:
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of # * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# shell script including quotes and variable substitutions, so put them in # and any embedded shellness will be escaped.
# double quotes to make sure that they get re-expanded; and # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# * put everything else in single quotes, so that it's not re-expanded. # treated as '${Hostname}' itself on the command line.
set -- \ set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \ "-Dorg.gradle.appname=$APP_BASE_NAME" \

22
gradlew.bat vendored
View file

@ -13,6 +13,8 @@
@rem See the License for the specific language governing permissions and @rem See the License for the specific language governing permissions and
@rem limitations under the License. @rem limitations under the License.
@rem @rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off @if "%DEBUG%"=="" @echo off
@rem ########################################################################## @rem ##########################################################################
@ -43,11 +45,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute if %ERRORLEVEL% equ 0 goto execute
echo. echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. echo location of your Java installation. 1>&2
goto fail goto fail
@ -57,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute if exist "%JAVA_EXE%" goto execute
echo. echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. echo location of your Java installation. 1>&2
goto fail goto fail

View file

@ -1,82 +1,90 @@
rootProject.name = "urlencoder" rootProject.name = "urlencoder"
pluginManagement { pluginManagement {
repositories { repositories {
mavenCentral() mavenCentral()
gradlePluginPortal() gradlePluginPortal()
} }
} }
@Suppress("UnstableApiUsage") @Suppress("UnstableApiUsage")
dependencyResolutionManagement { dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
repositories { repositories {
mavenCentral() mavenCentral()
maven("https://oss.sonatype.org/content/repositories/snapshots") { maven("https://oss.sonatype.org/content/repositories/snapshots") {
name = "Sonatype Snapshots" name = "Sonatype Snapshots"
mavenContent { snapshotsOnly() } 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 { // Declare the Node.js & Yarn download repositories
forRepository { exclusiveContent {
ivy("https://github.com/yarnpkg/yarn/releases/download") { forRepositories(
name = "Yarn Distributions at $url" ivy("https://nodejs.org/dist/") {
patternLayout { artifact("v[revision]/[artifact](-v[revision]).[ext]") } name = "Node Distributions at $url"
metadataSources { artifact() } patternLayout { artifact("v[revision]/[artifact](-v[revision]-[classifier]).[ext]") }
content { includeModule("com.yarnpkg", "yarn") } 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") }
} }
}
filter { includeGroup("com.yarnpkg") }
}
// workaround for https://youtrack.jetbrains.com/issue/KT-51379 exclusiveContent {
exclusiveContent { forRepository {
forRepository { ivy("https://github.com/yarnpkg/yarn/releases/download") {
ivy("https://download.jetbrains.com/kotlin/native/builds") { name = "Yarn Distributions at $url"
name = "Kotlin Native" patternLayout { artifact("v[revision]/[artifact](-v[revision]).[ext]") }
patternLayout { metadataSources { artifact() }
// 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]")
}
} }
} filter { includeGroup("com.yarnpkg") }
metadataSources { artifact() } }
// 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.*") }
} }
}
filter { includeModuleByRegex(".*", ".*kotlin-native-prebuilt.*") }
} }
}
} }
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
include( include(
":urlencoder-app", ":urlencoder-app",
":urlencoder-lib", ":urlencoder-lib",
) )

View file

@ -1,17 +1,21 @@
import org.jetbrains.dokka.gradle.DokkaTask import org.jetbrains.dokka.gradle.DokkaTask
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
plugins { plugins {
buildsrc.conventions.lang.`kotlin-multiplatform-jvm` buildsrc.conventions.lang.`kotlin-multiplatform-jvm`
// buildsrc.conventions.lang.`kotlin-multiplatform-js`
// buildsrc.conventions.lang.`kotlin-multiplatform-native`
buildsrc.conventions.publishing buildsrc.conventions.publishing
id("application")
id("com.github.ben-manes.versions") id("com.github.ben-manes.versions")
} }
val urlEncoderMainClass = "net.thauvin.erik.urlencoder.UrlEncoder" val urlEncoderMainClass = "net.thauvin.erik.urlencoder.UrlEncoder"
kotlin { kotlin {
jvm {
@OptIn(ExperimentalKotlinGradlePluginApi::class)
mainRun {
mainClass.set(urlEncoderMainClass)
}
}
sourceSets { sourceSets {
commonMain { commonMain {
dependencies { dependencies {
@ -32,10 +36,6 @@ base {
archivesName.set(rootProject.name) archivesName.set(rootProject.name)
} }
application {
mainClass.set(urlEncoderMainClass)
}
tasks { tasks {
jvmJar { jvmJar {
manifest { manifest {
@ -45,14 +45,13 @@ tasks {
val fatJar by registering(Jar::class) { val fatJar by registering(Jar::class) {
group = LifecycleBasePlugin.BUILD_GROUP group = LifecycleBasePlugin.BUILD_GROUP
dependsOn.addAll(listOf("compileJava", "compileKotlinJvm", "processResources"))
archiveClassifier.set("all") archiveClassifier.set("all")
duplicatesStrategy = DuplicatesStrategy.EXCLUDE duplicatesStrategy = DuplicatesStrategy.EXCLUDE
manifest { attributes(mapOf("Main-Class" to application.mainClass)) } manifest { attributes(mapOf("Main-Class" to urlEncoderMainClass)) }
from(sourceSets.main.get().output) from(sourceSets.main.map { it.output })
dependsOn(configurations.jvmRuntimeClasspath) dependsOn(configurations.jvmRuntimeClasspath)
from(configurations.jvmRuntimeClasspath.map { classpath -> from(configurations.jvmRuntimeClasspath.map { classpath ->
classpath.incoming.artifacts.artifactFiles.files.filter { it.name.endsWith("jar") }.map { zipTree(it) } classpath.filter { it.name.endsWith(".jar") }.map { zipTree(it) }
}) })
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2001-2023 the original author or authors. * Copyright 2001-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2001-2023 the original author or authors. * Copyright 2001-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -29,7 +29,7 @@ class UrlEncoderTest {
val validMap = listOf( val validMap = listOf(
"a test &" to "a%20test%20%26", "a test &" to "a%20test%20%26",
"!abcdefghijklmnopqrstuvwxyz%%ABCDEFGHIJKLMNOPQRSTUVQXYZ0123456789-_.~=" to "!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", "%#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", "\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",
) )

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2001-2023 the original author or authors. * Copyright 2001-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 = internal fun lowSurrogateOf(codePoint: Int): Char =
((codePoint and 0x3FF) + MIN_LOW_SURROGATE.code).toChar() ((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 MAX_CODE_POINT: Int = 0x10FFFF
private const val MIN_SUPPLEMENTARY_CODE_POINT: Int = 0x10000 private const val MIN_SUPPLEMENTARY_CODE_POINT: Int = 0x10000
private const val SURROGATE_DECODE_OFFSET: Int = private const val SURROGATE_DECODE_OFFSET: Int =
MIN_SUPPLEMENTARY_CODE_POINT - MIN_SUPPLEMENTARY_CODE_POINT -
(MIN_HIGH_SURROGATE.code shl 10) - (MIN_HIGH_SURROGATE.code shl 10) -
MIN_LOW_SURROGATE.code MIN_LOW_SURROGATE.code
private const val HIGH_SURROGATE_ENCODE_OFFSET: Char = MIN_HIGH_SURROGATE - (MIN_SUPPLEMENTARY_CODE_POINT ushr 10) private const val HIGH_SURROGATE_ENCODE_OFFSET: Char = MIN_HIGH_SURROGATE - (MIN_SUPPLEMENTARY_CODE_POINT ushr 10)
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2001-2023 the original author or authors. * Copyright 2001-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View file

@ -0,0 +1,43 @@
/*
* 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,
)

View file

@ -1,5 +1,5 @@
/* /*
* Copyright 2001-2023 the original author or authors. * Copyright 2001-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -23,30 +23,17 @@ import kotlin.test.DefaultAsserter.assertEquals
import kotlin.test.DefaultAsserter.assertSame import kotlin.test.DefaultAsserter.assertSame
class UrlEncoderUtilTest { 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 @Test
fun decodeURL() { fun decodeURL() {
for (m in validMap) { for ((unencoded, encoded) in decodedToEncoded) {
assertEquals(m.first, decode(m.second)) assertEquals(unencoded, decode(encoded))
} }
} }
@Test @Test
fun decodeWithException() { fun decodeWithException() {
for (source in invalid) { for (source in invalidContent) {
assertFailsWith<IllegalArgumentException>( assertFailsWith<IllegalArgumentException>(
message = "decode($source)", message = "decode($source)",
block = { decode(source) } block = { decode(source) }
@ -56,7 +43,7 @@ class UrlEncoderUtilTest {
@Test @Test
fun decodeWhenNoneNeeded() { fun decodeWhenNoneNeeded() {
assertSame(same, decode(same)) assertSame(standardContent, decode(standardContent))
assertEquals("decode('')", decode(""), "") assertEquals("decode('')", decode(""), "")
assertEquals("decode(' ')", decode(" "), " ") assertEquals("decode(' ')", decode(" "), " ")
} }
@ -72,8 +59,8 @@ class UrlEncoderUtilTest {
@Test @Test
fun encodeURL() { fun encodeURL() {
for (m in validMap) { for ((unencoded, encoded) in decodedToEncoded) {
assertEquals(m.second, encode(m.first)) assertEquals(encoded, encode(unencoded))
} }
} }
@ -86,8 +73,8 @@ class UrlEncoderUtilTest {
@Test @Test
fun encodeWhenNoneNeeded() { fun encodeWhenNoneNeeded() {
assertSame(encode(same), same) assertSame(encode(standardContent), standardContent)
assertSame("with empty allow", encode(same, allow = ""), same) assertSame("with empty allow", encode(standardContent, allow = ""), standardContent)
} }
@Test @Test

View file

@ -0,0 +1,50 @@
/*
* 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))
)
);
}
}