MediaWiki REL1_28
MaintenanceTest.php
Go to the documentation of this file.
1<?php
2
3// It would be great if we were able to use PHPUnit's getMockForAbstractClass
4// instead of the MaintenanceFixup hack below. However, we cannot do
5// without changing the visibility and without working around hacks in
6// Maintenance.php
7// For the same reason, we cannot just use FakeMaintenance.
8
29
30 // --- Making up for the register_shutdown_function hack in Maintenance.php
31
42 private $testCase;
43
49 private $shutdownSimulated = false;
50
54 public function simulateShutdown() {
55
56 if ( $this->shutdownSimulated ) {
57 $this->testCase->fail( __METHOD__ . " called more than once" );
58 }
59
60 // The cleanup action.
61 $this->outputChanneled( false );
62
63 // Bookkeeping that we simulated the clean up.
64 $this->shutdownSimulated = true;
65 }
66
67 // Note that the "public" here does not change visibility
68 public function outputChanneled( $msg, $channel = null ) {
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" );
74 }
75
76 // The current call is the one registered via register_shutdown_function.
77 // We can safely ignore it, as we simulated this one via simulateShutdown
78 // before (if we did not, the destructor of this instance will warn about
79 // it)
80 return;
81 }
82
83 call_user_func_array( [ "parent", __FUNCTION__ ], func_get_args() );
84 }
85
89 public function __destruct() {
90 if ( !$this->shutdownSimulated ) {
91 // Someone generated a MaintenanceFixup instance without calling
92 // simulateShutdown. We'd have to raise a PHPUnit exception to correctly
93 // flag this illegal usage. However, we are already in a destruktor, which
94 // would trigger undefined behavior. Hence, we can only report to the
95 // error output :( Hopefully people read the PHPUnit output.
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." );
100 }
101
102 // The following guard is required, as PHP does not offer default destructors :(
103 if ( is_callable( "parent::__destruct" ) ) {
104 parent::__destruct();
105 }
106 }
107
109 parent::__construct();
110 $this->testCase = $testCase;
111 }
112
113 // --- Making protected functions visible for test
114
115 public function output( $out, $channel = null ) {
116 // Just to make PHP not nag about signature mismatches, we copied
117 // Maintenance::output signature. However, we do not use (or rely on)
118 // those variables. Instead we pass to Maintenance::output whatever we
119 // receive at runtime.
120 return call_user_func_array( [ "parent", __FUNCTION__ ], func_get_args() );
121 }
122
123 public function addOption( $name, $description, $required = false,
124 $withArg = false, $shortName = false, $multiOccurance = false
125 ) {
126 return call_user_func_array( [ "parent", __FUNCTION__ ], func_get_args() );
127 }
128
129 public function getOption( $name, $default = null ) {
130 return call_user_func_array( [ "parent", __FUNCTION__ ], func_get_args() );
131 }
132
133 // --- Requirements for getting instance of abstract class
134
135 public function execute() {
136 $this->testCase->fail( __METHOD__ . " called unexpectedly" );
137 }
138}
139
144
150 private $m;
151
152 protected function setUp() {
153 parent::setUp();
154 $this->m = new MaintenanceFixup( $this );
155 }
156
157 protected function tearDown() {
158 if ( $this->m ) {
159 $this->m->simulateShutdown();
160 $this->m = null;
161 }
162 parent::tearDown();
163 }
164
177 private function assertOutputPrePostShutdown( $preShutdownOutput, $expectNLAppending ) {
178
179 $this->assertEquals( $preShutdownOutput, $this->getActualOutput(),
180 "Output before shutdown simulation" );
181
182 $this->m->simulateShutdown();
183 $this->m = null;
184
185 $postShutdownOutput = $preShutdownOutput . ( $expectNLAppending ? "\n" : "" );
186 $this->expectOutputString( $postShutdownOutput );
187 }
188
189 // Although the following tests do not seem to be too consistent (compare for
190 // example the newlines within the test.*StringString tests, or the
191 // test.*Intermittent.* tests), the objective of these tests is not to describe
192 // consistent behavior, but rather currently existing behavior.
193
194 function testOutputEmpty() {
195 $this->m->output( "" );
196 $this->assertOutputPrePostShutdown( "", false );
197 }
198
199 function testOutputString() {
200 $this->m->output( "foo" );
201 $this->assertOutputPrePostShutdown( "foo", false );
202 }
203
205 $this->m->output( "foo" );
206 $this->m->output( "bar" );
207 $this->assertOutputPrePostShutdown( "foobar", false );
208 }
209
211 $this->m->output( "foo\n" );
212 $this->assertOutputPrePostShutdown( "foo\n", false );
213 }
214
216 $this->m->output( "foo\n\n" );
217 $this->assertOutputPrePostShutdown( "foo\n\n", false );
218 }
219
221 $this->m->output( "foo\nbar" );
222 $this->assertOutputPrePostShutdown( "foo\nbar", false );
223 }
224
226 $this->m->output( "foo\nbar\n" );
227 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
228 }
229
231 $this->m->output( "foo\n" );
232 $this->m->output( "bar\n" );
233 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
234 }
235
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" );
244 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
245 }
246
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" );
255 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
256 }
257
259 $this->m->output( "", null );
260 $this->assertOutputPrePostShutdown( "", false );
261 }
262
264 $this->m->output( "foo", null );
265 $this->assertOutputPrePostShutdown( "foo", false );
266 }
267
269 $this->m->output( "foo", null );
270 $this->m->output( "bar", null );
271 $this->assertOutputPrePostShutdown( "foobar", false );
272 }
273
275 $this->m->output( "foo\n", null );
276 $this->assertOutputPrePostShutdown( "foo\n", false );
277 }
278
280 $this->m->output( "foo\n\n", null );
281 $this->assertOutputPrePostShutdown( "foo\n\n", false );
282 }
283
285 $this->m->output( "foo\nbar", null );
286 $this->assertOutputPrePostShutdown( "foo\nbar", false );
287 }
288
290 $this->m->output( "foo\nbar\n", null );
291 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
292 }
293
295 $this->m->output( "foo\n", null );
296 $this->m->output( "bar\n", null );
297 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
298 }
299
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 );
308 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
309 }
310
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 );
319 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
320 }
321
323 $this->m->output( "foo", "bazChannel" );
324 $this->assertOutputPrePostShutdown( "foo", true );
325 }
326
328 $this->m->output( "foo\n", "bazChannel" );
329 $this->assertOutputPrePostShutdown( "foo", true );
330 }
331
333 // If this test fails, note that output takes strings with double line
334 // endings (although output's implementation in this situation calls
335 // outputChanneled with a string ending in a nl ... which is not allowed
336 // according to the documentation of outputChanneled)
337 $this->m->output( "foo\n\n", "bazChannel" );
338 $this->assertOutputPrePostShutdown( "foo\n", true );
339 }
340
342 $this->m->output( "foo\nbar", "bazChannel" );
343 $this->assertOutputPrePostShutdown( "foo\nbar", true );
344 }
345
347 $this->m->output( "foo\nbar\n", "bazChannel" );
348 $this->assertOutputPrePostShutdown( "foo\nbar", true );
349 }
350
352 $this->m->output( "foo\n", "bazChannel" );
353 $this->m->output( "bar\n", "bazChannel" );
354 $this->assertOutputPrePostShutdown( "foobar", true );
355 }
356
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" );
365 $this->assertOutputPrePostShutdown( "foobar", true );
366 }
367
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" );
376 $this->assertOutputPrePostShutdown( "foo\nbar", true );
377 }
378
380 $this->m->output( "foo", "bazChannel" );
381 $this->m->output( "bar", "bazChannel" );
382 $this->m->output( "qux", "quuxChannel" );
383 $this->m->output( "corge", "bazChannel" );
384 $this->assertOutputPrePostShutdown( "foobar\nqux\ncorge", true );
385 }
386
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" );
392 $this->assertOutputPrePostShutdown( "foobar\nqux\ncorge", true );
393 }
394
396 $this->m->output( "foo" );
397 $this->m->output( "bar", "bazChannel" );
398 $this->m->output( "qux" );
399 $this->m->output( "quux", "bazChannel" );
400 $this->assertOutputPrePostShutdown( "foobar\nquxquux", true );
401 }
402
404 $this->m->output( "foo", "bazChannel" );
405 $this->m->output( "bar" );
406 $this->m->output( "qux", "bazChannel" );
407 $this->m->output( "quux" );
408 $this->assertOutputPrePostShutdown( "foo\nbarqux\nquux", false );
409 }
410
412 $this->m->output( "foo", 1 );
413 $this->m->output( "bar", 1.0 );
414 $this->assertOutputPrePostShutdown( "foo\nbar", true );
415 }
416
418 $this->m->output( "foo" );
419 $this->m->output( "" );
420 $this->m->output( "bar" );
421 $this->assertOutputPrePostShutdown( "foobar", false );
422 }
423
425 $this->m->output( "foo" );
426 $this->m->output( false );
427 $this->m->output( "bar" );
428 $this->assertOutputPrePostShutdown( "foobar", false );
429 }
430
432 $this->m->output( "qux", "quuxChannel" );
433 $this->m->output( "foo" );
434 $this->m->output( false );
435 $this->m->output( "bar" );
436 $this->assertOutputPrePostShutdown( "qux\nfoobar", false );
437 }
438
440 $this->m->output( "foo", null );
441 $this->m->output( "", null );
442 $this->m->output( "bar", null );
443 $this->assertOutputPrePostShutdown( "foobar", false );
444 }
445
447 $this->m->output( "foo", null );
448 $this->m->output( false, null );
449 $this->m->output( "bar", null );
450 $this->assertOutputPrePostShutdown( "foobar", false );
451 }
452
454 $this->m->output( "foo", "bazChannel" );
455 $this->m->output( "", "bazChannel" );
456 $this->m->output( "bar", "bazChannel" );
457 $this->assertOutputPrePostShutdown( "foobar", true );
458 }
459
461 $this->m->output( "foo", "bazChannel" );
462 $this->m->output( false, "bazChannel" );
463 $this->m->output( "bar", "bazChannel" );
464 $this->assertOutputPrePostShutdown( "foobar", true );
465 }
466
467 // Note that (per documentation) outputChanneled does take strings that end
468 // in \n, hence we do not test such strings.
469
471 $this->m->outputChanneled( "" );
472 $this->assertOutputPrePostShutdown( "\n", false );
473 }
474
476 $this->m->outputChanneled( "foo" );
477 $this->assertOutputPrePostShutdown( "foo\n", false );
478 }
479
481 $this->m->outputChanneled( "foo" );
482 $this->m->outputChanneled( "bar" );
483 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
484 }
485
487 $this->m->outputChanneled( "foo\nbar" );
488 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
489 }
490
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" );
499 $this->assertOutputPrePostShutdown( "\nfoo\n\n\nb\na\n\nr\n", false );
500 }
501
503 $this->m->outputChanneled( "", null );
504 $this->assertOutputPrePostShutdown( "\n", false );
505 }
506
508 $this->m->outputChanneled( "foo", null );
509 $this->assertOutputPrePostShutdown( "foo\n", false );
510 }
511
513 $this->m->outputChanneled( "foo", null );
514 $this->m->outputChanneled( "bar", null );
515 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
516 }
517
519 $this->m->outputChanneled( "foo\nbar", null );
520 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
521 }
522
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 );
531 $this->assertOutputPrePostShutdown( "\nfoo\n\n\nb\na\n\nr\n", false );
532 }
533
535 $this->m->outputChanneled( "foo", "bazChannel" );
536 $this->assertOutputPrePostShutdown( "foo", true );
537 }
538
540 $this->m->outputChanneled( "foo\nbar", "bazChannel" );
541 $this->assertOutputPrePostShutdown( "foo\nbar", true );
542 }
543
545 $this->m->outputChanneled( "foo", "bazChannel" );
546 $this->m->outputChanneled( "bar", "bazChannel" );
547 $this->assertOutputPrePostShutdown( "foobar", true );
548 }
549
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" );
558 $this->assertOutputPrePostShutdown( "foo\nbar", true );
559 }
560
562 $this->m->outputChanneled( "foo", "bazChannel" );
563 $this->m->outputChanneled( "bar", "bazChannel" );
564 $this->m->outputChanneled( "qux", "quuxChannel" );
565 $this->m->outputChanneled( "corge", "bazChannel" );
566 $this->assertOutputPrePostShutdown( "foobar\nqux\ncorge", true );
567 }
568
570 $this->m->outputChanneled( "foo", "bazChannel" );
571 $this->m->outputChanneled( "bar", null );
572 $this->m->outputChanneled( "qux", null );
573 $this->m->outputChanneled( "corge", "bazChannel" );
574 $this->assertOutputPrePostShutdown( "foo\nbar\nqux\ncorge", true );
575 }
576
578 $this->m->outputChanneled( "foo", "bazChannel" );
579 $this->m->outputChanneled( "bar", null );
580 $this->m->outputChanneled( "qux", null );
581 $this->m->outputChanneled( "corge", "quuxChannel" );
582 $this->assertOutputPrePostShutdown( "foo\nbar\nqux\ncorge", true );
583 }
584
586 $this->m->outputChanneled( "foo" );
587 $this->m->outputChanneled( "bar", "bazChannel" );
588 $this->m->outputChanneled( "qux" );
589 $this->m->outputChanneled( "quux", "bazChannel" );
590 $this->assertOutputPrePostShutdown( "foo\nbar\nqux\nquux", true );
591 }
592
594 $this->m->outputChanneled( "foo", "bazChannel" );
595 $this->m->outputChanneled( "bar" );
596 $this->m->outputChanneled( "qux", "bazChannel" );
597 $this->m->outputChanneled( "quux" );
598 $this->assertOutputPrePostShutdown( "foo\nbar\nqux\nquux\n", false );
599 }
600
602 $this->m->outputChanneled( "foo", 1 );
603 $this->m->outputChanneled( "bar", 1.0 );
604 $this->assertOutputPrePostShutdown( "foo\nbar", true );
605 }
606
608 $this->m->outputChanneled( "foo" );
609 $this->m->outputChanneled( "" );
610 $this->m->outputChanneled( "bar" );
611 $this->assertOutputPrePostShutdown( "foo\n\nbar\n", false );
612 }
613
615 $this->m->outputChanneled( "foo" );
616 $this->m->outputChanneled( false );
617 $this->m->outputChanneled( "bar" );
618 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
619 }
620
622 $this->m->outputChanneled( "foo", null );
623 $this->m->outputChanneled( "", null );
624 $this->m->outputChanneled( "bar", null );
625 $this->assertOutputPrePostShutdown( "foo\n\nbar\n", false );
626 }
627
629 $this->m->outputChanneled( "foo", null );
630 $this->m->outputChanneled( false, null );
631 $this->m->outputChanneled( "bar", null );
632 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
633 }
634
636 $this->m->outputChanneled( "foo", "bazChannel" );
637 $this->m->outputChanneled( "", "bazChannel" );
638 $this->m->outputChanneled( "bar", "bazChannel" );
639 $this->assertOutputPrePostShutdown( "foobar", true );
640 }
641
643 $this->m->outputChanneled( "foo", "bazChannel" );
644 $this->m->outputChanneled( false, "bazChannel" );
645 $this->m->outputChanneled( "bar", "bazChannel" );
646 $this->assertOutputPrePostShutdown( "foo\nbar", true );
647 }
648
650 $this->m->cleanupChanneled();
651 $this->assertOutputPrePostShutdown( "", false );
652 }
653
655 $this->m->output( "foo" );
656 $this->m->cleanupChanneled();
657 $this->assertOutputPrePostShutdown( "foo", false );
658 }
659
661 $this->m->output( "foo", null );
662 $this->m->cleanupChanneled();
663 $this->assertOutputPrePostShutdown( "foo", false );
664 }
665
667 $this->m->output( "foo", "bazChannel" );
668 $this->m->cleanupChanneled();
669 $this->assertOutputPrePostShutdown( "foo\n", false );
670 }
671
673 $this->m->output( "foo\n" );
674 $this->m->cleanupChanneled();
675 $this->assertOutputPrePostShutdown( "foo\n", false );
676 }
677
679 $this->m->output( "foo\n", null );
680 $this->m->cleanupChanneled();
681 $this->assertOutputPrePostShutdown( "foo\n", false );
682 }
683
685 $this->m->output( "foo\n", "bazChannel" );
686 $this->m->cleanupChanneled();
687 $this->assertOutputPrePostShutdown( "foo\n", false );
688 }
689
691 $this->m->outputChanneled( "foo" );
692 $this->m->cleanupChanneled();
693 $this->assertOutputPrePostShutdown( "foo\n", false );
694 }
695
697 $this->m->outputChanneled( "foo", null );
698 $this->m->cleanupChanneled();
699 $this->assertOutputPrePostShutdown( "foo\n", false );
700 }
701
703 $this->m->outputChanneled( "foo", "bazChannel" );
704 $this->m->cleanupChanneled();
705 $this->assertOutputPrePostShutdown( "foo\n", false );
706 }
707
709 $m2 = new MaintenanceFixup( $this );
710
711 $this->m->output( "foo" );
712 $m2->output( "bar" );
713
714 $this->assertEquals( "foobar", $this->getActualOutput(),
715 "Output before shutdown simulation (m2)" );
716 $m2->simulateShutdown();
717 $this->assertOutputPrePostShutdown( "foobar", false );
718 }
719
721 $m2 = new MaintenanceFixup( $this );
722
723 $this->m->output( "foo", null );
724 $m2->output( "bar", null );
725
726 $this->assertEquals( "foobar", $this->getActualOutput(),
727 "Output before shutdown simulation (m2)" );
728 $m2->simulateShutdown();
729 $this->assertOutputPrePostShutdown( "foobar", false );
730 }
731
733 $m2 = new MaintenanceFixup( $this );
734
735 $this->m->output( "foo", "bazChannel" );
736 $m2->output( "bar", "bazChannel" );
737
738 $this->assertEquals( "foobar", $this->getActualOutput(),
739 "Output before shutdown simulation (m2)" );
740 $m2->simulateShutdown();
741 $this->assertOutputPrePostShutdown( "foobar\n", true );
742 }
743
745 $m2 = new MaintenanceFixup( $this );
746
747 $this->m->output( "foo\n", null );
748 $m2->output( "bar\n", null );
749
750 $this->assertEquals( "foo\nbar\n", $this->getActualOutput(),
751 "Output before shutdown simulation (m2)" );
752 $m2->simulateShutdown();
753 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
754 }
755
757 $m2 = new MaintenanceFixup( $this );
758
759 $this->m->output( "foo\n", "bazChannel" );
760 $m2->output( "bar\n", "bazChannel" );
761
762 $this->assertEquals( "foobar", $this->getActualOutput(),
763 "Output before shutdown simulation (m2)" );
764 $m2->simulateShutdown();
765 $this->assertOutputPrePostShutdown( "foobar\n", true );
766 }
767
769 $m2 = new MaintenanceFixup( $this );
770
771 $this->m->outputChanneled( "foo" );
772 $m2->outputChanneled( "bar" );
773
774 $this->assertEquals( "foo\nbar\n", $this->getActualOutput(),
775 "Output before shutdown simulation (m2)" );
776 $m2->simulateShutdown();
777 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
778 }
779
781 $m2 = new MaintenanceFixup( $this );
782
783 $this->m->outputChanneled( "foo", null );
784 $m2->outputChanneled( "bar", null );
785
786 $this->assertEquals( "foo\nbar\n", $this->getActualOutput(),
787 "Output before shutdown simulation (m2)" );
788 $m2->simulateShutdown();
789 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
790 }
791
793 $m2 = new MaintenanceFixup( $this );
794
795 $this->m->outputChanneled( "foo", "bazChannel" );
796 $m2->outputChanneled( "bar", "bazChannel" );
797
798 $this->assertEquals( "foobar", $this->getActualOutput(),
799 "Output before shutdown simulation (m2)" );
800 $m2->simulateShutdown();
801 $this->assertOutputPrePostShutdown( "foobar\n", true );
802 }
803
805 $m2 = new MaintenanceFixup( $this );
806
807 $this->m->outputChanneled( "foo", "bazChannel" );
808 $m2->outputChanneled( "bar", "bazChannel" );
809
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" );
818
819 $m2->simulateShutdown();
820 $this->assertOutputPrePostShutdown( "foobar\n\n", false );
821 }
822
826 public function testGetConfig() {
827 $this->assertInstanceOf( 'Config', $this->m->getConfig() );
828 $this->assertSame(
829 ConfigFactory::getDefaultInstance()->makeConfig( 'main' ),
830 $this->m->getConfig()
831 );
832 }
833
837 public function testSetConfig() {
838 $conf = $this->getMock( 'Config' );
839 $this->m->setConfig( $conf );
840 $this->assertSame( $conf, $this->m->getConfig() );
841 }
842
843 function testParseArgs() {
844 $m2 = new MaintenanceFixup( $this );
845 // Create an option with an argument allowed to be specified multiple times
846 $m2->addOption( 'multi', 'This option does stuff', false, true, false, true );
847 $m2->loadWithArgv( [ '--multi', 'this1', '--multi', 'this2' ] );
848
849 $this->assertEquals( [ 'this1', 'this2' ], $m2->getOption( 'multi' ) );
850 $this->assertEquals( [ [ 'multi', 'this1' ], [ 'multi', 'this2' ] ],
851 $m2->orderedOptions );
852
853 $m2->simulateShutdown();
854
855 $m2 = new MaintenanceFixup( $this );
856
857 $m2->addOption( 'multi', 'This option does stuff', false, false, false, true );
858 $m2->loadWithArgv( [ '--multi', '--multi' ] );
859
860 $this->assertEquals( [ 1, 1 ], $m2->getOption( 'multi' ) );
861 $this->assertEquals( [ [ 'multi', 1 ], [ 'multi', 1 ] ], $m2->orderedOptions );
862
863 $m2->simulateShutdown();
864
865 $m2 = new MaintenanceFixup( $this );
866 // Create an option with an argument allowed to be specified multiple times
867 $m2->addOption( 'multi', 'This option doesn\'t actually support multiple occurrences' );
868 $m2->loadWithArgv( [ '--multi=yo' ] );
869
870 $this->assertEquals( 'yo', $m2->getOption( 'multi' ) );
871 $this->assertEquals( [ [ 'multi', 'yo' ] ], $m2->orderedOptions );
872
873 $m2->simulateShutdown();
874 }
875}
makes parts of the API of Maintenance that is hidden by protected visibily visible for testing,...
output( $out, $channel=null)
Throw some output to the user.
__construct(MediaWikiTestCase $testCase)
bool $shutdownSimulated
shutdownSimulated === true if simulateShutdown has done it's work
MediaWikiTestCase $testCase
The test case that generated this instance.
addOption( $name, $description, $required=false, $withArg=false, $shortName=false, $multiOccurance=false)
Add a parameter to the script.
execute()
Do the actual work.
outputChanneled( $msg, $channel=null)
Message outputter with channeled message support.
simulateShutdown()
Simulates what Maintenance wants to happen at script's end.
getOption( $name, $default=null)
Get an option, or return the default.
__destruct()
Safety net around register_shutdown_function of Maintenance.php.
testOutputWNullChannelStringNLStringNLLinewise()
testOutputChanneledWNullChannelIntermittentFalse()
testOutputStringNLStringNLArbitraryAgain()
testOutputWChannelStringNLStringNLArbitraryAgain()
testOutputWMultipleChannelsChannelChange()
testOutputChanneledWMultipleChannelsChannelAfterNullChange()
testOutputChanneledWChannelIntermittentFalse()
testMultipleMaintenanceObjectsInteractionOutputChanneledWNullChannel()
testMultipleMaintenanceObjectsInteractionOutputWChannelNL()
testOutputChanneledWNullChannelStringNLStringNLArbitraryAgain()
testOutputChanneledWNullChannelStringNLString()
testMultipleMaintenanceObjectsInteractionOutputWChannel()
testOutputChanneledWChannelIntermittentEmpty()
testOutputChanneledWMultipleChannelsChannelChangeEnclosedNull()
testOutputWNullChannelStringNLStringNLArbitraryAgain()
testMultipleMaintenanceObjectsInteractionCleanupChanneledWChannel()
testOutputChanneledWChannelStringNLString()
testOutputChanneledWOChannelIntermittentEmpty()
testMultipleMaintenanceObjectsInteractionOutputChanneled()
testOutputChanneledWNullChannelIntermittentEmpty()
testOutputChanneledWAndWOChannelStringStartWO()
testCleanupChanneledAfterNLOutputWNullChannel()
testCleanupChanneledAfterOutputWChannel()
MaintenanceFixup $m
The main Maintenance instance that is used for testing.
testCleanupChanneledAfterOutputChanneledWOChannel()
testGetConfig()
Maintenance::getConfig.
testOutputChanneledWChannelStringString()
assertOutputPrePostShutdown( $preShutdownOutput, $expectNLAppending)
asserts the output before and after simulating shutdown
testOutputChanneledWAndWOChannelStringStartW()
testSetConfig()
Maintenance::setConfig.
testOutputWMultipleChannelsChannelChangeNL()
testOutputWChannelStringNLStringNLArbitrary()
testMultipleMaintenanceObjectsInteractionOutputChanneledWChannel()
testOutputWNullChannelIntermittentFalse()
testOutputWNullChannelStringNLStringNLArbitrary()
testMultipleMaintenanceObjectsInteractionOutput()
testOutputChanneledWMultipleChannelsChannelChange()
testCleanupChanneledAfterOutputWNullChannel()
testCleanupChanneledAfterOutputChanneledWChannel()
testOutputChanneledWNullChannelStringString()
testCleanupChanneledAfterNLOutputWChannel()
testOutputChanneledWChannelStringNLStringNLArbitraryAgain()
testMultipleMaintenanceObjectsInteractionOutputWNullChannel()
testOutputWNullChannelIntermittentEmpty()
testOutputIntermittentFalseAfterOtherChannel()
testOutputWChannelStringNLStringNLLinewise()
testCleanupChanneledAfterOutputChanneledWNullChannel()
testOutputChanneledWOChannelIntermittentFalse()
testOutputChanneledStringNLStringNLArbitraryAgain()
testMultipleMaintenanceObjectsInteractionOutputWNullChannelNL()
Abstract maintenance class for quickly writing and churning out maintenance scripts with minimal effo...
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that probably a stub it is not rendered in wiki pages or galleries in category pages allow injecting custom HTML after the section Any uses of the hook need to handle escaping see BaseTemplate::getToolbox and BaseTemplate::makeListItem for details on the format of individual items inside of this array or by returning and letting standard HTTP rendering take place modifiable or by returning false and taking over the output $out
Definition hooks.txt:886
Allows to change the fields on the form that will be generated $name
Definition hooks.txt:304
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
Definition injection.txt:37