Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1871)

Unified Diff: mojom/mojom_parser/lexer/lexer_test.go

Issue 1387893002: New lexer for mojom written in go. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « mojom/mojom_parser/lexer/lexer.go ('k') | mojom/mojom_parser/lexer/token_stream.go » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: mojom/mojom_parser/lexer/lexer_test.go
diff --git a/mojom/mojom_parser/lexer/lexer_test.go b/mojom/mojom_parser/lexer/lexer_test.go
index 1b378a77bbc61b8f178c6843d37b198ebc079c20..19f9aae6e4caebd3f7d90bbc002bd54aac947cd3 100644
--- a/mojom/mojom_parser/lexer/lexer_test.go
+++ b/mojom/mojom_parser/lexer/lexer_test.go
@@ -6,10 +6,207 @@ package lexer
import "testing"
-// TODO(rudominer) This dummy test is here in order to be able to test the
-// go unit test infrastructure. It will eventually be replaced by a real test.
-func TestDummyLexerTest(t *testing.T) {
- if 5.1 > 2.1*3.1 {
- t.Fatalf("Something is wrong.")
+func checkEq(t *testing.T, expected, actual interface{}) {
+ if expected != actual {
+ t.Fatalf("Failed check: Expected (%v), Actual (%v)", expected, actual)
}
}
+
+// pumpTokens pumps all the tokens from a channel into a slice.
+func pumpTokens(tokensChan chan Token) []Token {
+ tokens := []Token{}
+ for token := range tokensChan {
+ tokens = append(tokens, token)
+ }
+ return tokens
+}
+
+// TestAllSingleTokens tests for each token that a valid string is accepted as
+// the correct token.
+func TestAllSingleTokens(t *testing.T) {
+ testData := []struct {
+ source string
+ token TokenKind
+ }{
+ {"(", LParen},
+ {")", RParen},
+ {"[", LBracket},
+ {"]", RBracket},
+ {"{", LBrace},
+ {"}", RBrace},
+ {"<", LAngle},
+ {">", RAngle},
+ {";", Semi},
+ {",", Comma},
+ {".", Dot},
+ {"-", Minus},
+ {"+", Plus},
+ {"&", Amp},
+ {"?", Qstn},
+ {"=", Equals},
+ {"=>", Response},
+ {"somet_hi3ng", Name},
+ {"import", Import},
+ {"module", Module},
+ {"struct", Struct},
+ {"union", Union},
+ {"interface", Interface},
+ {"enum", Enum},
+ {"const", Const},
+ {"true", True},
+ {"false", False},
+ {"default", Default},
+ {"@10", Ordinal},
+ {"10", IntConstDec},
+ {"0", IntConstDec},
+ {"0xA10", IntConstHex},
+ {"0xa10", IntConstHex},
+ {"0XA10", IntConstHex},
+ {"0Xa10", IntConstHex},
+ {"10.5", FloatConst},
+ {"10e5", FloatConst},
+ {"0.5", FloatConst},
+ {"0e5", FloatConst},
+ {"10e+5", FloatConst},
+ {"10e-5", FloatConst},
+ {"\"hello world\"", StringLiteral},
+ {"\"hello \\\"real\\\" world\"", StringLiteral},
+ }
+
+ for i := range testData {
+ l := lexer{source: testData[i].source, tokens: make(chan Token)}
+ go l.run()
+ tokens := pumpTokens(l.tokens)
+
+ if len(tokens) != 1 {
+ t.Fatalf("Source('%v'): Expected 1 token but got %v instead: %v",
+ testData[i].source, len(tokens), tokens)
+ }
+
+ checkEq(t, testData[i].source, tokens[0].Text)
+ checkEq(t, testData[i].token, tokens[0].Kind)
+ }
+}
+
+// TestTokenPosition tests that the position in the source string, the line
+// number and the position in the line of the lexed token are correctly found.
+func TestTokenPosition(t *testing.T) {
+ source := " \n ."
+ l := lexer{source: source, tokens: make(chan Token)}
+ go l.run()
+ tokens := pumpTokens(l.tokens)
+ token := tokens[0]
+
+ checkEq(t, 5, token.CharPos)
+ checkEq(t, 1, token.LineNo)
+ checkEq(t, 2, token.LinePos)
+}
+
+// TestTokenPositionChineseString tests that CharPos is expressed as a number
+// of runes and not a number of bytes.
+func TestTokenPositionChineseString(t *testing.T) {
+ source := "\"您好\" is"
+ ts := Tokenize(source)
+ checkEq(t, StringLiteral, ts.PeekNext().Kind)
+ ts.ConsumeNext()
+ checkEq(t, 5, ts.PeekNext().CharPos)
+}
+
+// TestSkipSkippable tests that all skippable characters are skipped.
+func TestSkipSkippable(t *testing.T) {
+ source := " \t \r \n ."
+ l := lexer{source: source, tokens: make(chan Token)}
+ go l.run()
+ tokens := pumpTokens(l.tokens)
+
+ checkEq(t, Dot, tokens[0].Kind)
+}
+
+// TestTokenize tests that a single token embedded in a larger string is
+// correctly lexed.
+func TestTokenize(t *testing.T) {
+ ts := Tokenize(" \t . ")
+ token := ts.PeekNext()
+ checkEq(t, Dot, token.Kind)
+
+ ts.ConsumeNext()
+ token = ts.PeekNext()
+ checkEq(t, EOF, token.Kind)
+}
+
+// TestTokenizeBadUTF8String tests that an invalid UTF8 string is handled.
+func TestTokenizeBadUTF8String(t *testing.T) {
+ ts := Tokenize("\xF0")
+ checkEq(t, ErrorIllegalChar, ts.PeekNext().Kind)
+}
+
+// TestTokenizeEmptyString tests that empty strings are handled correctly.
+func TestTokenizeEmptyString(t *testing.T) {
+ ts := Tokenize("")
+ checkEq(t, EOF, ts.PeekNext().Kind)
+}
+
+// TestTokenizeMoreThanOne tests that more than one token is correctly lexed.
+func TestTokenizeMoreThanOne(t *testing.T) {
+ ts := Tokenize("()")
+ checkEq(t, LParen, ts.PeekNext().Kind)
+ ts.ConsumeNext()
+ checkEq(t, RParen, ts.PeekNext().Kind)
+ ts.ConsumeNext()
+ checkEq(t, EOF, ts.PeekNext().Kind)
+}
+
+// TestIllegalChar tests that an illegal character is correctly spotted.
+func TestIllegalChar(t *testing.T) {
+ ts := Tokenize(" \t $ ")
+ checkEq(t, ErrorIllegalChar, ts.PeekNext().Kind)
+}
+
+// TestUnterminatedStringLiteralEos tests that the correct error is emitted if
+// a quoted string is never closed.
+func TestUnterminatedStringLiteralEos(t *testing.T) {
+ ts := Tokenize("\"hello world")
+ checkEq(t, ErrorUnterminatedStringLiteral, ts.PeekNext().Kind)
+}
+
+// TestUnterminatedStringLiteralEol tests that the correct error is emitted if
+// a quoted string is closed on a subsequent line.
+func TestUnterminatedStringLiteralEol(t *testing.T) {
+ ts := Tokenize("\"hello\n world\"")
+ checkEq(t, ErrorUnterminatedStringLiteral, ts.PeekNext().Kind)
+}
+
+// TestSingleLineComment tests that single line comments are correctly skipped.
+func TestSingleLineComment(t *testing.T) {
+ ts := Tokenize("( // some stuff\n)")
+ checkEq(t, LParen, ts.PeekNext().Kind)
+ ts.ConsumeNext()
+ checkEq(t, RParen, ts.PeekNext().Kind)
+}
+
+// TestMultiLineComment tests that multi line comments are correctly skipped.
+func TestMultiLineComment(t *testing.T) {
+ ts := Tokenize("( /* hello world/ * *\n */)")
+ checkEq(t, LParen, ts.PeekNext().Kind)
+ ts.ConsumeNext()
+ checkEq(t, RParen, ts.PeekNext().Kind)
+}
+
+// TestUnterminatedMultiLineComment tests that unterminated multiline comments
+// emit the correct error.
+func TestUnterminatedMultiLineComment(t *testing.T) {
+ ts := Tokenize("( /* hello world/ * *\n )")
+ checkEq(t, LParen, ts.PeekNext().Kind)
+ ts.ConsumeNext()
+ checkEq(t, ErrorUnterminatedComment, ts.PeekNext().Kind)
+}
+
+// TestUnterminatedMultiLineCommentAtStar tests that if the string ends at a *
+// (which could be the beginning of the close of a multiline comment) the right
+// error is emitted.
+func TestUnterminatedMultiLineCommentAtStar(t *testing.T) {
+ ts := Tokenize("( /* hello world/ *")
+ checkEq(t, LParen, ts.PeekNext().Kind)
+ ts.ConsumeNext()
+ checkEq(t, ErrorUnterminatedComment, ts.PeekNext().Kind)
+}
« no previous file with comments | « mojom/mojom_parser/lexer/lexer.go ('k') | mojom/mojom_parser/lexer/token_stream.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698