Source file src/cmd/go/internal/imports/read_test.go

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

View as plain text