Skip to content

Commit

Permalink
Scheme-specific tests
Browse files Browse the repository at this point in the history
  • Loading branch information
afs committed Oct 5, 2024
1 parent 3ae5178 commit 9fdea69
Show file tree
Hide file tree
Showing 6 changed files with 387 additions and 169 deletions.
2 changes: 1 addition & 1 deletion iri4ld/src/main/java/org/seaborne/rfc3986/Violation.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@
public record Violation (String iriStr, URIScheme scheme, Issue issue, String message) {
@Override
public String toString() {
return String.format("<%s> %s -- %s", iriStr, scheme.getPrefix(), message);
return String.format("<%s> [%s, %s] %s", iriStr, scheme.getPrefix(), issue, message);
}
}
149 changes: 149 additions & 0 deletions iri4ld/src/test/java/org/seaborne/rfc3986/LibTestURI.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.seaborne.rfc3986;

import static org.junit.jupiter.api.Assertions.*;

import java.util.*;
import java.util.function.Supplier;

/**
* Functions in support of IRI3986 testing.
*/
class LibTestURI {

// Syntax and violations
static void good(String iriStr) {
IRI3986 iri = RFC3986.create(iriStr);
if ( iri.hasViolations() )
showViolations(iri);
assertFalse(iri.hasViolations(), "Has violations");
}

// Syntax and violations
static void goodSyntax(String iriStr) {
IRI3986 iri = RFC3986.create(iriStr);
}


// Bad - syntax OK, but one or more violations
static void bad(String iriStr) {
throw new RuntimeException("Not implemented");
}

// Bad RFC 3986 syntax - scheme specific rules not run
static void badSyntax(String iriStr) {
IRIParseException ex = assertThrowsExactly(IRIParseException.class, ()->RFC3986.checkSyntax(iriStr));
}

/**
* Parse the IRI string 9expected to be valid) and execute
* the scheme specific rules, then test the outcome.
* If {@code expectedUriScheme}is null, don't check the scheme in the violation.
*/
static void schemeViolation(String iriStr, URIScheme expectedUriScheme, Issue...issues) {
int expectedCount = issues.length;

IRI3986 iri = RFC3986.create(iriStr);
if ( false || expectedCount == 0 ) {
// Develop helper.
showViolations(iri);
}

if ( expectedUriScheme != null ) {
assertNotNull(iri.scheme());
String expectedName = expectedUriScheme.getName();
String actualName = iri.str().substring(0, expectedName.length());
boolean matches = actualName.regionMatches(true, 0, expectedName, 0, expectedName.length());
assertTrue(matches, ()->String.format("Expected=%s, actual=%s", expectedName, actualName));
}

List<Issue> expected = List.of(issues);
List<Issue> actual = new ArrayList<>();
iri.forEachViolation(a->{
if ( expectedUriScheme != null )
assertEquals( expectedUriScheme, a.scheme(), "scheme --");
actual.add(a.issue());
});

Supplier<String> messageSupplier = ()->"Issues expected="+expected+", actual="+actual;
assertTrue(equalsUnordered(expected, actual), messageSupplier);

// int count = countViolations(iri);
// Set<Issue> expectedSet = new HashSet<>();
// expectedSet.addAll(expected);
//
// Set<Issue> actualSet = new HashSet<>();
// actualSet.addAll(actual);
//
//
// assertEquals(actualSet.size(), actual.size(), "Duplicates -- "+actual);
// assertEquals(expectedSet, actualSet, "Issues -- ");
}

private static final boolean printViolations = false;

/** Parse a syntactically correct string, test whether violations are raised. */
static IRI3986 test3986(String iristr, int expectedViolationCount ) {
IRI3986 iri = IRI3986.create(iristr);
int count = countViolations(iri);
if ( printViolations )
showViolations(iri);
assertEquals(expectedViolationCount, count, "Violation count");
return iri;
}

static void showViolations(IRI3986 iri) {
StringJoiner sj = new StringJoiner("\n ");
sj.add("<"+iri.str()+">");
iri.forEachViolation(v->sj.add(v.toString()));
String all = sj.toString();
System.err.println(all);
}

static int countViolations(IRI3986 iri) {
//class Ref { int vCount = 0; }
var x = new Object() { int vCount = 0; };
iri.forEachViolation(a->x.vCount++);
return x.vCount;
}

/**
* Compare two lists for unordered equality; same elements, same cardinality, any
* order.
* <p>
* This is not intended for use with very large lists.
*/
static <T> boolean equalsUnordered(List<T> list1, List<T> list2) {
if ( list1.size() != list2.size() )
return false;
// containsAll both ways round isn't enough.
// Copy, remove elements one by one, expecting to remove them all.
// The lists are the same length.
List<T> list2a = new ArrayList<>(list2);
for ( T elt : list1 ) {
list2a.remove(elt);
}
if ( list2a.size() != 0 )
return false;
return true;
}


}
35 changes: 5 additions & 30 deletions iri4ld/src/test/java/org/seaborne/rfc3986/TestParseDID.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,12 @@

package org.seaborne.rfc3986;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.util.StringJoiner;
import static org.junit.jupiter.api.Assertions.assertThrowsExactly;

import org.junit.Test;

import org.seaborne.rfc3986.ParseDID.DIDParseException;

/** Test the class ParseDID */
public class TestParseDID {
@Test public void parseDID_01() { goodDID("did:method:specific"); }
Expand All @@ -36,8 +34,6 @@ public class TestParseDID {

@Test public void parseDID_06() { goodDID("did:method:abc%41"); } // %41 == uppercase 'A'

// [DID] More tests

@Test public void parseDID_bad_01() { badDID("did::specific"); }
@Test public void parseDID_bad_02() { badDID("did:method:"); }
@Test public void parseDID_bad_03() { badDID("did::"); }
Expand All @@ -47,35 +43,14 @@ public class TestParseDID {
@Test public void parseDID_bad_07() { badDID("did:method:specifc:"); }
@Test public void parseDID_bad_08() { badDID("did:method:1:2:"); }

@Test public void parseDID_bad_09() { badDID("urn:%6b:NSS"); } // %61 == lowercase 'a'
@Test public void parseDID_bad_09() { badDID("urn:%61:NSS"); } // %61 == lowercase 'a'
@Test public void parseDID_bad_20() { badDID("urn:NID:NSS"); }

@Test public void parse_IRI3986_DID_01() { test3986("did:method:specific", true); }
@Test public void parse_IRI3986_DID_02() { test3986("did::", false); }

private void goodDID(String string) {
ParseDID.parse(string, false);
}

private void badDID(String string) {
try {
ParseDID.parse(string, false);
fail("Expected a parse exception: '"+string+"'");
} catch (IRIParseException ex) {}
}

static IRI3986 test3986(String iristr, boolean valid) {
IRI3986 iri = IRI3986.create(iristr);
if ( valid ) {
StringJoiner sj = new StringJoiner("\n");
if ( iri.hasViolations() ) {
iri.forEachViolation(v->sj.add(v.message()));
String all = sj.toString();
System.err.println(all);
}
assertFalse("Has violations", iri.hasViolations());
} else
assertTrue("Expected violations", iri.hasViolations());
return iri;
assertThrowsExactly(DIDParseException.class, ()->ParseDID.parse(string, false));
}
}
60 changes: 20 additions & 40 deletions iri4ld/src/test/java/org/seaborne/rfc3986/TestParseOID.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,63 +19,43 @@
package org.seaborne.rfc3986;

import org.junit.Test;
import static org.junit.Assert.*;

import java.util.StringJoiner;
import org.seaborne.rfc3986.ParseOID.OIDParseException;

import static org.junit.jupiter.api.Assertions.assertThrowsExactly;
import static org.seaborne.rfc3986.LibTestURI.test3986;

/** Test the class ParseOID */
public class TestParseOID {

@Test public void oid_01() { test("urn:oid:1", true); }
@Test public void oid_01() { goodOID("urn:oid:1"); }

@Test public void oid_02() { test("urn:oid:0", true);}
@Test public void oid_02() { goodOID("urn:oid:0");}

@Test public void oid_03() { test("urn:oid:153.8.0.981.0", true); }
@Test public void oid_03() { goodOID("urn:oid:153.8.0.981.0"); }

@Test public void oid_04() { test("urn:oid:1.2.840.113674.514.212.200", true); }
@Test public void oid_04() { goodOID("urn:oid:1.2.840.113674.514.212.200"); }

@Test public void oid_05() { test("urn:oid:", false); }
@Test public void oid_05() { badOID("urn:oid:"); }

@Test public void oid_06() { test("oid:", false); }
@Test public void oid_06() { badOID("oid:"); }

@Test public void oid_07() { test("urn:oid:01", false); }
@Test public void oid_07() { badOID("urn:oid:01"); }

@Test public void oid_08() { test("urn:oid:1.2.3.01", false); }
@Test public void oid_08() { badOID("urn:oid:1.2.3.01"); }

@Test public void oid_09() { test("urn:oid:Z", false); }
@Test public void oid_09() { badOID("urn:oid:Z"); }

@Test public void oid_10() { test("urn:oid:Z", false); }
@Test public void oid_10() { badOID("urn:oid:Z"); }

// Test the schema specific tests are in IRI3986
@Test public void iri3986_oid_10() { test3986("urn:oid:2.3.4", true); }
@Test public void iri3986_oid_11() { test3986("urn:oid:Z", false); }
@Test public void iri3986_oid_10() { test3986("urn:oid:2.3.4", 0); }
@Test public void iri3986_oid_11() { test3986("urn:oid:Z", 1); }

static IRI3986 test(String string, boolean valid) {
try {
IRI3986 iri = ParseOID.parse(string);
if ( valid ) {
return iri;
}
fail("Should have failed");
} catch (IRIParseException ex) {
if ( valid )
throw ex;
}
return null;
private void goodOID(String string) {
ParseOID.parse(string);
}

static IRI3986 test3986(String iristr, boolean valid) {
IRI3986 iri = IRI3986.create(iristr);
if ( valid ) {
StringJoiner sj = new StringJoiner("\n");
if ( iri.hasViolations() ) {
iri.forEachViolation(v->sj.add(v.message()));
String all = sj.toString();
System.err.println(all);
}
assertFalse("Has violations", iri.hasViolations());
} else
assertTrue("Expected violations", iri.hasViolations());
return iri;
private void badOID(String string) {
assertThrowsExactly(OIDParseException.class, ()->ParseOID.parse(string));
}
}
Loading

0 comments on commit 9fdea69

Please sign in to comment.