source: trunk/server/www/vendors/simpletest/simpletest.php @ 6

Last change on this file since 6 was 6, checked in by sander, 12 years ago

Added SimpleTest? test framework

File size: 13.3 KB
Line 
1<?php
2/**
3 *  Global state for SimpleTest and kicker script in future versions.
4 *  @package    SimpleTest
5 *  @subpackage UnitTester
6 *  @version    $Id: simpletest.php 1723 2008-04-08 00:34:10Z lastcraft $
7 */
8
9/**#@+
10 * include SimpleTest files
11 */
12if (version_compare(phpversion(), '5') >= 0) {
13    require_once(dirname(__FILE__) . '/reflection_php5.php');
14} else {
15    require_once(dirname(__FILE__) . '/reflection_php4.php');
16}
17require_once(dirname(__FILE__) . '/default_reporter.php');
18require_once(dirname(__FILE__) . '/compatibility.php');
19/**#@-*/
20
21/**
22 *    Registry and test context. Includes a few
23 *    global options that I'm slowly getting rid of.
24 *    @package  SimpleTest
25 *    @subpackage   UnitTester
26 */
27class SimpleTest {
28
29    /**
30     *    Reads the SimpleTest version from the release file.
31     *    @return string        Version string.
32     *    @static
33     *    @access public
34     */
35    function getVersion() {
36        $content = file(dirname(__FILE__) . '/VERSION');
37        return trim($content[0]);
38    }
39
40    /**
41     *    Sets the name of a test case to ignore, usually
42     *    because the class is an abstract case that should
43     *    not be run. Once PHP4 is dropped this will disappear
44     *    as a public method and "abstract" will rule.
45     *    @param string $class        Add a class to ignore.
46     *    @static
47     *    @access public
48     */
49    function ignore($class) {
50        $registry = &SimpleTest::_getRegistry();
51        $registry['IgnoreList'][strtolower($class)] = true;
52    }
53
54    /**
55     *    Scans the now complete ignore list, and adds
56     *    all parent classes to the list. If a class
57     *    is not a runnable test case, then it's parents
58     *    wouldn't be either. This is syntactic sugar
59     *    to cut down on ommissions of ignore()'s or
60     *    missing abstract declarations. This cannot
61     *    be done whilst loading classes wiithout forcing
62     *    a particular order on the class declarations and
63     *    the ignore() calls. It's just nice to have the ignore()
64     *    calls at the top of the file before the actual declarations.
65     *    @param array $classes     Class names of interest.
66     *    @static
67     *    @access public
68     */
69    function ignoreParentsIfIgnored($classes) {
70        $registry = &SimpleTest::_getRegistry();
71        foreach ($classes as $class) {
72            if (SimpleTest::isIgnored($class)) {
73                $reflection = new SimpleReflection($class);
74                if ($parent = $reflection->getParent()) {
75                    SimpleTest::ignore($parent);
76                }
77            }
78        }
79    }
80
81    /**
82     *   Puts the object to the global pool of 'preferred' objects
83     *   which can be retrieved with SimpleTest :: preferred() method.
84     *   Instances of the same class are overwritten.
85     *   @param object $object      Preferred object
86     *   @static
87     *   @access public
88     *   @see preferred()
89     */
90    function prefer(&$object) {
91        $registry = &SimpleTest::_getRegistry();
92        $registry['Preferred'][] = &$object;
93    }
94
95    /**
96     *   Retrieves 'preferred' objects from global pool. Class filter
97     *   can be applied in order to retrieve the object of the specific
98     *   class
99     *   @param array|string $classes       Allowed classes or interfaces.
100     *   @static
101     *   @access public
102     *   @return array|object|null
103     *   @see prefer()
104     */
105    function &preferred($classes) {
106        if (! is_array($classes)) {
107            $classes = array($classes);
108        }
109        $registry = &SimpleTest::_getRegistry();
110        for ($i = count($registry['Preferred']) - 1; $i >= 0; $i--) {
111            foreach ($classes as $class) {
112                if (SimpleTestCompatibility::isA($registry['Preferred'][$i], $class)) {
113                    return $registry['Preferred'][$i];
114                }
115            }
116        }
117        return null;
118    }
119
120    /**
121     *    Test to see if a test case is in the ignore
122     *    list. Quite obviously the ignore list should
123     *    be a separate object and will be one day.
124     *    This method is internal to SimpleTest. Don't
125     *    use it.
126     *    @param string $class        Class name to test.
127     *    @return boolean             True if should not be run.
128     *    @access public
129     *    @static
130     */
131    function isIgnored($class) {
132        $registry = &SimpleTest::_getRegistry();
133        return isset($registry['IgnoreList'][strtolower($class)]);
134    }
135
136    /**
137     *    @deprecated
138     */
139    function setMockBaseClass($mock_base) {
140        $registry = &SimpleTest::_getRegistry();
141        $registry['MockBaseClass'] = $mock_base;
142    }
143
144    /**
145     *    @deprecated
146     */
147    function getMockBaseClass() {
148        $registry = &SimpleTest::_getRegistry();
149        return $registry['MockBaseClass'];
150    }
151
152    /**
153     *    Sets proxy to use on all requests for when
154     *    testing from behind a firewall. Set host
155     *    to false to disable. This will take effect
156     *    if there are no other proxy settings.
157     *    @param string $proxy     Proxy host as URL.
158     *    @param string $username  Proxy username for authentication.
159     *    @param string $password  Proxy password for authentication.
160     *    @access public
161     */
162    function useProxy($proxy, $username = false, $password = false) {
163        $registry = &SimpleTest::_getRegistry();
164        $registry['DefaultProxy'] = $proxy;
165        $registry['DefaultProxyUsername'] = $username;
166        $registry['DefaultProxyPassword'] = $password;
167    }
168
169    /**
170     *    Accessor for default proxy host.
171     *    @return string       Proxy URL.
172     *    @access public
173     */
174    function getDefaultProxy() {
175        $registry = &SimpleTest::_getRegistry();
176        return $registry['DefaultProxy'];
177    }
178
179    /**
180     *    Accessor for default proxy username.
181     *    @return string    Proxy username for authentication.
182     *    @access public
183     */
184    function getDefaultProxyUsername() {
185        $registry = &SimpleTest::_getRegistry();
186        return $registry['DefaultProxyUsername'];
187    }
188
189    /**
190     *    Accessor for default proxy password.
191     *    @return string    Proxy password for authentication.
192     *    @access public
193     */
194    function getDefaultProxyPassword() {
195        $registry = &SimpleTest::_getRegistry();
196        return $registry['DefaultProxyPassword'];
197    }
198
199    /**
200     *    Accessor for global registry of options.
201     *    @return hash           All stored values.
202     *    @access private
203     *    @static
204     */
205    function &_getRegistry() {
206        static $registry = false;
207        if (! $registry) {
208            $registry = SimpleTest::_getDefaults();
209        }
210        return $registry;
211    }
212
213    /**
214     *    Accessor for the context of the current
215     *    test run.
216     *    @return SimpleTestContext    Current test run.
217     *    @access public
218     *    @static
219     */
220    function &getContext() {
221        static $context = false;
222        if (! $context) {
223            $context = new SimpleTestContext();
224        }
225        return $context;
226    }
227
228    /**
229     *    Constant default values.
230     *    @return hash       All registry defaults.
231     *    @access private
232     *    @static
233     */
234    function _getDefaults() {
235        return array(
236                'StubBaseClass' => 'SimpleStub',
237                'MockBaseClass' => 'SimpleMock',
238                'IgnoreList' => array(),
239                'DefaultProxy' => false,
240                'DefaultProxyUsername' => false,
241                'DefaultProxyPassword' => false,
242                'Preferred' => array(new HtmlReporter(), new TextReporter(), new XmlReporter()));
243    }
244}
245
246/**
247 *    Container for all components for a specific
248 *    test run. Makes things like error queues
249 *    available to PHP event handlers, and also
250 *    gets around some nasty reference issues in
251 *    the mocks.
252 *    @package  SimpleTest
253 */
254class SimpleTestContext {
255    var $_test;
256    var $_reporter;
257    var $_resources;
258
259    /**
260     *    Clears down the current context.
261     *    @access public
262     */
263    function clear() {
264        $this->_resources = array();
265    }
266
267    /**
268     *    Sets the current test case instance. This
269     *    global instance can be used by the mock objects
270     *    to send message to the test cases.
271     *    @param SimpleTestCase $test        Test case to register.
272     *    @access public
273     */
274    function setTest(&$test) {
275        $this->clear();
276        $this->_test = &$test;
277    }
278
279    /**
280     *    Accessor for currently running test case.
281     *    @return SimpleTestCase    Current test.
282     *    @access public
283     */
284    function &getTest() {
285        return $this->_test;
286    }
287
288    /**
289     *    Sets the current reporter. This
290     *    global instance can be used by the mock objects
291     *    to send messages.
292     *    @param SimpleReporter $reporter     Reporter to register.
293     *    @access public
294     */
295    function setReporter(&$reporter) {
296        $this->clear();
297        $this->_reporter = &$reporter;
298    }
299
300    /**
301     *    Accessor for current reporter.
302     *    @return SimpleReporter    Current reporter.
303     *    @access public
304     */
305    function &getReporter() {
306        return $this->_reporter;
307    }
308
309    /**
310     *    Accessor for the Singleton resource.
311     *    @return object       Global resource.
312     *    @access public
313     *    @static
314     */
315    function &get($resource) {
316        if (! isset($this->_resources[$resource])) {
317            $this->_resources[$resource] = &new $resource();
318        }
319        return $this->_resources[$resource];
320    }
321}
322
323/**
324 *    Interrogates the stack trace to recover the
325 *    failure point.
326 *    @package SimpleTest
327 *    @subpackage UnitTester
328 */
329class SimpleStackTrace {
330    var $_prefixes;
331
332    /**
333     *    Stashes the list of target prefixes.
334     *    @param array $prefixes      List of method prefixes
335     *                                to search for.
336     */
337    function SimpleStackTrace($prefixes) {
338        $this->_prefixes = $prefixes;
339    }
340
341    /**
342     *    Extracts the last method name that was not within
343     *    Simpletest itself. Captures a stack trace if none given.
344     *    @param array $stack      List of stack frames.
345     *    @return string           Snippet of test report with line
346     *                             number and file.
347     *    @access public
348     */
349    function traceMethod($stack = false) {
350        $stack = $stack ? $stack : $this->_captureTrace();
351        foreach ($stack as $frame) {
352            if ($this->_frameLiesWithinSimpleTestFolder($frame)) {
353                continue;
354            }
355            if ($this->_frameMatchesPrefix($frame)) {
356                return ' at [' . $frame['file'] . ' line ' . $frame['line'] . ']';
357            }
358        }
359        return '';
360    }
361
362    /**
363     *    Test to see if error is generated by SimpleTest itself.
364     *    @param array $frame     PHP stack frame.
365     *    @return boolean         True if a SimpleTest file.
366     *    @access private
367     */
368    function _frameLiesWithinSimpleTestFolder($frame) {
369        if (isset($frame['file'])) {
370            $path = substr(SIMPLE_TEST, 0, -1);
371            if (strpos($frame['file'], $path) === 0) {
372                if (dirname($frame['file']) == $path) {
373                    return true;
374                }
375            }
376        }
377        return false;
378    }
379
380    /**
381     *    Tries to determine if the method call is an assert, etc.
382     *    @param array $frame     PHP stack frame.
383     *    @return boolean         True if matches a target.
384     *    @access private
385     */
386    function _frameMatchesPrefix($frame) {
387        foreach ($this->_prefixes as $prefix) {
388            if (strncmp($frame['function'], $prefix, strlen($prefix)) == 0) {
389                return true;
390            }
391        }
392        return false;
393    }
394
395    /**
396     *    Grabs a current stack trace.
397     *    @return array        Fulle trace.
398     *    @access private
399     */
400    function _captureTrace() {
401        if (function_exists('debug_backtrace')) {
402            return array_reverse(debug_backtrace());
403        }
404        return array();
405    }
406}
407
408/**
409 *    @package SimpleTest
410 *    @subpackage UnitTester
411 *    @deprecated
412 */
413class SimpleTestOptions extends SimpleTest {
414
415    /**
416     *    @deprecated
417     */
418    function getVersion() {
419        return Simpletest::getVersion();
420    }
421
422    /**
423     *    @deprecated
424     */
425    function ignore($class) {
426        return Simpletest::ignore($class);
427    }
428
429    /**
430     *    @deprecated
431     */
432    function isIgnored($class) {
433        return Simpletest::isIgnored($class);
434    }
435
436    /**
437     *    @deprecated
438     */
439    function setMockBaseClass($mock_base) {
440        return Simpletest::setMockBaseClass($mock_base);
441    }
442
443    /**
444     *    @deprecated
445     */
446    function getMockBaseClass() {
447        return Simpletest::getMockBaseClass();
448    }
449
450    /**
451     *    @deprecated
452     */
453    function useProxy($proxy, $username = false, $password = false) {
454        return Simpletest::useProxy($proxy, $username, $password);
455    }
456
457    /**
458     *    @deprecated
459     */
460    function getDefaultProxy() {
461        return Simpletest::getDefaultProxy();
462    }
463
464    /**
465     *    @deprecated
466     */
467    function getDefaultProxyUsername() {
468        return Simpletest::getDefaultProxyUsername();
469    }
470
471    /**
472     *    @deprecated
473     */
474    function getDefaultProxyPassword() {
475        return Simpletest::getDefaultProxyPassword();
476    }
477}
478?>
Note: See TracBrowser for help on using the repository browser.