Skip to content

Commit

Permalink
Add constraint for node classes, FluentDOM\Utility\Constraints::asser…
Browse files Browse the repository at this point in the history
…tNodeClass()
  • Loading branch information
ThomasWeinert committed May 25, 2019
1 parent 9bab944 commit 1620d38
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 17 deletions.
23 changes: 7 additions & 16 deletions src/FluentDOM/Loader/JSONx.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use FluentDOM\DOM\DocumentFragment;
use FluentDOM\DOM\Element;
use FluentDOM\Loadable;
use FluentDOM\Utility\Constraints;
use FluentDOM\Utility\QualifiedName;

/**
Expand Down Expand Up @@ -89,22 +90,12 @@ public function loadFragment($source, string $contentType, $options = []) {
* @throws \LogicException
*/
private function transferNode(\DOMNode $node, \DOMNode $target) {
if (!($node instanceof Element)) {
throw new \LogicException(
sprintf('Unexpected node type: %s', get_class($node))
);
}
if (
!(
$target instanceOf Element ||
$target instanceof DocumentFragment ||
$target instanceof Document
)
) {
throw new \LogicException(
sprintf('Unexpected node type: %s', get_class($node))
);
}
Constraints::assertNodeClass(
$node, Element::class
);
Constraints::assertNodeClass(
$node, [Element::class, DocumentFragment::class, Document::class]
);
if ($node->namespaceURI === self::XMLNS_JSONX) {
if ($target instanceof Document) {
$normalizedName = $name = 'json:json';
Expand Down
22 changes: 22 additions & 0 deletions src/FluentDOM/Utility/Constraints.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

namespace FluentDOM\Utility {

use FluentDOM\DOM\Element;

/**
* Abstract utility class that provides several constraints/validations
*/
Expand Down Expand Up @@ -62,6 +64,26 @@ public static function assertNode($node, $message = 'DOMNode expected, got: %s.'
return TRUE;
}

/**
* @param \DOMNode $node
* @param string|string[] $classes
* @param string $message
* @return boolean
*/
public static function assertNodeClass(\DOMNode $node, $classes, $message = 'Unexpected node type: %s') {
if (!is_array($classes)) {
$classes = [$classes];
}
foreach ($classes as $className) {
if ($node instanceof $className) {
return TRUE;
}
}
throw new \LogicException(
sprintf($message, get_class($node))
);
}

/**
* Check if $elements is a traversable node list. It returns
* the $elements or NULL
Expand Down
59 changes: 58 additions & 1 deletion tests/FluentDOM/Utility/ConstraintsTest.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
<?php
/**
* FluentDOM
*
* @link https://thomas.weinert.info/FluentDOM/
* @copyright Copyright 2009-2019 FluentDOM Contributors
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*
*/

namespace FluentDOM\Utility {

require_once __DIR__ . '/../TestCase.php';

use FluentDOM\DOM\Element;
use FluentDOM\TestCase;

class ConstraintsTest extends TestCase {
Expand Down Expand Up @@ -85,6 +95,53 @@ public function testAssertNodeExpectingExceptionWithModifiedMessage() {
Constraints::assertNode(new \stdClass, 'Not a node but a %s.');
}

/**
* @group Utility
* @group Constraints
* @covers \FluentDOM\Utility\Constraints::assertNodeClass
*/
public function testAssertNodeClassWithMatchingClass() {
$document = new \DOMDocument();
$this->assertTrue(
Constraints::assertNodeClass($document, [\DOMElement::class, \DOMDocument::class])
);
}

/**
* @group Utility
* @group Constraints
* @covers \FluentDOM\Utility\Constraints::assertNodeClass
*/
public function testAssertNodeClassExpectingException() {
$document = new \DOMDocument();
$this->expectException(\LogicException::class);
$this->expectExceptionMessage('Unexpected node type: DOMDocument');
Constraints::assertNodeClass($document, \DOMElement::class);
}

/**
* @group Utility
* @group Constraints
* @covers \FluentDOM\Utility\Constraints::assertNodeClass
*/
public function testAssertNodeClassExpectingExceptionWithProvidedMessage() {
$document = new \DOMDocument();
$this->expectException(\LogicException::class);
$this->expectExceptionMessage('Expect DOMElement not DOMDocument');
Constraints::assertNodeClass($document, \DOMElement::class, 'Expect DOMElement not %s');
}

/**
* @group Utility
* @group Constraints
* @covers \FluentDOM\Utility\Constraints::assertNodeClass
*/
public function testAssertNodeClassWithMultipleClassesExpectingException() {
$document = new \DOMDocument();
$this->expectException(\LogicException::class);
Constraints::assertNodeClass($document, [\DOMElement::class, \DOMAttr::class]);
}


/**
* @group Utility
Expand Down Expand Up @@ -213,4 +270,4 @@ public function testHasOptionExpectingFalse() {
);
}
}
}
}

0 comments on commit 1620d38

Please sign in to comment.