diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml
new file mode 100644
index 0000000..e202431
--- /dev/null
+++ b/.github/workflows/phpunit.yml
@@ -0,0 +1,27 @@
+name: PHPUnit
+
+on:
+ push:
+ branches: [ "master" ]
+ pull_request:
+ branches: [ "master" ]
+
+jobs:
+ build-test:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v3
+
+ - uses: php-actions/composer@v6
+
+ - name: Tests
+ uses: php-actions/phpunit@v3
+ env:
+ TEST_NAME: Scarlett
+ with:
+ bootstrap: vendor/autoload.php
+ configuration: phpunit.xml
+ args: --coverage-text
+ version: 9
+ php_version: "7.4"
diff --git a/composer.json b/composer.json
index 6f673a1..99c5e7a 100644
--- a/composer.json
+++ b/composer.json
@@ -10,7 +10,7 @@
"php": ">=7.4"
},
"require-dev": {
- "phpunit/phpunit": "~7.5"
+ "phpunit/phpunit": "~9.6"
},
"autoload": {
"psr-4": {
diff --git a/phpunit.xml b/phpunit.xml
index cc01c81..577ca64 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -3,7 +3,6 @@
./tests/Mods/
- ./tests/Mods/Context
diff --git a/src/Mods/Attribute/Common/Linking/XlinkHrefAttribute.php b/src/Mods/Attribute/Common/Linking/XlinkHrefAttribute.php
index 0947ef4..551fca0 100644
--- a/src/Mods/Attribute/Common/Linking/XlinkHrefAttribute.php
+++ b/src/Mods/Attribute/Common/Linking/XlinkHrefAttribute.php
@@ -24,6 +24,6 @@ trait XlinkHrefAttribute
*/
public function getXlinkHref(): string
{
- return $this->getStringAttribute('xlinkHref');
+ return $this->getStringAttribute('xlink:href');
}
}
diff --git a/src/Mods/Element/Xml/Element.php b/src/Mods/Element/Xml/Element.php
index fe2f412..a186476 100644
--- a/src/Mods/Element/Xml/Element.php
+++ b/src/Mods/Element/Xml/Element.php
@@ -46,6 +46,7 @@ public function __construct(\SimpleXMLElement $xml, string $xpath)
{
$this->xml = $xml;
$this->xml->registerXPathNamespace('mods', 'http://www.loc.gov/mods/v3');
+ $this->xml->registerXPathNamespace('xlink', 'http://www.w3.org/1999/xlink');
$this->values = $this->xml->xpath($xpath);
}
diff --git a/src/Mods/ModsReader.php b/src/Mods/ModsReader.php
index 733fbfd..c86577b 100644
--- a/src/Mods/ModsReader.php
+++ b/src/Mods/ModsReader.php
@@ -109,16 +109,19 @@ public function getAccessConditions(string $query = ''): array
*
* @param string $query The XPath query for metadata search
*
- * @return ?Classification
+ * @return Classification[]
*/
- public function getClassification(string $query = ''): ?Classification
+ public function getClassifications(string $query = ''): array
{
+ $classifications = [];
$xpath = './mods:classification' . $query;
$element = new Element($this->xml, $xpath);
if ($element->exists()) {
- return new Classification($element->getValues()[0]);
+ foreach ($element->getValues() as $value) {
+ $classifications[] = new Classification($value);
+ }
}
- return null;
+ return $classifications;
}
/**
@@ -150,16 +153,19 @@ public function getExtensions(string $query = ''): array
*
* @param string $query The XPath query for metadata search
*
- * @return ?Genre
+ * @return Genre[]
*/
- public function getGenre(string $query = ''): ?Genre
+ public function getGenres(string $query = ''): array
{
- $xpath = './mods:classification' . $query;
+ $genres = [];
+ $xpath = './mods:genre' . $query;
$element = new Element($this->xml, $xpath);
if ($element->exists()) {
- return new Genre($element->getValues()[0]);
+ foreach ($element->getValues() as $value) {
+ $genres[] = new Genre($value);
+ }
}
- return null;
+ return $genres;
}
/**
@@ -210,16 +216,19 @@ public function getLanguage(string $query = ''): ?Language
*
* @param string $query The XPath query for metadata search
*
- * @return ?Location
+ * @return Location[]
*/
- public function getLocation(string $query = ''): ?Location
+ public function getLocations(string $query = ''): array
{
+ $locations = [];
$xpath = './mods:location' . $query;
$element = new Element($this->xml, $xpath);
if ($element->exists()) {
- return new Location($element->getValues()[0]);
+ foreach ($element->getValues() as $value) {
+ $locations[] = new Location($value);
+ }
}
- return null;
+ return $locations;
}
/**
@@ -363,7 +372,7 @@ public function getRecordInfos(string $query = ''): array
*
* @return RelatedItem[]
*/
- public function getRelatedItem(string $query = ''): array
+ public function getRelatedItems(string $query = ''): array
{
$relatedItems = [];
$xpath = './mods:relatedItem' . $query;
diff --git a/tests/Mods/ModsReaderTest.php b/tests/Mods/ModsReaderTest.php
new file mode 100644
index 0000000..9dcc919
--- /dev/null
+++ b/tests/Mods/ModsReaderTest.php
@@ -0,0 +1,944 @@
+bookReader = new ModsReader($xmlBook);
+
+ $xmlSerial = simplexml_load_file(__DIR__.'/../resources/mods_serial.xml');
+ $this->serialReader = new ModsReader($xmlSerial);
+ }
+
+ /**
+ * This method is called after each test.
+ */
+ protected function tearDown(): void
+ {
+ }
+
+ public function testGetAbstractForBookDocument()
+ {
+ $abstract = $this->bookReader->getAbstract();
+ self::assertNotNull($abstract);
+ self::assertNotEmpty($abstract->getDisplayLabel());
+ self::assertEquals('Content description', $abstract->getDisplayLabel());
+ self::assertNotEmpty($abstract->getValue());
+ self::assertEquals('Test description for document which contains display label.', $abstract->getValue());
+ self::assertTrue($abstract->isShareable());
+ }
+
+ public function testGetAbstractByQueryForBookDocument()
+ {
+ $abstract = $this->bookReader->getAbstract('[@displayLabel="Content description"]');
+ self::assertNotNull($abstract);
+ self::assertNotEmpty($abstract->getDisplayLabel());
+ self::assertEquals('Content description', $abstract->getDisplayLabel());
+ self::assertNotEmpty($abstract->getValue());
+ self::assertEquals('Test description for document which contains display label.', $abstract->getValue());
+ self::assertTrue($abstract->isShareable());
+ }
+
+ public function testGetNoAbstractByQueryForBookDocument()
+ {
+ $abstract = $this->bookReader->getAbstract('[@displayLabel="Random"]');
+ self::assertNull($abstract);
+ }
+
+ public function testGetAbstractForSerialDocument()
+ {
+ $abstract = $this->serialReader->getAbstract();
+ self::assertNotNull($abstract);
+ self::assertEmpty($abstract->getDisplayLabel());
+ self::assertNotEmpty($abstract->getValue());
+ self::assertEquals('Test description for non shareable document.', $abstract->getValue());
+ self::assertFalse($abstract->isShareable());
+ }
+
+ public function testGetAbstractByQueryForSerialDocument()
+ {
+ $abstract = $this->serialReader->getAbstract('[@shareable="no"]');
+ self::assertNotNull($abstract);
+ self::assertEmpty($abstract->getDisplayLabel());
+ self::assertNotEmpty($abstract->getValue());
+ self::assertEquals('Test description for non shareable document.', $abstract->getValue());
+ self::assertFalse($abstract->isShareable());
+ }
+
+ public function testGetNoAbstractByQueryForSerialDocument()
+ {
+ $abstract = $this->serialReader->getAbstract('[@shareable="yes"]');
+ self::assertNull($abstract);
+ }
+
+ public function testGetAccessConditionsForBookDocument()
+ {
+ $accessConditions = $this->bookReader->getAccessConditions();
+ self::assertNotEmpty($accessConditions);
+ self::assertEquals(1, count($accessConditions));
+ self::assertNotEmpty($accessConditions[0]->getValue());
+ self::assertEquals('Use of this public-domain resource is unrestricted.', $accessConditions[0]->getValue());
+ self::assertNotEmpty($accessConditions[0]->getType());
+ self::assertEquals('use and reproduction', $accessConditions[0]->getType());
+ self::assertEmpty($accessConditions[0]->getDisplayLabel());
+ self::assertEmpty($accessConditions[0]->getXlinkHref());
+ }
+
+ public function testGetAccessConditionsByQueryForBookDocument()
+ {
+ $accessConditions = $this->bookReader->getAccessConditions('[@type="use and reproduction"]');
+ self::assertNotEmpty($accessConditions);
+ self::assertEquals(1, count($accessConditions));
+ self::assertNotEmpty($accessConditions[0]->getValue());
+ self::assertEquals('Use of this public-domain resource is unrestricted.', $accessConditions[0]->getValue());
+ self::assertNotEmpty($accessConditions[0]->getType());
+ self::assertEquals('use and reproduction', $accessConditions[0]->getType());
+ self::assertEmpty($accessConditions[0]->getDisplayLabel());
+ self::assertEmpty($accessConditions[0]->getXlinkHref());
+ }
+
+ public function testGetNoAccessConditionsByQueryForBookDocument()
+ {
+ $accessConditions = $this->bookReader->getAccessConditions('[@type="restriction on access"]');
+ self::assertEmpty($accessConditions);
+ }
+
+ public function testGetAccessConditionsForSerialDocument()
+ {
+ $accessConditions = $this->serialReader->getAccessConditions();
+ self::assertNotEmpty($accessConditions);
+ self::assertEquals(1, count($accessConditions));
+ self::assertNotEmpty($accessConditions[0]->getValue());
+ self::assertEquals('Open Access', $accessConditions[0]->getValue());
+ self::assertNotEmpty($accessConditions[0]->getType());
+ self::assertEquals('restriction on access', $accessConditions[0]->getType());
+ self::assertNotEmpty($accessConditions[0]->getDisplayLabel());
+ self::assertEquals('Access Status', $accessConditions[0]->getDisplayLabel());
+ // TODO: check out xlink
+ //self::assertEquals('http://purl.org/eprint/accessRights/OpenAccess', $accessConditions[0]->getXlinkHref());
+ }
+
+ public function testGetAccessConditionsByQueryForSerialDocument()
+ {
+ $accessConditions = $this->serialReader->getAccessConditions('[@type="restriction on access"]');
+ self::assertNotEmpty($accessConditions);
+ self::assertEquals(1, count($accessConditions));
+ self::assertNotEmpty($accessConditions[0]->getValue());
+ self::assertEquals('Open Access', $accessConditions[0]->getValue());
+ self::assertNotEmpty($accessConditions[0]->getType());
+ self::assertEquals('restriction on access', $accessConditions[0]->getType());
+ self::assertNotEmpty($accessConditions[0]->getDisplayLabel());
+ self::assertEquals('Access Status', $accessConditions[0]->getDisplayLabel());
+ // TODO: check out xlink
+ //self::assertEquals('http://purl.org/eprint/accessRights/OpenAccess', $accessConditions[0]->getXlinkHref());
+ }
+
+ public function testGetNoAccessConditionsByQueryForSerialDocument()
+ {
+ $accessConditions = $this->serialReader->getAccessConditions('[@type="use and reproduction"]');
+ self::assertEmpty($accessConditions);
+ }
+
+ public function testGetClassificationsForBookDocument()
+ {
+ $classifications = $this->bookReader->getClassifications();
+ self::assertNotEmpty($classifications);
+ self::assertEquals(2, count($classifications));
+ self::assertNotEmpty($classifications[0]->getValue());
+ self::assertEquals('PN4888.P6 A48 1999', $classifications[0]->getValue());
+ self::assertNotEmpty($classifications[0]->getAuthority());
+ self::assertEquals('lcc', $classifications[0]->getAuthority());
+ self::assertEmpty($classifications[0]->getId());
+ self::assertEmpty($classifications[0]->getUsage());
+ }
+
+ public function testGetClassificationsByQueryForBookDocument()
+ {
+ $classifications = $this->bookReader->getClassifications('[@authority="ddc"]');
+ self::assertNotEmpty($classifications);
+ self::assertEquals(1, count($classifications));
+ self::assertNotEmpty($classifications[0]->getValue());
+ self::assertEquals('071/.3', $classifications[0]->getValue());
+ self::assertNotEmpty($classifications[0]->getEdition());
+ self::assertEquals('21', $classifications[0]->getEdition());
+ self::assertEmpty($classifications[0]->getDisplayLabel());
+ self::assertEmpty($classifications[0]->getGenerator());
+ }
+
+ public function testGetNoClassificationsByQueryForBookDocument()
+ {
+ $classifications = $this->bookReader->getAccessConditions('[@generator="xyz"]');
+ self::assertEmpty($classifications);
+ }
+
+ public function testGetClassificationsForSerialDocument()
+ {
+ $classifications = $this->serialReader->getClassifications();
+ self::assertNotEmpty($classifications);
+ self::assertEquals(1, count($classifications));
+ self::assertNotEmpty($classifications[0]->getValue());
+ self::assertEquals('027.7/05', $classifications[0]->getValue());
+ self::assertNotEmpty($classifications[0]->getAuthority());
+ self::assertEquals('ddc', $classifications[0]->getAuthority());
+ self::assertNotEmpty($classifications[0]->getEdition());
+ self::assertEquals('21', $classifications[0]->getEdition());
+ self::assertEmpty($classifications[0]->getDisplayLabel());
+ self::assertEmpty($classifications[0]->getGenerator());
+ }
+
+ public function testGetClassificationsByQueryForSerialDocument()
+ {
+ $classifications = $this->serialReader->getClassifications('[@authority="ddc"]');
+ self::assertNotEmpty($classifications);
+ self::assertEquals(1, count($classifications));
+ self::assertNotEmpty($classifications[0]->getValue());
+ self::assertEquals('027.7/05', $classifications[0]->getValue());
+ self::assertNotEmpty($classifications[0]->getAuthority());
+ self::assertEquals('ddc', $classifications[0]->getAuthority());
+ self::assertNotEmpty($classifications[0]->getEdition());
+ self::assertEquals('21', $classifications[0]->getEdition());
+ self::assertEmpty($classifications[0]->getDisplayLabel());
+ self::assertEmpty($classifications[0]->getGenerator());
+ }
+
+ public function testGetNoClassificationsByQueryForSerialDocument()
+ {
+ $classifications = $this->serialReader->getClassifications('[@edition="22"]');
+ self::assertEmpty($classifications);
+ }
+
+ public function testGetExtensionsForBookDocument()
+ {
+ $extensions = $this->bookReader->getExtensions();
+
+ $this->assertTrue(true, 'WIP');
+ }
+
+ public function testGetExtensionsForSerialDocument()
+ {
+ $extensions = $this->serialReader->getExtensions();
+
+ $this->assertTrue(true, 'WIP');
+ }
+
+ public function testGetGenresForBookDocument()
+ {
+ $genres = $this->bookReader->getGenres();
+ self::assertNotEmpty($genres);
+ self::assertEquals(1, count($genres));
+ self::assertNotEmpty($genres[0]->getValue());
+ self::assertEquals('bibliography', $genres[0]->getValue());
+ self::assertNotEmpty($genres[0]->getAuthority());
+ self::assertEquals('marcgt', $genres[0]->getAuthority());
+ self::assertEmpty($genres[0]->getLang());
+ self::assertEmpty($genres[0]->getScript());
+ }
+
+ public function testGetGenresByQueryForBookDocument()
+ {
+ $genres = $this->bookReader->getGenres('[@authority="marcgt"]');
+ self::assertNotEmpty($genres);
+ self::assertEquals(1, count($genres));
+ self::assertNotEmpty($genres[0]->getValue());
+ self::assertEquals('bibliography', $genres[0]->getValue());
+ self::assertNotEmpty($genres[0]->getAuthority());
+ self::assertEquals('marcgt', $genres[0]->getAuthority());
+ self::assertEmpty($genres[0]->getLang());
+ self::assertEmpty($genres[0]->getScript());
+ }
+
+ public function testGetNoGenresByQueryForBookDocument()
+ {
+ $genres = $this->bookReader->getGenres('[@authority="merc"]');
+ self::assertEmpty($genres);
+ }
+
+ public function testGetGenresForSerialDocument()
+ {
+ $genres = $this->serialReader->getGenres();
+ self::assertNotEmpty($genres);
+ self::assertEquals(2, count($genres));
+ self::assertNotEmpty($genres[0]->getValue());
+ self::assertEquals('periodical', $genres[0]->getValue());
+ self::assertNotEmpty($genres[0]->getUsage());
+ self::assertEquals('primary', $genres[0]->getUsage());
+ self::assertEmpty($genres[0]->getDisplayLabel());
+ self::assertEmpty($genres[0]->getTransliteration());
+ }
+
+ public function testGetGenresByQueryForSerialDocument()
+ {
+ $genres = $this->serialReader->getGenres('[@usage="primary"]');
+ self::assertNotEmpty($genres);
+ self::assertEquals(1, count($genres));
+ self::assertNotEmpty($genres[0]->getValue());
+ self::assertEquals('periodical', $genres[0]->getValue());
+ self::assertNotEmpty($genres[0]->getUsage());
+ self::assertEquals('primary', $genres[0]->getUsage());
+ self::assertEmpty($genres[0]->getDisplayLabel());
+ self::assertEmpty($genres[0]->getTransliteration());
+ }
+
+ public function testGetNoGenresByQueryForSerialDocument()
+ {
+ $genres = $this->serialReader->getGenres('[@type="xyz"]');
+ self::assertEmpty($genres);
+ }
+
+ public function testGetIdentifiersForBookDocument()
+ {
+ $identifiers = $this->bookReader->getIdentifiers();
+ self::assertNotEmpty($identifiers);
+ self::assertEquals(2, count($identifiers));
+ self::assertNotEmpty($identifiers[0]->getValue());
+ self::assertEquals('0801486394 (pbk. : acid-free, recycled paper)', $identifiers[0]->getValue());
+ self::assertNotEmpty($identifiers[0]->getType());
+ self::assertEquals('isbn', $identifiers[0]->getType());
+ self::assertEmpty($identifiers[0]->getLang());
+ self::assertFalse($identifiers[0]->isInvalid());
+ }
+
+ public function testGetIdentifiersByQueryForBookDocument()
+ {
+ $identifiers = $this->bookReader->getIdentifiers('[@type="lccn"]');
+ self::assertNotEmpty($identifiers);
+ self::assertEquals(1, count($identifiers));
+ self::assertNotEmpty($identifiers[0]->getValue());
+ self::assertEquals('99042030', $identifiers[0]->getValue());
+ self::assertNotEmpty($identifiers[0]->getType());
+ self::assertEquals('lccn', $identifiers[0]->getType());
+ self::assertEmpty($identifiers[0]->getLang());
+ self::assertFalse($identifiers[0]->isInvalid());
+ }
+
+ public function testGetNoIdentifiersByQueryForBookDocument()
+ {
+ $identifiers = $this->bookReader->getIdentifiers('[@type="xyz"]');
+ self::assertEmpty($identifiers);
+ }
+
+ public function testGetIdentifiersForSerialDocument()
+ {
+ $identifiers = $this->serialReader->getIdentifiers();
+ self::assertNotEmpty($identifiers);
+ self::assertEquals(4, count($identifiers));
+ self::assertNotEmpty($identifiers[0]->getValue());
+ self::assertEquals('1704-8532', $identifiers[0]->getValue());
+ self::assertNotEmpty($identifiers[0]->getType());
+ self::assertEquals('issn', $identifiers[0]->getType());
+ self::assertEmpty($identifiers[0]->getDisplayLabel());
+ self::assertFalse($identifiers[0]->isInvalid());
+ }
+
+ public function testGetIdentifiersByQueryForSerialDocument()
+ {
+ $identifiers = $this->serialReader->getIdentifiers('[@type="issn"]');
+ self::assertNotEmpty($identifiers);
+ self::assertEquals(2, count($identifiers));
+ self::assertNotEmpty($identifiers[1]->getValue());
+ self::assertEquals('1525-321X', $identifiers[1]->getValue());
+ self::assertNotEmpty($identifiers[0]->getType());
+ self::assertEquals('issn', $identifiers[1]->getType());
+ self::assertEmpty($identifiers[1]->getDisplayLabel());
+ self::assertTrue($identifiers[1]->isInvalid());
+ }
+
+ public function testGetNoIdentifiersByQueryForSerialDocument()
+ {
+ $identifiers = $this->serialReader->getIdentifiers('[@type="xyz"]');
+ self::assertEmpty($identifiers);
+ }
+
+ public function testGetLanguageForBookDocument()
+ {
+ $language = $this->bookReader->getLanguage();
+ self::assertNotNull($language);
+ // TODO: implement reading of languageTerm and scriptTerm
+ // self::assertNotEmpty($language->getLanguageTerm());
+ // self::assertNotEmpty($language->getScriptTerm());
+
+ $language = $this->bookReader->getLanguage('[@type="text"]');
+ self::assertNull($language);
+ }
+
+ public function testGetLanguageForSerialDocument()
+ {
+ $language = $this->serialReader->getLanguage();
+ self::assertNotNull($language);
+ // TODO: implement reading of languageTerm and scriptTerm
+ // self::assertNotEmpty($language->getLanguageTerm());
+ // self::assertNotEmpty($language->getScriptTerm());
+
+ $language = $this->serialReader->getLanguage('[@type="text"]');
+ self::assertNull($language);
+ }
+
+ public function testGetLocationsForBookDocument()
+ {
+ $locations = $this->bookReader->getLocations();
+ self::assertNotEmpty($locations);
+ self::assertEquals(1, count($locations));
+
+ // TODO: implement reading of location elements
+
+ }
+
+ public function testGetLocationsForSerialDocument()
+ {
+ $locations = $this->serialReader->getLocations();
+ self::assertNotEmpty($locations);
+ self::assertEquals(2, count($locations));
+
+ // TODO: implement reading of location elements
+ }
+
+ public function testGetNamesForBookDocument()
+ {
+ $names = $this->bookReader->getNames();
+ self::assertNotEmpty($names);
+ self::assertEquals(2, count($names));
+
+ // TODO: implement reading of name elements
+
+ }
+
+ public function testGetNamesForSerialDocument()
+ {
+ $names = $this->serialReader->getNames();
+ self::assertNotEmpty($names);
+ self::assertEquals(1, count($names));
+
+ // TODO: implement reading of name elements
+ }
+
+ public function testGetNotesForBookDocument()
+ {
+ $notes = $this->bookReader->getNotes();
+ self::assertNotEmpty($notes);
+ self::assertEquals(2, count($notes));
+ self::assertNotEmpty($notes[0]->getValue());
+ self::assertEquals('Eric Alterman.', $notes[0]->getValue());
+ self::assertNotEmpty($notes[0]->getType());
+ self::assertEquals('statement of responsibility', $notes[0]->getType());
+ }
+
+ public function testGetNotesByQueryForBookDocument()
+ {
+ $notes = $this->bookReader->getNotes('[@type="bibliography"]');
+ self::assertNotEmpty($notes);
+ self::assertEquals(1, count($notes));
+ self::assertNotEmpty($notes[0]->getValue());
+ self::assertEquals('Includes bibliographical references (p. 291-312) and index.', $notes[0]->getValue());
+ self::assertNotEmpty($notes[0]->getType());
+ self::assertEquals('bibliography', $notes[0]->getType());
+ }
+
+ public function testGetNoNotesByQueryForBookDocument()
+ {
+ $notes = $this->bookReader->getNotes('[@type="xyz"]');
+ self::assertEmpty($notes);
+ }
+
+ public function testGetNotesForSerialDocument()
+ {
+ $notes = $this->serialReader->getNotes();
+ self::assertNotEmpty($notes);
+ self::assertEquals(6, count($notes));
+ self::assertNotEmpty($notes[0]->getValue());
+ self::assertEquals('V. 3, no. 1/2 (winter 2002)-', $notes[0]->getValue());
+ self::assertNotEmpty($notes[0]->getType());
+ self::assertEquals('date/sequential designation', $notes[0]->getType());
+ }
+
+ public function testGetNotesByQueryForSerialDocument()
+ {
+ $notes = $this->serialReader->getNotes('[@type="system details"]');
+ self::assertNotEmpty($notes);
+ self::assertEquals(1, count($notes));
+ self::assertNotEmpty($notes[0]->getValue());
+ self::assertEquals('Mode of access: World Wide Web.', $notes[0]->getValue());
+ self::assertNotEmpty($notes[0]->getType());
+ self::assertEquals('system details', $notes[0]->getType());
+ }
+
+ public function testGetNoNotesByQueryForSerialDocument()
+ {
+ $notes = $this->serialReader->getNotes('[@type="xyz"]');
+ self::assertEmpty($notes);
+ }
+
+ public function testGetOriginInfosForBookDocument()
+ {
+ $originInfos = $this->bookReader->getOriginInfos();
+ self::assertNotEmpty($originInfos);
+ self::assertEquals(2, count($originInfos));
+ self::assertNotEmpty($originInfos[0]->getValue());
+ self::assertNotEmpty($originInfos[0]->getEventType());
+ self::assertEquals('publication', $originInfos[0]->getEventType());
+
+ // TODO: implement reading of elements
+ }
+
+ public function testGetOriginInfosByQueryForBookDocument()
+ {
+ $originInfos = $this->bookReader->getOriginInfos('[@eventType="redaction"]');
+ self::assertNotEmpty($originInfos);
+ self::assertEquals(1, count($originInfos));
+ self::assertNotEmpty($originInfos[0]->getValue());
+ self::assertNotEmpty($originInfos[0]->getEventType());
+ self::assertEquals('redaction', $originInfos[0]->getEventType());
+
+ // TODO: implement reading of elements
+ }
+
+ public function testGetNoOriginInfosByQueryForBookDocument()
+ {
+ $originInfos = $this->bookReader->getOriginInfos('[@eventType="xyz"]');
+ self::assertEmpty($originInfos);
+ }
+
+ public function testGetOriginInfosForSerialDocument()
+ {
+ $originInfos = $this->serialReader->getOriginInfos();
+ self::assertNotEmpty($originInfos);
+ self::assertEquals(1, count($originInfos));
+ self::assertNotEmpty($originInfos[0]->getValue());
+ self::assertNotEmpty($originInfos[0]->getEventType());
+ self::assertEquals('publication', $originInfos[0]->getEventType());
+
+ // TODO: implement reading of elements
+ }
+
+ public function testGetOriginInfosByQueryForSerialDocument()
+ {
+ $originInfos = $this->serialReader->getOriginInfos('[@eventType="publication"]');
+ self::assertNotEmpty($originInfos);
+ self::assertEquals(1, count($originInfos));
+ self::assertNotEmpty($originInfos[0]->getValue());
+ self::assertNotEmpty($originInfos[0]->getEventType());
+ self::assertEquals('publication', $originInfos[0]->getEventType());
+
+ // TODO: implement reading of elements
+ }
+
+ public function testGetNoOriginInfosByQueryForSerialDocument()
+ {
+ $originInfos = $this->serialReader->getOriginInfos('[@eventType="xyz"]');
+ self::assertEmpty($originInfos);
+ }
+
+ public function testGetPartsForBookDocument()
+ {
+ $parts = $this->bookReader->getParts();
+ self::assertNotEmpty($parts);
+ self::assertEquals(2, count($parts));
+ self::assertNotEmpty($parts[0]->getValue());
+ self::assertNotEmpty($parts[0]->getType());
+ self::assertEquals('poem', $parts[0]->getType());
+ self::assertNotEmpty($parts[0]->getOrder());
+ self::assertEquals(1, $parts[0]->getOrder());
+
+ // TODO: implement reading of elements
+ }
+
+ public function testGetPartsByQueryForBookDocument()
+ {
+ $parts = $this->bookReader->getParts('[@order="2"]');
+ self::assertNotEmpty($parts);
+ self::assertEquals(1, count($parts));
+ self::assertNotEmpty($parts[0]->getValue());
+ self::assertNotEmpty($parts[0]->getType());
+ self::assertEquals('poem', $parts[0]->getType());
+ self::assertNotEmpty($parts[0]->getOrder());
+ self::assertEquals(2, $parts[0]->getOrder());
+
+ // TODO: implement reading of elements
+ }
+
+ public function testGetNoPartsByQueryForBookDocument()
+ {
+ $parts = $this->bookReader->getParts('[@order="3"]');
+ self::assertEmpty($parts);
+ }
+
+ public function testGetNoPartsForSerialDocument()
+ {
+ $parts = $this->serialReader->getParts();
+ self::assertEmpty($parts);
+ }
+
+ public function testGetPhysicalDescriptionsForBookDocument()
+ {
+ $physicalDescriptions = $this->bookReader->getPhysicalDescriptions();
+ self::assertNotEmpty($physicalDescriptions);
+ self::assertEquals(1, count($physicalDescriptions));
+ self::assertNotEmpty($physicalDescriptions[0]->getValue());
+ //self::assertEquals('', $physicalDescriptions[0]->getValue());
+ //self::assertNotEmpty($physicalDescriptions[0]->getForm());
+ //self::assertNotEmpty($physicalDescriptions[0]->getExtent());
+
+ // TODO: implement reading of elements
+ }
+
+ public function testGetPhysicalDescriptionsByQueryForBookDocument()
+ {
+ $physicalDescriptions = $this->bookReader->getPhysicalDescriptions('[./mods:form[@authority="marcform"]="print"]');
+ self::assertNotEmpty($physicalDescriptions);
+ self::assertEquals(1, count($physicalDescriptions));
+ self::assertNotEmpty($physicalDescriptions[0]->getValue());
+ //self::assertEquals('', $physicalDescriptions[0]->getValue());
+ //self::assertNotEmpty($physicalDescriptions[0]->getForm());
+ //self::assertNotEmpty($physicalDescriptions[0]->getExtent());
+
+ // TODO: implement reading of elements
+ }
+
+ public function testGetNoPhysicalDescriptionsByQueryForBookDocument()
+ {
+ $physicalDescriptions = $this->bookReader->getPhysicalDescriptions('[./mods:form[@authority="marcform"]="electronic"]');
+ self::assertEmpty($physicalDescriptions);
+ }
+
+ public function testGetPhysicalDescriptionsForSerialDocument()
+ {
+ $physicalDescriptions = $this->serialReader->getPhysicalDescriptions();
+ self::assertNotEmpty($physicalDescriptions);
+ self::assertEquals(1, count($physicalDescriptions));
+ self::assertNotEmpty($physicalDescriptions[0]->getValue());
+ //self::assertEquals('', $physicalDescriptions[0]->getValue());
+ //self::assertNotEmpty($physicalDescriptions[0]->getForm());
+ //self::assertNotEmpty($physicalDescriptions[0]->getExtent());
+
+ // TODO: implement reading of elements
+ }
+
+ public function testGetPhysicalDescriptionsByQueryForSerialDocument()
+ {
+ $physicalDescriptions = $this->serialReader->getPhysicalDescriptions('[./mods:form[@authority="marcform"]="electronic"]');
+ self::assertNotEmpty($physicalDescriptions);
+ self::assertEquals(1, count($physicalDescriptions));
+ self::assertNotEmpty($physicalDescriptions[0]->getValue());
+ //self::assertEquals('', $physicalDescriptions[0]->getValue());
+ //self::assertNotEmpty($physicalDescriptions[0]->getForm());
+ //self::assertNotEmpty($physicalDescriptions[0]->getExtent());
+
+ // TODO: implement reading of elements
+ }
+
+ public function testGetNoPhysicalDescriptionsByQueryForSerialDocument()
+ {
+ $physicalDescriptions = $this->serialReader->getPhysicalDescriptions('[./mods:form[@authority="marcform"]="print"]');
+ self::assertEmpty($physicalDescriptions);
+ }
+
+ public function testGetRecordInfosForBookDocument()
+ {
+ $recordInfos = $this->bookReader->getRecordInfos();
+ self::assertNotEmpty($recordInfos);
+ self::assertEquals(1, count($recordInfos));
+ self::assertNotEmpty($recordInfos[0]->getValue());
+ //self::assertEquals('', $recordInfos[0]->getRecordIdentifier());
+ //self::assertNotEmpty($recordInfos[0]->getRecordOrigin());
+ //self::assertNotEmpty($recordInfos[0]->getLanguageOfCataloging());
+
+ // TODO: implement reading of elements
+ }
+
+ public function testGetRecordInfosByQueryForBookDocument()
+ {
+ $recordInfos = $this->bookReader->getRecordInfos('[./mods:descriptionStandard="aacr"]');
+ self::assertNotEmpty($recordInfos);
+ self::assertEquals(1, count($recordInfos));
+ self::assertNotEmpty($recordInfos[0]->getValue());
+ //self::assertEquals('', $recordInfos[0]->getRecordIdentifier());
+ //self::assertNotEmpty($recordInfos[0]->getRecordOrigin());
+ //self::assertNotEmpty($recordInfos[0]->getLanguageOfCataloging());
+
+ // TODO: implement reading of elements
+ }
+
+ public function testGetNoRecordInfosByQueryForBookDocument()
+ {
+ $recordInfos = $this->bookReader->getRecordInfos('[./mods:descriptionStandard="xyz"]');
+ self::assertEmpty($recordInfos);
+ }
+
+ public function testGetRecordInfosForSerialDocument()
+ {
+ $recordInfos = $this->serialReader->getRecordInfos();
+ self::assertNotEmpty($recordInfos);
+ self::assertEquals(1, count($recordInfos));
+ self::assertNotEmpty($recordInfos[0]->getValue());
+ //self::assertEquals('', $recordInfos[0]->getRecordIdentifier());
+ //self::assertNotEmpty($recordInfos[0]->getRecordOrigin());
+ //self::assertNotEmpty($recordInfos[0]->getLanguageOfCataloging());
+
+ // TODO: implement reading of elements
+ }
+
+ public function testGetRecordInfosByQueryForSerialDocument()
+ {
+ $recordInfos = $this->serialReader->getRecordInfos('[./mods:descriptionStandard="aacr"]');
+ self::assertNotEmpty($recordInfos);
+ self::assertEquals(1, count($recordInfos));
+ self::assertNotEmpty($recordInfos[0]->getValue());
+ //self::assertEquals('', $recordInfos[0]->getRecordIdentifier());
+ //self::assertNotEmpty($recordInfos[0]->getRecordOrigin());
+ //self::assertNotEmpty($recordInfos[0]->getLanguageOfCataloging());
+
+ // TODO: implement reading of elements
+ }
+
+ public function testGetNoRecordInfosByQueryForSerialDocument()
+ {
+ $recordInfos = $this->serialReader->getRecordInfos('[./mods:descriptionStandard="xyz"]');
+ self::assertEmpty($recordInfos);
+ }
+
+ public function testGetNoRelatedItemsForBookDocument()
+ {
+ $relatedItems = $this->bookReader->getRelatedItems();
+ self::assertEmpty($relatedItems);
+ }
+
+ public function testGetRelatedItemsForSerialDocument()
+ {
+ $relatedItems = $this->serialReader->getRelatedItems();
+ self::assertNotEmpty($relatedItems);
+ self::assertEquals(1, count($relatedItems));
+ self::assertNotEmpty($relatedItems[0]->getValue());
+ self::assertNotEmpty($relatedItems[0]->getType());
+ self::assertEquals('preceding', $relatedItems[0]->getType());
+
+ // TODO: implement reading of elements
+ }
+
+ public function testGetRelatedItemsByQueryForSerialDocument()
+ {
+ $relatedItems = $this->serialReader->getRelatedItems('[./mods:identifier="1525-321X"]');
+ self::assertNotEmpty($relatedItems);
+ self::assertEquals(1, count($relatedItems));
+ self::assertNotEmpty($relatedItems[0]->getValue());
+ self::assertNotEmpty($relatedItems[0]->getType());
+ self::assertEquals('preceding', $relatedItems[0]->getType());
+
+ // TODO: implement reading of elements
+ }
+
+ public function testGetNoRelatedItemsByQueryForSerialDocument()
+ {
+ $relatedItems = $this->serialReader->getRelatedItems('[./mods:identifier="15-32"]');
+ self::assertEmpty($relatedItems);
+ }
+
+ public function testGetSubjectsForBookDocument()
+ {
+ $subjects = $this->bookReader->getSubjects();
+ self::assertNotEmpty($subjects);
+ self::assertEquals(7, count($subjects));
+ self::assertNotEmpty($subjects[0]->getValue());
+ //self::assertNotEmpty($subjects[0]->getTopic());
+ //self::assertNotEmpty($subjects[0]->getGeographic());
+
+ // TODO: implement reading of elements
+ }
+
+ public function testGetSubjectsByQueryForBookDocument()
+ {
+ $subjects = $this->bookReader->getSubjects('[./mods:topic="Mass media"]');
+ self::assertNotEmpty($subjects);
+ self::assertEquals(1, count($subjects));
+ self::assertNotEmpty($subjects[0]->getValue());
+ //self::assertNotEmpty($subjects[0]->getTopic());
+ //self::assertNotEmpty($subjects[0]->getGeographic());
+
+ // TODO: implement reading of elements
+ }
+
+ public function testGetNoSubjectsByQueryForBookDocument()
+ {
+ $subjects = $this->bookReader->getSubjects('[./mods:topic="Unknown"]');
+ self::assertEmpty($subjects);
+ }
+
+ public function testGetSubjectsForSerialDocument()
+ {
+ $subjects = $this->serialReader->getSubjects();
+ self::assertNotEmpty($subjects);
+ self::assertEquals(6, count($subjects));
+ self::assertNotEmpty($subjects[0]->getValue());
+ //self::assertNotEmpty($subjects[0]->getTopic());
+ //self::assertNotEmpty($subjects[0]->getGenre());
+
+ // TODO: implement reading of elements
+ }
+
+ public function testGetSubjectsByQueryForSerialDocument()
+ {
+ $subjects = $this->serialReader->getSubjects('[./mods:genre="Directories"]');
+ self::assertNotEmpty($subjects);
+ self::assertEquals(1, count($subjects));
+ self::assertNotEmpty($subjects[0]->getValue());
+ //self::assertNotEmpty($subjects[0]->getForm());
+ //self::assertNotEmpty($subjects[0]->getGenre());
+
+ // TODO: implement reading of elements
+ }
+
+ public function testGetNoSubjectsByQueryForSerialDocument()
+ {
+ $subjects = $this->serialReader->getSubjects('[./mods:topic="Unknown"]');
+ self::assertEmpty($subjects);
+ }
+
+ public function testGetTableOfContentsForBookDocument()
+ {
+ $tableOfContents = $this->bookReader->getTableOfContents();
+ self::assertNotEmpty($tableOfContents);
+ self::assertEquals(1, count($tableOfContents));
+ self::assertNotEmpty($tableOfContents[0]->getValue());
+ self::assertEquals('Bluegrass odyssey -- Hills of Tennessee -- Sassafrass -- Muddy river -- Take your shoes off Moses -- Let Smokey Mountain smoke get in your eyes -- Farewell party -- Faded love', $tableOfContents[0]->getValue());
+ self::assertNotEmpty($tableOfContents[0]->getDisplayLabel());
+ self::assertEquals('Chapters', $tableOfContents[0]->getDisplayLabel());
+
+ // TODO: implement reading of elements
+ }
+
+ public function testGetTableOfContentsByQueryForBookDocument()
+ {
+ $tableOfContents = $this->bookReader->getTableOfContents('[@displayLabel="Chapters"]');
+ self::assertNotEmpty($tableOfContents);
+ self::assertEquals(1, count($tableOfContents));
+ self::assertNotEmpty($tableOfContents[0]->getValue());
+ self::assertEquals('Bluegrass odyssey -- Hills of Tennessee -- Sassafrass -- Muddy river -- Take your shoes off Moses -- Let Smokey Mountain smoke get in your eyes -- Farewell party -- Faded love', $tableOfContents[0]->getValue());
+ self::assertNotEmpty($tableOfContents[0]->getDisplayLabel());
+ self::assertEquals('Chapters', $tableOfContents[0]->getDisplayLabel());
+
+ // TODO: implement reading of elements
+ }
+
+ public function testGetNoTableOfContentsByQueryForBookDocument()
+ {
+ $tableOfContents = $this->bookReader->getTableOfContents('[@displayLabel="Pages"]');
+ self::assertEmpty($tableOfContents);
+ }
+
+ public function testGetNoTableOfContentsForSerialDocument()
+ {
+ $tableOfContents = $this->serialReader->getTableOfContents();
+ self::assertEmpty($tableOfContents);
+ }
+
+ public function testGetTitleInfosForBookDocument()
+ {
+ $titleInfos = $this->bookReader->getTitleInfos();
+ self::assertNotEmpty($titleInfos);
+ self::assertEquals(1, count($titleInfos));
+ self::assertNotEmpty($titleInfos[0]->getValue());
+ //self::assertNotEmpty($titleInfos[0]->getTitle());
+ //self::assertNotEmpty($titleInfos[0]->getSubTitle());
+
+ // TODO: implement reading of elements
+ }
+
+ public function testGetTitleInfosForSerialDocument()
+ {
+ $titleInfos = $this->serialReader->getTitleInfos();
+ self::assertNotEmpty($titleInfos);
+ self::assertEquals(3, count($titleInfos));
+ self::assertNotEmpty($titleInfos[0]->getValue());
+ //self::assertNotEmpty($titleInfos[0]->getTitle());
+ //self::assertNotEmpty($titleInfos[0]->getSubTitle());
+
+ // TODO: implement reading of elements
+ }
+
+ public function testGetTitleInfosByQueryForSerialDocument()
+ {
+ $titleInfos = $this->serialReader->getTitleInfos('[@type="alternative"]');
+ self::assertNotEmpty($titleInfos);
+ self::assertEquals(1, count($titleInfos));
+ self::assertNotEmpty($titleInfos[0]->getValue());
+ //self::assertNotEmpty($titleInfos[0]->getTitle());
+ //self::assertEmpty($titleInfos[0]->getSubTitle());
+
+ // TODO: implement reading of elements
+ }
+
+ public function testGetNoTitleInfosByQueryForSerialDocument()
+ {
+ $titleInfos = $this->serialReader->getTitleInfos('[@type="uniform"]');
+ self::assertEmpty($titleInfos);
+ }
+
+ public function testGetTypeOfResourceForBookDocument()
+ {
+ $typeOfResource = $this->bookReader->getTypeOfResource();
+ self::assertNotNull($typeOfResource);
+ self::assertNotEmpty($typeOfResource->getDisplayLabel());
+ self::assertEquals('format', $typeOfResource->getDisplayLabel());
+ self::assertNotEmpty($typeOfResource->getValue());
+ self::assertEquals('text', $typeOfResource->getValue());
+ }
+
+ public function testGetTypeOfResourceByQueryForBookDocument()
+ {
+ $typeOfResource = $this->bookReader->getTypeOfResource('[@displayLabel="format"]');
+ self::assertNotNull($typeOfResource);
+ self::assertNotEmpty($typeOfResource->getDisplayLabel());
+ self::assertEquals('format', $typeOfResource->getDisplayLabel());
+ self::assertNotEmpty($typeOfResource->getValue());
+ self::assertEquals('text', $typeOfResource->getValue());
+ }
+
+ public function testGetNoTypeOfResourceByQueryForBookDocument()
+ {
+ $typeOfResource = $this->bookReader->getTypeOfResource('[@displayLabel="random"]');
+ self::assertNull($typeOfResource);
+ }
+
+ public function testGetTypeOfResourceForSerialDocument()
+ {
+ $typeOfResource = $this->serialReader->getTypeOfResource();
+ self::assertNotNull($typeOfResource);
+ self::assertEmpty($typeOfResource->getDisplayLabel());
+ self::assertNotEmpty($typeOfResource->getValue());
+ self::assertEquals('text', $typeOfResource->getValue());
+ }
+
+ public function testGetNoTypeOfResourceByQueryForSerialDocument()
+ {
+ $abstract = $this->serialReader->getAbstract('[@displayForm="format"]');
+ self::assertNull($abstract);
+ }
+}
diff --git a/tests/resources/mods_book.xml b/tests/resources/mods_book.xml
new file mode 100644
index 0000000..fe259e6
--- /dev/null
+++ b/tests/resources/mods_book.xml
@@ -0,0 +1,140 @@
+
+
+
+ Sound and fury
+ the making of the punditocracy
+
+
+ Alterman, Eric.
+
+ creator
+ cre
+
+
+
+ author
+ aut
+
+
+
+ Aron
+ Jungerman
+
+ author
+ aut
+
+
+ text
+ bibliography
+
+
+ nyu
+
+ 2000
+ monographic
+
+ Ithaca, N.Y
+
+
+ Cornell University Press
+
+ c2000
+
+
+
+ nyu
+
+ 1999
+ monographic
+
+ Ithaca, N.Y
+
+
+ Cornell University Press
+
+ c1999
+
+
+ eng
+
+
+
+ vii, 322 p. ; 23 cm.
+ replacement
+ born digital
+
+ Test description for document which contains display label.
+ Eric Alterman.
+ Includes bibliographical references (p. 291-312) and index.
+
+ n-us---
+
+
+ Journalism
+ Political aspects
+ United States
+
+
+ Mass media
+ Political aspects
+ United States
+
+
+ Television and politics
+ United States
+
+
+ Press and politics
+ United States
+
+
+ Television talk shows
+ United States
+
+
+ United States
+ Politics and government
+ 20th century
+
+ PN4888.P6 A48 1999
+ 071/.3
+ 0801486394 (pbk. : acid-free, recycled paper)
+ 99042030
+
+ http://www.slub-dresden.de/some-url
+ http://www.slub-dresden.de/some-url/SLO-0000
+ http://www.slub-dresden.de/some-url/SLO-0000
+ http://www.slub-dresden.de/some-url/SLO-0000
+
+ Use of this public-domain resource is unrestricted.
+
+
+ Wayfarers
+
+
+ 97
+ 98
+
+
+
+
+ Vagabonds
+
+
+ 99
+ 100
+
+
+ Bluegrass odyssey -- Hills of Tennessee -- Sassafrass -- Muddy river -- Take your shoes off Moses -- Let Smokey Mountain smoke get in your eyes -- Farewell party -- Faded love
+
+ aacr
+ DLC
+ 990730
+ 20060801143536.0
+ 11761548
+ Converted from MARCXML to MODS version 3.8 using MARC21slim2MODS3-8_XSLT1-0.xsl
+ (Revision 1.172 20230208)
+
+
diff --git a/tests/resources/mods_serial.xml b/tests/resources/mods_serial.xml
new file mode 100644
index 0000000..60ee312
--- /dev/null
+++ b/tests/resources/mods_serial.xml
@@ -0,0 +1,114 @@
+
+
+
+ E-JASL
+ the electronic journal of academic and special librarianship
+
+
+ E-JASL
+ (Athabasca)
+
+
+ Electronic journal of academic and special librarianship
+
+
+ International Consortium for the Advancement of Academic Publication.
+
+ text
+ periodical
+ series
+
+
+ abc
+
+ 2002
+ 9999
+ serial
+ Three times a year
+
+ Athabasca [Alta.]
+
+
+ International Consortium for the Advancement of Academic Publication
+
+ 2002-
+ Three times a year (irregular)
+
+
+ eng
+
+
+
+
+ text/html
+
+ Test description for non shareable document.
+ V. 3, no. 1/2 (winter 2002)-
+ Title from title screen (viewed Aug. 13, 2002).
+ Archived by the National Library of Canada.
+ Latest issue consulted: V. 9 no. 1 (spring 2008) (viewed Sept. 5, 2008).
+ Mode of access: World Wide Web.
+ Electronic serial in HTML format.
+
+ Academic libraries
+ Periodicals
+
+
+ Special libraries
+ Periodicals
+
+
+ Web sites
+ Directories
+
+
+ Bibliothèques universitaires
+ Périodiques
+
+
+ Bibliothèques spécialisées
+ Périodiques
+
+
+ Sites Web
+ Répertoires
+
+ 027.7/05
+
+ http://bibpurl.oclc.org/web/7085
+
+
+ http://collection.nlc-bnc.ca/100/201/300/ejasl/index.html
+
+ Open Access
+
+
+ Journal of southern academic and special librarianship
+
+
+ Hammond, La. : P. Haschak ; Athabasca, Alta. : Distributed by the International Consortium for Alternative Academic Publication, 1999-2001
+
+ 1525-321X
+ (OCoLC)41477508
+ (DLC)sn 99004018
+ (CaOONL) 003900517
+
+ 1704-8532
+ 1525-321X
+ cn2002301668
+ ocm51090366
+
+ aacr
+ NLC
+ 021127
+ 20080910160139.0
+ 15446420
+ Converted from MARCXML to MODS version 3.8 using MARC21slim2MODS3-8_XSLT1-0.xsl
+ (Revision 1.172 20230208)
+
+ eng
+
+
+