Remove return from MaintenanceFixup::outputChanneled
[lhc/web/wiklou.git] / tests / phpunit / maintenance / MaintenanceTest.php
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 //
8 // For the same reason, we cannot just use FakeMaintenance.
9
10 /**
11 * makes parts of the API of Maintenance that is hidden by protected visibily
12 * visible for testing, and makes up for a stream closing hack in Maintenance.php.
13 *
14 * This class is solely used for being able to test Maintenance right now
15 * without having to apply major refactorings to fix some design issues in
16 * Maintenance.php. Before adding more functions here, please consider whether
17 * this approach is correct, or a refactoring Maintenance to separate concers
18 * is more appropriate.
19 *
20 * Upon refactoring, keep in mind that besides the maintenance scrits themselves
21 * and tests right here, also at least Extension:Maintenance make use of
22 * Maintenance.
23 *
24 * Due to a hack in Maintenance.php using register_shutdown_function, be sure to
25 * finally call simulateShutdown on MaintenanceFixup instance before a test
26 * ends.
27 *
28 */
29 class MaintenanceFixup extends Maintenance {
30
31 // --- Making up for the register_shutdown_function hack in Maintenance.php
32
33 /**
34 * The test case that generated this instance.
35 *
36 * This member is motivated by allowing the destructor to check whether or not
37 * the test failed, in order to avoid unnecessary nags about omitted shutdown
38 * simulation.
39 * But as it is already available, we also usi it to flagging tests as failed
40 *
41 * @var MediaWikiTestCase
42 */
43 private $testCase;
44
45 /**
46 * shutdownSimulated === true if simulateShutdown has done it's work
47 *
48 * @var bool
49 */
50 private $shutdownSimulated = false;
51
52 /**
53 * Simulates what Maintenance wants to happen at script's end.
54 */
55 public function simulateShutdown() {
56
57 if ( $this->shutdownSimulated ) {
58 $this->testCase->fail( __METHOD__ . " called more than once" );
59 }
60
61 // The cleanup action.
62 $this->outputChanneled( false );
63
64 // Bookkeeping that we simulated the clean up.
65 $this->shutdownSimulated = true;
66 }
67
68 // Note that the "public" here does not change visibility
69 public function outputChanneled( $msg, $channel = null ) {
70 if ( $this->shutdownSimulated ) {
71 if ( $msg !== false ) {
72 $this->testCase->fail( "Already past simulated shutdown, but msg is "
73 . "not false. Did the hack in Maintenance.php change? Please "
74 . "adapt the test case or Maintenance.php" );
75 }
76
77 // The current call is the one registered via register_shutdown_function.
78 // We can safely ignore it, as we simulated this one via simulateShutdown
79 // before (if we did not, the destructor of this instance will warn about
80 // it)
81 return;
82 }
83
84 call_user_func_array( array( "parent", __FUNCTION__ ), func_get_args() );
85 }
86
87 /**
88 * Safety net around register_shutdown_function of Maintenance.php
89 */
90 public function __destruct() {
91 if ( !$this->shutdownSimulated ) {
92 // Someone generated a MaintenanceFixup instance without calling
93 // simulateShutdown. We'd have to raise a PHPUnit exception to correctly
94 // flag this illegal usage. However, we are already in a destruktor, which
95 // would trigger undefined behavior. Hence, we can only report to the
96 // error output :( Hopefully people read the PHPUnit output.
97 $name = $this->testCase->getName();
98 fwrite( STDERR, "ERROR! Instance of " . __CLASS__ . " for test $name "
99 . "destructed without calling simulateShutdown method. Call "
100 . "simulateShutdown on the instance before it gets destructed." );
101 }
102
103 // The following guard is required, as PHP does not offer default destructors :(
104 if ( is_callable( "parent::__destruct" ) ) {
105 parent::__destruct();
106 }
107 }
108
109 public function __construct( MediaWikiTestCase $testCase ) {
110 parent::__construct();
111 $this->testCase = $testCase;
112 }
113
114 // --- Making protected functions visible for test
115
116 public function output( $out, $channel = null ) {
117 // Just to make PHP not nag about signature mismatches, we copied
118 // Maintenance::output signature. However, we do not use (or rely on)
119 // those variables. Instead we pass to Maintenance::output whatever we
120 // receive at runtime.
121 return call_user_func_array( array( "parent", __FUNCTION__ ), func_get_args() );
122 }
123
124 // --- Requirements for getting instance of abstract class
125
126 public function execute() {
127 $this->testCase->fail( __METHOD__ . " called unexpectedly" );
128 }
129 }
130
131 /**
132 * @covers Maintenance
133 */
134 class MaintenanceTest extends MediaWikiTestCase {
135
136 /**
137 * The main Maintenance instance that is used for testing.
138 *
139 * @var MaintenanceFixup
140 */
141 private $m;
142
143 protected function setUp() {
144 parent::setUp();
145 $this->m = new MaintenanceFixup( $this );
146 }
147
148 protected function tearDown() {
149 if ( $this->m ) {
150 $this->m->simulateShutdown();
151 $this->m = null;
152 }
153 parent::tearDown();
154 }
155
156 /**
157 * asserts the output before and after simulating shutdown
158 *
159 * This function simulates shutdown of self::m.
160 *
161 * @param string $preShutdownOutput Expected output before simulating shutdown
162 * @param bool $expectNLAppending Whether or not shutdown simulation is expected
163 * to add a newline to the output. If false, $preShutdownOutput is the
164 * expected output after shutdown simulation. Otherwise,
165 * $preShutdownOutput with an appended newline is the expected output
166 * after shutdown simulation.
167 */
168 private function assertOutputPrePostShutdown( $preShutdownOutput, $expectNLAppending ) {
169
170 $this->assertEquals( $preShutdownOutput, $this->getActualOutput(),
171 "Output before shutdown simulation" );
172
173 $this->m->simulateShutdown();
174 $this->m = null;
175
176 $postShutdownOutput = $preShutdownOutput . ( $expectNLAppending ? "\n" : "" );
177 $this->expectOutputString( $postShutdownOutput );
178 }
179
180 // Although the following tests do not seem to be too consistent (compare for
181 // example the newlines within the test.*StringString tests, or the
182 // test.*Intermittent.* tests), the objective of these tests is not to describe
183 // consistent behavior, but rather currently existing behavior.
184
185 function testOutputEmpty() {
186 $this->m->output( "" );
187 $this->assertOutputPrePostShutdown( "", false );
188 }
189
190 function testOutputString() {
191 $this->m->output( "foo" );
192 $this->assertOutputPrePostShutdown( "foo", false );
193 }
194
195 function testOutputStringString() {
196 $this->m->output( "foo" );
197 $this->m->output( "bar" );
198 $this->assertOutputPrePostShutdown( "foobar", false );
199 }
200
201 function testOutputStringNL() {
202 $this->m->output( "foo\n" );
203 $this->assertOutputPrePostShutdown( "foo\n", false );
204 }
205
206 function testOutputStringNLNL() {
207 $this->m->output( "foo\n\n" );
208 $this->assertOutputPrePostShutdown( "foo\n\n", false );
209 }
210
211 function testOutputStringNLString() {
212 $this->m->output( "foo\nbar" );
213 $this->assertOutputPrePostShutdown( "foo\nbar", false );
214 }
215
216 function testOutputStringNLStringNL() {
217 $this->m->output( "foo\nbar\n" );
218 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
219 }
220
221 function testOutputStringNLStringNLLinewise() {
222 $this->m->output( "foo\n" );
223 $this->m->output( "bar\n" );
224 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
225 }
226
227 function testOutputStringNLStringNLArbitrary() {
228 $this->m->output( "" );
229 $this->m->output( "foo" );
230 $this->m->output( "" );
231 $this->m->output( "\n" );
232 $this->m->output( "ba" );
233 $this->m->output( "" );
234 $this->m->output( "r\n" );
235 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
236 }
237
238 function testOutputStringNLStringNLArbitraryAgain() {
239 $this->m->output( "" );
240 $this->m->output( "foo" );
241 $this->m->output( "" );
242 $this->m->output( "\nb" );
243 $this->m->output( "a" );
244 $this->m->output( "" );
245 $this->m->output( "r\n" );
246 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
247 }
248
249 function testOutputWNullChannelEmpty() {
250 $this->m->output( "", null );
251 $this->assertOutputPrePostShutdown( "", false );
252 }
253
254 function testOutputWNullChannelString() {
255 $this->m->output( "foo", null );
256 $this->assertOutputPrePostShutdown( "foo", false );
257 }
258
259 function testOutputWNullChannelStringString() {
260 $this->m->output( "foo", null );
261 $this->m->output( "bar", null );
262 $this->assertOutputPrePostShutdown( "foobar", false );
263 }
264
265 function testOutputWNullChannelStringNL() {
266 $this->m->output( "foo\n", null );
267 $this->assertOutputPrePostShutdown( "foo\n", false );
268 }
269
270 function testOutputWNullChannelStringNLNL() {
271 $this->m->output( "foo\n\n", null );
272 $this->assertOutputPrePostShutdown( "foo\n\n", false );
273 }
274
275 function testOutputWNullChannelStringNLString() {
276 $this->m->output( "foo\nbar", null );
277 $this->assertOutputPrePostShutdown( "foo\nbar", false );
278 }
279
280 function testOutputWNullChannelStringNLStringNL() {
281 $this->m->output( "foo\nbar\n", null );
282 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
283 }
284
285 function testOutputWNullChannelStringNLStringNLLinewise() {
286 $this->m->output( "foo\n", null );
287 $this->m->output( "bar\n", null );
288 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
289 }
290
291 function testOutputWNullChannelStringNLStringNLArbitrary() {
292 $this->m->output( "", null );
293 $this->m->output( "foo", null );
294 $this->m->output( "", null );
295 $this->m->output( "\n", null );
296 $this->m->output( "ba", null );
297 $this->m->output( "", null );
298 $this->m->output( "r\n", null );
299 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
300 }
301
302 function testOutputWNullChannelStringNLStringNLArbitraryAgain() {
303 $this->m->output( "", null );
304 $this->m->output( "foo", null );
305 $this->m->output( "", null );
306 $this->m->output( "\nb", null );
307 $this->m->output( "a", null );
308 $this->m->output( "", null );
309 $this->m->output( "r\n", null );
310 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
311 }
312
313 function testOutputWChannelString() {
314 $this->m->output( "foo", "bazChannel" );
315 $this->assertOutputPrePostShutdown( "foo", true );
316 }
317
318 function testOutputWChannelStringNL() {
319 $this->m->output( "foo\n", "bazChannel" );
320 $this->assertOutputPrePostShutdown( "foo", true );
321 }
322
323 function testOutputWChannelStringNLNL() {
324 // If this test fails, note that output takes strings with double line
325 // endings (although output's implementation in this situation calls
326 // outputChanneled with a string ending in a nl ... which is not allowed
327 // according to the documentation of outputChanneled)
328 $this->m->output( "foo\n\n", "bazChannel" );
329 $this->assertOutputPrePostShutdown( "foo\n", true );
330 }
331
332 function testOutputWChannelStringNLString() {
333 $this->m->output( "foo\nbar", "bazChannel" );
334 $this->assertOutputPrePostShutdown( "foo\nbar", true );
335 }
336
337 function testOutputWChannelStringNLStringNL() {
338 $this->m->output( "foo\nbar\n", "bazChannel" );
339 $this->assertOutputPrePostShutdown( "foo\nbar", true );
340 }
341
342 function testOutputWChannelStringNLStringNLLinewise() {
343 $this->m->output( "foo\n", "bazChannel" );
344 $this->m->output( "bar\n", "bazChannel" );
345 $this->assertOutputPrePostShutdown( "foobar", true );
346 }
347
348 function testOutputWChannelStringNLStringNLArbitrary() {
349 $this->m->output( "", "bazChannel" );
350 $this->m->output( "foo", "bazChannel" );
351 $this->m->output( "", "bazChannel" );
352 $this->m->output( "\n", "bazChannel" );
353 $this->m->output( "ba", "bazChannel" );
354 $this->m->output( "", "bazChannel" );
355 $this->m->output( "r\n", "bazChannel" );
356 $this->assertOutputPrePostShutdown( "foobar", true );
357 }
358
359 function testOutputWChannelStringNLStringNLArbitraryAgain() {
360 $this->m->output( "", "bazChannel" );
361 $this->m->output( "foo", "bazChannel" );
362 $this->m->output( "", "bazChannel" );
363 $this->m->output( "\nb", "bazChannel" );
364 $this->m->output( "a", "bazChannel" );
365 $this->m->output( "", "bazChannel" );
366 $this->m->output( "r\n", "bazChannel" );
367 $this->assertOutputPrePostShutdown( "foo\nbar", true );
368 }
369
370 function testOutputWMultipleChannelsChannelChange() {
371 $this->m->output( "foo", "bazChannel" );
372 $this->m->output( "bar", "bazChannel" );
373 $this->m->output( "qux", "quuxChannel" );
374 $this->m->output( "corge", "bazChannel" );
375 $this->assertOutputPrePostShutdown( "foobar\nqux\ncorge", true );
376 }
377
378 function testOutputWMultipleChannelsChannelChangeNL() {
379 $this->m->output( "foo", "bazChannel" );
380 $this->m->output( "bar\n", "bazChannel" );
381 $this->m->output( "qux\n", "quuxChannel" );
382 $this->m->output( "corge", "bazChannel" );
383 $this->assertOutputPrePostShutdown( "foobar\nqux\ncorge", true );
384 }
385
386 function testOutputWAndWOChannelStringStartWO() {
387 $this->m->output( "foo" );
388 $this->m->output( "bar", "bazChannel" );
389 $this->m->output( "qux" );
390 $this->m->output( "quux", "bazChannel" );
391 $this->assertOutputPrePostShutdown( "foobar\nquxquux", true );
392 }
393
394 function testOutputWAndWOChannelStringStartW() {
395 $this->m->output( "foo", "bazChannel" );
396 $this->m->output( "bar" );
397 $this->m->output( "qux", "bazChannel" );
398 $this->m->output( "quux" );
399 $this->assertOutputPrePostShutdown( "foo\nbarqux\nquux", false );
400 }
401
402 function testOutputWChannelTypeSwitch() {
403 $this->m->output( "foo", 1 );
404 $this->m->output( "bar", 1.0 );
405 $this->assertOutputPrePostShutdown( "foo\nbar", true );
406 }
407
408 function testOutputIntermittentEmpty() {
409 $this->m->output( "foo" );
410 $this->m->output( "" );
411 $this->m->output( "bar" );
412 $this->assertOutputPrePostShutdown( "foobar", false );
413 }
414
415 function testOutputIntermittentFalse() {
416 $this->m->output( "foo" );
417 $this->m->output( false );
418 $this->m->output( "bar" );
419 $this->assertOutputPrePostShutdown( "foobar", false );
420 }
421
422 function testOutputIntermittentFalseAfterOtherChannel() {
423 $this->m->output( "qux", "quuxChannel" );
424 $this->m->output( "foo" );
425 $this->m->output( false );
426 $this->m->output( "bar" );
427 $this->assertOutputPrePostShutdown( "qux\nfoobar", false );
428 }
429
430 function testOutputWNullChannelIntermittentEmpty() {
431 $this->m->output( "foo", null );
432 $this->m->output( "", null );
433 $this->m->output( "bar", null );
434 $this->assertOutputPrePostShutdown( "foobar", false );
435 }
436
437 function testOutputWNullChannelIntermittentFalse() {
438 $this->m->output( "foo", null );
439 $this->m->output( false, null );
440 $this->m->output( "bar", null );
441 $this->assertOutputPrePostShutdown( "foobar", false );
442 }
443
444 function testOutputWChannelIntermittentEmpty() {
445 $this->m->output( "foo", "bazChannel" );
446 $this->m->output( "", "bazChannel" );
447 $this->m->output( "bar", "bazChannel" );
448 $this->assertOutputPrePostShutdown( "foobar", true );
449 }
450
451 function testOutputWChannelIntermittentFalse() {
452 $this->m->output( "foo", "bazChannel" );
453 $this->m->output( false, "bazChannel" );
454 $this->m->output( "bar", "bazChannel" );
455 $this->assertOutputPrePostShutdown( "foobar", true );
456 }
457
458 // Note that (per documentation) outputChanneled does take strings that end
459 // in \n, hence we do not test such strings.
460
461 function testOutputChanneledEmpty() {
462 $this->m->outputChanneled( "" );
463 $this->assertOutputPrePostShutdown( "\n", false );
464 }
465
466 function testOutputChanneledString() {
467 $this->m->outputChanneled( "foo" );
468 $this->assertOutputPrePostShutdown( "foo\n", false );
469 }
470
471 function testOutputChanneledStringString() {
472 $this->m->outputChanneled( "foo" );
473 $this->m->outputChanneled( "bar" );
474 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
475 }
476
477 function testOutputChanneledStringNLString() {
478 $this->m->outputChanneled( "foo\nbar" );
479 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
480 }
481
482 function testOutputChanneledStringNLStringNLArbitraryAgain() {
483 $this->m->outputChanneled( "" );
484 $this->m->outputChanneled( "foo" );
485 $this->m->outputChanneled( "" );
486 $this->m->outputChanneled( "\nb" );
487 $this->m->outputChanneled( "a" );
488 $this->m->outputChanneled( "" );
489 $this->m->outputChanneled( "r" );
490 $this->assertOutputPrePostShutdown( "\nfoo\n\n\nb\na\n\nr\n", false );
491 }
492
493 function testOutputChanneledWNullChannelEmpty() {
494 $this->m->outputChanneled( "", null );
495 $this->assertOutputPrePostShutdown( "\n", false );
496 }
497
498 function testOutputChanneledWNullChannelString() {
499 $this->m->outputChanneled( "foo", null );
500 $this->assertOutputPrePostShutdown( "foo\n", false );
501 }
502
503 function testOutputChanneledWNullChannelStringString() {
504 $this->m->outputChanneled( "foo", null );
505 $this->m->outputChanneled( "bar", null );
506 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
507 }
508
509 function testOutputChanneledWNullChannelStringNLString() {
510 $this->m->outputChanneled( "foo\nbar", null );
511 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
512 }
513
514 function testOutputChanneledWNullChannelStringNLStringNLArbitraryAgain() {
515 $this->m->outputChanneled( "", null );
516 $this->m->outputChanneled( "foo", null );
517 $this->m->outputChanneled( "", null );
518 $this->m->outputChanneled( "\nb", null );
519 $this->m->outputChanneled( "a", null );
520 $this->m->outputChanneled( "", null );
521 $this->m->outputChanneled( "r", null );
522 $this->assertOutputPrePostShutdown( "\nfoo\n\n\nb\na\n\nr\n", false );
523 }
524
525 function testOutputChanneledWChannelString() {
526 $this->m->outputChanneled( "foo", "bazChannel" );
527 $this->assertOutputPrePostShutdown( "foo", true );
528 }
529
530 function testOutputChanneledWChannelStringNLString() {
531 $this->m->outputChanneled( "foo\nbar", "bazChannel" );
532 $this->assertOutputPrePostShutdown( "foo\nbar", true );
533 }
534
535 function testOutputChanneledWChannelStringString() {
536 $this->m->outputChanneled( "foo", "bazChannel" );
537 $this->m->outputChanneled( "bar", "bazChannel" );
538 $this->assertOutputPrePostShutdown( "foobar", true );
539 }
540
541 function testOutputChanneledWChannelStringNLStringNLArbitraryAgain() {
542 $this->m->outputChanneled( "", "bazChannel" );
543 $this->m->outputChanneled( "foo", "bazChannel" );
544 $this->m->outputChanneled( "", "bazChannel" );
545 $this->m->outputChanneled( "\nb", "bazChannel" );
546 $this->m->outputChanneled( "a", "bazChannel" );
547 $this->m->outputChanneled( "", "bazChannel" );
548 $this->m->outputChanneled( "r", "bazChannel" );
549 $this->assertOutputPrePostShutdown( "foo\nbar", true );
550 }
551
552 function testOutputChanneledWMultipleChannelsChannelChange() {
553 $this->m->outputChanneled( "foo", "bazChannel" );
554 $this->m->outputChanneled( "bar", "bazChannel" );
555 $this->m->outputChanneled( "qux", "quuxChannel" );
556 $this->m->outputChanneled( "corge", "bazChannel" );
557 $this->assertOutputPrePostShutdown( "foobar\nqux\ncorge", true );
558 }
559
560 function testOutputChanneledWMultipleChannelsChannelChangeEnclosedNull() {
561 $this->m->outputChanneled( "foo", "bazChannel" );
562 $this->m->outputChanneled( "bar", null );
563 $this->m->outputChanneled( "qux", null );
564 $this->m->outputChanneled( "corge", "bazChannel" );
565 $this->assertOutputPrePostShutdown( "foo\nbar\nqux\ncorge", true );
566 }
567
568 function testOutputChanneledWMultipleChannelsChannelAfterNullChange() {
569 $this->m->outputChanneled( "foo", "bazChannel" );
570 $this->m->outputChanneled( "bar", null );
571 $this->m->outputChanneled( "qux", null );
572 $this->m->outputChanneled( "corge", "quuxChannel" );
573 $this->assertOutputPrePostShutdown( "foo\nbar\nqux\ncorge", true );
574 }
575
576 function testOutputChanneledWAndWOChannelStringStartWO() {
577 $this->m->outputChanneled( "foo" );
578 $this->m->outputChanneled( "bar", "bazChannel" );
579 $this->m->outputChanneled( "qux" );
580 $this->m->outputChanneled( "quux", "bazChannel" );
581 $this->assertOutputPrePostShutdown( "foo\nbar\nqux\nquux", true );
582 }
583
584 function testOutputChanneledWAndWOChannelStringStartW() {
585 $this->m->outputChanneled( "foo", "bazChannel" );
586 $this->m->outputChanneled( "bar" );
587 $this->m->outputChanneled( "qux", "bazChannel" );
588 $this->m->outputChanneled( "quux" );
589 $this->assertOutputPrePostShutdown( "foo\nbar\nqux\nquux\n", false );
590 }
591
592 function testOutputChanneledWChannelTypeSwitch() {
593 $this->m->outputChanneled( "foo", 1 );
594 $this->m->outputChanneled( "bar", 1.0 );
595 $this->assertOutputPrePostShutdown( "foo\nbar", true );
596 }
597
598 function testOutputChanneledWOChannelIntermittentEmpty() {
599 $this->m->outputChanneled( "foo" );
600 $this->m->outputChanneled( "" );
601 $this->m->outputChanneled( "bar" );
602 $this->assertOutputPrePostShutdown( "foo\n\nbar\n", false );
603 }
604
605 function testOutputChanneledWOChannelIntermittentFalse() {
606 $this->m->outputChanneled( "foo" );
607 $this->m->outputChanneled( false );
608 $this->m->outputChanneled( "bar" );
609 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
610 }
611
612 function testOutputChanneledWNullChannelIntermittentEmpty() {
613 $this->m->outputChanneled( "foo", null );
614 $this->m->outputChanneled( "", null );
615 $this->m->outputChanneled( "bar", null );
616 $this->assertOutputPrePostShutdown( "foo\n\nbar\n", false );
617 }
618
619 function testOutputChanneledWNullChannelIntermittentFalse() {
620 $this->m->outputChanneled( "foo", null );
621 $this->m->outputChanneled( false, null );
622 $this->m->outputChanneled( "bar", null );
623 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
624 }
625
626 function testOutputChanneledWChannelIntermittentEmpty() {
627 $this->m->outputChanneled( "foo", "bazChannel" );
628 $this->m->outputChanneled( "", "bazChannel" );
629 $this->m->outputChanneled( "bar", "bazChannel" );
630 $this->assertOutputPrePostShutdown( "foobar", true );
631 }
632
633 function testOutputChanneledWChannelIntermittentFalse() {
634 $this->m->outputChanneled( "foo", "bazChannel" );
635 $this->m->outputChanneled( false, "bazChannel" );
636 $this->m->outputChanneled( "bar", "bazChannel" );
637 $this->assertOutputPrePostShutdown( "foo\nbar", true );
638 }
639
640 function testCleanupChanneledClean() {
641 $this->m->cleanupChanneled();
642 $this->assertOutputPrePostShutdown( "", false );
643 }
644
645 function testCleanupChanneledAfterOutput() {
646 $this->m->output( "foo" );
647 $this->m->cleanupChanneled();
648 $this->assertOutputPrePostShutdown( "foo", false );
649 }
650
651 function testCleanupChanneledAfterOutputWNullChannel() {
652 $this->m->output( "foo", null );
653 $this->m->cleanupChanneled();
654 $this->assertOutputPrePostShutdown( "foo", false );
655 }
656
657 function testCleanupChanneledAfterOutputWChannel() {
658 $this->m->output( "foo", "bazChannel" );
659 $this->m->cleanupChanneled();
660 $this->assertOutputPrePostShutdown( "foo\n", false );
661 }
662
663 function testCleanupChanneledAfterNLOutput() {
664 $this->m->output( "foo\n" );
665 $this->m->cleanupChanneled();
666 $this->assertOutputPrePostShutdown( "foo\n", false );
667 }
668
669 function testCleanupChanneledAfterNLOutputWNullChannel() {
670 $this->m->output( "foo\n", null );
671 $this->m->cleanupChanneled();
672 $this->assertOutputPrePostShutdown( "foo\n", false );
673 }
674
675 function testCleanupChanneledAfterNLOutputWChannel() {
676 $this->m->output( "foo\n", "bazChannel" );
677 $this->m->cleanupChanneled();
678 $this->assertOutputPrePostShutdown( "foo\n", false );
679 }
680
681 function testCleanupChanneledAfterOutputChanneledWOChannel() {
682 $this->m->outputChanneled( "foo" );
683 $this->m->cleanupChanneled();
684 $this->assertOutputPrePostShutdown( "foo\n", false );
685 }
686
687 function testCleanupChanneledAfterOutputChanneledWNullChannel() {
688 $this->m->outputChanneled( "foo", null );
689 $this->m->cleanupChanneled();
690 $this->assertOutputPrePostShutdown( "foo\n", false );
691 }
692
693 function testCleanupChanneledAfterOutputChanneledWChannel() {
694 $this->m->outputChanneled( "foo", "bazChannel" );
695 $this->m->cleanupChanneled();
696 $this->assertOutputPrePostShutdown( "foo\n", false );
697 }
698
699 function testMultipleMaintenanceObjectsInteractionOutput() {
700 $m2 = new MaintenanceFixup( $this );
701
702 $this->m->output( "foo" );
703 $m2->output( "bar" );
704
705 $this->assertEquals( "foobar", $this->getActualOutput(),
706 "Output before shutdown simulation (m2)" );
707 $m2->simulateShutdown();
708 $this->assertOutputPrePostShutdown( "foobar", false );
709 }
710
711 function testMultipleMaintenanceObjectsInteractionOutputWNullChannel() {
712 $m2 = new MaintenanceFixup( $this );
713
714 $this->m->output( "foo", null );
715 $m2->output( "bar", null );
716
717 $this->assertEquals( "foobar", $this->getActualOutput(),
718 "Output before shutdown simulation (m2)" );
719 $m2->simulateShutdown();
720 $this->assertOutputPrePostShutdown( "foobar", false );
721 }
722
723 function testMultipleMaintenanceObjectsInteractionOutputWChannel() {
724 $m2 = new MaintenanceFixup( $this );
725
726 $this->m->output( "foo", "bazChannel" );
727 $m2->output( "bar", "bazChannel" );
728
729 $this->assertEquals( "foobar", $this->getActualOutput(),
730 "Output before shutdown simulation (m2)" );
731 $m2->simulateShutdown();
732 $this->assertOutputPrePostShutdown( "foobar\n", true );
733 }
734
735 function testMultipleMaintenanceObjectsInteractionOutputWNullChannelNL() {
736 $m2 = new MaintenanceFixup( $this );
737
738 $this->m->output( "foo\n", null );
739 $m2->output( "bar\n", null );
740
741 $this->assertEquals( "foo\nbar\n", $this->getActualOutput(),
742 "Output before shutdown simulation (m2)" );
743 $m2->simulateShutdown();
744 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
745 }
746
747 function testMultipleMaintenanceObjectsInteractionOutputWChannelNL() {
748 $m2 = new MaintenanceFixup( $this );
749
750 $this->m->output( "foo\n", "bazChannel" );
751 $m2->output( "bar\n", "bazChannel" );
752
753 $this->assertEquals( "foobar", $this->getActualOutput(),
754 "Output before shutdown simulation (m2)" );
755 $m2->simulateShutdown();
756 $this->assertOutputPrePostShutdown( "foobar\n", true );
757 }
758
759 function testMultipleMaintenanceObjectsInteractionOutputChanneled() {
760 $m2 = new MaintenanceFixup( $this );
761
762 $this->m->outputChanneled( "foo" );
763 $m2->outputChanneled( "bar" );
764
765 $this->assertEquals( "foo\nbar\n", $this->getActualOutput(),
766 "Output before shutdown simulation (m2)" );
767 $m2->simulateShutdown();
768 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
769 }
770
771 function testMultipleMaintenanceObjectsInteractionOutputChanneledWNullChannel() {
772 $m2 = new MaintenanceFixup( $this );
773
774 $this->m->outputChanneled( "foo", null );
775 $m2->outputChanneled( "bar", null );
776
777 $this->assertEquals( "foo\nbar\n", $this->getActualOutput(),
778 "Output before shutdown simulation (m2)" );
779 $m2->simulateShutdown();
780 $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
781 }
782
783 function testMultipleMaintenanceObjectsInteractionOutputChanneledWChannel() {
784 $m2 = new MaintenanceFixup( $this );
785
786 $this->m->outputChanneled( "foo", "bazChannel" );
787 $m2->outputChanneled( "bar", "bazChannel" );
788
789 $this->assertEquals( "foobar", $this->getActualOutput(),
790 "Output before shutdown simulation (m2)" );
791 $m2->simulateShutdown();
792 $this->assertOutputPrePostShutdown( "foobar\n", true );
793 }
794
795 function testMultipleMaintenanceObjectsInteractionCleanupChanneledWChannel() {
796 $m2 = new MaintenanceFixup( $this );
797
798 $this->m->outputChanneled( "foo", "bazChannel" );
799 $m2->outputChanneled( "bar", "bazChannel" );
800
801 $this->assertEquals( "foobar", $this->getActualOutput(),
802 "Output before first cleanup" );
803 $this->m->cleanupChanneled();
804 $this->assertEquals( "foobar\n", $this->getActualOutput(),
805 "Output after first cleanup" );
806 $m2->cleanupChanneled();
807 $this->assertEquals( "foobar\n\n", $this->getActualOutput(),
808 "Output after second cleanup" );
809
810 $m2->simulateShutdown();
811 $this->assertOutputPrePostShutdown( "foobar\n\n", false );
812 }
813 }