3 * @author Antoine Musso
4 * @copyright Copyright © 2013, Antoine Musso
5 * @copyright Copyright © 2013, Wikimedia Foundation Inc.
9 class MWExceptionTest
extends MediaWikiTestCase
{
12 * @expectedException MWException
14 public function testMwexceptionThrowing() {
15 throw new MWException();
19 * @dataProvider provideTextUseOutputPage
20 * @covers MWException::useOutputPage
22 public function testUseOutputPage( $expected, $langObj, $wgFullyInitialised, $wgOut ) {
23 $this->setMwGlobals( [
25 'wgFullyInitialised' => $wgFullyInitialised,
29 $e = new MWException();
30 $this->assertEquals( $expected, $e->useOutputPage() );
33 public function provideTextUseOutputPage() {
35 // expected, langObj, wgFullyInitialised, wgOut
36 [ false, null, null, null ],
37 [ false, $this->getMockLanguage(), null, null ],
38 [ false, $this->getMockLanguage(), true, null ],
39 [ false, null, true, null ],
40 [ false, null, null, true ],
41 [ true, $this->getMockLanguage(), true, true ],
45 private function getMockLanguage() {
46 return $this->getMockBuilder( 'Language' )
47 ->disableOriginalConstructor()
52 * @dataProvider provideUseMessageCache
53 * @covers MWException::useMessageCache
55 public function testUseMessageCache( $expected, $langObj ) {
56 $this->setMwGlobals( [
59 $e = new MWException();
60 $this->assertEquals( $expected, $e->useMessageCache() );
63 public function provideUseMessageCache() {
66 [ true, $this->getMockLanguage() ],
71 * @covers MWException::isLoggable
73 public function testIsLogable() {
74 $e = new MWException();
75 $this->assertTrue( $e->isLoggable() );
79 * @dataProvider provideRunHooks
80 * @covers MWException::runHooks
82 public function testRunHooks( $wgExceptionHooks, $name, $args, $expectedReturn ) {
83 $this->setMwGlobals( [
84 'wgExceptionHooks' => $wgExceptionHooks,
86 $e = new MWException();
87 $this->assertEquals( $expectedReturn, $e->runHooks( $name, $args ) );
90 public static function provideRunHooks() {
92 [ null, null, null, null ],
93 [ [], 'name', [], null ],
94 [ [ 'name' => false ], 'name', [], null ],
96 [ 'mockHook' => [ 'MWExceptionTest::mockHook' ] ],
97 'mockHook', [], 'YAY.[]'
100 [ 'mockHook' => [ 'MWExceptionTest::mockHook' ] ],
101 'mockHook', [ 'a' ], 'YAY.{"1":"a"}'
104 [ 'mockHook' => [ 'MWExceptionTest::mockHook' ] ],
105 'mockHook', [ null ], null
111 * Used in conjunction with provideRunHooks and testRunHooks as a mock callback for a hook
113 public static function mockHook() {
114 $args = func_get_args();
115 if ( !$args[0] instanceof MWException
) {
116 return '$caller not instance of MWException';
119 if ( array_key_exists( 1, $args ) && $args[1] === null ) {
122 return 'YAY.' . json_encode( $args );
126 * @dataProvider provideIsCommandLine
127 * @covers MWException::isCommandLine
129 public function testisCommandLine( $expected, $wgCommandLineMode ) {
130 $this->setMwGlobals( [
131 'wgCommandLineMode' => $wgCommandLineMode,
133 $e = new MWException();
134 $this->assertEquals( $expected, $e->isCommandLine() );
137 public static function provideIsCommandLine() {
145 * Verify the exception classes are JSON serializabe.
147 * @covers MWExceptionHandler::jsonSerializeException
148 * @dataProvider provideExceptionClasses
150 public function testJsonSerializeExceptions( $exception_class ) {
151 $json = MWExceptionHandler
::jsonSerializeException(
152 new $exception_class()
154 $this->assertNotEquals( false, $json,
155 "The $exception_class exception should be JSON serializable, got false." );
158 public static function provideExceptionClasses() {
166 * Lame JSON schema validation.
168 * @covers MWExceptionHandler::jsonSerializeException
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
175 public function testJsonserializeexceptionKeys( $expectedKeyType, $exClass, $key ) {
176 # Make sure we log a backtrace:
177 $this->setMwGlobals( [ 'wgLogExceptionBacktrace' => true ] );
180 MWExceptionHandler
::jsonSerializeException( new $exClass() )
182 $this->assertObjectHasAttribute( $key, $json,
183 "JSON serialized exception is missing key '$key'"
185 $this->assertInternalType( $expectedKeyType, $json->$key,
186 "JSON serialized key '$key' has type " . gettype( $json->$key )
187 . " (expected: $expectedKeyType)."
192 * Returns test cases: exception class, key name, gettype()
194 public static function provideJsonSerializedKeys() {
196 foreach ( [ 'Exception', 'MWException' ] as $exClass ) {
198 [ 'string', $exClass, 'id' ],
199 [ 'string', $exClass, 'file' ],
200 [ 'integer', $exClass, 'line' ],
201 [ 'string', $exClass, 'message' ],
202 [ 'null', $exClass, 'url' ],
203 # Backtrace only enabled with wgLogExceptionBacktrace = true
204 [ 'array', $exClass, 'backtrace' ],
206 $testCases = array_merge( $testCases, $exTests );
212 * Given wgLogExceptionBacktrace is true
213 * then serialized exception SHOULD have a backtrace
215 * @covers MWExceptionHandler::jsonSerializeException
217 public function testJsonserializeexceptionBacktracingEnabled() {
218 $this->setMwGlobals( [ 'wgLogExceptionBacktrace' => true ] );
220 MWExceptionHandler
::jsonSerializeException( new Exception() )
222 $this->assertObjectHasAttribute( 'backtrace', $json );
226 * Given wgLogExceptionBacktrace is false
227 * then serialized exception SHOULD NOT have a backtrace
229 * @covers MWExceptionHandler::jsonSerializeException
231 public function testJsonserializeexceptionBacktracingDisabled() {
232 $this->setMwGlobals( [ 'wgLogExceptionBacktrace' => false ] );
234 MWExceptionHandler
::jsonSerializeException( new Exception() )
236 $this->assertObjectNotHasAttribute( 'backtrace', $json );