mirror of
https://github.com/zhigang1992/esbuild.git
synced 2026-01-12 22:46:54 +08:00
145 lines
5.0 KiB
Go
145 lines
5.0 KiB
Go
package css_lexer
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/evanw/esbuild/internal/logger"
|
|
"github.com/evanw/esbuild/internal/test"
|
|
)
|
|
|
|
func lexToken(contents string) (T, string) {
|
|
log := logger.NewDeferLog()
|
|
tokens := Tokenize(log, test.SourceForTest(contents))
|
|
if len(tokens) > 0 {
|
|
t := tokens[0]
|
|
return t.Kind, t.DecodedText(contents)
|
|
}
|
|
return TEndOfFile, ""
|
|
}
|
|
|
|
func lexerError(contents string) string {
|
|
log := logger.NewDeferLog()
|
|
Tokenize(log, test.SourceForTest(contents))
|
|
text := ""
|
|
for _, msg := range log.Done() {
|
|
text += msg.String(logger.OutputOptions{}, logger.TerminalInfo{})
|
|
}
|
|
return text
|
|
}
|
|
|
|
func TestTokens(t *testing.T) {
|
|
expected := []struct {
|
|
contents string
|
|
token T
|
|
text string
|
|
}{
|
|
{"", TEndOfFile, "end of file"},
|
|
{"@media", TAtKeyword, "@-keyword"},
|
|
{"url(x y", TBadURL, "bad URL token"},
|
|
{"-->", TCDC, "\"-->\""},
|
|
{"<!--", TCDO, "\"<!--\""},
|
|
{"}", TCloseBrace, "\"}\""},
|
|
{"]", TCloseBracket, "\"]\""},
|
|
{")", TCloseParen, "\")\""},
|
|
{":", TColon, "\":\""},
|
|
{",", TComma, "\",\""},
|
|
{"?", TDelim, "delimiter"},
|
|
{"&", TDelimAmpersand, "\"&\""},
|
|
{"*", TDelimAsterisk, "\"*\""},
|
|
{"|", TDelimBar, "\"|\""},
|
|
{"^", TDelimCaret, "\"^\""},
|
|
{"$", TDelimDollar, "\"$\""},
|
|
{".", TDelimDot, "\".\""},
|
|
{"=", TDelimEquals, "\"=\""},
|
|
{"!", TDelimExclamation, "\"!\""},
|
|
{">", TDelimGreaterThan, "\">\""},
|
|
{"+", TDelimPlus, "\"+\""},
|
|
{"/", TDelimSlash, "\"/\""},
|
|
{"~", TDelimTilde, "\"~\""},
|
|
{"1px", TDimension, "dimension"},
|
|
{"max(", TFunction, "function token"},
|
|
{"#name", THash, "hash token"},
|
|
{"name", TIdent, "identifier"},
|
|
{"123", TNumber, "number"},
|
|
{"{", TOpenBrace, "\"{\""},
|
|
{"[", TOpenBracket, "\"[\""},
|
|
{"(", TOpenParen, "\"(\""},
|
|
{"50%", TPercentage, "percentage"},
|
|
{";", TSemicolon, "\";\""},
|
|
{"'abc'", TString, "string token"},
|
|
{"url(test)", TURL, "URL token"},
|
|
{" ", TWhitespace, "whitespace"},
|
|
}
|
|
|
|
for _, it := range expected {
|
|
contents := it.contents
|
|
token := it.token
|
|
t.Run(contents, func(t *testing.T) {
|
|
kind, _ := lexToken(contents)
|
|
test.AssertEqual(t, kind, token)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestStringParsing(t *testing.T) {
|
|
contentsOfStringToken := func(contents string) string {
|
|
t.Helper()
|
|
kind, text := lexToken(contents)
|
|
test.AssertEqual(t, kind, TString)
|
|
return text
|
|
}
|
|
test.AssertEqual(t, contentsOfStringToken("\"foo\""), "foo")
|
|
test.AssertEqual(t, contentsOfStringToken("\"f\\oo\""), "foo")
|
|
test.AssertEqual(t, contentsOfStringToken("\"f\\\"o\""), "f\"o")
|
|
test.AssertEqual(t, contentsOfStringToken("\"f\\\\o\""), "f\\o")
|
|
test.AssertEqual(t, contentsOfStringToken("\"f\\\no\""), "fo")
|
|
test.AssertEqual(t, contentsOfStringToken("\"f\\\ro\""), "fo")
|
|
test.AssertEqual(t, contentsOfStringToken("\"f\\\r\no\""), "fo")
|
|
test.AssertEqual(t, contentsOfStringToken("\"f\\\fo\""), "fo")
|
|
test.AssertEqual(t, contentsOfStringToken("\"f\\6fo\""), "foo")
|
|
test.AssertEqual(t, contentsOfStringToken("\"f\\6f o\""), "foo")
|
|
test.AssertEqual(t, contentsOfStringToken("\"f\\6f o\""), "fo o")
|
|
test.AssertEqual(t, contentsOfStringToken("\"f\\fffffffo\""), "f\uFFFDfo")
|
|
test.AssertEqual(t, contentsOfStringToken("\"f\\10abcdeo\""), "f\U0010ABCDeo")
|
|
}
|
|
|
|
func TestURLParsing(t *testing.T) {
|
|
contentsOfURLToken := func(expected T, contents string) string {
|
|
t.Helper()
|
|
kind, text := lexToken(contents)
|
|
test.AssertEqual(t, kind, expected)
|
|
return text
|
|
}
|
|
test.AssertEqual(t, contentsOfURLToken(TURL, "url(foo)"), "foo")
|
|
test.AssertEqual(t, contentsOfURLToken(TURL, "url( foo\t\t)"), "foo")
|
|
test.AssertEqual(t, contentsOfURLToken(TURL, "url(f\\oo)"), "foo")
|
|
test.AssertEqual(t, contentsOfURLToken(TURL, "url(f\\\"o)"), "f\"o")
|
|
test.AssertEqual(t, contentsOfURLToken(TURL, "url(f\\'o)"), "f'o")
|
|
test.AssertEqual(t, contentsOfURLToken(TURL, "url(f\\)o)"), "f)o")
|
|
test.AssertEqual(t, contentsOfURLToken(TURL, "url(f\\6fo)"), "foo")
|
|
test.AssertEqual(t, contentsOfURLToken(TURL, "url(f\\6f o)"), "foo")
|
|
test.AssertEqual(t, contentsOfURLToken(TBadURL, "url(f\\6f o)"), "url(f\\6f o)")
|
|
}
|
|
|
|
func TestComment(t *testing.T) {
|
|
test.AssertEqual(t, lexerError("/*"), "<stdin>: error: Expected \"*/\" to terminate multi-line comment\n<stdin>: note: The multi-line comment starts here\n")
|
|
test.AssertEqual(t, lexerError("/*/"), "<stdin>: error: Expected \"*/\" to terminate multi-line comment\n<stdin>: note: The multi-line comment starts here\n")
|
|
test.AssertEqual(t, lexerError("/**/"), "")
|
|
test.AssertEqual(t, lexerError("//"), "<stdin>: warning: Comments in CSS use \"/* ... */\" instead of \"//\"\n")
|
|
}
|
|
|
|
func TestString(t *testing.T) {
|
|
test.AssertEqual(t, lexerError("'"), "<stdin>: error: Unterminated string token\n")
|
|
test.AssertEqual(t, lexerError("\""), "<stdin>: error: Unterminated string token\n")
|
|
test.AssertEqual(t, lexerError("'\\'"), "<stdin>: error: Unterminated string token\n")
|
|
test.AssertEqual(t, lexerError("\"\\\""), "<stdin>: error: Unterminated string token\n")
|
|
test.AssertEqual(t, lexerError("''"), "")
|
|
test.AssertEqual(t, lexerError("\"\""), "")
|
|
}
|
|
|
|
func TestBOM(t *testing.T) {
|
|
// A byte order mark should not be parsed as an identifier
|
|
kind, _ := lexToken("\uFEFF.")
|
|
test.AssertEqual(t, kind, TDelimDot)
|
|
}
|