DocblockGrammar.php

<?php

namespace Tlf\Lexer\Test;


class DocblockGrammar extends Tester {

    /**
     * @test bug where an attribute on a line with only whitespace after the attribute causes the program to stall
     */
    public function testBuildAstWithAttributesBug(){
        $lines = [
            '@one ',
            '@two okay',
        ];
        $db_grammar = new \Tlf\Lexer\DocblockGrammar();
        $ast = $db_grammar->buildAstWithAttributes($lines);
        $this->compare(
            array (
              'type' => 'docblock',
              'description' => '',
              'attribute' => 
              array (
                0 => 
                array (
                  'type' => 'attribute',
                  'name' => 'one',
                  'description' => '',
                ),
                1 => 
                array (
                  'type' => 'attribute',
                  'name' => 'two',
                  'description' => 'okay',
                ),
              ),
            ),
            $ast->getTree()
        );
        
    }

    public function testBuildAstWithAttributes(){
        $lines = [
            '@one good',
            '@two okay',
        ];
        $db_grammar = new \Tlf\Lexer\DocblockGrammar();
        $ast = $db_grammar->buildAstWithAttributes($lines);
        $this->compare(
            array (
              'type' => 'docblock',
              'description' => '',
              'attribute' => 
              array (
                0 => 
                array (
                  'type' => 'attribute',
                  'name' => 'one',
                  'description' => 'good',
                ),
                1 => 
                array (
                  'type' => 'attribute',
                  'name' => 'two',
                  'description' => 'okay',
                ),
              ),
            ),
            $ast->getTree()
        );
        
    }

    /**
     * Directives to test.
     *
     * See Tester clsas for details on how these are structured.
     */
    protected $thingies = [

        'Docblock.AttributeStalls'=>[
            'is_bad_test'=>'Good test: tests when a docblock contains an @attribute followed by whitespace on one line, then an @attribute on the next line, causing the program to stall & output nothing', 
            // 'ast.type'=>'class_body',
            'start'=>['/*'],
            'input'=>
                "/**\n* @one \n* @two okay \n*/",
            'expect.previous'=>[
                "docblock"=> [
                    'type'=>'docblock',
                    'description'=>"",
                    'attribute'=>[
                        0=>[
                            'type'=>'attribute',
                            'name'=>'one',
                            'description'=>'',
                        ],
                        1=>[
                            'type'=>'attribute',
                            'name'=>'two',
                            'description'=>'okay',
                        ],
                    ],
                ],
            ]

        ],
        'Docblock.Empty'=>[
            'start'=>['/*'],
            'input'=>"/**\n     *\n     */",
            'expect.previous'=>[
                "docblock"=>[
                    'type'=>'docblock',
                    'description'=>'',
                ]
            ]
        ],

        'Docblock.MultilineWithGaps'=>[
            'start'=>['/*'],
            'input'=>"/**\n *\n * first \n * \n * \n * second \n * \n * \n */",
            'expect.previous'=>[
                "docblock"=> [
                    'type'=>'docblock',
                    'description'=>"first \n\n\nsecond ",
                ],
            ],
        ],


        'Docblock.SameNameAttributes'=>[
            'start'=>['/*'],
            'input'=>"  /*\n* abc \n* @cat attr-describe\n  still describing def"
                    ."\n * \n*\n @cat (did) a thing\n*/",
            'expect.previous'=>[
                "docblock"=> [
                    'type'=>'docblock',
                    'description'=>" abc ",
                    'attribute'=>[
                        0=>[
                            'type'=>'attribute',
                            'name'=>'cat',
                            'description'=>"attr-describe\n still describing def",
                        ],
                        1=>[
                            'type'=>'attribute',
                            'name'=>'cat',
                            'description'=>"(did) a thing",
                        ],
                    ],
                ],
            ],
        ],

        'Docblock.TwoAttributes'=>[
            'start'=>['/*'],
            'input'=>"  /*\n* abc \n* @def attr-describe\n  still describing def"
                    ."\n * \n*\n @cat (did) a thing\n*/",
            'expect.previous'=>[
                "docblock"=> [
                    'type'=>'docblock',
                    'description'=>" abc ",
                    'attribute'=>[
                        0=>[
                            'type'=>'attribute',
                            'name'=>'def',
                            'description'=>"attr-describe\n still describing def",
                        ],
                        1=>[
                            'type'=>'attribute',
                            'name'=>'cat',
                            'description'=>"(did) a thing",
                        ],
                    ],
                ],
            ],
        ],

        'Docblock.WithAttribute'=>[
            'start'=>['/*'],
            'input'=>"  /*\n* abc \n* @def attr-describe\n  still describing def*/",
            'expect.previous'=>[
                "docblock"=> [
                    'type'=>'docblock',
                    'description'=>"abc ",
                    'attribute'=>[
                        0=>[
                            'type'=>'attribute',
                            'name'=>'def',
                            'description'=>"attr-describe\nstill describing def",
                        ],
                    ],
                ],
            ],
        ],
        'Docblock.VariedIndents'=>[
            'start'=>['/*'],
            'input'=>"  /*01\n  * abc \n    * def \n ghi*/",
            'expect.previous'=>[
                "docblock"=> [
                    'type'=>'docblock',
                    'description'=>"01\n   abc \n     def \nghi",
                ],
            ],
        ],

        'Docblock.IndentedLines'=>[
            'start'=>['/*'],
            'input'=>"  /* abc \n    * def \n*/",
            'expect.previous'=>[
                "docblock"=> [
                    'type'=>'docblock',
                    'description'=>"abc\ndef ",
                ],
            ],
        ],
        'Docblock.MultiLine2'=>[
            'start'=>['/*'],
            'input'=>"/*\n*\n*\n* abc \n* def \n*/",
            'expect.previous'=>[
                "docblock"=> [
                    'type'=>'docblock',
                    'description'=>"abc \ndef ",
                ],
            ],
        ],
        'Docblock.MultiLine'=>[
            'start'=>['/*'],
            'input'=>"/** abc \n* def */",
            'expect.previous'=>[
                "docblock"=> [
                    'type'=>'docblock',
                    'description'=>"abc\ndef ",
                ],
            ],
        ],
        'Docblock./**OneLine'=>[
            'start'=>['/*'],
            'input'=>"/** abc */",
            'expect.previous'=>[
                "docblock"=> [
                    'type'=>'docblock',
                    'description'=>'abc',
                ],
            ],
        ],
        'Docblock.OneLine'=>[
            'start'=>['/*'],
            'input'=>"/* abc */",
            'expect.previous'=>[
                "docblock"=> [
                    'type'=>'docblock',
                    'description'=>'abc',
                ],
            ],
        ],
    ];

    /**
     * Test a bunch of directives
     */ 
    public function testDocblockDirectives(){
        $docGram = new \Tlf\Lexer\DocblockGrammar();
        $grammars = [
            $docGram,
        ];
        // $docGram->buildDirectives();

        $this->runDirectiveTests($grammars, $this->thingies);
    }

}