github.com/endocode/docker@v1.4.2-0.20160113120958-46eb4700391e/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 'abc xyz'"},
   101  			"expect": {"foo", "bar", "'abc xyz'"},
   102  		},
   103  		{
   104  			"input":  {`foo bar "abc xyz"`},
   105  			"expect": {"foo", "bar", `"abc xyz"`},
   106  		},
   107  	}
   108  
   109  	for _, test := range tests {
   110  		words := parseWords(test["input"][0])
   111  		if len(words) != len(test["expect"]) {
   112  			t.Fatalf("length check failed. input: %v, expect: %v, output: %v", test["input"][0], test["expect"], words)
   113  		}
   114  		for i, word := range words {
   115  			if word != test["expect"][i] {
   116  				t.Fatalf("word check failed for word: %q. input: %v, expect: %v, output: %v", word, test["input"][0], test["expect"], words)
   117  			}
   118  		}
   119  	}
   120  }
   121  
   122  func TestLineInformation(t *testing.T) {
   123  	df, err := os.Open(testFileLineInfo)
   124  	if err != nil {
   125  		t.Fatalf("Dockerfile missing for %s: %v", testFileLineInfo, err)
   126  	}
   127  	defer df.Close()
   128  
   129  	ast, err := Parse(df)
   130  	if err != nil {
   131  		t.Fatalf("Error parsing dockerfile %s: %v", testFileLineInfo, err)
   132  	}
   133  
   134  	if ast.StartLine != 4 || ast.EndLine != 30 {
   135  		fmt.Fprintf(os.Stderr, "Wrong root line information: expected(%d-%d), actual(%d-%d)\n", 4, 30, ast.StartLine, ast.EndLine)
   136  		t.Fatalf("Root line information doesn't match result.")
   137  	}
   138  	if len(ast.Children) != 3 {
   139  		fmt.Fprintf(os.Stderr, "Wrong number of child: expected(%d), actual(%d)\n", 3, len(ast.Children))
   140  		t.Fatalf("Root line information doesn't match result.")
   141  	}
   142  	expected := [][]int{
   143  		{4, 4},
   144  		{10, 11},
   145  		{16, 30},
   146  	}
   147  	for i, child := range ast.Children {
   148  		if child.StartLine != expected[i][0] || child.EndLine != expected[i][1] {
   149  			fmt.Fprintf(os.Stderr, "Wrong line information for child %d: expected(%d-%d), actual(%d-%d)\n",
   150  				i, expected[i][0], expected[i][1], child.StartLine, child.EndLine)
   151  			t.Fatalf("Root line information doesn't match result.")
   152  		}
   153  	}
   154  }