Allow deeper nesting of hostnames

This commit is contained in:
2026-06-02 13:19:25 +00:00
parent 6f3c7338c7
commit cb03c811ef
2 changed files with 121 additions and 103 deletions

View File

@@ -20,7 +20,7 @@ class COIDParser {
const COID_VERSIONED = 3; const COID_VERSIONED = 3;
const COID_VERSION_WILDCARD = 4; const COID_VERSION_WILDCARD = 4;
const REGEX_HOSTNAME = "/^([a-z0-9-]+\.)?[a-z0-9-]+\.[a-z]+$/"; const REGEX_HOSTNAME = "/^([a-z0-9-]+\.)*[a-z0-9-]+\.[a-z]+$/";
const REGEX_SEGMENT = "/^[A-Za-z-_0-9\.]+$/"; const REGEX_SEGMENT = "/^[A-Za-z-_0-9\.]+$/";
const REGEX_VERSION_WILDCARD = "/^((\^|~)(\d+\.)?\d|(\d+\.){1,2}\*)$/"; const REGEX_VERSION_WILDCARD = "/^((\^|~)(\d+\.)?\d|(\d+\.){1,2}\*)$/";

View File

@@ -10,121 +10,139 @@ use ML\IRI\IRI;
class COIDParserTest extends \PHPUnit\Framework\TestCase { class COIDParserTest extends \PHPUnit\Framework\TestCase {
public function testRootCOID() { public function testRootCOID() {
$coid = new IRI('coid://example.com'); $coid = new IRI('coid://example.com');
$this->assertEquals(COIDParser::COID_ROOT, COIDParser::getType($coid)); $this->assertEquals(COIDParser::COID_ROOT, COIDParser::getType($coid));
}
public function testInvalidRootCOID() { $coid = new IRI('coid://subdomain.example.com');
$coid = new IRI('coid://example'); $this->assertEquals(COIDParser::COID_ROOT, COIDParser::getType($coid));
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
$coid = new IRI('coid://exämple.com');
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
$coid = new IRI('coid://ex&mple.com');
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
}
public function testInvalidCOID() { $coid = new IRI('coid://anotherlevel.subdomain.example.com');
$coid = new IRI('http://example.com'); $this->assertEquals(COIDParser::COID_ROOT, COIDParser::getType($coid));
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid)); }
$coid = new IRI('example.com');
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
$coid = new IRI('COID://example.com');
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
$coid = new IRI('Coid://example.com');
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
$coid = new IRI('coid://EXAMPLE.COM');
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
$coid = new IRI('coid://exAMPle.CoM');
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
}
public function testUnversionedCOID() { public function testInvalidRootCOID() {
$coid = new IRI('coid://example.com/Example'); $coid = new IRI('coid://example');
$this->assertEquals(COIDParser::COID_UNVERSIONED, COIDParser::getType($coid)); $this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
}
public function testInvalidUnversionedCOID() { $coid = new IRI('coid://exämple.com');
$coid = new IRI('coid://example.com/Exümple'); $this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
$coid = new IRI('coid://example.com/Examp%e');
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
}
public function testVersionedCOID() { $coid = new IRI('coid://ex&mple.com');
$coid = new IRI('coid://example.com/Example/1.0'); $this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
$this->assertEquals(COIDParser::COID_VERSIONED, COIDParser::getType($coid)); }
$coid = new IRI('coid://example.com/Example/alpha');
$this->assertEquals(COIDParser::COID_VERSIONED, COIDParser::getType($coid));
}
public function testInvalidVersionedCOID() { public function testInvalidCOID() {
$coid = new IRI('coid://example.com/Example/1.$'); $coid = new IRI('http://example.com');
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid)); $this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
}
public function testVersionWildcardCOID() { $coid = new IRI('example.com');
$coid = new IRI('coid://example.com/Example/^1.0'); $this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
$this->assertEquals(COIDParser::COID_VERSION_WILDCARD, COIDParser::getType($coid));
$coid = new IRI('coid://example.com/Example/~1.0');
$this->assertEquals(COIDParser::COID_VERSION_WILDCARD, COIDParser::getType($coid));
$coid = new IRI('coid://example.com/Example/1.*');
$this->assertEquals(COIDParser::COID_VERSION_WILDCARD, COIDParser::getType($coid));
}
public function testInvalidVersionWildcardCOID() { $coid = new IRI('COID://example.com');
$coid = new IRI('coid://example.com/Example/^1.*'); $this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
$coid = new IRI('coid://example.com/Example/1.a.*');
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
}
public function testIRICaseSensitivity() { $coid = new IRI('Coid://example.com');
$coid1 = new IRI('coid://example.com/example/1.0'); $this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
$coid2 = new IRI('coid://example.com/Example/1.0');
$this->assertFalse($coid1->equals($coid2));
}
public function testRootFromString() { $coid = new IRI('coid://EXAMPLE.COM');
$coid1 = new IRI('coid://example.com'); $this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
$coid2 = COIDParser::fromString('coid://example.com');
$coid3 = COIDParser::fromString('example.com'); $coid = new IRI('coid://exAMPle.CoM');
$this->assertTrue($coid1->equals($coid2)); $this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
$this->assertTrue($coid1->equals($coid3)); }
}
public function testUnversionedFromString() { public function testUnversionedCOID() {
$coid1 = new IRI('coid://example.com/Example'); $coid = new IRI('coid://subdomain.example.com/Example');
$coid2 = COIDParser::fromString('coid://example.com/Example'); $this->assertEquals(COIDParser::COID_UNVERSIONED, COIDParser::getType($coid));
$coid3 = COIDParser::fromString('example.com/Example'); }
$this->assertTrue($coid1->equals($coid2));
$this->assertTrue($coid1->equals($coid3));
}
public function testVersionedFromString() { public function testInvalidUnversionedCOID() {
$coid1 = new IRI('coid://example.com/Example/1.0'); $coid = new IRI('coid://example.com/Exümple');
$coid2 = COIDParser::fromString('coid://example.com/Example/1.0'); $this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
$coid3 = COIDParser::fromString('example.com/Example/1.0');
$this->assertTrue($coid1->equals($coid2));
$this->assertTrue($coid1->equals($coid3));
}
public function testNormalizeRootFromString() { $coid = new IRI('coid://example.com/Examp%e');
$coid1 = new IRI('coid://example.com'); $this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
$coid2 = COIDParser::fromString('COID://example.com'); }
$coid3 = COIDParser::fromString('ExAmple.COM');
$this->assertTrue($coid1->equals($coid2));
$this->assertTrue($coid1->equals($coid3));
}
public function testNormalizeNonRootFromString() { public function testVersionedCOID() {
$coid1 = new IRI('coid://example.com/Example'); $coid = new IRI('coid://anotherlevel.subdomain.example.com/Example/1.0');
$coid2 = COIDParser::fromString('COID://example.com/Example'); $this->assertEquals(COIDParser::COID_VERSIONED, COIDParser::getType($coid));
$coid3 = COIDParser::fromString('ExAmple.COM/Example');
$coid4 = COIDParser::fromString('ExAmple.COM/EXample'); $coid = new IRI('coid://subdomain.example.com/Example/alpha');
$this->assertTrue($coid1->equals($coid2)); $this->assertEquals(COIDParser::COID_VERSIONED, COIDParser::getType($coid));
$this->assertTrue($coid1->equals($coid3)); }
$this->assertFalse($coid1->equals($coid4));
} public function testInvalidVersionedCOID() {
$coid = new IRI('coid://example.com/Example/1.$');
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
}
public function testVersionWildcardCOID() {
$coid = new IRI('coid://example.com/Example/^1.0');
$this->assertEquals(COIDParser::COID_VERSION_WILDCARD, COIDParser::getType($coid));
$coid = new IRI('coid://example.com/Example/~1.0');
$this->assertEquals(COIDParser::COID_VERSION_WILDCARD, COIDParser::getType($coid));
$coid = new IRI('coid://example.com/Example/1.*');
$this->assertEquals(COIDParser::COID_VERSION_WILDCARD, COIDParser::getType($coid));
}
public function testInvalidVersionWildcardCOID() {
$coid = new IRI('coid://example.com/Example/^1.*');
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
$coid = new IRI('coid://example.com/Example/1.a.*');
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
}
public function testIRICaseSensitivity() {
$coid1 = new IRI('coid://example.com/example/1.0');
$coid2 = new IRI('coid://example.com/Example/1.0');
$this->assertFalse($coid1->equals($coid2));
}
public function testRootFromString() {
$coid1 = new IRI('coid://example.com');
$coid2 = COIDParser::fromString('coid://example.com');
$coid3 = COIDParser::fromString('example.com');
$this->assertTrue($coid1->equals($coid2));
$this->assertTrue($coid1->equals($coid3));
}
public function testUnversionedFromString() {
$coid1 = new IRI('coid://example.com/Example');
$coid2 = COIDParser::fromString('coid://example.com/Example');
$coid3 = COIDParser::fromString('example.com/Example');
$this->assertTrue($coid1->equals($coid2));
$this->assertTrue($coid1->equals($coid3));
}
public function testVersionedFromString() {
$coid1 = new IRI('coid://example.com/Example/1.0');
$coid2 = COIDParser::fromString('coid://example.com/Example/1.0');
$coid3 = COIDParser::fromString('example.com/Example/1.0');
$this->assertTrue($coid1->equals($coid2));
$this->assertTrue($coid1->equals($coid3));
}
public function testNormalizeRootFromString() {
$coid1 = new IRI('coid://example.com');
$coid2 = COIDParser::fromString('COID://example.com');
$coid3 = COIDParser::fromString('ExAmple.COM');
$this->assertTrue($coid1->equals($coid2));
$this->assertTrue($coid1->equals($coid3));
}
public function testNormalizeNonRootFromString() {
$coid1 = new IRI('coid://example.com/Example');
$coid2 = COIDParser::fromString('COID://example.com/Example');
$coid3 = COIDParser::fromString('ExAmple.COM/Example');
$coid4 = COIDParser::fromString('ExAmple.COM/EXample');
$this->assertTrue($coid1->equals($coid2));
$this->assertTrue($coid1->equals($coid3));
$this->assertFalse($coid1->equals($coid4));
}
} }