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 }