JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
Fix db_get_value after mysql->mysqli upgrade
[wfpl.git] / unit_tests.php
1 <?php
2
3 # This program is in the public domain within the United States. Additionally,
4 # we waive copyright and related rights in the work worldwide through the CC0
5 # 1.0 Universal public domain dedication, which can be found at
6 # http://creativecommons.org/publicdomain/zero/1.0/
7
8
9 # This file is for running unit tests. Either on wfpl or your own code.
10
11 require_once(__DIR__.'/'.'template.php');
12 require_once(__DIR__.'/'.'messages.php');
13
14 # call this to declare that a unit test has passed
15 function unit_test_passed($msg) {
16         $GLOBALS['unit_tests_passed_msgs'][] = $msg;
17         $GLOBALS['unit_tests_passed'] += 1;
18 }
19
20 # call this to declare that a unit test has failed
21 function unit_test_failed($msg) {
22         $GLOBALS['unit_tests_failed_msgs'][] = $msg;
23         $GLOBALS['unit_tests_failed'] += 1;
24 }
25
26 function backslashinate($str) {
27         return '"' . addcslashes($str, "\0..\37\"\\\177..\377") . '"';
28 }
29
30 function backslashinate_each($a) {
31         foreach($a as &$v) {
32                 $v = backslashinate($v);
33         }
34
35         return $a;
36 }
37         
38
39 # use this function to unit-test a function
40 # real prototype: ($name, $args..., $correct)
41 function unit_test_func() {
42         $args = func_get_args();
43         $function = array_shift($args);
44         $correct = array_pop($args);
45         $result = call_user_func_array($function, $args);
46         $message = "$function(" . join(', ', backslashinate_each($args)) . ") returned " . backslashinate($result);
47         if($result === $correct) {
48                 unit_test_passed($message);
49         } else {
50                 unit_test_failed($message . " instead of " . backslashinate($correct));
51         }
52 }
53
54
55 function file_run_unit_tests($filename) {
56         require_once($filename);
57         $func = basename($filename, '.php') . '_unit_tests_main';
58
59         if(function_exists($func)) {
60                 return $func();
61         }
62 }
63
64 # Run many unit tests. Pass a directory containing php files with tests in
65 # them, and a space-separated list of their basenames. Each of those files is
66 # expected to define a function <basename>_unit_tests_main which will run all
67 # tests in that file. It should print a message() about each test that failed,
68 # and return the number of tests that failed.
69 function run_unit_tests($directory, $basenames) {
70         $files = array();
71         $GLOBALS['unit_tests_passed'] = 0;
72         $GLOBALS['unit_tests_failed'] = 0;
73         $basenames = explode(' ', $basenames);
74         foreach($basenames as $basename) {
75                 $GLOBALS['unit_tests_passed_msgs'] = array();
76                 $GLOBALS['unit_tests_failed_msgs'] = array();
77                 $already_passed = $GLOBALS['unit_tests_passed'];
78                 $already_failed = $GLOBALS['unit_tests_failed'];
79                 $filename = "$directory/$basename.php";
80                 file_run_unit_tests($filename);
81                 $files[] = array(
82                         'file' => $filename,
83                         'fails' => columnize($GLOBALS['unit_tests_failed_msgs']),
84                         'passes' => columnize($GLOBALS['unit_tests_passed_msgs']),
85                         'count_passed' => $GLOBALS['unit_tests_passed'] - $already_passed,
86                         'count_failed' => $GLOBALS['unit_tests_failed'] - $already_failed
87                 );
88         }
89         $passed = $GLOBALS['unit_tests_passed'];
90         $failed = $GLOBALS['unit_tests_failed'];
91         tem_set('unit_tests', array(
92                 'files' => $files,
93                 'total_passed' => $passed,
94                 'total_failed' => $failed
95         ));
96 }
97
98 # Call this to unit test wfpl. By default it tests everything, or you can pass
99 # a space-separated list of the basenames of the files in wfpl/unit_tests/
100 # that you'd like to run.
101 function unit_test_wfpl($basenames = 'format db misc encode') {
102         tem_load(__DIR__.'/'.'unit_tests/template.html');
103         run_unit_tests(__DIR__.'/'.'unit_tests', $basenames);
104         display_messages();
105         tem_output();
106         exit();
107 }