Skip to content

feat(tests): migrate Peridot test suite to PHPUnit 11#73

Open
guillaumedelre wants to merge 7 commits into
downforcetech:mainfrom
guillaumedelre:feature/issue-65
Open

feat(tests): migrate Peridot test suite to PHPUnit 11#73
guillaumedelre wants to merge 7 commits into
downforcetech:mainfrom
guillaumedelre:feature/issue-65

Conversation

@guillaumedelre
Copy link
Copy Markdown

Migrate Peridot test suite to PHPUnit 11

Context

This PR consolidates all changes from issues #14, #15, #23, #28, #44 and #52 into a single
integration branch and replaces the legacy Peridot BDD spec runner with PHPUnit 11. The
specs/FluidXml.php file (3 276 lines of Peridot DSL) is fully ported to idiomatic PHPUnit
test classes.


Test suite

208 tests across 5 files, run with PHP 8.2 on FrankenPHP:

File Tests Covers
tests/FluidXmlTest.php 171 Full FluidXml API
tests/FluidContextTest.php 12 FluidContext construction and iteration
tests/FluidNamespaceTest.php 5 FluidNamespace accessors and XPath formatting
tests/FluidHelperTest.php 6 DOM/SimpleXML serialization helpers
tests/CssTranslatorTest.php 14 CSS-to-XPath translation

A shared FluidTestCase base class provides assertEqualXml() and assertIsFluid() helpers
used throughout.

Coverage of previously merged PRs

Each commit cherry-picked into this branch has dedicated regression tests:

#14 - XML special character escaping
fix: escape XML special characters in addChild text content

  • testAddChildEscapesXmlSpecialCharsArgumentSyntax
  • testAddChildEscapesXmlSpecialCharsArraySyntax

#15 - libxml options for xml() and save()
feat: add libxml options support to xml() and save()

  • testXmlRendersEmptyElementsAsExplicitClosingTagsWithLibxmlNoemptytag
  • testXmlPassesLibxmlNoemptytagThroughWhenQueryingContext
  • testSaveStoresEntireXmlDocumentInFile
  • testSaveStoresFragmentOfXmlDocumentInFile
  • testSaveThrowsForNotWritableFile

#23 - @:text, @:cdata, @:comment in array syntax
feat: add @:text, @:cdata, @:comment to array syntax

  • testAddChildAddsTextContentUsingAtTextAlias
  • testAddChildAddsCdataContentUsingAtCdataSyntax
  • testAddChildAddsCommentContentUsingAtCommentSyntax

#28 - toArray() / toObject() with namespace support
feat: add toArray() and toObject() with namespace support

  • testToArrayExportsSimpleElementWithTextContent
  • testToArrayExportsAttributesUsingAtPrefix
  • testToArrayExportsNestedElementsAsNestedArrays
  • testToArrayExportsRepeatedSiblingElementsAsIndexedArrays
  • testToArrayExportsEmptyElementAsNull
  • testToArrayExportsQueriedNodesViaFluidContext
  • testToArrayExportsNamespaceDeclarationsUsingAtXmlnsPrefix
  • testToObjectReturnsstdClassMirroringToArray
  • testToObjectPreservesIndexedArraysForRepeatedSiblings
  • testToObjectReturnsArrayOfstdClassForFluidContext

#44 - DOMDocumentType crash on XML with DOCTYPE
fix: skip DOMDocumentType when importing XML with DOCTYPE declaration

  • testLoadImportsXmlFileContainingDoctype
  • testAddChildDoesNotThrowWithDoctypeXmlString

#52 - libxml flags for load()
feat: add libxml flags parameter to FluidXml::load()

  • testLoadAcceptsLibxmlFlags

Additional changes

source/ renamed to src/

Aligns with the PHP/OSS convention (src/ is the standard across Composer, Symfony and PSR
projects). All autoload paths in composer.json, phpunit.xml, rector.php and
.scrutinizer.yml updated accordingly.

Rector upgraded to ^2.0

Rector 0.18 is incompatible with phpstan ^2.0, which is pulled in transitively by
phpunit 11. Rector 2.x resolves the conflict. The rector.php config is updated to the 2.x
API (SetList::PHP_82 replacing LevelSetList::UP_TO_PHP_82). Running rector --dry-run
on src/ and tests/ produces no suggestions: the codebase is already fully PHP 8.2-compliant.

CI/CD configs updated

All four CI configs now use composer install --prefer-dist and php vendor/bin/phpunit
directly, replacing the deleted support/ shell scripts. Hardcoded GitHub access tokens
removed from circle.yml and .travis.yml.

File Changes
circle.yml PHP 8.2, vendor/ cache, token removed
.scrutinizer.yml PHPUnit command, coverage at build/logs/clover.xml, src/ filter
.travis.yml PHPUnit command, token removed, orphaned coveralls step removed
.coveralls.yml Added src_dir, coverage file paths

.gitignore updated

Added vendor/, build/ and .phpunit.result.cache.

README.md updated

The link to the deleted specs/FluidXml.php now points to tests/FluidXmlTest.php.


Removed

  • specs/ (3 276 lines of Peridot DSL)
  • support/ (14 shell scripts: init, test, coverage, coveralls, speedtest, gendoc, ...)
  • Peridot and its transitive dependencies (evenement/evenement, symfony/console 3.x,
    symfony/debug, peridot-php/peridot-scope, ...)

DOMElement::__construct does not escape & or < in its value argument,
causing DOMException when user data contains XML special characters.
Replace the value parameter with a createTextNode call after attachment,
which handles escaping at the DOM level.

Fixes downforcetech#14

Signed-off-by: Guillaume Delré <delre.guillaume@gmail.com>
xml() and save() now accept an $options integer bitmask forwarded to
DOMDocument::saveXML(), enabling LIBXML_NOEMPTYTAG and other libxml
flags. The same parameter propagates through FluidContext::xml(),
FluidSaveTrait, and the FluidHelper serialization helpers.

Closes downforcetech#15

Signed-off-by: Guillaume Delré <delre.guillaume@gmail.com>
The @ special key already sets text content in the concise array
syntax. This extends it with typed variants:
  - @:text   — explicit alias for @
  - @:cdata  — wraps content in a CDATA section
  - @:comment — inserts an XML comment

Closes downforcetech#23

Signed-off-by: Guillaume Delré <delre.guillaume@gmail.com>
FluidXml::toArray() returns ['rootTag' => value] for the document.
FluidContext::toArray() returns an array of ['tag' => value] entries
for each selected node.

Conversion rules:
  - Text-only element   -> plain string value
  - Empty element       -> null
  - Attributes          -> '@name' keys
  - Text with siblings  -> '@' key
  - CDATA content       -> '@:cdata' key
  - Comment             -> '@:comment' key
  - Repeated child tags -> indexed sub-arrays
  - Namespace decls     -> '@xmlns' / '@xmlns:prefix' keys (only those
                           introduced on the element, not inherited)

The output mirrors the array syntax accepted by addChild(), enabling
round-trip import/export.

FluidXml::toObject() and FluidContext::toObject() return the same
structure as stdClass instead of arrays, which integrates more
naturally with JSON workflows and property-access code. Associative
arrays become stdClass objects; indexed arrays (repeated siblings)
remain PHP arrays.

Namespace declarations are detected via the XPath namespace::* axis,
comparing in-scope namespaces with the parent element to emit only
the declarations local to each node.

Closes downforcetech#28

Signed-off-by: Guillaume Delré <delre.guillaume@gmail.com>
DOMDocument::importNode() returns false for DOMDocumentType nodes,
causing appendChild() to receive a boolean and throw a fatal error.

This happens when loading or inserting XML that contains a <!DOCTYPE>
declaration: the node list from childNodes includes the DOMDocumentType
node alongside the root element.

Skip DOMDocumentType entries in attachNodes() before attempting the
import, so the document content is imported correctly and the DOCTYPE
declaration is silently discarded.

Fixes downforcetech#44
Fixes downforcetech#50

Signed-off-by: Guillaume Delré <delre.guillaume@gmail.com>
Large XML files (or files served over HTTP) can exceed libxml's default
parser limits, causing load() to silently return empty data.

Pass an optional $flags int to load() and forward it to
DOMDocument::load(), which lets callers opt into LIBXML_PARSEHUGE,
LIBXML_COMPACT, or any other libxml flag as needed.

The implementation also switches from file_get_contents() + loadXML()
to DOMDocument::load() directly, which avoids loading the whole file
into a PHP string before parsing.

Closes downforcetech#52

Signed-off-by: Guillaume Delré <delre.guillaume@gmail.com>
Replaces the Peridot BDD spec runner with PHPUnit 11. All 208 tests
ported to 5 test files under tests/ covering FluidXml, FluidContext,
FluidNamespace, FluidHelper and CssTranslator.

Renames source/ to src/ to align with PHP/OSS convention.

Removes specs/, support/ and their Peridot dependency. Updates all CI
configs (CircleCI, Scrutinizer, Travis, Coveralls) to use composer
install and phpunit directly, removes hardcoded GitHub access tokens.
Upgrades rector to ^2.0 (required for compatibility with phpstan ^2.0
pulled by phpunit 11) and updates rector.php to the 2.x API.
Updates README to reference tests/ instead of specs/. Adds vendor/,
build/ and .phpunit.result.cache to .gitignore.

Signed-off-by: Guillaume Delré <delre.guillaume@gmail.com>
@guillaumedelre
Copy link
Copy Markdown
Author

Hey @daniele-orlando, this PR consolidates fixes for #14, #15, #23, #28, #44 and #52 — happy to adjust if anything looks off.

@guillaumedelre
Copy link
Copy Markdown
Author

Hey @daniele-orlando, gentle ping on this migration PR. Open to reworking if the approach doesn't fit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant