56 if ( $this->shutdownSimulated ) {
57 $this->testCase->fail( __METHOD__ .
" called more than once" );
64 $this->shutdownSimulated =
true;
69 if ( $this->shutdownSimulated ) {
70 if ( $msg !==
false ) {
71 $this->testCase->fail(
"Already past simulated shutdown, but msg is "
72 .
"not false. Did the hack in Maintenance.php change? Please "
73 .
"adapt the test case or Maintenance.php" );
83 call_user_func_array( [
"parent", __FUNCTION__ ], func_get_args() );
90 if ( !$this->shutdownSimulated ) {
96 $name = $this->testCase->getName();
97 fwrite( STDERR,
"ERROR! Instance of " . __CLASS__ .
" for test $name "
98 .
"destructed without calling simulateShutdown method. Call "
99 .
"simulateShutdown on the instance before it gets destructed." );
103 if ( is_callable(
"parent::__destruct" ) ) {
104 parent::__destruct();
109 parent::__construct();
120 return call_user_func_array( [
"parent", __FUNCTION__ ], func_get_args() );
124 $withArg =
false, $shortName =
false, $multiOccurance =
false
126 return call_user_func_array( [
"parent", __FUNCTION__ ], func_get_args() );
130 return call_user_func_array( [
"parent", __FUNCTION__ ], func_get_args() );
136 $this->testCase->fail( __METHOD__ .
" called unexpectedly" );
159 $this->m->simulateShutdown();
179 $this->assertEquals( $preShutdownOutput, $this->getActualOutput(),
180 "Output before shutdown simulation" );
182 $this->m->simulateShutdown();
185 $postShutdownOutput = $preShutdownOutput . ( $expectNLAppending ?
"\n" :
"" );
186 $this->expectOutputString( $postShutdownOutput );
195 $this->m->output(
"" );
200 $this->m->output(
"foo" );
205 $this->m->output(
"foo" );
206 $this->m->output(
"bar" );
211 $this->m->output(
"foo\n" );
216 $this->m->output(
"foo\n\n" );
221 $this->m->output(
"foo\nbar" );
226 $this->m->output(
"foo\nbar\n" );
231 $this->m->output(
"foo\n" );
232 $this->m->output(
"bar\n" );
237 $this->m->output(
"" );
238 $this->m->output(
"foo" );
239 $this->m->output(
"" );
240 $this->m->output(
"\n" );
241 $this->m->output(
"ba" );
242 $this->m->output(
"" );
243 $this->m->output(
"r\n" );
248 $this->m->output(
"" );
249 $this->m->output(
"foo" );
250 $this->m->output(
"" );
251 $this->m->output(
"\nb" );
252 $this->m->output(
"a" );
253 $this->m->output(
"" );
254 $this->m->output(
"r\n" );
259 $this->m->output(
"",
null );
264 $this->m->output(
"foo",
null );
269 $this->m->output(
"foo",
null );
270 $this->m->output(
"bar",
null );
275 $this->m->output(
"foo\n",
null );
280 $this->m->output(
"foo\n\n",
null );
285 $this->m->output(
"foo\nbar",
null );
290 $this->m->output(
"foo\nbar\n",
null );
295 $this->m->output(
"foo\n",
null );
296 $this->m->output(
"bar\n",
null );
301 $this->m->output(
"",
null );
302 $this->m->output(
"foo",
null );
303 $this->m->output(
"",
null );
304 $this->m->output(
"\n",
null );
305 $this->m->output(
"ba",
null );
306 $this->m->output(
"",
null );
307 $this->m->output(
"r\n",
null );
312 $this->m->output(
"",
null );
313 $this->m->output(
"foo",
null );
314 $this->m->output(
"",
null );
315 $this->m->output(
"\nb",
null );
316 $this->m->output(
"a",
null );
317 $this->m->output(
"",
null );
318 $this->m->output(
"r\n",
null );
323 $this->m->output(
"foo",
"bazChannel" );
328 $this->m->output(
"foo\n",
"bazChannel" );
337 $this->m->output(
"foo\n\n",
"bazChannel" );
342 $this->m->output(
"foo\nbar",
"bazChannel" );
347 $this->m->output(
"foo\nbar\n",
"bazChannel" );
352 $this->m->output(
"foo\n",
"bazChannel" );
353 $this->m->output(
"bar\n",
"bazChannel" );
358 $this->m->output(
"",
"bazChannel" );
359 $this->m->output(
"foo",
"bazChannel" );
360 $this->m->output(
"",
"bazChannel" );
361 $this->m->output(
"\n",
"bazChannel" );
362 $this->m->output(
"ba",
"bazChannel" );
363 $this->m->output(
"",
"bazChannel" );
364 $this->m->output(
"r\n",
"bazChannel" );
369 $this->m->output(
"",
"bazChannel" );
370 $this->m->output(
"foo",
"bazChannel" );
371 $this->m->output(
"",
"bazChannel" );
372 $this->m->output(
"\nb",
"bazChannel" );
373 $this->m->output(
"a",
"bazChannel" );
374 $this->m->output(
"",
"bazChannel" );
375 $this->m->output(
"r\n",
"bazChannel" );
380 $this->m->output(
"foo",
"bazChannel" );
381 $this->m->output(
"bar",
"bazChannel" );
382 $this->m->output(
"qux",
"quuxChannel" );
383 $this->m->output(
"corge",
"bazChannel" );
388 $this->m->output(
"foo",
"bazChannel" );
389 $this->m->output(
"bar\n",
"bazChannel" );
390 $this->m->output(
"qux\n",
"quuxChannel" );
391 $this->m->output(
"corge",
"bazChannel" );
396 $this->m->output(
"foo" );
397 $this->m->output(
"bar",
"bazChannel" );
398 $this->m->output(
"qux" );
399 $this->m->output(
"quux",
"bazChannel" );
404 $this->m->output(
"foo",
"bazChannel" );
405 $this->m->output(
"bar" );
406 $this->m->output(
"qux",
"bazChannel" );
407 $this->m->output(
"quux" );
412 $this->m->output(
"foo", 1 );
413 $this->m->output(
"bar", 1.0 );
418 $this->m->output(
"foo" );
419 $this->m->output(
"" );
420 $this->m->output(
"bar" );
425 $this->m->output(
"foo" );
426 $this->m->output(
false );
427 $this->m->output(
"bar" );
432 $this->m->output(
"qux",
"quuxChannel" );
433 $this->m->output(
"foo" );
434 $this->m->output(
false );
435 $this->m->output(
"bar" );
440 $this->m->output(
"foo",
null );
441 $this->m->output(
"",
null );
442 $this->m->output(
"bar",
null );
447 $this->m->output(
"foo",
null );
448 $this->m->output(
false,
null );
449 $this->m->output(
"bar",
null );
454 $this->m->output(
"foo",
"bazChannel" );
455 $this->m->output(
"",
"bazChannel" );
456 $this->m->output(
"bar",
"bazChannel" );
461 $this->m->output(
"foo",
"bazChannel" );
462 $this->m->output(
false,
"bazChannel" );
463 $this->m->output(
"bar",
"bazChannel" );
471 $this->m->outputChanneled(
"" );
476 $this->m->outputChanneled(
"foo" );
481 $this->m->outputChanneled(
"foo" );
482 $this->m->outputChanneled(
"bar" );
487 $this->m->outputChanneled(
"foo\nbar" );
492 $this->m->outputChanneled(
"" );
493 $this->m->outputChanneled(
"foo" );
494 $this->m->outputChanneled(
"" );
495 $this->m->outputChanneled(
"\nb" );
496 $this->m->outputChanneled(
"a" );
497 $this->m->outputChanneled(
"" );
498 $this->m->outputChanneled(
"r" );
503 $this->m->outputChanneled(
"",
null );
508 $this->m->outputChanneled(
"foo",
null );
513 $this->m->outputChanneled(
"foo",
null );
514 $this->m->outputChanneled(
"bar",
null );
519 $this->m->outputChanneled(
"foo\nbar",
null );
524 $this->m->outputChanneled(
"",
null );
525 $this->m->outputChanneled(
"foo",
null );
526 $this->m->outputChanneled(
"",
null );
527 $this->m->outputChanneled(
"\nb",
null );
528 $this->m->outputChanneled(
"a",
null );
529 $this->m->outputChanneled(
"",
null );
530 $this->m->outputChanneled(
"r",
null );
535 $this->m->outputChanneled(
"foo",
"bazChannel" );
540 $this->m->outputChanneled(
"foo\nbar",
"bazChannel" );
545 $this->m->outputChanneled(
"foo",
"bazChannel" );
546 $this->m->outputChanneled(
"bar",
"bazChannel" );
551 $this->m->outputChanneled(
"",
"bazChannel" );
552 $this->m->outputChanneled(
"foo",
"bazChannel" );
553 $this->m->outputChanneled(
"",
"bazChannel" );
554 $this->m->outputChanneled(
"\nb",
"bazChannel" );
555 $this->m->outputChanneled(
"a",
"bazChannel" );
556 $this->m->outputChanneled(
"",
"bazChannel" );
557 $this->m->outputChanneled(
"r",
"bazChannel" );
562 $this->m->outputChanneled(
"foo",
"bazChannel" );
563 $this->m->outputChanneled(
"bar",
"bazChannel" );
564 $this->m->outputChanneled(
"qux",
"quuxChannel" );
565 $this->m->outputChanneled(
"corge",
"bazChannel" );
570 $this->m->outputChanneled(
"foo",
"bazChannel" );
571 $this->m->outputChanneled(
"bar",
null );
572 $this->m->outputChanneled(
"qux",
null );
573 $this->m->outputChanneled(
"corge",
"bazChannel" );
578 $this->m->outputChanneled(
"foo",
"bazChannel" );
579 $this->m->outputChanneled(
"bar",
null );
580 $this->m->outputChanneled(
"qux",
null );
581 $this->m->outputChanneled(
"corge",
"quuxChannel" );
586 $this->m->outputChanneled(
"foo" );
587 $this->m->outputChanneled(
"bar",
"bazChannel" );
588 $this->m->outputChanneled(
"qux" );
589 $this->m->outputChanneled(
"quux",
"bazChannel" );
594 $this->m->outputChanneled(
"foo",
"bazChannel" );
595 $this->m->outputChanneled(
"bar" );
596 $this->m->outputChanneled(
"qux",
"bazChannel" );
597 $this->m->outputChanneled(
"quux" );
602 $this->m->outputChanneled(
"foo", 1 );
603 $this->m->outputChanneled(
"bar", 1.0 );
608 $this->m->outputChanneled(
"foo" );
609 $this->m->outputChanneled(
"" );
610 $this->m->outputChanneled(
"bar" );
615 $this->m->outputChanneled(
"foo" );
616 $this->m->outputChanneled(
false );
617 $this->m->outputChanneled(
"bar" );
622 $this->m->outputChanneled(
"foo",
null );
623 $this->m->outputChanneled(
"",
null );
624 $this->m->outputChanneled(
"bar",
null );
629 $this->m->outputChanneled(
"foo",
null );
630 $this->m->outputChanneled(
false,
null );
631 $this->m->outputChanneled(
"bar",
null );
636 $this->m->outputChanneled(
"foo",
"bazChannel" );
637 $this->m->outputChanneled(
"",
"bazChannel" );
638 $this->m->outputChanneled(
"bar",
"bazChannel" );
643 $this->m->outputChanneled(
"foo",
"bazChannel" );
644 $this->m->outputChanneled(
false,
"bazChannel" );
645 $this->m->outputChanneled(
"bar",
"bazChannel" );
650 $this->m->cleanupChanneled();
655 $this->m->output(
"foo" );
656 $this->m->cleanupChanneled();
661 $this->m->output(
"foo",
null );
662 $this->m->cleanupChanneled();
667 $this->m->output(
"foo",
"bazChannel" );
668 $this->m->cleanupChanneled();
673 $this->m->output(
"foo\n" );
674 $this->m->cleanupChanneled();
679 $this->m->output(
"foo\n",
null );
680 $this->m->cleanupChanneled();
685 $this->m->output(
"foo\n",
"bazChannel" );
686 $this->m->cleanupChanneled();
691 $this->m->outputChanneled(
"foo" );
692 $this->m->cleanupChanneled();
697 $this->m->outputChanneled(
"foo",
null );
698 $this->m->cleanupChanneled();
703 $this->m->outputChanneled(
"foo",
"bazChannel" );
704 $this->m->cleanupChanneled();
711 $this->m->output(
"foo" );
712 $m2->output(
"bar" );
714 $this->assertEquals(
"foobar", $this->getActualOutput(),
715 "Output before shutdown simulation (m2)" );
716 $m2->simulateShutdown();
723 $this->m->output(
"foo",
null );
724 $m2->output(
"bar",
null );
726 $this->assertEquals(
"foobar", $this->getActualOutput(),
727 "Output before shutdown simulation (m2)" );
728 $m2->simulateShutdown();
735 $this->m->output(
"foo",
"bazChannel" );
736 $m2->output(
"bar",
"bazChannel" );
738 $this->assertEquals(
"foobar", $this->getActualOutput(),
739 "Output before shutdown simulation (m2)" );
740 $m2->simulateShutdown();
747 $this->m->output(
"foo\n",
null );
748 $m2->output(
"bar\n",
null );
750 $this->assertEquals(
"foo\nbar\n", $this->getActualOutput(),
751 "Output before shutdown simulation (m2)" );
752 $m2->simulateShutdown();
759 $this->m->output(
"foo\n",
"bazChannel" );
760 $m2->output(
"bar\n",
"bazChannel" );
762 $this->assertEquals(
"foobar", $this->getActualOutput(),
763 "Output before shutdown simulation (m2)" );
764 $m2->simulateShutdown();
771 $this->m->outputChanneled(
"foo" );
772 $m2->outputChanneled(
"bar" );
774 $this->assertEquals(
"foo\nbar\n", $this->getActualOutput(),
775 "Output before shutdown simulation (m2)" );
776 $m2->simulateShutdown();
783 $this->m->outputChanneled(
"foo",
null );
784 $m2->outputChanneled(
"bar",
null );
786 $this->assertEquals(
"foo\nbar\n", $this->getActualOutput(),
787 "Output before shutdown simulation (m2)" );
788 $m2->simulateShutdown();
795 $this->m->outputChanneled(
"foo",
"bazChannel" );
796 $m2->outputChanneled(
"bar",
"bazChannel" );
798 $this->assertEquals(
"foobar", $this->getActualOutput(),
799 "Output before shutdown simulation (m2)" );
800 $m2->simulateShutdown();
807 $this->m->outputChanneled(
"foo",
"bazChannel" );
808 $m2->outputChanneled(
"bar",
"bazChannel" );
810 $this->assertEquals(
"foobar", $this->getActualOutput(),
811 "Output before first cleanup" );
812 $this->m->cleanupChanneled();
813 $this->assertEquals(
"foobar\n", $this->getActualOutput(),
814 "Output after first cleanup" );
815 $m2->cleanupChanneled();
816 $this->assertEquals(
"foobar\n\n", $this->getActualOutput(),
817 "Output after second cleanup" );
819 $m2->simulateShutdown();
827 $this->assertInstanceOf(
'Config', $this->m->getConfig() );
829 MediaWikiServices::getInstance()->getMainConfig(),
830 $this->m->getConfig()
838 $conf = $this->createMock(
'Config' );
839 $this->m->setConfig( $conf );
840 $this->assertSame( $conf, $this->m->getConfig() );
846 $m2->addOption(
'multi',
'This option does stuff',
false,
true,
false,
true );
847 $m2->loadWithArgv( [
'--multi',
'this1',
'--multi',
'this2' ] );
849 $this->assertEquals( [
'this1',
'this2' ], $m2->getOption(
'multi' ) );
850 $this->assertEquals( [ [
'multi',
'this1' ], [
'multi',
'this2' ] ],
851 $m2->orderedOptions );
853 $m2->simulateShutdown();
857 $m2->addOption(
'multi',
'This option does stuff',
false,
false,
false,
true );
858 $m2->loadWithArgv( [
'--multi',
'--multi' ] );
860 $this->assertEquals( [ 1, 1 ], $m2->getOption(
'multi' ) );
861 $this->assertEquals( [ [
'multi', 1 ], [
'multi', 1 ] ], $m2->orderedOptions );
863 $m2->simulateShutdown();
867 $m2->addOption(
'multi',
'This option doesn\'t actually support multiple occurrences' );
868 $m2->loadWithArgv( [
'--multi=yo' ] );
870 $this->assertEquals(
'yo', $m2->getOption(
'multi' ) );
871 $this->assertEquals( [ [
'multi',
'yo' ] ], $m2->orderedOptions );
873 $m2->simulateShutdown();