1<?php
2@include_once 'Text/Diff.php';
3@include_once 'Text/Diff/Renderer.php';
4@include_once 'Text/Diff/Renderer/unified.php';
5require_once 'PEAR/ErrorStack.php';
6require_once 'PEAR.php';
7class PEAR_PHPTest
8{
9    var $_diffonly;
10    var $_errors;
11    function PEAR_PHPTest($diffonly = false)
12    {
13        $this->_diffonly = $diffonly;
14        $this->_errors = array();
15        PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array(&$this, 'pearerrorCallback'));
16        PEAR_ErrorStack::setDefaultCallback(array(&$this, 'pearerrorstackCallback'));
17    }
18
19    function pearerrorCallback($err)
20    {
21        PEAR_ErrorStack::staticPush('PEAR_Error', -1, 'error', array('obj' => $err),
22            $err->getMessage());
23    }
24
25    function pearerrorstackCallback($err)
26    {
27        $this->_errors[] = $err;
28    }
29
30    function assertPEARError($err, $message)
31    {
32        if (is_a($err, 'PEAR_Error')) {
33            return true;
34        }
35        $this->_failTest(debug_backtrace(), $message);
36        echo "Not a PEAR_Error\n";
37        return false;
38    }
39
40    function assertNoErrors($message, $trace = null)
41    {
42        if (count($this->_errors) == 0) {
43            return true;
44        }
45        if ($trace === null) {
46            $trace = debug_backtrace();
47        }
48        $this->_failTest($trace, $message);
49        foreach ($this->_errors as $err) {
50            if ($err['package'] == 'PEAR_Error') {
51                echo "Unexpected PEAR_Error:\n";
52                echo 'message "' . $err['message'] . "\"\n";
53            } else {
54                echo "Unexpected PEAR_ErrorStack error:\n";
55                echo 'package "' . $err['package'] . "\"\n";
56                echo 'message "' . $err['message'] . "\"\n";
57            }
58        }
59        $this->_errors = array();
60        return false;
61    }
62
63    function assertErrors($errors, $message, $trace = null)
64    {
65        if (!count($this->_errors)) {
66            if ($trace === null) {
67                $trace = debug_backtrace();
68            }
69            $this->_failTest($trace, $message);
70            echo "No errors caught, but errors were expected\n";
71            return false;
72        }
73        if (!isset($errors[0])) {
74            $errors = array($errors);
75        }
76        $failed = false;
77        foreach ($errors as $err) {
78            $found = false;
79            foreach ($this->_errors as $i => $caughterror) {
80                if ($caughterror['package'] == $err['package']) {
81                    if ($caughterror['message'] == $err['message']) {
82                        $found = true;
83                        break;
84                    }
85                }
86            }
87            if ($found) {
88                unset($this->_errors[$i]);
89                continue;
90            }
91            if (!$failed) {
92                if ($trace === null) {
93                    $trace = debug_backtrace();
94                }
95                $failed = true;
96                $this->_failTest($trace, $message);
97            }
98            echo "Unthrown error:\n";
99            if ($err['package'] == 'PEAR_Error') {
100                echo "PEAR_Error:\n";
101            } else {
102                echo "error package: \"$err[package]\"\n";
103            }
104            echo "message: \"$err[message]\"\n";
105        }
106        if (count($this->_errors)) {
107            if (!$failed) {
108                if ($trace === null) {
109                    $trace = debug_backtrace();
110                }
111                $failed = true;
112                $this->_failTest($trace, $message);
113            }
114            foreach ($this->_errors as $err) {
115                echo "Unexpected error:\n";
116                if ($err['package'] == 'PEAR_Error') {
117                    echo "PEAR_Error:\n";
118                } else {
119                    echo "error package: \"$err[package]\"\n";
120                }
121                echo "message: \"$err[message]\"\n";
122            }
123        }
124        $this->_errors = array();
125        return !$failed;
126    }
127
128    function assertTrue($test, $message)
129    {
130        $this->assertNoErrors($message, debug_backtrace());
131        if ($test === true) {
132            return true;
133        }
134        $this->_failTest(debug_backtrace(), $message);
135        echo "Unexpected non-true value: \n";
136        var_export($test);
137        echo "\n'$message'\n";
138        return false;
139    }
140
141    function assertIsa($control, $test, $message)
142    {
143        $this->assertNoErrors($message, debug_backtrace());
144        if (is_a($test, $control)) {
145            return true;
146        }
147        $this->_failTest(debug_backtrace(), $message);
148        echo "Unexpected non-$control object: \n";
149        var_export($test);
150        echo "\n'$message'\n";
151        return false;
152    }
153
154    function assertNull($test, $message)
155    {
156        $this->assertNoErrors($message, debug_backtrace());
157        if ($test === null) {
158            return true;
159        }
160        $this->_failTest(debug_backtrace(), $message);
161        echo "Unexpected non-null value: \n";
162        var_export($test);
163        echo "\n'$message'\n";
164        return false;
165    }
166
167    function assertNotNull($test, $message)
168    {
169        $this->assertNoErrors($message, debug_backtrace());
170        if ($test !== null) {
171            return true;
172        }
173        $this->_failTest(debug_backtrace(), $message);
174        echo "Unexpected null: \n";
175        var_export($test);
176        echo "\n'$message'\n";
177        return false;
178    }
179
180    function assertSame($test, $test1, $message)
181    {
182        $this->assertNoErrors($message, debug_backtrace());
183        if ($test === $test1) {
184            return true;
185        }
186        $this->_failTest(debug_backtrace(), $message);
187        echo "Unexpectedly two vars are not the same thing: \n";
188        echo "\n'$message'\n";
189        return false;
190    }
191
192    function assertNotSame($test, $test1, $message)
193    {
194        $this->assertNoErrors($message, debug_backtrace());
195        if ($test !== $test1) {
196            return true;
197        }
198        $this->_failTest(debug_backtrace(), $message);
199        echo "Unexpectedly two vars are the same thing: \n";
200        echo "\n'$message'\n";
201        return false;
202    }
203
204    function assertFalse($test, $message)
205    {
206        $this->assertNoErrors($message, debug_backtrace());
207        if ($test === false) {
208            return true;
209        }
210        $this->_failTest(debug_backtrace(), $message);
211        echo "Unexpected non-false value: \n";
212        var_export($test);
213        echo "\n'$message'\n";
214        return false;
215    }
216
217    function assertNotTrue($test, $message)
218    {
219        $this->assertNoErrors($message, debug_backtrace());
220        if (!$test) {
221            return true;
222        }
223        $this->_failTest(debug_backtrace(), $message);
224        echo "Unexpected loose true value: \n";
225        var_export($test);
226        echo "\n'$message'\n";
227        return false;
228    }
229
230    function assertNotFalse($test, $message)
231    {
232        $this->assertNoErrors($message, debug_backtrace());
233        if ($test) {
234            return true;
235        }
236        $this->_failTest(debug_backtrace(), $message);
237        echo "Unexpected loose false value: \n";
238        var_export($test);
239        echo "\n'$message'\n";
240        return false;
241    }
242
243    function assertEquals($control, $test, $message)
244    {
245        $this->assertNoErrors($message, debug_backtrace());
246        if (str_replace(array("\r", "\n"), array('', ''),
247            var_export($control, true)) != str_replace(array("\r", "\n"), array('', ''),
248            var_export($test, true))) {
249            $this->_failTest(debug_backtrace(), $message);
250            if (class_exists('Text_Diff')) {
251                echo "Diff of expecting/received:\n";
252                $diff = &new Text_Diff(
253                    explode("\n", var_export($control, true)),
254                    explode("\n", var_export($test, true)));
255
256                // Output the diff in unified format.
257                $renderer = &new Text_Diff_Renderer_unified();
258                echo $renderer->render($diff);
259                if ($this->_diffonly) {
260                    return false;
261                }
262            }
263            echo "Expecting:\n";
264            var_export($control);
265            echo "\nReceived:\n";
266            var_export($test);
267            return false;
268        }
269        return true;
270    }
271
272    function assertFileExists($fname, $message)
273    {
274        $this->assertNoErrors($message, debug_backtrace());
275        if (!@file_exists($fname)) {
276            $this->_failTest(debug_backtrace(), $message);
277            echo "File '$fname' does not exist, and should\n";
278            return false;
279        }
280        return true;
281    }
282
283    function assertFileNotExists($fname, $message)
284    {
285        $this->assertNoErrors($message, debug_backtrace());
286        if (@file_exists($fname)) {
287            $this->_failTest(debug_backtrace(), $message);
288            echo "File '$fname' exists, and should not\n";
289            return false;
290        }
291        return true;
292    }
293
294    function assertRegEquals($dump, &$reg, $message)
295    {
296        $actualdump = var_export(trim($this->dumpReg($reg)), true);
297        $testdump = var_export(trim($dump), true);
298        return $this->assertEquals($testdump, $actualdump, $message);
299    }
300
301    function assertPackageInfoEquals($control, $test, $message)
302    {
303        $this->assertNoErrors($message, debug_backtrace());
304        if (isset($control[0])) {
305            if (!isset($test[0]) || (count($control) != count($test))) {
306                echo "Invalid packageInfo\n";
307                $ret = $this->assertEquals($control, $test, $message);
308            }
309            $ret = true;
310            foreach ($control as $i => $packageinfo) {
311                $ret = $ret &&
312                    $this->assertPackageInfoEquals($packageinfo, $test[$i], $message . $i);
313            }
314            return $ret;
315        }
316        if (isset($control['_lastmodified'])) {
317            if (!isset($test['_lastmodified'])) {
318                echo "_lastmodified is not set in packageInfo() output\n";
319                $this->_failTest(debug_backtrace(), $message);
320                return false;
321            }
322        }
323        $savecontrol = $control;
324        $savetest = $test;
325        unset($control['_lastmodified']);
326        unset($test['_lastmodified']);
327        if (var_export($control, true) != var_export($test, true)) {
328            $this->_failTest(debug_backtrace(), $message);
329            if (class_exists('Text_Diff')) {
330                echo "Diff of expecting/received:\n";
331                $diff = &new Text_Diff(
332                    explode("\n", var_export($control, true)),
333                    explode("\n", var_export($test, true)));
334
335                // Output the diff in unified format.
336                $renderer = &new Text_Diff_Renderer_unified();
337                echo $renderer->render($diff);
338                if ($this->_diffonly) {
339                    return false;
340                }
341            }
342            echo "Expecting:\n";
343            var_export($savecontrol);
344            echo "\nReceived:\n";
345            var_export($savetest);
346            return false;
347        }
348        return true;
349    }
350
351    function dumpReg(&$reg)
352    {
353        ob_start();
354        print "dumping registry...\n";
355        $infos = $reg->packageInfo(null, null, null);
356        foreach ($infos as $channel => $info) {
357            echo "channel $channel:\n";
358            foreach ($info as $pkg) {
359                print $pkg["name"] . ":";
360                unset($pkg["name"]);
361                foreach ($pkg as $k => $v) {
362                    if ($k == '_lastmodified') {
363                        print " _lastmodified is set";
364                        continue;
365                    }
366                    if (is_array($v) && $k == 'filelist') {
367                        print " $k=array(";
368                        $i = 0;
369                        foreach ($v as $k2 => $v2) {
370                            if ($i++ > 0) print ",";
371                            print "{$k2}[";
372                            $j = 0;
373                            foreach ($v2 as $k3 => $v3) {
374                                if ($j++ > 0) print ",";
375                                print "$k3=$v3";
376                            }
377                            print "]";
378                        }
379                        print ")";
380                    } else {
381                        print " $k=\"$v\"";
382                    }
383                }
384                print "\n";
385            }
386        }
387        print "dump done\n";
388        $ret = ob_get_contents();
389        ob_end_clean();
390        return $ret;
391    }
392
393    function _failTest($trace, $message)
394    {
395        echo 'Test Failure: "' . $message  . "\"\n in " . $trace[0]['file'] . ' line ' .
396            $trace[0]['line'] . "\n";
397    }
398
399    function showAll()
400    {
401        $this->_diffonly = false;
402    }
403}
404?>