github.com/kobeld/docker@v1.12.0-rc1/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 42 _, err = Parse(df) 43 if err == nil { 44 t.Fatalf("No error parsing broken dockerfile for %s", dir) 45 } 46 47 df.Close() 48 } 49 } 50 51 func TestTestData(t *testing.T) { 52 for _, dir := range getDirs(t, testDir) { 53 dockerfile := filepath.Join(testDir, dir, "Dockerfile") 54 resultfile := filepath.Join(testDir, dir, "result") 55 56 df, err := os.Open(dockerfile) 57 if err != nil { 58 t.Fatalf("Dockerfile missing for %s: %v", dir, err) 59 } 60 defer df.Close() 61 62 ast, err := Parse(df) 63 if err != nil { 64 t.Fatalf("Error parsing %s's dockerfile: %v", dir, err) 65 } 66 67 content, err := ioutil.ReadFile(resultfile) 68 if err != nil { 69 t.Fatalf("Error reading %s's result file: %v", dir, err) 70 } 71 72 if runtime.GOOS == "windows" { 73 // CRLF --> CR to match Unix behavior 74 content = bytes.Replace(content, []byte{'\x0d', '\x0a'}, []byte{'\x0a'}, -1) 75 } 76 77 if ast.Dump()+"\n" != string(content) { 78 fmt.Fprintln(os.Stderr, "Result:\n"+ast.Dump()) 79 fmt.Fprintln(os.Stderr, "Expected:\n"+string(content)) 80 t.Fatalf("%s: AST dump of dockerfile does not match result", dir) 81 } 82 } 83 } 84 85 func TestParseWords(t *testing.T) { 86 tests := []map[string][]string{ 87 { 88 "input": {"foo"}, 89 "expect": {"foo"}, 90 }, 91 { 92 "input": {"foo bar"}, 93 "expect": {"foo", "bar"}, 94 }, 95 { 96 "input": {"foo\\ bar"}, 97 "expect": {"foo\\ bar"}, 98 }, 99 { 100 "input": {"foo=bar"}, 101 "expect": {"foo=bar"}, 102 }, 103 { 104 "input": {"foo bar 'abc xyz'"}, 105 "expect": {"foo", "bar", "'abc xyz'"}, 106 }, 107 { 108 "input": {`foo bar "abc xyz"`}, 109 "expect": {"foo", "bar", `"abc xyz"`}, 110 }, 111 { 112 "input": {"àöû"}, 113 "expect": {"àöû"}, 114 }, 115 { 116 "input": {`föo bàr "âbc xÿz"`}, 117 "expect": {"föo", "bàr", `"âbc xÿz"`}, 118 }, 119 } 120 121 for _, test := range tests { 122 words := parseWords(test["input"][0]) 123 if len(words) != len(test["expect"]) { 124 t.Fatalf("length check failed. input: %v, expect: %v, output: %v", test["input"][0], test["expect"], words) 125 } 126 for i, word := range words { 127 if word != test["expect"][i] { 128 t.Fatalf("word check failed for word: %q. input: %v, expect: %v, output: %v", word, test["input"][0], test["expect"], words) 129 } 130 } 131 } 132 } 133 134 func TestLineInformation(t *testing.T) { 135 df, err := os.Open(testFileLineInfo) 136 if err != nil { 137 t.Fatalf("Dockerfile missing for %s: %v", testFileLineInfo, err) 138 } 139 defer df.Close() 140 141 ast, err := Parse(df) 142 if err != nil { 143 t.Fatalf("Error parsing dockerfile %s: %v", testFileLineInfo, err) 144 } 145 146 if ast.StartLine != 5 || ast.EndLine != 31 { 147 fmt.Fprintf(os.Stderr, "Wrong root line information: expected(%d-%d), actual(%d-%d)\n", 5, 31, ast.StartLine, ast.EndLine) 148 t.Fatalf("Root line information doesn't match result.") 149 } 150 if len(ast.Children) != 3 { 151 fmt.Fprintf(os.Stderr, "Wrong number of child: expected(%d), actual(%d)\n", 3, len(ast.Children)) 152 t.Fatalf("Root line information doesn't match result for %s", testFileLineInfo) 153 } 154 expected := [][]int{ 155 {5, 5}, 156 {11, 12}, 157 {17, 31}, 158 } 159 for i, child := range ast.Children { 160 if child.StartLine != expected[i][0] || child.EndLine != expected[i][1] { 161 t.Logf("Wrong line information for child %d: expected(%d-%d), actual(%d-%d)\n", 162 i, expected[i][0], expected[i][1], child.StartLine, child.EndLine) 163 t.Fatalf("Root line information doesn't match result.") 164 } 165 } 166 }