Home | History | Annotate | Download | only in build
      1 // Copyright 2012 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 package build
      6 
      7 import (
      8 	"io"
      9 	"strings"
     10 	"testing"
     11 )
     12 
     13 const quote = "`"
     14 
     15 type readTest struct {
     16 	// Test input contains  where readImports should stop.
     17 	in  string
     18 	err string
     19 }
     20 
     21 var readImportsTests = []readTest{
     22 	{
     23 		`package p`,
     24 		"",
     25 	},
     26 	{
     27 		`package p; import "x"`,
     28 		"",
     29 	},
     30 	{
     31 		`package p; import . "x"`,
     32 		"",
     33 	},
     34 	{
     35 		`package p; import "x";var x = 1`,
     36 		"",
     37 	},
     38 	{
     39 		`package p
     40 		
     41 		// comment
     42 		
     43 		import "x"
     44 		import _ "x"
     45 		import a "x"
     46 		
     47 		/* comment */
     48 		
     49 		import (
     50 			"x" /* comment */
     51 			_ "x"
     52 			a "x" // comment
     53 			` + quote + `x` + quote + `
     54 			_ /*comment*/ ` + quote + `x` + quote + `
     55 			a ` + quote + `x` + quote + `
     56 		)
     57 		import (
     58 		)
     59 		import ()
     60 		import()import()import()
     61 		import();import();import()
     62 		
     63 		var x = 1
     64 		`,
     65 		"",
     66 	},
     67 }
     68 
     69 var readCommentsTests = []readTest{
     70 	{
     71 		`package p`,
     72 		"",
     73 	},
     74 	{
     75 		`package p; import "x"`,
     76 		"",
     77 	},
     78 	{
     79 		`package p; import . "x"`,
     80 		"",
     81 	},
     82 	{
     83 		`// foo
     84 
     85 		/* bar */
     86 
     87 		/* quux */ // baz
     88 		
     89 		/*/ zot */
     90 
     91 		// asdf
     92 		Hello, world`,
     93 		"",
     94 	},
     95 }
     96 
     97 func testRead(t *testing.T, tests []readTest, read func(io.Reader) ([]byte, error)) {
     98 	for i, tt := range tests {
     99 		var in, testOut string
    100 		j := strings.Index(tt.in, "")
    101 		if j < 0 {
    102 			in = tt.in
    103 			testOut = tt.in
    104 		} else {
    105 			in = tt.in[:j] + tt.in[j+len(""):]
    106 			testOut = tt.in[:j]
    107 		}
    108 		r := strings.NewReader(in)
    109 		buf, err := read(r)
    110 		if err != nil {
    111 			if tt.err == "" {
    112 				t.Errorf("#%d: err=%q, expected success (%q)", i, err, string(buf))
    113 				continue
    114 			}
    115 			if !strings.Contains(err.Error(), tt.err) {
    116 				t.Errorf("#%d: err=%q, expected %q", i, err, tt.err)
    117 				continue
    118 			}
    119 			continue
    120 		}
    121 		if err == nil && tt.err != "" {
    122 			t.Errorf("#%d: success, expected %q", i, tt.err)
    123 			continue
    124 		}
    125 
    126 		out := string(buf)
    127 		if out != testOut {
    128 			t.Errorf("#%d: wrong output:\nhave %q\nwant %q\n", i, out, testOut)
    129 		}
    130 	}
    131 }
    132 
    133 func TestReadImports(t *testing.T) {
    134 	testRead(t, readImportsTests, func(r io.Reader) ([]byte, error) { return readImports(r, true, nil) })
    135 }
    136 
    137 func TestReadComments(t *testing.T) {
    138 	testRead(t, readCommentsTests, readComments)
    139 }
    140 
    141 var readFailuresTests = []readTest{
    142 	{
    143 		`package`,
    144 		"syntax error",
    145 	},
    146 	{
    147 		"package p\n\x00\nimport `math`\n",
    148 		"unexpected NUL in input",
    149 	},
    150 	{
    151 		`package p; import`,
    152 		"syntax error",
    153 	},
    154 	{
    155 		`package p; import "`,
    156 		"syntax error",
    157 	},
    158 	{
    159 		"package p; import ` \n\n",
    160 		"syntax error",
    161 	},
    162 	{
    163 		`package p; import "x`,
    164 		"syntax error",
    165 	},
    166 	{
    167 		`package p; import _`,
    168 		"syntax error",
    169 	},
    170 	{
    171 		`package p; import _ "`,
    172 		"syntax error",
    173 	},
    174 	{
    175 		`package p; import _ "x`,
    176 		"syntax error",
    177 	},
    178 	{
    179 		`package p; import .`,
    180 		"syntax error",
    181 	},
    182 	{
    183 		`package p; import . "`,
    184 		"syntax error",
    185 	},
    186 	{
    187 		`package p; import . "x`,
    188 		"syntax error",
    189 	},
    190 	{
    191 		`package p; import (`,
    192 		"syntax error",
    193 	},
    194 	{
    195 		`package p; import ("`,
    196 		"syntax error",
    197 	},
    198 	{
    199 		`package p; import ("x`,
    200 		"syntax error",
    201 	},
    202 	{
    203 		`package p; import ("x"`,
    204 		"syntax error",
    205 	},
    206 }
    207 
    208 func TestReadFailures(t *testing.T) {
    209 	// Errors should be reported (true arg to readImports).
    210 	testRead(t, readFailuresTests, func(r io.Reader) ([]byte, error) { return readImports(r, true, nil) })
    211 }
    212 
    213 func TestReadFailuresIgnored(t *testing.T) {
    214 	// Syntax errors should not be reported (false arg to readImports).
    215 	// Instead, entire file should be the output and no error.
    216 	// Convert tests not to return syntax errors.
    217 	tests := make([]readTest, len(readFailuresTests))
    218 	copy(tests, readFailuresTests)
    219 	for i := range tests {
    220 		tt := &tests[i]
    221 		if !strings.Contains(tt.err, "NUL") {
    222 			tt.err = ""
    223 		}
    224 	}
    225 	testRead(t, tests, func(r io.Reader) ([]byte, error) { return readImports(r, false, nil) })
    226 }
    227