1<?php 2 3namespace Sabre\Xml; 4 5class WriterTest extends \PHPUnit_Framework_TestCase { 6 7 protected $writer; 8 9 function setUp() { 10 11 $this->writer = new Writer(); 12 $this->writer->namespaceMap = [ 13 'http://sabredav.org/ns' => 's', 14 ]; 15 $this->writer->openMemory(); 16 $this->writer->setIndent(true); 17 $this->writer->startDocument(); 18 19 } 20 21 function compare($input, $output) { 22 23 $this->writer->write($input); 24 $this->assertEquals($output, $this->writer->outputMemory()); 25 26 } 27 28 29 function testSimple() { 30 31 $this->compare([ 32 '{http://sabredav.org/ns}root' => 'text', 33 ], <<<HI 34<?xml version="1.0"?> 35<s:root xmlns:s="http://sabredav.org/ns">text</s:root> 36 37HI 38 ); 39 40 } 41 42 /** 43 * @depends testSimple 44 */ 45 function testSimpleQuotes() { 46 47 $this->compare([ 48 '{http://sabredav.org/ns}root' => '"text"', 49 ], <<<HI 50<?xml version="1.0"?> 51<s:root xmlns:s="http://sabredav.org/ns">"text"</s:root> 52 53HI 54 ); 55 56 } 57 58 function testSimpleAttributes() { 59 60 $this->compare([ 61 '{http://sabredav.org/ns}root' => [ 62 'value' => 'text', 63 'attributes' => [ 64 'attr1' => 'attribute value', 65 ], 66 ], 67 ], <<<HI 68<?xml version="1.0"?> 69<s:root xmlns:s="http://sabredav.org/ns" attr1="attribute value">text</s:root> 70 71HI 72 ); 73 74 } 75 function testMixedSyntax() { 76 $this->compare([ 77 '{http://sabredav.org/ns}root' => [ 78 '{http://sabredav.org/ns}single' => 'value', 79 '{http://sabredav.org/ns}multiple' => [ 80 [ 81 'name' => '{http://sabredav.org/ns}foo', 82 'value' => 'bar', 83 ], 84 [ 85 'name' => '{http://sabredav.org/ns}foo', 86 'value' => 'foobar', 87 ], 88 ], 89 [ 90 'name' => '{http://sabredav.org/ns}attributes', 91 'value' => null, 92 'attributes' => [ 93 'foo' => 'bar', 94 ], 95 ], 96 [ 97 'name' => '{http://sabredav.org/ns}verbose', 98 'value' => 'syntax', 99 'attributes' => [ 100 'foo' => 'bar', 101 ], 102 ], 103 ], 104 ], <<<HI 105<?xml version="1.0"?> 106<s:root xmlns:s="http://sabredav.org/ns"> 107 <s:single>value</s:single> 108 <s:multiple> 109 <s:foo>bar</s:foo> 110 <s:foo>foobar</s:foo> 111 </s:multiple> 112 <s:attributes foo="bar"/> 113 <s:verbose foo="bar">syntax</s:verbose> 114</s:root> 115 116HI 117 ); 118 } 119 120 function testNull() { 121 122 $this->compare([ 123 '{http://sabredav.org/ns}root' => null, 124 ], <<<HI 125<?xml version="1.0"?> 126<s:root xmlns:s="http://sabredav.org/ns"/> 127 128HI 129 ); 130 131 } 132 133 function testArrayFormat2() { 134 135 $this->compare([ 136 '{http://sabredav.org/ns}root' => [ 137 [ 138 'name' => '{http://sabredav.org/ns}elem1', 139 'value' => 'text', 140 'attributes' => [ 141 'attr1' => 'attribute value', 142 ], 143 ], 144 ], 145 ], <<<HI 146<?xml version="1.0"?> 147<s:root xmlns:s="http://sabredav.org/ns"> 148 <s:elem1 attr1="attribute value">text</s:elem1> 149</s:root> 150 151HI 152 ); 153 154 } 155 156 function testArrayOfValues() { 157 158 $this->compare([ 159 '{http://sabredav.org/ns}root' => [ 160 [ 161 'name' => '{http://sabredav.org/ns}elem1', 162 'value' => [ 163 'foo', 164 'bar', 165 'baz', 166 ], 167 ], 168 ], 169 ], <<<HI 170<?xml version="1.0"?> 171<s:root xmlns:s="http://sabredav.org/ns"> 172 <s:elem1>foobarbaz</s:elem1> 173</s:root> 174 175HI 176 ); 177 178 } 179 180 /** 181 * @depends testArrayFormat2 182 */ 183 function testArrayFormat2NoValue() { 184 185 $this->compare([ 186 '{http://sabredav.org/ns}root' => [ 187 [ 188 'name' => '{http://sabredav.org/ns}elem1', 189 'attributes' => [ 190 'attr1' => 'attribute value', 191 ], 192 ], 193 ], 194 ], <<<HI 195<?xml version="1.0"?> 196<s:root xmlns:s="http://sabredav.org/ns"> 197 <s:elem1 attr1="attribute value"/> 198</s:root> 199 200HI 201 ); 202 203 } 204 205 function testCustomNamespace() { 206 207 $this->compare([ 208 '{http://sabredav.org/ns}root' => [ 209 '{urn:foo}elem1' => 'bar', 210 ], 211 ], <<<HI 212<?xml version="1.0"?> 213<s:root xmlns:s="http://sabredav.org/ns"> 214 <x1:elem1 xmlns:x1="urn:foo">bar</x1:elem1> 215</s:root> 216 217HI 218 ); 219 220 } 221 222 function testEmptyNamespace() { 223 224 // Empty namespaces are allowed, so we should support this. 225 $this->compare([ 226 '{http://sabredav.org/ns}root' => [ 227 '{}elem1' => 'bar', 228 ], 229 ], <<<HI 230<?xml version="1.0"?> 231<s:root xmlns:s="http://sabredav.org/ns"> 232 <elem1 xmlns="">bar</elem1> 233</s:root> 234 235HI 236 ); 237 238 } 239 240 function testAttributes() { 241 242 $this->compare([ 243 '{http://sabredav.org/ns}root' => [ 244 [ 245 'name' => '{http://sabredav.org/ns}elem1', 246 'value' => 'text', 247 'attributes' => [ 248 'attr1' => 'val1', 249 '{http://sabredav.org/ns}attr2' => 'val2', 250 '{urn:foo}attr3' => 'val3', 251 ], 252 ], 253 ], 254 ], <<<HI 255<?xml version="1.0"?> 256<s:root xmlns:s="http://sabredav.org/ns"> 257 <s:elem1 attr1="val1" s:attr2="val2" x1:attr3="val3" xmlns:x1="urn:foo">text</s:elem1> 258</s:root> 259 260HI 261 ); 262 263 } 264 265 function testBaseElement() { 266 267 $this->compare([ 268 '{http://sabredav.org/ns}root' => new Element\Base('hello') 269 ], <<<HI 270<?xml version="1.0"?> 271<s:root xmlns:s="http://sabredav.org/ns">hello</s:root> 272 273HI 274 ); 275 276 } 277 278 function testElementObj() { 279 280 $this->compare([ 281 '{http://sabredav.org/ns}root' => new Element\Mock() 282 ], <<<HI 283<?xml version="1.0"?> 284<s:root xmlns:s="http://sabredav.org/ns"> 285 <s:elem1>hiiii!</s:elem1> 286</s:root> 287 288HI 289 ); 290 291 } 292 293 function testEmptyNamespacePrefix() { 294 295 $this->writer->namespaceMap['http://sabredav.org/ns'] = null; 296 $this->compare([ 297 '{http://sabredav.org/ns}root' => new Element\Mock() 298 ], <<<HI 299<?xml version="1.0"?> 300<root xmlns="http://sabredav.org/ns"> 301 <elem1>hiiii!</elem1> 302</root> 303 304HI 305 ); 306 307 } 308 309 function testEmptyNamespacePrefixEmptyString() { 310 311 $this->writer->namespaceMap['http://sabredav.org/ns'] = ''; 312 $this->compare([ 313 '{http://sabredav.org/ns}root' => new Element\Mock() 314 ], <<<HI 315<?xml version="1.0"?> 316<root xmlns="http://sabredav.org/ns"> 317 <elem1>hiiii!</elem1> 318</root> 319 320HI 321 ); 322 323 } 324 325 function testWriteElement() { 326 327 $this->writer->writeElement("{http://sabredav.org/ns}foo", 'content'); 328 329 $output = <<<HI 330<?xml version="1.0"?> 331<s:foo xmlns:s="http://sabredav.org/ns">content</s:foo> 332 333HI; 334 335 $this->assertEquals($output, $this->writer->outputMemory()); 336 337 338 } 339 340 function testWriteElementComplex() { 341 342 $this->writer->writeElement("{http://sabredav.org/ns}foo", new Element\KeyValue(['{http://sabredav.org/ns}bar' => 'test'])); 343 344 $output = <<<HI 345<?xml version="1.0"?> 346<s:foo xmlns:s="http://sabredav.org/ns"> 347 <s:bar>test</s:bar> 348</s:foo> 349 350HI; 351 352 $this->assertEquals($output, $this->writer->outputMemory()); 353 354 } 355 356 /** 357 * @expectedException \InvalidArgumentException 358 */ 359 function testWriteBadObject() { 360 361 $this->writer->write(new \StdClass()); 362 363 } 364 365 function testStartElementSimple() { 366 367 $this->writer->startElement("foo"); 368 $this->writer->endElement(); 369 370 $output = <<<HI 371<?xml version="1.0"?> 372<foo xmlns:s="http://sabredav.org/ns"/> 373 374HI; 375 376 $this->assertEquals($output, $this->writer->outputMemory()); 377 378 } 379 380 function testCallback() { 381 382 $this->compare([ 383 '{http://sabredav.org/ns}root' => function(Writer $writer) { 384 $writer->text('deferred writer'); 385 }, 386 ], <<<HI 387<?xml version="1.0"?> 388<s:root xmlns:s="http://sabredav.org/ns">deferred writer</s:root> 389 390HI 391 ); 392 393 } 394 395 /** 396 * @expectedException \InvalidArgumentException 397 */ 398 function testResource() { 399 400 $this->compare([ 401 '{http://sabredav.org/ns}root' => fopen('php://memory', 'r'), 402 ], <<<HI 403<?xml version="1.0"?> 404<s:root xmlns:s="http://sabredav.org/ns">deferred writer</s:root> 405 406HI 407 ); 408 409 } 410 411 function testClassMap() { 412 413 $obj = (object)[ 414 'key1' => 'value1', 415 'key2' => 'value2', 416 ]; 417 418 $this->writer->classMap['stdClass'] = function(Writer $writer, $value) { 419 420 foreach (get_object_vars($value) as $key => $val) { 421 $writer->writeElement('{http://sabredav.org/ns}' . $key, $val); 422 } 423 424 }; 425 426 $this->compare([ 427 '{http://sabredav.org/ns}root' => $obj 428 ], <<<HI 429<?xml version="1.0"?> 430<s:root xmlns:s="http://sabredav.org/ns"> 431 <s:key1>value1</s:key1> 432 <s:key2>value2</s:key2> 433</s:root> 434 435HI 436 ); 437 438 } 439} 440