Compare commits
34 commits
Author | SHA1 | Date | |
---|---|---|---|
b882d68d4c | |||
9e60b31f9e | |||
c69d7b7076 | |||
742c221a20 | |||
0b6e55b338 | |||
09b44d53e8 | |||
df7482c3a0 | |||
3e36e389fb | |||
d66fdb12e6 | |||
|
6f33f9c2a9 | ||
dd3d500496 | |||
|
c801a9703f | ||
1ef2045b32 | |||
|
d03c61cb92 | ||
a689c56e1e | |||
b59d01ec6d | |||
|
8890fef665 | ||
|
171570159e | ||
61137e0878 | |||
f3fc266c6f | |||
7817198be1 | |||
b9791dc507 | |||
ee35984130 | |||
05d4a52240 | |||
8ebc178474 | |||
404ca93137 | |||
2523b31073 | |||
6acf3417e5 | |||
f711cf719f | |||
ebdc9ceef8 | |||
9f3803bdcd | |||
5b46ff448c | |||
d790a02365 | |||
7ea75e30e7 |
24 changed files with 361 additions and 382 deletions
26
.github/workflows/gradle.yml
vendored
26
.github/workflows/gradle.yml
vendored
|
@ -17,7 +17,7 @@ jobs:
|
|||
build:
|
||||
strategy:
|
||||
matrix:
|
||||
java-version: [ 11, 17, 20 ]
|
||||
java-version: [8, 11, 17, 21]
|
||||
os:
|
||||
- macos-latest
|
||||
- ubuntu-latest
|
||||
|
@ -28,27 +28,25 @@ jobs:
|
|||
GRADLE_OPTS: "-Dorg.gradle.jvmargs=-XX:MaxMetaspaceSize=512m"
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up JDK ${{ matrix.java-version }}
|
||||
uses: actions/setup-java@v3
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'zulu'
|
||||
distribution: "zulu"
|
||||
java-version: ${{ matrix.java-version }}
|
||||
|
||||
- name: Validate Gradle wrapper
|
||||
uses: gradle/wrapper-validation-action@v1
|
||||
uses: gradle/wrapper-validation-action@v2
|
||||
|
||||
- name: Cache Kotlin Konan
|
||||
id: cache-kotlin-konan
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.konan/**/*
|
||||
path: ~/.konan/**/*
|
||||
key: kotlin-konan-${{ runner.os }}
|
||||
|
||||
- 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 }}
|
||||
- name: Set up Gradle
|
||||
uses: gradle/actions/setup-gradle@v3
|
||||
|
||||
- name: Publish
|
||||
run: ./gradlew check build --stacktrace -PtestsBadgeApiKey=${{ secrets.TESTS_BADGE_API_KEY }}
|
||||
|
|
97
.github/workflows/publish.yml
vendored
97
.github/workflows/publish.yml
vendored
|
@ -4,90 +4,41 @@ 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-base:
|
||||
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:
|
||||
publish:
|
||||
runs-on: macos-latest
|
||||
strategy:
|
||||
max-parallel: 6
|
||||
matrix:
|
||||
target:
|
||||
- publishMacosArm64PublicationToOSSRHRepository
|
||||
- publishMacosX64PublicationToOSSRHRepository
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up JDK ${{ env.JAVA_VERSION }}
|
||||
uses: actions/setup-java@v3
|
||||
- name: Set up JDK
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: ${{ env.JAVA_VERSION }}
|
||||
distribution: ${{ env.JAVA_DISTRIBUTION }}
|
||||
java-version: "21"
|
||||
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
|
||||
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
|
||||
run: ./gradlew publish --no-parallel --stacktrace
|
||||
|
|
29
README.md
29
README.md
|
@ -1,5 +1,5 @@
|
|||
[](https://opensource.org/licenses/Apache-2.0)
|
||||
[](https://kotlinlang.org/)
|
||||
[](https://kotlinlang.org/)
|
||||
[](https://oss.sonatype.org/content/repositories/snapshots/net/thauvin/erik/urlencoder/)
|
||||
[](https://github.com/ethauvin/urlencoder/releases/latest)
|
||||
[](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
|
||||
`UriUtils` in Spring.
|
||||
|
||||
|
||||
## Examples (TL;DR)
|
||||
|
||||
```kotlin
|
||||
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.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.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
|
||||
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
|
||||
```
|
||||
|
||||
## Gradle, Maven, etc.
|
||||
|
@ -61,7 +60,7 @@ repositories {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
implementation("net.thauvin.erik.urlencoder:urlencoder-lib:1.4.0")
|
||||
implementation("net.thauvin.erik.urlencoder:urlencoder-lib:1.6.0")
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -72,7 +71,7 @@ to the artifact URL.
|
|||
<dependency>
|
||||
<groupId>net.thauvin.erik.urlencoder</groupId>
|
||||
<artifactId>urlencoder-lib-jvm</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.6.0</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
|
@ -90,7 +89,7 @@ You have two options:
|
|||
|
||||
The usage is as follows:
|
||||
|
||||
```
|
||||
```console
|
||||
Encode and decode URL components defensively.
|
||||
-e encode (default)
|
||||
-d decode
|
||||
|
@ -98,7 +97,7 @@ Encode and decode URL components defensively.
|
|||
|
||||
### Running with Gradle
|
||||
|
||||
```shell
|
||||
```console
|
||||
./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
|
||||
|
||||
|
@ -109,13 +108,13 @@ Encode and decode URL components defensively.
|
|||
|
||||
First build the jar file:
|
||||
|
||||
```shell
|
||||
```console
|
||||
./gradlew fatJar
|
||||
```
|
||||
|
||||
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 "%#okékÉȢ" # -> %25%23ok%C3%A9k%C3%89%C8%A2
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ plugins {
|
|||
}
|
||||
|
||||
group = "net.thauvin.erik.urlencoder"
|
||||
version = "1.4.0"
|
||||
version = "1.6.0"
|
||||
|
||||
dependencies {
|
||||
kover(projects.urlencoderLib)
|
||||
|
|
|
@ -3,9 +3,10 @@ plugins {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
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")
|
||||
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")
|
||||
}
|
|
@ -3,7 +3,9 @@ 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
|
||||
|
||||
|
@ -24,39 +26,31 @@ plugins {
|
|||
kotlin {
|
||||
//jvmToolchain(11)
|
||||
|
||||
targets.configureEach {
|
||||
compilations.configureEach {
|
||||
kotlinOptions {
|
||||
languageVersion = "1.6"
|
||||
}
|
||||
}
|
||||
applyDefaultHierarchyTemplate()
|
||||
|
||||
@OptIn(ExperimentalKotlinGradlePluginApi::class)
|
||||
compilerOptions {
|
||||
languageVersion = KotlinVersion.KOTLIN_1_6
|
||||
}
|
||||
|
||||
// configure all Kotlin/JVM Tests to use JUnit
|
||||
targets.withType<KotlinJvmTarget>().configureEach {
|
||||
testRuns.configureEach {
|
||||
executionTask.configure {
|
||||
// useJUnitPlatform()
|
||||
useJUnitPlatform()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets.configureEach {
|
||||
languageSettings {
|
||||
// languageVersion =
|
||||
// apiVersion =
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks {
|
||||
withType<JavaCompile>().configureEach {
|
||||
sourceCompatibility = JavaVersion.VERSION_11.toString()
|
||||
targetCompatibility = JavaVersion.VERSION_11.toString()
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8.toString()
|
||||
targetCompatibility = JavaVersion.VERSION_1_8.toString()
|
||||
}
|
||||
|
||||
withType<KotlinJvmCompile>().configureEach {
|
||||
compilerOptions.jvmTarget.set(JvmTarget.JVM_11)
|
||||
compilerOptions.jvmTarget.set(JvmTarget.JVM_1_8)
|
||||
}
|
||||
|
||||
withType<Test>().configureEach {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package buildsrc.conventions.lang
|
||||
|
||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl
|
||||
|
||||
/** conventions for a Kotlin/JS subproject */
|
||||
|
||||
plugins {
|
||||
|
@ -7,12 +9,38 @@ plugins {
|
|||
}
|
||||
|
||||
kotlin {
|
||||
targets {
|
||||
js(IR) {
|
||||
browser()
|
||||
nodejs()
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalWasmDsl::class)
|
||||
wasmJs {
|
||||
browser()
|
||||
nodejs()
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalWasmDsl::class)
|
||||
wasmWasi {
|
||||
nodejs()
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -7,94 +7,26 @@ 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()
|
||||
|
||||
// https://kotlinlang.org/docs/multiplatform-share-on-platforms.html#use-target-shortcuts
|
||||
ios() // iosArm64, iosX64
|
||||
watchos() // watchosArm32, watchosArm64, watchosX64
|
||||
tvos() // tvosArm64, tvosX64
|
||||
|
||||
iosArm64()
|
||||
iosX64()
|
||||
iosSimulatorArm64()
|
||||
tvosSimulatorArm64()
|
||||
|
||||
watchosArm32()
|
||||
watchosArm64()
|
||||
watchosX64()
|
||||
watchosSimulatorArm64()
|
||||
watchosDeviceArm64()
|
||||
|
||||
@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) }
|
||||
}
|
||||
tvosArm64()
|
||||
tvosX64()
|
||||
tvosSimulatorArm64()
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
plugins {
|
||||
|
@ -98,9 +82,11 @@ signing {
|
|||
})
|
||||
}
|
||||
|
||||
tasks.withType<Sign>().configureEach {
|
||||
tasks {
|
||||
withType<Sign>().configureEach {
|
||||
val signingRequiredPredicate = provider { signing.isRequired }
|
||||
onlyIf { signingRequiredPredicate.get() }
|
||||
}
|
||||
}
|
||||
|
||||
// https://youtrack.jetbrains.com/issue/KT-46466
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Copyright 2022-2023 Erik C. Thauvin (erik@thauvin.net)
|
||||
* 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
|
||||
*
|
||||
* 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
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
|
@ -17,14 +16,13 @@
|
|||
|
||||
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<String>
|
||||
|
@ -42,23 +40,23 @@ class Rife2TestListener(
|
|||
|
||||
if (apiKey != null) {
|
||||
println(apiKey)
|
||||
val response: HttpResponse<String> = HttpClient.newHttpClient()
|
||||
.send(
|
||||
HttpRequest.newBuilder()
|
||||
.uri(
|
||||
URI(
|
||||
"https://rife2.com/tests-badge/update/net.thauvin.erik/urlencoder?" +
|
||||
val url = "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())
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,6 +1,6 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
|
21
gradlew
vendored
21
gradlew
vendored
|
@ -15,6 +15,8 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
|
@ -55,7 +57,7 @@
|
|||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (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.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
|
@ -84,7 +86,8 @@ 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 "${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.
|
||||
MAX_FD=maximum
|
||||
|
@ -145,7 +148,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=SC3045
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
|
@ -153,7 +156,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=SC3045
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
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.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# 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.
|
||||
# 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.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
|
|
22
gradlew.bat
vendored
22
gradlew.bat
vendored
|
@ -13,6 +13,8 @@
|
|||
@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 ##########################################################################
|
||||
|
@ -43,11 +45,11 @@ set JAVA_EXE=java.exe
|
|||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
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.
|
||||
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
|
||||
|
||||
goto fail
|
||||
|
||||
|
@ -57,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
|||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
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.
|
||||
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
|
||||
|
||||
goto fail
|
||||
|
||||
|
|
|
@ -20,14 +20,23 @@ dependencyResolutionManagement {
|
|||
|
||||
// Declare the Node.js & Yarn download repositories
|
||||
exclusiveContent {
|
||||
forRepository {
|
||||
forRepositories(
|
||||
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") }
|
||||
}
|
||||
}
|
||||
},
|
||||
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") }
|
||||
}
|
||||
|
||||
|
@ -37,7 +46,6 @@ dependencyResolutionManagement {
|
|||
name = "Yarn Distributions at $url"
|
||||
patternLayout { artifact("v[revision]/[artifact](-v[revision]).[ext]") }
|
||||
metadataSources { artifact() }
|
||||
content { includeModule("com.yarnpkg", "yarn") }
|
||||
}
|
||||
}
|
||||
filter { includeGroup("com.yarnpkg") }
|
||||
|
|
|
@ -1,17 +1,21 @@
|
|||
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 {
|
||||
|
@ -32,10 +36,6 @@ base {
|
|||
archivesName.set(rootProject.name)
|
||||
}
|
||||
|
||||
application {
|
||||
mainClass.set(urlEncoderMainClass)
|
||||
}
|
||||
|
||||
tasks {
|
||||
jvmJar {
|
||||
manifest {
|
||||
|
@ -45,14 +45,13 @@ 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 application.mainClass)) }
|
||||
from(sourceSets.main.get().output)
|
||||
manifest { attributes(mapOf("Main-Class" to urlEncoderMainClass)) }
|
||||
from(sourceSets.main.map { it.output })
|
||||
dependsOn(configurations.jvmRuntimeClasspath)
|
||||
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) }
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -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");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -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");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -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");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -59,7 +59,7 @@ 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
|
||||
|
|
|
@ -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");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -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,
|
||||
)
|
|
@ -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");
|
||||
* 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
|
||||
|
||||
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 (m in validMap) {
|
||||
assertEquals(m.first, decode(m.second))
|
||||
for ((unencoded, encoded) in decodedToEncoded) {
|
||||
assertEquals(unencoded, decode(encoded))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun decodeWithException() {
|
||||
for (source in invalid) {
|
||||
for (source in invalidContent) {
|
||||
assertFailsWith<IllegalArgumentException>(
|
||||
message = "decode($source)",
|
||||
block = { decode(source) }
|
||||
|
@ -56,7 +43,7 @@ class UrlEncoderUtilTest {
|
|||
|
||||
@Test
|
||||
fun decodeWhenNoneNeeded() {
|
||||
assertSame(same, decode(same))
|
||||
assertSame(standardContent, decode(standardContent))
|
||||
assertEquals("decode('')", decode(""), "")
|
||||
assertEquals("decode(' ')", decode(" "), " ")
|
||||
}
|
||||
|
@ -72,8 +59,8 @@ class UrlEncoderUtilTest {
|
|||
|
||||
@Test
|
||||
fun encodeURL() {
|
||||
for (m in validMap) {
|
||||
assertEquals(m.second, encode(m.first))
|
||||
for ((unencoded, encoded) in decodedToEncoded) {
|
||||
assertEquals(encoded, encode(unencoded))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,8 +73,8 @@ class UrlEncoderUtilTest {
|
|||
|
||||
@Test
|
||||
fun encodeWhenNoneNeeded() {
|
||||
assertSame(encode(same), same)
|
||||
assertSame("with empty allow", encode(same, allow = ""), same)
|
||||
assertSame(encode(standardContent), standardContent)
|
||||
assertSame("with empty allow", encode(standardContent, allow = ""), standardContent)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -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))
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue