- Add comprehensive health check system with multiple endpoints - Add Prometheus metrics endpoint - Add production logging configurations (5 strategies) - Add complete deployment documentation suite: * QUICKSTART.md - 30-minute deployment guide * DEPLOYMENT_CHECKLIST.md - Printable verification checklist * DEPLOYMENT_WORKFLOW.md - Complete deployment lifecycle * PRODUCTION_DEPLOYMENT.md - Comprehensive technical reference * production-logging.md - Logging configuration guide * ANSIBLE_DEPLOYMENT.md - Infrastructure as Code automation * README.md - Navigation hub * DEPLOYMENT_SUMMARY.md - Executive summary - Add deployment scripts and automation - Add DEPLOYMENT_PLAN.md - Concrete plan for immediate deployment - Update README with production-ready features All production infrastructure is now complete and ready for deployment.
162 lines
4.5 KiB
PHP
162 lines
4.5 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Framework\OutputBuffer\BufferHandle;
|
|
use App\Framework\OutputBuffer\OutputBuffer;
|
|
use App\Framework\OutputBuffer\OutputBufferConfig;
|
|
use App\Framework\OutputBuffer\OutputBufferException;
|
|
|
|
describe('BufferHandle', function () {
|
|
beforeEach(function () {
|
|
while (ob_get_level() > 0) {
|
|
ob_end_clean();
|
|
}
|
|
});
|
|
|
|
afterEach(function () {
|
|
while (ob_get_level() > 0) {
|
|
ob_end_clean();
|
|
}
|
|
});
|
|
|
|
describe('clean()', function () {
|
|
it('cleans buffer and returns content', function () {
|
|
$handle = OutputBuffer::start();
|
|
echo "Test content";
|
|
|
|
$content = $handle->clean();
|
|
|
|
expect($content)->toBe("Test content");
|
|
expect(ob_get_level())->toBe(0);
|
|
});
|
|
|
|
it('throws exception if buffer level mismatch', function () {
|
|
$handle = OutputBuffer::start();
|
|
ob_start(); // Create additional buffer
|
|
|
|
expect(fn() => $handle->clean())
|
|
->toThrow(OutputBufferException::class);
|
|
|
|
ob_end_clean();
|
|
$handle->end();
|
|
});
|
|
});
|
|
|
|
describe('end()', function () {
|
|
it('ends buffer without returning content', function () {
|
|
$handle = OutputBuffer::start();
|
|
echo "Test content";
|
|
|
|
$handle->end();
|
|
|
|
expect(ob_get_level())->toBe(0);
|
|
});
|
|
|
|
it('validates buffer level before ending', function () {
|
|
$handle = OutputBuffer::start();
|
|
$handle->end();
|
|
|
|
expect(fn() => $handle->end())
|
|
->toThrow(OutputBufferException::class);
|
|
});
|
|
});
|
|
|
|
describe('flush()', function () {
|
|
it('flushes buffer contents', function () {
|
|
$handle = OutputBuffer::start();
|
|
echo "Test";
|
|
|
|
// Flush should work (though output goes nowhere in tests)
|
|
expect(fn() => $handle->flush())->not->toThrow(Exception::class);
|
|
|
|
$handle->end();
|
|
});
|
|
});
|
|
|
|
describe('getContents()', function () {
|
|
it('gets contents without clearing buffer', function () {
|
|
$handle = OutputBuffer::start();
|
|
echo "Test";
|
|
|
|
$content = $handle->getContents();
|
|
|
|
expect($content)->toBe("Test");
|
|
expect($handle->isActive())->toBeTrue();
|
|
|
|
$handle->end();
|
|
});
|
|
|
|
it('can be called multiple times', function () {
|
|
$handle = OutputBuffer::start();
|
|
echo "Test";
|
|
|
|
$content1 = $handle->getContents();
|
|
echo " More";
|
|
$content2 = $handle->getContents();
|
|
|
|
expect($content1)->toBe("Test");
|
|
expect($content2)->toBe("Test More");
|
|
|
|
$handle->end();
|
|
});
|
|
});
|
|
|
|
describe('getLength()', function () {
|
|
it('returns buffer content length', function () {
|
|
$handle = OutputBuffer::start();
|
|
|
|
expect($handle->getLength())->toBe(0);
|
|
|
|
echo "Test";
|
|
expect($handle->getLength())->toBe(4);
|
|
|
|
echo "ing";
|
|
expect($handle->getLength())->toBe(7);
|
|
|
|
$handle->end();
|
|
});
|
|
});
|
|
|
|
describe('isActive()', function () {
|
|
it('returns true when buffer is active', function () {
|
|
$handle = OutputBuffer::start();
|
|
|
|
expect($handle->isActive())->toBeTrue();
|
|
|
|
$handle->end();
|
|
});
|
|
|
|
it('returns false after buffer is cleaned', function () {
|
|
$handle = OutputBuffer::start();
|
|
$handle->end();
|
|
|
|
expect($handle->isActive())->toBeFalse();
|
|
});
|
|
});
|
|
|
|
describe('level validation', function () {
|
|
it('validates buffer level for all operations', function () {
|
|
$handle = OutputBuffer::start();
|
|
$handle->end();
|
|
|
|
// All operations should fail after buffer is ended
|
|
expect(fn() => $handle->clean())->toThrow(OutputBufferException::class);
|
|
expect(fn() => $handle->getContents())->toThrow(OutputBufferException::class);
|
|
expect(fn() => $handle->flush())->toThrow(OutputBufferException::class);
|
|
});
|
|
|
|
it('detects level mismatch', function () {
|
|
$handle1 = OutputBuffer::start();
|
|
$handle2 = OutputBuffer::start();
|
|
|
|
// Try to clean handle1 while handle2 is active
|
|
expect(fn() => $handle1->clean())
|
|
->toThrow(OutputBufferException::class);
|
|
|
|
$handle2->end();
|
|
$handle1->end();
|
|
});
|
|
});
|
|
});
|