Merge "Don't check namespace in SpecialWantedtemplates"
[lhc/web/wiklou.git] / tests / phpunit / includes / exception / MWExceptionTest.php
1 <?php
2 /**
3 * @author Antoine Musso
4 * @copyright Copyright © 2013, Antoine Musso
5 * @copyright Copyright © 2013, Wikimedia Foundation Inc.
6 * @file
7 */
8
9 class MWExceptionTest extends MediaWikiTestCase {
10
11 /**
12 * @expectedException MWException
13 */
14 public function testMwexceptionThrowing() {
15 throw new MWException();
16 }
17
18 /**
19 * @dataProvider provideTextUseOutputPage
20 * @covers MWException::useOutputPage
21 */
22 public function testUseOutputPage( $expected, $wgLang, $wgFullyInitialised, $wgOut ) {
23 $this->setMwGlobals( array(
24 'wgLang' => $wgLang,
25 'wgFullyInitialised' => $wgFullyInitialised,
26 'wgOut' => $wgOut,
27 ) );
28
29 $e = new MWException();
30 $this->assertEquals( $expected, $e->useOutputPage() );
31 }
32
33 public function provideTextUseOutputPage() {
34 return array(
35 // expected, wgLang, wgFullyInitialised, wgOut
36 array( false, null, null, null ),
37 array( false, $this->getMockLanguage(), null, null ),
38 array( false, $this->getMockLanguage(), true, null ),
39 array( false, null, true, null ),
40 array( false, null, null, true ),
41 array( true, $this->getMockLanguage(), true, true ),
42 );
43 }
44
45 private function getMockLanguage() {
46 return $this->getMockBuilder( 'Language' )
47 ->disableOriginalConstructor()
48 ->getMock();
49 }
50
51 /**
52 * @dataProvider provideUseMessageCache
53 * @covers MWException::useMessageCache
54 */
55 public function testUseMessageCache( $expected, $wgLang ) {
56 $this->setMwGlobals( array(
57 'wgLang' => $wgLang,
58 ) );
59 $e = new MWException();
60 $this->assertEquals( $expected, $e->useMessageCache() );
61 }
62
63 public function provideUseMessageCache() {
64 return array(
65 array( false, null ),
66 array( true, $this->getMockLanguage() ),
67 );
68 }
69
70 /**
71 * @covers MWException::isLoggable
72 */
73 public function testIsLogable() {
74 $e = new MWException();
75 $this->assertTrue( $e->isLoggable() );
76 }
77
78 /**
79 * @dataProvider provideRunHooks
80 * @covers MWException::runHooks
81 */
82 public function testRunHooks( $wgExceptionHooks, $name, $args, $expectedReturn ) {
83 $this->setMwGlobals( array(
84 'wgExceptionHooks' => $wgExceptionHooks,
85 ) );
86 $e = new MWException();
87 $this->assertEquals( $expectedReturn, $e->runHooks( $name, $args ) );
88 }
89
90 public static function provideRunHooks() {
91 return array(
92 array( null, null, null, null ),
93 array( array(), 'name', array(), null ),
94 array( array( 'name' => false ), 'name', array(), null ),
95 array(
96 array( 'mockHook' => array( 'MWExceptionTest::mockHook' ) ),
97 'mockHook', array(), 'YAY.[]'
98 ),
99 array(
100 array( 'mockHook' => array( 'MWExceptionTest::mockHook' ) ),
101 'mockHook', array( 'a' ), 'YAY.{"1":"a"}'
102 ),
103 array(
104 array( 'mockHook' => array( 'MWExceptionTest::mockHook' ) ),
105 'mockHook', array( null ), null
106 ),
107 );
108 }
109
110 /**
111 * Used in conjunction with provideRunHooks and testRunHooks as a mock callback for a hook
112 */
113 public static function mockHook() {
114 $args = func_get_args();
115 if ( !$args[0] instanceof MWException ) {
116 return '$caller not instance of MWException';
117 }
118 unset( $args[0] );
119 if ( array_key_exists( 1, $args ) && $args[1] === null ) {
120 return null;
121 }
122 return 'YAY.' . json_encode( $args );
123 }
124
125 /**
126 * @dataProvider provideIsCommandLine
127 * @covers MWException::isCommandLine
128 */
129 public function testisCommandLine( $expected, $wgCommandLineMode ) {
130 $this->setMwGlobals( array(
131 'wgCommandLineMode' => $wgCommandLineMode,
132 ) );
133 $e = new MWException();
134 $this->assertEquals( $expected, $e->isCommandLine() );
135 }
136
137 public static function provideIsCommandLine() {
138 return array(
139 array( false, null ),
140 array( true, true ),
141 );
142 }
143
144 /**
145 * Verify the exception classes are JSON serializabe.
146 *
147 * @covers MWExceptionHandler::jsonSerializeException
148 * @dataProvider provideExceptionClasses
149 */
150 public function testJsonSerializeExceptions( $exception_class ) {
151 $json = MWExceptionHandler::jsonSerializeException(
152 new $exception_class()
153 );
154 $this->assertNotEquals( false, $json,
155 "The $exception_class exception should be JSON serializable, got false." );
156 }
157
158 public static function provideExceptionClasses() {
159 return array(
160 array( 'Exception' ),
161 array( 'MWException' ),
162 );
163 }
164
165 /**
166 * Lame JSON schema validation.
167 *
168 * @covers MWExceptionHandler::jsonSerializeException
169 *
170 * @param string $expectedKeyType Type expected as returned by gettype()
171 * @param string $exClass An exception class (ie: Exception, MWException)
172 * @param string $key Name of the key to validate in the serialized JSON
173 * @dataProvider provideJsonSerializedKeys
174 */
175 public function testJsonserializeexceptionKeys( $expectedKeyType, $exClass, $key ) {
176
177 # Make sure we log a backtrace:
178 $this->setMwGlobals( array( 'wgLogExceptionBacktrace' => true ) );
179
180 $json = json_decode(
181 MWExceptionHandler::jsonSerializeException( new $exClass() )
182 );
183 $this->assertObjectHasAttribute( $key, $json,
184 "JSON serialized exception is missing key '$key'"
185 );
186 $this->assertInternalType( $expectedKeyType, $json->$key,
187 "JSON serialized key '$key' has type " . gettype( $json->$key )
188 . " (expected: $expectedKeyType)."
189 );
190 }
191
192 /**
193 * Returns test cases: exception class, key name, gettype()
194 */
195 public static function provideJsonSerializedKeys() {
196 $testCases = array();
197 foreach ( array( 'Exception', 'MWException' ) as $exClass ) {
198 $exTests = array(
199 array( 'string', $exClass, 'id' ),
200 array( 'string', $exClass, 'file' ),
201 array( 'integer', $exClass, 'line' ),
202 array( 'string', $exClass, 'message' ),
203 array( 'null', $exClass, 'url' ),
204 # Backtrace only enabled with wgLogExceptionBacktrace = true
205 array( 'array', $exClass, 'backtrace' ),
206 );
207 $testCases = array_merge( $testCases, $exTests );
208 }
209 return $testCases;
210 }
211
212 /**
213 * Given wgLogExceptionBacktrace is true
214 * then serialized exception SHOULD have a backtrace
215 *
216 * @covers MWExceptionHandler::jsonSerializeException
217 */
218 public function testJsonserializeexceptionBacktracingEnabled() {
219 $this->setMwGlobals( array( 'wgLogExceptionBacktrace' => true ) );
220 $json = json_decode(
221 MWExceptionHandler::jsonSerializeException( new Exception() )
222 );
223 $this->assertObjectHasAttribute( 'backtrace', $json );
224 }
225
226 /**
227 * Given wgLogExceptionBacktrace is false
228 * then serialized exception SHOULD NOT have a backtrace
229 *
230 * @covers MWExceptionHandler::jsonSerializeException
231 */
232 public function testJsonserializeexceptionBacktracingDisabled() {
233 $this->setMwGlobals( array( 'wgLogExceptionBacktrace' => false ) );
234 $json = json_decode(
235 MWExceptionHandler::jsonSerializeException( new Exception() )
236 );
237 $this->assertObjectNotHasAttribute( 'backtrace', $json );
238
239 }
240
241 }