Skip to content

Commit

Permalink
Improve handling of boolean and null values in xpath methods (#88)
Browse files Browse the repository at this point in the history
* increase xpath support

* use single quote
  • Loading branch information
pamoller committed Aug 22, 2022
1 parent 2535889 commit 57b35f9
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 11 deletions.
24 changes: 23 additions & 1 deletion src/Codeception/Util/JsonArray.php
Expand Up @@ -121,11 +121,33 @@ private function arrayToXml(DOMDocument $doc, DOMNode $node, array $array): void
if (is_array($value)) {
$this->arrayToXml($doc, $subNode, $value);
} else {
$subNode->nodeValue = htmlspecialchars((string)$value);
$this->setValue($subNode, $value);
}
}
}

private function setValue($subNode, $value) {
switch(gettype($value)) {
case 'boolean':
$subNode->nodeValue = $value?'true':'false';
$subNode->setAttribute('type', 'boolean');
break;
case 'integer':
case 'double':
$subNode->nodeValue = (string) $value;
$subNode->setAttribute('type', 'number');
break;
case 'NULL':
$subNode->nodeValue = '';
$subNode->setAttribute('type', 'null');
break;
default:
$subNode->nodeValue = htmlspecialchars((string) $value);
$subNode->setAttribute('type', 'string');
break;
}
}

private function getValidTagNameForInvalidKey($key)
{
static $map = [];
Expand Down
36 changes: 26 additions & 10 deletions tests/unit/Codeception/Util/JsonArrayTest.php
Expand Up @@ -21,7 +21,7 @@ protected function _before()
public function testXmlConversion()
{
$this->assertStringContainsString(
'<ticket><title>Bug should be fixed</title><user><name>Davert</name></user><labels></labels></ticket>',
'<ticket><title type="string">Bug should be fixed</title><user><name type="string">Davert</name></user><labels type="null"></labels></ticket>',
$this->jsonArray->toXml()->saveXML()
);
}
Expand All @@ -32,17 +32,33 @@ public function testXmlArrayConversion2()
'[{"user":"Blacknoir","age":27,"tags":["wed-dev","php"]},'
. '{"user":"John Doe","age":27,"tags":["web-dev","java"]}]'
);
$this->assertStringContainsString('<tags>wed-dev</tags>', $jsonArray->toXml()->saveXML());
$this->assertStringContainsString('<tags type="string">wed-dev</tags>', $jsonArray->toXml()->saveXML());
$this->assertSame(2, $jsonArray->filterByXPath('//user')->length);
}

public function testXPathEvaluation()
{
$this->assertSame(true, $this->jsonArray->evaluateXPath('count(//ticket/title)>0'));
$this->assertEquals(1.0 , $this->jsonArray->evaluateXPath('count(//ticket/user/name)'));
$this->assertSame(true, $this->jsonArray->evaluateXPath("count(//user/name[text() = 'Davert']) > 0"));
$this->assertTrue($this->jsonArray->evaluateXPath('count(//ticket/title)>0'));
$this->assertEquals(1, $this->jsonArray->evaluateXPath('count(//ticket/user/name)'));
$this->assertTrue($this->jsonArray->evaluateXPath("count(//user/name[text() = 'Davert']) > 0"));
}

public function testXPathTypes()
{
$jsonArray = new JsonArray(
'{"boolean":true, "number": -1.2780E+2, "null": null, "string": "i\'am a sentence"}'
);
$this->assertEquals(0, $jsonArray->evaluateXPath("count(//*[text() = 'false'])"));
$this->assertEquals(1, $jsonArray->evaluateXPath("count(//boolean[text() = 'true'])"));
$this->assertEquals(1, $jsonArray->evaluateXPath("count(//boolean[@type = 'boolean'])"));
$this->assertEquals(1, $jsonArray->evaluateXPath("count(//number[text() = -127.80])"));
$this->assertEquals(1, $jsonArray->evaluateXPath("count(//number[text() = -1.2780E+2])"));
$this->assertEquals(1, $jsonArray->evaluateXPath("count(//number[@type = 'number'])"));
$this->assertEquals(1, $jsonArray->evaluateXPath("count(//null[@type = 'null'])"));
$this->assertEquals(1, $jsonArray->evaluateXPath("count(//null[text() = ''])"));
$this->assertEquals(1, $jsonArray->evaluateXPath("count(//string[@type = 'string'])"));
}

public function testXPathLocation()
{
$this->assertGreaterThan(0, $this->jsonArray->filterByXPath('//ticket/title')->length);
Expand Down Expand Up @@ -83,32 +99,32 @@ public function testConvertsBareJson()
public function testInvalidXmlTag()
{
$jsonArray = new JsonArray('{"a":{"foo/bar":1,"":2},"b":{"foo/bar":1,"":2},"baz":2}');
$expectedXml = '<a><invalidTag1>1</invalidTag1><invalidTag2>2</invalidTag2></a>'
. '<b><invalidTag1>1</invalidTag1><invalidTag2>2</invalidTag2></b><baz>2</baz>';
$expectedXml = '<a><invalidTag1 type="number">1</invalidTag1><invalidTag2 type="number">2</invalidTag2></a>'
. '<b><invalidTag1 type="number">1</invalidTag1><invalidTag2 type="number">2</invalidTag2></b><baz type="number">2</baz>';
$this->assertStringContainsString($expectedXml, $jsonArray->toXml()->saveXML());
}

public function testConvertsArrayHavingSingleElement()
{
$jsonArray = new JsonArray('{"success": 1}');
$expectedXml = '<?xml version="1.0" encoding="UTF-8"?>'
. "\n<root><success>1</success></root>\n";
. "\n<root><success type=\"number\">1</success></root>\n";
$this->assertSame($expectedXml, $jsonArray->toXml()->saveXML());
}

public function testConvertsArrayHavingTwoElements()
{
$jsonArray = new JsonArray('{"success": 1, "info": "test"}');
$expectedXml = '<?xml version="1.0" encoding="UTF-8"?>'
. "\n<root><success>1</success><info>test</info></root>\n";
. "\n<root><success type=\"number\">1</success><info type=\"string\">test</info></root>\n";
$this->assertSame($expectedXml, $jsonArray->toXml()->saveXML());
}

public function testConvertsArrayHavingSingleSubArray()
{
$jsonArray = new JsonArray('{"array": {"success": 1}}');
$expectedXml = '<?xml version="1.0" encoding="UTF-8"?>'
. "\n<array><success>1</success></array>\n";
. "\n<array><success type=\"number\">1</success></array>\n";
$this->assertSame($expectedXml, $jsonArray->toXml()->saveXML());
}
}

0 comments on commit 57b35f9

Please sign in to comment.