github.com/NeowayLabs/nash@v0.2.2-0.20200127205349-a227041ffd50/parser/parse_regression_test.go (about)

     1  package parser
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/madlambda/nash/ast"
     7  	"github.com/madlambda/nash/token"
     8  )
     9  
    10  func init() {
    11  	ast.DebugCmp = true
    12  }
    13  
    14  func TestParseIssue22(t *testing.T) {
    15  	expected := ast.NewTree("issue 22")
    16  	ln := ast.NewBlockNode(token.NewFileInfo(1, 0))
    17  
    18  	fn := ast.NewFnDeclNode(token.NewFileInfo(1, 3), "gocd")
    19  	fn.AddArg(ast.NewFnArgNode(token.NewFileInfo(1, 8), "path", false))
    20  
    21  	fnTree := ast.NewTree("fn")
    22  	fnBlock := ast.NewBlockNode(token.NewFileInfo(1, 0))
    23  
    24  	ifDecl := ast.NewIfNode(token.NewFileInfo(2, 1))
    25  	ifDecl.SetLvalue(ast.NewVarExpr(token.NewFileInfo(2, 4), "$path"))
    26  	ifDecl.SetOp("==")
    27  
    28  	ifDecl.SetRvalue(ast.NewStringExpr(token.NewFileInfo(2, 13), "", true))
    29  
    30  	ifTree := ast.NewTree("if")
    31  	ifBlock := ast.NewBlockNode(token.NewFileInfo(2, 1))
    32  
    33  	cdNode := ast.NewCommandNode(token.NewFileInfo(3, 2), "cd", false)
    34  	arg := ast.NewVarExpr(token.NewFileInfo(3, 5), "$GOPATH")
    35  	cdNode.AddArg(arg)
    36  
    37  	ifBlock.Push(cdNode)
    38  	ifTree.Root = ifBlock
    39  	ifDecl.SetIfTree(ifTree)
    40  
    41  	elseTree := ast.NewTree("else")
    42  	elseBlock := ast.NewBlockNode(token.NewFileInfo(4, 9))
    43  
    44  	args := make([]ast.Expr, 3)
    45  	args[0] = ast.NewVarExpr(token.NewFileInfo(5, 5), "$GOPATH")
    46  	args[1] = ast.NewStringExpr(token.NewFileInfo(5, 12), "/src/", true)
    47  	args[2] = ast.NewVarExpr(token.NewFileInfo(5, 20), "$path")
    48  
    49  	cdNodeElse := ast.NewCommandNode(token.NewFileInfo(5, 2), "cd", false)
    50  	carg := ast.NewConcatExpr(token.NewFileInfo(5, 5), args)
    51  	cdNodeElse.AddArg(carg)
    52  
    53  	elseBlock.Push(cdNodeElse)
    54  	elseTree.Root = elseBlock
    55  
    56  	ifDecl.SetElseTree(elseTree)
    57  
    58  	fnBlock.Push(ifDecl)
    59  	fnTree.Root = fnBlock
    60  	fn.SetTree(fnTree)
    61  
    62  	ln.Push(fn)
    63  	expected.Root = ln
    64  
    65  	parserTest("issue 22", `fn gocd(path) {
    66  	if $path == "" {
    67  		cd $GOPATH
    68  	} else {
    69  		cd $GOPATH+"/src/"+$path
    70  	}
    71  }`, expected, t, true)
    72  
    73  }
    74  
    75  func TestParseIssue38(t *testing.T) {
    76  	expected := ast.NewTree("parse issue38")
    77  	ln := ast.NewBlockNode(token.NewFileInfo(1, 0))
    78  	fnInv := ast.NewFnInvNode(token.NewFileInfo(1, 0), "cd")
    79  	args := make([]ast.Expr, 3)
    80  	args[0] = ast.NewVarExpr(token.NewFileInfo(1, 3), "$GOPATH")
    81  	args[1] = ast.NewStringExpr(token.NewFileInfo(1, 12), "/src/", true)
    82  	args[2] = ast.NewVarExpr(token.NewFileInfo(1, 19), "$path")
    83  
    84  	arg := ast.NewConcatExpr(token.NewFileInfo(1, 3), args)
    85  	fnInv.AddArg(arg)
    86  	ln.Push(fnInv)
    87  	expected.Root = ln
    88  
    89  	parserTest("parse issue38", `cd($GOPATH+"/src/"+$path)`, expected, t, true)
    90  }
    91  
    92  func TestParseIssue43(t *testing.T) {
    93  	content := `fn gpull() {
    94  	branch <= git rev-parse --abbrev-ref HEAD | xargs echo -n
    95  
    96  	git pull origin $branch
    97  
    98  	refreshPrompt()
    99  }`
   100  
   101  	expected := ast.NewTree("parse issue 41")
   102  	ln := ast.NewBlockNode(token.NewFileInfo(1, 0))
   103  
   104  	fnDecl := ast.NewFnDeclNode(token.NewFileInfo(1, 3), "gpull")
   105  	fnTree := ast.NewTree("fn")
   106  	fnBlock := ast.NewBlockNode(token.NewFileInfo(1, 0))
   107  
   108  	gitRevParse := ast.NewCommandNode(token.NewFileInfo(2, 11), "git", false)
   109  
   110  	gitRevParse.AddArg(ast.NewStringExpr(token.NewFileInfo(2, 15), "rev-parse", true))
   111  	gitRevParse.AddArg(ast.NewStringExpr(token.NewFileInfo(2, 25), "--abbrev-ref", false))
   112  	gitRevParse.AddArg(ast.NewStringExpr(token.NewFileInfo(2, 38), "HEAD", false))
   113  
   114  	branchAssign, err := ast.NewExecAssignNode(token.NewFileInfo(2, 1), []*ast.NameNode{
   115  		ast.NewNameNode(token.NewFileInfo(2, 1),
   116  			"branch",
   117  			nil,
   118  		)}, gitRevParse)
   119  
   120  	if err != nil {
   121  		t.Error(err)
   122  		return
   123  	}
   124  
   125  	xargs := ast.NewCommandNode(token.NewFileInfo(2, 45), "xargs", false)
   126  	xargs.AddArg(ast.NewStringExpr(token.NewFileInfo(2, 51), "echo", false))
   127  	xargs.AddArg(ast.NewStringExpr(token.NewFileInfo(2, 56), "-n", false))
   128  
   129  	pipe := ast.NewPipeNode(token.NewFileInfo(2, 43), false)
   130  	pipe.AddCmd(gitRevParse)
   131  	pipe.AddCmd(xargs)
   132  
   133  	branchAssign.SetCommand(pipe)
   134  
   135  	fnBlock.Push(branchAssign)
   136  
   137  	gitPull := ast.NewCommandNode(token.NewFileInfo(1, 0), "git", false)
   138  
   139  	gitPull.AddArg(ast.NewStringExpr(token.NewFileInfo(1, 0), "pull", false))
   140  	gitPull.AddArg(ast.NewStringExpr(token.NewFileInfo(1, 0), "origin", false))
   141  	gitPull.AddArg(ast.NewVarExpr(token.NewFileInfo(1, 0), "$branch"))
   142  
   143  	fnBlock.Push(gitPull)
   144  
   145  	fnInv := ast.NewFnInvNode(token.NewFileInfo(1, 0), "refreshPrompt")
   146  	fnBlock.Push(fnInv)
   147  	fnTree.Root = fnBlock
   148  
   149  	fnDecl.SetTree(fnTree)
   150  	ln.Push(fnDecl)
   151  
   152  	expected.Root = ln
   153  
   154  	parserTest("parse issue 41", content, expected, t, true)
   155  }
   156  
   157  func TestParseIssue68(t *testing.T) {
   158  	expected := ast.NewTree("parse issue #68")
   159  	ln := ast.NewBlockNode(token.NewFileInfo(1, 0))
   160  
   161  	catCmd := ast.NewCommandNode(token.NewFileInfo(1, 0), "cat", false)
   162  
   163  	catArg := ast.NewStringExpr(token.NewFileInfo(1, 4), "PKGBUILD", false)
   164  	catCmd.AddArg(catArg)
   165  
   166  	sedCmd := ast.NewCommandNode(token.NewFileInfo(1, 15), "sed", false)
   167  	sedArg := ast.NewStringExpr(token.NewFileInfo(1, 20), `s#\$pkgdir#/home/i4k/alt#g`, true)
   168  	sedCmd.AddArg(sedArg)
   169  
   170  	sedRedir := ast.NewRedirectNode(token.NewFileInfo(1, 49))
   171  	sedRedirArg := ast.NewStringExpr(token.NewFileInfo(1, 51), "PKGBUILD2", false)
   172  	sedRedir.SetLocation(sedRedirArg)
   173  	sedCmd.AddRedirect(sedRedir)
   174  
   175  	pipe := ast.NewPipeNode(token.NewFileInfo(1, 13), false)
   176  	pipe.AddCmd(catCmd)
   177  	pipe.AddCmd(sedCmd)
   178  
   179  	ln.Push(pipe)
   180  	expected.Root = ln
   181  
   182  	parserTest("parse issue #68", `cat PKGBUILD | sed "s#\\$pkgdir#/home/i4k/alt#g" > PKGBUILD2`, expected, t, false)
   183  }
   184  
   185  func TestParseIssue69(t *testing.T) {
   186  	expected := ast.NewTree("parse-issue-69")
   187  	ln := ast.NewBlockNode(token.NewFileInfo(1, 0))
   188  
   189  	parts := make([]ast.Expr, 2)
   190  
   191  	parts[0] = ast.NewVarExpr(token.NewFileInfo(1, 5), "$a")
   192  	parts[1] = ast.NewStringExpr(token.NewFileInfo(1, 9), "b", true)
   193  
   194  	concat := ast.NewConcatExpr(token.NewFileInfo(1, 5), parts)
   195  
   196  	listValues := make([]ast.Expr, 1)
   197  	listValues[0] = concat
   198  
   199  	list := ast.NewListExpr(token.NewFileInfo(1, 4), listValues)
   200  
   201  	assign := ast.NewSingleAssignNode(token.NewFileInfo(1, 0),
   202  		ast.NewNameNode(token.NewFileInfo(1, 0), "a", nil), list,
   203  	)
   204  
   205  	ln.Push(assign)
   206  	expected.Root = ln
   207  
   208  	parserTest("parse-issue-69", `a = ($a+"b")`, expected, t, true)
   209  }
   210  
   211  func TestParseImportIssue94(t *testing.T) {
   212  	expected := ast.NewTree("test import")
   213  	ln := ast.NewBlockNode(token.NewFileInfo(1, 0))
   214  	importStmt := ast.NewImportNode(token.NewFileInfo(1, 0), ast.NewStringExpr(token.NewFileInfo(1, 7), "common", false))
   215  	ln.Push(importStmt)
   216  	expected.Root = ln
   217  
   218  	parserTest("test import", "import common", expected, t, true)
   219  }
   220  
   221  func TestParseIssue108(t *testing.T) {
   222  	// keywords cannot be used as command arguments
   223  
   224  	expected := ast.NewTree("parse issue #108")
   225  	ln := ast.NewBlockNode(token.NewFileInfo(1, 0))
   226  
   227  	catCmd := ast.NewCommandNode(token.NewFileInfo(1, 0), "cat", false)
   228  
   229  	catArg := ast.NewStringExpr(token.NewFileInfo(1, 4), "spec.ebnf", false)
   230  	catCmd.AddArg(catArg)
   231  
   232  	grepCmd := ast.NewCommandNode(token.NewFileInfo(1, 16), "grep", false)
   233  	grepArg := ast.NewStringExpr(token.NewFileInfo(1, 21), `-i`, false)
   234  	grepArg2 := ast.NewStringExpr(token.NewFileInfo(1, 24), "rfork", false)
   235  
   236  	grepCmd.AddArg(grepArg)
   237  	grepCmd.AddArg(grepArg2)
   238  
   239  	pipe := ast.NewPipeNode(token.NewFileInfo(1, 14), false)
   240  	pipe.AddCmd(catCmd)
   241  	pipe.AddCmd(grepCmd)
   242  
   243  	ln.Push(pipe)
   244  	expected.Root = ln
   245  
   246  	parserTest("parse issue #108", `cat spec.ebnf | grep -i rfork`, expected, t, false)
   247  }
   248  
   249  func TestParseIssue123(t *testing.T) {
   250  	parser := NewParser("invalid cmd assignment", `IFS <= ("\n")`)
   251  
   252  	_, err := parser.Parse()
   253  
   254  	if err == nil {
   255  		t.Errorf("Must fail...")
   256  		return
   257  	}
   258  
   259  	expected := "invalid cmd assignment:1:9: Unexpected token STRING. Expecting IDENT or ARG"
   260  	if err.Error() != expected {
   261  		t.Fatalf("Error string differs. Expecting '%s' but got '%s'",
   262  			expected, err.Error())
   263  	}
   264  }