diff --git a/files/constants.php b/files/constants.php index f8de8181..33be7e65 100644 --- a/files/constants.php +++ b/files/constants.php @@ -160,6 +160,7 @@ const PHPFHIR_TEST_CLASSNAME_VERSION_CONFIG = PHPFHIR_CLASSNAME_VERSION_CONFIG . 'Test'; const PHPFHIR_TEST_ENCODING_CLASSNAME_UNSERIALIZE_CONFIG = PHPFHIR_ENCODING_CLASSNAME_UNSERIALIZE_CONFIG . 'Test'; const PHPFHIR_TEST_ENCODING_CLASSNAME_SERIALIZE_CONFIG = PHPFHIR_ENCODING_CLASSNAME_SERIALIZE_CONFIG . 'Test'; +const PHPFHIR_TEST_ENCODING_CLASSSNAME_XML_WRITER = PHPFHIR_ENCODING_CLASSNAME_XML_WRITER . 'Test'; // Test constant names const PHPFHIR_TEST_CONSTANT_INTEGRATION_ENDPOINT = 'PHPFHIR_TEST_INTEGRATION_ENDPOINT'; diff --git a/files/funcs.php b/files/funcs.php index 91cd65b5..41a9206f 100644 --- a/files/funcs.php +++ b/files/funcs.php @@ -19,13 +19,22 @@ /** * require_with is used to ensure a clean context per required template file. * - * @param string $requiredFile + * @param string $_filename * @param array $vars * @return mixed */ -function require_with(string $requiredFile, array $vars): mixed +function require_with(string $_filename, array $vars): mixed { - $num = extract($vars, EXTR_OVERWRITE); + if (array_key_exists('_filename', $vars)) { + throw new \InvalidArgumentException('Cannot set "_filename" as key in $vars array.'); + } else if (array_key_exists('_realpath', $vars)) { + throw new \InvalidArgumentException('Cannot set "_realpath" as key in $vars array.'); + } + $_realpath = realpath($_filename); + if (false === $_realpath) { + throw new \RuntimeException(sprintf('Unable to resolve path for file "%s"', $_filename)); + } + $num = extract($vars); if ($num !== count($vars)) { throw new \RuntimeException( sprintf( @@ -37,8 +46,8 @@ function require_with(string $requiredFile, array $vars): mixed ); } // unset vars defined by this func - unset($vars, $num); - return require $requiredFile; + unset($vars, $num, $_filename); + return require $_realpath; } /** @@ -64,12 +73,9 @@ function pretty_var_export(mixed $var, int $indent = 0, bool $indentFirst = fals foreach ($var as $k => $v) { $literal = false; $indentFirst = is_int($k); - // TODO: if it works, is it really a shit idea? Probably. - if ('libxmlOptMask' === $k) { - $k = 'libxmlOpts'; - $literal = true; - } else if ('xhtmlLibxmlOptMask' === $k) { - $k = 'xhtmlLibxmlOpts'; + // handle output of option mask constant names. + if (is_string($k) && str_ends_with($k, 'OptMask')) { + $k = str_replace('OptMask', 'Opts', $k); $literal = true; } $out = sprintf("%s\n%s%s => %s,", diff --git a/template/core/encoding/class_xml_writer.php b/template/core/encoding/class_xml_writer.php index f55ca315..fd4a0a51 100644 --- a/template/core/encoding/class_xml_writer.php +++ b/template/core/encoding/class_xml_writer.php @@ -41,13 +41,21 @@ final class extends \XMLWri { private const _MEM = 'memory'; - /** @var bool */ + private getEntityName(); ?> $_config; private bool $_docStarted = false; - /** @var bool */ private bool $_rootOpen = false; - /** @var null|string */ private null|string $_open = null; + /** + * getEntityName(); ?> constructor. + * + * @param getFullyQualifiedName(true); ?> $config + */ + public function __construct(getEntityName(); ?> $config) + { + $this->_config = $config; + } + /** * @see https://www.php.net/manual/en/xmlwriter.openmemory.php * @@ -132,23 +140,24 @@ public function isRootOpen(): bool } /** - * @param getFullyQualifiedName(true); ?> $config * @param string $name * @param string|null $sourceXMLNS * @return bool */ - public function openRootNode( $config, string $name, null|string $sourceXMLNS): bool + public function openRootNode(string $name, null|string $sourceXMLNS): bool { if (null === $this->_open) { throw new \LogicException('Must open write destination before writing root node'); } else if (!$this->_docStarted) { throw new \LogicException('Document must be started before writing root node'); + } else if ($this->_rootOpen) { + throw new \LogicException('Root node is already open'); } if (!$this->startElement($name)) { return false; } - if ($config->getOverrideSourceXMLNS() || null === $sourceXMLNS) { - $ns = (string)$config->getRootXMLNS(); + if ($this->_config->getOverrideSourceXMLNS() || null === $sourceXMLNS) { + $ns = (string)$this->_config->getRootXMLNS(); } else { $ns = $sourceXMLNS; } diff --git a/template/core/tests/encoding/test_class_serialize_config.php b/template/core/tests/encoding/test_class_serialize_config.php index 808581f2..ff41d6c5 100644 --- a/template/core/tests/encoding/test_class_serialize_config.php +++ b/template/core/tests/encoding/test_class_serialize_config.php @@ -16,7 +16,6 @@ * limitations under the License. */ - use DCarbone\PHPFHIR\Utilities\ImportUtils; /** @var \DCarbone\PHPFHIR\Config $config */ @@ -43,7 +42,7 @@ class extends TestCase { - public function testEmptyConstruct() + public function testCanConstructWithoutParams() { $sc = new getEntityName(); ?>(); $this->assertFalse($sc->getOverrideSourceXMLNS()); @@ -51,7 +50,7 @@ public function testEmptyConstruct() $this->assertEquals(, $sc->getXHTMLLibxmlOpts()); } - public function testValuedConstruct() + public function testCanConstructWithValidValues() { $sc = new getEntityName(); ?>(overrideSourceXMLNS: true, rootXMLNS: 'urn:foo:bar', xhtmlLibxmlOpts: 123); $this->assertTrue($sc->getOverrideSourceXMLNS()); diff --git a/template/core/tests/encoding/test_class_unserialize_config.php b/template/core/tests/encoding/test_class_unserialize_config.php index 205889ab..8e3fd541 100644 --- a/template/core/tests/encoding/test_class_unserialize_config.php +++ b/template/core/tests/encoding/test_class_unserialize_config.php @@ -16,7 +16,6 @@ * limitations under the License. */ - use DCarbone\PHPFHIR\Utilities\ImportUtils; /** @var \DCarbone\PHPFHIR\Config $config */ @@ -42,14 +41,14 @@ class extends TestCase { - public function testEmptyConstruct() + public function testCanConstructWithoutParams() { $uc = new getEntityName(); ?>(); $this->assertEquals(, $uc->getLibxmlOpts()); $this->assertEquals(512, $uc->getJSONDecodeMaxDepth()); } - public function testValuedConstruct() + public function testCanConstructWithValidValues() { $uc = new getEntityName(); ?>(libxmlOpts: 123, jsonDecodeMaxDepth: 456); $this->assertEquals(123, $uc->getLibxmlOpts()); diff --git a/template/core/tests/encoding/test_class_xml_writer.php b/template/core/tests/encoding/test_class_xml_writer.php new file mode 100644 index 00000000..bd0470ab --- /dev/null +++ b/template/core/tests/encoding/test_class_xml_writer.php @@ -0,0 +1,143 @@ +getImports(); +$imports->addCoreFileImportsByName( + PHPFHIR_ENCODING_CLASSNAME_SERIALIZE_CONFIG, + PHPFHIR_ENCODING_CLASSNAME_XML_WRITER, +); + +$coreFiles = $config->getCoreFiles(); + +$xmlWriterClass = $coreFiles->getCoreFileByEntityName(PHPFHIR_ENCODING_CLASSNAME_XML_WRITER); +$serializeConfigClass = $coreFiles->getCoreFileByEntityName(PHPFHIR_ENCODING_CLASSNAME_SERIALIZE_CONFIG); + +ob_start(); +echo " +namespace getFullyQualifiedNamespace(false); ?>; + +getBasePHPFHIRCopyrightComment(false); ?> + + +use PHPUnit\Framework\TestCase; + +class extends TestCase +{ + public function testCanConstructWithDefaultConfig() + { + $sc = new getEntityName(); ?>(); + $xw = new getEntityName(); ?>($sc); + $this->assertFalse($xw->isOpen()); + $this->assertNull($xw->getWriteDestination()); + $this->assertFalse($xw->isDocStarted()); + $this->assertFalse($xw->isRootOpen()); + } + + public function testCanGetMemoryWriteDestination() + { + $sc = new getEntityName(); ?>(); + $xw = new getEntityName(); ?>($sc); + $this->assertTrue($xw->openMemory()); + $this->assertEquals('memory', $xw->getWriteDestination()); + } + + public function testCanGetUriWriteDestination() + { + $sc = new getEntityName(); ?>(); + $xw = new getEntityName(); ?>($sc); + $this->assertTrue($xw->openUri('php://memory')); + $this->assertEquals('php://memory', $xw->getWriteDestination()); + } + + public function testCannotOpenMemoryTwice() + { + $this->expectException(\LogicException::class); + $sc = new getEntityName(); ?>(); + $xw = new getEntityName(); ?>($sc); + $this->assertTrue($xw->openMemory()); + $xw->openMemory(); + } + + public function testCannotOpenUriTwice() + { + $this->expectException(\LogicException::class); + $sc = new getEntityName(); ?>(); + $xw = new getEntityName(); ?>($sc); + $this->assertTrue($xw->openUri('php://memory')); + $xw->openUri('php://memory'); + } + + public function testCannotOpenMixedTwice() + { + $this->expectException(\LogicException::class); + $sc = new getEntityName(); ?>(); + $xw = new getEntityName(); ?>($sc); + $this->assertTrue($xw->openMemory()); + $xw->openUri('php://memory'); + } + + public function testCanStartDocument() + { + $sc = new getEntityName(); ?>(); + $xw = new getEntityName(); ?>($sc); + $this->assertFalse($xw->isDocStarted()); + $this->assertTrue($xw->openMemory()); + $this->assertTrue($xw->startDocument()); + $this->assertTrue($xw->isDocStarted()); + } + + public function testCannotStartDocumentTwice() + { + $this->expectException(\LogicException::class); + $sc = new getEntityName(); ?>(); + $xw = new getEntityName(); ?>($sc); + $this->assertTrue($xw->openMemory()); + $this->assertTrue($xw->startDocument()); + $xw->startDocument(); + } + + public function testCanOpenRootNode() + { + $sc = new getEntityName(); ?>(); + $xw = new getEntityName(); ?>($sc); + $this->assertTrue($xw->openMemory()); + $this->assertTrue($xw->startDocument()); + $this->assertFalse($xw->isRootOpen()); + $this->assertTrue($xw->openRootNode('root', null)); + $this->assertTrue($xw->isRootOpen()); + } + + public function testCannotOpenRootNodeTwice() + { + $this->expectException(\LogicException::class); + $sc = new getEntityName(); ?>(); + $xw = new getEntityName(); ?>($sc); + $this->assertTrue($xw->openMemory()); + $this->assertTrue($xw->startDocument()); + $this->assertFalse($xw->isRootOpen()); + $this->assertTrue($xw->openRootNode('root', null)); + $this->assertTrue($xw->isRootOpen()); + $this->assertTrue($xw->openRootNode('root', null)); + } +} + extends TestCase { - public function testEmptyConstruct() + public function testCanConstructWithoutParams() { $vc = new getEntityName(); ?>(); $uc = $vc->getUnserializeConfig(); @@ -60,7 +60,7 @@ public function testEmptyConstruct() $this->assertEquals(, $sc->getXHTMLLibxmlOpts()); } - public function testArrayConstruct() + public function testCanConstructWithValidMapParams() { $vc = new getEntityName(); ?>( unserializeConfig: ['libxmlOpts' => 456, 'jsonDecodeMaxDepth' => 789], @@ -77,7 +77,7 @@ public function testArrayConstruct() $this->assertEquals(123, $sc->getXHTMLLibxmlOpts()); } - public function testValuedConstruct() + public function testCanConstructWithValidObjectParams() { $vc = new getEntityName(); ?>( unserializeConfig: new getEntityName(); ?>(), diff --git a/template/versions/types/class_default.php b/template/versions/types/class_default.php index 14c5b805..787435b2 100644 --- a/template/versions/types/class_default.php +++ b/template/versions/types/class_default.php @@ -31,7 +31,7 @@ // build file header echo require_with( - PHPFHIR_TEMPLATE_VERSION_TYPES_DIR . DIRECTORY_SEPARATOR . 'header.php', + PHPFHIR_TEMPLATE_VERSION_TYPES_DIR . '/header.php', [ 'version' => $version, 'type' => $type, @@ -99,7 +99,7 @@ // -- end field properties echo require_with( - PHPFHIR_TEMPLATE_VERSION_TYPES_METHODS_DIR . DIRECTORY_SEPARATOR . 'constructor.php', + PHPFHIR_TEMPLATE_VERSION_TYPES_METHODS_DIR . '/constructor.php', [ 'version' => $version, 'type' => $type, @@ -134,7 +134,7 @@ public function _getResourceType(): string if ($type->getKind()->isOneOf(TypeKindEnum::PRIMITIVE, TypeKindEnum::LIST)) : echo require_with( - PHPFHIR_TEMPLATE_VERSION_TYPES_PROPERTIES_DIR . DIRECTORY_SEPARATOR . 'methods' . DIRECTORY_SEPARATOR . 'primitive.php', + PHPFHIR_TEMPLATE_VERSION_TYPES_PROPERTIES_DIR . '/methods/primitive.php', [ 'version' => $version, 'type' => $type @@ -142,7 +142,7 @@ public function _getResourceType(): string ); else : echo require_with( - PHPFHIR_TEMPLATE_VERSION_TYPES_PROPERTIES_DIR . DIRECTORY_SEPARATOR . 'methods' . DIRECTORY_SEPARATOR . 'default.php', + PHPFHIR_TEMPLATE_VERSION_TYPES_PROPERTIES_DIR . '/methods/default.php', [ 'version' => $version, 'type' => $type, @@ -157,7 +157,7 @@ public function _getResourceType(): string echo "\n"; echo require_with( - PHPFHIR_TEMPLATE_VERSION_TYPES_VALIDATION_DIR . DIRECTORY_SEPARATOR . 'methods.php', + PHPFHIR_TEMPLATE_VERSION_TYPES_VALIDATION_DIR . '/methods.php', [ 'version' => $version, 'type' => $type, @@ -169,7 +169,7 @@ public function _getResourceType(): string echo "\n"; echo require_with( - PHPFHIR_TEMPLATE_VERSION_TYPES_SERIALIZATION_DIR . DIRECTORY_SEPARATOR . 'xml.php', + PHPFHIR_TEMPLATE_VERSION_TYPES_SERIALIZATION_DIR . '/xml.php', [ 'version' => $version, 'type' => $type, @@ -179,7 +179,7 @@ public function _getResourceType(): string echo "\n"; echo require_with( - PHPFHIR_TEMPLATE_VERSION_TYPES_SERIALIZATION_DIR . DIRECTORY_SEPARATOR . 'json.php', + PHPFHIR_TEMPLATE_VERSION_TYPES_SERIALIZATION_DIR . '/json.php', [ 'version' => $version, 'type' => $type, diff --git a/template/versions/types/class_resource_container.php b/template/versions/types/class_resource_container.php index e10d68de..b1439c21 100644 --- a/template/versions/types/class_resource_container.php +++ b/template/versions/types/class_resource_container.php @@ -38,7 +38,7 @@ // build file header echo require_with( - PHPFHIR_TEMPLATE_VERSION_TYPES_DIR . DIRECTORY_SEPARATOR . 'header.php', + PHPFHIR_TEMPLATE_VERSION_TYPES_DIR . '/header.php', [ 'version' => $version, 'type' => $type, @@ -107,7 +107,7 @@ public function setContainedType(null| $version, 'type' => $type, @@ -165,7 +165,7 @@ public function xmlSerialize(null| $version, 'type' => $type, diff --git a/template/versions/types/class_xhtml.php b/template/versions/types/class_xhtml.php index 74867a90..e7551b2c 100644 --- a/template/versions/types/class_xhtml.php +++ b/template/versions/types/class_xhtml.php @@ -34,7 +34,7 @@ // build file header echo require_with( - PHPFHIR_TEMPLATE_VERSION_TYPES_DIR . DIRECTORY_SEPARATOR . 'header.php', + PHPFHIR_TEMPLATE_VERSION_TYPES_DIR . '/header.php', [ 'version' => $version, 'type' => $type, @@ -148,7 +148,7 @@ public function getXMLReader(int $libxmlOpts): null|\XMLReader $version, 'type' => $type, @@ -159,32 +159,15 @@ public function getXMLReader(int $libxmlOpts): null|\XMLReader return $type; } - /** - * @param null|getFullyQualifiedName(true); ?> $xw - * @param null|getFullyQualifiedName(true); ?> $config - * @return getFullyQualifiedName(true); ?> - - */ - public function xmlSerialize(null| $xw = null, null| $config = null): - - { - if (null === $xw) { - $xw = new (); - } - if (!$xw->isOpen()) { - $xw->openMemory(); - } - if (!$xw->isDocStarted()) { - $docStarted = true; - $xw->startDocument(); - } - if (null === $config) { - $config = (new ())->getConfig()->getSerializeConfig(); - } - if (!$xw->isRootOpen()) { - $rootOpened = true; - $xw->openRootNode($config, 'XHTML', $this->_getSourceXMLNS()); - } + $version, + 'type' => $type, + ] +); +?> $xr = $this->getXMLReader($config->getXHTMLLibxmlOpts()); if (null === $xr) { return $xw; @@ -203,13 +186,7 @@ public function xmlSerialize(null| $version, 'type' => $type, diff --git a/template/versions/types/methods/constructor.php b/template/versions/types/methods/constructor.php index 126cdd9f..1500d807 100644 --- a/template/versions/types/methods/constructor.php +++ b/template/versions/types/methods/constructor.php @@ -105,7 +105,7 @@ public function __construct(getAllPropertiesIndexedIterator continue; } echo require_with( - PHPFHIR_TEMPLATE_VERSION_TYPES_CONSTRUCTORS_DIR . DIRECTORY_SEPARATOR . 'default_property_setter_call.php', + PHPFHIR_TEMPLATE_VERSION_TYPES_CONSTRUCTORS_DIR . '/default_property_setter_call.php', [ 'type' => $type, 'property' => $property diff --git a/template/versions/types/properties/methods/primitive.php b/template/versions/types/properties/methods/primitive.php index b4ad1f94..d65ae729 100644 --- a/template/versions/types/properties/methods/primitive.php +++ b/template/versions/types/properties/methods/primitive.php @@ -50,11 +50,11 @@ public function getValue(): $version, 'type' => $type, @@ -42,13 +36,7 @@ echo "\n"; echo require_with( - PHPFHIR_TEMPLATE_VERSION_TYPES_SERIALIZATION_DIR - . DIRECTORY_SEPARATOR - . 'json' - . DIRECTORY_SEPARATOR - . 'unserialize' - . DIRECTORY_SEPARATOR - . 'body.php', + PHPFHIR_TEMPLATE_VERSION_TYPES_SERIALIZATION_DIR . '/json/unserialize/body.php', [ 'version' => $version, 'type' => $type, @@ -59,13 +47,7 @@ if ($typeKind->isOneOf(TypeKindEnum::PRIMITIVE, TypeKindEnum::LIST)) : echo require_with( - PHPFHIR_TEMPLATE_VERSION_TYPES_SERIALIZATION_DIR - . DIRECTORY_SEPARATOR - . 'json' - . DIRECTORY_SEPARATOR - . 'serialize' - . DIRECTORY_SEPARATOR - . 'primitive.php', + PHPFHIR_TEMPLATE_VERSION_TYPES_SERIALIZATION_DIR . '/json/serialize/primitive.php', [ 'version' => $version, 'type' => $type, @@ -73,13 +55,7 @@ ); else: echo require_with( - PHPFHIR_TEMPLATE_VERSION_TYPES_SERIALIZATION_DIR - . DIRECTORY_SEPARATOR - . 'json' - . DIRECTORY_SEPARATOR - . 'serialize' - . DIRECTORY_SEPARATOR - . 'default.php', + PHPFHIR_TEMPLATE_VERSION_TYPES_SERIALIZATION_DIR . '/json/serialize/default.php', [ 'version' => $version, 'type' => $type, diff --git a/template/versions/types/serialization/xml.php b/template/versions/types/serialization/xml.php index bb88cb48..fa5742d9 100644 --- a/template/versions/types/serialization/xml.php +++ b/template/versions/types/serialization/xml.php @@ -25,7 +25,7 @@ // unserialize portion echo require_with( - PHPFHIR_TEMPLATE_VERSION_TYPES_SERIALIZATION_DIR . DIRECTORY_SEPARATOR . 'xml' . DIRECTORY_SEPARATOR . 'unserialize' . DIRECTORY_SEPARATOR . 'header.php', + PHPFHIR_TEMPLATE_VERSION_TYPES_SERIALIZATION_DIR . '/xml/unserialize/header.php', [ 'version' => $version, 'type' => $type, @@ -34,7 +34,7 @@ if (count($type->getAllPropertiesIndexedIterator()) > 0) : echo require_with( - PHPFHIR_TEMPLATE_VERSION_TYPES_SERIALIZATION_DIR . DIRECTORY_SEPARATOR . 'xml' . DIRECTORY_SEPARATOR . 'unserialize' . DIRECTORY_SEPARATOR . 'body.php', + PHPFHIR_TEMPLATE_VERSION_TYPES_SERIALIZATION_DIR . '/xml/unserialize/body.php', [ 'version' => $version, 'type' => $type, @@ -48,7 +48,7 @@ $version, 'type' => $type, @@ -57,7 +57,7 @@ if ($type->hasLocalProperties()) { echo require_with( - PHPFHIR_TEMPLATE_VERSION_TYPES_SERIALIZATION_DIR . DIRECTORY_SEPARATOR . 'xml' . DIRECTORY_SEPARATOR . 'serialize' . DIRECTORY_SEPARATOR . 'body.php', + PHPFHIR_TEMPLATE_VERSION_TYPES_SERIALIZATION_DIR . '/xml/serialize/body.php', [ 'version' => $version, 'type' => $type, diff --git a/template/versions/types/serialization/xml/serialize/header.php b/template/versions/types/serialization/xml/serialize/header.php index b0d062cb..273cb1f7 100644 --- a/template/versions/types/serialization/xml/serialize/header.php +++ b/template/versions/types/serialization/xml/serialize/header.php @@ -37,8 +37,11 @@ public function xmlSerialize(null| $xw = null, null| $config = null): { + if (null === $config) { + $config = (new ())->getConfig()->getSerializeConfig(); + } if (null === $xw) { - $xw = new (); + $xw = new ($config); } if (!$xw->isOpen()) { $xw->openMemory(); @@ -47,11 +50,8 @@ public function xmlSerialize(null|startDocument(); } - if (null === $config) { - $config = (new ())->getConfig()->getSerializeConfig(); - } if (!$xw->isRootOpen()) { $rootOpened = true; - $xw->openRootNode($config, '', $this->_getSourceXMLNS()); + $xw->openRootNode('', $this->_getSourceXMLNS()); }