github.com/cilki/sh@v2.6.4+incompatible/syntax/walk_test.go (about) 1 // Copyright (c) 2016, Daniel Martà <mvdan@mvdan.cc> 2 // See LICENSE for licensing information 3 4 package syntax 5 6 import ( 7 "fmt" 8 "reflect" 9 "strings" 10 "testing" 11 ) 12 13 func TestWalk(t *testing.T) { 14 t.Parallel() 15 seen := map[string]bool{ 16 "*syntax.File": false, 17 "*syntax.Comment": false, 18 "*syntax.Stmt": false, 19 "*syntax.Assign": false, 20 "*syntax.Redirect": false, 21 "*syntax.CallExpr": false, 22 "*syntax.Subshell": false, 23 "*syntax.Block": false, 24 "*syntax.IfClause": false, 25 "*syntax.WhileClause": false, 26 "*syntax.ForClause": false, 27 "*syntax.WordIter": false, 28 "*syntax.CStyleLoop": false, 29 "*syntax.BinaryCmd": false, 30 "*syntax.FuncDecl": false, 31 "*syntax.Word": false, 32 "*syntax.Lit": false, 33 "*syntax.SglQuoted": false, 34 "*syntax.DblQuoted": false, 35 "*syntax.CmdSubst": false, 36 "*syntax.ParamExp": false, 37 "*syntax.ArithmExp": false, 38 "*syntax.ArithmCmd": false, 39 "*syntax.BinaryArithm": false, 40 "*syntax.UnaryArithm": false, 41 "*syntax.ParenArithm": false, 42 "*syntax.CaseClause": false, 43 "*syntax.CaseItem": false, 44 "*syntax.TestClause": false, 45 "*syntax.BinaryTest": false, 46 "*syntax.UnaryTest": false, 47 "*syntax.ParenTest": false, 48 "*syntax.DeclClause": false, 49 "*syntax.ArrayExpr": false, 50 "*syntax.ArrayElem": false, 51 "*syntax.ExtGlob": false, 52 "*syntax.ProcSubst": false, 53 "*syntax.TimeClause": false, 54 "*syntax.CoprocClause": false, 55 "*syntax.LetClause": false, 56 } 57 parser := NewParser(KeepComments) 58 var allStrs []string 59 for _, c := range fileTests { 60 allStrs = append(allStrs, c.Strs[0]) 61 } 62 for _, c := range printTests { 63 allStrs = append(allStrs, c.in) 64 } 65 for i, in := range allStrs { 66 t.Run(fmt.Sprintf("%03d", i), func(t *testing.T) { 67 prog, err := parser.Parse(strings.NewReader(in), "") 68 if err != nil { 69 // good enough for now, as the bash 70 // parser ignoring errors covers what we 71 // need. 72 return 73 } 74 lastOffs := uint(0) 75 Walk(prog, func(node Node) bool { 76 if node == nil { 77 return false 78 } 79 tstr := reflect.TypeOf(node).String() 80 if _, ok := seen[tstr]; !ok { 81 t.Errorf("unexpected type: %s", tstr) 82 } else { 83 seen[tstr] = true 84 } 85 switch node.(type) { 86 case *Lit: 87 return false 88 case *Comment: 89 default: 90 return true 91 } 92 offs := node.Pos().Offset() 93 if offs >= lastOffs { 94 lastOffs = offs 95 } else { 96 t.Errorf("comment offset goes back") 97 } 98 return true 99 }) 100 }) 101 } 102 for tstr, tseen := range seen { 103 if !tseen { 104 t.Errorf("type not seen: %s", tstr) 105 } 106 } 107 } 108 109 type newNode struct{} 110 111 func (newNode) Pos() Pos { return Pos{} } 112 func (newNode) End() Pos { return Pos{} } 113 114 func TestWalkUnexpectedType(t *testing.T) { 115 t.Parallel() 116 defer func() { 117 if r := recover(); r == nil { 118 t.Errorf("did not panic") 119 } 120 }() 121 Walk(newNode{}, func(node Node) bool { 122 return true 123 }) 124 }