Repository: phar-io/manifest Branch: master Commit: c581d4941e19 Files: 112 Total size: 159.4 KB Directory structure: gitextract_flwa4hbi/ ├── .gitattributes ├── .github/ │ ├── FUNDING.yml │ └── workflows/ │ └── ci.yml ├── .gitignore ├── .php-cs-fixer.dist.php ├── CHANGELOG.md ├── LICENSE ├── README.md ├── build.xml ├── composer.json ├── examples/ │ ├── example-01.php │ └── example-02.php ├── manifest.xsd ├── phive.xml ├── phpunit.xml ├── psalm.xml ├── src/ │ ├── ManifestDocumentMapper.php │ ├── ManifestLoader.php │ ├── ManifestSerializer.php │ ├── exceptions/ │ │ ├── ElementCollectionException.php │ │ ├── Exception.php │ │ ├── InvalidApplicationNameException.php │ │ ├── InvalidEmailException.php │ │ ├── InvalidUrlException.php │ │ ├── ManifestDocumentException.php │ │ ├── ManifestDocumentLoadingException.php │ │ ├── ManifestDocumentMapperException.php │ │ ├── ManifestElementException.php │ │ ├── ManifestLoaderException.php │ │ └── NoEmailAddressException.php │ ├── values/ │ │ ├── Application.php │ │ ├── ApplicationName.php │ │ ├── Author.php │ │ ├── AuthorCollection.php │ │ ├── AuthorCollectionIterator.php │ │ ├── BundledComponent.php │ │ ├── BundledComponentCollection.php │ │ ├── BundledComponentCollectionIterator.php │ │ ├── CopyrightInformation.php │ │ ├── Email.php │ │ ├── Extension.php │ │ ├── Library.php │ │ ├── License.php │ │ ├── Manifest.php │ │ ├── PhpExtensionRequirement.php │ │ ├── PhpVersionRequirement.php │ │ ├── Requirement.php │ │ ├── RequirementCollection.php │ │ ├── RequirementCollectionIterator.php │ │ ├── Type.php │ │ └── Url.php │ └── xml/ │ ├── AuthorElement.php │ ├── AuthorElementCollection.php │ ├── BundlesElement.php │ ├── ComponentElement.php │ ├── ComponentElementCollection.php │ ├── ContainsElement.php │ ├── CopyrightElement.php │ ├── ElementCollection.php │ ├── ExtElement.php │ ├── ExtElementCollection.php │ ├── ExtensionElement.php │ ├── LicenseElement.php │ ├── ManifestDocument.php │ ├── ManifestElement.php │ ├── PhpElement.php │ └── RequiresElement.php └── tests/ ├── ManifestDocumentMapperTest.php ├── ManifestLoaderTest.php ├── ManifestSerializerTest.php ├── _fixture/ │ ├── custom.xml │ ├── extension-invalidcompatible.xml │ ├── extension.xml │ ├── invalidversion.xml │ ├── invalidversionconstraint.xml │ ├── library.xml │ ├── manifest.xml │ ├── noemailauthor.xml │ ├── phpunit-5.6.5.xml │ └── test.phar ├── exceptions/ │ └── ManifestDocumentLoadingExceptionTest.php ├── values/ │ ├── ApplicationNameTest.php │ ├── ApplicationTest.php │ ├── AuthorCollectionTest.php │ ├── AuthorTest.php │ ├── BundledComponentCollectionTest.php │ ├── BundledComponentTest.php │ ├── CopyrightInformationTest.php │ ├── EmailTest.php │ ├── ExtensionTest.php │ ├── LibraryTest.php │ ├── LicenseTest.php │ ├── ManifestTest.php │ ├── PhpExtensionRequirementTest.php │ ├── PhpVersionRequirementTest.php │ ├── RequirementCollectionTest.php │ └── UrlTest.php └── xml/ ├── AuthorElementCollectionTest.php ├── AuthorElementTest.php ├── BundlesElementTest.php ├── ComponentElementCollectionTest.php ├── ComponentElementTest.php ├── ContainsElementTest.php ├── CopyrightElementTest.php ├── ElementCollectionTest.php ├── ExtElementCollectionTest.php ├── ExtElementTest.php ├── ExtensionElementTest.php ├── LicenseElementTest.php ├── ManifestDocumentTest.php ├── PhpElementTest.php └── RequiresElementTest.php ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitattributes ================================================ /.github export-ignore /build export-ignore /examples export-ignore /tests export-ignore /tools export-ignore /.gitattributes export-ignore /.gitignore export-ignore /.php_cs.dist.php export-ignore /build.xml export-ignore /phive.xml export-ignore /phpunit.xml export-ignore /psalm.xml export-ignore ================================================ FILE: .github/FUNDING.yml ================================================ # These are supported funding model platforms github: [theseer] ================================================ FILE: .github/workflows/ci.yml ================================================ name: "CI" on: push: branches: - "master" pull_request: null jobs: qa: name: "QA" runs-on: "ubuntu-latest" steps: - name: "Checkout" uses: "actions/checkout@v3.5.2" - name: "Set up PHP" uses: "shivammathur/setup-php@2.25.1" with: coverage: "none" php-version: "8.0" tools: "phive" - name: "Install dependencies with composer" run: "composer install --no-interaction --optimize-autoloader --prefer-dist" - name: "Install dependencies with phive" env: GITHUB_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: "ant install-tools" - name: "Run php-cs-fixer" run: "ant php-cs-fixer" - name: "Run psalm" run: "ant psalm" tests: name: "Tests" runs-on: "ubuntu-latest" strategy: fail-fast: false matrix: php-versions: - "7.2" - "7.3" - "7.4" - "8.0" - "8.1" - "8.2" - "8.3" - "8.4" steps: - name: "Checkout" uses: "actions/checkout@v3.5.2" - name: "Set up PHP" uses: "shivammathur/setup-php@2.25.1" env: COMPOSER_TOKEN: "${{ secrets.GITHUB_TOKEN }}" with: coverage: "pcov" extensions: "${{ env.extensions }}" ini-values: "display_errors=On, error_reporting=-1, memory_limit=2G" php-version: "${{ matrix.php-versions }}" tools: "phive" - name: "Install dependencies with composer" run: "composer install --no-interaction --optimize-autoloader --prefer-dist" - name: "Install dependencies with phive" env: GITHUB_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: "ant install-tools" - name: "Run PHPUnit" run: "tools/phpunit --coverage-clover build/logs/clover.xml" - name: "Send code coverage report to codecov.io" uses: "codecov/codecov-action@v3.1.4" with: files: "build/logs/clover.xml" ================================================ FILE: .gitignore ================================================ /.idea /.php_cs.cache /src/autoload.php /tools /vendor /build .phpunit.result.cache .php-cs-fixer.cache ================================================ FILE: .php-cs-fixer.dist.php ================================================ registerCustomFixers([ new \PharIo\CSFixer\PhpdocSingleLineVarFixer() ]) ->setRiskyAllowed(true) ->setRules( [ 'PharIo/phpdoc_single_line_var_fixer' => true, 'align_multiline_comment' => true, 'array_indentation' => true, 'array_syntax' => ['syntax' => 'short'], 'binary_operator_spaces' => [ 'operators' => [ '=' => 'align', '=>' => 'align', ], ], 'blank_line_after_namespace' => true, 'blank_line_after_opening_tag' => false, 'blank_line_before_statement' => [ 'statements' => [ 'break', 'continue', 'declare', 'do', 'for', 'foreach', 'if', 'include', 'include_once', 'require', 'require_once', 'return', 'switch', 'throw', 'try', 'while', 'yield', ], ], 'braces' => [ 'allow_single_line_closure' => false, 'position_after_anonymous_constructs' => 'same', 'position_after_control_structures' => 'same', 'position_after_functions_and_oop_constructs' => 'same' ], 'cast_spaces' => ['space' => 'none'], // This fixer removes the blank line at class start, no way to disable that, so we disable the fixer :( //'class_attributes_separation' => ['elements' => ['const', 'method', 'property']], 'combine_consecutive_issets' => true, 'combine_consecutive_unsets' => true, 'compact_nullable_typehint' => true, 'concat_space' => ['spacing' => 'one'], 'date_time_immutable' => true, 'declare_equal_normalize' => ['space' => 'single'], 'declare_strict_types' => true, 'dir_constant' => true, 'elseif' => true, 'encoding' => true, 'full_opening_tag' => true, 'fully_qualified_strict_types' => true, 'function_declaration' => [ 'closure_function_spacing' => 'one' ], 'global_namespace_import' => [ 'import_classes' => true, 'import_constants' => true, 'import_functions' => true, ], 'header_comment' => ['header' => $header, 'separate' => 'none'], 'indentation_type' => true, 'is_null' => true, 'line_ending' => true, 'list_syntax' => ['syntax' => 'short'], 'logical_operators' => true, 'lowercase_cast' => true, 'constant_case' => ['case' => 'lower'], 'lowercase_keywords' => true, 'lowercase_static_reference' => true, 'magic_constant_casing' => true, 'method_argument_space' => ['on_multiline' => 'ensure_fully_multiline'], 'modernize_types_casting' => true, 'multiline_comment_opening_closing' => true, 'multiline_whitespace_before_semicolons' => true, 'new_with_braces' => false, 'no_alias_functions' => true, 'no_alternative_syntax' => true, 'no_blank_lines_after_class_opening' => false, 'no_blank_lines_after_phpdoc' => true, 'no_blank_lines_before_namespace' => true, 'no_closing_tag' => true, 'no_empty_comment' => true, 'no_empty_phpdoc' => true, 'no_empty_statement' => true, 'no_extra_blank_lines' => true, 'no_homoglyph_names' => true, 'no_leading_import_slash' => true, 'no_leading_namespace_whitespace' => true, 'no_mixed_echo_print' => ['use' => 'print'], 'no_multiline_whitespace_around_double_arrow' => true, 'no_null_property_initialization' => true, 'no_php4_constructor' => true, 'no_short_bool_cast' => true, 'echo_tag_syntax' => ['format' => 'long'], 'no_singleline_whitespace_before_semicolons' => true, 'no_spaces_after_function_name' => true, 'no_spaces_inside_parenthesis' => true, 'no_superfluous_elseif' => true, 'no_superfluous_phpdoc_tags' => true, 'no_trailing_comma_in_list_call' => true, 'no_trailing_comma_in_singleline_array' => true, 'no_trailing_whitespace' => true, 'no_trailing_whitespace_in_comment' => true, 'no_unneeded_control_parentheses' => false, 'no_unneeded_curly_braces' => false, 'no_unneeded_final_method' => true, 'no_unreachable_default_argument_value' => true, 'no_unset_on_property' => true, 'no_unused_imports' => true, 'no_useless_else' => true, 'no_useless_return' => true, 'no_whitespace_before_comma_in_array' => true, 'no_whitespace_in_blank_line' => true, 'non_printable_character' => true, 'normalize_index_brace' => true, 'object_operator_without_whitespace' => true, 'ordered_class_elements' => [ 'order' => [ 'use_trait', 'constant_public', 'constant_protected', 'constant_private', 'property_public_static', 'property_protected_static', 'property_private_static', 'property_public', 'property_protected', 'property_private', 'method_public_static', 'construct', 'destruct', 'magic', 'phpunit', 'method_public', 'method_protected', 'method_private', 'method_protected_static', 'method_private_static', ], ], 'ordered_imports' => [ 'imports_order' => [ PhpCsFixer\Fixer\Import\OrderedImportsFixer::IMPORT_TYPE_CLASS, PhpCsFixer\Fixer\Import\OrderedImportsFixer::IMPORT_TYPE_CONST, PhpCsFixer\Fixer\Import\OrderedImportsFixer::IMPORT_TYPE_FUNCTION, ] ], 'phpdoc_add_missing_param_annotation' => true, 'phpdoc_align' => true, 'phpdoc_annotation_without_dot' => true, 'phpdoc_indent' => true, 'phpdoc_no_access' => true, 'phpdoc_no_empty_return' => true, 'phpdoc_no_package' => true, 'phpdoc_order' => true, 'phpdoc_return_self_reference' => true, 'phpdoc_scalar' => true, 'phpdoc_separation' => true, 'phpdoc_single_line_var_spacing' => true, 'phpdoc_to_comment' => true, 'phpdoc_trim' => true, 'phpdoc_trim_consecutive_blank_line_separation' => true, 'phpdoc_types' => ['groups' => ['simple', 'meta']], 'phpdoc_types_order' => true, 'phpdoc_to_return_type' => true, 'phpdoc_var_without_name' => true, 'pow_to_exponentiation' => true, 'protected_to_private' => true, 'return_assignment' => true, 'return_type_declaration' => ['space_before' => 'none'], 'self_accessor' => false, 'semicolon_after_instruction' => true, 'set_type_to_cast' => true, 'short_scalar_cast' => true, 'simplified_null_return' => true, 'single_blank_line_at_eof' => true, 'single_import_per_statement' => true, 'single_line_after_imports' => true, 'single_quote' => true, 'standardize_not_equals' => true, 'ternary_to_null_coalescing' => true, 'trailing_comma_in_multiline' => false, 'trim_array_spaces' => true, 'unary_operator_spaces' => true, 'visibility_required' => [ 'elements' => [ 'const', 'method', 'property', ], ], 'void_return' => true, 'whitespace_after_comma_in_array' => true, 'yoda_style' => false ] ) ->setFinder( PhpCsFixer\Finder::create() ->files() ->in(__DIR__ . '/build') ->in(__DIR__ . '/src') ->in(__DIR__ . '/tests') ->notName('autoload.php') ); ================================================ FILE: CHANGELOG.md ================================================ # Changelog All notable changes to phar-io/manifest are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles. ## [2.0.4] - 03-03-2024 ### Changed - Make `EMail` an optional attribute for author - Stick with PHP 7.2 compatibilty - Do not use implict nullable type (thanks @sebastianbergmann), this should make things work on PHP 8.4 ## [2.0.3] - 20.07.2021 - Fixed PHP 7.2 / PHP 7.3 incompatibility introduced in previous release ## [2.0.2] - 20.07.2021 - Fixed PHP 8.1 deprecation notice ## [2.0.1] - 27.06.2020 This release now supports the use of PHP 7.2+ and ^8.0 ## [2.0.0] - 10.05.2020 This release now requires PHP 7.2+ ### Changed - Upgraded to phar-io/version 3.0 - Version strings `v1.2.3` will now be converted to valid semantic version strings `1.2.3` - Abreviated strings like `1.0` will get expaneded to `1.0.0` ### Unreleased [Unreleased]: https://github.com/phar-io/manifest/compare/2.1.0...HEAD [2.1.0]: https://github.com/phar-io/manifest/compare/2.0.3...2.1.0 [2.0.3]: https://github.com/phar-io/manifest/compare/2.0.2...2.0.3 [2.0.2]: https://github.com/phar-io/manifest/compare/2.0.1...2.0.2 [2.0.1]: https://github.com/phar-io/manifest/compare/2.0.0...2.0.1 [2.0.0]: https://github.com/phar-io/manifest/compare/1.0.1...2.0.0 [1.0.3]: https://github.com/phar-io/manifest/compare/1.0.2...1.0.3 [1.0.2]: https://github.com/phar-io/manifest/compare/1.0.1...1.0.2 [1.0.1]: https://github.com/phar-io/manifest/compare/1.0.0...1.0.1 ================================================ FILE: LICENSE ================================================ Phar.io - Manifest Copyright (c) 2016-2019 Arne Blankerts , Sebastian Heuer , Sebastian Bergmann , and contributors All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Arne Blankerts nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: README.md ================================================ # Manifest Component for reading [phar.io](https://phar.io/) manifest information from a [PHP Archive (PHAR)](http://php.net/phar). ## Installation You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/): composer require phar-io/manifest If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency: composer require --dev phar-io/manifest ## Usage Examples ### Read from `manifest.xml` ```php use PharIo\Manifest\ManifestLoader; use PharIo\Manifest\ManifestSerializer; $manifest = ManifestLoader::fromFile('manifest.xml'); var_dump($manifest); echo (new ManifestSerializer)->serializeToString($manifest); ```
Output ```shell object(PharIo\Manifest\Manifest)#14 (6) { ["name":"PharIo\Manifest\Manifest":private]=> object(PharIo\Manifest\ApplicationName)#10 (1) { ["name":"PharIo\Manifest\ApplicationName":private]=> string(12) "some/library" } ["version":"PharIo\Manifest\Manifest":private]=> object(PharIo\Version\Version)#12 (5) { ["originalVersionString":"PharIo\Version\Version":private]=> string(5) "1.0.0" ["major":"PharIo\Version\Version":private]=> object(PharIo\Version\VersionNumber)#13 (1) { ["value":"PharIo\Version\VersionNumber":private]=> int(1) } ["minor":"PharIo\Version\Version":private]=> object(PharIo\Version\VersionNumber)#23 (1) { ["value":"PharIo\Version\VersionNumber":private]=> int(0) } ["patch":"PharIo\Version\Version":private]=> object(PharIo\Version\VersionNumber)#22 (1) { ["value":"PharIo\Version\VersionNumber":private]=> int(0) } ["preReleaseSuffix":"PharIo\Version\Version":private]=> NULL } ["type":"PharIo\Manifest\Manifest":private]=> object(PharIo\Manifest\Library)#6 (0) { } ["copyrightInformation":"PharIo\Manifest\Manifest":private]=> object(PharIo\Manifest\CopyrightInformation)#19 (2) { ["authors":"PharIo\Manifest\CopyrightInformation":private]=> object(PharIo\Manifest\AuthorCollection)#9 (1) { ["authors":"PharIo\Manifest\AuthorCollection":private]=> array(1) { [0]=> object(PharIo\Manifest\Author)#15 (2) { ["name":"PharIo\Manifest\Author":private]=> string(13) "Reiner Zufall" ["email":"PharIo\Manifest\Author":private]=> object(PharIo\Manifest\Email)#16 (1) { ["email":"PharIo\Manifest\Email":private]=> string(16) "reiner@zufall.de" } } } } ["license":"PharIo\Manifest\CopyrightInformation":private]=> object(PharIo\Manifest\License)#11 (2) { ["name":"PharIo\Manifest\License":private]=> string(12) "BSD-3-Clause" ["url":"PharIo\Manifest\License":private]=> object(PharIo\Manifest\Url)#18 (1) { ["url":"PharIo\Manifest\Url":private]=> string(26) "https://domain.tld/LICENSE" } } } ["requirements":"PharIo\Manifest\Manifest":private]=> object(PharIo\Manifest\RequirementCollection)#17 (1) { ["requirements":"PharIo\Manifest\RequirementCollection":private]=> array(1) { [0]=> object(PharIo\Manifest\PhpVersionRequirement)#20 (1) { ["versionConstraint":"PharIo\Manifest\PhpVersionRequirement":private]=> object(PharIo\Version\SpecificMajorAndMinorVersionConstraint)#24 (3) { ["originalValue":"PharIo\Version\AbstractVersionConstraint":private]=> string(3) "7.0" ["major":"PharIo\Version\SpecificMajorAndMinorVersionConstraint":private]=> int(7) ["minor":"PharIo\Version\SpecificMajorAndMinorVersionConstraint":private]=> int(0) } } } } ["bundledComponents":"PharIo\Manifest\Manifest":private]=> object(PharIo\Manifest\BundledComponentCollection)#8 (1) { ["bundledComponents":"PharIo\Manifest\BundledComponentCollection":private]=> array(0) { } } } ```
### Create via API ```php $bundled = new \PharIo\Manifest\BundledComponentCollection(); $bundled->add( new \PharIo\Manifest\BundledComponent('vendor/packageA', new \PharIo\Version\Version('1.2.3-dev') ) ); $manifest = new PharIo\Manifest\Manifest( new \PharIo\Manifest\ApplicationName('vendor/package'), new \PharIo\Version\Version('1.0.0'), new \PharIo\Manifest\Library(), new \PharIo\Manifest\CopyrightInformation( new \PharIo\Manifest\AuthorCollection(), new \PharIo\Manifest\License( 'BSD-3-Clause', new \PharIo\Manifest\Url('https://spdx.org/licenses/BSD-3-Clause.html') ) ), new \PharIo\Manifest\RequirementCollection(), $bundled ); echo (new ManifestSerializer)->serializeToString($manifest); ```
Output ```xml ```
================================================ FILE: build.xml ================================================ ================================================ FILE: composer.json ================================================ { "name": "phar-io/manifest", "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", "license": "BSD-3-Clause", "authors": [ { "name": "Arne Blankerts", "email": "arne@blankerts.de", "role": "Developer" }, { "name": "Sebastian Heuer", "email": "sebastian@phpeople.de", "role": "Developer" }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de", "role": "Developer" } ], "support": { "issues": "https://github.com/phar-io/manifest/issues" }, "require": { "php": "^7.2 || ^8.0", "ext-dom": "*", "ext-phar": "*", "ext-libxml": "*", "ext-xmlwriter": "*", "phar-io/version": "^3.0.1" }, "autoload": { "classmap": [ "src/" ] }, "extra": { "branch-alias": { "dev-master": "2.0.x-dev" } } } ================================================ FILE: examples/example-01.php ================================================ , Sebastian Heuer , Sebastian Bergmann * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ use PharIo\Manifest\ManifestLoader; use PharIo\Manifest\ManifestSerializer; require __DIR__ . '/../vendor/autoload.php'; $manifest = ManifestLoader::fromFile(__DIR__ . '/../tests/_fixture/phpunit-5.6.5.xml'); echo sprintf( "Manifest for %s (%s):\n\n", $manifest->getName()->asString(), $manifest->getVersion()->getVersionString() ); echo (new ManifestSerializer)->serializeToString($manifest); ================================================ FILE: examples/example-02.php ================================================ add( new \PharIo\Manifest\BundledComponent( 'vendor/packageA', new \PharIo\Version\Version('0.0.0-dev') ) ); $manifest = new PharIo\Manifest\Manifest( new \PharIo\Manifest\ApplicationName('vendor/package'), new \PharIo\Version\Version('1.0.0'), new \PharIo\Manifest\Library(), new \PharIo\Manifest\CopyrightInformation( new \PharIo\Manifest\AuthorCollection(), new \PharIo\Manifest\License( 'BSD-3-Clause', new \PharIo\Manifest\Url('https://spdx.org/licenses/BSD-3-Clause.html') ) ), new \PharIo\Manifest\RequirementCollection(), $bundledComponentCollection ); echo (new ManifestSerializer)->serializeToString($manifest); /* * Output produced * */ ================================================ FILE: manifest.xsd ================================================ ================================================ FILE: phive.xml ================================================ ================================================ FILE: phpunit.xml ================================================ src tests ================================================ FILE: psalm.xml ================================================ ================================================ FILE: src/ManifestDocumentMapper.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use PharIo\Version\Exception as VersionException; use PharIo\Version\Version; use PharIo\Version\VersionConstraintParser; use Throwable; use function sprintf; class ManifestDocumentMapper { public function map(ManifestDocument $document): Manifest { try { $contains = $document->getContainsElement(); $type = $this->mapType($contains); $copyright = $this->mapCopyright($document->getCopyrightElement()); $requirements = $this->mapRequirements($document->getRequiresElement()); $bundledComponents = $this->mapBundledComponents($document); return new Manifest( new ApplicationName($contains->getName()), new Version($contains->getVersion()), $type, $copyright, $requirements, $bundledComponents ); } catch (Throwable $e) { throw new ManifestDocumentMapperException($e->getMessage(), (int)$e->getCode(), $e); } } private function mapType(ContainsElement $contains): Type { switch ($contains->getType()) { case 'application': return Type::application(); case 'library': return Type::library(); case 'extension': return $this->mapExtension($contains->getExtensionElement()); } throw new ManifestDocumentMapperException( sprintf('Unsupported type %s', $contains->getType()) ); } private function mapCopyright(CopyrightElement $copyright): CopyrightInformation { $authors = new AuthorCollection(); foreach ($copyright->getAuthorElements() as $authorElement) { $authors->add( new Author( $authorElement->getName(), $authorElement->hasEMail() ? new Email($authorElement->getEmail()) : null ) ); } $licenseElement = $copyright->getLicenseElement(); $license = new License( $licenseElement->getType(), new Url($licenseElement->getUrl()) ); return new CopyrightInformation( $authors, $license ); } private function mapRequirements(RequiresElement $requires): RequirementCollection { $collection = new RequirementCollection(); $phpElement = $requires->getPHPElement(); $parser = new VersionConstraintParser; try { $versionConstraint = $parser->parse($phpElement->getVersion()); } catch (VersionException $e) { throw new ManifestDocumentMapperException( sprintf('Unsupported version constraint - %s', $e->getMessage()), (int)$e->getCode(), $e ); } $collection->add( new PhpVersionRequirement( $versionConstraint ) ); if (!$phpElement->hasExtElements()) { return $collection; } foreach ($phpElement->getExtElements() as $extElement) { $collection->add( new PhpExtensionRequirement($extElement->getName()) ); } return $collection; } private function mapBundledComponents(ManifestDocument $document): BundledComponentCollection { $collection = new BundledComponentCollection(); if (!$document->hasBundlesElement()) { return $collection; } foreach ($document->getBundlesElement()->getComponentElements() as $componentElement) { $collection->add( new BundledComponent( $componentElement->getName(), new Version( $componentElement->getVersion() ) ) ); } return $collection; } private function mapExtension(ExtensionElement $extension): Extension { try { $versionConstraint = (new VersionConstraintParser)->parse($extension->getCompatible()); return Type::extension( new ApplicationName($extension->getFor()), $versionConstraint ); } catch (VersionException $e) { throw new ManifestDocumentMapperException( sprintf('Unsupported version constraint - %s', $e->getMessage()), (int)$e->getCode(), $e ); } } } ================================================ FILE: src/ManifestLoader.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use function sprintf; class ManifestLoader { public static function fromFile(string $filename): Manifest { try { return (new ManifestDocumentMapper())->map( ManifestDocument::fromFile($filename) ); } catch (Exception $e) { throw new ManifestLoaderException( sprintf('Loading %s failed.', $filename), (int)$e->getCode(), $e ); } } public static function fromPhar(string $filename): Manifest { return self::fromFile('phar://' . $filename . '/manifest.xml'); } public static function fromString(string $manifest): Manifest { try { return (new ManifestDocumentMapper())->map( ManifestDocument::fromString($manifest) ); } catch (Exception $e) { throw new ManifestLoaderException( 'Processing string failed', (int)$e->getCode(), $e ); } } } ================================================ FILE: src/ManifestSerializer.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use PharIo\Version\AnyVersionConstraint; use PharIo\Version\Version; use PharIo\Version\VersionConstraint; use XMLWriter; use function count; use function file_put_contents; use function str_repeat; /** @psalm-suppress MissingConstructor */ class ManifestSerializer { /** @var XMLWriter */ private $xmlWriter; public function serializeToFile(Manifest $manifest, string $filename): void { file_put_contents( $filename, $this->serializeToString($manifest) ); } public function serializeToString(Manifest $manifest): string { $this->startDocument(); $this->addContains($manifest->getName(), $manifest->getVersion(), $manifest->getType()); $this->addCopyright($manifest->getCopyrightInformation()); $this->addRequirements($manifest->getRequirements()); $this->addBundles($manifest->getBundledComponents()); return $this->finishDocument(); } private function startDocument(): void { $xmlWriter = new XMLWriter(); $xmlWriter->openMemory(); $xmlWriter->setIndent(true); $xmlWriter->setIndentString(str_repeat(' ', 4)); $xmlWriter->startDocument('1.0', 'UTF-8'); $xmlWriter->startElement('phar'); $xmlWriter->writeAttribute('xmlns', 'https://phar.io/xml/manifest/1.0'); $this->xmlWriter = $xmlWriter; } private function finishDocument(): string { $this->xmlWriter->endElement(); $this->xmlWriter->endDocument(); return $this->xmlWriter->outputMemory(); } private function addContains(ApplicationName $name, Version $version, Type $type): void { $this->xmlWriter->startElement('contains'); $this->xmlWriter->writeAttribute('name', $name->asString()); $this->xmlWriter->writeAttribute('version', $version->getVersionString()); switch (true) { case $type->isApplication(): { $this->xmlWriter->writeAttribute('type', 'application'); break; } case $type->isLibrary(): { $this->xmlWriter->writeAttribute('type', 'library'); break; } case $type->isExtension(): { $this->xmlWriter->writeAttribute('type', 'extension'); /* @var $type Extension */ $this->addExtension( $type->getApplicationName(), $type->getVersionConstraint() ); break; } default: { $this->xmlWriter->writeAttribute('type', 'custom'); } } $this->xmlWriter->endElement(); } private function addCopyright(CopyrightInformation $copyrightInformation): void { $this->xmlWriter->startElement('copyright'); foreach ($copyrightInformation->getAuthors() as $author) { $this->xmlWriter->startElement('author'); $this->xmlWriter->writeAttribute('name', $author->getName()); $this->xmlWriter->writeAttribute('email', $author->getEmail()->asString()); $this->xmlWriter->endElement(); } $license = $copyrightInformation->getLicense(); $this->xmlWriter->startElement('license'); $this->xmlWriter->writeAttribute('type', $license->getName()); $this->xmlWriter->writeAttribute('url', $license->getUrl()->asString()); $this->xmlWriter->endElement(); $this->xmlWriter->endElement(); } private function addRequirements(RequirementCollection $requirementCollection): void { $phpRequirement = new AnyVersionConstraint(); $extensions = []; foreach ($requirementCollection as $requirement) { if ($requirement instanceof PhpVersionRequirement) { $phpRequirement = $requirement->getVersionConstraint(); continue; } if ($requirement instanceof PhpExtensionRequirement) { $extensions[] = $requirement->asString(); } } $this->xmlWriter->startElement('requires'); $this->xmlWriter->startElement('php'); $this->xmlWriter->writeAttribute('version', $phpRequirement->asString()); foreach ($extensions as $extension) { $this->xmlWriter->startElement('ext'); $this->xmlWriter->writeAttribute('name', $extension); $this->xmlWriter->endElement(); } $this->xmlWriter->endElement(); $this->xmlWriter->endElement(); } private function addBundles(BundledComponentCollection $bundledComponentCollection): void { if (count($bundledComponentCollection) === 0) { return; } $this->xmlWriter->startElement('bundles'); foreach ($bundledComponentCollection as $bundledComponent) { $this->xmlWriter->startElement('component'); $this->xmlWriter->writeAttribute('name', $bundledComponent->getName()); $this->xmlWriter->writeAttribute('version', $bundledComponent->getVersion()->getVersionString()); $this->xmlWriter->endElement(); } $this->xmlWriter->endElement(); } private function addExtension(ApplicationName $applicationName, VersionConstraint $versionConstraint): void { $this->xmlWriter->startElement('extension'); $this->xmlWriter->writeAttribute('for', $applicationName->asString()); $this->xmlWriter->writeAttribute('compatible', $versionConstraint->asString()); $this->xmlWriter->endElement(); } } ================================================ FILE: src/exceptions/ElementCollectionException.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use InvalidArgumentException; class ElementCollectionException extends InvalidArgumentException implements Exception { } ================================================ FILE: src/exceptions/Exception.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use Throwable; interface Exception extends Throwable { } ================================================ FILE: src/exceptions/InvalidApplicationNameException.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use InvalidArgumentException; class InvalidApplicationNameException extends InvalidArgumentException implements Exception { public const InvalidFormat = 2; } ================================================ FILE: src/exceptions/InvalidEmailException.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use InvalidArgumentException; class InvalidEmailException extends InvalidArgumentException implements Exception { } ================================================ FILE: src/exceptions/InvalidUrlException.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use InvalidArgumentException; class InvalidUrlException extends InvalidArgumentException implements Exception { } ================================================ FILE: src/exceptions/ManifestDocumentException.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use RuntimeException; class ManifestDocumentException extends RuntimeException implements Exception { } ================================================ FILE: src/exceptions/ManifestDocumentLoadingException.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use LibXMLError; use function sprintf; class ManifestDocumentLoadingException extends \Exception implements Exception { /** @var LibXMLError[] */ private $libxmlErrors; /** * ManifestDocumentLoadingException constructor. * * @param LibXMLError[] $libxmlErrors */ public function __construct(array $libxmlErrors) { $this->libxmlErrors = $libxmlErrors; $first = $this->libxmlErrors[0]; parent::__construct( sprintf( '%s (Line: %d / Column: %d / File: %s)', $first->message, $first->line, $first->column, $first->file ), $first->code ); } /** * @return LibXMLError[] */ public function getLibxmlErrors(): array { return $this->libxmlErrors; } } ================================================ FILE: src/exceptions/ManifestDocumentMapperException.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use RuntimeException; class ManifestDocumentMapperException extends RuntimeException implements Exception { } ================================================ FILE: src/exceptions/ManifestElementException.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use RuntimeException; class ManifestElementException extends RuntimeException implements Exception { } ================================================ FILE: src/exceptions/ManifestLoaderException.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; class ManifestLoaderException extends \Exception implements Exception { } ================================================ FILE: src/exceptions/NoEmailAddressException.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use InvalidArgumentException; class NoEmailAddressException extends InvalidArgumentException implements Exception { } ================================================ FILE: src/values/Application.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; class Application extends Type { public function isApplication(): bool { return true; } } ================================================ FILE: src/values/ApplicationName.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use function preg_match; use function sprintf; class ApplicationName { /** @var string */ private $name; public function __construct(string $name) { $this->ensureValidFormat($name); $this->name = $name; } public function asString(): string { return $this->name; } public function isEqual(ApplicationName $name): bool { return $this->name === $name->name; } private function ensureValidFormat(string $name): void { if (!preg_match('#\w/\w#', $name)) { throw new InvalidApplicationNameException( sprintf('Format of name "%s" is not valid - expected: vendor/packagename', $name), InvalidApplicationNameException::InvalidFormat ); } } } ================================================ FILE: src/values/Author.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use function sprintf; class Author { /** @var string */ private $name; /** @var null|Email */ private $email; public function __construct(string $name, ?Email $email = null) { $this->name = $name; $this->email = $email; } public function asString(): string { if (!$this->hasEmail()) { return $this->name; } return sprintf( '%s <%s>', $this->name, $this->email->asString() ); } public function getName(): string { return $this->name; } /** * @psalm-assert-if-true Email $this->email */ public function hasEmail(): bool { return $this->email !== null; } public function getEmail(): Email { if (!$this->hasEmail()) { throw new NoEmailAddressException(); } return $this->email; } } ================================================ FILE: src/values/AuthorCollection.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use Countable; use IteratorAggregate; use function count; /** @template-implements IteratorAggregate */ class AuthorCollection implements Countable, IteratorAggregate { /** @var Author[] */ private $authors = []; public function add(Author $author): void { $this->authors[] = $author; } /** * @return Author[] */ public function getAuthors(): array { return $this->authors; } public function count(): int { return count($this->authors); } public function getIterator(): AuthorCollectionIterator { return new AuthorCollectionIterator($this); } } ================================================ FILE: src/values/AuthorCollectionIterator.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use Iterator; use function count; /** @template-implements Iterator */ class AuthorCollectionIterator implements Iterator { /** @var Author[] */ private $authors; /** @var int */ private $position = 0; public function __construct(AuthorCollection $authors) { $this->authors = $authors->getAuthors(); } public function rewind(): void { $this->position = 0; } public function valid(): bool { return $this->position < count($this->authors); } public function key(): int { return $this->position; } public function current(): Author { return $this->authors[$this->position]; } public function next(): void { $this->position++; } } ================================================ FILE: src/values/BundledComponent.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use PharIo\Version\Version; class BundledComponent { /** @var string */ private $name; /** @var Version */ private $version; public function __construct(string $name, Version $version) { $this->name = $name; $this->version = $version; } public function getName(): string { return $this->name; } public function getVersion(): Version { return $this->version; } } ================================================ FILE: src/values/BundledComponentCollection.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use Countable; use IteratorAggregate; use function count; /** @template-implements IteratorAggregate */ class BundledComponentCollection implements Countable, IteratorAggregate { /** @var BundledComponent[] */ private $bundledComponents = []; public function add(BundledComponent $bundledComponent): void { $this->bundledComponents[] = $bundledComponent; } /** * @return BundledComponent[] */ public function getBundledComponents(): array { return $this->bundledComponents; } public function count(): int { return count($this->bundledComponents); } public function getIterator(): BundledComponentCollectionIterator { return new BundledComponentCollectionIterator($this); } } ================================================ FILE: src/values/BundledComponentCollectionIterator.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use Iterator; use function count; /** @template-implements Iterator */ class BundledComponentCollectionIterator implements Iterator { /** @var BundledComponent[] */ private $bundledComponents; /** @var int */ private $position = 0; public function __construct(BundledComponentCollection $bundledComponents) { $this->bundledComponents = $bundledComponents->getBundledComponents(); } public function rewind(): void { $this->position = 0; } public function valid(): bool { return $this->position < count($this->bundledComponents); } public function key(): int { return $this->position; } public function current(): BundledComponent { return $this->bundledComponents[$this->position]; } public function next(): void { $this->position++; } } ================================================ FILE: src/values/CopyrightInformation.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; class CopyrightInformation { /** @var AuthorCollection */ private $authors; /** @var License */ private $license; public function __construct(AuthorCollection $authors, License $license) { $this->authors = $authors; $this->license = $license; } public function getAuthors(): AuthorCollection { return $this->authors; } public function getLicense(): License { return $this->license; } } ================================================ FILE: src/values/Email.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use const FILTER_VALIDATE_EMAIL; use function filter_var; class Email { /** @var string */ private $email; public function __construct(string $email) { $this->ensureEmailIsValid($email); $this->email = $email; } public function asString(): string { return $this->email; } private function ensureEmailIsValid(string $url): void { if (filter_var($url, FILTER_VALIDATE_EMAIL) === false) { throw new InvalidEmailException; } } } ================================================ FILE: src/values/Extension.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use PharIo\Version\Version; use PharIo\Version\VersionConstraint; class Extension extends Type { /** @var ApplicationName */ private $application; /** @var VersionConstraint */ private $versionConstraint; public function __construct(ApplicationName $application, VersionConstraint $versionConstraint) { $this->application = $application; $this->versionConstraint = $versionConstraint; } public function getApplicationName(): ApplicationName { return $this->application; } public function getVersionConstraint(): VersionConstraint { return $this->versionConstraint; } public function isExtension(): bool { return true; } public function isExtensionFor(ApplicationName $name): bool { return $this->application->isEqual($name); } public function isCompatibleWith(ApplicationName $name, Version $version): bool { return $this->isExtensionFor($name) && $this->versionConstraint->complies($version); } } ================================================ FILE: src/values/Library.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; class Library extends Type { public function isLibrary(): bool { return true; } } ================================================ FILE: src/values/License.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; class License { /** @var string */ private $name; /** @var Url */ private $url; public function __construct(string $name, Url $url) { $this->name = $name; $this->url = $url; } public function getName(): string { return $this->name; } public function getUrl(): Url { return $this->url; } } ================================================ FILE: src/values/Manifest.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use PharIo\Version\Version; class Manifest { /** @var ApplicationName */ private $name; /** @var Version */ private $version; /** @var Type */ private $type; /** @var CopyrightInformation */ private $copyrightInformation; /** @var RequirementCollection */ private $requirements; /** @var BundledComponentCollection */ private $bundledComponents; public function __construct(ApplicationName $name, Version $version, Type $type, CopyrightInformation $copyrightInformation, RequirementCollection $requirements, BundledComponentCollection $bundledComponents) { $this->name = $name; $this->version = $version; $this->type = $type; $this->copyrightInformation = $copyrightInformation; $this->requirements = $requirements; $this->bundledComponents = $bundledComponents; } public function getName(): ApplicationName { return $this->name; } public function getVersion(): Version { return $this->version; } public function getType(): Type { return $this->type; } public function getCopyrightInformation(): CopyrightInformation { return $this->copyrightInformation; } public function getRequirements(): RequirementCollection { return $this->requirements; } public function getBundledComponents(): BundledComponentCollection { return $this->bundledComponents; } public function isApplication(): bool { return $this->type->isApplication(); } public function isLibrary(): bool { return $this->type->isLibrary(); } public function isExtension(): bool { return $this->type->isExtension(); } public function isExtensionFor(ApplicationName $application, ?Version $version = null): bool { if (!$this->isExtension()) { return false; } /** @var Extension $type */ $type = $this->type; if ($version !== null) { return $type->isCompatibleWith($application, $version); } return $type->isExtensionFor($application); } } ================================================ FILE: src/values/PhpExtensionRequirement.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; class PhpExtensionRequirement implements Requirement { /** @var string */ private $extension; public function __construct(string $extension) { $this->extension = $extension; } public function asString(): string { return $this->extension; } } ================================================ FILE: src/values/PhpVersionRequirement.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use PharIo\Version\VersionConstraint; class PhpVersionRequirement implements Requirement { /** @var VersionConstraint */ private $versionConstraint; public function __construct(VersionConstraint $versionConstraint) { $this->versionConstraint = $versionConstraint; } public function getVersionConstraint(): VersionConstraint { return $this->versionConstraint; } } ================================================ FILE: src/values/Requirement.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; interface Requirement { } ================================================ FILE: src/values/RequirementCollection.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use Countable; use IteratorAggregate; use function count; /** @template-implements IteratorAggregate */ class RequirementCollection implements Countable, IteratorAggregate { /** @var Requirement[] */ private $requirements = []; public function add(Requirement $requirement): void { $this->requirements[] = $requirement; } /** * @return Requirement[] */ public function getRequirements(): array { return $this->requirements; } public function count(): int { return count($this->requirements); } public function getIterator(): RequirementCollectionIterator { return new RequirementCollectionIterator($this); } } ================================================ FILE: src/values/RequirementCollectionIterator.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use Iterator; use function count; /** @template-implements Iterator */ class RequirementCollectionIterator implements Iterator { /** @var Requirement[] */ private $requirements; /** @var int */ private $position = 0; public function __construct(RequirementCollection $requirements) { $this->requirements = $requirements->getRequirements(); } public function rewind(): void { $this->position = 0; } public function valid(): bool { return $this->position < count($this->requirements); } public function key(): int { return $this->position; } public function current(): Requirement { return $this->requirements[$this->position]; } public function next(): void { $this->position++; } } ================================================ FILE: src/values/Type.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use PharIo\Version\VersionConstraint; abstract class Type { public static function application(): Application { return new Application; } public static function library(): Library { return new Library; } public static function extension(ApplicationName $application, VersionConstraint $versionConstraint): Extension { return new Extension($application, $versionConstraint); } /** @psalm-assert-if-true Application $this */ public function isApplication(): bool { return false; } /** @psalm-assert-if-true Library $this */ public function isLibrary(): bool { return false; } /** @psalm-assert-if-true Extension $this */ public function isExtension(): bool { return false; } } ================================================ FILE: src/values/Url.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use const FILTER_VALIDATE_URL; use function filter_var; class Url { /** @var string */ private $url; public function __construct(string $url) { $this->ensureUrlIsValid($url); $this->url = $url; } public function asString(): string { return $this->url; } /** * @throws InvalidUrlException */ private function ensureUrlIsValid(string $url): void { if (filter_var($url, FILTER_VALIDATE_URL) === false) { throw new InvalidUrlException; } } } ================================================ FILE: src/xml/AuthorElement.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; class AuthorElement extends ManifestElement { public function getName(): string { return $this->getAttributeValue('name'); } public function getEmail(): string { return $this->getAttributeValue('email'); } public function hasEMail(): bool { return $this->hasAttribute('email'); } } ================================================ FILE: src/xml/AuthorElementCollection.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; class AuthorElementCollection extends ElementCollection { public function current(): AuthorElement { return new AuthorElement( $this->getCurrentElement() ); } } ================================================ FILE: src/xml/BundlesElement.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; class BundlesElement extends ManifestElement { public function getComponentElements(): ComponentElementCollection { return new ComponentElementCollection( $this->getChildrenByName('component') ); } } ================================================ FILE: src/xml/ComponentElement.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; class ComponentElement extends ManifestElement { public function getName(): string { return $this->getAttributeValue('name'); } public function getVersion(): string { return $this->getAttributeValue('version'); } } ================================================ FILE: src/xml/ComponentElementCollection.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; class ComponentElementCollection extends ElementCollection { public function current(): ComponentElement { return new ComponentElement( $this->getCurrentElement() ); } } ================================================ FILE: src/xml/ContainsElement.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; class ContainsElement extends ManifestElement { public function getName(): string { return $this->getAttributeValue('name'); } public function getVersion(): string { return $this->getAttributeValue('version'); } public function getType(): string { return $this->getAttributeValue('type'); } public function getExtensionElement(): ExtensionElement { return new ExtensionElement( $this->getChildByName('extension') ); } } ================================================ FILE: src/xml/CopyrightElement.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; class CopyrightElement extends ManifestElement { public function getAuthorElements(): AuthorElementCollection { return new AuthorElementCollection( $this->getChildrenByName('author') ); } public function getLicenseElement(): LicenseElement { return new LicenseElement( $this->getChildByName('license') ); } } ================================================ FILE: src/xml/ElementCollection.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use DOMElement; use DOMNodeList; use Iterator; use ReturnTypeWillChange; use function count; use function get_class; use function sprintf; /** @template-implements Iterator */ abstract class ElementCollection implements Iterator { /** @var DOMElement[] */ private $nodes = []; /** @var int */ private $position; public function __construct(DOMNodeList $nodeList) { $this->position = 0; $this->importNodes($nodeList); } #[ReturnTypeWillChange] abstract public function current(); public function next(): void { $this->position++; } public function key(): int { return $this->position; } public function valid(): bool { return $this->position < count($this->nodes); } public function rewind(): void { $this->position = 0; } protected function getCurrentElement(): DOMElement { return $this->nodes[$this->position]; } private function importNodes(DOMNodeList $nodeList): void { foreach ($nodeList as $node) { if (!$node instanceof DOMElement) { throw new ElementCollectionException( sprintf('\DOMElement expected, got \%s', get_class($node)) ); } $this->nodes[] = $node; } } } ================================================ FILE: src/xml/ExtElement.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; class ExtElement extends ManifestElement { public function getName(): string { return $this->getAttributeValue('name'); } } ================================================ FILE: src/xml/ExtElementCollection.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; class ExtElementCollection extends ElementCollection { public function current(): ExtElement { return new ExtElement( $this->getCurrentElement() ); } } ================================================ FILE: src/xml/ExtensionElement.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; class ExtensionElement extends ManifestElement { public function getFor(): string { return $this->getAttributeValue('for'); } public function getCompatible(): string { return $this->getAttributeValue('compatible'); } } ================================================ FILE: src/xml/LicenseElement.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; class LicenseElement extends ManifestElement { public function getType(): string { return $this->getAttributeValue('type'); } public function getUrl(): string { return $this->getAttributeValue('url'); } } ================================================ FILE: src/xml/ManifestDocument.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use DOMDocument; use DOMElement; use Throwable; use function count; use function file_get_contents; use function is_file; use function libxml_clear_errors; use function libxml_get_errors; use function libxml_use_internal_errors; use function sprintf; class ManifestDocument { public const XMLNS = 'https://phar.io/xml/manifest/1.0'; /** @var DOMDocument */ private $dom; public static function fromFile(string $filename): ManifestDocument { if (!is_file($filename)) { throw new ManifestDocumentException( sprintf('File "%s" not found', $filename) ); } return self::fromString( file_get_contents($filename) ); } public static function fromString(string $xmlString): ManifestDocument { $prev = libxml_use_internal_errors(true); libxml_clear_errors(); try { $dom = new DOMDocument(); $dom->loadXML($xmlString); $errors = libxml_get_errors(); libxml_use_internal_errors($prev); } catch (Throwable $t) { throw new ManifestDocumentException($t->getMessage(), 0, $t); } if (count($errors) !== 0) { throw new ManifestDocumentLoadingException($errors); } return new self($dom); } private function __construct(DOMDocument $dom) { $this->ensureCorrectDocumentType($dom); $this->dom = $dom; } public function getContainsElement(): ContainsElement { return new ContainsElement( $this->fetchElementByName('contains') ); } public function getCopyrightElement(): CopyrightElement { return new CopyrightElement( $this->fetchElementByName('copyright') ); } public function getRequiresElement(): RequiresElement { return new RequiresElement( $this->fetchElementByName('requires') ); } public function hasBundlesElement(): bool { return $this->dom->getElementsByTagNameNS(self::XMLNS, 'bundles')->length === 1; } public function getBundlesElement(): BundlesElement { return new BundlesElement( $this->fetchElementByName('bundles') ); } private function ensureCorrectDocumentType(DOMDocument $dom): void { $root = $dom->documentElement; if ($root->localName !== 'phar' || $root->namespaceURI !== self::XMLNS) { throw new ManifestDocumentException('Not a phar.io manifest document'); } } private function fetchElementByName(string $elementName): DOMElement { $element = $this->dom->getElementsByTagNameNS(self::XMLNS, $elementName)->item(0); if (!$element instanceof DOMElement) { throw new ManifestDocumentException( sprintf('Element %s missing', $elementName) ); } return $element; } } ================================================ FILE: src/xml/ManifestElement.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use DOMElement; use DOMNodeList; use function sprintf; class ManifestElement { public const XMLNS = 'https://phar.io/xml/manifest/1.0'; /** @var DOMElement */ private $element; public function __construct(DOMElement $element) { $this->element = $element; } protected function getAttributeValue(string $name): string { if (!$this->element->hasAttribute($name)) { throw new ManifestElementException( sprintf( 'Attribute %s not set on element %s', $name, $this->element->localName ) ); } return $this->element->getAttribute($name); } protected function hasAttribute(string $name): bool { return $this->element->hasAttribute($name); } protected function getChildByName(string $elementName): DOMElement { $element = $this->element->getElementsByTagNameNS(self::XMLNS, $elementName)->item(0); if (!$element instanceof DOMElement) { throw new ManifestElementException( sprintf('Element %s missing', $elementName) ); } return $element; } protected function getChildrenByName(string $elementName): DOMNodeList { $elementList = $this->element->getElementsByTagNameNS(self::XMLNS, $elementName); if ($elementList->length === 0) { throw new ManifestElementException( sprintf('Element(s) %s missing', $elementName) ); } return $elementList; } protected function hasChild(string $elementName): bool { return $this->element->getElementsByTagNameNS(self::XMLNS, $elementName)->length !== 0; } } ================================================ FILE: src/xml/PhpElement.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; class PhpElement extends ManifestElement { public function getVersion(): string { return $this->getAttributeValue('version'); } public function hasExtElements(): bool { return $this->hasChild('ext'); } public function getExtElements(): ExtElementCollection { return new ExtElementCollection( $this->getChildrenByName('ext') ); } } ================================================ FILE: src/xml/RequiresElement.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; class RequiresElement extends ManifestElement { public function getPHPElement(): PhpElement { return new PhpElement( $this->getChildByName('php') ); } } ================================================ FILE: tests/ManifestDocumentMapperTest.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; /** * @covers \PharIo\Manifest\ManifestDocumentMapper * * @uses \PharIo\Manifest\ApplicationName * @uses \PharIo\Manifest\Author * @uses \PharIo\Manifest\AuthorCollection * @uses \PharIo\Manifest\AuthorCollectionIterator * @uses \PharIo\Manifest\AuthorElement * @uses \PharIo\Manifest\AuthorElementCollection * @uses \PharIo\Manifest\BundledComponent * @uses \PharIo\Manifest\BundledComponentCollection * @uses \PharIo\Manifest\BundledComponentCollectionIterator * @uses \PharIo\Manifest\BundlesElement * @uses \PharIo\Manifest\ComponentElement * @uses \PharIo\Manifest\ComponentElementCollection * @uses \PharIo\Manifest\ContainsElement * @uses \PharIo\Manifest\CopyrightElement * @uses \PharIo\Manifest\CopyrightInformation * @uses \PharIo\Manifest\ElementCollection * @uses \PharIo\Manifest\Email * @uses \PharIo\Manifest\ExtElement * @uses \PharIo\Manifest\ExtElementCollection * @uses \PharIo\Manifest\License * @uses \PharIo\Manifest\LicenseElement * @uses \PharIo\Manifest\Manifest * @uses \PharIo\Manifest\ManifestDocument * @uses \PharIo\Manifest\ManifestDocumentMapper * @uses \PharIo\Manifest\ManifestElement * @uses \PharIo\Manifest\ManifestLoader * @uses \PharIo\Manifest\PhpElement * @uses \PharIo\Manifest\PhpExtensionRequirement * @uses \PharIo\Manifest\PhpVersionRequirement * @uses \PharIo\Manifest\RequirementCollection * @uses \PharIo\Manifest\RequirementCollectionIterator * @uses \PharIo\Manifest\RequiresElement * @uses \PharIo\Manifest\Type * @uses \PharIo\Manifest\Url * @uses \PharIo\Version\Version * @uses \PharIo\Version\VersionConstraint */ class ManifestDocumentMapperTest extends \PHPUnit\Framework\TestCase { /** * @dataProvider dataProvider * * @uses \PharIo\Manifest\Application * @uses \PharIo\Manifest\ApplicationName * @uses \PharIo\Manifest\Library * @uses \PharIo\Manifest\Extension * @uses \PharIo\Manifest\ExtensionElement */ public function testCanSerializeToString($expected): void { $manifestDocument = ManifestDocument::fromFile($expected); $mapper = new ManifestDocumentMapper(); $this->assertInstanceOf( Manifest::class, $mapper->map($manifestDocument) ); } public function dataProvider() { return [ 'application' => [__DIR__ . '/_fixture/phpunit-5.6.5.xml'], 'library' => [__DIR__ . '/_fixture/library.xml'], 'extension' => [__DIR__ . '/_fixture/extension.xml'], 'noemailauthor' => [__DIR__ . '/_fixture/noemailauthor.xml'] ]; } public function testThrowsExceptionOnUnsupportedType(): void { $manifestDocument = ManifestDocument::fromFile(__DIR__ . '/_fixture/custom.xml'); $mapper = new ManifestDocumentMapper(); $this->expectException(ManifestDocumentMapperException::class); $mapper->map($manifestDocument); } public function testInvalidVersionInformationThrowsException(): void { $manifestDocument = ManifestDocument::fromFile(__DIR__ . '/_fixture/invalidversion.xml'); $mapper = new ManifestDocumentMapper(); $this->expectException(ManifestDocumentMapperException::class); $mapper->map($manifestDocument); } public function testInvalidVersionConstraintThrowsException(): void { $manifestDocument = ManifestDocument::fromFile(__DIR__ . '/_fixture/invalidversionconstraint.xml'); $mapper = new ManifestDocumentMapper(); $this->expectException(ManifestDocumentMapperException::class); $mapper->map($manifestDocument); } /** * @uses \PharIo\Manifest\ExtensionElement */ public function testInvalidCompatibleConstraintThrowsException(): void { $manifestDocument = ManifestDocument::fromFile(__DIR__ . '/_fixture/extension-invalidcompatible.xml'); $mapper = new ManifestDocumentMapper(); $this->expectException(ManifestDocumentMapperException::class); $mapper->map($manifestDocument); } } ================================================ FILE: tests/ManifestLoaderTest.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use function file_get_contents; /** * @covers \PharIo\Manifest\ManifestLoader * * @uses \PharIo\Manifest\Author * @uses \PharIo\Manifest\AuthorCollection * @uses \PharIo\Manifest\AuthorCollectionIterator * @uses \PharIo\Manifest\AuthorElement * @uses \PharIo\Manifest\AuthorElementCollection * @uses \PharIo\Manifest\ApplicationName * @uses \PharIo\Manifest\BundledComponent * @uses \PharIo\Manifest\BundledComponentCollection * @uses \PharIo\Manifest\BundledComponentCollectionIterator * @uses \PharIo\Manifest\BundlesElement * @uses \PharIo\Manifest\ComponentElement * @uses \PharIo\Manifest\ComponentElementCollection * @uses \PharIo\Manifest\ContainsElement * @uses \PharIo\Manifest\CopyrightElement * @uses \PharIo\Manifest\CopyrightInformation * @uses \PharIo\Manifest\ElementCollection * @uses \PharIo\Manifest\Email * @uses \PharIo\Manifest\ExtElement * @uses \PharIo\Manifest\ExtElementCollection * @uses \PharIo\Manifest\License * @uses \PharIo\Manifest\LicenseElement * @uses \PharIo\Manifest\Manifest * @uses \PharIo\Manifest\ManifestDocument * @uses \PharIo\Manifest\ManifestDocumentMapper * @uses \PharIo\Manifest\ManifestElement * @uses \PharIo\Manifest\ManifestLoader * @uses \PharIo\Manifest\PhpElement * @uses \PharIo\Manifest\PhpExtensionRequirement * @uses \PharIo\Manifest\PhpVersionRequirement * @uses \PharIo\Manifest\RequirementCollection * @uses \PharIo\Manifest\RequirementCollectionIterator * @uses \PharIo\Manifest\RequiresElement * @uses \PharIo\Manifest\Type * @uses \PharIo\Manifest\Url * @uses \PharIo\Version\Version * @uses \PharIo\Version\VersionConstraint */ class ManifestLoaderTest extends \PHPUnit\Framework\TestCase { public function testCanBeLoadedFromFile(): void { $this->assertInstanceOf( Manifest::class, ManifestLoader::fromFile(__DIR__ . '/_fixture/library.xml') ); } public function testCanBeLoadedFromString(): void { $this->assertInstanceOf( Manifest::class, ManifestLoader::fromString( file_get_contents(__DIR__ . '/_fixture/library.xml') ) ); } public function testCanBeLoadedFromPhar(): void { $this->assertInstanceOf( Manifest::class, ManifestLoader::fromPhar(__DIR__ . '/_fixture/test.phar') ); } public function testLoadingNonExistingFileThrowsException(): void { $this->expectException(ManifestLoaderException::class); ManifestLoader::fromFile('/not/existing'); } /** * @uses \PharIo\Manifest\ManifestDocumentLoadingException */ public function testLoadingInvalidXmlThrowsException(): void { $this->expectException(ManifestLoaderException::class); ManifestLoader::fromString(''); } } ================================================ FILE: tests/ManifestSerializerTest.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use PharIo\Version\Version; use function file_get_contents; use function sys_get_temp_dir; use function uniqid; use function unlink; /** * @covers \PharIo\Manifest\ManifestSerializer * * @uses \PharIo\Manifest\ApplicationName * @uses \PharIo\Manifest\Author * @uses \PharIo\Manifest\AuthorCollection * @uses \PharIo\Manifest\AuthorCollectionIterator * @uses \PharIo\Manifest\AuthorElement * @uses \PharIo\Manifest\AuthorElementCollection * @uses \PharIo\Manifest\BundledComponent * @uses \PharIo\Manifest\BundledComponentCollection * @uses \PharIo\Manifest\BundledComponentCollectionIterator * @uses \PharIo\Manifest\BundlesElement * @uses \PharIo\Manifest\ComponentElement * @uses \PharIo\Manifest\ComponentElementCollection * @uses \PharIo\Manifest\ContainsElement * @uses \PharIo\Manifest\CopyrightElement * @uses \PharIo\Manifest\CopyrightInformation * @uses \PharIo\Manifest\ElementCollection * @uses \PharIo\Manifest\Email * @uses \PharIo\Manifest\ExtElement * @uses \PharIo\Manifest\ExtElementCollection * @uses \PharIo\Manifest\License * @uses \PharIo\Manifest\LicenseElement * @uses \PharIo\Manifest\Manifest * @uses \PharIo\Manifest\ManifestDocument * @uses \PharIo\Manifest\ManifestDocumentMapper * @uses \PharIo\Manifest\ManifestElement * @uses \PharIo\Manifest\ManifestLoader * @uses \PharIo\Manifest\PhpElement * @uses \PharIo\Manifest\PhpExtensionRequirement * @uses \PharIo\Manifest\PhpVersionRequirement * @uses \PharIo\Manifest\RequirementCollection * @uses \PharIo\Manifest\RequirementCollectionIterator * @uses \PharIo\Manifest\RequiresElement * @uses \PharIo\Manifest\Type * @uses \PharIo\Manifest\Url * @uses \PharIo\Version\Version * @uses \PharIo\Version\VersionConstraint */ class ManifestSerializerTest extends \PHPUnit\Framework\TestCase { /** * @dataProvider dataProvider * * @uses \PharIo\Manifest\Application * @uses \PharIo\Manifest\Library * @uses \PharIo\Manifest\Extension * @uses \PharIo\Manifest\ExtensionElement */ public function testCanSerializeToString($expected): void { $manifest = ManifestLoader::fromString($expected); $serializer = new ManifestSerializer(); $this->assertXmlStringEqualsXmlString( $expected, $serializer->serializeToString($manifest) ); } public function dataProvider() { return [ 'application' => [file_get_contents(__DIR__ . '/_fixture/phpunit-5.6.5.xml')], 'library' => [file_get_contents(__DIR__ . '/_fixture/library.xml')], 'extension' => [file_get_contents(__DIR__ . '/_fixture/extension.xml')] ]; } /** * @uses \PharIo\Manifest\Library * @uses \PharIo\Manifest\ApplicationName */ public function testCanSerializeToFile(): void { $src = __DIR__ . '/_fixture/library.xml'; $dest = sys_get_temp_dir() . '/' . uniqid('serializer', true); $manifest = ManifestLoader::fromFile($src); $serializer = new ManifestSerializer(); $serializer->serializeToFile($manifest, $dest); $this->assertXmlFileEqualsXmlFile($src, $dest); unlink($dest); } /** * @uses \PharIo\Manifest\ApplicationName */ public function testCanHandleUnknownType(): void { $type = $this->getMockForAbstractClass(Type::class); $manifest = new Manifest( new ApplicationName('testvendor/testname'), new Version('1.0.0'), $type, new CopyrightInformation( new AuthorCollection(), new License('bsd-3', new Url('https://some/uri')) ), new RequirementCollection(), new BundledComponentCollection() ); $serializer = new ManifestSerializer(); $this->assertXmlStringEqualsXmlFile( __DIR__ . '/_fixture/custom.xml', $serializer->serializeToString($manifest) ); } } ================================================ FILE: tests/_fixture/custom.xml ================================================ ================================================ FILE: tests/_fixture/extension-invalidcompatible.xml ================================================ ================================================ FILE: tests/_fixture/extension.xml ================================================ ================================================ FILE: tests/_fixture/invalidversion.xml ================================================ ================================================ FILE: tests/_fixture/invalidversionconstraint.xml ================================================ ================================================ FILE: tests/_fixture/library.xml ================================================ ================================================ FILE: tests/_fixture/manifest.xml ================================================ ================================================ FILE: tests/_fixture/noemailauthor.xml ================================================ ================================================ FILE: tests/_fixture/phpunit-5.6.5.xml ================================================ ================================================ FILE: tests/exceptions/ManifestDocumentLoadingExceptionTest.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use DOMDocument; use LibXMLError; use function libxml_get_errors; use function libxml_use_internal_errors; class ManifestDocumentLoadingExceptionTest extends \PHPUnit\Framework\TestCase { public function testXMLErrorsCanBeRetrieved(): void { $dom = new DOMDocument(); $prev = libxml_use_internal_errors(true); $dom->loadXML(''); $exception = new ManifestDocumentLoadingException(libxml_get_errors()); libxml_use_internal_errors($prev); $this->assertContainsOnlyInstancesOf(LibXMLError::class, $exception->getLibxmlErrors()); } } ================================================ FILE: tests/values/ApplicationNameTest.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use PHPUnit\Framework\TestCase; class ApplicationNameTest extends TestCase { public function testCanBeCreatedWithValidName(): void { $this->assertInstanceOf( ApplicationName::class, new ApplicationName('foo/bar') ); } public function testUsingInvalidFormatForNameThrowsException(): void { $this->expectException(InvalidApplicationNameException::class); $this->expectExceptionCode(InvalidApplicationNameException::InvalidFormat); new ApplicationName('foo'); } public function testReturnsTrueForEqualNamesWhenCompared(): void { $app = new ApplicationName('foo/bar'); $this->assertTrue( $app->isEqual($app) ); } public function testReturnsFalseForNonEqualNamesWhenCompared(): void { $app1 = new ApplicationName('foo/bar'); $app2 = new ApplicationName('foo/foo'); $this->assertFalse( $app1->isEqual($app2) ); } public function testCanBeConvertedToString(): void { $this->assertEquals( 'foo/bar', (new ApplicationName('foo/bar'))->asString() ); } } ================================================ FILE: tests/values/ApplicationTest.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use PHPUnit\Framework\TestCase; /** * @covers PharIo\Manifest\Application * @covers PharIo\Manifest\Type */ class ApplicationTest extends TestCase { /** @var Application */ private $type; protected function setUp(): void { $this->type = Type::application(); } public function testCanBeCreated(): void { $this->assertInstanceOf(Application::class, $this->type); } public function testIsApplication(): void { $this->assertTrue($this->type->isApplication()); } public function testIsNotLibrary(): void { $this->assertFalse($this->type->isLibrary()); } public function testIsNotExtension(): void { $this->assertFalse($this->type->isExtension()); } } ================================================ FILE: tests/values/AuthorCollectionTest.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use PHPUnit\Framework\TestCase; /** * @covers \PharIo\Manifest\AuthorCollection * @covers \PharIo\Manifest\AuthorCollectionIterator * * @uses \PharIo\Manifest\Author * @uses \PharIo\Manifest\Email */ class AuthorCollectionTest extends TestCase { /** @var AuthorCollection */ private $collection; /** @var Author */ private $item; protected function setUp(): void { $this->collection = new AuthorCollection; $this->item = new Author('Joe Developer', new Email('user@example.com')); } public function testCanBeCreated(): void { $this->assertInstanceOf(AuthorCollection::class, $this->collection); } public function testCanBeCounted(): void { $this->collection->add($this->item); $this->assertCount(1, $this->collection); } public function testCanBeIterated(): void { $this->collection->add( new Author('Dummy First', new Email('dummy@example.com')) ); $this->collection->add($this->item); $this->assertContains($this->item, $this->collection); } public function testKeyPositionCanBeRetrieved(): void { $this->collection->add($this->item); foreach ($this->collection as $key => $item) { $this->assertEquals(0, $key); } } } ================================================ FILE: tests/values/AuthorTest.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use PHPUnit\Framework\TestCase; /** * @covers PharIo\Manifest\Author * * @uses PharIo\Manifest\Email */ class AuthorTest extends TestCase { /** @var Author */ private $author; protected function setUp(): void { $this->author = new Author('Joe Developer', new Email('user@example.com')); } public function testCanBeCreated(): void { $this->assertInstanceOf(Author::class, $this->author); } public function testNameCanBeRetrieved(): void { $this->assertEquals('Joe Developer', $this->author->getName()); } public function testEmailCanBeRetrieved(): void { $email = $this->author->getEmail(); $this->assertEquals('user@example.com', $email->asString()); } public function testCanBeUsedAsString(): void { $this->assertEquals('Joe Developer ', $this->author->asString()); } public function testCanBeCreatedWithoutEmail(): void { $this->assertInstanceOf(Author::class, new Author('Joe Developer')); } public function testHasEmailReturnsTrueWhenEMailIsSet(): void { $this->assertTrue($this->author->hasEmail()); } public function testHasEmailReturnsFalseOnMissingEMail(): void { $this->assertFalse((new Author('Joe Developer'))->hasEmail()); } public function testThrowsExceptionWhenMissingEmailAddressIsQueried(): void { $author = new Author('Joe Developer'); $this->expectException(NoEmailAddressException::class); $author->getEmail(); } } ================================================ FILE: tests/values/BundledComponentCollectionTest.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use PharIo\Version\Version; use PHPUnit\Framework\TestCase; /** * @covers \PharIo\Manifest\BundledComponentCollection * @covers \PharIo\Manifest\BundledComponentCollectionIterator * * @uses \PharIo\Manifest\BundledComponent * @uses \PharIo\Version\Version */ class BundledComponentCollectionTest extends TestCase { /** @var BundledComponentCollection */ private $collection; /** @var BundledComponent */ private $item; protected function setUp(): void { $this->collection = new BundledComponentCollection; $this->item = new BundledComponent('phpunit/php-code-coverage', new Version('4.0.2')); } public function testCanBeCreated(): void { $this->assertInstanceOf(BundledComponentCollection::class, $this->collection); } public function testCanBeCounted(): void { $this->collection->add($this->item); $this->assertCount(1, $this->collection); } public function testCanBeIterated(): void { $this->collection->add($this->createMock(BundledComponent::class)); $this->collection->add($this->item); $this->assertContains($this->item, $this->collection); } public function testKeyPositionCanBeRetrieved(): void { $this->collection->add($this->item); foreach ($this->collection as $key => $item) { $this->assertEquals(0, $key); } } } ================================================ FILE: tests/values/BundledComponentTest.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use PharIo\Version\Version; use PHPUnit\Framework\TestCase; /** * @covers PharIo\Manifest\BundledComponent * * @uses \PharIo\Version\Version */ class BundledComponentTest extends TestCase { /** @var BundledComponent */ private $bundledComponent; protected function setUp(): void { $this->bundledComponent = new BundledComponent('phpunit/php-code-coverage', new Version('4.0.2')); } public function testCanBeCreated(): void { $this->assertInstanceOf(BundledComponent::class, $this->bundledComponent); } public function testNameCanBeRetrieved(): void { $this->assertEquals('phpunit/php-code-coverage', $this->bundledComponent->getName()); } public function testVersionCanBeRetrieved(): void { $this->assertEquals('4.0.2', $this->bundledComponent->getVersion()->getVersionString()); } } ================================================ FILE: tests/values/CopyrightInformationTest.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use PHPUnit\Framework\TestCase; /** * @covers PharIo\Manifest\CopyrightInformation * * @uses PharIo\Manifest\AuthorCollection * @uses PharIo\Manifest\AuthorCollectionIterator * @uses PharIo\Manifest\Author * @uses PharIo\Manifest\Email * @uses PharIo\Manifest\License * @uses PharIo\Manifest\Url */ class CopyrightInformationTest extends TestCase { /** @var CopyrightInformation */ private $copyrightInformation; /** @var Author */ private $author; /** @var License */ private $license; protected function setUp(): void { $this->author = new Author('Joe Developer', new Email('user@example.com')); $this->license = new License('BSD-3-Clause', new Url('https://github.com/sebastianbergmann/phpunit/blob/master/LICENSE')); $authors = new AuthorCollection; $authors->add($this->author); $this->copyrightInformation = new CopyrightInformation($authors, $this->license); } public function testCanBeCreated(): void { $this->assertInstanceOf(CopyrightInformation::class, $this->copyrightInformation); } public function testAuthorsCanBeRetrieved(): void { $this->assertContains($this->author, $this->copyrightInformation->getAuthors()); } public function testLicenseCanBeRetrieved(): void { $this->assertEquals($this->license, $this->copyrightInformation->getLicense()); } } ================================================ FILE: tests/values/EmailTest.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use PHPUnit\Framework\TestCase; /** * @covers \PharIo\Manifest\Email */ class EmailTest extends TestCase { public function testCanBeCreatedForValidEmail(): void { $this->assertInstanceOf(Email::class, new Email('user@example.com')); } public function testCanBeRequestedAsString(): void { $this->assertEquals('user@example.com', (new Email('user@example.com'))->asString()); } /** * @covers \PharIo\Manifest\InvalidEmailException */ public function testCannotBeCreatedForInvalidEmail(): void { $this->expectException(InvalidEmailException::class); new Email('invalid'); } } ================================================ FILE: tests/values/ExtensionTest.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use PharIo\Version\AnyVersionConstraint; use PharIo\Version\Version; use PharIo\Version\VersionConstraint; use PharIo\Version\VersionConstraintParser; use PHPUnit\Framework\TestCase; use PHPUnit_Framework_MockObject_MockObject; /** * @covers \PharIo\Manifest\Extension * @covers \PharIo\Manifest\Type * * @uses \PharIo\Version\VersionConstraint * @uses \PharIo\Manifest\ApplicationName */ class ExtensionTest extends TestCase { /** @var Extension */ private $type; /** @var ApplicationName|PHPUnit_Framework_MockObject_MockObject */ private $name; protected function setUp(): void { $this->name = $this->createMock(ApplicationName::class); $this->type = Type::extension($this->name, new AnyVersionConstraint); } public function testCanBeCreated(): void { $this->assertInstanceOf(Extension::class, $this->type); } public function testIsNotApplication(): void { $this->assertFalse($this->type->isApplication()); } public function testIsNotLibrary(): void { $this->assertFalse($this->type->isLibrary()); } public function testIsExtension(): void { $this->assertTrue($this->type->isExtension()); } public function testApplicationCanBeRetrieved(): void { $this->assertInstanceOf(ApplicationName::class, $this->type->getApplicationName()); } public function testVersionConstraintCanBeRetrieved(): void { $this->assertInstanceOf( VersionConstraint::class, $this->type->getVersionConstraint() ); } public function testApplicationCanBeQueried(): void { $this->name->method('isEqual')->willReturn(true); $this->assertTrue( $this->type->isExtensionFor($this->createMock(ApplicationName::class)) ); } public function testCompatibleWithReturnsTrueForMatchingVersionConstraintAndApplication(): void { $app = new ApplicationName('foo/bar'); $extension = Type::extension($app, (new VersionConstraintParser)->parse('^1.0')); $version = new Version('1.0.0'); $this->assertTrue( $extension->isCompatibleWith($app, $version) ); } public function testCompatibleWithReturnsFalseForNotMatchingVersionConstraint(): void { $app = new ApplicationName('foo/bar'); $extension = Type::extension($app, (new VersionConstraintParser)->parse('^1.0')); $version = new Version('2.0.0'); $this->assertFalse( $extension->isCompatibleWith($app, $version) ); } public function testCompatibleWithReturnsFalseForNotMatchingApplication(): void { $app1 = new ApplicationName('foo/bar'); $app2 = new ApplicationName('foo/foo'); $extension = Type::extension($app1, (new VersionConstraintParser)->parse('^1.0')); $version = new Version('1.0.0'); $this->assertFalse( $extension->isCompatibleWith($app2, $version) ); } } ================================================ FILE: tests/values/LibraryTest.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use PHPUnit\Framework\TestCase; /** * @covers PharIo\Manifest\Library * @covers PharIo\Manifest\Type */ class LibraryTest extends TestCase { /** @var Library */ private $type; protected function setUp(): void { $this->type = Type::library(); } public function testCanBeCreated(): void { $this->assertInstanceOf(Library::class, $this->type); } public function testIsNotApplication(): void { $this->assertFalse($this->type->isApplication()); } public function testIsLibrary(): void { $this->assertTrue($this->type->isLibrary()); } public function testIsNotExtension(): void { $this->assertFalse($this->type->isExtension()); } } ================================================ FILE: tests/values/LicenseTest.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use PHPUnit\Framework\TestCase; /** * @covers PharIo\Manifest\License * * @uses PharIo\Manifest\Url */ class LicenseTest extends TestCase { /** @var License */ private $license; protected function setUp(): void { $this->license = new License('BSD-3-Clause', new Url('https://github.com/sebastianbergmann/phpunit/blob/master/LICENSE')); } public function testCanBeCreated(): void { $this->assertInstanceOf(License::class, $this->license); } public function testNameCanBeRetrieved(): void { $this->assertEquals('BSD-3-Clause', $this->license->getName()); } public function testUrlCanBeRetrieved(): void { $this->assertEquals( 'https://github.com/sebastianbergmann/phpunit/blob/master/LICENSE', $this->license->getUrl()->asString() ); } } ================================================ FILE: tests/values/ManifestTest.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use PharIo\Version\AnyVersionConstraint; use PharIo\Version\Version; use PHPUnit\Framework\TestCase; /** * @covers \PharIo\Manifest\Manifest * * @uses \PharIo\Manifest\ApplicationName * @uses \PharIo\Manifest\Author * @uses \PharIo\Manifest\AuthorCollection * @uses \PharIo\Manifest\BundledComponent * @uses \PharIo\Manifest\BundledComponentCollection * @uses \PharIo\Manifest\CopyrightInformation * @uses \PharIo\Manifest\Email * @uses \PharIo\Manifest\License * @uses \PharIo\Manifest\RequirementCollection * @uses \PharIo\Manifest\PhpVersionRequirement * @uses \PharIo\Manifest\Type * @uses \PharIo\Manifest\Application * @uses \PharIo\Manifest\Url * @uses \PharIo\Version\Version * @uses \PharIo\Version\VersionConstraint */ class ManifestTest extends TestCase { /** @var ApplicationName */ private $name; /** @var Version */ private $version; /** @var Type */ private $type; /** @var CopyrightInformation */ private $copyrightInformation; /** @var RequirementCollection */ private $requirements; /** @var BundledComponentCollection */ private $bundledComponents; /** @var Manifest */ private $manifest; protected function setUp(): void { $this->version = new Version('5.6.5'); $this->type = Type::application(); $author = new Author('Joe Developer', new Email('user@example.com')); $license = new License('BSD-3-Clause', new Url('https://github.com/sebastianbergmann/phpunit/blob/master/LICENSE')); $authors = new AuthorCollection; $authors->add($author); $this->copyrightInformation = new CopyrightInformation($authors, $license); $this->requirements = new RequirementCollection; $this->requirements->add(new PhpVersionRequirement(new AnyVersionConstraint)); $this->bundledComponents = new BundledComponentCollection; $this->bundledComponents->add(new BundledComponent('phpunit/php-code-coverage', new Version('4.0.2'))); $this->name = new ApplicationName('phpunit/phpunit'); $this->manifest = new Manifest( $this->name, $this->version, $this->type, $this->copyrightInformation, $this->requirements, $this->bundledComponents ); } public function testCanBeCreated(): void { $this->assertInstanceOf(Manifest::class, $this->manifest); } public function testNameCanBeRetrieved(): void { $this->assertEquals($this->name, $this->manifest->getName()); } public function testVersionCanBeRetrieved(): void { $this->assertEquals($this->version, $this->manifest->getVersion()); } public function testTypeCanBeRetrieved(): void { $this->assertEquals($this->type, $this->manifest->getType()); } public function testTypeCanBeQueried(): void { $this->assertTrue($this->manifest->isApplication()); $this->assertFalse($this->manifest->isLibrary()); $this->assertFalse($this->manifest->isExtension()); } public function testCopyrightInformationCanBeRetrieved(): void { $this->assertEquals($this->copyrightInformation, $this->manifest->getCopyrightInformation()); } public function testRequirementsCanBeRetrieved(): void { $this->assertEquals($this->requirements, $this->manifest->getRequirements()); } public function testBundledComponentsCanBeRetrieved(): void { $this->assertEquals($this->bundledComponents, $this->manifest->getBundledComponents()); } /** * @uses \PharIo\Manifest\Extension */ public function testExtendedApplicationCanBeQueriedForExtension(): void { $appName = new ApplicationName('foo/bar'); $manifest = new Manifest( new ApplicationName('foo/foo'), new Version('1.0.0'), Type::extension($appName, new AnyVersionConstraint), $this->copyrightInformation, new RequirementCollection, new BundledComponentCollection ); $this->assertTrue($manifest->isExtensionFor($appName)); } public function testNonExtensionReturnsFalseWhenQueriesForExtension(): void { $appName = new ApplicationName('foo/bar'); $manifest = new Manifest( new ApplicationName('foo/foo'), new Version('1.0.0'), Type::library(), $this->copyrightInformation, new RequirementCollection, new BundledComponentCollection ); $this->assertFalse($manifest->isExtensionFor($appName)); } /** * @uses \PharIo\Manifest\Extension */ public function testExtendedApplicationCanBeQueriedForExtensionWithVersion(): void { $appName = new ApplicationName('foo/bar'); $manifest = new Manifest( new ApplicationName('foo/foo'), new Version('1.0.0'), Type::extension($appName, new AnyVersionConstraint), $this->copyrightInformation, new RequirementCollection, new BundledComponentCollection ); $this->assertTrue($manifest->isExtensionFor($appName, new Version('1.2.3'))); } } ================================================ FILE: tests/values/PhpExtensionRequirementTest.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use PHPUnit\Framework\TestCase; /** * @covers PharIo\Manifest\PhpExtensionRequirement */ class PhpExtensionRequirementTest extends TestCase { public function testCanBeCreated(): void { $this->assertInstanceOf(PhpExtensionRequirement::class, new PhpExtensionRequirement('dom')); } public function testCanBeConvertedToString(): void { $this->assertEquals('dom', (new PhpExtensionRequirement('dom'))->asString()); } } ================================================ FILE: tests/values/PhpVersionRequirementTest.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use PharIo\Version\ExactVersionConstraint; use PHPUnit\Framework\TestCase; /** * @covers PharIo\Manifest\PhpVersionRequirement * * @uses \PharIo\Version\VersionConstraint */ class PhpVersionRequirementTest extends TestCase { /** @var PhpVersionRequirement */ private $requirement; protected function setUp(): void { $this->requirement = new PhpVersionRequirement(new ExactVersionConstraint('7.1.0')); } public function testCanBeCreated(): void { $this->assertInstanceOf(PhpVersionRequirement::class, $this->requirement); } public function testVersionConstraintCanBeRetrieved(): void { $this->assertEquals('7.1.0', $this->requirement->getVersionConstraint()->asString()); } } ================================================ FILE: tests/values/RequirementCollectionTest.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use PharIo\Version\ExactVersionConstraint; use PHPUnit\Framework\TestCase; /** * @covers \PharIo\Manifest\RequirementCollection * @covers \PharIo\Manifest\RequirementCollectionIterator * * @uses \PharIo\Manifest\PhpVersionRequirement * @uses \PharIo\Version\VersionConstraint */ class RequirementCollectionTest extends TestCase { /** @var RequirementCollection */ private $collection; /** @var Requirement */ private $item; protected function setUp(): void { $this->collection = new RequirementCollection; $this->item = new PhpVersionRequirement(new ExactVersionConstraint('7.1.0')); } public function testCanBeCreated(): void { $this->assertInstanceOf(RequirementCollection::class, $this->collection); } public function testCanBeCounted(): void { $this->collection->add($this->item); $this->assertCount(1, $this->collection); } public function testCanBeIterated(): void { $this->collection->add(new PhpVersionRequirement(new ExactVersionConstraint('5.6.0'))); $this->collection->add($this->item); $this->assertContains($this->item, $this->collection); } public function testKeyPositionCanBeRetrieved(): void { $this->collection->add($this->item); foreach ($this->collection as $key => $item) { $this->assertEquals(0, $key); } } } ================================================ FILE: tests/values/UrlTest.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use PHPUnit\Framework\TestCase; /** * @covers PharIo\Manifest\Url */ class UrlTest extends TestCase { public function testCanBeCreatedForValidUrl(): void { $this->assertInstanceOf(Url::class, new Url('https://phar.io/')); } public function testCanBeConvertedToString(): void { $this->assertEquals('https://phar.io/', (new Url('https://phar.io/'))->asString()); } /** * @covers PharIo\Manifest\InvalidUrlException */ public function testCannotBeCreatedForInvalidUrl(): void { $this->expectException(InvalidUrlException::class); new Url('invalid'); } } ================================================ FILE: tests/xml/AuthorElementCollectionTest.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use DOMDocument; class AuthorElementCollectionTest extends \PHPUnit\Framework\TestCase { public function testAuthorElementCanBeRetrievedFromCollection(): void { $dom = new DOMDocument(); $dom->loadXML(''); $collection = new AuthorElementCollection($dom->childNodes); foreach ($collection as $authorElement) { $this->assertInstanceOf(AuthorElement::class, $authorElement); } } } ================================================ FILE: tests/xml/AuthorElementTest.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use DOMDocument; class AuthorElementTest extends \PHPUnit\Framework\TestCase { /** @var AuthorElement */ private $author; protected function setUp(): void { $dom = new DOMDocument(); $dom->loadXML(''); $this->author = new AuthorElement($dom->documentElement); } public function testNameCanBeRetrieved(): void { $this->assertEquals('Reiner Zufall', $this->author->getName()); } public function testEmailCanBeRetrieved(): void { $this->assertEquals('reiner@zufall.de', $this->author->getEmail()); } public function testHasEmailReturnsTrueWhenEMailIsSet(): void { $this->assertTrue($this->author->hasEmail()); } public function testHasEMailReturnsFalseWhenNoEMailAddressIsSet(): void { $dom = new DOMDocument(); $dom->loadXML(''); $this->assertFalse((new AuthorElement($dom->documentElement))->hasEMail()); } } ================================================ FILE: tests/xml/BundlesElementTest.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use DOMDocument; class BundlesElementTest extends \PHPUnit\Framework\TestCase { /** @var DOMDocument */ private $dom; /** @var BundlesElement */ private $bundles; protected function setUp(): void { $this->dom = new DOMDocument(); $this->dom->loadXML(''); $this->bundles = new BundlesElement($this->dom->documentElement); } public function testThrowsExceptionWhenGetComponentElementsIsCalledButNodesAreMissing(): void { $this->expectException(ManifestElementException::class); $this->bundles->getComponentElements(); } public function testGetComponentElementsReturnsComponentElementCollection(): void { $this->addComponent(); $this->assertInstanceOf( ComponentElement::class, $this->bundles->getComponentElements()->current() ); } private function addComponent(): void { $this->dom->documentElement->appendChild( $this->dom->createElementNS('https://phar.io/xml/manifest/1.0', 'component') ); } } ================================================ FILE: tests/xml/ComponentElementCollectionTest.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use DOMDocument; class ComponentElementCollectionTest extends \PHPUnit\Framework\TestCase { public function testComponentElementCanBeRetrievedFromCollection(): void { $dom = new DOMDocument(); $dom->loadXML(''); $collection = new ComponentElementCollection($dom->childNodes); foreach ($collection as $componentElement) { $this->assertInstanceOf(ComponentElement::class, $componentElement); } } } ================================================ FILE: tests/xml/ComponentElementTest.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use DOMDocument; class ComponentElementTest extends \PHPUnit\Framework\TestCase { /** @var ComponentElement */ private $component; protected function setUp(): void { $dom = new DOMDocument(); $dom->loadXML(''); $this->component = new ComponentElement($dom->documentElement); } public function testNameCanBeRetrieved(): void { $this->assertEquals('phar-io/phive', $this->component->getName()); } public function testEmailCanBeRetrieved(): void { $this->assertEquals('0.6.0', $this->component->getVersion()); } } ================================================ FILE: tests/xml/ContainsElementTest.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use DOMDocument; use DOMElement; class ContainsElementTest extends \PHPUnit\Framework\TestCase { /** @var DOMElement */ private $domElement; /** @var ContainsElement */ private $contains; protected function setUp(): void { $dom = new DOMDocument(); $dom->loadXML(''); $this->domElement = $dom->documentElement; $this->contains = new ContainsElement($this->domElement); } public function testVersionCanBeRetrieved(): void { $this->assertEquals('5.6.5', $this->contains->getVersion()); } public function testThrowsExceptionWhenVersionAttributeIsMissing(): void { $this->domElement->removeAttribute('version'); $this->expectException(ManifestElementException::class); $this->contains->getVersion(); } public function testNameCanBeRetrieved(): void { $this->assertEquals('phpunit/phpunit', $this->contains->getName()); } public function testThrowsExceptionWhenNameAttributeIsMissing(): void { $this->domElement->removeAttribute('name'); $this->expectException(ManifestElementException::class); $this->contains->getName(); } public function testTypeCanBeRetrieved(): void { $this->assertEquals('application', $this->contains->getType()); } public function testThrowsExceptionWhenTypeAttributeIsMissing(): void { $this->domElement->removeAttribute('type'); $this->expectException(ManifestElementException::class); $this->contains->getType(); } public function testGetExtensionElementReturnsExtensionElement(): void { $this->domElement->appendChild( $this->domElement->ownerDocument->createElementNS('https://phar.io/xml/manifest/1.0', 'extension') ); $this->assertInstanceOf(ExtensionElement::class, $this->contains->getExtensionElement()); } } ================================================ FILE: tests/xml/CopyrightElementTest.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use DOMDocument; class CopyrightElementTest extends \PHPUnit\Framework\TestCase { /** @var DOMDocument */ private $dom; /** @var CopyrightElement */ private $copyright; protected function setUp(): void { $this->dom = new DOMDocument(); $this->dom->loadXML(''); $this->copyright = new CopyrightElement($this->dom->documentElement); } public function testThrowsExceptionWhenGetAuthroElementsIsCalledButNodesAreMissing(): void { $this->expectException(ManifestElementException::class); $this->copyright->getAuthorElements(); } public function testThrowsExceptionWhenGetLicenseElementIsCalledButNodeIsMissing(): void { $this->expectException(ManifestElementException::class); $this->copyright->getLicenseElement(); } public function testGetAuthorElementsReturnsAuthorElementCollection(): void { $this->dom->documentElement->appendChild( $this->dom->createElementNS('https://phar.io/xml/manifest/1.0', 'author') ); $this->assertInstanceOf( AuthorElementCollection::class, $this->copyright->getAuthorElements() ); } public function testGetLicenseElementReturnsLicenseElement(): void { $this->dom->documentElement->appendChild( $this->dom->createElementNS('https://phar.io/xml/manifest/1.0', 'license') ); $this->assertInstanceOf( LicenseElement::class, $this->copyright->getLicenseElement() ); } } ================================================ FILE: tests/xml/ElementCollectionTest.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use DOMDocument; use PHPUnit\Framework\TestCase; class ElementCollectionTest extends TestCase { public function testEnforcesDOMElementsOnly(): void { $dom = new DOMDocument(); $dom->loadXML('text'); $this->expectException(ElementCollectionException::class); new class($dom->documentElement->childNodes) extends ElementCollection { public function current(): void { } }; } } ================================================ FILE: tests/xml/ExtElementCollectionTest.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use DOMDocument; class ExtElementCollectionTest extends \PHPUnit\Framework\TestCase { public function testComponentElementCanBeRetrievedFromCollection(): void { $dom = new DOMDocument(); $dom->loadXML(''); $collection = new ExtElementCollection($dom->childNodes); foreach ($collection as $position => $extElement) { $this->assertInstanceOf(ExtElement::class, $extElement); $this->assertEquals(0, $position); } } } ================================================ FILE: tests/xml/ExtElementTest.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use DOMDocument; class ExtElementTest extends \PHPUnit\Framework\TestCase { /** @var ExtElement */ private $ext; protected function setUp(): void { $dom = new DOMDocument(); $dom->loadXML(''); $this->ext = new ExtElement($dom->documentElement); } public function testNameCanBeRetrieved(): void { $this->assertEquals('dom', $this->ext->getName()); } } ================================================ FILE: tests/xml/ExtensionElementTest.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use DOMDocument; class ExtensionElementTest extends \PHPUnit\Framework\TestCase { /** @var ExtensionElement */ private $extension; protected function setUp(): void { $dom = new DOMDocument(); $dom->loadXML(''); $this->extension = new ExtensionElement($dom->documentElement); } public function testNForCanBeRetrieved(): void { $this->assertEquals('phar-io/phive', $this->extension->getFor()); } public function testCompatibleVersionConstraintCanBeRetrieved(): void { $this->assertEquals('~0.6', $this->extension->getCompatible()); } } ================================================ FILE: tests/xml/LicenseElementTest.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use DOMDocument; class LicenseElementTest extends \PHPUnit\Framework\TestCase { /** @var LicenseElement */ private $license; protected function setUp(): void { $dom = new DOMDocument(); $dom->loadXML(''); $this->license = new LicenseElement($dom->documentElement); } public function testTypeCanBeRetrieved(): void { $this->assertEquals('BSD-3', $this->license->getType()); } public function testUrlCanBeRetrieved(): void { $this->assertEquals('https://some.tld/LICENSE', $this->license->getUrl()); } } ================================================ FILE: tests/xml/ManifestDocumentTest.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use function file_get_contents; class ManifestDocumentTest extends \PHPUnit\Framework\TestCase { public function testThrowsExceptionWhenFileDoesNotExist(): void { $this->expectException(ManifestDocumentException::class); ManifestDocument::fromFile('/does/not/exist'); } public function testCanBeCreatedFromFile(): void { $this->assertInstanceOf( ManifestDocument::class, ManifestDocument::fromFile(__DIR__ . '/../_fixture/phpunit-5.6.5.xml') ); } public function testFromStringThrowsExceptionOnEmptyString(): void { $this->expectException(ManifestDocumentException::class); ManifestDocument::fromString(''); } public function testCanBeConstructedFromString(): void { $content = file_get_contents(__DIR__ . '/../_fixture/phpunit-5.6.5.xml'); $this->assertInstanceOf( ManifestDocument::class, ManifestDocument::fromString($content) ); } public function testThrowsExceptionOnInvalidXML(): void { $this->expectException(ManifestDocumentLoadingException::class); ManifestDocument::fromString(''); } public function testLoadingDocumentWithWrongRootNameThrowsException(): void { $this->expectException(ManifestDocumentException::class); ManifestDocument::fromString(''); } public function testLoadingDocumentWithWrongNamespaceThrowsException(): void { $this->expectException(ManifestDocumentException::class); ManifestDocument::fromString(''); } public function testContainsElementCanBeRetrieved(): void { $this->assertInstanceOf( ContainsElement::class, $this->loadFixture()->getContainsElement() ); } public function testRequiresElementCanBeRetrieved(): void { $this->assertInstanceOf( RequiresElement::class, $this->loadFixture()->getRequiresElement() ); } public function testCopyrightElementCanBeRetrieved(): void { $this->assertInstanceOf( CopyrightElement::class, $this->loadFixture()->getCopyrightElement() ); } public function testBundlesElementCanBeRetrieved(): void { $this->assertInstanceOf( BundlesElement::class, $this->loadFixture()->getBundlesElement() ); } public function testThrowsExceptionWhenContainsIsMissing(): void { $this->expectException(ManifestDocumentException::class); $this->loadEmptyFixture()->getContainsElement(); } public function testThrowsExceptionWhenCopyirhgtIsMissing(): void { $this->expectException(ManifestDocumentException::class); $this->loadEmptyFixture()->getCopyrightElement(); } public function testThrowsExceptionWhenRequiresIsMissing(): void { $this->expectException(ManifestDocumentException::class); $this->loadEmptyFixture()->getRequiresElement(); } public function testThrowsExceptionWhenBundlesIsMissing(): void { $this->expectException(ManifestDocumentException::class); $this->loadEmptyFixture()->getBundlesElement(); } public function testHasBundlesReturnsTrueWhenBundlesNodeIsPresent(): void { $this->assertTrue( $this->loadFixture()->hasBundlesElement() ); } public function testHasBundlesReturnsFalseWhenBundlesNoNodeIsPresent(): void { $this->assertFalse( $this->loadEmptyFixture()->hasBundlesElement() ); } private function loadFixture() { return ManifestDocument::fromFile(__DIR__ . '/../_fixture/phpunit-5.6.5.xml'); } private function loadEmptyFixture() { return ManifestDocument::fromString( '' ); } } ================================================ FILE: tests/xml/PhpElementTest.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use DOMDocument; class PhpElementTest extends \PHPUnit\Framework\TestCase { /** @var DOMDocument */ private $dom; /** @var PhpElement */ private $php; protected function setUp(): void { $this->dom = new DOMDocument(); $this->dom->loadXML(''); $this->php = new PhpElement($this->dom->documentElement); } public function testVersionConstraintCanBeRetrieved(): void { $this->assertEquals('^5.6 || ^7.0', $this->php->getVersion()); } public function testHasExtElementsReturnsFalseWhenNoExtensionsAreRequired(): void { $this->assertFalse($this->php->hasExtElements()); } public function testHasExtElementsReturnsTrueWhenExtensionsAreRequired(): void { $this->addExtElement(); $this->assertTrue($this->php->hasExtElements()); } public function testGetExtElementsReturnsExtElementCollection(): void { $this->addExtElement(); $this->assertInstanceOf(ExtElementCollection::class, $this->php->getExtElements()); } private function addExtElement(): void { $this->dom->documentElement->appendChild( $this->dom->createElementNS('https://phar.io/xml/manifest/1.0', 'ext') ); } } ================================================ FILE: tests/xml/RequiresElementTest.php ================================================ , Sebastian Heuer , Sebastian Bergmann and contributors * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * */ namespace PharIo\Manifest; use DOMDocument; class RequiresElementTest extends \PHPUnit\Framework\TestCase { /** @var DOMDocument */ private $dom; /** @var RequiresElement */ private $requires; protected function setUp(): void { $this->dom = new DOMDocument(); $this->dom->loadXML(''); $this->requires = new RequiresElement($this->dom->documentElement); } public function testThrowsExceptionWhenGetPhpElementIsCalledButElementIsMissing(): void { $this->expectException(ManifestElementException::class); $this->requires->getPHPElement(); } public function testHasExtElementsReturnsTrueWhenExtensionsAreRequired(): void { $this->dom->documentElement->appendChild( $this->dom->createElementNS('https://phar.io/xml/manifest/1.0', 'php') ); $this->assertInstanceOf(PhpElement::class, $this->requires->getPHPElement()); } }