|
2 | 2 |
|
3 | 3 | namespace LaLit; |
4 | 4 |
|
| 5 | +define('XML_CONTENT', 'XmlContent'); |
| 6 | +define('PHP_CONTENT', 'PhpContent'); |
| 7 | +define('RESULTS_KEY', 'ResultsKey'); |
| 8 | +define('ATTRIBUTE_CONTENT', 'AttributeContent'); |
| 9 | +define('VALUE_CONTENT', 'ValueContent'); |
| 10 | +define('CDATA_CONTENT', 'CDataContent'); |
| 11 | +define('ARRAY_TO_XML_ONLY', 'Array2XMLOnly'); |
| 12 | +define('VALID_TEST_FOR', 'ValidTestFor'); |
| 13 | +define('ALL_TESTS', 'AllTests'); |
| 14 | + |
5 | 15 | class MainLaLitTest extends \PHPUnit\Framework\TestCase |
6 | 16 | { |
| 17 | + /** |
| 18 | + * @param string|string[] $tags |
| 19 | + * |
| 20 | + * @return array |
| 21 | + */ |
| 22 | + private function generateTags($tags) |
| 23 | + { |
| 24 | + if (is_array($tags)) { |
| 25 | + $tag = array_shift($tags); |
| 26 | + } else { |
| 27 | + $tag = $tags; |
| 28 | + } |
| 29 | + |
| 30 | + // Base attribute set. |
| 31 | + $attributeSet = [ |
| 32 | + 'No attributes' => [ |
| 33 | + XML_CONTENT => '', |
| 34 | + ], |
| 35 | + 'Empty attribute' => [ |
| 36 | + XML_CONTENT => ' attribute1=""', |
| 37 | + PHP_CONTENT => [ |
| 38 | + '@attributes' => [ |
| 39 | + 'attribute1' => '', |
| 40 | + ], |
| 41 | + ], |
| 42 | + ], |
| 43 | + 'Encoded attribute' => [ |
| 44 | + XML_CONTENT => ' attribute2="<important>"', |
| 45 | + PHP_CONTENT => [ |
| 46 | + '@attributes' => [ |
| 47 | + 'attribute2' => '<important>', |
| 48 | + ], |
| 49 | + ], |
| 50 | + ], |
| 51 | + 'Simple attribute' => [ |
| 52 | + XML_CONTENT => ' attribute3="1"', |
| 53 | + PHP_CONTENT => [ |
| 54 | + '@attributes' => [ |
| 55 | + 'attribute3' => '1', |
| 56 | + ], |
| 57 | + ], |
| 58 | + ], |
| 59 | + 'Quoted and encoded attribute' => [ |
| 60 | + XML_CONTENT => ' attribute4="\'<important>\'"', |
| 61 | + PHP_CONTENT => [ |
| 62 | + '@attributes' => [ |
| 63 | + 'attribute4' => '\'<important>\'', |
| 64 | + ], |
| 65 | + ], |
| 66 | + ], |
| 67 | + 'Empty quoted attribute' => [ |
| 68 | + XML_CONTENT => ' attribute5="\'\'"', |
| 69 | + PHP_CONTENT => [ |
| 70 | + '@attributes' => [ |
| 71 | + 'attribute5' => '\'\'', |
| 72 | + ], |
| 73 | + ], |
| 74 | + ], |
| 75 | + 'Null attribute' => [ |
| 76 | + XML_CONTENT => ' attribute6=""', |
| 77 | + PHP_CONTENT => [ |
| 78 | + '@attributes' => [ |
| 79 | + 'attribute6' => null, // A null in PHP will become an empty value in XML. |
| 80 | + ], |
| 81 | + ], |
| 82 | + VALID_TEST_FOR => ARRAY_TO_XML_ONLY, |
| 83 | + ], |
| 84 | + 'All attributes' => [ |
| 85 | + XML_CONTENT => ' attribute1="" attribute2="<important>" attribute3="1" attribute4="\'<important>\'" attribute5="\'\'" attribute6=""', |
| 86 | + PHP_CONTENT => [ |
| 87 | + '@attributes' => [ |
| 88 | + 'attribute1' => '', |
| 89 | + 'attribute2' => '<important>', |
| 90 | + 'attribute3' => '1', |
| 91 | + 'attribute4' => '\'<important>\'', |
| 92 | + 'attribute5' => '\'\'', |
| 93 | + 'attribute6' => null, // A null in PHP will become an empty value in XML. |
| 94 | + ], |
| 95 | + ], |
| 96 | + VALID_TEST_FOR => ARRAY_TO_XML_ONLY, |
| 97 | + ], |
| 98 | + 'All attributes without null attribute' => [ |
| 99 | + XML_CONTENT => ' attribute1="" attribute2="<important>" attribute3="1" attribute4="\'<important>\'" attribute5="\'\'"', |
| 100 | + PHP_CONTENT => [ |
| 101 | + '@attributes' => [ |
| 102 | + 'attribute1' => '', |
| 103 | + 'attribute2' => '<important>', |
| 104 | + 'attribute3' => '1', |
| 105 | + 'attribute4' => '\'<important>\'', |
| 106 | + 'attribute5' => '\'\'', |
| 107 | + ], |
| 108 | + ], |
| 109 | + ], |
| 110 | + ]; |
| 111 | + |
| 112 | + // Base value set. |
| 113 | + $valueSet = [ |
| 114 | + 'Null value' => [ |
| 115 | + XML_CONTENT => '', |
| 116 | + PHP_CONTENT => [ |
| 117 | + '@value' => null, |
| 118 | + ], // A null in PHP will become an empty value in XML. |
| 119 | + ARRAY_TO_XML_ONLY => true, |
| 120 | + ], |
| 121 | + 'Empty value' => [ |
| 122 | + XML_CONTENT => '', |
| 123 | + PHP_CONTENT => [ |
| 124 | + '@value' => '', |
| 125 | + ], |
| 126 | + ], |
| 127 | + 'Zero' => [ |
| 128 | + XML_CONTENT => 0, |
| 129 | + PHP_CONTENT => [ |
| 130 | + '@value' => '0', |
| 131 | + ], |
| 132 | + ], |
| 133 | + 'Simple value' => [ |
| 134 | + XML_CONTENT => 'normal', |
| 135 | + PHP_CONTENT => [ |
| 136 | + '@value' => 'normal', |
| 137 | + ], |
| 138 | + ], |
| 139 | + 'Encoded value' => [ |
| 140 | + XML_CONTENT => '<escaped>', |
| 141 | + PHP_CONTENT => [ |
| 142 | + '@value' => '<escaped>', |
| 143 | + ], |
| 144 | + ], |
| 145 | + 'Empty CDATA' => [ |
| 146 | + XML_CONTENT => '<![CDATA[]]>', |
| 147 | + PHP_CONTENT => [ |
| 148 | + '@cdata' => '', |
| 149 | + ], |
| 150 | + ], |
| 151 | + 'CDATA with tagged value' => [ |
| 152 | + XML_CONTENT => '<![CDATA[<very_important>]]>', |
| 153 | + PHP_CONTENT => [ |
| 154 | + '@cdata' => '<very_important>', |
| 155 | + ], |
| 156 | + ], |
| 157 | + ]; |
| 158 | + |
| 159 | + // If we have an array of tags, then generate the value for each tag and it to the value set. |
| 160 | + if (is_array($tags) && count($tags) > 0) { |
| 161 | + $valueSet = array_merge($valueSet, $this->generateTags($tags)); |
| 162 | + } |
| 163 | + |
| 164 | + // Build a result set. |
| 165 | + $results = []; |
| 166 | + |
| 167 | + // Iterate the attribute and value sets. |
| 168 | + foreach ($attributeSet as $attributeType => $attribute) { |
| 169 | + foreach ($valueSet as $valueType => $value) { |
| 170 | + |
| 171 | + $tagName = is_array($tag) ? $tag[0] : $tag; |
| 172 | + $phpContent = array_merge( |
| 173 | + array_key_exists(PHP_CONTENT, $attribute) ? $attribute[PHP_CONTENT] : [], |
| 174 | + array_key_exists(PHP_CONTENT, $value) ? $value[PHP_CONTENT] : [] |
| 175 | + ) ?: ''; |
| 176 | + if (!array_key_exists('@attributes', $phpContent) && array_key_exists('@value', $phpContent)) { |
| 177 | + $phpContent = $value[PHP_CONTENT]['@value']; |
| 178 | + } |
| 179 | + $xmlContent = "<{$tagName}{$attribute[XML_CONTENT]}>{$value[XML_CONTENT]}</{$tagName}>"; |
| 180 | + |
| 181 | + // If the tag is not an array, then it is a single tag, |
| 182 | + // build the expected XML and PHP for XML2Array and Array2XML. |
| 183 | + if (!is_array($tag)) { |
| 184 | + $resultsKey = $attributeType.' - '.$valueType; |
| 185 | + $results[$resultsKey][XML_CONTENT] = $xmlContent; |
| 186 | + $results[$resultsKey][PHP_CONTENT][$tagName] = $phpContent; |
| 187 | + } else { |
| 188 | + $resultsKey = $attributeType.' - '.$valueType.' with '.$tag[1].' nodes'; |
| 189 | + // As the tag is an array, the first element is the tag name, and the second is a count. |
| 190 | + // Iterate the count, building a collection of nodes. |
| 191 | + $results[$resultsKey][XML_CONTENT] = ''; |
| 192 | + $results[$resultsKey][PHP_CONTENT][$tag[0]] = []; |
| 193 | + foreach (range(1, $tag[1]) as $repeat) { |
| 194 | + $results[$resultsKey][XML_CONTENT] .= $xmlContent; |
| 195 | + $results[$resultsKey][PHP_CONTENT][$tagName][] = $phpContent; |
| 196 | + } |
| 197 | + } |
| 198 | + $results[$resultsKey][RESULTS_KEY] = $resultsKey; |
| 199 | + $results[$resultsKey][VALID_TEST_FOR] = $results[$resultsKey][VALID_TEST_FOR] ?? ALL_TESTS; |
| 200 | + } |
| 201 | + } |
| 202 | + |
| 203 | + return $results; |
| 204 | + } |
| 205 | + |
7 | 206 | public function provideTestData() |
8 | 207 | { |
9 | | - return include __DIR__.'/files/testData.inc'; |
| 208 | + return array_merge( |
| 209 | + $this->generateTags(['root']), |
| 210 | + $this->generateTags(['root', 'node']), |
| 211 | + $this->generateTags(['root', ['node', 2]]), |
| 212 | + $this->generateTags(['root', 'collection', ['node', 2]]), |
| 213 | + $this->generateTags(['root', ['collections', 2], ['node', 2]]) |
| 214 | + ); |
10 | 215 | } |
11 | 216 |
|
12 | 217 | /** |
13 | 218 | * @dataProvider provideTestData |
14 | 219 | * |
15 | | - * @param string $php |
16 | 220 | * @param string $xml |
| 221 | + * @param string $php |
17 | 222 | * @param string $structure |
18 | 223 | */ |
19 | | - public function testArrayToXML($php, $xml, $structure) |
| 224 | + public function testArrayToXML($xml, $php, $structure, $validTestFor) |
20 | 225 | { |
21 | | - $actualResults = Array2XML::createXML('root', $php['root'])->saveXML(); |
22 | | - $expectedResults = $xml; |
| 226 | + $actualResults = preg_replace('`[\\n\\r]++ *`sim', '', Array2XML::createXML('root', $php['root'])->saveXML()); |
| 227 | + $expectedResults = '<?xml version="1.0" encoding="utf-8" standalone="no"?>'.$xml; |
23 | 228 |
|
24 | 229 | $this->assertEquals($expectedResults, $actualResults, $structure); |
25 | 230 | } |
26 | 231 |
|
27 | 232 | /** |
28 | 233 | * @dataProvider provideTestData |
29 | 234 | * |
| 235 | + * @param string $xml |
30 | 236 | * @param string $php |
31 | | - * @param string $xmlString |
32 | 237 | * @param string $structure |
| 238 | + * |
| 239 | + * @throws \Exception |
33 | 240 | */ |
34 | | - public function testXMLToArray($php, $xmlString, $structure) |
| 241 | + public function testXMLToArray($xml, $php, $structure, $validTestFor) |
35 | 242 | { |
36 | 243 | $xmlDOM = new \DOMDocument(1.0, 'UTF-8'); |
37 | 244 | $xmlDOM->xmlStandalone = false; |
38 | 245 | $xmlDOM->preserveWhiteSpace = false; |
39 | | - $xmlDOM->loadXML($xmlString); |
| 246 | + $xmlDOM->loadXML($xml); |
40 | 247 | $xmlDOM->formatOutput = true; |
41 | 248 |
|
42 | | - $xmlStringResults = XML2Array::createArray($xmlString); |
| 249 | + $xmlStringResults = XML2Array::createArray($xml); |
43 | 250 | $xmlDOMResults = XML2Array::createArray($xmlDOM); |
44 | 251 |
|
45 | 252 | $this->assertEquals($php, $xmlStringResults, $structure); |
|
0 commit comments