github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/builder/dockerfile/parser/parser_test.go (about) 1 package parser 2 3 import ( 4 "bytes" 5 "fmt" 6 "io/ioutil" 7 "os" 8 "path/filepath" 9 "runtime" 10 "testing" 11 ) 12 13 const testDir = "testfiles" 14 const negativeTestDir = "testfiles-negative" 15 const testFileLineInfo = "testfile-line/Dockerfile" 16 17 func getDirs(t *testing.T, dir string) []string { 18 f, err := os.Open(dir) 19 if err != nil { 20 t.Fatal(err) 21 } 22 23 defer f.Close() 24 25 dirs, err := f.Readdirnames(0) 26 if err != nil { 27 t.Fatal(err) 28 } 29 30 return dirs 31 } 32 33 func TestTestNegative(t *testing.T) { 34 for _, dir := range getDirs(t, negativeTestDir) { 35 dockerfile := filepath.Join(negativeTestDir, dir, "Dockerfile") 36 37 df, err := os.Open(dockerfile) 38 if err != nil { 39 t.Fatalf("Dockerfile missing for %s: %v", dir, err) 40 } 41 defer df.Close() 42 43 d := Directive{LookingForDirectives: true} 44 SetEscapeToken(DefaultEscapeToken, &d) 45 _, err = Parse(df, &d) 46 if err == nil { 47 t.Fatalf("No error parsing broken dockerfile for %s", dir) 48 } 49 } 50 } 51 52 func TestTestData(t *testing.T) { 53 for _, dir := range getDirs(t, testDir) { 54 dockerfile := filepath.Join(testDir, dir, "Dockerfile") 55 resultfile := filepath.Join(testDir, dir, "result") 56 57 df, err := os.Open(dockerfile) 58 if err != nil { 59 t.Fatalf("Dockerfile missing for %s: %v", dir, err) 60 } 61 defer df.Close() 62 63 d := Directive{LookingForDirectives: true} 64 SetEscapeToken(DefaultEscapeToken, &d) 65 ast, err := Parse(df, &d) 66 if err != nil { 67 t.Fatalf("Error parsing %s's dockerfile: %v", dir, err) 68 } 69 70 content, err := ioutil.ReadFile(resultfile) 71 if err != nil { 72 t.Fatalf("Error reading %s's result file: %v", dir, err) 73 } 74 75 if runtime.GOOS == "windows" { 76 // CRLF --> CR to match Unix behavior 77 content = bytes.Replace(content, []byte{'\x0d', '\x0a'}, []byte{'\x0a'}, -1) 78 } 79 80 if ast.Dump()+"\n" != string(content) { 81 fmt.Fprintln(os.Stderr, "Result:\n"+ast.Dump()) 82 fmt.Fprintln(os.Stderr, "Expected:\n"+string(content)) 83 t.Fatalf("%s: AST dump of dockerfile does not match result", dir) 84 } 85 } 86 } 87 88 func TestParseWords(t *testing.T) { 89 tests := []map[string][]string{ 90 { 91 "input": {"foo"}, 92 "expect": {"foo"}, 93 }, 94 { 95 "input": {"foo bar"}, 96 "expect": {"foo", "bar"}, 97 }, 98 { 99 "input": {"foo\\ bar"}, 100 "expect": {"foo\\ bar"}, 101 }, 102 { 103 "input": {"foo=bar"}, 104 "expect": {"foo=bar"}, 105 }, 106 { 107 "input": {"foo bar 'abc xyz'"}, 108 "expect": {"foo", "bar", "'abc xyz'"}, 109 }, 110 { 111 "input": {`foo bar "abc xyz"`}, 112 "expect": {"foo", "bar", `"abc xyz"`}, 113 }, 114 { 115 "input": {"àöû"}, 116 "expect": {"àöû"}, 117 }, 118 { 119 "input": {`föo bàr "âbc xÿz"`}, 120 "expect": {"föo", "bàr", `"âbc xÿz"`}, 121 }, 122 } 123 124 for _, test := range tests { 125 d := Directive{LookingForDirectives: true} 126 SetEscapeToken(DefaultEscapeToken, &d) 127 words := parseWords(test["input"][0], &d) 128 if len(words) != len(test["expect"]) { 129 t.Fatalf("length check failed. input: %v, expect: %q, output: %q", test["input"][0], test["expect"], words) 130 } 131 for i, word := range words { 132 if word != test["expect"][i] { 133 t.Fatalf("word check failed for word: %q. input: %q, expect: %q, output: %q", word, test["input"][0], test["expect"], words) 134 } 135 } 136 } 137 } 138 139 func TestLineInformation(t *testing.T) { 140 df, err := os.Open(testFileLineInfo) 141 if err != nil { 142 t.Fatalf("Dockerfile missing for %s: %v", testFileLineInfo, err) 143 } 144 defer df.Close() 145 146 d := Directive{LookingForDirectives: true} 147 SetEscapeToken(DefaultEscapeToken, &d) 148 ast, err := Parse(df, &d) 149 if err != nil { 150 t.Fatalf("Error parsing dockerfile %s: %v", testFileLineInfo, err) 151 } 152 153 if ast.StartLine != 5 || ast.EndLine != 31 { 154 fmt.Fprintf(os.Stderr, "Wrong root line information: expected(%d-%d), actual(%d-%d)\n", 5, 31, ast.StartLine, ast.EndLine) 155 t.Fatalf("Root line information doesn't match result.") 156 } 157 if len(ast.Children) != 3 { 158 fmt.Fprintf(os.Stderr, "Wrong number of child: expected(%d), actual(%d)\n", 3, len(ast.Children)) 159 t.Fatalf("Root line information doesn't match result for %s", testFileLineInfo) 160 } 161 expected := [][]int{ 162 {5, 5}, 163 {11, 12}, 164 {17, 31}, 165 } 166 for i, child := range ast.Children { 167 if child.StartLine != expected[i][0] || child.EndLine != expected[i][1] { 168 t.Logf("Wrong line information for child %d: expected(%d-%d), actual(%d-%d)\n", 169 i, expected[i][0], expected[i][1], child.StartLine, child.EndLine) 170 t.Fatalf("Root line information doesn't match result.") 171 } 172 } 173 }