scanner: fix tests

This commit is contained in:
Fatih Arslan 2015-10-07 12:24:03 +03:00
parent 8169cb79d7
commit fa991d3df2
2 changed files with 212 additions and 214 deletions

View File

@ -4,163 +4,161 @@ import (
"bytes" "bytes"
"fmt" "fmt"
"testing" "testing"
"github.com/fatih/hcl/token"
) )
var f100 = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" var f100 = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
type tokenPair struct { type tokenPair struct {
tok token.Token tok TokenType
text string text string
} }
var tokenLists = map[string][]tokenPair{ var tokenLists = map[string][]tokenPair{
"comment": []tokenPair{ "comment": []tokenPair{
{token.COMMENT, "//"}, {COMMENT, "//"},
{token.COMMENT, "////"}, {COMMENT, "////"},
{token.COMMENT, "// comment"}, {COMMENT, "// comment"},
{token.COMMENT, "// /* comment */"}, {COMMENT, "// /* comment */"},
{token.COMMENT, "// // comment //"}, {COMMENT, "// // comment //"},
{token.COMMENT, "//" + f100}, {COMMENT, "//" + f100},
{token.COMMENT, "#"}, {COMMENT, "#"},
{token.COMMENT, "##"}, {COMMENT, "##"},
{token.COMMENT, "# comment"}, {COMMENT, "# comment"},
{token.COMMENT, "# /* comment */"}, {COMMENT, "# /* comment */"},
{token.COMMENT, "# # comment #"}, {COMMENT, "# # comment #"},
{token.COMMENT, "#" + f100}, {COMMENT, "#" + f100},
{token.COMMENT, "/**/"}, {COMMENT, "/**/"},
{token.COMMENT, "/***/"}, {COMMENT, "/***/"},
{token.COMMENT, "/* comment */"}, {COMMENT, "/* comment */"},
{token.COMMENT, "/* // comment */"}, {COMMENT, "/* // comment */"},
{token.COMMENT, "/* /* comment */"}, {COMMENT, "/* /* comment */"},
{token.COMMENT, "/*\n comment\n*/"}, {COMMENT, "/*\n comment\n*/"},
{token.COMMENT, "/*" + f100 + "*/"}, {COMMENT, "/*" + f100 + "*/"},
}, },
"operator": []tokenPair{ "operator": []tokenPair{
{token.LBRACK, "["}, {LBRACK, "["},
{token.LBRACE, "{"}, {LBRACE, "{"},
{token.COMMA, ","}, {COMMA, ","},
{token.PERIOD, "."}, {PERIOD, "."},
{token.RBRACK, "]"}, {RBRACK, "]"},
{token.RBRACE, "}"}, {RBRACE, "}"},
{token.ASSIGN, "="}, {ASSIGN, "="},
{token.ADD, "+"}, {ADD, "+"},
{token.SUB, "-"}, {SUB, "-"},
}, },
"bool": []tokenPair{ "bool": []tokenPair{
{token.BOOL, "true"}, {BOOL, "true"},
{token.BOOL, "false"}, {BOOL, "false"},
}, },
"ident": []tokenPair{ "ident": []tokenPair{
{token.IDENT, "a"}, {IDENT, "a"},
{token.IDENT, "a0"}, {IDENT, "a0"},
{token.IDENT, "foobar"}, {IDENT, "foobar"},
{token.IDENT, "abc123"}, {IDENT, "abc123"},
{token.IDENT, "LGTM"}, {IDENT, "LGTM"},
{token.IDENT, "_"}, {IDENT, "_"},
{token.IDENT, "_abc123"}, {IDENT, "_abc123"},
{token.IDENT, "abc123_"}, {IDENT, "abc123_"},
{token.IDENT, "_abc_123_"}, {IDENT, "_abc_123_"},
{token.IDENT, "_äöü"}, {IDENT, "_äöü"},
{token.IDENT, "_本"}, {IDENT, "_本"},
{token.IDENT, "äöü"}, {IDENT, "äöü"},
{token.IDENT, "本"}, {IDENT, "本"},
{token.IDENT, "a۰۱۸"}, {IDENT, "a۰۱۸"},
{token.IDENT, "foo६४"}, {IDENT, "foo६४"},
{token.IDENT, "bar"}, {IDENT, "bar"},
}, },
"string": []tokenPair{ "string": []tokenPair{
{token.STRING, `" "`}, {STRING, `" "`},
{token.STRING, `"a"`}, {STRING, `"a"`},
{token.STRING, `"本"`}, {STRING, `"本"`},
{token.STRING, `"\a"`}, {STRING, `"\a"`},
{token.STRING, `"\b"`}, {STRING, `"\b"`},
{token.STRING, `"\f"`}, {STRING, `"\f"`},
{token.STRING, `"\n"`}, {STRING, `"\n"`},
{token.STRING, `"\r"`}, {STRING, `"\r"`},
{token.STRING, `"\t"`}, {STRING, `"\t"`},
{token.STRING, `"\v"`}, {STRING, `"\v"`},
{token.STRING, `"\""`}, {STRING, `"\""`},
{token.STRING, `"\000"`}, {STRING, `"\000"`},
{token.STRING, `"\777"`}, {STRING, `"\777"`},
{token.STRING, `"\x00"`}, {STRING, `"\x00"`},
{token.STRING, `"\xff"`}, {STRING, `"\xff"`},
{token.STRING, `"\u0000"`}, {STRING, `"\u0000"`},
{token.STRING, `"\ufA16"`}, {STRING, `"\ufA16"`},
{token.STRING, `"\U00000000"`}, {STRING, `"\U00000000"`},
{token.STRING, `"\U0000ffAB"`}, {STRING, `"\U0000ffAB"`},
{token.STRING, `"` + f100 + `"`}, {STRING, `"` + f100 + `"`},
}, },
"number": []tokenPair{ "number": []tokenPair{
{token.NUMBER, "0"}, {NUMBER, "0"},
{token.NUMBER, "1"}, {NUMBER, "1"},
{token.NUMBER, "9"}, {NUMBER, "9"},
{token.NUMBER, "42"}, {NUMBER, "42"},
{token.NUMBER, "1234567890"}, {NUMBER, "1234567890"},
{token.NUMBER, "00"}, {NUMBER, "00"},
{token.NUMBER, "01"}, {NUMBER, "01"},
{token.NUMBER, "07"}, {NUMBER, "07"},
{token.NUMBER, "042"}, {NUMBER, "042"},
{token.NUMBER, "01234567"}, {NUMBER, "01234567"},
{token.NUMBER, "0x0"}, {NUMBER, "0x0"},
{token.NUMBER, "0x1"}, {NUMBER, "0x1"},
{token.NUMBER, "0xf"}, {NUMBER, "0xf"},
{token.NUMBER, "0x42"}, {NUMBER, "0x42"},
{token.NUMBER, "0x123456789abcDEF"}, {NUMBER, "0x123456789abcDEF"},
{token.NUMBER, "0x" + f100}, {NUMBER, "0x" + f100},
{token.NUMBER, "0X0"}, {NUMBER, "0X0"},
{token.NUMBER, "0X1"}, {NUMBER, "0X1"},
{token.NUMBER, "0XF"}, {NUMBER, "0XF"},
{token.NUMBER, "0X42"}, {NUMBER, "0X42"},
{token.NUMBER, "0X123456789abcDEF"}, {NUMBER, "0X123456789abcDEF"},
{token.NUMBER, "0X" + f100}, {NUMBER, "0X" + f100},
{token.NUMBER, "0e0"}, {NUMBER, "0e0"},
{token.NUMBER, "1e0"}, {NUMBER, "1e0"},
{token.NUMBER, "42e0"}, {NUMBER, "42e0"},
{token.NUMBER, "01234567890e0"}, {NUMBER, "01234567890e0"},
{token.NUMBER, "0E0"}, {NUMBER, "0E0"},
{token.NUMBER, "1E0"}, {NUMBER, "1E0"},
{token.NUMBER, "42E0"}, {NUMBER, "42E0"},
{token.NUMBER, "01234567890E0"}, {NUMBER, "01234567890E0"},
{token.NUMBER, "0e+10"}, {NUMBER, "0e+10"},
{token.NUMBER, "1e-10"}, {NUMBER, "1e-10"},
{token.NUMBER, "42e+10"}, {NUMBER, "42e+10"},
{token.NUMBER, "01234567890e-10"}, {NUMBER, "01234567890e-10"},
{token.NUMBER, "0E+10"}, {NUMBER, "0E+10"},
{token.NUMBER, "1E-10"}, {NUMBER, "1E-10"},
{token.NUMBER, "42E+10"}, {NUMBER, "42E+10"},
{token.NUMBER, "01234567890E-10"}, {NUMBER, "01234567890E-10"},
}, },
"float": []tokenPair{ "float": []tokenPair{
{token.FLOAT, "0."}, {FLOAT, "0."},
{token.FLOAT, "1."}, {FLOAT, "1."},
{token.FLOAT, "42."}, {FLOAT, "42."},
{token.FLOAT, "01234567890."}, {FLOAT, "01234567890."},
{token.FLOAT, ".0"}, {FLOAT, ".0"},
{token.FLOAT, ".1"}, {FLOAT, ".1"},
{token.FLOAT, ".42"}, {FLOAT, ".42"},
{token.FLOAT, ".0123456789"}, {FLOAT, ".0123456789"},
{token.FLOAT, "0.0"}, {FLOAT, "0.0"},
{token.FLOAT, "1.0"}, {FLOAT, "1.0"},
{token.FLOAT, "42.0"}, {FLOAT, "42.0"},
{token.FLOAT, "01234567890.0"}, {FLOAT, "01234567890.0"},
{token.FLOAT, "01.8e0"}, {FLOAT, "01.8e0"},
{token.FLOAT, "1.4e0"}, {FLOAT, "1.4e0"},
{token.FLOAT, "42.2e0"}, {FLOAT, "42.2e0"},
{token.FLOAT, "01234567890.12e0"}, {FLOAT, "01234567890.12e0"},
{token.FLOAT, "0.E0"}, {FLOAT, "0.E0"},
{token.FLOAT, "1.12E0"}, {FLOAT, "1.12E0"},
{token.FLOAT, "42.123E0"}, {FLOAT, "42.123E0"},
{token.FLOAT, "01234567890.213E0"}, {FLOAT, "01234567890.213E0"},
{token.FLOAT, "0.2e+10"}, {FLOAT, "0.2e+10"},
{token.FLOAT, "1.2e-10"}, {FLOAT, "1.2e-10"},
{token.FLOAT, "42.54e+10"}, {FLOAT, "42.54e+10"},
{token.FLOAT, "01234567890.98e-10"}, {FLOAT, "01234567890.98e-10"},
{token.FLOAT, "0.1E+10"}, {FLOAT, "0.1E+10"},
{token.FLOAT, "1.1E-10"}, {FLOAT, "1.1E-10"},
{token.FLOAT, "42.1E+10"}, {FLOAT, "42.1E+10"},
{token.FLOAT, "01234567890.1E-10"}, {FLOAT, "01234567890.1E-10"},
}, },
} }
@ -272,102 +270,102 @@ func TestRealExample(t *testing.T) {
}` }`
literals := []struct { literals := []struct {
token token.Token token TokenType
literal string literal string
}{ }{
{token.COMMENT, `// This comes from Terraform, as a test`}, {COMMENT, `// This comes from Terraform, as a test`},
{token.IDENT, `variable`}, {IDENT, `variable`},
{token.STRING, `"foo"`}, {STRING, `"foo"`},
{token.LBRACE, `{`}, {LBRACE, `{`},
{token.IDENT, `default`}, {IDENT, `default`},
{token.ASSIGN, `=`}, {ASSIGN, `=`},
{token.STRING, `"bar"`}, {STRING, `"bar"`},
{token.IDENT, `description`}, {IDENT, `description`},
{token.ASSIGN, `=`}, {ASSIGN, `=`},
{token.STRING, `"bar"`}, {STRING, `"bar"`},
{token.RBRACE, `}`}, {RBRACE, `}`},
{token.IDENT, `provider`}, {IDENT, `provider`},
{token.STRING, `"aws"`}, {STRING, `"aws"`},
{token.LBRACE, `{`}, {LBRACE, `{`},
{token.IDENT, `access_key`}, {IDENT, `access_key`},
{token.ASSIGN, `=`}, {ASSIGN, `=`},
{token.STRING, `"foo"`}, {STRING, `"foo"`},
{token.IDENT, `secret_key`}, {IDENT, `secret_key`},
{token.ASSIGN, `=`}, {ASSIGN, `=`},
{token.STRING, `"bar"`}, {STRING, `"bar"`},
{token.RBRACE, `}`}, {RBRACE, `}`},
{token.IDENT, `resource`}, {IDENT, `resource`},
{token.STRING, `"aws_security_group"`}, {STRING, `"aws_security_group"`},
{token.STRING, `"firewall"`}, {STRING, `"firewall"`},
{token.LBRACE, `{`}, {LBRACE, `{`},
{token.IDENT, `count`}, {IDENT, `count`},
{token.ASSIGN, `=`}, {ASSIGN, `=`},
{token.NUMBER, `5`}, {NUMBER, `5`},
{token.RBRACE, `}`}, {RBRACE, `}`},
{token.IDENT, `resource`}, {IDENT, `resource`},
{token.IDENT, `aws_instance`}, {IDENT, `aws_instance`},
{token.STRING, `"web"`}, {STRING, `"web"`},
{token.LBRACE, `{`}, {LBRACE, `{`},
{token.IDENT, `ami`}, {IDENT, `ami`},
{token.ASSIGN, `=`}, {ASSIGN, `=`},
{token.STRING, `"${var.foo}"`}, {STRING, `"${var.foo}"`},
{token.IDENT, `security_groups`}, {IDENT, `security_groups`},
{token.ASSIGN, `=`}, {ASSIGN, `=`},
{token.LBRACK, `[`}, {LBRACK, `[`},
{token.STRING, `"foo"`}, {STRING, `"foo"`},
{token.COMMA, `,`}, {COMMA, `,`},
{token.STRING, `"${aws_security_group.firewall.foo}"`}, {STRING, `"${aws_security_group.firewall.foo}"`},
{token.RBRACK, `]`}, {RBRACK, `]`},
{token.IDENT, `network_interface`}, {IDENT, `network_interface`},
{token.LBRACE, `{`}, {LBRACE, `{`},
{token.IDENT, `device_index`}, {IDENT, `device_index`},
{token.ASSIGN, `=`}, {ASSIGN, `=`},
{token.NUMBER, `0`}, {NUMBER, `0`},
{token.IDENT, `description`}, {IDENT, `description`},
{token.ASSIGN, `=`}, {ASSIGN, `=`},
{token.STRING, `"Main network interface"`}, {STRING, `"Main network interface"`},
{token.RBRACE, `}`}, {RBRACE, `}`},
{token.RBRACE, `}`}, {RBRACE, `}`},
{token.EOF, ``}, {EOF, ``},
} }
s := NewScanner([]byte(complexHCL)) s := NewScanner([]byte(complexHCL))
for _, l := range literals { for _, l := range literals {
tok := s.Scan() tok := s.Scan()
if l.token != tok { if l.token != tok.Type() {
t.Errorf("got: %s want %s for %s\n", tok, l.token, s.TokenText()) t.Errorf("got: %s want %s for %s\n", tok, l.token, tok.String())
} }
if l.literal != s.TokenText() { if l.literal != tok.String() {
t.Errorf("got: %s want %s\n", s.TokenText(), l.literal) t.Errorf("got: %s want %s\n", tok, l.literal)
} }
} }
} }
func TestError(t *testing.T) { func TestError(t *testing.T) {
testError(t, "\x80", "1:1", "illegal UTF-8 encoding", token.ILLEGAL) testError(t, "\x80", "1:1", "illegal UTF-8 encoding", ILLEGAL)
testError(t, "\xff", "1:1", "illegal UTF-8 encoding", token.ILLEGAL) testError(t, "\xff", "1:1", "illegal UTF-8 encoding", ILLEGAL)
testError(t, "ab\x80", "1:3", "illegal UTF-8 encoding", token.IDENT) testError(t, "ab\x80", "1:3", "illegal UTF-8 encoding", IDENT)
testError(t, "abc\xff", "1:4", "illegal UTF-8 encoding", token.IDENT) testError(t, "abc\xff", "1:4", "illegal UTF-8 encoding", IDENT)
testError(t, `"ab`+"\x80", "1:4", "illegal UTF-8 encoding", token.STRING) testError(t, `"ab`+"\x80", "1:4", "illegal UTF-8 encoding", STRING)
testError(t, `"abc`+"\xff", "1:5", "illegal UTF-8 encoding", token.STRING) testError(t, `"abc`+"\xff", "1:5", "illegal UTF-8 encoding", STRING)
testError(t, `01238`, "1:6", "illegal octal number", token.NUMBER) testError(t, `01238`, "1:6", "illegal octal number", NUMBER)
testError(t, `01238123`, "1:9", "illegal octal number", token.NUMBER) testError(t, `01238123`, "1:9", "illegal octal number", NUMBER)
testError(t, `0x`, "1:3", "illegal hexadecimal number", token.NUMBER) testError(t, `0x`, "1:3", "illegal hexadecimal number", NUMBER)
testError(t, `0xg`, "1:3", "illegal hexadecimal number", token.NUMBER) testError(t, `0xg`, "1:3", "illegal hexadecimal number", NUMBER)
testError(t, `'aa'`, "1:1", "illegal char", token.ILLEGAL) testError(t, `'aa'`, "1:1", "illegal char", ILLEGAL)
testError(t, `"`, "1:2", "literal not terminated", token.STRING) testError(t, `"`, "1:2", "literal not terminated", STRING)
testError(t, `"abc`, "1:5", "literal not terminated", token.STRING) testError(t, `"abc`, "1:5", "literal not terminated", STRING)
testError(t, `"abc`+"\n", "1:5", "literal not terminated", token.STRING) testError(t, `"abc`+"\n", "1:5", "literal not terminated", STRING)
testError(t, `/*/`, "1:4", "comment not terminated", token.COMMENT) testError(t, `/*/`, "1:4", "comment not terminated", COMMENT)
} }
func testError(t *testing.T, src, pos, msg string, tok token.Token) { func testError(t *testing.T, src, pos, msg string, tok TokenType) {
s := NewScanner([]byte(src)) s := NewScanner([]byte(src))
errorCalled := false errorCalled := false
@ -385,7 +383,7 @@ func testError(t *testing.T, src, pos, msg string, tok token.Token) {
} }
tk := s.Scan() tk := s.Scan()
if tk != tok { if tk.Type() != tok {
t.Errorf("tok = %s, want %s for %q", tk, tok, src) t.Errorf("tok = %s, want %s for %q", tk, tok, src)
} }
if !errorCalled { if !errorCalled {
@ -406,7 +404,7 @@ func testTokenList(t *testing.T, tokenList []tokenPair) {
s := NewScanner(buf.Bytes()) s := NewScanner(buf.Bytes())
for _, ident := range tokenList { for _, ident := range tokenList {
tok := s.Scan() tok := s.Scan()
if tok != ident.tok { if tok.Type() != ident.tok {
t.Errorf("tok = %q want %q for %q\n", tok, ident.tok, ident.text) t.Errorf("tok = %q want %q for %q\n", tok, ident.tok, ident.text)
} }

View File

@ -100,9 +100,9 @@ func (t Token) Pos() Position {
return t.pos return t.pos
} }
// Text retusn the token's literal text. Note that this is only // String returns the token's literal text. Note that this is only
// applicable for certain token types, such as token.IDENT, // applicable for certain token types, such as token.IDENT,
// token.STRING, etc.. // token.STRING, etc..
func (t Token) Text() string { func (t Token) String() string {
return t.text return t.text
} }