Junit 5 update, matrix params, path trie

This commit is contained in:
Jörg Prante 2019-07-14 17:44:45 +02:00
parent 1f949104ef
commit bc84cfce4a
23 changed files with 989 additions and 375 deletions

View file

@ -6,20 +6,6 @@ plugins {
id "org.xbib.gradle.plugin.asciidoctor" version "1.5.6.0.1"
}
printf "Host: %s\nOS: %s %s %s\nJVM: %s %s %s %s\nGradle: %s Groovy: %s Java: %s\n" +
"Build: group: ${project.group} name: ${project.name} version: ${project.version}\n",
InetAddress.getLocalHost(),
System.getProperty("os.name"),
System.getProperty("os.arch"),
System.getProperty("os.version"),
System.getProperty("java.version"),
System.getProperty("java.vm.version"),
System.getProperty("java.vm.vendor"),
System.getProperty("java.vm.name"),
gradle.gradleVersion,
GroovySystem.getVersion(),
JavaVersion.current()
subprojects {
apply plugin: 'java'
@ -36,14 +22,15 @@ subprojects {
configurations {
asciidoclet
wagon
}
dependencies {
testCompile "junit:junit:${project.property('junit.version')}"
testCompile "com.fasterxml.jackson.core:jackson-databind:${project.property('jackson.version')}"
testImplementation "org.junit.jupiter:junit-jupiter-api:${project.property('junit.version')}"
testImplementation "org.junit.jupiter:junit-jupiter-params:${project.property('junit.version')}"
testImplementation "org.hamcrest:hamcrest-library:${project.property('hamcrest.version')}"
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${project.property('junit.version')}"
testImplementation "com.fasterxml.jackson.core:jackson-databind:${project.property('jackson.version')}"
asciidoclet "org.asciidoctor:asciidoclet:${project.property('asciidoclet.version')}"
wagon "org.apache.maven.wagon:wagon-ssh:${project.property('wagon.version')}"
}
compileJava {
@ -51,8 +38,8 @@ subprojects {
targetCompatibility = JavaVersion.VERSION_1_8
}
compileTestJava {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
tasks.withType(JavaCompile) {
options.compilerArgs << "-Xlint:all,-serial"
@ -69,12 +56,22 @@ subprojects {
}
test {
testLogging {
showStandardStreams = false
exceptionFormat = 'full'
}
useJUnitPlatform()
systemProperty 'java.net.preferIPv4Stack', 'false'
systemProperty 'java.net.preferIPv6Addresses', 'true'
failFast = false
testLogging {
events 'PASSED', 'FAILED', 'SKIPPED'
}
afterSuite { desc, result ->
if (!desc.parent) {
println "\nTest result: ${result.resultType}"
println "Test summary: ${result.testCount} tests, " +
"${result.successfulTestCount} succeeded, " +
"${result.failedTestCount} failed, " +
"${result.skippedTestCount} skipped"
}
}
}
asciidoctor {
@ -114,12 +111,6 @@ subprojects {
archives sourcesJar, javadocJar
}
if (project.hasProperty('signing.keyId')) {
signing {
sign configurations.archives
}
}
apply from: "${rootProject.projectDir}/gradle/publish.gradle"
tasks.withType(Checkstyle) {

View file

@ -1,10 +1,11 @@
group = org.xbib
name = net
version = 1.2.2
version = 1.3.3
# test
jackson.version = 2.8.11
junit.version = 4.12
wagon.version = 3.0.0
junit.version = 5.4.2
hamcrest.version = 2.1
asciidoclet.version = 1.5.4
org.gradle.warning.mode=all
org.gradle.warning.mode = all

View file

@ -6,7 +6,7 @@ ext {
scmDeveloperConnection = 'scm:git:git://github.com/xbib/net.git'
}
task xbibUpload(type: Upload) {
/*task xbibUpload(type: Upload) {
group = 'publish'
configuration = configurations.archives
uploadDescriptor = true
@ -20,7 +20,7 @@ task xbibUpload(type: Upload) {
}
}
}
}
}*/
task sonatypeUpload(type: Upload, dependsOn: build) {
group = 'publish'

View file

@ -1,5 +1,7 @@
package org.xbib.net;
import java.nio.charset.MalformedInputException;
import java.nio.charset.UnmappableCharacterException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@ -7,8 +9,15 @@ import java.util.stream.Collectors;
/**
* Query parameter list, of limited size. Default is 1024 pairs.
*/
@SuppressWarnings("serial")
public class QueryParameters extends ArrayList<QueryParameters.Pair<String, String>> {
private static final char AMPERSAND_CHAR = '&';
private static final char EQUAL_CHAR = '=';
private final PercentDecoder percentDecoder;
private final int max;
public QueryParameters() {
@ -17,6 +26,7 @@ public class QueryParameters extends ArrayList<QueryParameters.Pair<String, Stri
public QueryParameters(int max) {
this.max = max;
this.percentDecoder = new PercentDecoder();
}
public List<String> get(String key) {
@ -36,6 +46,34 @@ public class QueryParameters extends ArrayList<QueryParameters.Pair<String, Stri
return size() < max && super.add(element);
}
public QueryParameters addPercentEncodedBody(String body) throws MalformedInputException, UnmappableCharacterException {
String s = body;
while (s != null) {
Pair<String, String> pairs = indexOf(AMPERSAND_CHAR, s);
Pair<String, String> pair = indexOf(EQUAL_CHAR, pairs.getFirst());
if (!isNullOrEmpty(pair.getFirst())) {
add(percentDecoder.decode(pair.getFirst()),
percentDecoder.decode(pair.getSecond()));
}
s = pairs.getSecond();
}
return this;
}
/**
* Returns true if the parameter string is neither null nor empty.
*/
private static boolean isNullOrEmpty(String str) {
return str == null || str.isEmpty();
}
private static Pair<String, String> indexOf(char ch, String input) {
int i = input.indexOf(ch);
String k = i >= 0 ? input.substring(0, i) : input;
String v = i >= 0 ? input.substring(i + 1) : null;
return new Pair<>(k, v);
}
/**
* A pair of query parameters.
* @param <K> the key type parameter
@ -45,7 +83,7 @@ public class QueryParameters extends ArrayList<QueryParameters.Pair<String, Stri
private final K first;
private final V second;
public Pair(K first, V second) {
Pair(K first, V second) {
this.first = first;
this.second = second;
}

View file

@ -240,12 +240,12 @@ public class URL implements Comparable<URL> {
return new Parser();
}
public static Resolver base(URL base) {
return new Resolver(base);
public static Resolver base(String base) {
return base(URL.create(base));
}
public static Resolver base(String base) {
return new Resolver(URL.create(base));
public static Resolver base(URL base) {
return new Resolver(base);
}
private static final URL NULL_URL = URL.builder().build();
@ -416,6 +416,10 @@ public class URL implements Comparable<URL> {
return decode(path);
}
public List<PathSegment> getPathSegments() {
return builder.pathSegments;
}
/**
* Get the query ('?q=foo{@literal &}bar') of the {@code URL} if it exists.
* @return the query
@ -457,6 +461,20 @@ public class URL implements Comparable<URL> {
return !isNullOrEmpty(builder.scheme) && !isNullOrEmpty(builder.schemeSpecificPart) && builder.host == null;
}
/**
* Whether this is a hierarchical URL or not. That is, a URL that allows multiple path segments.
*
* The term <em>hierarchical</em> comes form the URI standard
* (<a href="https://www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>).
* Other libraries might refer to it as <em>relative</em> or <em>cannot-be-a-base-URL</em>.
* The later is the current WHATWG URL standard
* (see <a href="https://github.com/whatwg/url/issues/89">whatwg/url#89</a> for the rationale).
* @return true if URL is hierarchical
*/
public boolean isHierarchical() {
return !isOpaque();
}
/**
* @return true if URL is absolute.
*/
@ -645,7 +663,7 @@ public class URL implements Comparable<URL> {
return sb.length() == 0 ? null : sb.toString();
}
private void appendQuery(StringBuilder sb, boolean encoded, boolean withQuestionMark) {
private void appendQuery(StringBuilder sb, boolean withEncoding, boolean withQuestionMark) {
if (!builder.queryParams.isEmpty()) {
if (withQuestionMark) {
sb.append(QUESTION_CHAR);
@ -654,9 +672,9 @@ public class URL implements Comparable<URL> {
while (it.hasNext()) {
QueryParameters.Pair<String, String> queryParam = it.next();
try {
sb.append(encoded ? queryParamEncoder.encode(queryParam.getFirst()) : queryParam.getFirst());
sb.append(withEncoding ? queryParamEncoder.encode(queryParam.getFirst()) : queryParam.getFirst());
if (queryParam.getSecond() != null) {
sb.append(EQUAL_CHAR).append(encoded ?
sb.append(EQUAL_CHAR).append(withEncoding ?
queryParamEncoder.encode(queryParam.getSecond()) : queryParam.getSecond());
}
} catch (CharacterCodingException e) {
@ -670,7 +688,7 @@ public class URL implements Comparable<URL> {
if (withQuestionMark) {
sb.append(QUESTION_CHAR);
}
if (encoded) {
if (withEncoding) {
try {
sb.append(queryEncoder.encode(builder.query));
} catch (CharacterCodingException e) {
@ -898,10 +916,11 @@ public class URL implements Comparable<URL> {
}
public Builder pathSegment(String segment) {
if (pathSegments.isEmpty() && !isNullOrEmpty(host) && !isNullOrEmpty(segment)) {
pathSegments.add(EMPTY_SEGMENT);
if (pathSegments.isEmpty() && !isNullOrEmpty(host) && isNullOrEmpty(segment)) {
pathSegments.add(EMPTY_SEGMENT);
} else {
pathSegments.add(new PathSegment(segment));
}
pathSegments.add(new PathSegment(segment));
return this;
}
@ -1132,8 +1151,9 @@ public class URL implements Comparable<URL> {
}
}
private void parsePathWithQueryAndFragment(Builder builder, String input)
private void parsePathWithQueryAndFragment(Builder builder, String inputStr)
throws MalformedInputException, UnmappableCharacterException {
String input = inputStr;
if (input == null) {
return;
}
@ -1221,7 +1241,7 @@ public class URL implements Comparable<URL> {
private final URL base;
public Resolver(URL base) {
Resolver(URL base) {
this.base = base;
}
@ -1357,8 +1377,16 @@ public class URL implements Comparable<URL> {
}
}
private static class Pair<K, V> {
/**
* A pair for matrix params.
*
* @param <K> key
* @param <V> value
*/
public static class Pair<K, V> {
private final K first;
private final V second;
Pair(K first, V second) {
@ -1366,11 +1394,11 @@ public class URL implements Comparable<URL> {
this.second = second;
}
K getFirst() {
public K getFirst() {
return first;
}
V getSecond() {
public V getSecond() {
return second;
}
@ -1381,9 +1409,9 @@ public class URL implements Comparable<URL> {
}
/**
* A path segment with any associated matrix params.
* A path segment with associated matrix params, if any.
*/
private static class PathSegment {
public static class PathSegment {
private final String segment;
@ -1394,7 +1422,11 @@ public class URL implements Comparable<URL> {
this.params = new ArrayList<>();
}
List<Pair<String, String>> getMatrixParams() {
public String getSegment() {
return segment;
}
public List<Pair<String, String>> getMatrixParams() {
return params;
}

View file

@ -74,8 +74,8 @@ public class PathMatcher {
}
public String extractPathWithinPattern(String pattern, String path) {
List<String> patternParts = tokenize(pattern, this.pathSeparator, this.trimTokens, true);
List<String> pathParts = tokenize(path, this.pathSeparator, this.trimTokens, true);
List<String> patternParts = tokenize(pattern, pathSeparator, trimTokens);
List<String> pathParts = tokenize(path, pathSeparator, trimTokens);
StringBuilder sb = new StringBuilder();
boolean pathStarted = false;
for (int segment = 0; segment < patternParts.size(); segment++) {
@ -95,13 +95,13 @@ public class PathMatcher {
}
public String combine(String pattern1, String pattern2) {
if (!hasText(pattern1) && !hasText(pattern2)) {
if (hasNotText(pattern1) && hasNotText(pattern2)) {
return "";
}
if (!hasText(pattern1)) {
if (hasNotText(pattern1)) {
return pattern2;
}
if (!hasText(pattern2)) {
if (hasNotText(pattern2)) {
return pattern1;
}
boolean pattern1ContainsUriVar = pattern1.indexOf('{') != -1;
@ -135,17 +135,17 @@ public class PathMatcher {
return new PathPatternComparator(path);
}
private static boolean hasText(CharSequence str) {
private static boolean hasNotText(CharSequence str) {
if (str == null || str.length() == 0) {
return false;
return true;
}
int strLen = str.length();
for (int i = 0; i < strLen; i++) {
if (!Character.isWhitespace(str.charAt(i))) {
return true;
return false;
}
}
return false;
return true;
}
private String concat(String path1, String path2) {
@ -274,22 +274,22 @@ public class PathMatcher {
return tokenizedPatternCache.computeIfAbsent(pattern, this::tokenizePath);
}
private List<String> tokenizePath(String path) {
return tokenize(path, this.pathSeparator, this.trimTokens, true);
public List<String> tokenizePath(String path) {
return tokenize(path, pathSeparator, trimTokens);
}
private static List<String> tokenize(String str, String delimiters, boolean trimTokens, boolean ignoreEmptyTokens) {
private static List<String> tokenize(String str, String delimiters, boolean trimTokens) {
List<String> tokens = new ArrayList<>();
if (str == null) {
return null;
return tokens;
}
StringTokenizer st = new StringTokenizer(str, delimiters);
List<String> tokens = new ArrayList<>();
while (st.hasMoreTokens()) {
String token = st.nextToken();
if (trimTokens) {
token = token.trim();
}
if (!ignoreEmptyTokens || token.length() > 0) {
if (token.length() > 0) {
tokens.add(token);
}
}
@ -310,6 +310,7 @@ public class PathMatcher {
* @param <K> the key type parameter
* @param <V> the vale type parameter
*/
@SuppressWarnings("serial")
private static class LRUCache<K, V> extends LinkedHashMap<K, V> {
private final int cacheSize;

View file

@ -9,22 +9,25 @@ import java.util.StringTokenizer;
*/
public class PathNormalizer {
private static final char separator = '/';
private static final char SEPARATOR_CHAR = '/';
private static final String SEPARATOR_STRING = "/";
private PathNormalizer() {
}
public static String normalize(String path) {
if (path == null || "".equals(path) || "/".equals(path)) {
return "/";
public static String normalize(String p) {
String path = p;
if (path == null || "".equals(path) || SEPARATOR_STRING.equals(path)) {
return SEPARATOR_STRING;
}
path = path.replaceAll("/+", "/");
path = path.replaceAll("/+", SEPARATOR_STRING);
int leadingSlashes = 0;
while (leadingSlashes < path.length() && path.charAt(leadingSlashes) == '/') {
while (leadingSlashes < path.length() && path.charAt(leadingSlashes) == SEPARATOR_CHAR) {
++leadingSlashes;
}
boolean isDir = (path.charAt(path.length() - 1) == '/');
StringTokenizer st = new StringTokenizer(path, "/");
boolean isDir = (path.charAt(path.length() - 1) == SEPARATOR_CHAR);
StringTokenizer st = new StringTokenizer(path, SEPARATOR_STRING);
LinkedList<String> list = new LinkedList<>();
while (st.hasMoreTokens()) {
String token = st.nextToken();
@ -41,16 +44,16 @@ public class PathNormalizer {
}
StringBuilder sb = new StringBuilder();
while (leadingSlashes-- > 0) {
sb.append('/');
sb.append(SEPARATOR_CHAR);
}
for (Iterator<String> it = list.iterator(); it.hasNext();) {
sb.append(it.next());
if (it.hasNext()) {
sb.append('/');
sb.append(SEPARATOR_CHAR);
}
}
if (isDir && sb.length() > 0 && sb.charAt(sb.length() - 1) != '/') {
sb.append('/');
if (isDir && sb.length() > 0 && sb.charAt(sb.length() - 1) != SEPARATOR_CHAR) {
sb.append(SEPARATOR_CHAR);
}
return sb.toString();
}

View file

@ -0,0 +1,249 @@
package org.xbib.net.path;
import org.xbib.net.matcher.CharMatcher;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* A simple trie that maps pairs of HTTP methods and parameterized paths to arbitrary data. Each
* node in the tree is a path segment. For example, given a path "discovery/v1/apis", the data would
* be stored in the node path represented by "discovery" -&gt; "v1" -&gt; "apis". A path is
* considered parameterized if one or more segments is of the form "{name}". When a parameterized
* path is resolved, a map from parameter names to raw String values is returned as part of the
* result. Null values are not acceptable values in this trie. Parameter names can only contain
* alphanumeric characters or underscores, and cannot start with a numeric.
*/
public class PathTrie<T> {
private static final String PARAMETER_PATH_SEGMENT = "{}";
private static final Pattern PARAMETER_NAME_PATTERN = Pattern.compile("[a-zA-Z_][a-zA-Z_\\d]*");
// General delimiters that must be URL encoded, as defined by RFC 3986.
private static final CharMatcher RESERVED_URL_CHARS = CharMatcher.anyOf(":/?#[]{}");
private final Map<String, PathTrie<T>> subTries;
private final Map<String, MethodInfo<T>> httpMethodMap;
private final PathMatcher pathMatcher;
private PathTrie(Builder<T> builder) {
this.httpMethodMap = builder.httpMethodMap;
Map<String, PathTrie<T>> subTriesBuilder = new LinkedHashMap<>();
for (Entry<String, Builder<T>> entry : builder.subBuilders.entrySet()) {
subTriesBuilder.put(entry.getKey(), new PathTrie<>(entry.getValue()));
}
this.subTries = subTriesBuilder;
this.pathMatcher = new PathMatcher();
}
/**
* Attempts to resolve a path. Resolution prefers literal paths over path parameters. The result
* includes the object to which the path mapped, as well a map from parameter names to
* URL-decoded values. If the path cannot be resolved, null is returned.
* @param method method
* @param path path
* @return result of resolving
*/
public Result<T> resolve(String method, String path) {
Objects.requireNonNull(method, "method");
Objects.requireNonNull(path, "path");
return resolve(method, pathMatcher.tokenizePath(path), 0, new ArrayList<>(), new ArrayList<>());
}
private Result<T> resolve(String method, List<String> pathSegments, int index,
List<String> context, List<String> rawParameters) {
if (index < pathSegments.size()) {
String segment = pathSegments.get(index);
PathTrie<T> subTrie = subTries.get(segment);
if (subTrie != null) {
context.add(segment);
Result<T> result = subTrie.resolve(method, pathSegments, index + 1, context, rawParameters);
if (result != null) {
return result;
}
}
subTrie = subTries.get(PARAMETER_PATH_SEGMENT);
if (subTrie != null) {
rawParameters.add(segment);
Result<T> result = subTrie.resolve(method, pathSegments, index + 1, context, rawParameters);
if (result == null) {
rawParameters.remove(rawParameters.size() - 1);
}
return result;
}
return null;
} else if (httpMethodMap.containsKey(method)) {
MethodInfo<T> methodInfo = httpMethodMap.get(method);
List<String> parameterNames = methodInfo.parameterNames;
if (rawParameters.size() != parameterNames.size()) {
throw new IllegalStateException();
}
Map<String, String> rawParameterMap = new LinkedHashMap<>();
for (int i = 0; i < parameterNames.size(); i++) {
rawParameterMap.put(parameterNames.get(i), rawParameters.get(i));
}
return new Result<>(methodInfo.value, context, rawParameterMap);
}
return null;
}
/**
* The resulting information for a successful path resolution, which includes the value to which
* the path maps, as well as the raw (but URL decoded) string values of all path parameters.
*/
public static class Result<T> {
private final T result;
private final List<String> context;
private final Map<String, String> rawParameters;
Result(T result, List<String> context, Map<String, String> rawParameters) {
this.result = result;
this.context = context;
this.rawParameters = rawParameters;
}
public T getResult() {
return result;
}
public List<String> getContext() {
return context;
}
public Map<String, String> getRawParameters() {
return rawParameters;
}
}
/**
* Returns a new, path conflict validating {@link PathTrie.Builder}.
*
* @param <T> the type that the trie will be storing
* @return the trie builder
*/
public static <T> Builder<T> builder() {
return new Builder<>(true);
}
/**
* Returns a new {@link PathTrie.Builder}.
*
* @param throwOnConflict whether or not to throw an exception on path conflicts
* @param <T> the type that the trie will be storing
* @return the trie builder
*/
public static <T> Builder<T> builder(boolean throwOnConflict) {
return new Builder<>(throwOnConflict);
}
/**
* A builder for creating a {@link PathTrie}, which is immutable.
*/
public static class Builder<T> {
private final Map<String, Builder<T>> subBuilders = new LinkedHashMap<>();
private final Map<String, MethodInfo<T>> httpMethodMap =new LinkedHashMap<>();
private final boolean throwOnConflict;
private final PathMatcher pathMatcher;
Builder(boolean throwOnConflict) {
this.throwOnConflict = throwOnConflict;
this.pathMatcher = new PathMatcher();
}
/**
* Adds a path to the trie.
*
* @param method the method
* @param path the path
* @param value the value
* @return the trie builder
* @throws IllegalArgumentException if the path cannot be added to the trie
* @throws NullPointerException if either path or value are null
*/
public Builder<T> add(String method, String path, T value) {
Objects.requireNonNull(method, "method");
Objects.requireNonNull(path, "path");
Objects.requireNonNull(value, "value");
add(method, path, pathMatcher.tokenizePath(path).iterator(), value, new ArrayList<>());
return this;
}
public PathTrie<T> build() {
return new PathTrie<>(this);
}
private void add(String method, String path, Iterator<String> pathSegments, T value,
List<String> parameterNames) {
if (pathSegments.hasNext()) {
String segment = pathSegments.next();
if (segment.startsWith("{")) {
if (segment.endsWith("}")) {
parameterNames.add(getAndCheckParameterName(segment));
getOrCreateSubBuilder(PARAMETER_PATH_SEGMENT)
.add(method, path, pathSegments, value, parameterNames);
} else {
throw new IllegalArgumentException(String.format("'%s' contains invalid parameter syntax: %s",
path, segment));
}
} else {
if (RESERVED_URL_CHARS.matchesAnyOf(segment)) {
throw new IllegalArgumentException(String.format("'%s' contains invalid path segment: %s",
path, segment));
}
getOrCreateSubBuilder(segment).add(method, path, pathSegments, value, parameterNames);
}
} else {
boolean pathExists = httpMethodMap.containsKey(method);
if (pathExists && throwOnConflict) {
throw new IllegalArgumentException(String.format("Path '%s' is already mapped", path));
}
httpMethodMap.put(method, new MethodInfo<>(parameterNames, value));
}
}
private String getAndCheckParameterName(String segment) {
String name = segment.substring(1, segment.length() - 1);
Matcher matcher = PARAMETER_NAME_PATTERN.matcher(name);
if (!matcher.matches()) {
throw new IllegalArgumentException(String.format("'%s' not a valid path parameter name", name));
}
return name;
}
private Builder<T> getOrCreateSubBuilder(String segment) {
Builder<T> subBuilder = subBuilders.get(segment);
if (subBuilder == null) {
subBuilder = builder(throwOnConflict);
subBuilders.put(segment, subBuilder);
}
return subBuilder;
}
}
private static class MethodInfo<T> {
private final List<String> parameterNames;
private final T value;
MethodInfo(List<String> parameterNames, T value) {
this.parameterNames = parameterNames;
this.value = value;
}
}
}

View file

@ -16,7 +16,7 @@ public class Variables {
private final Map<String, VariableValue> vars;
Variables(Builder builder) {
private Variables(Builder builder) {
this.vars = builder.vars;
}
@ -45,7 +45,7 @@ public class Variables {
}
/**
*
* A Builder for variables.
*/
public static class Builder {

View file

@ -1,39 +1,35 @@
package org.xbib.net;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import org.junit.jupiter.api.Test;
import java.text.Normalizer;
/**
*
*/
public class IRITest {
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
class IRITest {
@Test
public void testIpv4() {
void testIpv4() {
URL iri = URL.create("http://127.0.0.1");
assertEquals("http://127.0.0.1", iri.toExternalForm());
}
@Test
public void testIpv6() {
void testIpv6() {
URL iri = URL.from("http://[2001:0db8:85a3:08d3:1319:8a2e:0370:7344]");
assertEquals(iri.getProtocolVersion(), ProtocolVersion.IPV6);
assertEquals("http://[2001:db8:85a3:8d3:1319:8a2e:370:7344]", iri.toString());
}
@Test
public void testIpv6Invalid() {
void testIpv6Invalid() {
URL iri = URL.from("http://[2001:0db8:85a3:08d3:1319:8a2e:0370:734o]");
assertEquals(URL.nullUrl(), iri);
}
@Test
public void testSimple() {
void testSimple() {
URL iri = URL.create("http://validator.w3.org/check?uri=http%3A%2F%2Fr\u00E9sum\u00E9.example.org");
//assertEquals("http://validator.w3.org/check?uri=http%3A%2F%2Fr\u00E9sum\u00E9.example.org", iri.toString());
assertEquals("http://validator.w3.org/check?uri=http://r%C3%A9sum%C3%A9.example.org",
@ -41,7 +37,7 @@ public class IRITest {
}
@Test
public void testFile() throws Exception {
void testFile() throws Exception {
URL iri = URL.create("file:///tmp/test/foo");
assertEquals("", iri.getHost());
assertEquals("/tmp/test/foo", iri.getPath());
@ -50,25 +46,25 @@ public class IRITest {
}
@Test
public void testSimple2() throws Exception {
void testSimple2() throws Exception {
URL iri = URL.create("http://www.example.org/red%09ros\u00E9#red");
assertEquals("http://www.example.org/red%09ros%C3%A9#red", iri.toExternalForm());
}
@Test
public void testNotSoSimple() throws Exception {
void testNotSoSimple() throws Exception {
URL iri = URL.create("http://example.com/\uD800\uDF00\uD800\uDF01\uD800\uDF02");
assertEquals("http://example.com/%F0%90%8C%80%F0%90%8C%81%F0%90%8C%82", iri.toExternalForm());
}
@Test
public void testIRItoURI() throws Exception {
void testIRItoURI() throws Exception {
URL iri = URL.from("http://\u7D0D\u8C46.example.org/%E2%80%AE");
assertEquals("http://xn--99zt52a.example.org/%E2%80%AE", iri.toExternalForm());
}
@Test
public void testComparison() throws Exception {
void testComparison() throws Exception {
URL url1 = URL.create("http://www.example.org/");
URL url2 = URL.create("http://www.example.org/..");
@ -90,7 +86,7 @@ public class IRITest {
}
@Test
public void testUCN() throws Exception {
void testUCN() throws Exception {
URL iri1 = URL.create("http://www.example.org/r\u00E9sum\u00E9.html");
String s = Normalizer.normalize("http://www.example.org/re\u0301sume\u0301.html", Normalizer.Form.NFC);
URL iri2 = URL.create(s);
@ -98,20 +94,20 @@ public class IRITest {
}
@Test
public void testPercent() {
void testPercent() {
URL iri1 = URL.create("http://example.org/%7e%2Fuser?%2f");
URL iri2 = URL.create("http://example.org/%7E%2fuser?/");
assertEquals(iri1.normalize(), iri2.normalize());
}
@Test
public void testIDN() {
void testIDN() {
URL iri1 = URL.from("http://r\u00E9sum\u00E9.example.org");
assertEquals("xn--rsum-bpad.example.org", iri1.getHost());
}
@Test
public void testResolveRelative() {
void testResolveRelative() {
URL base = URL.create("http://example.org/foo/");
assertEquals("http://example.org/", base.resolve("/").toString());
assertEquals("http://example.org/test", base.resolve("/test").toString());
@ -125,7 +121,7 @@ public class IRITest {
}
@Test
public void testSchemes() {
void testSchemes() {
URL iri = URL.create("http://a:b@c.org:80/d/e?f#g");
assertEquals("http", iri.getScheme());

View file

@ -1,10 +1,6 @@
package org.xbib.net;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import org.junit.jupiter.api.Test;
import java.nio.charset.MalformedInputException;
import java.nio.charset.StandardCharsets;
@ -17,33 +13,29 @@ import java.util.stream.Collectors;
import static java.lang.Character.isHighSurrogate;
import static java.lang.Character.isLowSurrogate;
import static java.lang.Integer.toHexString;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
/**
*/
public class PercentDecoderTest {
class PercentDecoderTest {
private static final int CODE_POINT_IN_SUPPLEMENTARY = 2;
private static final int CODE_POINT_IN_BMP = 1;
private PercentDecoder decoder;
@Before
public void setUp() {
decoder = new PercentDecoder(StandardCharsets.UTF_8.newDecoder());
}
private PercentDecoder decoder = new PercentDecoder(StandardCharsets.UTF_8.newDecoder());
@Test
public void testDecodesWithoutPercents() throws Exception {
void testDecodesWithoutPercents() throws Exception {
assertEquals("asdf", decoder.decode("asdf"));
}
@Test
public void testDecodeSingleByte() throws Exception {
void testDecodeSingleByte() throws Exception {
assertEquals("#", decoder.decode("%23"));
}
@Test
public void testIncompletePercentPairNoNumbers() throws Exception {
void testIncompletePercentPairNoNumbers() throws Exception {
try {
decoder.decode("%");
fail();
@ -53,7 +45,7 @@ public class PercentDecoderTest {
}
@Test
public void testIncompletePercentPairOneNumber() throws Exception {
void testIncompletePercentPairOneNumber() throws Exception {
try {
decoder.decode("%2");
fail();
@ -63,7 +55,7 @@ public class PercentDecoderTest {
}
@Test
public void testInvalidHex() throws Exception {
void testInvalidHex() throws Exception {
try {
decoder.decode("%xz");
fail();
@ -73,7 +65,7 @@ public class PercentDecoderTest {
}
@Test
public void testRandomStrings() throws MalformedInputException, UnmappableCharacterException {
void testRandomStrings() throws MalformedInputException, UnmappableCharacterException {
PercentEncoder encoder = PercentEncoders.getQueryEncoder(StandardCharsets.UTF_8);
Random rand = new Random();
long seed = rand.nextLong();
@ -87,10 +79,10 @@ public class PercentDecoderTest {
randString(buf, codePoints, charBuf, rand, 1 + rand.nextInt(1000));
byte[] origBytes = buf.toString().getBytes(StandardCharsets.UTF_8);
byte[] decodedBytes = null;
String codePointsHex = String.join("", codePoints.stream().map(Integer::toHexString).collect(Collectors.toList()));
String codePointsHex = codePoints.stream().map(Integer::toHexString).collect(Collectors.joining(""));
try {
decodedBytes = decoder.decode(encoder.encode(buf.toString())).getBytes(StandardCharsets.UTF_8);
assertEquals("Seed: $seed Code points: $codePointsHex", toHex(origBytes), toHex(decodedBytes));
assertEquals(toHex(origBytes), toHex(decodedBytes));
} catch (IllegalArgumentException e) {
List<String> charHex = new ArrayList<>();
for (int j = 0; j < buf.toString().length(); j++) {

View file

@ -1,25 +1,22 @@
package org.xbib.net;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import java.nio.charset.StandardCharsets;
import java.util.BitSet;
import static java.nio.charset.CodingErrorAction.REPLACE;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
*
*/
public class PercentEncoderTest {
class PercentEncoderTest {
private PercentEncoder alnum;
private PercentEncoder alnum16;
private static PercentEncoder alnum;
@Before
public void setUp() {
private static PercentEncoder alnum16;
@BeforeAll
static void setUp() {
BitSet bs = new BitSet();
for (int i = 'a'; i <= 'z'; i++) {
bs.set(i);
@ -31,14 +28,14 @@ public class PercentEncoderTest {
bs.set(i);
}
this.alnum = new PercentEncoder(bs, StandardCharsets.UTF_8.newEncoder().onMalformedInput(REPLACE)
alnum = new PercentEncoder(bs, StandardCharsets.UTF_8.newEncoder().onMalformedInput(REPLACE)
.onUnmappableCharacter(REPLACE));
this.alnum16 = new PercentEncoder(bs, StandardCharsets.UTF_16BE.newEncoder().onMalformedInput(REPLACE)
alnum16 = new PercentEncoder(bs, StandardCharsets.UTF_16BE.newEncoder().onMalformedInput(REPLACE)
.onUnmappableCharacter(REPLACE));
}
@Test
public void testDoesntEncodeSafe() throws Exception {
void testDoesntEncodeSafe() throws Exception {
BitSet set = new BitSet();
for (int i = 'a'; i <= 'z'; i++) {
set.set(i);
@ -49,32 +46,32 @@ public class PercentEncoderTest {
}
@Test
public void testEncodeInBetweenSafe() throws Exception {
void testEncodeInBetweenSafe() throws Exception {
assertEquals("abc%20123", alnum.encode("abc 123"));
}
@Test
public void testSafeInBetweenEncoded() throws Exception {
void testSafeInBetweenEncoded() throws Exception {
assertEquals("%20abc%20", alnum.encode(" abc "));
}
@Test
public void testEncodeUtf8() throws Exception {
void testEncodeUtf8() throws Exception {
assertEquals("snowman%E2%98%83", alnum.encode("snowman\u2603"));
}
@Test
public void testEncodeUtf8SurrogatePair() throws Exception {
void testEncodeUtf8SurrogatePair() throws Exception {
assertEquals("clef%F0%9D%84%9E", alnum.encode("clef\ud834\udd1e"));
}
@Test
public void testEncodeUtf16() throws Exception {
void testEncodeUtf16() throws Exception {
assertEquals("snowman%26%03", alnum16.encode("snowman\u2603"));
}
@Test
public void testUrlEncodedUtf16SurrogatePair() throws Exception {
void testUrlEncodedUtf16SurrogatePair() throws Exception {
assertEquals("clef%D8%34%DD%1E", alnum16.encode("clef\ud834\udd1e"));
}
}

View file

@ -1,18 +1,15 @@
package org.xbib.net;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import org.junit.jupiter.api.Test;
import java.net.URI;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
*/
public class URIComponentTest {
class URIComponentTest {
@Test
public void testURI() {
void testURI() {
URI uri = URI.create("ftp://user:pass@host:1234/path/to/filename.txt");
assertEquals("ftp", scheme(uri));
assertEquals("user", user(uri));
@ -24,7 +21,7 @@ public class URIComponentTest {
}
@Test
public void testURI2() {
void testURI2() {
URI uri = URI.create("sftp://user:pass@host:1234/filename.txt");
assertEquals("sftp", scheme(uri));
assertEquals("user", user(uri));

View file

@ -1,26 +1,23 @@
package org.xbib.net;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
*
*/
public class URLBuilderTest {
class URLBuilderTest {
@Test
public void testNoUrlParts() {
void testNoUrlParts() {
assertUrl(URL.http().resolveFromHost("foo.com").toUrlString(), "http://foo.com");
}
@Test
public void testWithPort() {
void testWithPort() {
assertUrl(URL.http().resolveFromHost("foo.com").port(33).toUrlString(), "http://foo.com:33");
}
@Test
public void testSimplePath() {
void testSimplePath() {
assertUrl(URL.http().resolveFromHost("foo.com")
.pathSegment("seg1")
.pathSegment("seg2")
@ -29,7 +26,7 @@ public class URLBuilderTest {
}
@Test
public void testPathWithReserved() {
void testPathWithReserved() {
// RFC 1738 S3.3
assertUrl(URL.http().resolveFromHost("foo.com")
.pathSegment("seg/;?ment")
@ -38,14 +35,14 @@ public class URLBuilderTest {
}
@Test
public void testPathSegments() {
void testPathSegments() {
assertUrl(URL.http().resolveFromHost("foo.com")
.pathSegments("seg1", "seg2", "seg3")
.toUrlString(), "http://foo.com/seg1/seg2/seg3");
}
@Test
public void testMatrixWithReserved() {
void testMatrixWithReserved() {
assertUrl(URL.http().resolveFromHost("foo.com")
.pathSegment("foo")
.matrixParam("foo", "bar")
@ -55,28 +52,28 @@ public class URLBuilderTest {
}
@Test
public void testUrlEncodedPathSegmentUtf8() {
void testUrlEncodedPathSegmentUtf8() {
assertUrl(URL.http().resolveFromHost("foo.com")
.pathSegment("snowman").pathSegment("\u2603")
.toUrlString(), "http://foo.com/snowman/%E2%98%83");
}
@Test
public void testUrlEncodedPathSegmentUtf8SurrogatePair() {
void testUrlEncodedPathSegmentUtf8SurrogatePair() {
assertUrl(URL.http().resolveFromHost("foo.com")
.pathSegment("clef").pathSegment("\ud834\udd1e")
.toUrlString(), "http://foo.com/clef/%F0%9D%84%9E");
}
@Test
public void testQueryParamNoPath() {
void testQueryParamNoPath() {
assertUrl(URL.http().resolveFromHost("foo.com")
.queryParam("foo", "bar")
.toUrlString(), "http://foo.com?foo=bar");
}
@Test
public void testQueryParamsDuplicated() {
void testQueryParamsDuplicated() {
assertUrl(URL.http().resolveFromHost("foo.com")
.queryParam("foo", "bar")
.queryParam("foo", "bar2")
@ -86,7 +83,7 @@ public class URLBuilderTest {
}
@Test
public void testEncodeQueryParams() {
void testEncodeQueryParams() {
assertUrl(URL.http().resolveFromHost("foo.com")
.queryParam("foo", "bar&=#baz")
.queryParam("foo", "bar?/2")
@ -94,7 +91,7 @@ public class URLBuilderTest {
}
@Test
public void testEncodeQueryParamWithSpaceAndPlus() {
void testEncodeQueryParamWithSpaceAndPlus() {
assertUrl(URL.http().resolveFromHost("foo.com")
.queryParam("foo", "spa ce")
.queryParam("fo+o", "plus+")
@ -102,7 +99,7 @@ public class URLBuilderTest {
}
@Test
public void testPlusInVariousParts() {
void testPlusInVariousParts() {
assertUrl(URL.http().resolveFromHost("foo.com")
.pathSegment("has+plus")
.matrixParam("plusMtx", "pl+us")
@ -112,7 +109,7 @@ public class URLBuilderTest {
}
@Test
public void testFragment() {
void testFragment() {
assertUrl(URL.http().resolveFromHost("foo.com")
.queryParam("foo", "bar")
.fragment("#frag/?")
@ -120,7 +117,7 @@ public class URLBuilderTest {
}
@Test
public void testAllParts() {
void testAllParts() {
assertUrl(URL.https().resolveFromHost("foo.bar.com").port(3333)
.pathSegment("foo")
.pathSegment("bar")
@ -134,24 +131,24 @@ public class URLBuilderTest {
}
@Test
public void testSlashInHost() {
void testSlashInHost() {
URL.http().resolveFromHost("/").toUrlString();
}
@Test
public void testGoogle() {
void testGoogle() {
URL url = URL.https().resolveFromHost("google.com").build();
assertEquals("https://google.com", url.toString());
}
@Test
public void testBadIPv4LiteralDoesntChoke() {
void testBadIPv4LiteralDoesntChoke() {
assertUrl(URL.http().resolveFromHost("300.100.50.1")
.toUrlString(), "http://300.100.50.1");
}
@Test
public void testIPv4Literal() {
void testIPv4Literal() {
if ("false".equals(System.getProperty("java.net.preferIPv6Addresses"))) {
assertUrl(URL.http().resolveFromHost("127.0.0.1")
.toUrlString(), "http://localhost");
@ -161,7 +158,7 @@ public class URLBuilderTest {
}
@Test
public void testIPv6LiteralLocalhost() {
void testIPv6LiteralLocalhost() {
String s = URL.http().resolveFromHost("[::1]").toUrlString();
if ("true".equals(System.getProperty("java.net.preferIPv6Addresses"))) {
assertEquals("http://[0:0:0:0:0:0:0:1]", s);
@ -171,7 +168,7 @@ public class URLBuilderTest {
}
@Test
public void testIPv6Literal() {
void testIPv6Literal() {
if ("true".equals(System.getProperty("java.net.preferIPv6Addresses"))) {
String s = URL.http().resolveFromHost("[2001:db8:85a3::8a2e:370:7334]")
.toUrlString();
@ -180,21 +177,21 @@ public class URLBuilderTest {
}
@Test
public void testEncodedRegNameSingleByte() {
void testEncodedRegNameSingleByte() {
String s = URL.http().resolveFromHost("host?name;")
.toUrlString();
assertEquals("http://host%3Fname;", s);
}
@Test
public void testEncodedRegNameMultiByte() {
void testEncodedRegNameMultiByte() {
String s = URL.http().host("snow\u2603man")
.toUrlString();
assertEquals("http://snow%E2%98%83man", s);
}
@Test
public void testThreePathSegments() {
void testThreePathSegments() {
String s = URL.https().resolveFromHost("foo.com")
.pathSegments("a", "b", "c")
.toUrlString();
@ -202,7 +199,7 @@ public class URLBuilderTest {
}
@Test
public void testThreePathSegmentsWithQueryParams() {
void testThreePathSegmentsWithQueryParams() {
String s = URL.https().resolveFromHost("foo.com")
.pathSegments("a", "b", "c")
.queryParam("foo", "bar")
@ -211,7 +208,7 @@ public class URLBuilderTest {
}
@Test
public void testIntermingledMatrixParamsAndPathSegments() {
void testIntermingledMatrixParamsAndPathSegments() {
String s = URL.http().resolveFromHost("foo.com")
.pathSegments("seg1", "seg2")
.matrixParam("m1", "v1")
@ -222,7 +219,7 @@ public class URLBuilderTest {
}
@Test
public void testUseQueryParamAfterQuery() {
void testUseQueryParamAfterQuery() {
String s = URL.http().resolveFromHost("foo.com")
.query("q")
.queryParam("foo", "bar")
@ -231,7 +228,7 @@ public class URLBuilderTest {
}
@Test
public void testUseQueryAfterQueryParam() {
void testUseQueryAfterQueryParam() {
String s = URL.http().resolveFromHost("foo.com")
.queryParam("foo", "bar")
.query("q")
@ -240,7 +237,7 @@ public class URLBuilderTest {
}
@Test
public void testQueryWithNoSpecialChars() {
void testQueryWithNoSpecialChars() {
String s = URL.http().resolveFromHost("foo.com")
.query("q")
.toUrlString();
@ -248,28 +245,28 @@ public class URLBuilderTest {
}
@Test
public void testQueryWithOkSpecialChars() {
void testQueryWithOkSpecialChars() {
String s = URL.http().resolveFromHost("foo.com")
.query("q?/&=").toUrlString();
assertEquals("http://foo.com?q?/&=", s);
}
@Test
public void testQueryWithEscapedSpecialChars() {
void testQueryWithEscapedSpecialChars() {
String s = URL.http().resolveFromHost("foo.com")
.query("q#+").toUrlString();
assertEquals("http://foo.com?q%23%2B", s);
}
@Test
public void testNewBuilder() {
void testNewBuilder() {
URL.Builder builder = URL.from("http://google.com:8008/foobar").newBuilder();
builder.scheme("https");
assertEquals("https://google.com:8008/foobar", builder.build().toString());
}
@Test
public void testUserInfo(){
void testUserInfo(){
String s = URL.http().userInfo("foo:bar").host("foo.com").toUrlString();
assertEquals("http://foo:bar@foo.com", s);
s = URL.http().userInfo("foo:foo:bar").host("foo.com").toUrlString();

View file

@ -1,39 +1,39 @@
package org.xbib.net;
import org.junit.Test;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import java.util.Iterator;
/**
*
*/
public class URLParserTest {
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
class URLParserTest {
@Test
public void testNull() {
void testNull() {
assertEquals(URL.nullUrl(), URL.from(null));
}
@Test
public void testEmpty() {
void testEmpty() {
assertEquals(URL.nullUrl(), URL.from(""));
}
@Test
public void testNewline() {
void testNewline() {
assertEquals(URL.nullUrl(), URL.from("\n"));
}
@Test(expected = IllegalArgumentException.class)
public void testInvalidScheme() {
URL.from("/:23");
@Test
void testInvalidScheme() {
Assertions.assertThrows(IllegalArgumentException.class, () -> URL.from("/:23"));
}
@Test
public void testScheme() throws Exception {
void testScheme() throws Exception {
URL url = URL.from("http://");
assertEquals("http://", url.toExternalForm());
assertEquals("http://", url.toString());
@ -41,7 +41,7 @@ public class URLParserTest {
}
@Test
public void testPath(){
void testPath(){
URL url = URL.from("http");
assertFalse(url.isAbsolute());
assertNull(url.getScheme());
@ -52,7 +52,7 @@ public class URLParserTest {
}
@Test
public void testOpaque() throws Exception {
void testOpaque() throws Exception {
URL url = URL.from("a:b");
assertEquals("a", url.getScheme());
assertEquals("b", url.getSchemeSpecificPart());
@ -62,13 +62,13 @@ public class URLParserTest {
}
@Test
public void testGopher() {
void testGopher() {
URL url = URL.from("gopher:/example.com/");
assertEquals("gopher:/example.com/", url.toExternalForm());
}
@Test
public void testWithoutDoubleSlash() throws Exception {
void testWithoutDoubleSlash() throws Exception {
URL url = URL.from("http:foo.com");
assertEquals("http:foo.com", url.toExternalForm());
assertEquals("http:foo.com", url.toString());
@ -76,82 +76,82 @@ public class URLParserTest {
}
@Test
public void testSlashAfterScheme() {
void testSlashAfterScheme() {
URL url = URL.from("http:/example.com/");
assertEquals("http:/example.com/", url.toExternalForm());
}
@Test
public void testSchemeHost() throws Exception {
void testSchemeHost() throws Exception {
URL url = URL.from("http://foo.bar");
assertEquals("http://foo.bar", url.toString());
assertRoundTrip(url.toExternalForm());
}
@Test
public void testSchemeHostPort() throws Exception {
void testSchemeHostPort() throws Exception {
URL url = URL.from("http://f:/c");
assertEquals("http://f:/c", url.toString());
assertRoundTrip(url.toExternalForm());
}
@Test
public void testNetworkLocation() {
void testNetworkLocation() {
URL url = URL.from("//foo.bar");
assertEquals("//foo.bar", url.toExternalForm());
assertEquals("//foo.bar", url.toString());
}
@Test
public void testSchemeHostAuthInfo() throws Exception {
void testSchemeHostAuthInfo() throws Exception {
URL url = URL.from("http://auth@foo.bar");
assertEquals("http://auth@foo.bar", url.toString());
assertRoundTrip(url.toExternalForm());
}
@Test
public void testSchemeHostAuthInfoPort() throws Exception {
void testSchemeHostAuthInfoPort() throws Exception {
URL url = URL.from("http://auth@foo.bar:1");
assertEquals("http://auth@foo.bar:1", url.toString());
assertRoundTrip(url.toExternalForm());
}
@Test
public void testSchemeHostAuthInfoPortPath() throws Exception {
void testSchemeHostAuthInfoPortPath() throws Exception {
URL url = URL.from("http://auth@foo.bar:1/path");
assertEquals("http://auth@foo.bar:1/path", url.toString());
assertRoundTrip(url.toExternalForm());
}
@Test
public void testTrailingSlash() throws Exception {
void testTrailingSlash() throws Exception {
URL url = URL.from("http://foo.bar/path/");
assertEquals("http://foo.bar/path/", url.toString());
assertRoundTrip(url.toExternalForm());
}
@Test
public void testBackslash() {
void testBackslash() {
URL url = URL.from("http://foo.com/\\@");
assertEquals("http://foo.com/@", url.toExternalForm());
}
@Test
public void testQuery() throws Exception {
void testQuery() throws Exception {
URL url = URL.from("http://auth@foo.bar:1/path?query");
assertEquals("http://auth@foo.bar:1/path?query", url.toString());
assertRoundTrip(url.toExternalForm());
}
@Test
public void testFragment() throws Exception {
void testFragment() throws Exception {
URL url = URL.from("http://auth@foo.bar:1/path#fragment");
assertEquals("http://auth@foo.bar:1/path#fragment", url.toString());
assertRoundTrip(url.toExternalForm());
}
@Test
public void testReservedChar() throws Exception {
void testReservedChar() throws Exception {
URL url = URL.from("http://www.google.com/ig/calculator?q=1USD=?EUR");
if ("false".equals(System.getProperty("java.net.preferIPv6Addresses"))) {
assertEquals("http://www.google.com/ig/calculator?q=1USD%3D?EUR", url.toString());
@ -160,7 +160,7 @@ public class URLParserTest {
}
@Test
public void testPassword() throws Exception {
void testPassword() throws Exception {
URL url = URL.from("ftp://aaa:b%2B1@www.google.com");
assertEquals("b+1", url.getPassword());
assertRoundTrip(url.toExternalForm());
@ -170,21 +170,21 @@ public class URLParserTest {
}
@Test
public void testPlus() throws Exception {
void testPlus() throws Exception {
URL url = URL.from("http://foobar:8080/test/print?value=%EA%B0%80+%EB%82%98");
assertEquals("http://foobar:8080/test/print?value=%EA%B0%80%2B%EB%82%98", url.toExternalForm());
assertRoundTrip(url.toExternalForm());
}
@Test
public void testIPv6() throws Exception {
void testIPv6() throws Exception {
URL url = URL.from("http://[2001:db8:85a3::8a2e:370:7334]");
assertEquals("http://[2001:db8:85a3:0:0:8a2e:370:7334]", url.toString());
assertRoundTrip(url.toExternalForm());
}
@Test
public void testIPv6WithScope() throws Exception {
void testIPv6WithScope() throws Exception {
// test scope ID. Must be a valid IPv6
URL url = URL.from("http://[3002:0:0:0:20c:29ff:fe64:614a%2]:8080/resource");
assertEquals("http://[3002:0:0:0:20c:29ff:fe64:614a%2]:8080/resource", url.toString());
@ -192,90 +192,90 @@ public class URLParserTest {
}
@Test
public void testIPv6WithIPv4() throws Exception {
void testIPv6WithIPv4() throws Exception {
URL url = URL.from("http://[::192.168.1.1]:8080/resource");
assertEquals("http://[0:0:0:0:0:0:c0a8:101]:8080/resource", url.toString());
assertRoundTrip(url.toExternalForm());
}
@Test
public void testFromUrlWithEverything() throws Exception {
void testFromUrlWithEverything() throws Exception {
assertUrlCompatibility("https://foo.bar.com:3333/foo/ba%20r;mtx1=val1;mtx2=val%202/"
+ "seg%203;m2=v2?q1=v1&q2=v%202#zomg%20it's%20a%20fragment");
}
@Test
public void testFromUrlWithEmptyPath() throws Exception {
void testFromUrlWithEmptyPath() throws Exception {
assertUrlCompatibility("http://foo.com");
}
@Test
public void testFromUrlWithPort() throws Exception {
void testFromUrlWithPort() throws Exception {
assertUrlCompatibility("http://foo.com:1234");
}
@Test
public void testFromUrlWithEncodedHost() throws Exception {
void testFromUrlWithEncodedHost() throws Exception {
assertUrlCompatibility("http://f%20oo.com/bar");
}
@Test
public void testFromUrlWithEncodedPathSegment() throws Exception {
void testFromUrlWithEncodedPathSegment() throws Exception {
assertUrlCompatibility("http://foo.com/foo/b%20ar");
}
@Test
public void testFromUrlWithEncodedMatrixParam() throws Exception {
void testFromUrlWithEncodedMatrixParam() throws Exception {
assertUrlCompatibility("http://foo.com/foo;m1=v1;m%202=v%202");
}
@Test
public void testFromUrlWithEncodedQueryParam() throws Exception {
void testFromUrlWithEncodedQueryParam() throws Exception {
assertUrlCompatibility("http://foo.com/foo?q%201=v%202&q2=v2");
}
@Test
public void testFromUrlWithEncodedQueryParamDelimiter() throws Exception {
void testFromUrlWithEncodedQueryParamDelimiter() throws Exception {
assertUrlCompatibility("http://foo.com/foo?q1=%3Dv1&%26q2=v2");
}
@Test
public void testFromUrlWithEncodedFragment() throws Exception {
void testFromUrlWithEncodedFragment() throws Exception {
assertUrlCompatibility("http://foo.com/foo#b%20ar");
}
@Test
public void testFromUrlWithEmptyPathSegmentWithMatrixParams() throws Exception {
void testFromUrlWithEmptyPathSegmentWithMatrixParams() throws Exception {
assertUrlCompatibility("http://foo.com/foo/;m1=v1");
}
@Test
public void testFromUrlWithEmptyPathWithMatrixParams() throws Exception {
void testFromUrlWithEmptyPathWithMatrixParams() throws Exception {
assertUrlCompatibility("http://foo.com/;m1=v1");
}
@Test
public void testFromUrlWithEmptyPathWithMultipleMatrixParams() throws Exception {
void testFromUrlWithEmptyPathWithMultipleMatrixParams() throws Exception {
assertUrlCompatibility("http://foo.com/;m1=v1;m2=v2");
}
@Test
public void testFromUrlMalformedQueryParamNoValue() throws Exception {
void testFromUrlMalformedQueryParamNoValue() throws Exception {
assertUrlCompatibility("http://foo.com/foo?q1=v1&q2");
}
@Test
public void testFromUrlMalformedQueryParamMultiValues() throws Exception {
void testFromUrlMalformedQueryParamMultiValues() throws Exception {
assertRoundTrip("http://foo.com/foo?q1=v1=v2");
}
@Test
public void testFromUrlQueryWithEscapedChars() throws Exception {
void testFromUrlQueryWithEscapedChars() throws Exception {
assertRoundTrip("http://foo.com/foo?query==&%23");
}
@Test
public void testSimple() throws Exception {
void testSimple() throws Exception {
URL url = URL.parser().parse("http://foo.com/seg1/seg2");
assertEquals("http", url.getScheme());
assertEquals("foo.com", url.getHostInfo());
@ -283,7 +283,7 @@ public class URLParserTest {
}
@Test
public void testReserved() throws Exception {
void testReserved() throws Exception {
URL url = URL.parser().parse("http://foo.com/seg%2F%3B%3Fment/seg=&2");
assertEquals("http", url.getScheme());
assertEquals("foo.com", url.getHostInfo());
@ -291,7 +291,7 @@ public class URLParserTest {
}
@Test
public void testMatrix() throws Exception {
void testMatrix() throws Exception {
URL url = URL.parser().parse("http://foo.com/;foo=bar");
assertEquals("http", url.getScheme());
assertEquals("foo.com", url.getHostInfo());
@ -299,7 +299,28 @@ public class URLParserTest {
}
@Test
public void testAnotherQuery() throws Exception {
void testMatrix2() throws Exception {
URL url = URL.parser().parse("http://foo.com/some;p1=v1/path;p2=v2?q1=v3");
assertEquals("http", url.getScheme());
assertEquals("foo.com", url.getHostInfo());
assertEquals("/some;p1=v1/path;p2=v2", url.getPath());
Iterator<URL.PathSegment> iterator = url.getPathSegments().iterator();
URL.PathSegment pathSegment = iterator.next();
assertEquals("", pathSegment.getSegment());
assertEquals("[]", pathSegment.getMatrixParams().toString());
pathSegment = iterator.next();
assertEquals("some", pathSegment.getSegment());
assertEquals("p1", pathSegment.getMatrixParams().get(0).getFirst());
assertEquals("v1", pathSegment.getMatrixParams().get(0).getSecond());
pathSegment = iterator.next();
assertEquals("path", pathSegment.getSegment());
assertEquals("p2", pathSegment.getMatrixParams().get(0).getFirst());
assertEquals("v2", pathSegment.getMatrixParams().get(0).getSecond());
assertEquals("v3", url.getQueryParams().get("q1").get(0));
}
@Test
void testAnotherQuery() throws Exception {
URL url = URL.parser().parse("http://foo.com?foo=bar");
assertEquals("http", url.getScheme());
assertEquals("foo.com", url.getHostInfo());
@ -307,7 +328,7 @@ public class URLParserTest {
}
@Test
public void testQueryAndFragment() throws Exception {
void testQueryAndFragment() throws Exception {
URL url = URL.parser().parse("http://foo.com?foo=bar#fragment");
assertEquals("http", url.getScheme());
assertEquals("foo.com", url.getHostInfo());
@ -316,7 +337,7 @@ public class URLParserTest {
}
@Test
public void testRelative() throws Exception {
void testRelative() throws Exception {
URL url = URL.parser().parse("/foo/bar?foo=bar#fragment");
assertNull(url.getScheme());
assertEquals("", url.getHostInfo());
@ -326,7 +347,7 @@ public class URLParserTest {
}
@Test
public void testRelativeDecoded() throws Exception {
void testRelativeDecoded() throws Exception {
URL url = URL.parser().parse("/foo/bar%2F?foo=b%2Far#frag%2Fment");
assertNull(url.getScheme());
assertEquals("", url.getHostInfo());
@ -336,7 +357,7 @@ public class URLParserTest {
}
@Test
public void testFileSchemeSpecificPart() throws Exception {
void testFileSchemeSpecificPart() throws Exception {
URL url = URL.parser().parse("file:foo/bar?foo=bar#fragment");
assertEquals("", url.getHostInfo());
assertNotNull(url.getSchemeSpecificPart());
@ -344,7 +365,7 @@ public class URLParserTest {
}
@Test
public void testRelativeFilePath() throws Exception {
void testRelativeFilePath() throws Exception {
URL url = URL.parser().parse("file:/foo/bar?foo=bar#fragment");
assertEquals("file", url.getScheme());
assertEquals("", url.getHostInfo());
@ -354,7 +375,7 @@ public class URLParserTest {
}
@Test
public void testAbsoluteFilePath() throws Exception {
void testAbsoluteFilePath() throws Exception {
URL url = URL.parser().parse("file:///foo/bar?foo=bar#fragment");
assertEquals("file", url.getScheme());
assertEquals("", url.getHostInfo());
@ -364,14 +385,14 @@ public class URLParserTest {
}
@Test
public void testMoreQuery() throws Exception {
void testMoreQuery() throws Exception {
URL url = URL.parser().parse("http://foo.com?foo=bar%26%3D%23baz&foo=bar?/2");
assertEquals("foo=bar%26%3D%23baz&foo=bar?/2", url.getQuery());
assertEquals("foo=bar&=#baz&foo=bar?/2", url.getDecodedQuery());
}
@Test
public void testAnotherPlus() throws Exception {
void testAnotherPlus() throws Exception {
URL url = URL.parser().parse("http://foo.com/has+plus;plusMtx=pl+us?plusQp=pl%2Bus#plus+frag");
assertEquals("/has+plus;plusMtx=pl+us", url.getPath());
assertEquals("plusQp=pl%2Bus", url.getQuery());
@ -379,7 +400,7 @@ public class URLParserTest {
}
@Test
public void testUserInfo() throws Exception {
void testUserInfo() throws Exception {
URL url = URL.parser().parse("http://foo:bar@foo.com/");
assertEquals("foo:bar", url.getUserInfo());
url = URL.parser().parse("http://foo:foo:bar@foo.com/");

View file

@ -1,19 +1,17 @@
package org.xbib.net;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import org.junit.jupiter.api.Test;
import java.net.URI;
import java.nio.charset.MalformedInputException;
import java.nio.charset.UnmappableCharacterException;
/**
*/
public class URLResolverTest {
import static org.junit.jupiter.api.Assertions.assertEquals;
class URLResolverTest {
@Test
public void testResolveURI() throws Exception {
void testResolveURI() throws Exception {
URI base = URI.create("http://example.org/foo");
assertEquals("http://example.org/", base.resolve("/").toString());
assertEquals("http://example.org/foobar", base.resolve("/foobar").toString());
@ -25,7 +23,7 @@ public class URLResolverTest {
}
@Test
public void testResolveURL() throws Exception {
void testResolveURL() throws Exception {
URL base = URL.create("http://example.org/foo");
assertEquals("http://example.org/", base.resolve("/").toString());
assertEquals("http://example.org/foobar", base.resolve("/foobar").toString());
@ -37,7 +35,7 @@ public class URLResolverTest {
}
@Test
public void testMultiResolve() throws Exception {
void testMultiResolve() throws Exception {
URL base = URL.create("http://example:8080");
String pathSpec = "foobar/";
String index = "index.html";
@ -47,7 +45,7 @@ public class URLResolverTest {
}
@Test
public void testFielding() throws Exception {
void testFielding() throws Exception {
// http://www.ics.uci.edu/~fielding/url/test1.html
resolve("http://a/b/c/d;p?q", "g:h", "g:h");
resolve("http://a/b/c/d;p?q", "g", "http://a/b/c/g");

View file

@ -4,33 +4,30 @@ import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.List;
/**
*/
public class URLTest {
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
class URLTest {
@Test
public void test() throws Exception {
void test() throws Exception {
List<JsonTest> tests = readTests(fromResource("/urltestdata.json"));
for (JsonTest test : tests) {
String base = test.base;
String input = test.input;
System.err.println("testing: " + base + " " + input + " " + test.failure);
//System.err.println("testing: " + base + " " + input + " " + test.failure);
if (test.skip) {
continue;
}
if (test.failure) {
try {
URL url = URL.base(base).resolve(input);
System.err.println("resolved: " + url.toString());
//System.err.println("resolved: " + url.toString());
fail();
} catch (Exception e) {
// pass
@ -39,7 +36,7 @@ public class URLTest {
if (base != null && input != null) {
try {
URL url = URL.base(base).resolve(input);
System.err.println("resolved: " + url.toString());
//System.err.println("resolved: " + url.toString());
if (test.protocol != null) {
assertEquals(test.protocol, url.getScheme() + ":");
}
@ -58,9 +55,9 @@ public class URLTest {
//if (test.pathname != null && !test.pathname.isEmpty() && url.getPath() != null) {
// assertEquals(test.pathname, url.getPath());
//}
System.err.println("passed: " + base + " " + input);
//System.err.println("passed: " + base + " " + input);
} catch (URLSyntaxException e) {
System.err.println("unable to resolve: " + base + " " + input + " reason: " + e.getMessage());
//System.err.println("unable to resolve: " + base + " " + input + " reason: " + e.getMessage());
}
}
}

View file

@ -0,0 +1,38 @@
package org.xbib.net.body;
import org.junit.jupiter.api.Test;
import org.xbib.net.QueryParameters;
import java.nio.charset.MalformedInputException;
import java.nio.charset.UnmappableCharacterException;
import java.util.ArrayList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
class ParseBodyTest {
@Test
void testSimpleParse() throws MalformedInputException, UnmappableCharacterException {
QueryParameters queryParameters = new QueryParameters();
String body = "a=b&c=d&e=f";
queryParameters.addPercentEncodedBody(body);
assertEquals("b", queryParameters.get("a").get(0));
assertEquals("d", queryParameters.get("c").get(0));
assertEquals("f", queryParameters.get("e").get(0));
}
@Test
void testManyParse() throws MalformedInputException, UnmappableCharacterException {
QueryParameters queryParameters = new QueryParameters(100);
List<String> list = new ArrayList<>();
for (int i = 0; i < 200; i++) {
list.add("a" + i + "=b" + i );
}
String body = String.join("&", list);
queryParameters.addPercentEncodedBody(body);
assertEquals("b0", queryParameters.get("a0").get(0));
assertEquals("b99", queryParameters.get("a99").get(0));
assertEquals("[]", queryParameters.get("a100").toString());
}
}

View file

@ -1,42 +1,40 @@
package org.xbib.net.path;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import org.xbib.net.URL;
import static org.junit.Assert.assertEquals;
import java.nio.charset.MalformedInputException;
import java.nio.charset.StandardCharsets;
import java.nio.charset.UnmappableCharacterException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*/
public class PathDecoderTest {
import static org.junit.jupiter.api.Assertions.assertEquals;
class PathDecoderTest {
@Test
public void testPlusSign() throws Exception {
void testPlusSign() throws Exception {
PathDecoder decoder = new PathDecoder("/path?a=b+c", "d=e+f", StandardCharsets.UTF_8);
assertEquals("[b c]", decoder.params().get("a").toString());
assertEquals("[e f]", decoder.params().get("d").toString());
}
@Test
public void testSlash() throws Exception {
void testSlash() throws Exception {
PathDecoder decoder = new PathDecoder("path/foo/bar/?a=b+c", "d=e+f", StandardCharsets.UTF_8);
assertEquals("[b c]", decoder.params().get("a").toString());
assertEquals("[e f]", decoder.params().get("d").toString());
}
@Test
public void testDoubleSlashes() throws Exception {
void testDoubleSlashes() throws Exception {
PathDecoder decoder = new PathDecoder("//path", "", StandardCharsets.UTF_8);
assertEquals("/path", decoder.path());
}
@Test
public void testSlashes() throws Exception {
void testSlashes() throws Exception {
PathDecoder decoder = new PathDecoder("//path?a=b+c", "d=e+f", StandardCharsets.UTF_8);
assertEquals("/path", decoder.path());
assertEquals("[b c]", decoder.params().get("a").toString());
@ -44,7 +42,7 @@ public class PathDecoderTest {
}
@Test
public void testPlusPercent() throws Exception {
void testPlusPercent() throws Exception {
PathDecoder decoder = new PathDecoder("//path?a=b%2Bc", "d=e%2Bf", StandardCharsets.UTF_8);
assertEquals("/path", decoder.path());
assertEquals("[b+c]", decoder.params().get("a").toString());
@ -52,7 +50,7 @@ public class PathDecoderTest {
}
@Test
public void decodeURL() throws MalformedInputException, UnmappableCharacterException {
void decodeURL() throws MalformedInputException, UnmappableCharacterException {
String requestURI = "/pdfconverter/index.gtpl?x-fl-key=20190035592&x-fl-source=ftp://DE-465:r09t00k25@herakles.hbz-nrw.de/fl/upload/20190035592/20190035592.pdf&x-fl-target=ftp://DE-1073:haribo%2B1@herakles.hbz-nrw.de/fl/download/20190035592/Fernleihe_Kopienlieferung_null_FB201900373_BLQDMT62_20190035592_20190035592.pdf&x-fl-copy=&x-fl-ack=https://fl.hbz-nrw.de/app/ack/index.gtpl&x-fl-pages=1-";
URL url = URL.builder().path(requestURI).build();
log.log(Level.INFO, "URL: url=" + url + " path=" + url.getPath() + " query=" + url.getQuery() +

View file

@ -1,31 +1,27 @@
package org.xbib.net.path;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.xbib.net.QueryParameters;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
*/
public class PathMatcherTest {
class PathMatcherTest {
private PathMatcher pathMatcher = new PathMatcher();
@Rule
public final ExpectedException exception = ExpectedException.none();
@Test
public void match() {
void match() {
// test exact matching
assertTrue(pathMatcher.match("test", "test"));
assertTrue(pathMatcher.match("/test", "/test"));
@ -110,7 +106,7 @@ public class PathMatcherTest {
}
@Test
public void withMatchStart() {
void withMatchStart() {
// test exact matching
assertTrue(pathMatcher.matchStart("test", "test"));
assertTrue(pathMatcher.matchStart("/test", "/test"));
@ -197,7 +193,7 @@ public class PathMatcherTest {
}
@Test
public void uniqueDeliminator() {
void uniqueDeliminator() {
pathMatcher.setPathSeparator(".");
// test exact matching
@ -259,7 +255,7 @@ public class PathMatcherTest {
}
@Test
public void extractPathWithinPattern() throws Exception {
void extractPathWithinPattern() throws Exception {
assertEquals("",
pathMatcher.extractPathWithinPattern("/docs/commit.html", "/docs/commit.html"));
@ -303,7 +299,7 @@ public class PathMatcherTest {
}
@Test
public void extractUriTemplateVariables() throws Exception {
void extractUriTemplateVariables() throws Exception {
QueryParameters result = pathMatcher.extractUriTemplateVariables("/hotels/{hotel}", "/hotels/1");
assertEquals("[hotel:1]", result.toString());
result = pathMatcher.extractUriTemplateVariables("/h?tels/{hotel}", "/hotels/1");
@ -323,7 +319,7 @@ public class PathMatcherTest {
}
@Test
public void extractUriTemplateVariablesRegex() {
void extractUriTemplateVariablesRegex() {
QueryParameters result = pathMatcher
.extractUriTemplateVariables("{symbolicName:[\\w\\.]+}-{version:[\\w\\.]+}.jar",
"com.example-1.0.0.jar");
@ -337,7 +333,7 @@ public class PathMatcherTest {
}
@Test
public void extractUriTemplateVarsRegexQualifiers() {
void extractUriTemplateVarsRegexQualifiers() {
QueryParameters result = pathMatcher.extractUriTemplateVariables(
"{symbolicName:[\\p{L}\\.]+}-sources-{version:[\\p{N}\\.]+}.jar",
"com.example-sources-1.0.0.jar");
@ -359,14 +355,14 @@ public class PathMatcherTest {
}
@Test
public void extractUriTemplateVarsRegexCapturingGroups() {
exception.expect(IllegalArgumentException.class);
//exception.expectMessage(containsString("The number of capturing groups in the pattern"))
pathMatcher.extractUriTemplateVariables("/web/{id:foo(bar)?}", "/web/foobar");
void extractUriTemplateVarsRegexCapturingGroups() {
Assertions.assertThrows(IllegalArgumentException.class, () -> {
pathMatcher.extractUriTemplateVariables("/web/{id:foo(bar)?}", "/web/foobar");
});
}
@Test
public void combine() {
void combine() {
assertEquals("", pathMatcher.combine(null, null));
assertEquals("/hotels", pathMatcher.combine("/hotels", null));
assertEquals("/hotels", pathMatcher.combine(null, "/hotels"));
@ -397,13 +393,14 @@ public class PathMatcherTest {
}
@Test
public void combineWithTwoFileExtensionPatterns() {
exception.expect(IllegalArgumentException.class);
pathMatcher.combine("/*.html", "/*.txt");
void combineWithTwoFileExtensionPatterns() {
Assertions.assertThrows(IllegalArgumentException.class, () ->{
pathMatcher.combine("/*.html", "/*.txt");
});
}
@Test
public void patternComparator() {
void patternComparator() {
Comparator<String> comparator = pathMatcher.getPatternComparator("/hotels/new");
assertEquals(0, comparator.compare(null, null));
@ -451,7 +448,7 @@ public class PathMatcherTest {
}
@Test
public void patternComparatorSort() {
void patternComparatorSort() {
Comparator<String> comparator = pathMatcher.getPatternComparator("/hotels/new");
List<String> paths = new ArrayList<>(3);
paths.add(null);
@ -546,7 +543,7 @@ public class PathMatcherTest {
}
@Test
public void trimTokensOff() {
void trimTokensOff() {
pathMatcher.setTrimTokens(false);
assertTrue(pathMatcher.match("/group/{groupName}/members", "/group/sales/members"));
assertTrue(pathMatcher.match("/group/{groupName}/members", "/group/ sales/members"));
@ -554,7 +551,7 @@ public class PathMatcherTest {
}
@Test
public void caseInsensitive() {
void caseInsensitive() {
pathMatcher.setCaseSensitive(false);
assertTrue(pathMatcher.match("/group/{groupName}/members", "/group/sales/members"));
assertTrue(pathMatcher.match("/group/{groupName}/members", "/Group/Sales/Members"));
@ -562,10 +559,9 @@ public class PathMatcherTest {
}
@Test
public void extensionMappingWithDotPathSeparator() {
void extensionMappingWithDotPathSeparator() {
pathMatcher.setPathSeparator(".");
assertEquals("Extension mapping should be disabled with \".\" as path separator",
"/*.html.hotel.*", pathMatcher.combine("/*.html", "hotel.*"));
assertEquals("/*.html.hotel.*", pathMatcher.combine("/*.html", "hotel.*"));
}
}

View file

@ -1,73 +1,69 @@
package org.xbib.net.path;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
*
*/
public class PathNormalizerTest {
class PathNormalizerTest {
@Test
public void normalizeNullPath() {
void normalizeNullPath() {
assertEquals("/", PathNormalizer.normalize(null));
}
@Test
public void normalizeEmptyPath() {
void normalizeEmptyPath() {
assertEquals("/", PathNormalizer.normalize(""));
}
@Test
public void normalizeSlashPath() {
void normalizeSlashPath() {
assertEquals("/", PathNormalizer.normalize("/"));
}
@Test
public void normalizeDoubleSlashPath() {
void normalizeDoubleSlashPath() {
assertEquals("/", PathNormalizer.normalize("//"));
}
@Test
public void normalizeTripleSlashPath() {
void normalizeTripleSlashPath() {
assertEquals("/", PathNormalizer.normalize("///"));
}
@Test
public void normalizePathWithPoint() {
void normalizePathWithPoint() {
assertEquals("/", PathNormalizer.normalize("/."));
}
@Test
public void normalizePathWithPointAndElement() {
void normalizePathWithPointAndElement() {
assertEquals("/a", PathNormalizer.normalize("/./a"));
}
@Test
public void normalizePathWithTwoPointsAndElement() {
void normalizePathWithTwoPointsAndElement() {
assertEquals("/a", PathNormalizer.normalize("/././a"));
}
@Test
public void normalizePathWithDoublePoint() {
void normalizePathWithDoublePoint() {
assertEquals("/", PathNormalizer.normalize("/.."));
assertEquals("/", PathNormalizer.normalize("/../.."));
assertEquals("/", PathNormalizer.normalize("/../../.."));
}
@Test
public void normalizePathWithFirstElementAndDoublePoint() {
void normalizePathWithFirstElementAndDoublePoint() {
assertEquals("/", PathNormalizer.normalize("/a/.."));
assertEquals("/", PathNormalizer.normalize("/a/../.."));
assertEquals("/", PathNormalizer.normalize("/a/../../.."));
}
@Test
public void normalizePathWithTwoElementsAndDoublePoint() {
void normalizePathWithTwoElementsAndDoublePoint() {
assertEquals("/b", PathNormalizer.normalize("/a/../b"));
assertEquals("/b", PathNormalizer.normalize("/a/../../b"));
assertEquals("/b", PathNormalizer.normalize("/a/../../../b"));
}
}

View file

@ -0,0 +1,277 @@
package org.xbib.net.path;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import java.util.Collections;
import java.util.Map;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.fail;
class PathTrieTest {
@Test
void example() {
PathTrie<Integer> trie = PathTrie.<Integer>builder()
.add("GET", "/static/{file}", 1234)
.add("HEAD", "/static/{file}", 1234)
.build();
assertSuccessfulResolution(trie, "GET", "/static/test.txt", 1234, Map.of("file", "test.txt"));
}
@Test
void simple() {
PathTrie<Integer> trie = PathTrie.<Integer>builder()
.add("GET", "explorer", 1234)
.build();
assertSuccessfulGetResolution(trie, "explorer", 1234);
assertFailedGetResolution(trie, "PUT", "explorer");
assertFailedGetResolution(trie, "");
assertFailedGetResolution(trie, "test");
}
@Test
void sharedPrefix() {
PathTrie<Integer> trie = PathTrie.<Integer>builder()
.add("GET", "discovery/v1/rest", 1234)
.add("GET", "discovery/v2/rest", 4321)
.build();
assertSuccessfulGetResolution(trie, "discovery/v1/rest", 1234);
assertSuccessfulGetResolution(trie, "discovery/v2/rest", 4321);
assertFailedGetResolution(trie, "");
assertFailedGetResolution(trie, "discovery");
assertFailedGetResolution(trie, "discovery/v1");
}
@Test
void prefix() {
PathTrie<Integer> trie = PathTrie.<Integer>builder()
.add("GET", "discovery", 1234)
.add("GET", "discovery/v1", 4321)
.build();
assertSuccessfulGetResolution(trie, "discovery", 1234);
assertSuccessfulGetResolution(trie, "discovery/v1", 4321);
assertFailedGetResolution(trie, "");
}
@Test
void parameter() {
PathTrie<Integer> trie = PathTrie.<Integer>builder()
.add("GET", "discovery/{version}/rest", 1234)
.build();
assertSuccessfulGetResolution(
trie, "discovery/v1/rest", 1234, Map.of("version", "v1"));
}
@Test
void multipleParameters() {
PathTrie<Integer> trie = PathTrie.<Integer>builder()
.add("GET", "discovery/{discovery_version}/apis/{api}/{format}", 1234)
.build();
assertSuccessfulGetResolution(trie, "discovery/v1/apis/test/rest", 1234,
Map.of("discovery_version", "v1", "api", "test", "format", "rest"));
}
@Test
void sharedParameterPrefix() {
PathTrie<Integer> trie = PathTrie.<Integer>builder()
.add("GET", "discovery/{version}/rest", 1234)
.add("GET", "discovery/{version}/rpc", 4321)
.build();
assertSuccessfulGetResolution(
trie, "discovery/v1/rest", 1234, Map.of("version", "v1"));
assertSuccessfulGetResolution(
trie, "discovery/v1/rpc", 4321, Map.of("version", "v1"));
}
@Disabled
@Test
void encodedParameter() {
PathTrie<Integer> trie = PathTrie.<Integer>builder()
.add("GET", "{value}", 1234)
.build();
assertSuccessfulGetResolution(
trie, "%E4%B8%AD%E6%96%87", 1234, Map.of("value", "中文"));
}
@Test
void testResolveParameterAfterLiteral() {
PathTrie<Integer> trie = PathTrie.<Integer>builder()
.add("GET", "{one}/three", 1234)
.add("GET", "one/two", 4321)
.build();
assertSuccessfulGetResolution(trie, "one/three", 1234, Map.of("one", "one"));
assertSuccessfulGetResolution(trie, "one/two", 4321);
}
@Test
void testResolveBacktrack() {
PathTrie<Integer> trie = PathTrie.<Integer>builder()
.add("GET", "{one}/{two}/three/{four}", 1234)
.add("GET", "one/two/{three}/four", 4321)
.build();
assertSuccessfulGetResolution(trie, "one/two/three/five", 1234,
Map.of("one", "one", "two", "two", "four", "five"));
assertSuccessfulGetResolution(
trie, "one/two/three/four", 4321, Map.of("three", "three"));
}
@Test
void pathMethodsWithDifferentParameterNames() {
PathTrie<Integer> trie = PathTrie.<Integer>builder()
.add("GET", "test/{one}", 1234)
.add("PUT", "test/{two}", 4321)
.build();
assertSuccessfulResolution(
trie, "GET", "test/foo", 1234, Map.of("one", "foo"));
assertSuccessfulResolution(
trie, "PUT", "test/foo", 4321, Map.of("two", "foo"));
}
@Test
void duplicatePath() {
doStrictDuplicateTest("test/path", "test/path");
}
@Test
void duplicateParameterizedPath() {
doStrictDuplicateTest("test/{param}/path", "test/{parameterized}/path");
}
@Test
void laxDuplicatePath() {
PathTrie<Integer> trie = PathTrie.<Integer>builder(false)
.add("GET", "test/{one}", 1234)
.add("GET", "test/{two}", 4321)
.build();
PathTrie.Result<Integer> result = trie.resolve("GET", "test/foo");
// We don't care which result is returned as long as it is a valid one.
if (result.getRawParameters().containsKey("one")) {
assertThat(result.getResult(), is(1234));
assertThat(result.getRawParameters().get("one"), is("foo"));
} else {
assertThat(result.getResult(), is(4321));
assertThat(result.getRawParameters().get("two"), is("foo"));
}
}
@Test
void builderNullPath() {
try {
PathTrie.builder().add("GET", null, 1234);
fail("expected NullPointerException");
} catch (NullPointerException e) {
// expected
}
}
@Test
void builderNullValue() {
try {
PathTrie.builder().add("GET", "throws/an/exception", null);
fail("expected NullPointerException");
} catch (NullPointerException e) {
// expected
}
}
@Test
void resolveNullPath() {
try {
PathTrie<Integer> trie = PathTrie.<Integer>builder().build();
trie.resolve("GET", null);
fail("expected NullPointerException");
} catch (NullPointerException e) {
// expected
}
}
@Test
void invalidParameterName() {
try {
PathTrie.builder().add("GET", "bad/{[test}", 1234);
fail("expected IllegalArgumentException");
} catch (IllegalArgumentException e) {
// expected
}
}
@Test
void invalidPathParameterSyntax() {
try {
PathTrie.builder().add("GET", "bad/{test", 1234);
fail("expected IllegalArgumentException");
} catch (IllegalArgumentException e) {
// expected
}
}
@Test
void invalidParameterSegment() {
String invalids = "?#[]{}";
for (char c : invalids.toCharArray()) {
try {
PathTrie.builder().add("GET", "bad/" + c, 1234);
fail("expected IllegalArgumentException");
} catch (IllegalArgumentException e) {
// expected
}
}
}
private void doStrictDuplicateTest(String path, String duplicatePath) {
try {
PathTrie.builder()
.add("GET", path, 1234)
.add("GET", duplicatePath, 4321);
fail("expected IllegalArgumentException");
} catch (IllegalArgumentException e) {
// expected
}
}
private void assertSuccessfulGetResolution(PathTrie<Integer> trie, String path, Integer value) {
assertSuccessfulResolution(trie, "GET", path, value);
}
private void assertSuccessfulResolution(PathTrie<Integer> trie, String method, String path, Integer value) {
assertSuccessfulResolution(trie, method, path, value, Collections.emptyMap());
}
private void assertSuccessfulGetResolution(PathTrie<Integer> trie, String path, Integer value,
Map<String, String> rawParameters) {
assertSuccessfulResolution(trie, "GET", path, value, rawParameters);
}
private void assertSuccessfulResolution(PathTrie<Integer> trie, String method, String path, Integer value,
Map<String, String> rawParameters) {
PathTrie.Result<Integer> result = trie.resolve(method, path);
assertThat(result, notNullValue());
assertThat(result.getResult(), is(value));
assertThat(result.getRawParameters(), is(rawParameters));
}
private void assertFailedGetResolution(PathTrie<Integer> trie, String path) {
assertFailedGetResolution(trie, "GET", path);
}
private void assertFailedGetResolution(PathTrie<Integer> trie, String method, String path) {
assertThat(trie.resolve(method, path), nullValue());
}
}

View file

@ -4,7 +4,8 @@ import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import org.xbib.net.template.expression.ExpressionType;
import org.xbib.net.template.expression.TemplateExpression;
import org.xbib.net.template.expression.URITemplateExpression;
@ -23,11 +24,11 @@ import org.xbib.net.template.vars.values.NullValue;
import org.xbib.net.template.vars.values.ScalarValue;
import org.xbib.net.template.vars.values.VariableValue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import java.nio.CharBuffer;
import java.util.ArrayList;
@ -38,12 +39,10 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
*/
public class URITemplateTest {
class URITemplateTest {
@Test
public void simpleTest() {
void simpleTest() {
String[] strings = new String[]{
"foo", "%33foo", "foo%20", "foo_%20bar", "FoOb%02ZAZE287", "foo.bar", "foo_%20bar.baz%af.r"
};
@ -57,7 +56,7 @@ public class URITemplateTest {
}
@Test
public void invalidTest() {
void invalidTest() {
String[] strings = new String[]{"", "%", "foo..bar", ".", "foo%ra", "foo%ar"};
for (String s : strings) {
try {
@ -71,7 +70,7 @@ public class URITemplateTest {
}
@Test
public void literalTest() {
void literalTest() {
Variables vars = Variables.builder().build();
String[] strings = new String[]{"foo", "%23foo", "%23foo%24", "foo%24", "f%c4oo", "http://slashdot.org",
"x?y=e", "urn:d:ze:/oize#/e/e", "ftp://ftp.foo.com/ee/z?a=b#e/dz",
@ -85,7 +84,7 @@ public class URITemplateTest {
}
@Test
public void parsingEmptyInputGivesEmptyList() {
void parsingEmptyInputGivesEmptyList() {
CharBuffer buffer = CharBuffer.wrap("").asReadOnlyBuffer();
List<URITemplateExpression> list = URITemplateParser.parse(buffer);
assertTrue(list.isEmpty());
@ -94,7 +93,7 @@ public class URITemplateTest {
@Test
@SuppressWarnings("unchecked")
public void parseExpressions() {
void parseExpressions() {
List<Object[]> list = new ArrayList<>();
String input;
ExpressionType type;
@ -130,7 +129,7 @@ public class URITemplateTest {
}
@Test
public void parseInvalidExpressions() {
void parseInvalidExpressions() {
try {
CharBuffer buffer = CharBuffer.wrap("{foo").asReadOnlyBuffer();
new ExpressionParser().parse(buffer);
@ -148,7 +147,7 @@ public class URITemplateTest {
}
@Test
public void parsePrefixes() {
void parsePrefixes() {
String[] strings = new String[]{"foo:323", "%33foo:323", "foo%20:323", "foo_%20bar:323", "FoOb%02ZAZE287:323",
"foo.bar:323", "foo_%20bar.baz%af.r:323"};
for (String s : strings) {
@ -161,7 +160,7 @@ public class URITemplateTest {
}
@Test
public void parseInvalidPrefixes() {
void parseInvalidPrefixes() {
String[] strings = new String[]{"foo:", "foo:-1", "foo:a", "foo:10001", "foo:2147483648"};
for (String s : strings) {
try {
@ -174,7 +173,7 @@ public class URITemplateTest {
}
@Test
public void parseExploded() {
void parseExploded() {
String[] strings = new String[]{"foo*", "%33foo*", "foo%20*", "foo_%20bar*", "FoOb%02ZAZE287*", "foo.bar*",
"foo_%20bar.baz%af.r*"};
for (String s : strings) {
@ -187,7 +186,7 @@ public class URITemplateTest {
}
@Test
public void parseExceptions() {
void parseExceptions() {
String[] strings = new String[]{"foo%", "foo%r", "foo%ra", "foo%ar", "foo<", "foo{"};
for (String s : strings) {
try {
@ -200,7 +199,7 @@ public class URITemplateTest {
}
@Test
public void testExamples() throws Exception {
void testExamples() throws Exception {
JsonNode data = fromResource("/spec-examples.json");
List<Map<String, Object>> list = new ArrayList<>();
for (JsonNode node : data) {
@ -240,7 +239,7 @@ public class URITemplateTest {
}
@Test
public void testExamplesBySection() throws Exception {
void testExamplesBySection() throws Exception {
JsonNode data = fromResource("/spec-examples-by-section.json");
List<Map<String, Object>> list = new ArrayList<>();
for (JsonNode node : data) {
@ -280,7 +279,7 @@ public class URITemplateTest {
}
@Test
public void extendedTests() throws Exception {
void extendedTests() throws Exception {
JsonNode data = fromResource("/extended-tests.json");
List<Map<String, Object>> list = new ArrayList<>();
for (JsonNode node : data) {
@ -320,7 +319,7 @@ public class URITemplateTest {
}
@Test
public void negativeTests() throws Exception {
void negativeTests() throws Exception {
JsonNode data = fromResource("/negative-tests.json");
JsonNode node = data.get("Failure Tests").get("variables");
Variables.Builder builder = Variables.builder();
@ -347,7 +346,7 @@ public class URITemplateTest {
}
@Test
public void expansionTest() throws Exception {
void expansionTest() throws Exception {
String[] strings = new String[]{"/rfcExamples.json", "/strings.json", "/multipleStrings.json",
"/lists.json", "/multipleLists.json"};
for (String s : strings) {