xref: /dokuwiki/_test/core/DokuWikiTest.php (revision 01ef6ea2906c3ad2ecb460be3a26261a0444d837)
1<?php
2
3
4if(!class_exists('PHPUnit_Framework_TestCase')) {
5    /**
6     * phpunit 5/6 compatibility
7     */
8    class PHPUnit_Framework_TestCase extends PHPUnit\Framework\TestCase {
9        /**
10         * @param string $class
11         * @param null|string $message
12         */
13        public function setExpectedException($class, $message=null) {
14            $this->expectException($class);
15            if(!is_null($message)) {
16                $this->expectExceptionMessage($message);
17            }
18        }
19    }
20}
21
22
23
24/**
25 * Helper class to provide basic functionality for tests
26 */
27abstract class DokuWikiTest extends PHPUnit_Framework_TestCase {
28
29    /**
30     * tests can override this
31     *
32     * @var array plugins to enable for test class
33     */
34    protected $pluginsEnabled = array();
35
36    /**
37     * tests can override this
38     *
39     * @var array plugins to disable for test class
40     */
41    protected $pluginsDisabled = array();
42
43    /**
44     * Setup the data directory
45     *
46     * This is ran before each test class
47     */
48    public static function setUpBeforeClass() {
49        // just to be safe not to delete something undefined later
50        if(!defined('TMP_DIR')) die('no temporary directory');
51        if(!defined('DOKU_TMP_DATA')) die('no temporary data directory');
52
53        // remove any leftovers from the last run
54        if(is_dir(DOKU_TMP_DATA)){
55            // clear indexer data and cache
56            idx_get_indexer()->clear();
57            TestUtils::rdelete(DOKU_TMP_DATA);
58        }
59
60        // populate default dirs
61        TestUtils::rcopy(TMP_DIR, dirname(__FILE__).'/../data/');
62    }
63
64    /**
65     * Reset the DokuWiki environment before each test run. Makes sure loaded config,
66     * language and plugins are correct.
67     *
68     * @throws Exception if plugin actions fail
69     * @return void
70     */
71    public function setUp() {
72
73        // reload config
74        global $conf, $config_cascade;
75        $conf = array();
76        foreach (array('default','local','protected') as $config_group) {
77            if (empty($config_cascade['main'][$config_group])) continue;
78            foreach ($config_cascade['main'][$config_group] as $config_file) {
79                if (file_exists($config_file)) {
80                    include($config_file);
81                }
82            }
83        }
84
85        // reload license config
86        global $license;
87        $license = array();
88
89        // load the license file(s)
90        foreach (array('default','local') as $config_group) {
91            if (empty($config_cascade['license'][$config_group])) continue;
92            foreach ($config_cascade['license'][$config_group] as $config_file) {
93                if(file_exists($config_file)){
94                    include($config_file);
95                }
96            }
97        }
98        // reload some settings
99        $conf['gzip_output'] &= (strpos($_SERVER['HTTP_ACCEPT_ENCODING'],'gzip') !== false);
100
101        if($conf['compression'] == 'bz2' && !DOKU_HAS_BZIP) {
102            $conf['compression'] = 'gz';
103        }
104        if($conf['compression'] == 'gz' && !DOKU_HAS_GZIP) {
105            $conf['compression'] = 0;
106        }
107        // make real paths and check them
108        init_paths();
109        init_files();
110
111        // reset loaded plugins
112        global $plugin_controller_class, $plugin_controller;
113        /** @var Doku_Plugin_Controller $plugin_controller */
114        $plugin_controller = new $plugin_controller_class();
115
116        // disable all non-default plugins
117        global $default_plugins;
118        foreach ($plugin_controller->getList() as $plugin) {
119            if (!in_array($plugin, $default_plugins)) {
120                if (!$plugin_controller->disable($plugin)) {
121                    throw new Exception('Could not disable plugin "'.$plugin.'"!');
122                }
123            }
124        }
125
126        // disable and enable configured plugins
127        foreach ($this->pluginsDisabled as $plugin) {
128            if (!$plugin_controller->disable($plugin)) {
129                throw new Exception('Could not disable plugin "'.$plugin.'"!');
130            }
131        }
132        foreach ($this->pluginsEnabled as $plugin) {
133            /*  enable() returns false but works...
134            if (!$plugin_controller->enable($plugin)) {
135                throw new Exception('Could not enable plugin "'.$plugin.'"!');
136            }
137            */
138            $plugin_controller->enable($plugin);
139        }
140
141        // reset event handler
142        global $EVENT_HANDLER;
143        $EVENT_HANDLER = new Doku_Event_Handler();
144
145        // reload language
146        $local = $conf['lang'];
147        trigger_event('INIT_LANG_LOAD', $local, 'init_lang', true);
148
149        global $INPUT;
150        $INPUT = new Input();
151    }
152
153    /**
154     * Compatibility for older PHPUnit versions
155     *
156     * @param string $originalClassName
157     * @return PHPUnit_Framework_MockObject_MockObject
158     */
159    protected function createMock($originalClassName) {
160        if(is_callable(array('parent', 'createMock'))) {
161            return parent::createMock($originalClassName);
162        } else {
163            return $this->getMock($originalClassName);
164        }
165    }
166
167    /**
168     * Compatibility for older PHPUnit versions
169     *
170     * @param string $originalClassName
171     * @param array $methods
172     * @return PHPUnit_Framework_MockObject_MockObject
173     */
174    protected function createPartialMock($originalClassName, array $methods) {
175        if(is_callable(array('parent', 'createPartialMock'))) {
176            return parent::createPartialMock($originalClassName, $methods);
177        } else {
178            return $this->getMock($originalClassName, $methods);
179        }
180    }
181
182    /**
183     * Waits until a new second has passed
184     *
185     * The very first call will return immeadiately, proceeding calls will return
186     * only after at least 1 second after the last call has passed.
187     *
188     * When passing $init=true it will not return immeadiately but use the current
189     * second as initialization. It might still return faster than a second.
190     *
191     * @param bool $init wait from now on, not from last time
192     * @return int new timestamp
193     */
194    protected function waitForTick($init = false) {
195        static $last = 0;
196        if($init) $last = time();
197        while($last === $now = time()) {
198            usleep(100000); //recheck in a 10th of a second
199        }
200        $last = $now;
201        return $now;
202    }
203}
204