ILIAS  trunk Revision v11.0_alpha-2662-g519ff7d528f
StructurallyCoupledTest.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
22 
48 
49 class 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
92  ): ?ElementInterface {
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>
238 XML;
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>
299 XML;
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>
353 XML;
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>
369 XML;
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>
406 XML;
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>
459 XML;
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 
502  public function testReadWithLangstringLanguageNone(): void
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>
511 XML;
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>
563 XML;
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>
608 XML;
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>
655 XML;
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 
703  public function testReadWithOmittedContainerElement(): void
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>
714 XML;
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>
754 XML;
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
getElement()
Element data types and tag information are contained hyphen-separated in their names in the xml: name...
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
__construct()
Constructor setup ILIAS global object public.
Definition: class.ilias.php:76
$langstring
COMMON SUB-ELEMENTS.
getDefinition()
Defining properties of the metadata element.
$info
Definition: entry_point.php:21
language()
description: > Example for rendring a language glyph.
Definition: language.php:41