BashGrammar.php

<?php

namespace Tlf\Lexer\Test;

class BashGrammar extends Tester {

    /**
     * Array of inputs to lex & test
     * @key name of test
     * @value array with keys 
     *
     * @param start the name of the directive to initialize the lexer with
     * @param input a string to parse (optionally can use input_file instead)
     * @param expect an array of what the output AST should be
     * @param input_file (optional) a file to load as input, relative to project root.
     */
    protected $thingies = [
        // whitespace, docblock, function, comment
        'ws_dblock_func_cmnt'=>[
            'start'=>'bash',
            'input_file'=>'test/input/bash/ws_dblock_func_cmnt.bash',
            'input'=>null,
            'expect'=>[
                'function'=>
                [
                    0=>[
                        'type' => 'function',
                        'name' => 'echo_path',
                        'docblock' => 
                        [
                            'type' => 'docblock',
                            'description' => "\n Description",
                            'attribute' => 
                            [
                                0 => 
                                [
                                    'type' => 'attribute',
                                    'name' => 'arg',
                                    'description' => '$1 a path',
                                ]

                            ]
                        ]
                    ],
                    1=>[
                        'type'=>'function',
                        'name'=>'echo_string',
                        'docblock'=>null
                    ]
                ],
                'comments'=>[
                    0=>[
                        'type'=>'comment',
                        'src'=> '# comment 1',
                        'description'=> ' comment 1',
                    ],
                    1=>[
                        'type'=>'comment',
                        'src'=> '# comment 2',
                        'description'=> ' comment 2',
                    ],
                    2=>[
                        'type'=>'comment',
                        'src'=> '# comment 3',
                        'description'=> ' comment 3',
                    ]
                ],
            ],
        ],
        'comments_functions'=>[
            'start'=>'bash',
            'input_file'=>'test/input/bash/comments_functions.bash',
            'input'=>null,
            'expect'=>[
                'comments'=>[
                    0=>[
                        'type'=>'comment',
                        'src'=>'#!/usr/bin/env bash',
                        'description'=>'!/usr/bin/env bash',
                    ],
                    1=>[
                        'type'=>'comment',
                        'src'=>'# comment one',
                        'description'=> ' comment one',
                    ]
                ],
                'function'=>[
                    0=>[ 'type'=>'function',
                        'name'=>'pre_comment',
                        'docblock'=>null
                    ],
                    1=>[ 'type'=>'function',
                        'name'=>'post_comment',
                        'docblock'=>null
                    ],
                ],
            ],
        ],
        'whitespace_docblock_function'=>[
            'start'=>'bash',
            'input_file'=>'test/input/bash/whitespace_docblock_function.bash',
            'input'=>null,
            'expect'=>[
                'function'=>
                [
                    0=>[
                        'type' => 'function',
                        'name' => 'echo_path',
                        'docblock' => 
                        [
                            'type' => 'docblock',
                            'description' => "\n Description",
                            'attribute' => 
                            [
                                0 => 
                                [
                                    'type' => 'attribute',
                                    'name' => 'arg',
                                    'description' => '$1 a path',
                                ]

                            ]

                        ]
                    ]
                ]
            ],
        ],
        'Docblock_Function'=>[
            'start'=>'bash',
            'input'=>"##\n# Commit all files & push to origin host\n#\n# @tip Save your project\n# @shorthand s, commit\n#"
                    ."\nfunction core_save(){\nmsg \"Pretend save function\"\n}",
            'expect'=>[
                'function'=>[
                    0=>[
                        'type'=>'function',
                        'name'=>'core_save',
                        'docblock'=>[
                            'type'=>'docblock',
                            'description'=> "\n Commit all files & push to origin host\n",
                            "attribute"=>[
                                0=>[
                                    'type'=>'attribute',
                                    'name'=>'tip',
                                    'description'=>'Save your project'
                                ],
                                1=>[
                                    'type'=>'attribute',
                                    'name'=>'shorthand',
                                    'description'=>"s, commit\n",
                                ]
                            ],
                        ]
                    ],
                ]
            ],
        ],
        'Comments'=>[
            'start'=>'comment',
            'input'=>"var=\"abc\"\n#I am a comment\nvarb=\"def\"",
            'expect'=>[
                "comments"=>[
                    0=>[
                        'type'=>'comment',
                        'src'=>'#I am a comment',
                        'description'=> "I am a comment",
                    ]
                ],
            ],
        ],
    ];

    public function testBashStuff(){
        $this->disable();
        foreach ($this->thingies as $description=>$test){
            $startingDirective=$test['start'];
            $inputString=$test['input']??file_get_contents($test['file']);
            $expect=$test['expect'];
            $this->test($description);
            if (!isset($this->options['run'])||$this->options['run']==$description){
                $output = $this->parse($inputString, $startingDirective);
                $this->compare($expect, $output);
            } else {
                echo "\n  '-run' specified for a different test";
            }
        }
    }

    public function testBashComment(){
        $this->disable();
        $description="I am a comment";
        $src = "#$description";
        $input = "var=\"abc\"\n$src\nvarb=\"def\"";
        $expect = [
            "comments"=>[
                0=>$description,
            ],
        ];

        $this->compare(
            $expect,
            $this->parse($input, "comment"),
        );
    }

    /**
     * Parse & test all tests listed in `$this->thingies[]`
     */
    public function testBashDirectives(){

        foreach ($this->thingies as $test_name=>$test_settings){
            if (isset($test_settings['input_file']))$this->thingies[$test_name]['input'] = file_get_contents($this->file($this->thingies[$test_name]['input_file']));
        }
        $bashGram = new \Tlf\Lexer\BashGrammar();
        $grammars = [
            $bashGram,
        ];
        // $docGram->buildDirectives();

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

    // protected function parse($stringInput, $startingDirective){
    //     $lexer = new \Tlf\Lexer();
    //     $lexer->debug = true;
    //     $bashGrammar=new \Tlf\Lexer\BashGrammar();
    //     $lexer->addGrammar($bashGrammar);
    //
    //     // print_r($bashGrammar->getDirectives(':comment')['comment']);
    //     // exit;
    //     //
    //     $startingDirectives = $bashGrammar->getDirectives(':comment');
    //     foreach ($startingDirectives as $se){
    //         $lexer->addDirective($se);
    //     }
    //
    //     $ast = $lexer->lexStr($stringInput);
    //
    //     $tree = $ast->getTree();
    //     unset($tree['type'], $tree['src']);
    //
    //     return $tree;
    // }
}