func TestConvertDir(t *testing.T) { bFile := `package bar ` dFile := `package c ` root := path.Join("foo", "bar") files := map[string]*testutil.FakeFile{ path.Join(root, "a"): &testutil.FakeFile{Buffer: *bytes.NewBufferString("a")}, path.Join(root, "b"+fExt): &testutil.FakeFile{Buffer: *bytes.NewBufferString(bFile)}, path.Join(root, "b"+fExt+goExt): &testutil.FakeFile{}, path.Join(root, "c", "d"+fExt): &testutil.FakeFile{Buffer: *bytes.NewBufferString(dFile)}, path.Join(root, "c", "d"+fExt+goExt): &testutil.FakeFile{}, } infos := map[string][]os.FileInfo{ root: []os.FileInfo{ &FileInfo{name: "a", size: 1}, &FileInfo{name: "b" + fExt, size: int64(len(bFile))}, &FileInfo{name: "c", isDir: true}, }, path.Join(root, "c"): []os.FileInfo{ &FileInfo{name: "d" + fExt, size: int64(len(dFile))}, }, } readDir := func(s string) ([]os.FileInfo, error) { return infos[s], nil } open := func(s string) (io.ReadWriteCloser, error) { return files[s], nil } create := func(s string) (io.ReadWriteCloser, error) { return files[s], nil } err := convertDir(root, readDir, open, create) defect.Equal(t, err, nil) defect.Equal(t, files[path.Join(root, "b"+fExt+goExt)].String(), header+bFile) defect.Equal(t, files[path.Join(root, "c", "d"+fExt+goExt)].String(), header+dFile) }
func TestLexer_Token(t *testing.T) { l := Lexer{Lexer: util.Lexer{ Reader: util.NewReader(`123 + 456 2 - 78 4569 a = 1 + 2 * (3 / 4 - b)`), IsWhitespace: util.IsWhitespaceST, }} for _, expected := range []struct { Token Token Kind int }{ {"123", NUM}, {"+", '+'}, {"456", NUM}, {"\n", '\n'}, {"2", NUM}, {"-", '-'}, {"78", NUM}, {"\n", '\n'}, {"4569", NUM}, {"\n", '\n'}, {"a", VAR}, {"=", '='}, {"1", NUM}, {"+", '+'}, {"2", NUM}, {"*", '*'}, {"(", '('}, {"3", NUM}, {"/", '/'}, {"4", NUM}, {"-", '-'}, {"b", VAR}, {")", ')'}, } { token, kind, err := l.Token() defect.Equal(t, err, nil) defect.Equal(t, kind, expected.Kind) defect.Equal(t, token, expected.Token) } }
func TestIsWhitespaceSTNL(t *testing.T) { l := Lexer{ Reader: NewReader("1 2\t3\n4"), IsWhitespace: IsWhitespaceSTNL, } for _, expected := range []rune{'1', '2', '3', '4', EOF} { r, err := l.Scan() defect.Equal(t, err, nil) defect.Equal(t, r, expected) } }
func TestLexer_Scan(t *testing.T) { l := Lexer{ Reader: NewReader("1 + 2"), IsWhitespace: IsWhitespaceST, } for _, expected := range []rune{'1', '+', '2', EOF} { r, err := l.Scan() defect.Equal(t, err, nil) defect.Equal(t, r, expected) } }
func TestLexer_Token(t *testing.T) { l := Lexer{Lexer: util.Lexer{ Reader: util.NewReader(`123 + 456 2 - 78 4569 0 15 == 16 a != 3 3 >= 4 5 <= 6 7 > 8 9 < 10 a = 1 + 2 * (3 / 4 - b) wwhilew iiff`), IsWhitespace: util.IsWhitespaceSTNL, }} for _, expected := range []struct { Token Token Kind int }{ {"123", NUM}, {"+", '+'}, {"456", NUM}, {"2", NUM}, {"-", '-'}, {"78", NUM}, {"4569", NUM}, {"0", NUM}, {"15", NUM}, {"==", EQ}, {"16", NUM}, {"a", VAR}, {"!=", NEQ}, {"3", NUM}, {"3", NUM}, {">=", GTEQ}, {"4", NUM}, {"5", NUM}, {"<=", LTEQ}, {"6", NUM}, {"7", NUM}, {">", '>'}, {"8", NUM}, {"9", NUM}, {"<", '<'}, {"10", NUM}, {"a", VAR}, {"=", '='}, {"1", NUM}, {"+", '+'}, {"2", NUM}, {"*", '*'}, {"(", '('}, {"3", NUM}, {"/", '/'}, {"4", NUM}, {"-", '-'}, {"b", VAR}, {")", ')'}, {"w", VAR}, {"while", WHILE}, {"w", VAR}, {"i", VAR}, {"if", IF}, {"f", VAR}, } { token, kind, err := l.Token() defect.Equal(t, err, nil) defect.Equal(t, kind, expected.Kind) defect.Equal(t, token, expected.Token) } // errors l = Lexer{Lexer: util.Lexer{ Reader: util.NewReader("01\n"), IsWhitespace: util.IsWhitespaceSTNL, }} _, _, err := l.Token() defect.Equal(t, err, IllegalInteger) }
func TestParseDancer(t *testing.T) { dancer := &Dancer{} err := dancer.Parse([]string{}) defect.Equal(t, err, ErrWrongNumFields) err = dancer.Parse([]string{"12132", "Cohen", "Miles"}) defect.Equal(t, err, nil) defect.Equal(t, *dancer, Dancer{ Number: 12132, First: "Miles", Last: "Cohen", }) }
func TestConvert(t *testing.T) { fn := func(buffSize int, s string) { out := strings.NewReader(s) in := &bytes.Buffer{} err := convert(out, in, buffSize) defect.Equal(t, err, nil) defect.Equal(t, string(in.Bytes()), header+s) } fn(4, "foo") // 1 pass fn(3, "baz") // exact fn(2, "bar") // 2 passes }
func TestReadRune(t *testing.T) { r := NewReader("foo") fn := func(expected rune) { rn, err := readRune(r) defect.Equal(t, err, nil) defect.Equal(t, rn, expected) } fn('f') fn('o') fn('o') fn(EOF) }
func TestParseCompetition(t *testing.T) { comp := &Competition{} err := comp.Parse([]string{}) defect.Equal(t, err, ErrWrongNumFields) err = comp.Parse([]string{"56", "Easter Swing", "Bellevue, WA", "Apr 2015"}) defect.Equal(t, err, nil) defect.Equal(t, *comp, Competition{ Number: 56, Name: "Easter Swing", Location: "Bellevue, WA", Date: time.Date(2015, 4, 1, 0, 0, 0, 0, time.UTC), }) }
func TestLexer_Scan(t *testing.T) { l := Lexer{Lexer: util.Lexer{ Reader: util.NewReader("a = 1 + 2 * (3 / 4 - b)"), IsWhitespace: util.IsWhitespaceSTNL, }} for _, expected := range []rune{ 'a', '=', '1', '+', '2', '*', '(', '3', '/', '4', '-', 'b', ')', util.EOF, } { r, err := l.Scan() defect.Equal(t, err, nil) defect.Equal(t, r, expected) } }
func TestScanner_Scan(t *testing.T) { s := Scanner{} expected := map[string][]token.Token{ `package main `: {token.PACKAGE, token.IDENT, token.SEMICOLON}, `package main import "fmt" func main(){ fmt.Println("hello world") } `: {token.PACKAGE, token.IDENT, token.SEMICOLON, token.IMPORT, token.STRING, token.SEMICOLON, token.FUNC, token.IDENT, token.LPAREN, token.RPAREN, token.LBRACE, token.IDENT, token.PERIOD, token.IDENT, token.LPAREN, token.STRING, token.RPAREN, token.SEMICOLON, token.RBRACE, token.SEMICOLON}, } for text, symbols := range expected { s.Init([]byte(text)) i := 0 _, tok, _ := s.Scan() for tok != token.EOF { defect.Equal(t, tok, symbols[i]) _, tok, _ = s.Scan() i++ } } }
func TestLexer(t *testing.T) { l := Lexer{Lexer: util.Lexer{Reader: util.NewReader("12")}} fn := func(get func() (rune, error), expected rune) { r, err := get() defect.Equal(t, err, nil) defect.Equal(t, r, expected) } fn(l.Peek, '1') fn(l.Peek, '1') fn(l.Next, '1') fn(l.Peek, '2') fn(l.Next, '2') fn(l.Peek, util.EOF) fn(l.Next, util.EOF) }
func TestIsFenec(t *testing.T) { tests := map[string]bool{ "foo": false, "foo" + goExt: false, "foo" + fExt: true, "foo" + fExt + goExt: false, } for k, v := range tests { defect.Equal(t, IsFenec(k), v) } }
func TestLexer_Token(t *testing.T) { l := Lexer{Lexer: util.Lexer{ Reader: util.NewReader(`123 + 456 2 - 78 4569`), IsWhitespace: util.IsWhitespaceST, }} for _, expected := range []struct { Token Token Kind int }{ {"123", NUM}, {"+", '+'}, {"456", NUM}, {"\n", '\n'}, {"2", NUM}, {"-", '-'}, {"78", NUM}, {"\n", '\n'}, {"4569", NUM}, } { token, kind, err := l.Token() defect.Equal(t, err, nil) defect.Equal(t, kind, expected.Kind) defect.Equal(t, token, expected.Token) } }
func TestEmptyGenerics_literals(t *testing.T) { src := []string{ "struct{}{}", // empty struct "struct[]{}{}", // empty generic struct "func(){}", // empty function "func[](){}", // empty generic function } for _, s := range src { _, err := ParseExpr(s) defect.Equal(t, err, nil) } }
func TestLexer_PeekAndScan(t *testing.T) { fn := func(get func() (rune, error), expected rune) { r, err := get() defect.Equal(t, err, nil) defect.Equal(t, r, expected) } // empty l := Lexer{Reader: NewReader("")} fn(l.Peek, EOF) fn(l.Next, EOF) // basic l = Lexer{Reader: NewReader("12")} fn(l.Peek, '1') fn(l.Peek, '1') fn(l.Next, '1') fn(l.Peek, '2') fn(l.Next, '2') fn(l.Peek, EOF) fn(l.Next, EOF) }
func TestScanner_Peek(t *testing.T) { s := Scanner{} s.Init([]byte(`package main func main(){} `)) expected := []token.Token{ token.PACKAGE, token.IDENT, token.SEMICOLON, token.FUNC, token.IDENT, token.LPAREN, token.RPAREN, token.LBRACE, token.RBRACE, token.SEMICOLON, } for _, e := range expected { _, tok, _ := s.Peek() defect.Equal(t, tok, e) s.Scan() } }
func TestInDir(t *testing.T) { readDir := func(string) ([]os.FileInfo, error) { return []os.FileInfo{ &FileInfo{name: "foo" + goExt, size: 12, isDir: false}, &FileInfo{name: "bar" + fExt, size: int64(len(basicFile)), isDir: false}, &FileInfo{name: "baz", size: 0, isDir: true}, &FileInfo{name: "quux" + fExt, size: 0, isDir: true}, }, nil } p := path.Join("foo", "bar", "baz") files, dirs, err := inDir(p, readDir) defect.Equal(t, err, nil) defect.DeepEqual(t, files, []string{path.Join(p, "bar"+fExt)}) defect.DeepEqual(t, dirs, []string{ path.Join(p, "baz"), path.Join(p, "quux"+fExt), }) }
func TestYyParse(t *testing.T) { fn := func(s string, expected []int) { Output.Mtx.Lock() Output.Val = []int{} p := yyParse(&Lexer{Lexer: util.Lexer{ Reader: util.NewReader(s), IsWhitespace: util.IsWhitespaceST, }}) defect.Equal(t, p, util.EOF) defect.DeepEqual(t, Output.Val, expected) Output.Mtx.Unlock() } fn("6\n", []int{6}) fn("67 + 89\n", []int{67 + 89}) fn("2 * 3\n", []int{6}) fn("6 / 2\n", []int{3}) fn("(4)\n", []int{4}) fn("1 + 3 * (4 / 2 - 5)\n", []int{-8}) fn("a = 1\n", []int{}) fn(`a = 1 a `, []int{1}) fn(`123 + 456 2 - 78 4569 `, []int{123 + 456, 2 - 78, 4569}) fn("1 + 3 * (4 / 2 - 5)\n", []int{-8}) fn(`a = 1 + 3 * (4 / 2 - 5) b = a + 10 b `, []int{2}) // examples from the book fn(`3 * (4 + 5) x = 3 * (4 + 5) y = 5 x y x + 2 * y `, []int{27, 27, 5, 37}) }
func TestV1Parse(t *testing.T) { fn := func(s string, expected []int) { Output.Mtx.Lock() Output.Val = []int{} p := yyParse(&Lexer{Lexer: util.Lexer{ Reader: util.NewReader(s), IsWhitespace: util.IsWhitespaceST, }}) defect.Equal(t, p, util.EOF) defect.DeepEqual(t, Output.Val, expected) Output.Mtx.Unlock() } fn("6\n", []int{6}) fn("67 + 89\n", []int{67 + 89}) fn(`123 + 456 2 - 78 4569 `, []int{123 + 456, 2 - 78, 4569}) }
func TestParseResult(t *testing.T) { result := &Result{} err := result.Parse([]string{}) defect.Equal(t, err, ErrWrongNumFields) err = result.Parse([]string{"12132", "56", "f", "All-Stars", "F", "1"}) defect.Equal(t, err, nil) defect.Equal(t, *result, Result{ Dancer: 12132, Competition: 56, Lead: false, Category: "All-Stars", Result: 0, Points: 1, }) err = result.Parse([]string{"12132", "56", "l", "Novice", "0", "1"}) defect.Equal(t, err, nil) defect.Equal(t, *result, Result{ Dancer: 12132, Competition: 56, Lead: true, Category: "Novice", Result: 0, Points: 1, }) err = result.Parse([]string{"12132", "56", "f", "Invitational", "1", "10"}) defect.Equal(t, err, nil) defect.Equal(t, *result, Result{ Dancer: 12132, Competition: 56, Lead: false, Category: "Invitational", Result: 1, Points: 10, }) }
func TestConvertFile(t *testing.T) { name := "/foo/bar/baz" + fExt of := testutil.FakeFile{} o := func(s string) (io.ReadWriteCloser, error) { of.Path = s of.WriteString(basicFile) return &of, nil } cf := testutil.FakeFile{} c := func(s string) (io.ReadWriteCloser, error) { cf.Path = s return &cf, nil } err := convertFile(name, o, c) defect.Equal(t, err, nil) defect.Equal(t, cf.String(), header+basicFile) defect.Equal(t, of.Closed, true) defect.Equal(t, cf.Closed, true) defect.Equal(t, of.Path, name) defect.Equal(t, cf.Path, name+goExt) }
func TestYyParse(t *testing.T) { fn := func(s string, expected []interface{}) { Mtx.Lock() Initialize() p := yyParse(&Lexer{Lexer: util.Lexer{ Reader: util.NewReader(s), IsWhitespace: util.IsWhitespaceSTNL, }}) defect.Equal(t, p, util.EOF) defect.DeepEqual(t, vals(Output), expected) Mtx.Unlock() } fn("print 6;", []interface{}{6}) fn("print 67 + 89;", []interface{}{67 + 89}) fn("print 2 * 3;", []interface{}{6}) fn("print 6 / 2;", []interface{}{3}) fn("print (4);", []interface{}{4}) fn("print 1 + 3 * (4 / 2 - 5);", []interface{}{-8}) fn("print -2;", []interface{}{-2}) fn("a = 1;", []interface{}{}) fn(`a = 1; print a; `, []interface{}{1}) fn(`print 123 + 456; print 2 - 78; print 4569; `, []interface{}{123 + 456, 2 - 78, 4569}) fn("print 1 + 3 * (4 / 2 - 5);", []interface{}{-8}) fn(`a = 1 + 3 * (4 / 2 - 5); b = a + 10; print b; `, []interface{}{2}) fn("print 1 == 1;", []interface{}{true}) fn("print (1 == 1) == (2 == 3);", []interface{}{false}) fn("print 2 < 1;", []interface{}{false}) fn("print 2 > 1;", []interface{}{true}) fn("print 3 >= 3;", []interface{}{true}) fn("print 4 <= 3;", []interface{}{false}) fn("print 2 != 2;", []interface{}{false}) fn("print (1 != 1) != (1 != 2);", []interface{}{true}) fn("{print 1; print 2;}", []interface{}{1, 2}) fn("{{{print 1;}}}", []interface{}{1}) fn("a = 1; { a = 2; {{ a = 3; a = 4; } a = 5; }} print a;", []interface{}{5}) fn("{a = 1; print a;}", []interface{}{1}) fn("if (1 == 1) {print 1;}", []interface{}{1}) fn("if (1 == 2) {print 1;}", []interface{}{}) fn("a = 1; if (a == 1) { print 1; }", []interface{}{1}) fn("a = 1 == 1; if (a) { print 1; }", []interface{}{1}) fn("{a = 1; if (a == 1) { print 1; }}", []interface{}{1}) fn("a = 1; while (a < 3) { print a; a = a + 1; }", []interface{}{1, 2}) fn("if (1 == 2) print 1; else print 2;", []interface{}{2}) fn("a = 1; if (a == 2) print 1; else print 2;", []interface{}{2}) fn(`a = 1; if (a == 2) { a = a + 1; print a; } else { a = a + 1; if (a == 2) print a == 2; else print a == 2; }`, []interface{}{true}) fn(`a = 1; while (a < 4) { while (a < 4) { print a; a = a + 1; } }`, []interface{}{1, 2, 3}) // examples from the book fn(`print 3 * (4 + 5); x = 3 * (4 + 5); y = 5; print x; print y; print x + 2 * y; `, []interface{}{27, 27, 5, 37}) }
func ParseTestFile(t *testing.T, s string) *ast.File { fset := token.NewFileSet() file, err := ParseFile(fset, "", s, AllErrors) defect.Equal(t, err, nil) return file }