~mna/snow

ref: 312f82aa74262ef61bc38df8a053385f424416ce snow/pkg/compiler/parser_test.go -rw-r--r-- 2.2 KiB
312f82aaMartin Angers pkg/compiler: fix bad pos panic 1 year, 11 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package compiler

import (
	"bytes"
	"flag"
	goscanner "go/scanner"
	gotoken "go/token"
	"io/ioutil"
	"os"
	"path/filepath"
	"testing"

	"github.com/kylelemons/godebug/diff"
)

var testUpdateParserTests = flag.Bool("test.update-parser-tests", false, "If set, replace expected parser test results with actual results.")

func TestParser(t *testing.T) {
	baseDir := filepath.Join("testdata", "parser")
	fis, err := ioutil.ReadDir(baseDir)
	if err != nil {
		t.Fatal(err)
	}

	for _, fi := range fis {
		if !fi.Mode().IsRegular() {
			continue
		}
		if filepath.Ext(fi.Name()) != ".snow" {
			continue
		}

		t.Run(fi.Name(), func(t *testing.T) {
			var p parser

			b, err := ioutil.ReadFile(filepath.Join(baseDir, fi.Name()))
			if err != nil {
				t.Fatal(err)
			}

			fset := gotoken.NewFileSet()
			p.init(fset, fi.Name(), b)

			f := p.parseFile()
			// for the test, keep all errors per line, in the order they occurred
			//p.errors.RemoveMultiples()
			parseErr := p.errors.Err()
			//pretty.Print(f)

			var ebuf bytes.Buffer
			goscanner.PrintError(&ebuf, parseErr)

			var buf bytes.Buffer
			pp := printer{w: &buf, posMode: posOffsets, withComments: true}
			if err := pp.Print(f, p.file); err != nil {
				t.Fatal(err)
			}

			wantFile := filepath.Join(baseDir, fi.Name()+".want")
			errFile := filepath.Join(baseDir, fi.Name()+".err")
			if *testUpdateParserTests {
				if err := ioutil.WriteFile(wantFile, buf.Bytes(), 0666); err != nil {
					t.Fatal(err)
				}

				if err := ioutil.WriteFile(errFile, ebuf.Bytes(), 0666); err != nil {
					t.Fatal(err)
				}
				return
			}

			// validate AST output
			want, err := ioutil.ReadFile(wantFile)
			if err != nil && !os.IsNotExist(err) {
				t.Fatal(err)
			}
			if patch := diff.Diff(buf.String(), string(want)); patch != "" {
				t.Logf("got:\n%s\n", buf.String())
				t.Logf("want:\n%s\n", string(want))
				t.Errorf("diff (input eof=%d):\n%s\n", len(b), patch)
			}

			// validate errors output
			ewant, err := ioutil.ReadFile(errFile)
			if err != nil && !os.IsNotExist(err) {
				t.Fatal(err)
			}
			if patch := diff.Diff(ebuf.String(), string(ewant)); patch != "" {
				t.Logf("got error(s):\n%s\n", ebuf.String())
				t.Logf("want error(s):\n%s\n", string(ewant))
				t.Errorf("diff error(s):\n%s\n", patch)
			}
		})
	}
}