Skip to content

Commit

Permalink
xmlwriter improvements and some tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dcarbone committed Jan 16, 2025
1 parent 33234b8 commit 983583e
Show file tree
Hide file tree
Showing 15 changed files with 230 additions and 120 deletions.
1 change: 1 addition & 0 deletions files/constants.php
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
28 changes: 17 additions & 11 deletions files/funcs.php
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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;
}

/**
Expand All @@ -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,",
Expand Down
23 changes: 16 additions & 7 deletions template/core/encoding/class_xml_writer.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,21 @@ final class <?php echo PHPFHIR_ENCODING_CLASSNAME_XML_WRITER; ?> extends \XMLWri
{
private const _MEM = 'memory';

/** @var bool */
private <?php echo $serializeConfigClass->getEntityName(); ?> $_config;
private bool $_docStarted = false;
/** @var bool */
private bool $_rootOpen = false;
/** @var null|string */
private null|string $_open = null;

/**
* <?php echo $coreFile->getEntityName(); ?> constructor.
*
* @param <?php echo $serializeConfigClass->getFullyQualifiedName(true); ?> $config
*/
public function __construct(<?php echo $serializeConfigClass->getEntityName(); ?> $config)
{
$this->_config = $config;
}

/**
* @see https://www.php.net/manual/en/xmlwriter.openmemory.php
*
Expand Down Expand Up @@ -132,23 +140,24 @@ public function isRootOpen(): bool
}

/**
* @param <?php echo $serializeConfigClass->getFullyQualifiedName(true); ?> $config
* @param string $name
* @param string|null $sourceXMLNS
* @return bool
*/
public function openRootNode(<?php echo PHPFHIR_ENCODING_CLASSNAME_SERIALIZE_CONFIG; ?> $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;
}
Expand Down
5 changes: 2 additions & 3 deletions template/core/tests/encoding/test_class_serialize_config.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
* limitations under the License.
*/


use DCarbone\PHPFHIR\Utilities\ImportUtils;

/** @var \DCarbone\PHPFHIR\Config $config */
Expand All @@ -43,15 +42,15 @@

class <?php echo PHPFHIR_TEST_ENCODING_CLASSNAME_SERIALIZE_CONFIG; ?> extends TestCase
{
public function testEmptyConstruct()
public function testCanConstructWithoutParams()
{
$sc = new <?php echo $serializeConfigClass->getEntityName(); ?>();
$this->assertFalse($sc->getOverrideSourceXMLNS());
$this->assertNull($sc->getRootXMLNS());
$this->assertEquals(<?php echo PHPFHIR_DEFAULT_LIBXML_OPTS ?>, $sc->getXHTMLLibxmlOpts());
}

public function testValuedConstruct()
public function testCanConstructWithValidValues()
{
$sc = new <?php echo $serializeConfigClass->getEntityName(); ?>(overrideSourceXMLNS: true, rootXMLNS: 'urn:foo:bar', xhtmlLibxmlOpts: 123);
$this->assertTrue($sc->getOverrideSourceXMLNS());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
* limitations under the License.
*/


use DCarbone\PHPFHIR\Utilities\ImportUtils;

/** @var \DCarbone\PHPFHIR\Config $config */
Expand All @@ -42,14 +41,14 @@

class <?php echo PHPFHIR_TEST_ENCODING_CLASSNAME_UNSERIALIZE_CONFIG; ?> extends TestCase
{
public function testEmptyConstruct()
public function testCanConstructWithoutParams()
{
$uc = new <?php echo $unserializeConfigClass->getEntityName(); ?>();
$this->assertEquals(<?php echo PHPFHIR_DEFAULT_LIBXML_OPTS; ?>, $uc->getLibxmlOpts());
$this->assertEquals(512, $uc->getJSONDecodeMaxDepth());
}

public function testValuedConstruct()
public function testCanConstructWithValidValues()
{
$uc = new <?php echo $unserializeConfigClass->getEntityName(); ?>(libxmlOpts: 123, jsonDecodeMaxDepth: 456);
$this->assertEquals(123, $uc->getLibxmlOpts());
Expand Down
143 changes: 143 additions & 0 deletions template/core/tests/encoding/test_class_xml_writer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
<?php declare(strict_types=1);

/*
* Copyright 2025 Daniel Carbone ([email protected])
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

use DCarbone\PHPFHIR\Utilities\ImportUtils;

/** @var \DCarbone\PHPFHIR\Config $config */
/** @var \DCarbone\PHPFHIR\CoreFile $coreFile */

$imports = $coreFile->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 "<?php\n\n";?>
namespace <?php echo $coreFile->getFullyQualifiedNamespace(false); ?>;

<?php echo $config->getBasePHPFHIRCopyrightComment(false); ?>

<?php echo ImportUtils::compileImportStatements($imports); ?>
use PHPUnit\Framework\TestCase;

class <?php echo PHPFHIR_TEST_ENCODING_CLASSSNAME_XML_WRITER; ?> extends TestCase
{
public function testCanConstructWithDefaultConfig()
{
$sc = new <?php echo $serializeConfigClass->getEntityName(); ?>();
$xw = new <?php echo $xmlWriterClass->getEntityName(); ?>($sc);
$this->assertFalse($xw->isOpen());
$this->assertNull($xw->getWriteDestination());
$this->assertFalse($xw->isDocStarted());
$this->assertFalse($xw->isRootOpen());
}

public function testCanGetMemoryWriteDestination()
{
$sc = new <?php echo $serializeConfigClass->getEntityName(); ?>();
$xw = new <?php echo $xmlWriterClass->getEntityName(); ?>($sc);
$this->assertTrue($xw->openMemory());
$this->assertEquals('memory', $xw->getWriteDestination());
}

public function testCanGetUriWriteDestination()
{
$sc = new <?php echo $serializeConfigClass->getEntityName(); ?>();
$xw = new <?php echo $xmlWriterClass->getEntityName(); ?>($sc);
$this->assertTrue($xw->openUri('php://memory'));
$this->assertEquals('php://memory', $xw->getWriteDestination());
}

public function testCannotOpenMemoryTwice()
{
$this->expectException(\LogicException::class);
$sc = new <?php echo $serializeConfigClass->getEntityName(); ?>();
$xw = new <?php echo $xmlWriterClass->getEntityName(); ?>($sc);
$this->assertTrue($xw->openMemory());
$xw->openMemory();
}

public function testCannotOpenUriTwice()
{
$this->expectException(\LogicException::class);
$sc = new <?php echo $serializeConfigClass->getEntityName(); ?>();
$xw = new <?php echo $xmlWriterClass->getEntityName(); ?>($sc);
$this->assertTrue($xw->openUri('php://memory'));
$xw->openUri('php://memory');
}

public function testCannotOpenMixedTwice()
{
$this->expectException(\LogicException::class);
$sc = new <?php echo $serializeConfigClass->getEntityName(); ?>();
$xw = new <?php echo $xmlWriterClass->getEntityName(); ?>($sc);
$this->assertTrue($xw->openMemory());
$xw->openUri('php://memory');
}

public function testCanStartDocument()
{
$sc = new <?php echo $serializeConfigClass->getEntityName(); ?>();
$xw = new <?php echo $xmlWriterClass->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 <?php echo $serializeConfigClass->getEntityName(); ?>();
$xw = new <?php echo $xmlWriterClass->getEntityName(); ?>($sc);
$this->assertTrue($xw->openMemory());
$this->assertTrue($xw->startDocument());
$xw->startDocument();
}

public function testCanOpenRootNode()
{
$sc = new <?php echo $serializeConfigClass->getEntityName(); ?>();
$xw = new <?php echo $xmlWriterClass->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 <?php echo $serializeConfigClass->getEntityName(); ?>();
$xw = new <?php echo $xmlWriterClass->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));
}
}
<?php return ob_get_clean();
6 changes: 3 additions & 3 deletions template/core/tests/test_class_version_config.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@

class <?php echo PHPFHIR_TEST_CLASSNAME_VERSION_CONFIG; ?> extends TestCase
{
public function testEmptyConstruct()
public function testCanConstructWithoutParams()
{
$vc = new <?php echo $versionConfigClass->getEntityName(); ?>();
$uc = $vc->getUnserializeConfig();
Expand All @@ -60,7 +60,7 @@ public function testEmptyConstruct()
$this->assertEquals(<?php echo PHPFHIR_DEFAULT_LIBXML_OPTS; ?>, $sc->getXHTMLLibxmlOpts());
}

public function testArrayConstruct()
public function testCanConstructWithValidMapParams()
{
$vc = new <?php echo $versionConfigClass->getEntityName(); ?>(
unserializeConfig: ['libxmlOpts' => 456, 'jsonDecodeMaxDepth' => 789],
Expand All @@ -77,7 +77,7 @@ public function testArrayConstruct()
$this->assertEquals(123, $sc->getXHTMLLibxmlOpts());
}

public function testValuedConstruct()
public function testCanConstructWithValidObjectParams()
{
$vc = new <?php echo $versionConfigClass->getEntityName(); ?>(
unserializeConfig: new <?php echo $unserializeConfigClass->getEntityName(); ?>(),
Expand Down
14 changes: 7 additions & 7 deletions template/versions/types/class_default.php
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -134,15 +134,15 @@ 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
]
);
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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand Down
Loading

0 comments on commit 983583e

Please sign in to comment.