ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
AbstractFactoryTest.php
Go to the documentation of this file.
1 <?php
2 
3 require_once("libs/composer/vendor/autoload.php");
4 
7 
18 {
19  const COMPONENT = 1;
20  const FACTORY = 2;
21 
22  /* kitchensink info test configuration:
23  * true = should be there, check
24  * false = may be there, don't check
25  * Notice, some properties (MUST/MUST NOT) will always be checked.
26  */
28  = array('description'
29  => true
30  ,'background'
31  => false
32  ,'context'
33  => true
34  ,'featurewiki'
35  => false
36  ,'javascript'
37  => false
38  ,'rules'
39  => true);
40 
41  /* You can overwrite these settings per factory method when using this test
42  * by writing $kitchensink_info_settings. See GlyphFactoryTest for an example.
43  */
44 
45 
46  // Definitions and Helpers:
47 
49  array('purpose', 'composition', 'effect', 'rival');
50 
52  array('usage', 'interaction', 'wording', 'style', 'ordering', 'responsiveness',
53  'composition','accessibility');
54 
55  final protected function returnsFactory($docstring_data)
56  {
57  return $this->isFactoryName($docstring_data["namespace"]);
58  }
59 
60  final protected function returnsComponent($docstring_data)
61  {
62  $reflection = new ReflectionClass($docstring_data["namespace"]);
63  return in_array("ILIAS\\UI\\Component\\Component", $reflection->getInterfaceNames());
64  }
65 
66  final protected function isFactoryName($name)
67  {
68  return preg_match("#^(\\\\)?ILIAS\\\\UI\\\\Component\\\\([a-zA-Z]+\\\\)*Factory$#", $name) === 1;
69  }
70 
71  final public function buildFactoryReflection()
72  {
73  return new ReflectionClass($this->factory_title);
74  }
75 
76  final public function methods_provider()
77  {
78  $reflection = $this->buildFactoryReflection();
79  return array_map(function ($element) {
80  return array($element, $element->getName());
81  }, $reflection->getMethods());
82  }
83 
84  // Setup
85 
86  public function setUp()
87  {
88  $this->yaml_parser = new Crawler\EntriesYamlParser();
89  $this->reflection = $this->buildFactoryReflection();
90  }
91 
92  public function test_proper_namespace()
93  {
94  $message = "TODO: Put your factory into the proper namespace.";
95  $this->assertRegExp(
96  "#^ILIAS\\\\UI\\\\Component.#",
97  $this->reflection->getNamespaceName(),
98  $message
99  );
100  }
101 
102  public function test_proper_name()
103  {
104  $name = $this->reflection->getName();
105  $message = "TODO: Give your factory a proper name.";
106  $this->assertTrue(
107  $this->isFactoryName($name),
108  $message
109  );
110  }
111 
117  final public function test_check_yaml_extraction($method_reflection, $name)
118  {
119  try {
120  //Todo (TA) this is not pretty. We should think about using only reflection in the parser as well.
121  $function_name_string = "\n public function " . $method_reflection->getName() . "()";
122  $docstring_data = $this->yaml_parser->parseArrayFromString(
123  $method_reflection->getDocComment() . $function_name_string
124  );
125  $this->assertTrue(true);
126  } catch (CrawlerException\CrawlerException $e) {
127  $message = "TODO ($name): fix parse error in kitchen sink yaml: " . $e->getMessage();
128  $this->assertTrue(false, $message);
129  }
130  $this->assertCount(1, $docstring_data);
131  return $docstring_data[0];
132  }
133 
139  final public function test_return_type($method_reflection, $name)
140  {
141  $message = "TODO ($name): fix return type, it must be a factory or a component.";
142  $docstring_data = $this->test_check_yaml_extraction($method_reflection, $name);
143  if ($this->returnsFactory($docstring_data)) {
144  $this->assertTrue(true);
145  } elseif ($this->returnsComponent($docstring_data)) {
146  $this->assertTrue(true);
147  } else {
148  $this->assertTrue(false, $message);
149  }
150  }
151 
157  final public function test_factory_method_name_compatible_docstring($method_reflection, $name)
158  {
159  $docstring_data = $this->test_check_yaml_extraction($method_reflection, $name);
160  $this->test_return_type($method_reflection, $name);
161 
162  $return_doc = $docstring_data["namespace"];
163  $name_uppercase = ucwords($name);
164  $regex_factory_namespace = $this->get_regex_factory_namespace();
165  $regex_head = "#^(\\\\?)$regex_factory_namespace";
166 
167  $message = "TODO ($name): fix @return, it does not match the method name.";
168  if ($this->returnsFactory($docstring_data)) {
169  $this->assertRegExp(
170  "$regex_head\\\\$name_uppercase\\\\Factory$#",
171  $return_doc,
172  $message
173  );
174  } else { // returnsComponent
175  // Every component MUST be described by a single interface, where the name of
176  // the interface corresponds to the name of the component.
177  $standard_pattern = "$regex_head\\\\$name_uppercase#";
178  $standard_case = preg_match($standard_pattern, $return_doc);
179 
180  // unless they only differ in a type and share a common prefix to their pathes.
181  $namespace_parts = explode("\\", $this->reflection->getNamespaceName());
182  $typediff_only_pattern = "$regex_head\\\\" . array_pop($namespace_parts) . "#";
183  $typediff_only_case = preg_match($typediff_only_pattern, $return_doc);
184 
185  $this->assertTrue($standard_case || $typediff_only_case, $message);
186  }
187  }
188 
189  protected function get_regex_factory_namespace()
190  {
191  return str_replace("\\", "\\\\", $this->reflection->getNamespaceName());
192  }
193 
199  final public function test_method_params($method_reflection, $name)
200  {
201  $docstring_data = $this->test_check_yaml_extraction($method_reflection, $name);
202  if ($this->returnsFactory($docstring_data)) {
203  $message = "TODO ($name): remove params from method that returns Factory.";
204  $this->assertEquals(0, $method_reflection->getNumberOfParameters(), $message);
205  }
206  }
207 
208  // Common rules for all factory methods, regardless whether they return other
209  // factories or components.
210 
214  final public function test_kitchensink_info_description($method_reflection, $name)
215  {
216  $docstring_data = $this->test_check_yaml_extraction($method_reflection, $name);
217  $kitchensink_info_settings = $this->kitchensink_info_settings_merged_with_defaults($name);
218 
219  if ($kitchensink_info_settings['description']) {
220  $message = "TODO ($name): add a description.";
221  $this->assertArrayHasKey('description', $docstring_data, $message);
222 
223  $desc_fields = implode(", ", $this->description_categories);
224  $message = "TODO ($name): the description field should at least contain one of these: $desc_fields.";
225  $existing_keys = array_keys($docstring_data["description"]);
226  $existing_expected_keys = array_intersect($this->description_categories, $existing_keys);
227  $this->assertGreaterThanOrEqual(
228  1,
229  $existing_expected_keys,
230  $message
231  );
232  }
233  }
234 
238  final public function test_kitchensink_info_background($method_reflection, $name)
239  {
240  $docstring_data = $this->test_check_yaml_extraction($method_reflection, $name);
241  $kitchensink_info_settings = $this->kitchensink_info_settings_merged_with_defaults($name);
242 
243  if ($kitchensink_info_settings['background']) {
244  $message = "TODO ($name): add a background field.";
245  $this->assertArrayHasKey('background', $docstring_data, $message);
246  }
247  }
248 
252  final public function test_kitchensink_info_featurewiki($method_reflection, $name)
253  {
254  $docstring_data = $this->test_check_yaml_extraction($method_reflection, $name);
255  $kitchensink_info_settings = $this->kitchensink_info_settings_merged_with_defaults($name);
256 
257  if ($kitchensink_info_settings['featurewiki']) {
258  $message = "TODO ($name): add a featurewiki field.";
259  $this->assertArrayHasKey('featurewiki', $docstring_data, $message);
260  }
261  }
262 
266  final public function test_kitchensink_info_javascript($method_reflection, $name)
267  {
268  $docstring_data = $this->test_check_yaml_extraction($method_reflection, $name);
269  $kitchensink_info_settings = $this->kitchensink_info_settings_merged_with_defaults($name);
270 
271  if ($kitchensink_info_settings['javascript']) {
272  $message = "TODO ($name): add a javascript field.";
273  $this->assertArrayHasKey('javascript', $docstring_data, $message);
274  }
275  }
276 
280  final public function test_kitchensink_info_rules($method_reflection, $name)
281  {
282  $docstring_data = $this->test_check_yaml_extraction($method_reflection, $name);
283  $kitchensink_info_settings = $this->kitchensink_info_settings_merged_with_defaults($name);
284 
285  if ($kitchensink_info_settings['rules']) {
286  $message = "TODO ($name): add a rules field.";
287  $this->assertArrayHasKey('rules', $docstring_data, $message);
288 
289  $rules_fields = implode(", ", $this->rules_categories);
290  $message = "TODO ($name): the rules field should at least contain one of these: $rules_fields.";
291  $existing_keys = array_keys($docstring_data["rules"]);
292  $existing_expected_keys = array_intersect($this->rules_categories, $existing_keys);
293  $this->assertGreaterThanOrEqual(
294  1,
295  $existing_expected_keys,
296  $message
297  );
298  }
299  }
300 
304  final public function test_kitchensink_info_context($method_reflection, $name)
305  {
306  $docstring_data = $this->test_check_yaml_extraction($method_reflection, $name);
307  $kitchensink_info_settings = $this->kitchensink_info_settings_merged_with_defaults($name);
308 
309  // Special rules for factory methods:
310  if ($this->returnsFactory($docstring_data)) {
311  $message = "TODO ($name): remove 'context' field, method returns a factory.";
312  $this->assertArrayNotHasKey("context", $docstring_data, $message);
313  } else { // returnsComponent
314  if ($kitchensink_info_settings["context"]) {
315  $message = "TODO ($name): factory method returning component should have context field. Add it.";
316  $this->assertArrayHasKey("context", $docstring_data, $message);
317  }
318  }
319  }
320 
322  {
323  if (array_key_exists($name, $this->kitchensink_info_settings)) {
324  return array_merge(
325  $this->kitchensink_info_settings_default,
326  $this->kitchensink_info_settings[$name]
327  );
328  } else {
330  }
331  }
332 }
test_method_params($method_reflection, $name)
Tests whether methods returning factories have no parameters.
test_return_type($method_reflection, $name)
Tests whether the method either returns a factory or a component.
test_kitchensink_info_context($method_reflection, $name)
methods_provider
test_kitchensink_info_description($method_reflection, $name)
methods_provider
test_check_yaml_extraction($method_reflection, $name)
Tests whether the YAML Kitchen Sink info can be parsed.
test_kitchensink_info_featurewiki($method_reflection, $name)
methods_provider
test_kitchensink_info_javascript($method_reflection, $name)
methods_provider
returnsFactory($docstring_data)
test_factory_method_name_compatible_docstring($method_reflection, $name)
Tests whether the method name matches the.
if($format !==null) $name
Definition: metadata.php:146
catch(Exception $e) $message
Defines tests every SHOULD pass UI-factory.
test_kitchensink_info_background($method_reflection, $name)
methods_provider
kitchensink_info_settings_merged_with_defaults($name)
Create styles array
The data for the language used.
test_kitchensink_info_rules($method_reflection, $name)
methods_provider
returnsComponent($docstring_data)