mirror of
https://github.com/gbevin/urlencoder.git
synced 2025-04-25 07:17:11 -07:00
Migrated to bld
This commit is contained in:
parent
baa1784ca1
commit
6f8fc8df36
30 changed files with 349 additions and 573 deletions
BIN
lib/bld/bld-wrapper.jar
Normal file
BIN
lib/bld/bld-wrapper.jar
Normal file
Binary file not shown.
6
lib/bld/bld-wrapper.properties
Normal file
6
lib/bld/bld-wrapper.properties
Normal file
|
@ -0,0 +1,6 @@
|
|||
bld.downloadExtensionJavadoc=false
|
||||
bld.downloadExtensionSources=true
|
||||
bld.extensions=com.uwyn.rife2:bld-tests-badge:0.9.3
|
||||
bld.repositories=MAVEN_CENTRAL,RIFE2
|
||||
rife2.downloadLocation=
|
||||
rife2.version=1.5.17
|
|
@ -1,160 +0,0 @@
|
|||
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
|
||||
import org.gradle.api.tasks.testing.logging.TestLogEvent
|
||||
import java.net.*
|
||||
import java.net.http.*
|
||||
|
||||
plugins {
|
||||
application
|
||||
`java-library`
|
||||
`maven-publish`
|
||||
signing
|
||||
jacoco
|
||||
id("org.sonarqube") version "4.0.0.2929"
|
||||
}
|
||||
|
||||
group = "com.uwyn"
|
||||
version = "1.3.1-SNAPSHOT"
|
||||
|
||||
val mavenName = "UrlEncoder"
|
||||
val javaMainClass = "$group.${rootProject.name}.$mavenName"
|
||||
|
||||
base {
|
||||
archivesName.set(rootProject.name)
|
||||
}
|
||||
|
||||
java {
|
||||
withJavadocJar()
|
||||
withSourcesJar()
|
||||
sourceCompatibility = JavaVersion.VERSION_11
|
||||
targetCompatibility = JavaVersion.VERSION_11
|
||||
}
|
||||
|
||||
application {
|
||||
mainClass.set(javaMainClass)
|
||||
}
|
||||
|
||||
sonarqube {
|
||||
properties {
|
||||
property("sonar.projectName", rootProject.name)
|
||||
property("sonar.projectKey", "gbevin_${rootProject.name}")
|
||||
property("sonar.organization", "gbevin")
|
||||
property("sonar.host.url", "https://sonarcloud.io")
|
||||
property("sonar.sourceEncoding", "UTF-8")
|
||||
}
|
||||
}
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testImplementation("org.junit.jupiter:junit-jupiter:5.9.0")
|
||||
}
|
||||
|
||||
tasks {
|
||||
jar {
|
||||
manifest {
|
||||
attributes["Main-Class"] = javaMainClass
|
||||
}
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
testLogging {
|
||||
exceptionFormat = TestExceptionFormat.FULL
|
||||
events = setOf(TestLogEvent.PASSED, TestLogEvent.SKIPPED, TestLogEvent.FAILED)
|
||||
}
|
||||
addTestListener(object : TestListener {
|
||||
override fun beforeTest(p0: TestDescriptor?) = Unit
|
||||
override fun beforeSuite(p0: TestDescriptor?) = Unit
|
||||
override fun afterTest(desc: TestDescriptor, result: TestResult) = Unit
|
||||
override fun afterSuite(desc: TestDescriptor, result: TestResult) {
|
||||
if (desc.parent == null) {
|
||||
val passed = result.successfulTestCount
|
||||
val failed = result.failedTestCount
|
||||
val skipped = result.skippedTestCount
|
||||
|
||||
if (project.properties["testsBadgeApiKey"] != null) {
|
||||
val apiKey = project.properties["testsBadgeApiKey"]
|
||||
val response: HttpResponse<String> = HttpClient.newHttpClient()
|
||||
.send(
|
||||
HttpRequest.newBuilder()
|
||||
.uri(
|
||||
URI(
|
||||
"https://rife2.com/tests-badge/update/com.uwyn/urlencoder?" +
|
||||
"apiKey=$apiKey&" +
|
||||
"passed=$passed&" +
|
||||
"failed=$failed&" +
|
||||
"skipped=$skipped"
|
||||
)
|
||||
)
|
||||
.POST(HttpRequest.BodyPublishers.noBody())
|
||||
.build(), HttpResponse.BodyHandlers.ofString()
|
||||
)
|
||||
println("RESPONSE: " + response.statusCode())
|
||||
println(response.body())
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
jacocoTestReport {
|
||||
reports {
|
||||
xml.required.set(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
create<MavenPublication>("mavenJava") {
|
||||
artifactId = rootProject.name
|
||||
from(components["java"])
|
||||
pom {
|
||||
name.set(mavenName)
|
||||
description.set("A simple defensive library to encode/decode URL components")
|
||||
url.set("https://github.com/gbevin/urlencoder")
|
||||
licenses {
|
||||
license {
|
||||
name.set("The Apache License, Version 2.0")
|
||||
url.set("http://www.apache.org/licenses/LICENSE-2.0.txt")
|
||||
}
|
||||
}
|
||||
developers {
|
||||
developer {
|
||||
id.set("gbevin")
|
||||
name.set("Geert Bevin")
|
||||
email.set("gbevin@uwyn.com")
|
||||
url.set("https://github.com/gbevin")
|
||||
}
|
||||
developer {
|
||||
id.set("ethauvin")
|
||||
name.set("Erik C. Thauvin")
|
||||
email.set("erik@thauvin.net")
|
||||
url.set("https://erik.thauvin.net/")
|
||||
}
|
||||
}
|
||||
scm {
|
||||
connection.set("scm:git:https://github.com/gbevin/urlencoder.git")
|
||||
developerConnection.set("scm:git:git@github.com:gbevin/urlencoder.git")
|
||||
url.set("https://github.com/gbevin/urlencoder")
|
||||
}
|
||||
}
|
||||
repositories {
|
||||
maven {
|
||||
credentials {
|
||||
username = project.properties["ossrhUsername"].toString()
|
||||
password = project.properties["ossrhPassword"].toString()
|
||||
}
|
||||
val releasesRepoUrl = uri("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/")
|
||||
val snapshotsRepoUrl = uri("https://s01.oss.sonatype.org/content/repositories/snapshots/")
|
||||
url = if (version.toString().endsWith("SNAPSHOT")) snapshotsRepoUrl else releasesRepoUrl
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
signing {
|
||||
sign(publishing.publications["mavenJava"])
|
||||
}
|
|
@ -1,339 +0,0 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
package com.uwyn.urlencoder;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.BitSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Most defensive approach to URL encoding and decoding.
|
||||
* <p>
|
||||
* Rules determined by combining the unreserved character set from
|
||||
* <a href="https://www.rfc-editor.org/rfc/rfc3986#page-13">RFC 3986</a> with
|
||||
* the percent-encode set from
|
||||
* <a href="https://url.spec.whatwg.org/#application-x-www-form-urlencoded-percent-encode-set">application/x-www-form-urlencoded</a>.
|
||||
* <p>
|
||||
* Both specs above support percent decoding of two hexadecimal digits to a
|
||||
* binary octet, however their unreserved set of characters differs and
|
||||
* {@code application/x-www-form-urlencoded} adds conversion of space to +,
|
||||
* which has the potential to be misunderstood.
|
||||
* <p>
|
||||
* This class encodes with rules that will be decoded correctly in either case.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @author Erik C. Thauvin (erik@thauvin.net)
|
||||
* @since 1.0
|
||||
*/
|
||||
public final class UrlEncoder {
|
||||
static final BitSet UNRESERVED_URI_CHARS;
|
||||
private static final char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray();
|
||||
|
||||
static {
|
||||
// see https://www.rfc-editor.org/rfc/rfc3986#page-13
|
||||
// and https://url.spec.whatwg.org/#application-x-www-form-urlencoded-percent-encode-set
|
||||
var unreserved = new BitSet('z' + 1);
|
||||
unreserved.set('-');
|
||||
unreserved.set('.');
|
||||
for (int c = '0'; c <= '9'; ++c) unreserved.set(c);
|
||||
for (int c = 'A'; c <= 'Z'; ++c) unreserved.set(c);
|
||||
unreserved.set('_');
|
||||
for (int c = 'a'; c <= 'z'; ++c) unreserved.set(c);
|
||||
UNRESERVED_URI_CHARS = unreserved;
|
||||
}
|
||||
|
||||
private UrlEncoder() {
|
||||
// no-op
|
||||
}
|
||||
|
||||
private static void appendUrlEncodedByte(StringBuilder out, int ch) {
|
||||
out.append("%");
|
||||
appendUrlEncodedDigit(out, ch >> 4);
|
||||
appendUrlEncodedDigit(out, ch);
|
||||
}
|
||||
|
||||
private static void appendUrlEncodedDigit(StringBuilder out, int digit) {
|
||||
out.append(HEX_DIGITS[digit & 0x0F]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a provided <code>String</code> URL into a new string,
|
||||
* containing decoded URL characters in the UTF-8 encoding.
|
||||
*
|
||||
* @param source The string URL that has to be decoded
|
||||
* @return The decoded <code>String</code> object.
|
||||
* @see #encode(String, String)
|
||||
* @since 1.0
|
||||
*/
|
||||
public static String decode(String source) {
|
||||
return decode(source, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a provided <code>String</code> URL into a new string,
|
||||
* containing decoded URL characters in the UTF-8 encoding.
|
||||
*
|
||||
* @param source The string URL that has to be decoded
|
||||
* @param plusToSpace Convert any {@code +} to space.
|
||||
* @return The decoded <code>String</code> object.
|
||||
* @see #encode(String, String)
|
||||
* @since 1.0
|
||||
*/
|
||||
public static String decode(String source, boolean plusToSpace) {
|
||||
if (source == null || source.isEmpty()) {
|
||||
return source;
|
||||
}
|
||||
|
||||
var length = source.length();
|
||||
StringBuilder out = null;
|
||||
char ch;
|
||||
byte[] bytes_buffer = null;
|
||||
var bytes_pos = 0;
|
||||
var i = 0;
|
||||
while (i < length) {
|
||||
ch = source.charAt(i);
|
||||
|
||||
if (ch == '%') {
|
||||
out = startConstructingIfNeeded(out, source, i);
|
||||
|
||||
if (bytes_buffer == null) {
|
||||
// the remaining characters divided by the length
|
||||
// of the encoding format %xx, is the maximum number of
|
||||
// bytes that can be extracted
|
||||
bytes_buffer = new byte[(length - i) / 3];
|
||||
}
|
||||
|
||||
i += 1;
|
||||
if (length < i + 2) {
|
||||
throw new IllegalArgumentException("Illegal escape sequence");
|
||||
}
|
||||
try {
|
||||
var v = Integer.parseInt(source, i, i + 2, 16);
|
||||
if (v < 0 || v > 0xFF) {
|
||||
throw new IllegalArgumentException("Illegal escape value");
|
||||
}
|
||||
|
||||
bytes_buffer[bytes_pos++] = (byte) v;
|
||||
|
||||
i += 2;
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException("Illegal characters in escape sequence: " + e.getMessage(), e);
|
||||
}
|
||||
} else {
|
||||
if (bytes_buffer != null) {
|
||||
out.append(new String(bytes_buffer, 0, bytes_pos, StandardCharsets.UTF_8));
|
||||
|
||||
bytes_buffer = null;
|
||||
bytes_pos = 0;
|
||||
}
|
||||
|
||||
if (plusToSpace && ch == '+') {
|
||||
out = startConstructingIfNeeded(out, source, i);
|
||||
out.append(" ");
|
||||
} else if (out != null) {
|
||||
out.append(ch);
|
||||
}
|
||||
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (out == null) {
|
||||
return source;
|
||||
}
|
||||
|
||||
if (bytes_buffer != null) {
|
||||
out.append(new String(bytes_buffer, 0, bytes_pos, StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
private static StringBuilder startConstructingIfNeeded(StringBuilder out, String source, int currentSourcePosition) {
|
||||
if (out == null) {
|
||||
out = new StringBuilder(source.length());
|
||||
out.append(source, 0, currentSourcePosition);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a provided <code>String</code> object into a new string,
|
||||
* containing only valid URL characters in the UTF-8 encoding.
|
||||
*
|
||||
* @param source The string that has to be transformed into a valid URL
|
||||
* string.
|
||||
* @return The encoded <code>String</code> object.
|
||||
* @see #decode(String)
|
||||
* @since 1.0
|
||||
*/
|
||||
public static String encode(String source) {
|
||||
return encode(source, null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a provided <code>String</code> object into a new string,
|
||||
* containing only valid URL characters in the UTF-8 encoding.
|
||||
*
|
||||
* @param source The string that has to be transformed into a valid URL
|
||||
* string.
|
||||
* @param allow Additional characters to allow.
|
||||
* @return The encoded <code>String</code> object.
|
||||
* @see #decode(String)
|
||||
* @since 1.0
|
||||
*/
|
||||
public static String encode(String source, String allow) {
|
||||
return encode(source, allow, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a provided <code>String</code> object into a new string,
|
||||
* containing only valid URL characters in the UTF-8 encoding.
|
||||
*
|
||||
* @param source The string that has to be transformed into a valid URL
|
||||
* string.
|
||||
* @param spaceToPlus Convert any space to {@code +}.
|
||||
* @return The encoded <code>String</code> object.
|
||||
* @see #decode(String)
|
||||
* @since 1.0
|
||||
*/
|
||||
public static String encode(String source, boolean spaceToPlus) {
|
||||
return encode(source, null, spaceToPlus);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a provided <code>String</code> object into a new string,
|
||||
* containing only valid URL characters in the UTF-8 encoding.
|
||||
*
|
||||
* @param source The string that has to be transformed into a valid URL
|
||||
* string.
|
||||
* @param allow Additional characters to allow.
|
||||
* @param spaceToPlus Convert any space to {@code +}.
|
||||
* @return The encoded <code>String</code> object.
|
||||
* @see #decode(String)
|
||||
* @since 1.0
|
||||
*/
|
||||
public static String encode(String source, String allow, boolean spaceToPlus) {
|
||||
if (source == null || source.isEmpty()) {
|
||||
return source;
|
||||
}
|
||||
|
||||
StringBuilder out = null;
|
||||
char ch;
|
||||
var i = 0;
|
||||
while (i < source.length()) {
|
||||
ch = source.charAt(i);
|
||||
if (isUnreservedUriChar(ch) || (allow != null && allow.indexOf(ch) != -1)) {
|
||||
if (out != null) {
|
||||
out.append(ch);
|
||||
}
|
||||
i += 1;
|
||||
} else {
|
||||
out = startConstructingIfNeeded(out, source, i);
|
||||
|
||||
var cp = source.codePointAt(i);
|
||||
if (cp < 0x80) {
|
||||
if (spaceToPlus && ch == ' ') {
|
||||
out.append('+');
|
||||
} else {
|
||||
appendUrlEncodedByte(out, cp);
|
||||
}
|
||||
i += 1;
|
||||
} else if (Character.isBmpCodePoint(cp)) {
|
||||
for (var b : Character.toString(ch).getBytes(StandardCharsets.UTF_8)) {
|
||||
appendUrlEncodedByte(out, b);
|
||||
}
|
||||
i += 1;
|
||||
} else if (Character.isSupplementaryCodePoint(cp)) {
|
||||
var high = Character.highSurrogate(cp);
|
||||
var low = Character.lowSurrogate(cp);
|
||||
for (var b : new String(new char[]{high, low}).getBytes(StandardCharsets.UTF_8)) {
|
||||
appendUrlEncodedByte(out, b);
|
||||
}
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (out == null) {
|
||||
return source;
|
||||
}
|
||||
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
// see https://www.rfc-editor.org/rfc/rfc3986#page-13
|
||||
// and https://url.spec.whatwg.org/#application-x-www-form-urlencoded-percent-encode-set
|
||||
private static boolean isUnreservedUriChar(char ch) {
|
||||
return ch <= 'z' && UNRESERVED_URI_CHARS.get(ch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Main method to encode/decode URLs on the command line
|
||||
*
|
||||
* @param arguments the command line arguments
|
||||
* @since 1.1
|
||||
*/
|
||||
public static void main(String[] arguments) {
|
||||
try {
|
||||
var result = processMain(arguments);
|
||||
if (result.status == 0) {
|
||||
System.out.println(result.output);
|
||||
} else {
|
||||
System.err.println(result.output);
|
||||
}
|
||||
System.exit(result.status);
|
||||
} catch (IllegalArgumentException e) {
|
||||
System.err.println(UrlEncoder.class.getSimpleName() + ": " + e.getMessage());
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static MainResult processMain(String... arguments) {
|
||||
var valid_arguments = false;
|
||||
var perform_decode = false;
|
||||
var args = new ArrayList<>(List.of(arguments));
|
||||
if (!args.isEmpty() && args.get(0).startsWith("-")) {
|
||||
var option = args.remove(0);
|
||||
if (("-d").equals(option)) {
|
||||
perform_decode = true;
|
||||
valid_arguments = (args.size() == 1);
|
||||
} else if (("-e").equals(option)) {
|
||||
valid_arguments = (args.size() == 1);
|
||||
} else {
|
||||
args.clear();
|
||||
}
|
||||
}
|
||||
|
||||
var text = "";
|
||||
if (args.size() == 1 && !args.get(0).isEmpty()) {
|
||||
text = args.remove(0);
|
||||
valid_arguments = true;
|
||||
}
|
||||
|
||||
if (!valid_arguments) {
|
||||
return new MainResult("Usage : java -jar urlencoder-*.jar [-ed] text" + System.lineSeparator() +
|
||||
"Encode and decode URL components defensively." + System.lineSeparator() +
|
||||
" -e encode (default)" + System.lineSeparator() +
|
||||
" -d decode", 1);
|
||||
}
|
||||
if (perform_decode) {
|
||||
return new MainResult(UrlEncoder.decode(text), 0);
|
||||
} else {
|
||||
return new MainResult(UrlEncoder.encode(text), 0);
|
||||
}
|
||||
}
|
||||
|
||||
static class MainResult {
|
||||
final String output;
|
||||
final int status;
|
||||
|
||||
public MainResult(String output, int status) {
|
||||
this.output = output;
|
||||
this.status = status;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,169 +0,0 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
package com.uwyn.urlencoder;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.junit.jupiter.params.provider.Arguments.arguments;
|
||||
|
||||
class UrlEncoderTest {
|
||||
private final String same = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVQXYZ0123456789-_.";
|
||||
|
||||
private static Stream<String> invalid() {
|
||||
return Stream.of("sdkjfh%", "sdkjfh%6", "sdkjfh%xx", "sdfjfh%-1");
|
||||
}
|
||||
|
||||
private static Stream<Arguments> validMap() {
|
||||
return Stream.of(
|
||||
arguments("a test &", "a%20test%20%26"),
|
||||
arguments(
|
||||
"!abcdefghijklmnopqrstuvwxyz%%ABCDEFGHIJKLMNOPQRSTUVQXYZ0123456789-_.~=",
|
||||
"%21abcdefghijklmnopqrstuvwxyz%25%25ABCDEFGHIJKLMNOPQRSTUVQXYZ0123456789-_.%7E%3D"
|
||||
),
|
||||
arguments("%#okékÉȢ smile!😁", "%25%23ok%C3%A9k%C3%89%C8%A2%20smile%21%F0%9F%98%81"),
|
||||
arguments(
|
||||
"\uD808\uDC00\uD809\uDD00\uD808\uDF00\uD808\uDD00",
|
||||
"%F0%92%80%80%F0%92%94%80%F0%92%8C%80%F0%92%84%80"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDecodeNotNeeded() {
|
||||
assertSame(same, UrlEncoder.decode(same));
|
||||
assertEquals("", UrlEncoder.decode(""), "decode('')");
|
||||
assertEquals(" ", UrlEncoder.decode(" "), "decode(' ')");
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "decode({0}) should be {1}")
|
||||
@MethodSource("validMap")
|
||||
void testDecodeUrl(String expected, String source) {
|
||||
assertEquals(expected, UrlEncoder.decode(source));
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "decode({0})")
|
||||
@MethodSource("invalid")
|
||||
void testDecodeWithException(String source) {
|
||||
assertThrows(IllegalArgumentException.class, () -> UrlEncoder.decode(source), "decode(" + source + ")");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDecodeWithNull() {
|
||||
assertNull(UrlEncoder.decode(null), "decode(null)");
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "encode({0}) should be {1}")
|
||||
@MethodSource("validMap")
|
||||
void testEncodeUrl(String source, String expected) {
|
||||
assertEquals(expected, UrlEncoder.encode(source));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEncodeWhenNoneNeeded() {
|
||||
assertSame(same, UrlEncoder.encode(same));
|
||||
assertSame(same, UrlEncoder.encode(same, ""), "with empty allow");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEncodeWithAllowArg() {
|
||||
assertEquals("?test=a%20test", UrlEncoder.encode("?test=a test", "=?"), "encode(x, =?)");
|
||||
assertEquals("aaa", UrlEncoder.encode("aaa", "a"), "encode(aaa, a)");
|
||||
assertEquals(" ", UrlEncoder.encode(" ", " "), "encode(' ', ' ')");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEncodeWithEmptyOrBlank() {
|
||||
assertTrue(UrlEncoder.encode("", "").isEmpty(), "encode('','')");
|
||||
assertEquals("", UrlEncoder.encode(""), "encode('')");
|
||||
assertEquals("%20", UrlEncoder.encode(" "), "encode('')");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEncodeWithNulls() {
|
||||
assertNull(UrlEncoder.encode(null), "encode(null)");
|
||||
assertNull(UrlEncoder.encode(null, null), "encode(null, null)");
|
||||
assertEquals("foo", UrlEncoder.encode("foo", null), "encode(foo, null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEncodeSpaceToPlus() {
|
||||
assertEquals("foo+bar", UrlEncoder.encode("foo bar", true));
|
||||
assertEquals("foo+bar++foo", UrlEncoder.encode("foo bar foo", true));
|
||||
assertEquals("foo bar", UrlEncoder.encode("foo bar", " ", true));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDecodePlusToSpace() {
|
||||
assertEquals("foo bar", UrlEncoder.decode("foo+bar", true));
|
||||
assertEquals("foo bar foo", UrlEncoder.decode("foo+bar++foo", true));
|
||||
assertEquals("foo bar foo", UrlEncoder.decode("foo+%20bar%20+foo", true));
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "processMain(-d {1}) should be {0}")
|
||||
@MethodSource("validMap")
|
||||
void testMainDecode(String expected, String source) {
|
||||
var result = UrlEncoder.processMain("-d", source);
|
||||
assertEquals(expected, result.output);
|
||||
assertEquals(0, result.status, "processMain(-d " + source + ").status");
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "processMain(-e {0})")
|
||||
@MethodSource("validMap")
|
||||
void testMainEncode(String source, String expected) {
|
||||
var result = UrlEncoder.processMain(source);
|
||||
assertEquals(expected, result.output);
|
||||
assertEquals(0, result.status, "processMain(-e " + source + ").status");
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "processMain(-d {0})")
|
||||
@MethodSource("invalid")
|
||||
void testMainEncodeWithExceptions(String source) {
|
||||
assertThrows(IllegalArgumentException.class, () -> UrlEncoder.processMain("-d", source), source);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMainTooManyArgs() {
|
||||
assertTrue(UrlEncoder.processMain("foo", "bar", "test").output.contains("Usage :"), "too many args");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMainWithEmptyArgs() {
|
||||
assertTrue(UrlEncoder.processMain(" ", " ").output.contains("Usage :"), "processMain(' ', ' ')");
|
||||
assertTrue(UrlEncoder.processMain("foo", " ").output.contains("Usage :"), "processMain('foo', ' ')");
|
||||
assertTrue(UrlEncoder.processMain(" ", "foo").output.contains("Usage :"), "processMain(' ', 'foo')");
|
||||
assertTrue(UrlEncoder.processMain("-d ", "").output.contains("Usage :"), "processMain('-d', '')");
|
||||
assertEquals("%20", UrlEncoder.processMain(new String[]{"-e", " "}).output, "processMain('-e', ' ')");
|
||||
assertEquals(" ", UrlEncoder.processMain(new String[]{"-d", " "}).output, "processMain('-d', ' ')");
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"", "-d", "-e"})
|
||||
void testMainWithInvalidArgs(String arg) {
|
||||
var result = UrlEncoder.processMain(arg);
|
||||
assertTrue(result.output.contains("Usage :"), "processMain('" + arg + "')");
|
||||
assertEquals(1, result.status, "processMain('" + arg + "').status");
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "processMain(-e {0})")
|
||||
@MethodSource("validMap")
|
||||
void testMainWithOption(String source, String expected) {
|
||||
var result = UrlEncoder.processMain("-e", source);
|
||||
assertEquals(expected, result.output);
|
||||
assertEquals(0, result.status, "processMain(-e " + source + ").status");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMainWithUnknownOptions() {
|
||||
assertTrue(UrlEncoder.processMain("-p").output.contains("Usage :"), "processMain(-p)");
|
||||
assertTrue(UrlEncoder.processMain("-").output.contains("Usage :"), "processMain(-)");
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue