xref: /dokuwiki/_test/tests/Parsing/ParserMode/ParserTestBase.php (revision 504c13e8df88563c11b3720b317991bc38835a35)
1<?php
2
3namespace dokuwiki\test\Parsing\ParserMode;
4
5use dokuwiki\Parsing\Handler;
6use dokuwiki\Parsing\Parser;
7
8/**
9 * Base class for parser mode tests
10 *
11 * Sets up a fresh Parser and Handler for each test. Provides assertion helpers
12 * for comparing handler call sequences.
13 */
14abstract class ParserTestBase extends \DokuWikiTest
15{
16    /** @var Parser parser instance for the current test */
17    protected Parser $P;
18    /** @var Handler handler instance that records calls made by the parser */
19    protected Handler $H;
20
21    /** @inheritdoc */
22    public function setUp(): void
23    {
24        parent::setUp();
25        $this->H = new Handler();
26        $this->P = new Parser($this->H);
27    }
28
29    /** @inheritdoc */
30    public function tearDown(): void
31    {
32        unset($this->P, $this->H);
33        parent::tearDown();
34    }
35
36    /**
37     * Assert that handler calls match the expected calls, ignoring byte index positions
38     *
39     * The byte index (element [2] in each call) is stripped before comparison because
40     * it depends on internal parser state and is not relevant for most tests.
41     *
42     * @param array $expected the expected call sequence
43     * @param array $actual the actual handler calls (typically $this->H->calls)
44     * @param string $message optional failure message
45     */
46    protected function assertCalls(array $expected, array $actual, string $message = ''): void
47    {
48        $this->assertEquals($expected, array_map($this->stripByteIndex(...), $actual), $message);
49    }
50
51    /**
52     * Remove the byte index from a single handler call
53     *
54     * Recursively processes nested calls (e.g. footnotes).
55     *
56     * @param array $call a single handler call [method, args, byteindex]
57     * @return array the call with the byte index removed
58     */
59    private function stripByteIndex(array $call): array
60    {
61        unset($call[2]);
62        if ($call[0] === 'nest') {
63            $call[1][0] = array_map($this->stripByteIndex(...), $call[1][0]);
64        }
65        return $call;
66    }
67}
68