* @copyright 2011-2026 Nicola Asuni - Tecnick.com LTD * @license https://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE) * @link https://github.com/tecnickcom/tc-lib-unicode * * This file is part of tc-lib-unicode software library. */ namespace Test\Bidi; use Com\Tecnick\Unicode\Bidi\StepN; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; /** * Bidi Test * * @since 2011-05-23 * @category Library * @package Unicode * @author Nicola Asuni * @copyright 2011-2026 Nicola Asuni - Tecnick.com LTD * @license https://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE) * @link https://github.com/tecnickcom/tc-lib-unicode */ class StepNTest extends TestCase { /** * @param array{ * 'e': int, * 'edir': string, * 'end': int, * 'eos': string, * 'length': int, * 'maxlevel': int, * 'sos': string, * 'start': int, * 'item': array, * } $seq Isolated Sequence array */ #[DataProvider('stepN0DataProvider')] public function testStepN0(array $seq, mixed $expected): void { $stepn = new StepN($seq, false); $stepn->processStep('getBracketPairs'); $stepn->processStep('processN0'); $this->assertEquals($expected, $stepn->getSequence()); } /** * BD16 regression: a closing bracket pairs with the nearest matching opening bracket. * For nested same-type brackets "(())" the pairs must be (1,2) and (0,3); the previous * implementation produced a spurious (0,2) pair and dropped the outer (0,3) pair. * * @throws \ReflectionException */ public function testBracketPairsNestedSameType(): void { $items = []; foreach ([0x28, 0x28, 0x29, 0x29] as $pos => $char) { $items[] = [ 'x' => 0, 'pos' => $pos, 'char' => $char, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'ON', 'otype' => 'ON', ]; } $stepn = new StepN([ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 3, 'length' => 4, 'maxlevel' => 0, 'sos' => 'L', 'eos' => 'L', 'item' => $items, ], false); $stepn->processStep('getBracketPairs'); $property = new \ReflectionProperty(StepN::class, 'brackets'); $this->assertEquals([1 => 2, 0 => 3], $property->getValue($stepn)); } /** * @return array, * }>> */ public static function stepN0DataProvider(): array { return [ [ [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 4, 'length' => 5, 'maxlevel' => 0, 'sos' => 'L', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 8207, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], [ 'x' => 0, 'pos' => 1, 'char' => 0x3008, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'ON', 'otype' => 'ON', ], [ 'x' => 0, 'pos' => 2, 'char' => 65, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], [ 'x' => 0, 'pos' => 3, 'char' => 0x3009, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'ON', 'otype' => 'ON', ], [ 'x' => 0, 'pos' => 4, 'char' => 8207, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], ], ], [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 4, 'length' => 5, 'maxlevel' => 0, 'sos' => 'L', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 8207, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], [ 'x' => 0, 'pos' => 1, 'char' => 0x3008, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'ON', ], [ 'x' => 0, 'pos' => 2, 'char' => 65, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], [ 'x' => 0, 'pos' => 3, 'char' => 0x3009, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'ON', ], [ 'x' => 0, 'pos' => 4, 'char' => 8207, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], ], ], ], [ [ 'e' => 1, 'edir' => 'R', 'start' => 0, 'end' => 4, 'length' => 5, 'maxlevel' => 0, 'sos' => 'R', 'eos' => 'R', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 65, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], [ 'x' => 0, 'pos' => 1, 'char' => 91, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'ON', 'otype' => 'ON', ], // [ [ 'x' => 0, 'pos' => 2, 'char' => 65, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], [ 'x' => 0, 'pos' => 3, 'char' => 8207, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], [ 'x' => 0, 'pos' => 4, 'char' => 93, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'ON', 'otype' => 'ON', ], ], ], [ 'e' => 1, 'edir' => 'R', 'start' => 0, 'end' => 4, 'length' => 5, 'maxlevel' => 0, 'sos' => 'R', 'eos' => 'R', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 65, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], [ 'x' => 0, 'pos' => 1, 'char' => 91, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'ON', ], [ 'x' => 0, 'pos' => 2, 'char' => 65, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], [ 'x' => 0, 'pos' => 3, 'char' => 8207, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], [ 'x' => 0, 'pos' => 4, 'char' => 93, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'ON', ], ], ], ], [ [ 'e' => 1, 'edir' => 'R', 'start' => 0, 'end' => 4, 'length' => 5, 'maxlevel' => 0, 'sos' => 'R', 'eos' => 'R', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 65, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], [ 'x' => 0, 'pos' => 1, 'char' => 91, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'ON', 'otype' => 'ON', ], // [ [ 'x' => 0, 'pos' => 2, 'char' => 5760, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'NI', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 3, 'char' => 8207, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], [ 'x' => 0, 'pos' => 4, 'char' => 93, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'ON', 'otype' => 'ON', ], ], ], [ 'e' => 1, 'edir' => 'R', 'start' => 0, 'end' => 4, 'length' => 5, 'maxlevel' => 0, 'sos' => 'R', 'eos' => 'R', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 65, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], [ 'x' => 0, 'pos' => 1, 'char' => 91, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'ON', ], [ 'x' => 0, 'pos' => 2, 'char' => 5760, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'NI', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 3, 'char' => 8207, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], [ 'x' => 0, 'pos' => 4, 'char' => 93, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'ON', ], ], ], ], [ [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 4, 'length' => 5, 'maxlevel' => 0, 'sos' => 'L', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 8207, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], [ 'x' => 0, 'pos' => 1, 'char' => 91, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'ON', 'otype' => 'ON', ], // [ [ 'x' => 0, 'pos' => 2, 'char' => 8207, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], [ 'x' => 0, 'pos' => 3, 'char' => 93, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'ON', 'otype' => 'ON', ], // ] [ 'x' => 0, 'pos' => 4, 'char' => 65, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], ], ], [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 4, 'length' => 5, 'maxlevel' => 0, 'sos' => 'L', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 8207, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], [ 'x' => 0, 'pos' => 1, 'char' => 91, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'ON', ], [ 'x' => 0, 'pos' => 2, 'char' => 8207, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], [ 'x' => 0, 'pos' => 3, 'char' => 93, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'ON', ], [ 'x' => 0, 'pos' => 4, 'char' => 65, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], ], ], ], [ [ 'e' => 1, 'edir' => 'R', 'start' => 0, 'end' => 5, 'length' => 6, 'maxlevel' => 0, 'sos' => 'R', 'eos' => 'R', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 65, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], [ 'x' => 0, 'pos' => 1, 'char' => 91, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'ON', 'otype' => 'ON', ], // [ [ 'x' => 0, 'pos' => 2, 'char' => 65, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], [ 'x' => 0, 'pos' => 3, 'char' => 5760, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'NI', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 4, 'char' => 93, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'ON', 'otype' => 'ON', ], // ] [ 'x' => 0, 'pos' => 5, 'char' => 65, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], ], ], [ 'e' => 1, 'edir' => 'R', 'start' => 0, 'end' => 5, 'length' => 6, 'maxlevel' => 0, 'sos' => 'R', 'eos' => 'R', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 65, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], [ 'x' => 0, 'pos' => 1, 'char' => 91, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'ON', ], [ 'x' => 0, 'pos' => 2, 'char' => 65, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], [ 'x' => 0, 'pos' => 3, 'char' => 5760, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'NI', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 4, 'char' => 93, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'ON', ], [ 'x' => 0, 'pos' => 5, 'char' => 65, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], ], ], ], [ [ 'e' => 1, 'edir' => 'R', 'start' => 0, 'end' => 4, 'length' => 5, 'maxlevel' => 0, 'sos' => 'R', 'eos' => 'R', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 8207, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], [ 'x' => 0, 'pos' => 1, 'char' => 91, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'ON', 'otype' => 'ON', ], // [ [ 'x' => 0, 'pos' => 2, 'char' => 65, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], [ 'x' => 0, 'pos' => 3, 'char' => 93, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'ON', 'otype' => 'ON', ], // ] [ 'x' => 0, 'pos' => 4, 'char' => 65, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], ], ], [ 'e' => 1, 'edir' => 'R', 'start' => 0, 'end' => 4, 'length' => 5, 'maxlevel' => 0, 'sos' => 'R', 'eos' => 'R', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 8207, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], [ 'x' => 0, 'pos' => 1, 'char' => 91, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'ON', ], [ 'x' => 0, 'pos' => 2, 'char' => 65, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], [ 'x' => 0, 'pos' => 3, 'char' => 93, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'ON', ], [ 'x' => 0, 'pos' => 4, 'char' => 65, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], ], ], ], [ [ 'e' => 1, 'edir' => 'R', 'start' => 0, 'end' => 4, 'length' => 5, 'maxlevel' => 0, 'sos' => 'R', 'eos' => 'R', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 8207, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], [ 'x' => 0, 'pos' => 1, 'char' => 91, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'ON', 'otype' => 'ON', ], // [ [ 'x' => 0, 'pos' => 2, 'char' => 65, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], [ 'x' => 0, 'pos' => 3, 'char' => 93, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'ON', 'otype' => 'ON', ], // ] [ 'x' => 0, 'pos' => 4, 'char' => 8207, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], ], ], [ 'e' => 1, 'edir' => 'R', 'start' => 0, 'end' => 4, 'length' => 5, 'maxlevel' => 0, 'sos' => 'R', 'eos' => 'R', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 8207, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], [ 'x' => 0, 'pos' => 1, 'char' => 91, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'ON', ], [ 'x' => 0, 'pos' => 2, 'char' => 65, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], [ 'x' => 0, 'pos' => 3, 'char' => 93, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'ON', ], [ 'x' => 0, 'pos' => 4, 'char' => 8207, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], ], ], ], [ [ 'e' => 1, 'edir' => 'R', 'start' => 0, 'end' => 4, 'length' => 5, 'maxlevel' => 0, 'sos' => 'R', 'eos' => 'R', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 8207, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], [ 'x' => 0, 'pos' => 1, 'char' => 91, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'ON', 'otype' => 'ON', ], // [ [ 'x' => 0, 'pos' => 2, 'char' => 5760, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'NI', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 3, 'char' => 93, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'ON', 'otype' => 'ON', ], // ] [ 'x' => 0, 'pos' => 4, 'char' => 65, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], ], ], [ 'e' => 1, 'edir' => 'R', 'start' => 0, 'end' => 4, 'length' => 5, 'maxlevel' => 0, 'sos' => 'R', 'eos' => 'R', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 8207, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], [ 'x' => 0, 'pos' => 1, 'char' => 91, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'ON', 'otype' => 'ON', ], [ 'x' => 0, 'pos' => 2, 'char' => 5760, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'NI', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 3, 'char' => 93, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'ON', 'otype' => 'ON', ], [ 'x' => 0, 'pos' => 4, 'char' => 65, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], ], ], ], [ [ 'e' => 1, 'edir' => 'R', 'start' => 0, 'end' => 4, 'length' => 5, 'maxlevel' => 0, 'sos' => 'R', 'eos' => 'R', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 8207, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], [ 'x' => 0, 'pos' => 1, 'char' => 5760, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'NI', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 2, 'char' => 91, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'ON', 'otype' => 'ON', ], // [ [ 'x' => 0, 'pos' => 3, 'char' => 65, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], [ 'x' => 0, 'pos' => 4, 'char' => 93, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'ON', 'otype' => 'ON', ], ], ], [ 'e' => 1, 'edir' => 'R', 'start' => 0, 'end' => 4, 'length' => 5, 'maxlevel' => 0, 'sos' => 'R', 'eos' => 'R', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 8207, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], [ 'x' => 0, 'pos' => 1, 'char' => 5760, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'NI', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 2, 'char' => 91, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'ON', ], [ 'x' => 0, 'pos' => 3, 'char' => 65, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], [ 'x' => 0, 'pos' => 4, 'char' => 93, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'ON', ], ], ], ], [ [ 'e' => 1, 'edir' => 'R', 'start' => 0, 'end' => 4, 'length' => 5, 'maxlevel' => 0, 'sos' => 'R', 'eos' => 'R', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 5760, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'NI', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 1, 'char' => 5760, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'NI', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 2, 'char' => 91, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'ON', 'otype' => 'ON', ], // [ [ 'x' => 0, 'pos' => 3, 'char' => 65, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], [ 'x' => 0, 'pos' => 4, 'char' => 93, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'ON', 'otype' => 'ON', ], ], ], [ 'e' => 1, 'edir' => 'R', 'start' => 0, 'end' => 4, 'length' => 5, 'maxlevel' => 0, 'sos' => 'R', 'eos' => 'R', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 5760, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'NI', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 1, 'char' => 5760, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'NI', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 2, 'char' => 91, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'ON', ], [ 'x' => 0, 'pos' => 3, 'char' => 65, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], [ 'x' => 0, 'pos' => 4, 'char' => 93, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'ON', ], ], ], ], [ [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 5, 'length' => 6, 'maxlevel' => 0, 'sos' => 'L', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 8207, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], [ 'x' => 0, 'pos' => 1, 'char' => 0x3008, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'ON', 'otype' => 'ON', ], [ 'x' => 0, 'pos' => 2, 'char' => 65, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], [ 'x' => 0, 'pos' => 3, 'char' => 0x3009, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'ON', 'otype' => 'ON', ], [ 'x' => 0, 'pos' => 4, 'char' => 1809, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'NSM', 'otype' => 'NSM', ], [ 'x' => 0, 'pos' => 5, 'char' => 1809, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'NSM', 'otype' => 'NSM', ], ], ], [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 5, 'length' => 6, 'maxlevel' => 0, 'sos' => 'L', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 8207, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], [ 'x' => 0, 'pos' => 1, 'char' => 0x3008, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'ON', ], [ 'x' => 0, 'pos' => 2, 'char' => 65, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], [ 'x' => 0, 'pos' => 3, 'char' => 0x3009, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'ON', ], [ 'x' => 0, 'pos' => 4, 'char' => 1809, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'NSM', ], [ 'x' => 0, 'pos' => 5, 'char' => 1809, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'NSM', ], ], ], ], ]; } /** * @param array{ * 'e': int, * 'edir': string, * 'end': int, * 'eos': string, * 'length': int, * 'maxlevel': int, * 'sos': string, * 'start': int, * 'item': array, * } $seq Isolated Sequence array */ #[DataProvider('stepN1DataProvider')] public function testStepN1(array $seq, mixed $expected): void { $stepn = new \Com\Tecnick\Unicode\Bidi\StepN($seq, false); $stepn->processStep('processN1'); $this->assertEquals($expected, $stepn->getSequence()); } /** * @return array, * }>> */ public static function stepN1DataProvider(): array { return [ [ [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 2, 'length' => 3, 'maxlevel' => 0, 'sos' => 'L', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 65, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], [ 'x' => 0, 'pos' => 1, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'NI', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 2, 'char' => 65, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], ], ], [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 2, 'length' => 3, 'maxlevel' => 0, 'sos' => 'L', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 65, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], [ 'x' => 0, 'pos' => 1, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 2, 'char' => 65, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], ], ], ], [ [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 2, 'length' => 3, 'maxlevel' => 0, 'sos' => 'L', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 8207, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], [ 'x' => 0, 'pos' => 1, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'NI', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 2, 'char' => 8207, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], ], ], [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 2, 'length' => 3, 'maxlevel' => 0, 'sos' => 'L', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 8207, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], [ 'x' => 0, 'pos' => 1, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 2, 'char' => 8207, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], ], ], ], [ [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 2, 'length' => 3, 'maxlevel' => 0, 'sos' => 'L', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 8207, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], [ 'x' => 0, 'pos' => 1, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'NI', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 2, 'char' => 1632, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'AN', 'otype' => 'AN', ], ], ], [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 2, 'length' => 3, 'maxlevel' => 0, 'sos' => 'L', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 8207, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], [ 'x' => 0, 'pos' => 1, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 2, 'char' => 1632, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'AN', 'otype' => 'AN', ], ], ], ], [ [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 2, 'length' => 3, 'maxlevel' => 0, 'sos' => 'L', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 8207, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], [ 'x' => 0, 'pos' => 1, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'NI', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 2, 'char' => 1776, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'EN', 'otype' => 'EN', ], ], ], [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 2, 'length' => 3, 'maxlevel' => 0, 'sos' => 'L', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 8207, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], [ 'x' => 0, 'pos' => 1, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 2, 'char' => 1776, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'EN', 'otype' => 'EN', ], ], ], ], [ [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 2, 'length' => 3, 'maxlevel' => 0, 'sos' => 'L', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 1632, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'AN', 'otype' => 'AN', ], [ 'x' => 0, 'pos' => 1, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'NI', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 2, 'char' => 8207, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], ], ], [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 2, 'length' => 3, 'maxlevel' => 0, 'sos' => 'L', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 1632, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'AN', 'otype' => 'AN', ], [ 'x' => 0, 'pos' => 1, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 2, 'char' => 8207, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], ], ], ], [ [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 2, 'length' => 3, 'maxlevel' => 0, 'sos' => 'L', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 1632, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'AN', 'otype' => 'AN', ], [ 'x' => 0, 'pos' => 1, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'NI', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 2, 'char' => 1632, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'AN', 'otype' => 'AN', ], ], ], [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 2, 'length' => 3, 'maxlevel' => 0, 'sos' => 'L', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 1632, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'AN', 'otype' => 'AN', ], [ 'x' => 0, 'pos' => 1, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 2, 'char' => 1632, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'AN', 'otype' => 'AN', ], ], ], ], [ [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 2, 'length' => 3, 'maxlevel' => 0, 'sos' => 'L', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 1632, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'AN', 'otype' => 'AN', ], [ 'x' => 0, 'pos' => 1, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'NI', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 2, 'char' => 1776, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'EN', 'otype' => 'EN', ], ], ], [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 2, 'length' => 3, 'maxlevel' => 0, 'sos' => 'L', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 1632, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'AN', 'otype' => 'AN', ], [ 'x' => 0, 'pos' => 1, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 2, 'char' => 1776, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'EN', 'otype' => 'EN', ], ], ], ], [ [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 2, 'length' => 3, 'maxlevel' => 0, 'sos' => 'L', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 1776, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'EN', 'otype' => 'EN', ], [ 'x' => 0, 'pos' => 1, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'NI', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 2, 'char' => 8207, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], ], ], [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 2, 'length' => 3, 'maxlevel' => 0, 'sos' => 'L', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 1776, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'EN', 'otype' => 'EN', ], [ 'x' => 0, 'pos' => 1, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 2, 'char' => 8207, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], ], ], ], [ [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 2, 'length' => 3, 'maxlevel' => 0, 'sos' => 'L', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 1776, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'EN', 'otype' => 'EN', ], [ 'x' => 0, 'pos' => 1, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'NI', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 2, 'char' => 1632, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'AN', 'otype' => 'AN', ], ], ], [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 2, 'length' => 3, 'maxlevel' => 0, 'sos' => 'L', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 1776, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'EN', 'otype' => 'EN', ], [ 'x' => 0, 'pos' => 1, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 2, 'char' => 1632, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'AN', 'otype' => 'AN', ], ], ], ], [ [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 2, 'length' => 3, 'maxlevel' => 0, 'sos' => 'L', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 1776, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'EN', 'otype' => 'EN', ], [ 'x' => 0, 'pos' => 1, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'NI', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 2, 'char' => 1776, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'EN', 'otype' => 'EN', ], ], ], [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 2, 'length' => 3, 'maxlevel' => 0, 'sos' => 'L', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 1776, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'EN', 'otype' => 'EN', ], [ 'x' => 0, 'pos' => 1, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 2, 'char' => 1776, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'EN', 'otype' => 'EN', ], ], ], ], [ [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 3, 'length' => 4, 'maxlevel' => 0, 'sos' => 'L', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 65, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], [ 'x' => 0, 'pos' => 1, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'NI', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 2, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'NI', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 3, 'char' => 65, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], ], ], [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 3, 'length' => 4, 'maxlevel' => 0, 'sos' => 'L', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 65, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], [ 'x' => 0, 'pos' => 1, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 2, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 3, 'char' => 65, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], ], ], ], [ // Realistic pipeline types: ordinary neutrals (WS, ON) between two strong R // characters must take the R direction (issue #13: the N rules used to match // only the literal 'NI' type, which real neutrals never carry). [ 'e' => 1, 'edir' => 'R', 'start' => 0, 'end' => 3, 'length' => 4, 'maxlevel' => 0, 'sos' => 'R', 'eos' => 'R', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 1514, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], [ 'x' => 0, 'pos' => 1, 'char' => 32, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'WS', 'otype' => 'WS', ], [ 'x' => 0, 'pos' => 2, 'char' => 38, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'ON', 'otype' => 'ON', ], [ 'x' => 0, 'pos' => 3, 'char' => 1514, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], ], ], [ 'e' => 1, 'edir' => 'R', 'start' => 0, 'end' => 3, 'length' => 4, 'maxlevel' => 0, 'sos' => 'R', 'eos' => 'R', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 1514, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], [ 'x' => 0, 'pos' => 1, 'char' => 32, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'WS', ], [ 'x' => 0, 'pos' => 2, 'char' => 38, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'ON', ], [ 'x' => 0, 'pos' => 3, 'char' => 1514, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], ], ], ], ]; } /** * @param array{ * 'e': int, * 'edir': string, * 'end': int, * 'eos': string, * 'length': int, * 'maxlevel': int, * 'sos': string, * 'start': int, * 'item': array, * } $seq Isolated Sequence array */ #[DataProvider('stepN2DataProvider')] public function testStepN2(array $seq, mixed $expected): void { $stepn = new \Com\Tecnick\Unicode\Bidi\StepN($seq, false); $stepn->processStep('processN2'); $this->assertEquals($expected, $stepn->getSequence()); } /** * @return array, * }>> */ public static function stepN2DataProvider(): array { return [ [ [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 1, 'length' => 1, 'maxlevel' => 0, 'sos' => 'L', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'NI', 'otype' => 'NI', ], ], ], [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 1, 'length' => 1, 'maxlevel' => 0, 'sos' => 'L', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'NI', ], ], ], ], [ // Realistic pipeline type: an unresolved ON takes the embedding direction // (issue #13: N2 used to match only the literal 'NI' type). [ 'e' => 1, 'edir' => 'R', 'start' => 0, 'end' => 0, 'length' => 1, 'maxlevel' => 0, 'sos' => 'L', 'eos' => 'R', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 38, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'ON', 'otype' => 'ON', ], ], ], [ 'e' => 1, 'edir' => 'R', 'start' => 0, 'end' => 0, 'length' => 1, 'maxlevel' => 0, 'sos' => 'L', 'eos' => 'R', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 38, 'i' => -1, 'level' => 1, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'ON', ], ], ], ], ]; } /** * @param array{ * 'e': int, * 'edir': string, * 'end': int, * 'eos': string, * 'length': int, * 'maxlevel': int, * 'sos': string, * 'start': int, * 'item': array, * } $seq Isolated Sequence array */ #[DataProvider('stepNDataProvider')] public function testStepN(array $seq, mixed $expected): void { $stepn = new \Com\Tecnick\Unicode\Bidi\StepN($seq); $this->assertEquals($expected, $stepn->getSequence()); } /** * @return array, * }>> */ public static function stepNDataProvider(): array { return [ [ [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 2, 'length' => 3, 'maxlevel' => 0, 'sos' => 'R', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 65, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], [ 'x' => 0, 'pos' => 1, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'NI', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 2, 'char' => 65, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], ], ], [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 2, 'length' => 3, 'maxlevel' => 0, 'sos' => 'R', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 65, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], [ 'x' => 0, 'pos' => 1, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 2, 'char' => 65, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], ], ], ], [ [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 2, 'length' => 3, 'maxlevel' => 0, 'sos' => 'R', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 8207, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], [ 'x' => 0, 'pos' => 1, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'NI', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 2, 'char' => 65, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], ], ], [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 2, 'length' => 3, 'maxlevel' => 0, 'sos' => 'R', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 8207, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], [ 'x' => 0, 'pos' => 1, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 2, 'char' => 65, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], ], ], ], [ [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 2, 'length' => 3, 'maxlevel' => 0, 'sos' => 'R', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 65, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], [ 'x' => 0, 'pos' => 1, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'NI', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 2, 'char' => 8207, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], ], ], [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 2, 'length' => 3, 'maxlevel' => 0, 'sos' => 'R', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 65, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'L', ], [ 'x' => 0, 'pos' => 1, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 2, 'char' => 8207, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], ], ], ], [ [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 2, 'length' => 3, 'maxlevel' => 0, 'sos' => 'R', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 8207, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], [ 'x' => 0, 'pos' => 1, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'NI', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 2, 'char' => 8207, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], ], ], [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 2, 'length' => 3, 'maxlevel' => 0, 'sos' => 'R', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 8207, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], [ 'x' => 0, 'pos' => 1, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 2, 'char' => 8207, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], ], ], ], [ [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 2, 'length' => 3, 'maxlevel' => 0, 'sos' => 'R', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'NI', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 1, 'char' => 91, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'ON', 'otype' => 'ON', ], [ 'x' => 0, 'pos' => 2, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'NI', 'otype' => 'NI', ], ], ], [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 2, 'length' => 3, 'maxlevel' => 0, 'sos' => 'R', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 1, 'char' => 91, 'i' => -1, 'level' => 0, 'pdimatch' => -1, // The ON is part of the NI run between sos (R) and eos (L): // the conflict means N1 skips it and N2 resolves it to edir. 'type' => 'L', 'otype' => 'ON', ], [ 'x' => 0, 'pos' => 2, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'NI', ], ], ], ], [ [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 2, 'length' => 3, 'maxlevel' => 0, 'sos' => 'R', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 8207, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], [ 'x' => 0, 'pos' => 1, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'NI', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 2, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'NI', 'otype' => 'NI', ], ], ], [ 'e' => 0, 'edir' => 'L', 'start' => 0, 'end' => 2, 'length' => 3, 'maxlevel' => 0, 'sos' => 'R', 'eos' => 'L', 'item' => [ [ 'x' => 0, 'pos' => 0, 'char' => 8207, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'R', 'otype' => 'R', ], [ 'x' => 0, 'pos' => 1, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'NI', ], [ 'x' => 0, 'pos' => 2, 'char' => 5760, 'i' => -1, 'level' => 0, 'pdimatch' => -1, 'type' => 'L', 'otype' => 'NI', ], ], ], ], ]; } }