<?php

function testBufferCallback1() {
    echo "callback1";
}

class testBufferCallbackFromCallback {
    
    public $buffer;
    
    function doit() {
        echo "pre-";
        $this->buffer->onOutputDo('testBufferCallback1');
        echo "-post";
    }
}


class Wact_Response_BufferTestCase extends Wact_Test_Case {

    protected $buffer;

    function setUp() {
        $this->buffer = new Wact_Response_Buffer();
    }

    function testEndOutputsBufferContents() {
        $text = "hello";
    
        ob_start();
        $levelBefore = ob_get_level();

        $this->buffer->start();
        echo $text;
        $this->buffer->end();
        
        $levelAfter = ob_get_level();
        $result = ob_get_clean();

        // Outer buffer should contain the content of the inner buffer        
        $this->assertEqual($result, $text);
    }

    function testGetReturnsBufferedOutput() {
        $text = "hello";
    
        ob_start();
        $levelBefore = ob_get_level();

        $this->buffer->start();
        echo $text;
        $buffered = $this->buffer->get();
        
        $levelAfter = ob_get_level();
        $result = ob_get_clean();
        
        // output buffering levels should be balanced
        $this->assertEqual($levelBefore, $levelAfter);
        
        // There should be no output
        $this->assertEqual($result, '');

        // The buffered value should be what we echoed
        $this->assertEqual($buffered, $text);
    }

    function testCleanOutputsNothing() {
        $text = "hello";
    
        ob_start();
        $levelBefore = ob_get_level();

        $this->buffer->start();
        echo $text;
        $this->buffer->clean();
        
        $levelAfter = ob_get_level();
        $result = ob_get_clean();

        // output buffering levels should be balanced
        $this->assertEqual($levelBefore, $levelAfter);
        
        // There should be no output
        $this->assertEqual($result, '');
    }

    function testNestedBuffersReturnsBufferedOutput() {
        ob_start();
        $levelBefore = ob_get_level();

        $this->buffer->start();
        echo '1';
        $this->buffer->start();
        echo '-2-';
        $this->buffer->end();
        echo '3';
        $buffered = $this->buffer->get();
        
        $levelAfter = ob_get_level();
        $result = ob_get_clean();
        
        // output buffering levels should be balanced
        $this->assertEqual($levelBefore, $levelAfter);
        
        // There should be no output
        $this->assertEqual($result, '');

        // The buffered value should be what we echoed
        $this->assertEqual($buffered, '1-2-3');
    }

    function testCleanInsideNestedBufferDiscardsOutput() {
        ob_start();
        $levelBefore = ob_get_level();

        $this->buffer->start();
        echo '1';
        $this->buffer->start();
        echo '-2-';
        $this->buffer->clean();
        echo '3';
        $buffered = $this->buffer->get();
        
        $levelAfter = ob_get_level();
        $result = ob_get_clean();
        
        // output buffering levels should be balanced
        $this->assertEqual($levelBefore, $levelAfter);
        
        // There should be no output
        $this->assertEqual($result, '');

        // The buffered value should be what we echoed
        $this->assertEqual($buffered, '13');
    }

    function testTwoConsecutiveSeqmentsNested() {
        ob_start();
        $levelBefore = ob_get_level();

        $this->buffer->start();
        $this->buffer->start();
        echo "one-";
        $this->buffer->end();
        $this->buffer->start();
        echo "two";
        $this->buffer->end();
        $buffered = $this->buffer->get();
        
        $levelAfter = ob_get_level();
        $result = ob_get_clean();
        
        // output buffering levels should be balanced
        $this->assertEqual($levelBefore, $levelAfter);
        
        // There should be no output
        $this->assertEqual($result, '');

        // The buffered value should be what we echoed
        $this->assertEqual($buffered, 'one-two');
    }

    function testCallbackOutputIsBuffered() {
        ob_start();
        $levelBefore = ob_get_level();

        $this->buffer->start();
        echo "before-";
        $this->buffer->onOutputDo('testBufferCallback1');
        echo "-after";
        $buffered = $this->buffer->get();
        
        $levelAfter = ob_get_level();
        $result = ob_get_clean();
        
        // output buffering levels should be balanced
        $this->assertEqual($levelBefore, $levelAfter);
        
        // There should be no output
        $this->assertEqual($result, '');

        // The buffered value should be what we echoed
        $this->assertEqual($buffered, 'before-callback1-after');
    }

    function testTwoConsecutiveCallbacks() {
        ob_start();
        $levelBefore = ob_get_level();

        $this->buffer->start();
        echo "before-";
        $this->buffer->onOutputDo('testBufferCallback1');
        echo "-";
        $this->buffer->onOutputDo('testBufferCallback1');
        echo "-after";
        $buffered = $this->buffer->get();
        
        $levelAfter = ob_get_level();
        $result = ob_get_clean();
        
        // output buffering levels should be balanced
        $this->assertEqual($levelBefore, $levelAfter);
        
        // There should be no output
        $this->assertEqual($result, '');

        // The buffered value should be what we echoed
        $this->assertEqual($buffered, 'before-callback1-callback1-after');
    }

    function testCalbackWithinCallbackIsNotInfinite() {
        ob_start();
        $levelBefore = ob_get_level();

        $obj = new testBufferCallbackFromCallback();
        $obj->buffer = $this->buffer;
    
        $this->buffer->start();
        echo "before-";
        $this->buffer->onOutputDo(array($obj, 'doit'));
        echo "-after";
        $buffered = $this->buffer->get();
        
        $levelAfter = ob_get_level();
        $result = ob_get_clean();
        
        // output buffering levels should be balanced
        $this->assertEqual($levelBefore, $levelAfter);
        
        // There should be no output
        $this->assertEqual($result, '');

        // The buffered value should be what we echoed
        $this->assertEqual($buffered, 'before-pre-callback1-post-after');
    }

}

?>