Class Kitab\Compiler\Target\DocTest\CodeBlockHandler\Php

class Php
{
    public function getDefinitionName(): string;
    public function mightHandleCodeblock(string $codeBlockType): bool;
    public function compileToTestCaseBody(string $codeBlockType, string $codeBlockContent): string;
    protected function unfoldCode(string $phpCode): string;
    protected static function getPhpTraverser(): PhpParser\NodeTraverser;
}

A code block handler for the php type.

This handler defines the php type with the following options:

  • php,ignore to avoid compiling the code block into a test case. The code block is just displayed in the documentation, but not tested,
  • php,must_throw to indicate that the code block must throw an exception, so catching an exception is expected,
  • php,must_throw(E) to indicate that the code block must throw an exception of kind E.

Attributes

protected static $_phpTraverser = null;

A traverser, for PHP-Parser, is a set of visitors visiting the Abstract Syntax Tree produced by the parser. This traverser will be used to pretty print the PHP code, and to make it embeddable inside a test case.

The traverser is allocated once, hence the static declaration.

Methods

public function getDefinitionName(): string

The handler name is php.

Examples

$handler = new Kitab\Compiler\Target\DocTest\CodeBlockHandler\Php();

assert('php' === $handler->getDefinitionName());
public function mightHandleCodeblock(string $codeBlockType): bool

Check whether a code block type contains php or is empty. The consequence is that the php type will be assumed if a code block has no type.

Examples

All the following type syntaxes are handled:

$handler = new Kitab\Compiler\Target\DocTest\CodeBlockHandler\Php();

assert(true  === $handler->mightHandleCodeblock('php'));
assert(true  === $handler->mightHandleCodeblock('php,ignore'));
assert(true  === $handler->mightHandleCodeblock('php,must_throw'));
assert(false === $handler->mightHandleCodeblock('foobar'));

A code block with no type is assumed to be of type php:

$handler = new Kitab\Compiler\Target\DocTest\CodeBlockHandler\Php();

assert($handler->mightHandleCodeblock(''));
public function compileToTestCaseBody(string $codeBlockType, string $codeBlockContent): string

Unfold the code block content, and compile it into a test case.

Examples

A regular code block content:

$handler = new Kitab\Compiler\Target\DocTest\CodeBlockHandler\Php();

$codeBlockType    = 'php';
$codeBlockContent = 'assert(true);';
$output           =
    '$this' . "\n" .
    '    ->assert(function () {' . "\n" .
    '        \assert(\true);' . "\n" .
    '    });';

assert($output === $handler->compileToTestCaseBody($codeBlockType, $codeBlockContent));

A code block that must not be tested:

$handler = new Kitab\Compiler\Target\DocTest\CodeBlockHandler\Php();

$codeBlockType    = 'php,ignore';
$codeBlockContent = 'assert(true);';
$output           = '$this->skip(\'Skipped because the code block type contains `ignore`: `php,ignore`.\');';

assert($output === $handler->compileToTestCaseBody($codeBlockType, $codeBlockContent));

A code block that must throw an exception of kind E:

$handler = new Kitab\Compiler\Target\DocTest\CodeBlockHandler\Php();

$codeBlockType    = 'php,must_throw(E)';
$codeBlockContent = 'assert(true);';
$output           =
    '$this' . "\n" .
    '    ->exception(function () {' . "\n" .
    '        \assert(\true);' . "\n" .
    '    })' . "\n" .
    '        ->isInstanceOf(\E::class);';

assert($output === $handler->compileToTestCaseBody($codeBlockType, $codeBlockContent));
protected function unfoldCode(string $phpCode): string

Prepare the code to be embeddable inside a test case.

protected static function getPhpTraverser(): PhpParser\NodeTraverser

Get the statically allocated traverser instance.

Interfaces

interface Kitab\Compiler\Target\DocTest\CodeBlockHandler\Definition