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 }