package interpreter import ( "masonry/lang" "testing" ) func TestGetIteratorItems(t *testing.T) { // Create a test AST with nested sections and components ast := createTestAST() interpreter := NewTemplateInterpreter() // Test pages iterator t.Run("pages iterator", func(t *testing.T) { items := interpreter.getIteratorItems("pages", ast) if len(items) != 2 { t.Errorf("Expected 2 pages, got %d", len(items)) } page1 := items[0].(*lang.Page) if page1.Name != "HomePage" { t.Errorf("Expected page name 'HomePage', got '%s'", page1.Name) } }) // Test entities iterator t.Run("entities iterator", func(t *testing.T) { items := interpreter.getIteratorItems("entities", ast) if len(items) != 1 { t.Errorf("Expected 1 entity, got %d", len(items)) } entity := items[0].(*lang.Entity) if entity.Name != "User" { t.Errorf("Expected entity name 'User', got '%s'", entity.Name) } }) // Test endpoints iterator t.Run("endpoints iterator", func(t *testing.T) { items := interpreter.getIteratorItems("endpoints", ast) if len(items) != 1 { t.Errorf("Expected 1 endpoint, got %d", len(items)) } endpoint := items[0].(*lang.Endpoint) if endpoint.Method != "GET" { t.Errorf("Expected endpoint method 'GET', got '%s'", endpoint.Method) } }) // Test servers iterator t.Run("servers iterator", func(t *testing.T) { items := interpreter.getIteratorItems("servers", ast) if len(items) != 1 { t.Errorf("Expected 1 server, got %d", len(items)) } server := items[0].(*lang.Server) if server.Name != "api" { t.Errorf("Expected server name 'api', got '%s'", server.Name) } }) // Test sections iterator - should find all nested sections t.Run("sections iterator", func(t *testing.T) { items := interpreter.getIteratorItems("sections", ast) // Expected sections: // - HomePage: hero, content // - AdminPage: dashboard // - hero has nested: banner // - content has nested: sidebar // Total: 5 sections (hero, content, banner, sidebar, dashboard) expectedCount := 5 if len(items) != expectedCount { t.Errorf("Expected %d sections, got %d", expectedCount, len(items)) // Print section names for debugging for i, item := range items { section := item.(*lang.Section) t.Logf("Section %d: %s", i, section.Name) } } // Check that we have the expected section names sectionNames := make(map[string]bool) for _, item := range items { section := item.(*lang.Section) sectionNames[section.Name] = true } expectedSections := []string{"hero", "content", "banner", "sidebar", "dashboard"} for _, expected := range expectedSections { if !sectionNames[expected] { t.Errorf("Expected to find section '%s' but didn't", expected) } } }) // Test components iterator - should find all nested components t.Run("components iterator", func(t *testing.T) { items := interpreter.getIteratorItems("components", ast) // Expected components: // - HomePage direct: header, footer // - In hero section: carousel // - In content section: article // - In sidebar section: widget // Total: 5 components expectedCount := 5 if len(items) != expectedCount { t.Errorf("Expected %d components, got %d", expectedCount, len(items)) // Print component types for debugging for i, item := range items { component := item.(*lang.Component) t.Logf("Component %d: %s", i, component.Type) } } // Check that we have the expected component types componentTypes := make(map[string]bool) for _, item := range items { component := item.(*lang.Component) componentTypes[component.Type] = true } expectedComponents := []string{"header", "footer", "carousel", "article", "widget"} for _, expected := range expectedComponents { if !componentTypes[expected] { t.Errorf("Expected to find component type '%s' but didn't", expected) } } }) // Test unknown iterator t.Run("unknown iterator", func(t *testing.T) { items := interpreter.getIteratorItems("unknown", ast) if len(items) != 0 { t.Errorf("Expected 0 items for unknown iterator, got %d", len(items)) } }) } // createTestAST creates a complex test AST with nested sections and components func createTestAST() lang.AST { // Helper function to create string pointers strPtr := func(s string) *string { return &s } return lang.AST{ Definitions: []lang.Definition{ // Server definition { Server: &lang.Server{ Name: "api", Settings: []lang.ServerSetting{ { Host: &lang.ConfigValue{ Literal: strPtr("localhost"), }, }, }, }, }, // Entity definition { Entity: &lang.Entity{ Name: "User", Fields: []lang.Field{ { Name: "name", Type: "string", }, }, }, }, // Endpoint definition { Endpoint: &lang.Endpoint{ Method: "GET", Path: "/api/users", }, }, // HomePage with nested sections and components { Page: &lang.Page{ Name: "HomePage", Path: "/", Layout: "public", Elements: []lang.PageElement{ { Component: &lang.Component{ Type: "header", }, }, { Component: &lang.Component{ Type: "footer", }, }, { Section: &lang.Section{ Name: "hero", Type: strPtr("container"), Elements: []lang.SectionElement{ { Component: &lang.Component{ Type: "carousel", }, }, { Section: &lang.Section{ Name: "banner", Type: strPtr("panel"), }, }, }, }, }, { Section: &lang.Section{ Name: "content", Type: strPtr("container"), Elements: []lang.SectionElement{ { Component: &lang.Component{ Type: "article", }, }, { Section: &lang.Section{ Name: "sidebar", Type: strPtr("panel"), Elements: []lang.SectionElement{ { Component: &lang.Component{ Type: "widget", }, }, }, }, }, }, }, }, }, }, }, // AdminPage with simpler structure { Page: &lang.Page{ Name: "AdminPage", Path: "/admin", Layout: "admin", Elements: []lang.PageElement{ { Section: &lang.Section{ Name: "dashboard", Type: strPtr("container"), }, }, }, }, }, }, } }