ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
StructurallyCoupledTest.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
22
23use PHPUnit\Framework\TestCase;
42use SimpleXMLElement;
48
49class StructurallyCoupledTest extends TestCase
50{
63 protected function getElement(): ElementInterface
64 {
65 return new class () extends NullElement {
66 public array $exposed_data;
67 protected ElementInterface $super_element;
68 protected array $sub_elements;
69
70 public function getDefinition(): DefinitionInterface
71 {
72 return new class ($this->exposed_data) extends NullDefinition {
73 public function __construct(public array $exposed_data)
74 {
75 }
76
77 public function name(): string
78 {
79 return $this->exposed_data['name'];
80 }
81
82 public function dataType(): Type
83 {
84 return $this->exposed_data['type'];
85 }
86 };
87 }
88
89 public function addScaffoldToSubElements(
90 ScaffoldProviderInterface $scaffold_provider,
91 string $name
93 if ($name === 'failme') {
94 return null;
95 }
96
97 $scaffold = clone $this;
98 $this->sub_elements[] = $scaffold;
99
100 $scaffold->sub_elements = [];
101 $scaffold->super_element = $this;
102 $scaffold->exposed_data = [];
103
104 $info_from_name = explode('-', $name);
105
106 // langstrings need to treated as a special case
107 if ($name === 'string') {
108 $type = Type::STRING;
109 } elseif ($name === 'language') {
110 $type = Type::LANG;
111 } else {
112 $type = Type::from($info_from_name[1]);
113 }
114
115 $scaffold->exposed_data['name'] = $name;
116 $scaffold->exposed_data['type'] = $type;
117
118 return $scaffold;
119 }
120
121 public function mark(
122 MarkerFactoryInterface $factory,
123 Action $action,
124 string $data_value = ''
125 ): void {
126 $this->exposed_data['marker_action'] = $action;
127 $this->exposed_data['marker_value'] = $data_value;
128 if (isset($this->super_element)) {
129 $this->super_element->mark($factory, $action);
130 }
131 }
132
133 public function exposeData(): array
134 {
135 $data = $this->exposed_data;
136 $data['subs'] = [];
137 foreach ($this->sub_elements as $sub_element) {
138 $data['subs'][] = $sub_element->exposeData();
139 }
140 return $data;
141 }
142 };
143 }
144
145 protected function getReader(): StructurallyCoupled
146 {
147 $root = $this->getElement();
148 $root->exposed_data = ['name' => 'correctroot', 'type' => Type::NULL];
149
150 $scaffold_provider = new class ($root) extends NullScaffoldProvider {
151 public function __construct(protected ElementInterface $root)
152 {
153 }
154
155 public function set(): SetInterface
156 {
157 return new class ($this->root) extends NullSet {
158 public function __construct(protected ElementInterface $root)
159 {
160 }
161
162 public function getRoot(): ElementInterface
163 {
164 return $this->root;
165 }
166 };
167 }
168 };
169
170 $dictionary = new class () extends NullDictionary {
171 public function tagForElement(
172 BaseElementInterface $element,
174 ): ?TagInterface {
175 $info_from_name = explode('-', $element->getDefinition()->name());
176
177 //throw away name and type
178 array_shift($info_from_name);
179 array_shift($info_from_name);
180
181 $langstring = false;
182 $omitted = false;
183 foreach ($info_from_name as $info) {
184 if ($info === SpecialCase::LANGSTRING->value . '.' . $version->value) {
185 $langstring = true;
186 }
187 if ($info === SpecialCase::OMITTED->value . '.' . $version->value) {
188 $omitted = true;
189 }
190 }
191
192 return new class ($langstring, $omitted) extends NullTag {
193 public function __construct(
194 protected bool $langstring,
195 protected bool $omitted
196 ) {
197 }
198
199 public function isExportedAsLangString(): bool
200 {
201 return $this->langstring;
202 }
203
204 public function isOmitted(): bool
205 {
206 return $this->omitted;
207 }
208 };
209 }
210 };
211
212 $copyright_handler = new class () extends NullCopyrightHandler {
213 public function copyrightFromExport(string $copyright): string
214 {
215 return '~parsed:' . $copyright . '~';
216 }
217 };
218
219 return new StructurallyCoupled(
220 new NullMarkerFactory(),
221 $scaffold_provider,
222 $dictionary,
223 $copyright_handler
224 );
225 }
226
227 public function testRead(): void
228 {
229 $xml_string = <<<XML
230<?xml version="1.0"?>
231<correctroot>
232 <el1-string>val1</el1-string>
233 <el2-none>
234 <el2.1-non_neg_int>val2.1</el2.1-non_neg_int>
235 <el2.2-duration>val2.2</el2.2-duration>
236 </el2-none>
237</correctroot>
238XML;
239 $xml = new SimpleXMLElement($xml_string);
240
241 $expected_data = [
242 'name' => 'correctroot',
243 'type' => Type::NULL,
244 'marker_action' => Action::CREATE_OR_UPDATE,
245 'marker_value' => '',
246 'subs' => [
247 [
248 'name' => 'el1-string',
249 'type' => Type::STRING,
250 'marker_action' => Action::CREATE_OR_UPDATE,
251 'marker_value' => 'val1',
252 'subs' => []
253 ],
254 [
255 'name' => 'el2-none',
256 'type' => Type::NULL,
257 'marker_action' => Action::CREATE_OR_UPDATE,
258 'marker_value' => '',
259 'subs' => [
260 [
261 'name' => 'el2.1-non_neg_int',
262 'type' => Type::NON_NEG_INT,
263 'marker_action' => Action::CREATE_OR_UPDATE,
264 'marker_value' => 'val2.1',
265 'subs' => []
266 ],
267 [
268 'name' => 'el2.2-duration',
269 'type' => Type::DURATION,
270 'marker_action' => Action::CREATE_OR_UPDATE,
271 'marker_value' => 'val2.2',
272 'subs' => []
273 ]
274 ]
275 ]
276 ]
277 ];
278
279 $reader = $this->getReader();
280 $result_set = $reader->read($xml, Version::V10_0);
281
282 $this->assertEquals(
283 $expected_data,
284 $result_set->getRoot()->exposeData()
285 );
286 }
287
288 public function testReadWrongStructure(): void
289 {
290 $xml_string = <<<XML
291<?xml version="1.0"?>
292<correctroot>
293 <el1-string>val1</el1-string>
294 <el2-none>
295 <failme>val2.1</failme>
296 <el2.2-duration>val2.2</el2.2-duration>
297 </el2-none>
298</correctroot>
299XML;
300 $xml = new SimpleXMLElement($xml_string);
301
302 $expected_data = [
303 'name' => 'correctroot',
304 'type' => Type::NULL,
305 'marker_action' => Action::CREATE_OR_UPDATE,
306 'marker_value' => '',
307 'subs' => [
308 [
309 'name' => 'el1-string',
310 'type' => Type::STRING,
311 'marker_action' => Action::CREATE_OR_UPDATE,
312 'marker_value' => 'val1',
313 'subs' => []
314 ],
315 [
316 'name' => 'el2-none',
317 'type' => Type::NULL,
318 'marker_action' => Action::CREATE_OR_UPDATE,
319 'marker_value' => '',
320 'subs' => [
321 [
322 'name' => 'el2.2-duration',
323 'type' => Type::DURATION,
324 'marker_action' => Action::CREATE_OR_UPDATE,
325 'marker_value' => 'val2.2',
326 'subs' => []
327 ]
328 ]
329 ]
330 ]
331 ];
332
333 $reader = $this->getReader();
334 $result_set = $reader->read($xml, Version::V10_0);
335
336 $this->assertEquals(
337 $expected_data,
338 $result_set->getRoot()->exposeData()
339 );
340 }
341
342 public function testReadInvalidRootException(): void
343 {
344 $xml_string = <<<XML
345<?xml version="1.0"?>
346<incorrectroot>
347 <el1-string>val1</el1-string>
348 <el2-none>
349 <el2.1-non_neg_int>val2.1</el2.1-non_neg_int>
350 <el2.2-duration>val2.2</el2.2-duration>
351 </el2-none>
352</incorrectroot>
353XML;
354 $xml = new SimpleXMLElement($xml_string);
355
356 $reader = $this->getReader();
357
358 $this->expectException(\ilMDXMLException::class);
359 $result_set = $reader->read($xml, Version::V10_0);
360 }
361
362 public function testReadWithLanguageNone(): void
363 {
364 $xml_string = <<<XML
365<?xml version="1.0"?>
366<correctroot>
367 <el-lang>none</el-lang>
368</correctroot>
369XML;
370 $xml = new SimpleXMLElement($xml_string);
371
372 $expected_data = [
373 'name' => 'correctroot',
374 'type' => Type::NULL,
375 'marker_action' => Action::CREATE_OR_UPDATE,
376 'marker_value' => '',
377 'subs' => [
378 [
379 'name' => 'el-lang',
380 'type' => Type::LANG,
381 'marker_action' => Action::CREATE_OR_UPDATE,
382 'marker_value' => 'xx',
383 'subs' => []
384 ]
385 ]
386 ];
387
388 $reader = $this->getReader();
389 $result_set = $reader->read($xml, Version::V10_0);
390
391 $this->assertEquals(
392 $expected_data,
393 $result_set->getRoot()->exposeData()
394 );
395 }
396
397 public function testReadWithLangstring(): void
398 {
399 $xml_string = <<<XML
400<?xml version="1.0"?>
401<correctroot>
402 <el1-none-langstring.10.0>
403 <string language="br">some text</string>
404 </el1-none-langstring.10.0>
405</correctroot>
406XML;
407 $xml = new SimpleXMLElement($xml_string);
408
409 $expected_data = [
410 'name' => 'correctroot',
411 'type' => Type::NULL,
412 'marker_action' => Action::CREATE_OR_UPDATE,
413 'marker_value' => '',
414 'subs' => [
415 [
416 'name' => 'el1-none-langstring.10.0',
417 'type' => Type::NULL,
418 'marker_action' => Action::CREATE_OR_UPDATE,
419 'marker_value' => '',
420 'subs' => [
421 [
422 'name' => 'string',
423 'type' => Type::STRING,
424 'marker_action' => Action::CREATE_OR_UPDATE,
425 'marker_value' => 'some text',
426 'subs' => []
427 ],
428 [
429 'name' => 'language',
430 'type' => Type::LANG,
431 'marker_action' => Action::CREATE_OR_UPDATE,
432 'marker_value' => 'br',
433 'subs' => []
434 ]
435 ]
436 ]
437 ]
438 ];
439
440 $reader = $this->getReader();
441 $result_set = $reader->read($xml, Version::V10_0);
442
443 $this->assertEquals(
444 $expected_data,
445 $result_set->getRoot()->exposeData()
446 );
447 }
448
450 {
451 $xml_string = <<<XML
452<?xml version="1.0"?>
453<correctroot>
454 <el1-none-langstring.4.1.0>
455 <el1.1-string>val1.1</el1.1-string>
456 <el1.2-lang>val1.2</el1.2-lang>
457 </el1-none-langstring.4.1.0>
458</correctroot>
459XML;
460 $xml = new SimpleXMLElement($xml_string);
461
462 $expected_data = [
463 'name' => 'correctroot',
464 'type' => Type::NULL,
465 'marker_action' => Action::CREATE_OR_UPDATE,
466 'marker_value' => '',
467 'subs' => [
468 [
469 'name' => 'el1-none-langstring.4.1.0',
470 'type' => Type::NULL,
471 'marker_action' => Action::CREATE_OR_UPDATE,
472 'marker_value' => '',
473 'subs' => [
474 [
475 'name' => 'el1.1-string',
476 'type' => Type::STRING,
477 'marker_action' => Action::CREATE_OR_UPDATE,
478 'marker_value' => 'val1.1',
479 'subs' => []
480 ],
481 [
482 'name' => 'el1.2-lang',
483 'type' => Type::LANG,
484 'marker_action' => Action::CREATE_OR_UPDATE,
485 'marker_value' => 'val1.2',
486 'subs' => []
487 ]
488 ]
489 ]
490 ]
491 ];
492
493 $reader = $this->getReader();
494 $result_set = $reader->read($xml, Version::V10_0);
495
496 $this->assertEquals(
497 $expected_data,
498 $result_set->getRoot()->exposeData()
499 );
500 }
501
503 {
504 $xml_string = <<<XML
505<?xml version="1.0"?>
506<correctroot>
507 <el1-none-langstring.10.0>
508 <string language="none">some text</string>
509 </el1-none-langstring.10.0>
510</correctroot>
511XML;
512 $xml = new SimpleXMLElement($xml_string);
513
514 $expected_data = [
515 'name' => 'correctroot',
516 'type' => Type::NULL,
517 'marker_action' => Action::CREATE_OR_UPDATE,
518 'marker_value' => '',
519 'subs' => [
520 [
521 'name' => 'el1-none-langstring.10.0',
522 'type' => Type::NULL,
523 'marker_action' => Action::CREATE_OR_UPDATE,
524 'marker_value' => '',
525 'subs' => [
526 [
527 'name' => 'string',
528 'type' => Type::STRING,
529 'marker_action' => Action::CREATE_OR_UPDATE,
530 'marker_value' => 'some text',
531 'subs' => []
532 ],
533 [
534 'name' => 'language',
535 'type' => Type::LANG,
536 'marker_action' => Action::CREATE_OR_UPDATE,
537 'marker_value' => 'xx',
538 'subs' => []
539 ]
540 ]
541 ]
542 ]
543 ];
544
545 $reader = $this->getReader();
546 $result_set = $reader->read($xml, Version::V10_0);
547
548 $this->assertEquals(
549 $expected_data,
550 $result_set->getRoot()->exposeData()
551 );
552 }
553
554 public function testReadWithLangstringNoLanguage(): void
555 {
556 $xml_string = <<<XML
557<?xml version="1.0"?>
558<correctroot>
559 <el1-none-langstring.10.0>
560 <string>some text</string>
561 </el1-none-langstring.10.0>
562</correctroot>
563XML;
564 $xml = new SimpleXMLElement($xml_string);
565
566 $expected_data = [
567 'name' => 'correctroot',
568 'type' => Type::NULL,
569 'marker_action' => Action::CREATE_OR_UPDATE,
570 'marker_value' => '',
571 'subs' => [
572 [
573 'name' => 'el1-none-langstring.10.0',
574 'type' => Type::NULL,
575 'marker_action' => Action::CREATE_OR_UPDATE,
576 'marker_value' => '',
577 'subs' => [
578 [
579 'name' => 'string',
580 'type' => Type::STRING,
581 'marker_action' => Action::CREATE_OR_UPDATE,
582 'marker_value' => 'some text',
583 'subs' => []
584 ]
585 ]
586 ]
587 ]
588 ];
589
590 $reader = $this->getReader();
591 $result_set = $reader->read($xml, Version::V10_0);
592
593 $this->assertEquals(
594 $expected_data,
595 $result_set->getRoot()->exposeData()
596 );
597 }
598
599 public function testReadWithLangstringNoString(): void
600 {
601 $xml_string = <<<XML
602<?xml version="1.0"?>
603<correctroot>
604 <el1-none-langstring.10.0>
605 <string language="pl"/>
606 </el1-none-langstring.10.0>
607</correctroot>
608XML;
609 $xml = new SimpleXMLElement($xml_string);
610
611 $expected_data = [
612 'name' => 'correctroot',
613 'type' => Type::NULL,
614 'marker_action' => Action::CREATE_OR_UPDATE,
615 'marker_value' => '',
616 'subs' => [
617 [
618 'name' => 'el1-none-langstring.10.0',
619 'type' => Type::NULL,
620 'marker_action' => Action::CREATE_OR_UPDATE,
621 'marker_value' => '',
622 'subs' => [
623 [
624 'name' => 'language',
625 'type' => Type::LANG,
626 'marker_action' => Action::CREATE_OR_UPDATE,
627 'marker_value' => 'pl',
628 'subs' => []
629 ]
630 ]
631 ]
632 ]
633 ];
634
635 $reader = $this->getReader();
636 $result_set = $reader->read($xml, Version::V10_0);
637
638 $this->assertEquals(
639 $expected_data,
640 $result_set->getRoot()->exposeData()
641 );
642 }
643
645 {
646 $xml_string = <<<XML
647<?xml version="1.0"?>
648<correctroot>
649 <el1-string>val1</el1-string>
650 <el2-none>
651 <el2.1-non_neg_int-omitted.10.0>val2.1</el2.1-non_neg_int-omitted.10.0>
652 <el2.2-duration>val2.2</el2.2-duration>
653 </el2-none>
654</correctroot>
655XML;
656 $xml = new SimpleXMLElement($xml_string);
657
658 $expected_data = [
659 'name' => 'correctroot',
660 'type' => Type::NULL,
661 'marker_action' => Action::CREATE_OR_UPDATE,
662 'marker_value' => '',
663 'subs' => [
664 [
665 'name' => 'el1-string',
666 'type' => Type::STRING,
667 'marker_action' => Action::CREATE_OR_UPDATE,
668 'marker_value' => 'val1',
669 'subs' => []
670 ],
671 [
672 'name' => 'el2-none',
673 'type' => Type::NULL,
674 'marker_action' => Action::CREATE_OR_UPDATE,
675 'marker_value' => '',
676 'subs' => [
677 [
678 'name' => 'el2.1-non_neg_int-omitted.10.0',
679 'type' => Type::NON_NEG_INT,
680 'subs' => []
681 ],
682 [
683 'name' => 'el2.2-duration',
684 'type' => Type::DURATION,
685 'marker_action' => Action::CREATE_OR_UPDATE,
686 'marker_value' => 'val2.2',
687 'subs' => []
688 ]
689 ]
690 ]
691 ]
692 ];
693
694 $reader = $this->getReader();
695 $result_set = $reader->read($xml, Version::V10_0);
696
697 $this->assertEquals(
698 $expected_data,
699 $result_set->getRoot()->exposeData()
700 );
701 }
702
704 {
705 $xml_string = <<<XML
706<?xml version="1.0"?>
707<correctroot>
708 <el1-none-omitted.10.0>
709 <el1.1-non_neg_int>val1.1</el1.1-non_neg_int>
710 <el1.2-duration>val1.2</el1.2-duration>
711 </el1-none-omitted.10.0>
712 <el2-string>val2</el2-string>
713</correctroot>
714XML;
715 $xml = new SimpleXMLElement($xml_string);
716
717 $expected_data = [
718 'name' => 'correctroot',
719 'type' => Type::NULL,
720 'marker_action' => Action::CREATE_OR_UPDATE,
721 'marker_value' => '',
722 'subs' => [
723 [
724 'name' => 'el1-none-omitted.10.0',
725 'type' => Type::NULL,
726 'subs' => []
727 ],
728 [
729 'name' => 'el2-string',
730 'type' => Type::STRING,
731 'marker_action' => Action::CREATE_OR_UPDATE,
732 'marker_value' => 'val2',
733 'subs' => []
734 ],
735 ]
736 ];
737
738 $reader = $this->getReader();
739 $result_set = $reader->read($xml, Version::V10_0);
740
741 $this->assertEquals(
742 $expected_data,
743 $result_set->getRoot()->exposeData()
744 );
745 }
746
748 {
749 $xml_string = <<<XML
750<?xml version="1.0"?>
751<correctroot>
752 <el1-string-omitted.4.1.0>val1</el1-string-omitted.4.1.0>
753</correctroot>
754XML;
755 $xml = new SimpleXMLElement($xml_string);
756
757 $expected_data = [
758 'name' => 'correctroot',
759 'type' => Type::NULL,
760 'marker_action' => Action::CREATE_OR_UPDATE,
761 'marker_value' => '',
762 'subs' => [
763 [
764 'name' => 'el1-string-omitted.4.1.0',
765 'type' => Type::STRING,
766 'marker_action' => Action::CREATE_OR_UPDATE,
767 'marker_value' => 'val1',
768 'subs' => []
769 ],
770 ]
771 ];
772
773 $reader = $this->getReader();
774 $result_set = $reader->read($xml, Version::V10_0);
775
776 $this->assertEquals(
777 $expected_data,
778 $result_set->getRoot()->exposeData()
779 );
780 }
781}
$version
Definition: plugin.php:24
$langstring
COMMON SUB-ELEMENTS.
getElement()
Element data types and tag information are contained hyphen-separated in their names in the xml: name...
__construct()
Constructor setup ILIAS global object @access public.
Definition: class.ilias.php:76
$info
Definition: entry_point.php:21
getDefinition()
Defining properties of the metadata element.