1<?php declare(strict_types=1);
2
3namespace PhpParser\Node\Scalar;
4
5use PhpParser\Node\Stmt\Echo_;
6use PhpParser\ParserFactory;
7
8class StringTest extends \PHPUnit\Framework\TestCase {
9    public function testRawValue(): void {
10        $parser = (new ParserFactory())->createForNewestSupportedVersion();
11        $nodes = $parser->parse('<?php echo "sequence \x41";');
12
13        $echo = $nodes[0];
14        $this->assertInstanceOf(Echo_::class, $echo);
15
16        /** @var Echo_ $echo */
17        $string = $echo->exprs[0];
18        $this->assertInstanceOf(String_::class, $string);
19
20        /** @var String_ $string */
21        $this->assertSame('sequence A', $string->value);
22        $this->assertSame('"sequence \\x41"', $string->getAttribute('rawValue'));
23    }
24
25    /**
26     * @dataProvider provideTestParseEscapeSequences
27     */
28    public function testParseEscapeSequences($expected, $string, $quote): void {
29        $this->assertSame(
30            $expected,
31            String_::parseEscapeSequences($string, $quote)
32        );
33    }
34
35    /**
36     * @dataProvider provideTestParse
37     */
38    public function testCreate($expected, $string): void {
39        $this->assertSame(
40            $expected,
41            String_::parse($string)
42        );
43    }
44
45    public static function provideTestParseEscapeSequences() {
46        return [
47            ['"',              '\\"',              '"'],
48            ['\\"',            '\\"',              '`'],
49            ['\\"\\`',         '\\"\\`',           null],
50            ["\\\$\n\r\t\f\v", '\\\\\$\n\r\t\f\v', null],
51            ["\x1B",           '\e',               null],
52            [chr(255),         '\xFF',             null],
53            [chr(255),         '\377',             null],
54            [chr(0),           '\400',             null],
55            ["\0",             '\0',               null],
56            ['\xFF',           '\\\\xFF',          null],
57        ];
58    }
59
60    public static function provideTestParse() {
61        $tests = [
62            ['A', '\'A\''],
63            ['A', 'b\'A\''],
64            ['A', '"A"'],
65            ['A', 'b"A"'],
66            ['\\', '\'\\\\\''],
67            ['\'', '\'\\\'\''],
68        ];
69
70        foreach (self::provideTestParseEscapeSequences() as $i => $test) {
71            // skip second and third tests, they aren't for double quotes
72            if ($i !== 1 && $i !== 2) {
73                $tests[] = [$test[0], '"' . $test[1] . '"'];
74            }
75        }
76
77        return $tests;
78    }
79}
80