Files
masonry/lang/parser_ui_page_test.go

301 lines
6.8 KiB
Go

package lang
import (
"testing"
)
func TestParsePageDefinitions(t *testing.T) {
tests := []struct {
name string
input string
want AST
wantErr bool
}{
{
name: "basic page with minimal fields",
input: `page Dashboard at "/dashboard" layout main`,
want: AST{
Definitions: []Definition{
{
Page: &Page{
Name: "Dashboard",
Path: "/dashboard",
Layout: "main",
},
},
},
},
},
{
name: "page with all optional fields",
input: `page UserProfile at "/profile" layout main title "User Profile" desc "Manage user profile settings" auth`,
want: AST{
Definitions: []Definition{
{
Page: &Page{
Name: "UserProfile",
Path: "/profile",
Layout: "main",
Title: stringPtr("User Profile"),
Description: stringPtr("Manage user profile settings"),
Auth: true,
},
},
},
},
},
{
name: "page with meta tags",
input: `page HomePage at "/" layout main {
meta description "Welcome to our application"
meta keywords "app, dashboard, management"
}`,
want: AST{
Definitions: []Definition{
{
Page: &Page{
Name: "HomePage",
Path: "/",
Layout: "main",
Meta: []MetaTag{
{Name: "description", Content: "Welcome to our application"},
{Name: "keywords", Content: "app, dashboard, management"},
},
},
},
},
},
},
{
name: "page with nested sections",
input: `page Settings at "/settings" layout main {
section tabs type tab {
section profile label "Profile" active {
component form for User {
field name type text
}
}
section security label "Security" {
component form for User {
field password type password
}
}
}
}`,
want: AST{
Definitions: []Definition{
{
Page: &Page{
Name: "Settings",
Path: "/settings",
Layout: "main",
Sections: []Section{
{
Name: "tabs",
Type: stringPtr("tab"),
Elements: []SectionElement{
{
Section: &Section{
Name: "profile",
Label: stringPtr("Profile"),
Active: true,
Elements: []SectionElement{
{
Component: &Component{
Type: "form",
Entity: stringPtr("User"),
Elements: []ComponentElement{
{
Field: &ComponentField{
Name: "name",
Type: "text",
},
},
},
},
},
},
},
},
{
Section: &Section{
Name: "security",
Label: stringPtr("Security"),
Elements: []SectionElement{
{
Component: &Component{
Type: "form",
Entity: stringPtr("User"),
Elements: []ComponentElement{
{
Field: &ComponentField{
Name: "password",
Type: "password",
},
},
},
},
},
},
},
},
},
},
},
},
},
},
},
},
{
name: "page with modal and panel sections",
input: `page ProductList at "/products" layout main {
section main type container {
component table for Product
}
section editModal type modal trigger "edit-product" {
component form for Product {
field name type text required
button save label "Save Changes" style "primary"
}
}
section filters type panel position "left" {
component form {
field category type select
field price_range type range
}
}
}`,
want: AST{
Definitions: []Definition{
{
Page: &Page{
Name: "ProductList",
Path: "/products",
Layout: "main",
Sections: []Section{
{
Name: "main",
Type: stringPtr("container"),
Elements: []SectionElement{
{
Component: &Component{
Type: "table",
Entity: stringPtr("Product"),
},
},
},
},
{
Name: "editModal",
Type: stringPtr("modal"),
Trigger: stringPtr("edit-product"),
Elements: []SectionElement{
{
Component: &Component{
Type: "form",
Entity: stringPtr("Product"),
Elements: []ComponentElement{
{
Field: &ComponentField{
Name: "name",
Type: "text",
Attributes: []ComponentFieldAttribute{
{Required: true},
},
},
},
{
Button: &ComponentButton{
Name: "save",
Label: "Save Changes",
Attributes: []ComponentButtonAttr{
{Style: &ComponentButtonStyle{Value: "primary"}},
},
},
},
},
},
},
},
},
{
Name: "filters",
Type: stringPtr("panel"),
Position: stringPtr("left"),
Elements: []SectionElement{
{
Component: &Component{
Type: "form",
Elements: []ComponentElement{
{
Field: &ComponentField{
Name: "category",
Type: "select",
},
},
{
Field: &ComponentField{
Name: "price_range",
Type: "range",
},
},
},
},
},
},
},
},
},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := ParseInput(tt.input)
if (err != nil) != tt.wantErr {
t.Errorf("ParseInput() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !astEqual(got, tt.want) {
t.Errorf("ParseInput() got = %v, want %v", got, tt.want)
}
})
}
}
func TestParsePageErrors(t *testing.T) {
tests := []struct {
name string
input string
}{
{
name: "missing layout",
input: `page Dashboard at "/dashboard"`,
},
{
name: "missing path",
input: `page Dashboard layout main`,
},
{
name: "invalid path format",
input: `page Dashboard at dashboard layout main`,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, err := ParseInput(tt.input)
if err == nil {
t.Errorf("ParseInput() expected error for invalid syntax, got nil")
}
})
}
}