Source file
src/go/parser/parser_test.go
1
2
3
4
5 package parser
6
7 import (
8 "bytes"
9 "fmt"
10 "go/ast"
11 "go/token"
12 "io/fs"
13 "runtime"
14 "strings"
15 "testing"
16 )
17
18 var validFiles = []string{
19 "parser.go",
20 "parser_test.go",
21 "error_test.go",
22 "short_test.go",
23 }
24
25 func TestParse(t *testing.T) {
26 for _, filename := range validFiles {
27 _, err := ParseFile(token.NewFileSet(), filename, nil, DeclarationErrors)
28 if err != nil {
29 t.Fatalf("ParseFile(%s): %v", filename, err)
30 }
31 }
32 }
33
34 func nameFilter(filename string) bool {
35 switch filename {
36 case "parser.go", "interface.go", "parser_test.go":
37 return true
38 case "parser.go.orig":
39 return true
40 }
41 return false
42 }
43
44 func dirFilter(f fs.FileInfo) bool { return nameFilter(f.Name()) }
45
46 func TestParseFile(t *testing.T) {
47 src := "package p\nvar _=s[::]+\ns[::]+\ns[::]+\ns[::]+\ns[::]+\ns[::]+\ns[::]+\ns[::]+\ns[::]+\ns[::]+\ns[::]+\ns[::]"
48 _, err := ParseFile(token.NewFileSet(), "", src, 0)
49 if err == nil {
50 t.Errorf("ParseFile(%s) succeeded unexpectedly", src)
51 }
52 }
53
54 func TestParseExprFrom(t *testing.T) {
55 src := "s[::]+\ns[::]+\ns[::]+\ns[::]+\ns[::]+\ns[::]+\ns[::]+\ns[::]+\ns[::]+\ns[::]+\ns[::]+\ns[::]"
56 _, err := ParseExprFrom(token.NewFileSet(), "", src, 0)
57 if err == nil {
58 t.Errorf("ParseExprFrom(%s) succeeded unexpectedly", src)
59 }
60 }
61
62 func TestParseDir(t *testing.T) {
63 path := "."
64 pkgs, err := ParseDir(token.NewFileSet(), path, dirFilter, 0)
65 if err != nil {
66 t.Fatalf("ParseDir(%s): %v", path, err)
67 }
68 if n := len(pkgs); n != 1 {
69 t.Errorf("got %d packages; want 1", n)
70 }
71 pkg := pkgs["parser"]
72 if pkg == nil {
73 t.Errorf(`package "parser" not found`)
74 return
75 }
76 if n := len(pkg.Files); n != 3 {
77 t.Errorf("got %d package files; want 3", n)
78 }
79 for filename := range pkg.Files {
80 if !nameFilter(filename) {
81 t.Errorf("unexpected package file: %s", filename)
82 }
83 }
84 }
85
86 func TestIssue42951(t *testing.T) {
87 path := "./testdata/issue42951"
88 _, err := ParseDir(token.NewFileSet(), path, nil, 0)
89 if err != nil {
90 t.Errorf("ParseDir(%s): %v", path, err)
91 }
92 }
93
94 func TestParseExpr(t *testing.T) {
95
96
97 src := "a + b"
98 x, err := ParseExpr(src)
99 if err != nil {
100 t.Errorf("ParseExpr(%q): %v", src, err)
101 }
102
103 if _, ok := x.(*ast.BinaryExpr); !ok {
104 t.Errorf("ParseExpr(%q): got %T, want *ast.BinaryExpr", src, x)
105 }
106
107
108 src = "struct{x *int}"
109 x, err = ParseExpr(src)
110 if err != nil {
111 t.Errorf("ParseExpr(%q): %v", src, err)
112 }
113
114 if _, ok := x.(*ast.StructType); !ok {
115 t.Errorf("ParseExpr(%q): got %T, want *ast.StructType", src, x)
116 }
117
118
119 src = "a + *"
120 x, err = ParseExpr(src)
121 if err == nil {
122 t.Errorf("ParseExpr(%q): got no error", src)
123 }
124 if x == nil {
125 t.Errorf("ParseExpr(%q): got no (partial) result", src)
126 }
127 if _, ok := x.(*ast.BinaryExpr); !ok {
128 t.Errorf("ParseExpr(%q): got %T, want *ast.BinaryExpr", src, x)
129 }
130
131
132 src = "a[i] := x"
133 if _, err := ParseExpr(src); err == nil {
134 t.Errorf("ParseExpr(%q): got no error", src)
135 }
136
137
138 src = "a + b\n"
139 if _, err := ParseExpr(src); err != nil {
140 t.Errorf("ParseExpr(%q): got error %s", src, err)
141 }
142 src = "a + b;"
143 if _, err := ParseExpr(src); err == nil {
144 t.Errorf("ParseExpr(%q): got no error", src)
145 }
146
147
148 const validExpr = "a + b"
149 const anything = "dh3*#D)#_"
150 for _, c := range "!)]};," {
151 src := validExpr + string(c) + anything
152 if _, err := ParseExpr(src); err == nil {
153 t.Errorf("ParseExpr(%q): got no error", src)
154 }
155 }
156
157
158 for _, src := range valids {
159 ParseExpr(src)
160 }
161 }
162
163 func TestColonEqualsScope(t *testing.T) {
164 f, err := ParseFile(token.NewFileSet(), "", `package p; func f() { x, y, z := x, y, z }`, 0)
165 if err != nil {
166 t.Fatal(err)
167 }
168
169
170 as := f.Decls[0].(*ast.FuncDecl).Body.List[0].(*ast.AssignStmt)
171 for _, v := range as.Rhs {
172 id := v.(*ast.Ident)
173 if id.Obj != nil {
174 t.Errorf("rhs %s has Obj, should not", id.Name)
175 }
176 }
177 for _, v := range as.Lhs {
178 id := v.(*ast.Ident)
179 if id.Obj == nil {
180 t.Errorf("lhs %s does not have Obj, should", id.Name)
181 }
182 }
183 }
184
185 func TestVarScope(t *testing.T) {
186 f, err := ParseFile(token.NewFileSet(), "", `package p; func f() { var x, y, z = x, y, z }`, 0)
187 if err != nil {
188 t.Fatal(err)
189 }
190
191
192 as := f.Decls[0].(*ast.FuncDecl).Body.List[0].(*ast.DeclStmt).Decl.(*ast.GenDecl).Specs[0].(*ast.ValueSpec)
193 for _, v := range as.Values {
194 id := v.(*ast.Ident)
195 if id.Obj != nil {
196 t.Errorf("rhs %s has Obj, should not", id.Name)
197 }
198 }
199 for _, id := range as.Names {
200 if id.Obj == nil {
201 t.Errorf("lhs %s does not have Obj, should", id.Name)
202 }
203 }
204 }
205
206 func TestObjects(t *testing.T) {
207 const src = `
208 package p
209 import fmt "fmt"
210 const pi = 3.14
211 type T struct{}
212 var x int
213 func f() { L: }
214 `
215
216 f, err := ParseFile(token.NewFileSet(), "", src, 0)
217 if err != nil {
218 t.Fatal(err)
219 }
220
221 objects := map[string]ast.ObjKind{
222 "p": ast.Bad,
223 "fmt": ast.Bad,
224 "pi": ast.Con,
225 "T": ast.Typ,
226 "x": ast.Var,
227 "int": ast.Bad,
228 "f": ast.Fun,
229 "L": ast.Lbl,
230 }
231
232 ast.Inspect(f, func(n ast.Node) bool {
233 if ident, ok := n.(*ast.Ident); ok {
234 obj := ident.Obj
235 if obj == nil {
236 if objects[ident.Name] != ast.Bad {
237 t.Errorf("no object for %s", ident.Name)
238 }
239 return true
240 }
241 if obj.Name != ident.Name {
242 t.Errorf("names don't match: obj.Name = %s, ident.Name = %s", obj.Name, ident.Name)
243 }
244 kind := objects[ident.Name]
245 if obj.Kind != kind {
246 t.Errorf("%s: obj.Kind = %s; want %s", ident.Name, obj.Kind, kind)
247 }
248 }
249 return true
250 })
251 }
252
253 func TestUnresolved(t *testing.T) {
254 f, err := ParseFile(token.NewFileSet(), "", `
255 package p
256 //
257 func f1a(int)
258 func f2a(byte, int, float)
259 func f3a(a, b int, c float)
260 func f4a(...complex)
261 func f5a(a s1a, b ...complex)
262 //
263 func f1b(*int)
264 func f2b([]byte, (int), *float)
265 func f3b(a, b *int, c []float)
266 func f4b(...*complex)
267 func f5b(a s1a, b ...[]complex)
268 //
269 type s1a struct { int }
270 type s2a struct { byte; int; s1a }
271 type s3a struct { a, b int; c float }
272 //
273 type s1b struct { *int }
274 type s2b struct { byte; int; *float }
275 type s3b struct { a, b *s3b; c []float }
276 `, 0)
277 if err != nil {
278 t.Fatal(err)
279 }
280
281 want := "int " +
282 "byte int float " +
283 "int float " +
284 "complex " +
285 "complex " +
286
287 "int " +
288 "byte int float " +
289 "int float " +
290 "complex " +
291 "complex " +
292
293 "int " +
294 "byte int " +
295 "int float " +
296
297 "int " +
298 "byte int float " +
299 "float "
300
301
302 var buf bytes.Buffer
303 for _, u := range f.Unresolved {
304 buf.WriteString(u.Name)
305 buf.WriteByte(' ')
306 }
307 got := buf.String()
308
309 if got != want {
310 t.Errorf("\ngot: %s\nwant: %s", got, want)
311 }
312 }
313
314 var imports = map[string]bool{
315 `"a"`: true,
316 "`a`": true,
317 `"a/b"`: true,
318 `"a.b"`: true,
319 `"m\x61th"`: true,
320 `"greek/αβ"`: true,
321 `""`: false,
322
323
324
325
326
327
328 `"\x00"`: false,
329 "`\x00`": false,
330 `"\x7f"`: false,
331 "`\x7f`": false,
332 `"a!"`: false,
333 "`a!`": false,
334 `"a b"`: false,
335 "`a b`": false,
336 `"a\\b"`: false,
337 "`a\\b`": false,
338 "\"`a`\"": false,
339 "`\"a\"`": false,
340 `"\x80\x80"`: false,
341 "`\x80\x80`": false,
342 `"\xFFFD"`: false,
343 "`\xFFFD`": false,
344 }
345
346 func TestImports(t *testing.T) {
347 for path, isValid := range imports {
348 src := fmt.Sprintf("package p; import %s", path)
349 _, err := ParseFile(token.NewFileSet(), "", src, 0)
350 switch {
351 case err != nil && isValid:
352 t.Errorf("ParseFile(%s): got %v; expected no error", src, err)
353 case err == nil && !isValid:
354 t.Errorf("ParseFile(%s): got no error; expected one", src)
355 }
356 }
357 }
358
359 func TestCommentGroups(t *testing.T) {
360 f, err := ParseFile(token.NewFileSet(), "", `
361 package p /* 1a */ /* 1b */ /* 1c */ // 1d
362 /* 2a
363 */
364 // 2b
365 const pi = 3.1415
366 /* 3a */ // 3b
367 /* 3c */ const e = 2.7182
368
369 // Example from issue 3139
370 func ExampleCount() {
371 fmt.Println(strings.Count("cheese", "e"))
372 fmt.Println(strings.Count("five", "")) // before & after each rune
373 // Output:
374 // 3
375 // 5
376 }
377 `, ParseComments)
378 if err != nil {
379 t.Fatal(err)
380 }
381 expected := [][]string{
382 {"/* 1a */", "/* 1b */", "/* 1c */", "// 1d"},
383 {"/* 2a\n*/", "// 2b"},
384 {"/* 3a */", "// 3b", "/* 3c */"},
385 {"// Example from issue 3139"},
386 {"// before & after each rune"},
387 {"// Output:", "// 3", "// 5"},
388 }
389 if len(f.Comments) != len(expected) {
390 t.Fatalf("got %d comment groups; expected %d", len(f.Comments), len(expected))
391 }
392 for i, exp := range expected {
393 got := f.Comments[i].List
394 if len(got) != len(exp) {
395 t.Errorf("got %d comments in group %d; expected %d", len(got), i, len(exp))
396 continue
397 }
398 for j, exp := range exp {
399 got := got[j].Text
400 if got != exp {
401 t.Errorf("got %q in group %d; expected %q", got, i, exp)
402 }
403 }
404 }
405 }
406
407 func getField(file *ast.File, fieldname string) *ast.Field {
408 parts := strings.Split(fieldname, ".")
409 for _, d := range file.Decls {
410 if d, ok := d.(*ast.GenDecl); ok && d.Tok == token.TYPE {
411 for _, s := range d.Specs {
412 if s, ok := s.(*ast.TypeSpec); ok && s.Name.Name == parts[0] {
413 if s, ok := s.Type.(*ast.StructType); ok {
414 for _, f := range s.Fields.List {
415 for _, name := range f.Names {
416 if name.Name == parts[1] {
417 return f
418 }
419 }
420 }
421 }
422 }
423 }
424 }
425 }
426 return nil
427 }
428
429
430 func commentText(c *ast.CommentGroup) string {
431 var buf bytes.Buffer
432 if c != nil {
433 for _, c := range c.List {
434 buf.WriteString(c.Text)
435 }
436 }
437 return buf.String()
438 }
439
440 func checkFieldComments(t *testing.T, file *ast.File, fieldname, lead, line string) {
441 f := getField(file, fieldname)
442 if f == nil {
443 t.Fatalf("field not found: %s", fieldname)
444 }
445 if got := commentText(f.Doc); got != lead {
446 t.Errorf("got lead comment %q; expected %q", got, lead)
447 }
448 if got := commentText(f.Comment); got != line {
449 t.Errorf("got line comment %q; expected %q", got, line)
450 }
451 }
452
453 func TestLeadAndLineComments(t *testing.T) {
454 f, err := ParseFile(token.NewFileSet(), "", `
455 package p
456 type T struct {
457 /* F1 lead comment */
458 //
459 F1 int /* F1 */ // line comment
460 // F2 lead
461 // comment
462 F2 int // F2 line comment
463 // f3 lead comment
464 f3 int // f3 line comment
465 }
466 `, ParseComments)
467 if err != nil {
468 t.Fatal(err)
469 }
470 checkFieldComments(t, f, "T.F1", "/* F1 lead comment *///", "/* F1 */// line comment")
471 checkFieldComments(t, f, "T.F2", "// F2 lead// comment", "// F2 line comment")
472 checkFieldComments(t, f, "T.f3", "// f3 lead comment", "// f3 line comment")
473 ast.FileExports(f)
474 checkFieldComments(t, f, "T.F1", "/* F1 lead comment *///", "/* F1 */// line comment")
475 checkFieldComments(t, f, "T.F2", "// F2 lead// comment", "// F2 line comment")
476 if getField(f, "T.f3") != nil {
477 t.Error("not expected to find T.f3")
478 }
479 }
480
481
482 func TestIssue9979(t *testing.T) {
483 for _, src := range []string{
484 "package p; func f() {;}",
485 "package p; func f() {L:}",
486 "package p; func f() {L:;}",
487 "package p; func f() {L:\n}",
488 "package p; func f() {L:\n;}",
489 "package p; func f() { ; }",
490 "package p; func f() { L: }",
491 "package p; func f() { L: ; }",
492 "package p; func f() { L: \n}",
493 "package p; func f() { L: \n; }",
494 } {
495 fset := token.NewFileSet()
496 f, err := ParseFile(fset, "", src, 0)
497 if err != nil {
498 t.Fatal(err)
499 }
500
501 var pos, end token.Pos
502 ast.Inspect(f, func(x ast.Node) bool {
503 switch s := x.(type) {
504 case *ast.BlockStmt:
505 pos, end = s.Pos()+1, s.End()-1
506 case *ast.LabeledStmt:
507 pos, end = s.Pos()+2, s.End()
508 case *ast.EmptyStmt:
509
510 if s.Pos() < pos || s.End() > end {
511 t.Errorf("%s: %T[%d, %d] not inside [%d, %d]", src, s, s.Pos(), s.End(), pos, end)
512 }
513
514 offs := fset.Position(s.Pos()).Offset
515 if ch := src[offs]; ch != ';' != s.Implicit {
516 want := "want ';'"
517 if s.Implicit {
518 want = "but ';' is implicit"
519 }
520 t.Errorf("%s: found %q at offset %d; %s", src, ch, offs, want)
521 }
522 }
523 return true
524 })
525 }
526 }
527
528
529
530
531 func TestIncompleteSelection(t *testing.T) {
532 for _, src := range []string{
533 "package p; var _ = fmt.",
534 "package p; var _ = fmt.\ntype X int",
535 } {
536 fset := token.NewFileSet()
537 f, err := ParseFile(fset, "", src, 0)
538 if err == nil {
539 t.Errorf("ParseFile(%s) succeeded unexpectedly", src)
540 continue
541 }
542
543 const wantErr = "expected selector or type assertion"
544 if !strings.Contains(err.Error(), wantErr) {
545 t.Errorf("ParseFile returned wrong error %q, want %q", err, wantErr)
546 }
547
548 var sel *ast.SelectorExpr
549 ast.Inspect(f, func(n ast.Node) bool {
550 if n, ok := n.(*ast.SelectorExpr); ok {
551 sel = n
552 }
553 return true
554 })
555 if sel == nil {
556 t.Error("found no *ast.SelectorExpr")
557 continue
558 }
559 const wantSel = "&{fmt _}"
560 if fmt.Sprint(sel) != wantSel {
561 t.Errorf("found selector %s, want %s", sel, wantSel)
562 continue
563 }
564 }
565 }
566
567 func TestLastLineComment(t *testing.T) {
568 const src = `package main
569 type x int // comment
570 `
571 fset := token.NewFileSet()
572 f, err := ParseFile(fset, "", src, ParseComments)
573 if err != nil {
574 t.Fatal(err)
575 }
576 comment := f.Decls[0].(*ast.GenDecl).Specs[0].(*ast.TypeSpec).Comment.List[0].Text
577 if comment != "// comment" {
578 t.Errorf("got %q, want %q", comment, "// comment")
579 }
580 }
581
582 var parseDepthTests = []struct {
583 name string
584 format string
585
586
587
588
589
590 parseMultiplier int
591
592
593 scope bool
594
595
596 scopeMultiplier int
597 }{
598
599
600
601 {name: "array", format: "package main; var x «[1]»int"},
602 {name: "slice", format: "package main; var x «[]»int"},
603 {name: "struct", format: "package main; var x «struct { X «int» }»", scope: true},
604 {name: "pointer", format: "package main; var x «*»int"},
605 {name: "func", format: "package main; var x «func()»int", scope: true},
606 {name: "chan", format: "package main; var x «chan »int"},
607 {name: "chan2", format: "package main; var x «<-chan »int"},
608 {name: "interface", format: "package main; var x «interface { M() «int» }»", scope: true, scopeMultiplier: 2},
609 {name: "map", format: "package main; var x «map[int]»int"},
610 {name: "slicelit", format: "package main; var x = «[]any{«»}»", parseMultiplier: 2},
611 {name: "arraylit", format: "package main; var x = «[1]any{«nil»}»", parseMultiplier: 2},
612 {name: "structlit", format: "package main; var x = «struct{x any}{«nil»}»", parseMultiplier: 2},
613 {name: "maplit", format: "package main; var x = «map[int]any{1:«nil»}»", parseMultiplier: 2},
614 {name: "dot", format: "package main; var x = «x.»x"},
615 {name: "index", format: "package main; var x = x«[1]»"},
616 {name: "slice", format: "package main; var x = x«[1:2]»"},
617 {name: "slice3", format: "package main; var x = x«[1:2:3]»"},
618 {name: "dottype", format: "package main; var x = x«.(any)»"},
619 {name: "callseq", format: "package main; var x = x«()»"},
620 {name: "methseq", format: "package main; var x = x«.m()»", parseMultiplier: 2},
621 {name: "binary", format: "package main; var x = «1+»1"},
622 {name: "binaryparen", format: "package main; var x = «1+(«1»)»", parseMultiplier: 2},
623 {name: "unary", format: "package main; var x = «^»1"},
624 {name: "addr", format: "package main; var x = «& »x"},
625 {name: "star", format: "package main; var x = «*»x"},
626 {name: "recv", format: "package main; var x = «<-»x"},
627 {name: "call", format: "package main; var x = «f(«1»)»", parseMultiplier: 2},
628 {name: "conv", format: "package main; var x = «(*T)(«1»)»", parseMultiplier: 2},
629 {name: "label", format: "package main; func main() { «Label:» }"},
630 {name: "if", format: "package main; func main() { «if true { «» }»}", parseMultiplier: 2, scope: true, scopeMultiplier: 2},
631 {name: "ifelse", format: "package main; func main() { «if true {} else » {} }", scope: true},
632 {name: "switch", format: "package main; func main() { «switch { default: «» }»}", scope: true, scopeMultiplier: 2},
633 {name: "typeswitch", format: "package main; func main() { «switch x.(type) { default: «» }» }", scope: true, scopeMultiplier: 2},
634 {name: "for0", format: "package main; func main() { «for { «» }» }", scope: true, scopeMultiplier: 2},
635 {name: "for1", format: "package main; func main() { «for x { «» }» }", scope: true, scopeMultiplier: 2},
636 {name: "for3", format: "package main; func main() { «for f(); g(); h() { «» }» }", scope: true, scopeMultiplier: 2},
637 {name: "forrange0", format: "package main; func main() { «for range x { «» }» }", scope: true, scopeMultiplier: 2},
638 {name: "forrange1", format: "package main; func main() { «for x = range z { «» }» }", scope: true, scopeMultiplier: 2},
639 {name: "forrange2", format: "package main; func main() { «for x, y = range z { «» }» }", scope: true, scopeMultiplier: 2},
640 {name: "go", format: "package main; func main() { «go func() { «» }()» }", parseMultiplier: 2, scope: true},
641 {name: "defer", format: "package main; func main() { «defer func() { «» }()» }", parseMultiplier: 2, scope: true},
642 {name: "select", format: "package main; func main() { «select { default: «» }» }", scope: true},
643 }
644
645
646
647 func split(x string) (pre, mid, post string) {
648 start, end := strings.Index(x, "«"), strings.LastIndex(x, "»")
649 if start < 0 || end < 0 {
650 return x, "", ""
651 }
652 return x[:start], x[start+len("«") : end], x[end+len("»"):]
653 }
654
655 func TestParseDepthLimit(t *testing.T) {
656 if runtime.GOARCH == "wasm" {
657 t.Skip("causes call stack exhaustion on js/wasm")
658 }
659 for _, tt := range parseDepthTests {
660 for _, size := range []string{"small", "big"} {
661 t.Run(tt.name+"/"+size, func(t *testing.T) {
662 n := maxNestLev + 1
663 if tt.parseMultiplier > 0 {
664 n /= tt.parseMultiplier
665 }
666 if size == "small" {
667
668
669
670
671
672 n -= 10
673 }
674
675 pre, mid, post := split(tt.format)
676 if strings.Contains(mid, "«") {
677 left, base, right := split(mid)
678 mid = strings.Repeat(left, n) + base + strings.Repeat(right, n)
679 } else {
680 mid = strings.Repeat(mid, n)
681 }
682 input := pre + mid + post
683
684 fset := token.NewFileSet()
685 _, err := ParseFile(fset, "", input, ParseComments|SkipObjectResolution)
686 if size == "small" {
687 if err != nil {
688 t.Errorf("ParseFile(...): %v (want success)", err)
689 }
690 } else {
691 expected := "exceeded max nesting depth"
692 if err == nil || !strings.HasSuffix(err.Error(), expected) {
693 t.Errorf("ParseFile(...) = _, %v, want %q", err, expected)
694 }
695 }
696 })
697 }
698 }
699 }
700
701 func TestScopeDepthLimit(t *testing.T) {
702 if runtime.GOARCH == "wasm" {
703 t.Skip("causes call stack exhaustion on js/wasm")
704 }
705 for _, tt := range parseDepthTests {
706 if !tt.scope {
707 continue
708 }
709 for _, size := range []string{"small", "big"} {
710 t.Run(tt.name+"/"+size, func(t *testing.T) {
711 n := maxScopeDepth + 1
712 if tt.scopeMultiplier > 0 {
713 n /= tt.scopeMultiplier
714 }
715 if size == "small" {
716
717
718
719
720
721 n -= 10
722 }
723
724 pre, mid, post := split(tt.format)
725 if strings.Contains(mid, "«") {
726 left, base, right := split(mid)
727 mid = strings.Repeat(left, n) + base + strings.Repeat(right, n)
728 } else {
729 mid = strings.Repeat(mid, n)
730 }
731 input := pre + mid + post
732
733 fset := token.NewFileSet()
734 _, err := ParseFile(fset, "", input, DeclarationErrors)
735 if size == "small" {
736 if err != nil {
737 t.Errorf("ParseFile(...): %v (want success)", err)
738 }
739 } else {
740 expected := "exceeded max scope depth during object resolution"
741 if err == nil || !strings.HasSuffix(err.Error(), expected) {
742 t.Errorf("ParseFile(...) = _, %v, want %q", err, expected)
743 }
744 }
745 })
746 }
747 }
748 }
749
View as plain text