packages/sql-fixture/bench/FixtureGenerationBench.php

1<?php
2
3declare(strict_types=1);
4
5namespace Bench;
6
7use Faker\Factory;
8use PhpBench\Attributes as Bench;
9use SqlFixture\FixtureProvider;
10use SqlFixture\Plan\FixturePlan;
11
12/**
13 * Measures warm row generation separately from relational-plan materialization.
14 */
15#[Bench\Groups(['fixtures'])]
16#[Bench\BeforeMethods('setUp')]
17#[Bench\Revs(5000)]
18final class FixtureGenerationBench
19{
20    private const ITEMS_SQL = 'CREATE TABLE items (id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(80) NOT NULL, price DECIMAL(8,2) NOT NULL)';
21
22    private FixtureProvider $provider;
23    private FixturePlan $plan;
24
25    /**
26     * Warms schema and plan caches outside the measured operation, then seeds the random source.
27     */
28    public function setUp(): void
29    {
30        $faker = Factory::create();
31        $this->provider = new FixtureProvider($faker);
32        $this->provider->registerSchema(self::ITEMS_SQL);
33        $this->provider->registerSchema('CREATE TABLE details (item_id INT NOT NULL, quantity INT NOT NULL)');
34        $this->plan = FixturePlan::from('items.id < details.item_id');
35        $faker->seed(2026);
36    }
37
38    /**
39     * Generates one row through the cached public provider.
40     */
41    public function benchWarmRow(): void
42    {
43        $this->provider->fixture(self::ITEMS_SQL);
44    }
45
46    /**
47     * Generates a fixed three-child relation without reparsing the plan.
48     */
49    public function benchRelatedRows(): void
50    {
51        $this->provider->fixtures($this->plan, ['details' => 3]);
52    }
53}
54