github.com/joomcode/cue@v0.4.4-0.20221111115225-539fe3512047/cue/load/read_test.go (about)

     1  // Copyright 2018 The CUE Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package load
    16  
    17  import (
    18  	"io"
    19  	"strings"
    20  	"testing"
    21  
    22  	"github.com/joomcode/cue/cue/errors"
    23  )
    24  
    25  const quote = "`"
    26  
    27  type readTest struct {
    28  	// Test input contains ℙ where readImports should stop.
    29  	in  string
    30  	err string
    31  }
    32  
    33  var readImportsTests = []readTest{
    34  	{
    35  		`package p`,
    36  		"",
    37  	},
    38  	{
    39  		`package p; import "x"`,
    40  		"",
    41  	},
    42  	{
    43  		`package p; import . "x"`,
    44  		"",
    45  	},
    46  	{
    47  		`package p; import "x";ℙvar x = 1`,
    48  		"",
    49  	},
    50  	{
    51  		`package p
    52  		
    53  		// comment
    54  		
    55  		import "x"
    56  		import _ "x"
    57  		import a "x"
    58  
    59  		import (
    60  			"x"
    61  			_ "x"
    62  			a "x" // comment
    63  			` + quote + `x` + quote + `
    64  			_ ` + quote + `x` + quote + `
    65  			a ` + quote + `x` + quote + `
    66  		)
    67  		import (
    68  		)
    69  		import ()
    70  		import()import()import()
    71  		import();import();import()
    72  
    73  		ℙvar x = 1
    74  		`,
    75  		"",
    76  	},
    77  }
    78  
    79  var readCommentsTests = []readTest{
    80  	{
    81  		`ℙpackage p`,
    82  		"",
    83  	},
    84  	{
    85  		`ℙpackage p; import "x"`,
    86  		"",
    87  	},
    88  	{
    89  		`ℙpackage p; import . "x"`,
    90  		"",
    91  	},
    92  	{
    93  		`// foo
    94  
    95  		// asdf
    96  		ℙHello, world`,
    97  		"",
    98  	},
    99  }
   100  
   101  func testRead(t *testing.T, tests []readTest, read func(io.Reader) ([]byte, errors.Error)) {
   102  	for i, tt := range tests {
   103  		var in, testOut string
   104  		j := strings.Index(tt.in, "ℙ")
   105  		if j < 0 {
   106  			in = tt.in
   107  			testOut = tt.in
   108  		} else {
   109  			in = tt.in[:j] + tt.in[j+len("ℙ"):]
   110  			testOut = tt.in[:j]
   111  		}
   112  		r := strings.NewReader(in)
   113  		buf, err := read(r)
   114  		if err != nil {
   115  			if tt.err == "" {
   116  				t.Errorf("#%d: err=%q, expected success (%q)", i, err, string(buf))
   117  				continue
   118  			}
   119  			if !strings.Contains(err.Error(), tt.err) {
   120  				t.Errorf("#%d: err=%q, expected %q", i, err, tt.err)
   121  				continue
   122  			}
   123  			continue
   124  		}
   125  		if tt.err != "" {
   126  			t.Errorf("#%d: success, expected %q", i, tt.err)
   127  			continue
   128  		}
   129  
   130  		out := string(buf)
   131  		if out != testOut {
   132  			t.Errorf("#%d: wrong output:\nhave %q\nwant %q\n", i, out, testOut)
   133  		}
   134  	}
   135  }
   136  
   137  func TestReadImports(t *testing.T) {
   138  	testRead(t, readImportsTests, func(r io.Reader) ([]byte, errors.Error) {
   139  		return readImports(r, true, nil)
   140  	})
   141  }
   142  
   143  func TestReadComments(t *testing.T) {
   144  	testRead(t, readCommentsTests, readComments)
   145  }
   146  
   147  var readFailuresTests = []readTest{
   148  	{
   149  		`package`,
   150  		"syntax error",
   151  	},
   152  	{
   153  		"package p\n\x00\nimport `math`\n",
   154  		"unexpected NUL in input",
   155  	},
   156  	{
   157  		`package p; import`,
   158  		"syntax error",
   159  	},
   160  	{
   161  		`package p; import "`,
   162  		"syntax error",
   163  	},
   164  	{
   165  		"package p; import ` \n\n",
   166  		"syntax error",
   167  	},
   168  	{
   169  		`package p; import "x`,
   170  		"syntax error",
   171  	},
   172  	{
   173  		`package p; import _`,
   174  		"syntax error",
   175  	},
   176  	{
   177  		`package p; import _ "`,
   178  		"syntax error",
   179  	},
   180  	{
   181  		`package p; import _ "x`,
   182  		"syntax error",
   183  	},
   184  	{
   185  		`package p; import .`,
   186  		"syntax error",
   187  	},
   188  	{
   189  		`package p; import . "`,
   190  		"syntax error",
   191  	},
   192  	{
   193  		`package p; import . "x`,
   194  		"syntax error",
   195  	},
   196  	{
   197  		`package p; import (`,
   198  		"syntax error",
   199  	},
   200  	{
   201  		`package p; import ("`,
   202  		"syntax error",
   203  	},
   204  	{
   205  		`package p; import ("x`,
   206  		"syntax error",
   207  	},
   208  	{
   209  		`package p; import ("x"`,
   210  		"syntax error",
   211  	},
   212  }
   213  
   214  func TestReadFailures(t *testing.T) {
   215  	// Errors should be reported (true arg to readImports).
   216  	testRead(t, readFailuresTests, func(r io.Reader) ([]byte, errors.Error) {
   217  		return readImports(r, true, nil)
   218  	})
   219  }
   220  
   221  func TestReadFailuresIgnored(t *testing.T) {
   222  	// Syntax errors should not be reported (false arg to readImports).
   223  	// Instead, entire file should be the output and no error.
   224  	// Convert tests not to return syntax errors.
   225  	tests := make([]readTest, len(readFailuresTests))
   226  	copy(tests, readFailuresTests)
   227  	for i := range tests {
   228  		tt := &tests[i]
   229  		if !strings.Contains(tt.err, "NUL") {
   230  			tt.err = ""
   231  		}
   232  	}
   233  	testRead(t, tests, func(r io.Reader) ([]byte, errors.Error) {
   234  		return readImports(r, false, nil)
   235  	})
   236  }