Add js web stuff to landing page + documentation
This commit is contained in:
116
go/jsbundler/compile_solid_test.go
Normal file
116
go/jsbundler/compile_solid_test.go
Normal file
@@ -0,0 +1,116 @@
|
||||
package jsbundler
|
||||
|
||||
import "testing"
|
||||
|
||||
// parseOne parses a single JSX element starting at the first '<'.
|
||||
func parseOne(t *testing.T, src string) jsxNode {
|
||||
t.Helper()
|
||||
i := 0
|
||||
for i < len(src) && src[i] != '<' {
|
||||
i++
|
||||
}
|
||||
node, next, err := parseJSX(src, i)
|
||||
if err != nil {
|
||||
t.Fatalf("parseJSX(%q): %v", src, err)
|
||||
}
|
||||
if next != len(src) {
|
||||
t.Fatalf("parseJSX(%q): consumed to %d, want %d (trailing %q)", src, next, len(src), src[next:])
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
func TestParseStaticElement(t *testing.T) {
|
||||
n := parseOne(t, `<div class="x">hi</div>`)
|
||||
if n.kind != jsxElement || n.tag != "div" {
|
||||
t.Fatalf("kind/tag = %d/%q", n.kind, n.tag)
|
||||
}
|
||||
if len(n.attrs) != 1 || n.attrs[0].kind != attrStatic || n.attrs[0].name != "class" || n.attrs[0].value != "x" {
|
||||
t.Fatalf("attrs = %+v", n.attrs)
|
||||
}
|
||||
if len(n.children) != 1 || n.children[0].kind != jsxText || n.children[0].text != "hi" {
|
||||
t.Fatalf("children = %+v", n.children)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseComponent(t *testing.T) {
|
||||
n := parseOne(t, `<Foo bar={1}>child</Foo>`)
|
||||
if n.kind != jsxComponent || n.tag != "Foo" {
|
||||
t.Fatalf("kind/tag = %d/%q", n.kind, n.tag)
|
||||
}
|
||||
if len(n.attrs) != 1 || n.attrs[0].kind != attrExpr || n.attrs[0].name != "bar" || n.attrs[0].expr != "1" {
|
||||
t.Fatalf("attrs = %+v", n.attrs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseNested(t *testing.T) {
|
||||
n := parseOne(t, `<div><span>a</span><b>{x()}</b></div>`)
|
||||
if len(n.children) != 2 {
|
||||
t.Fatalf("want 2 element children, got %d: %+v", len(n.children), n.children)
|
||||
}
|
||||
if n.children[0].tag != "span" || n.children[1].tag != "b" {
|
||||
t.Fatalf("child tags = %q, %q", n.children[0].tag, n.children[1].tag)
|
||||
}
|
||||
b := n.children[1]
|
||||
if len(b.children) != 1 || b.children[0].kind != jsxExpr || b.children[0].expr != "x()" {
|
||||
t.Fatalf("b children = %+v", b.children)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseFragment(t *testing.T) {
|
||||
n := parseOne(t, `<>{a()}{b()}</>`)
|
||||
if n.kind != jsxFragment || len(n.children) != 2 {
|
||||
t.Fatalf("fragment: kind=%d children=%d", n.kind, len(n.children))
|
||||
}
|
||||
if n.children[0].expr != "a()" || n.children[1].expr != "b()" {
|
||||
t.Fatalf("fragment children = %+v", n.children)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseSelfCloseAndBool(t *testing.T) {
|
||||
n := parseOne(t, `<input disabled type="text" />`)
|
||||
if n.tag != "input" || len(n.children) != 0 {
|
||||
t.Fatalf("input: tag=%q children=%d", n.tag, len(n.children))
|
||||
}
|
||||
if len(n.attrs) != 2 || !n.attrs[0].boolt || n.attrs[0].name != "disabled" {
|
||||
t.Fatalf("attrs = %+v", n.attrs)
|
||||
}
|
||||
if n.attrs[1].name != "type" || n.attrs[1].value != "text" {
|
||||
t.Fatalf("type attr = %+v", n.attrs[1])
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseSpread(t *testing.T) {
|
||||
n := parseOne(t, `<div {...p} class="x">hi</div>`)
|
||||
if len(n.attrs) != 2 || n.attrs[0].kind != attrSpread || n.attrs[0].expr != "p" {
|
||||
t.Fatalf("attrs = %+v", n.attrs)
|
||||
}
|
||||
}
|
||||
|
||||
// The hardest case: an expression child containing nested JSX AND braces inside
|
||||
// strings/templates. The parser must capture the whole expression opaquely.
|
||||
func TestParseExprWithNestedJSX(t *testing.T) {
|
||||
n := parseOne(t, "<ul>{items.map((x) => <li>{x}</li>)}</ul>")
|
||||
if len(n.children) != 1 || n.children[0].kind != jsxExpr {
|
||||
t.Fatalf("children = %+v", n.children)
|
||||
}
|
||||
if n.children[0].expr != "items.map((x) => <li>{x}</li>)" {
|
||||
t.Fatalf("expr = %q", n.children[0].expr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCaptureBracesLexer(t *testing.T) {
|
||||
cases := []struct{ in, want string }{
|
||||
{`{a + "}" + b}`, `a + "}" + b`},
|
||||
{"{`a${nested}b`}", "`a${nested}b`"},
|
||||
{`{ {k: 1} }`, ` {k: 1} `},
|
||||
{`{f(/[}]/)}`, `f(/[}]/)`},
|
||||
{`{x} rest`, `x`},
|
||||
}
|
||||
for _, c := range cases {
|
||||
got, next := captureBraces(c.in, 0)
|
||||
if got != c.want {
|
||||
t.Errorf("captureBraces(%q) = %q, want %q", c.in, got, c.want)
|
||||
}
|
||||
_ = next
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user