Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions .github/workflows/benchmark-comment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,11 @@ jobs:

Comparison of `${{ steps.bench.outputs.head-ref }}` against `${{ steps.bench.outputs.base-ref }}` (`${{ steps.bench.outputs.base-sha }}`).

```
<details>
<summary>Open to see the benchmark results</summary>

${{ steps.bench.outputs.result }}
```

</details>

<sub>Generated by phpbench against commit ${{ steps.bench.outputs.head-sha }}</sub>
2 changes: 1 addition & 1 deletion .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
run: |
git checkout ${{ github.event.pull_request.head.sha }}
composer install --no-interaction --prefer-dist --quiet
vendor/bin/phpbench run --tag=pr --store --ref=base --report=aggregate --progress=none 2>&1 | tee benchmark-result.txt || true
vendor/bin/phpbench run --tag=pr --store --ref=base --report=aggregate --progress=none --output=markdown | tee benchmark-result.txt || true

- name: Prepare artifact
run: |
Expand Down
5 changes: 4 additions & 1 deletion phpbench.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,8 @@
"$schema": "./vendor/phpbench/phpbench/phpbench.schema.json",
"runner.bootstrap": "vendor/autoload.php",
"runner.path": "tests/Bench",
"runner.file_pattern": "*Bench.php"
"runner.file_pattern": "*Bench.php",
"core.extensions": [
"Tempest\\Highlight\\Tests\\Bench\\Extension\\MarkdownExtension"
]
}
33 changes: 33 additions & 0 deletions tests/Bench/Extension/MarkdownExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace Tempest\Highlight\Tests\Bench\Extension;

use PhpBench\DependencyInjection\Container;
use PhpBench\DependencyInjection\ExtensionInterface;
use PhpBench\Extension\ConsoleExtension;
use PhpBench\Extension\ExpressionExtension;
use PhpBench\Extension\ReportExtension;
use Symfony\Component\OptionsResolver\OptionsResolver;

final class MarkdownExtension implements ExtensionInterface
{
public function configure(OptionsResolver $resolver): void
{
}

public function load(Container $container): void
{
$container->register(MarkdownRenderer::class, function (Container $container) {
return new MarkdownRenderer(
$container->get(ConsoleExtension::SERVICE_OUTPUT_STD),
$container->get(ExpressionExtension::SERVICE_PLAIN_PRINTER),
);
}, [
ReportExtension::TAG_REPORT_RENDERER => [
'name' => 'markdown',
],
]);
}
}
133 changes: 133 additions & 0 deletions tests/Bench/Extension/MarkdownRenderer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
<?php

declare(strict_types=1);

namespace Tempest\Highlight\Tests\Bench\Extension;

use PhpBench\Expression\Ast\Node;
use PhpBench\Expression\Printer;
use PhpBench\Registry\Config;
use PhpBench\Report\Model\Reports;
use PhpBench\Report\Model\Table;
use PhpBench\Report\Model\TableRow;
use PhpBench\Report\RendererInterface;
use RuntimeException;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

final readonly class MarkdownRenderer implements RendererInterface
{
public function __construct(
private OutputInterface $output,
private Printer $printer,
) {
}

public function render(Reports $reports, Config $config): void
{
$content = $this->renderContent($reports);
$file = $config['file'];

if ($file === null) {
$this->output->write($content);

return;
}

$this->writeFile($file, $content);
}

public function configure(OptionsResolver $options): void
{
$options->setDefaults([
'file' => null,
]);
$options->setAllowedTypes('file', ['null', 'string']);
}

private function renderContent(Reports $reports): string
{
$lines = [];

foreach ($reports->tables() as $table) {
array_push($lines, ...$this->renderTable($table));
}

return implode("\n", $lines) . "\n";
}

private function renderTable(Table $table): array
{
$lines = [];
$title = $table->title();

if ($title !== null && $title !== '') {
$lines[] = "## {$title}";
$lines[] = '';
}

$columns = $table->columnNames();

if ($columns === []) {
return $lines;
}

$lines[] = $this->renderRow($columns);
$lines[] = $this->renderSeparatorRow($columns);

foreach ($table as $row) {
$lines[] = $this->renderDataRow($row);
}

$lines[] = '';

return $lines;
}

private function renderRow(array $cells): string
{
return '| ' . implode(' | ', $cells) . ' |';
}

private function renderSeparatorRow(array $columns): string
{
return $this->renderRow(array_map(
fn (string $column): string => str_repeat('-', max(3, mb_strlen($column))),
$columns,
));
}

private function renderDataRow(TableRow $row): string
{
$cells = array_map($this->formatCell(...), iterator_to_array($row));

return $this->renderRow($cells);
}

private function formatCell(Node $node): string
{
return str_replace('|', '\\|', trim($this->printer->print($node)));
}

private function writeFile(string $file, string $content): void
{
$this->createDirectory(dirname($file));

if (file_put_contents($file, $content) === false) {
throw new RuntimeException(sprintf('Could not write to file "%s"', $file));
}

$this->output->writeln("Written markdown report to: {$file}");
}

private function createDirectory(string $directory): void
{
if (is_dir($directory)) {
return;
}

if (! mkdir($directory, 0o777, true) && ! is_dir($directory)) {
throw new RuntimeException(sprintf('Could not create directory "%s"', $directory));
}
}
}