]> git.mxchange.org Git - friendica.git/blob - simplepie/test/unit_test/unit_test2.php
Add simplepie
[friendica.git] / simplepie / test / unit_test / unit_test2.php
1 <?php
2
3 /**
4  * @package Unit Test
5  * @author Geoffrey Sneddon <geoffers@gmail.com>
6  * @version $Id: unit_test2.php 16 2007-08-08 14:52:36Z gsnedders $
7  * @license http://www.opensource.org/licenses/zlib-license.php zlib/libpng license
8  * @license http://opensource.org/licenses/lgpl-license.php GNU Lesser General Public License
9  * @copyright Copyright © 2007, Geoffrey Sneddon
10  */
11
12 /**
13  * Unit Test
14  *
15  * @abstract
16  * @package Unit Test
17  */
18 class Unit_Test2
19 {
20         /**
21          * Sets whether this class is a unit test or not
22          *
23          * @access protected
24          * @var bool
25          */
26         var $test = true;
27
28         /**
29          * Test name
30          *
31          * @access protected
32          * @var mixed
33          */
34         var $name;
35
36         /**
37          * Test data
38          *
39          * @access protected
40          * @var mixed
41          */
42         var $data;
43
44         /**
45          * Expected result
46          *
47          * @access protected
48          * @var mixed
49          */
50         var $expected;
51
52         /**
53          * Test result
54          *
55          * @access protected
56          * @var mixed
57          */
58         var $result;
59
60         /**
61          * Number of tests passed
62          *
63          * @access protected
64          * @var int
65          */
66         var $passes = 0;
67
68         /**
69          * Number of tests failed
70          *
71          * @access protected
72          * @var int
73          */
74         var $fails = 0;
75
76         /**
77          * Set the test name to the class name by default, replacing "_" with " "
78          */
79         function Unit_Test2()
80         {
81                 $this->name = str_replace('_', ' ', get_class($this));
82         }
83
84         /**
85          * Whether this class is a test
86          *
87          * @final
88          * @access public
89          * @return bool
90          */
91         function is_test()
92         {
93                 return (bool) $this->test;
94         }
95
96         /**
97          * Test name
98          *
99          * @final
100          * @access public
101          * @return mixed
102          */
103         function name()
104         {
105                 return $this->name;
106         }
107
108         /**
109          * Number of tests passed
110          *
111          * @final
112          * @access public
113          * @return int
114          */
115         function passes()
116         {
117                 return (int) $this->passes;
118         }
119
120         /**
121          * Number of tests failed
122          *
123          * @final
124          * @access public
125          * @return int
126          */
127         function fails()
128         {
129                 return (int) $this->fails;
130         }
131
132         /**
133          * Total number of tests
134          *
135          * @final
136          * @access public
137          * @return int
138          */
139         function total()
140         {
141                 return $this->passes() + $this->fails();
142         }
143
144         /**
145          * Run the test
146          *
147          * @final
148          * @access public
149          */
150         function run()
151         {
152                 $this->init();
153                 $this->data();
154                 $this->expected();
155                 $this->test();
156                 $this->result();
157         }
158
159         /**
160          * First method called when running the test
161          *
162          * This isn't defined as abstract as it's optional
163          *
164          * @access protected
165          */
166         function init()
167         {
168         }
169
170         /**
171          * Set Unit_Test2::$data
172          *
173          * @abstract
174          * @access protected
175          * @see Unit_Test2::$data
176          */
177         function data()
178         {
179         }
180
181         /**
182          * Set Unit_Test2::$expected
183          *
184          * @abstract
185          * @access protected
186          * @see Unit_Test2::$expected
187          */
188         function expected()
189         {
190         }
191
192         /**
193          * Actually run the test (should set Unit_Test::$result)
194          *
195          * @abstract
196          * @access protected
197          * @see Unit_Test2::$result
198          */
199         function test()
200         {
201         }
202
203         /**
204          * Check whether the result is valid (should call Unit_Test2::pass() or Unit_Test2::fail())
205          *
206          * @abstract
207          * @access protected
208          * @see Unit_Test2::$expected
209          * @see Unit_Test2::$result
210          */
211         function result()
212         {
213         }
214
215         /**
216          * Process a pass
217          *
218          * @access protected
219          */
220         function pass()
221         {
222                 $this->passes++;
223         }
224
225         /**
226          * Process a fail
227          *
228          * @access protected
229          */
230         function fail()
231         {
232                 $this->fails++;
233         }
234 }
235
236 /**
237  * Unit Test Group
238  *
239  * @package Unit Test
240  */
241 class Unit_Test2_Group
242 {
243         /**
244          * Unit Test Group Name
245          *
246          * @access protected
247          * @var mixed
248          */
249         var $name;
250
251         /**
252          * Tests
253          *
254          * @access protected
255          * @var array
256          */
257         var $tests = array(array());
258
259         /**
260          * Number of tests passed
261          *
262          * @access protected
263          * @var int
264          */
265         var $passes = 0;
266
267         /**
268          * Number of tests failed
269          *
270          * @access protected
271          * @var int
272          */
273         var $fails = 0;
274
275         /**
276          * Time taken to run tests
277          *
278          * @access protected
279          * @var float
280          */
281         var $time = 0.0;
282
283         /**
284          * Create Unit Test Group
285          *
286          * @access public
287          * @param string $name Unit Test Group Name
288          */
289         function Unit_Test2_Group($name)
290         {
291                 $this->name = $name;
292         }
293
294         /**
295          * Unit Test Group Name
296          *
297          * @final
298          * @access public
299          * @return mixed
300          */
301         function name()
302         {
303                 return $this->name;
304         }
305
306         /**
307          * Number of tests passed
308          *
309          * @final
310          * @access public
311          * @return int
312          */
313         function passes()
314         {
315                 return (int) $this->passes;
316         }
317
318         /**
319          * Number of tests failed
320          *
321          * @final
322          * @access public
323          * @return int
324          */
325         function fails()
326         {
327                 return (int) $this->fails;
328         }
329
330         /**
331          * Total number of tests
332          *
333          * @final
334          * @access public
335          * @return int
336          */
337         function total()
338         {
339                 return $this->passes() + $this->fails();
340         }
341
342         /**
343          * Time to run tests
344          *
345          * @final
346          * @access public
347          * @return float
348          */
349         function time()
350         {
351                 return (float) $this->time;
352         }
353
354         /**
355          * Add a test (a Unit_Test2 child, or a Unit_Test2_Group)
356          *
357          * @access public
358          * @param object $test Test to add
359          */
360         function add($test)
361         {
362                 $this->tests[$test->name()][] = $test;
363         }
364
365         /**
366          * Remove a test
367          *
368          * @access public
369          * @param string $name Test name
370          */
371         function remove($name)
372         {
373                 unset($this->tests[$name]);
374         }
375
376         /**
377          * Load tests in folder
378          *
379          * This loads all the Unit_Test2 classes within files with the same
380          * extension as this file within the specified folder
381          *
382          * @access public
383          * @param string $folder Folder name
384          */
385         function load_folder($folder)
386         {
387                 static $extension = null;
388                 if (!$extension)
389                 {
390                         $extension = pathinfo(__FILE__, PATHINFO_EXTENSION);
391                 }
392                 $files = Unit_Test2_Files::get_files($folder);
393                 $count_classes = count(get_declared_classes());
394                 foreach ($files as $file)
395                 {
396                         if (is_file($file) && pathinfo($file, PATHINFO_EXTENSION) === $extension)
397                         {
398                                 include $file;
399                         }
400                 }
401                 $classes = array_slice(get_declared_classes(), $count_classes);
402                 foreach ($classes as $class)
403                 {
404                         if ($this->is_subclass_of($class, 'Unit_Test2'))
405                         {
406                                 $class = new $class;
407                                 if ($class->is_test())
408                                 {
409                                         $this->add($class);
410                                 }
411                         }
412                 }
413         }
414
415         /**
416          * Run the tests
417          *
418          * @access public
419          */
420         function run()
421         {
422                 $this->pre();
423                 $start_time = $this->microtime(true);
424                 foreach ($this->tests as $tests)
425                 {
426                         foreach ($tests as $test)
427                         {
428                                 if ($this->is_a($test, 'Unit_Test2') || $this->is_a($test, 'Unit_Test2_Group'))
429                                 {
430                                         $test->run();
431                                         $this->passes += $test->passes();
432                                         $this->fails += $test->fails();
433                                 }
434                         }
435                 }
436                 $this->time = $this->microtime(true) - $start_time;
437                 $this->post();
438         }
439
440         /**
441          * Executed before the tests are executed
442          *
443          * @abstract
444          * @access protected
445          */
446         function pre()
447         {
448         }
449
450         /**
451          * Executed after the tests are executed
452          *
453          * @abstract
454          * @access protected
455          */
456         function post()
457         {
458         }
459
460         /**
461          * Re-implementation of PHP 5.0.3's is_subclass_of()
462          *
463          * @access public
464          * @param mixed $object
465          * @param string $class_name
466          */
467         function is_subclass_of($object, $class_name)
468         {
469                 if (func_num_args() != 2)
470                 {
471                         trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING);
472                 }
473                 else
474                 {
475                         if (version_compare(phpversion(), '5.0.3', '>=') || is_object($object))
476                         {
477                                 return is_subclass_of($object, $class_name);
478                         }
479                         else if (is_string($object) && is_string($class_name))
480                         {
481                                 if (class_exists($object))
482                                 {
483                                         if (class_exists($class_name))
484                                         {
485                                                 $class_name = strtolower($class_name);
486                                                 while ($object = strtolower(get_parent_class($object)))
487                                                 {
488                                                         if ($object == $class_name)
489                                                         {
490                                                                 return true;
491                                                         }
492                                                 }
493                                         }
494                                 }
495                                 else
496                                 {
497                                         trigger_error('Unknown class passed as parameter', E_USER_WARNNG);
498                                 }
499                         }
500                         return false;
501                 }
502         }
503
504         /**
505          * Re-implementation of PHP 4.2.0's is_a()
506          *
507          * @access public
508          * @param object $object The tested object
509          * @param string $class_name The class name
510          * @return bool Returns true if the object is of this class or has this class as one of its parents, false otherwise
511          */
512          function is_a($object, $class_name)
513          {
514                 if (function_exists('is_a'))
515                 {
516                         return is_a($object, $class_name);
517                 }
518                 elseif (!is_object($object))
519                 {
520                         return false;
521                 }
522                 elseif (get_class($object) == strtolower($class_name))
523                 {
524                         return true;
525                 }
526                 else
527                 {
528                         return is_subclass_of($object, $class_name);
529                 }
530          }
531
532         /**
533          * Re-implementation of PHP 5's microtime()
534          *
535          * @access public
536          * @param bool $get_as_float
537          */
538         function microtime($get_as_float = false)
539         {
540                 if ($get_as_float)
541                 {
542                         if (is_float($time = microtime(true)))
543                         {
544                                 return $time;
545                         }
546                         else
547                         {
548                                 list($user, $sec) = explode(' ', $time);
549                                 return ((float) $user + (float) $sec);
550                         }
551                 }
552                 else
553                 {
554                         // PHP6 will likely return a float by default, so explicitly pass false (this is just ignored under PHP < 5)
555                         return microtime(false);
556                 }
557         }
558 }
559
560 /**
561  * File listing class
562  *
563  * @package Unit Test
564  */
565 class Unit_Test2_Files
566 {
567         /**
568          * Get a list of files/folders within $dir
569          *
570          * @static
571          * @access public
572          * @param string $dir Folder to get listing for
573          * @return array
574          */
575         function get_files($dir)
576         {
577                 $files = array();
578                 if ($dh = opendir($dir))
579                 {
580                         while (($file = readdir($dh)) !== false)
581                         {
582                                 if (substr($file, 0, 1) != '.')
583                                 {
584                                         $files[] = "$dir/$file";
585                                 }
586                         }
587                         closedir($dh);
588                         usort($files, array(__CLASS__, 'sort_files'));
589                         foreach ($files as $file)
590                         {
591                                 if (is_dir($file))
592                                 {
593                                         array_splice($files, array_search($file, $files), 0, Unit_Test2_Files::get_files($file));
594                                 }
595                         }
596                 }
597                 return $files;
598         }
599
600         /**
601          * Sort files/folders with files listed before inner folders
602          *
603          * @static
604          * @access public
605          * @param string $a File/folder 1
606          * @param string $b File/folder 2
607          * @return int
608          */
609         function sort_files($a, $b)
610         {
611                 if (is_dir($a) && is_dir($b))
612                 {
613                         return strnatcmp($a, $b);
614                 }
615                 else if (is_dir($a))
616                 {
617                         return 1;
618                 }
619                 else if (is_dir($b))
620                 {
621                         return -1;
622                 }
623                 else
624                 {
625                         return strnatcmp($a, $b);
626                 }
627         }
628 }
629
630 ?>