Skip to main content
Glama

CTX: Context as Code (CaC) tool

by context-hub
MIT License
235
  • Apple
  • Linux
DocumentCompilerTest.php9.5 kB
<?php declare(strict_types=1); namespace Tests\Unit\Document\Compiler; use Butschster\ContextGenerator\Document\Compiler\DocumentCompiler; use Butschster\ContextGenerator\Document\Compiler\Error\SourceError; use Butschster\ContextGenerator\Document\Document; use Butschster\ContextGenerator\Lib\Content\ContentBuilderFactory; use Butschster\ContextGenerator\Lib\Variable\VariableResolver; use Butschster\ContextGenerator\Modifier\SourceModifierRegistry; use Butschster\ContextGenerator\Source\SourceInterface; use Butschster\ContextGenerator\SourceParserInterface; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\Test; use Psr\Log\LoggerInterface; use Spiral\Files\FilesInterface; use Tests\TestCase; #[CoversClass(DocumentCompiler::class)] final class DocumentCompilerTest extends TestCase { private DocumentCompiler $compiler; private FilesInterface $files; private SourceParserInterface $parser; private SourceModifierRegistry $modifierRegistry; private ContentBuilderFactory $builderFactory; private LoggerInterface $logger; #[Test] public function it_should_compile_document_with_basic_content(): void { $document = Document::create( description: 'Test Document', outputPath: 'output.txt', overwrite: true, ); $this->files ->expects($this->once()) ->method('exists') ->with('/base/path/output.txt') ->willReturn(false); $this->files ->expects($this->once()) ->method('ensureDirectory') ->with('/base/path'); $this->files ->expects($this->once()) ->method('write') ->with( '/base/path/output.txt', $content = "# Test Document", ); $compiled = $this->compiler->compile($document); $this->assertEquals($content, (string) $compiled->content); $this->assertEquals(0, \count($compiled->errors)); } #[Test] public function it_should_skip_compilation_if_file_exists_and_overwrite_is_false(): void { $document = Document::create( description: 'Test Document', outputPath: 'output.txt', overwrite: false, ); $this->files ->expects($this->once()) ->method('exists') ->with('/base/path/output.txt') ->willReturn(true); $this->files ->expects($this->never()) ->method('write'); $compiled = $this->compiler->compile($document); $this->assertEquals("", (string) $compiled->content); $this->assertEquals(0, \count($compiled->errors)); } #[Test] public function it_should_handle_source_errors(): void { $document = Document::create( description: 'Test Document', outputPath: 'output.txt', overwrite: true, ); $source = $this->createMock(SourceInterface::class); $source ->method('parseContent') ->willThrowException(new \RuntimeException('Source error')); $document = $document->addSource($source); $this->files ->expects($this->once()) ->method('exists') ->with('/base/path/output.txt') ->willReturn(false); $compiled = $this->compiler->compile($document); $this->assertEquals("# Test Document", (string) $compiled->content); $this->assertEquals(1, \count($compiled->errors)); $this->assertInstanceOf(SourceError::class, $compiled->errors->getIterator()[0]); } #[Test] public function it_should_include_document_tags(): void { $document = Document::create( description: 'Test Document', outputPath: 'output.txt', overwrite: true, )->addTag(...['tag1', 'tag2']); $this->files ->expects($this->once()) ->method('exists') ->with('/base/path/output.txt') ->willReturn(false); $this->files ->expects($this->once()) ->method('write') ->with( '/base/path/output.txt', $content = "# Test Document\n<DOCUMENT_TAGS>\ntag1, tag2\n</DOCUMENT_TAGS>", ); $compiled = $this->compiler->compile($document); $this->assertEquals($content, (string) $compiled->content); $this->assertEquals(0, \count($compiled->errors)); } #[Test] public function it_should_process_multiple_sources(): void { $document = Document::create( description: 'Test Document', outputPath: 'output.txt', overwrite: true, ); $source1 = $this->createMock(SourceInterface::class); $source1 ->method('parseContent') ->willReturn('Content from source 1'); $source2 = $this->createMock(SourceInterface::class); $source2 ->method('parseContent') ->willReturn('Content from source 2'); $document = $document->addSource($source1)->addSource($source2); $this->files ->expects($this->once()) ->method('exists') ->with('/base/path/output.txt') ->willReturn(false); $this->files ->expects($this->once()) ->method('write') ->with( '/base/path/output.txt', $content = "# Test Document\nContent from source 1\nContent from source 2", ); $compiled = $this->compiler->compile($document); $this->assertEquals($content, (string) $compiled->content); $this->assertEquals(0, \count($compiled->errors)); } #[Test] public function it_should_include_source_description(): void { $document = Document::create( description: 'Test Document', outputPath: 'output.txt', overwrite: true, ); $source = $this->createMock(SourceInterface::class); $source->method('hasDescription')->willReturn(true); $source->method('getDescription')->willReturn('Source Description'); $source->method('parseContent')->willReturn('Source content'); $document = $document->addSource($source); $this->files ->expects($this->once()) ->method('write') ->with( '/base/path/output.txt', $content = "# Test Document\n_SOURCE: Source Description_\nSource content", ); $compiled = $this->compiler->compile($document); $this->assertEquals($content, (string) $compiled->content); $this->assertEquals(0, \count($compiled->errors)); } #[Test] public function it_should_handle_multiple_source_errors(): void { $document = Document::create( description: 'Test Document', outputPath: 'output.txt', overwrite: true, ); $source1 = $this->createMock(SourceInterface::class); $source1 ->method('parseContent') ->willThrowException(new \RuntimeException('Error 1')); $source2 = $this->createMock(SourceInterface::class); $source2 ->method('parseContent') ->willThrowException(new \RuntimeException('Error 2')); $document = $document->addSource($source1)->addSource($source2); $compiled = $this->compiler->compile($document); $this->assertEquals("# Test Document", (string) $compiled->content); $this->assertEquals(2, \count($compiled->errors)); $errors = \iterator_to_array($compiled->errors->getIterator()); $this->assertInstanceOf(SourceError::class, $errors[0]); $this->assertInstanceOf(SourceError::class, $errors[1]); $this->assertEquals('Error 1', $errors[0]->exception->getMessage()); $this->assertEquals('Error 2', $errors[1]->exception->getMessage()); } #[Test] public function it_should_compile_empty_document(): void { $document = Document::create( description: 'Empty Document', outputPath: 'empty.txt', overwrite: true, ); $this->files ->expects($this->once()) ->method('write') ->with( '/base/path/empty.txt', $content = "# Empty Document", ); $compiled = $this->compiler->compile($document); $this->assertEquals($content, (string) $compiled->content); $this->assertEquals(0, \count($compiled->errors)); } protected function setUp(): void { parent::setUp(); $this->files = $this->createMock(FilesInterface::class); $this->parser = $this->createMock(SourceParserInterface::class); $this->modifierRegistry = new SourceModifierRegistry(); $this->builderFactory = new ContentBuilderFactory(); $this->logger = $this->createMock(LoggerInterface::class); $this->compiler = new DocumentCompiler( files: $this->files, parser: $this->parser, basePath: '/base/path', modifierRegistry: $this->modifierRegistry, variables: new VariableResolver(), builderFactory: $this->builderFactory, logger: $this->logger, ); } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/context-hub/generator'

If you have feedback or need assistance with the MCP directory API, please join our Discord server