package codegen import ( "strings" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestGenerateClass_Good(t *testing.T) { js, err := GenerateClass("photo-grid", "C") require.NoError(t, err) assert.Contains(t, js, "class PhotoGrid extends HTMLElement") assert.Contains(t, js, "attachShadow") assert.Contains(t, js, `mode: "closed"`) assert.Contains(t, js, "photo-grid") } func TestGenerateClass_Bad_InvalidTag(t *testing.T) { _, err := GenerateClass("invalid", "C") assert.Error(t, err, "custom element names must contain a hyphen") _, err = GenerateClass("Nav-Bar", "C") assert.Error(t, err, "custom element names must be lowercase") _, err = GenerateClass("nav bar", "C") assert.Error(t, err, "custom element names must reject spaces") } func TestGenerateRegistration_Good(t *testing.T) { js := GenerateRegistration("photo-grid", "PhotoGrid") assert.Contains(t, js, "customElements.define") assert.Contains(t, js, `"photo-grid"`) assert.Contains(t, js, "PhotoGrid") } func TestTagToClassName_Good(t *testing.T) { tests := []struct{ tag, want string }{ {"photo-grid", "PhotoGrid"}, {"nav-breadcrumb", "NavBreadcrumb"}, {"my-super-widget", "MySuperWidget"}, } for _, tt := range tests { got := TagToClassName(tt.tag) assert.Equal(t, tt.want, got, "TagToClassName(%q)", tt.tag) } } func TestGenerateBundle_Good(t *testing.T) { slots := map[string]string{ "C": "main-content", "H": "nav-bar", "F": "page-footer", } js, err := GenerateBundle(slots) require.NoError(t, err) assert.Contains(t, js, "NavBar") assert.Contains(t, js, "MainContent") assert.Contains(t, js, "PageFooter") assert.Equal(t, 3, strings.Count(js, "extends HTMLElement")) h := strings.Index(js, "NavBar") c := strings.Index(js, "MainContent") f := strings.Index(js, "PageFooter") assert.True(t, h >= 0 && c >= 0 && f >= 0, "expected all generated classes in output") assert.True(t, h < c && c < f, "expected canonical HLCRF order in generated bundle") } func TestGenerateBundle_DeduplicatesTags(t *testing.T) { slots := map[string]string{ "H": "nav-bar", "C": "nav-bar", "F": "page-footer", } js, err := GenerateBundle(slots) require.NoError(t, err) assert.Equal(t, 2, strings.Count(js, "extends HTMLElement")) assert.Equal(t, 1, strings.Count(js, "class NavBar extends HTMLElement")) assert.Equal(t, 1, strings.Count(js, "class PageFooter extends HTMLElement")) } func TestGenerateBundle_Bad_InvalidSlotKey(t *testing.T) { slots := map[string]string{ "H": "nav-bar", "X": "custom-widget", } _, err := GenerateBundle(slots) require.Error(t, err) assert.Contains(t, err.Error(), "invalid slot key") assert.Contains(t, err.Error(), `"X"`) } func TestGenerateTypeDefinitions_Good(t *testing.T) { slots := map[string]string{ "H": "nav-bar", "C": "main-content", } dts, err := GenerateTypeDefinitions(slots) require.NoError(t, err) assert.Contains(t, dts, "declare global") assert.Contains(t, dts, "interface WcReadyDetail") assert.Contains(t, dts, `interface HTMLElementEventMap`) assert.Contains(t, dts, `"wc-ready": CustomEvent;`) assert.Contains(t, dts, "export declare class NavBar extends HTMLElement") assert.Contains(t, dts, "export declare class MainContent extends HTMLElement") assert.Contains(t, dts, `"nav-bar": NavBar;`) assert.Contains(t, dts, `"main-content": MainContent;`) assert.Contains(t, dts, "export {};") } func TestGenerateTypeDefinitions_DeduplicatesTags(t *testing.T) { slots := map[string]string{ "H": "nav-bar", "C": "nav-bar", "F": "page-footer", } dts, err := GenerateTypeDefinitions(slots) require.NoError(t, err) assert.Equal(t, 2, strings.Count(dts, "extends HTMLElement")) assert.Equal(t, 1, strings.Count(dts, `"nav-bar": NavBar;`)) assert.Equal(t, 1, strings.Count(dts, `"page-footer": PageFooter;`)) } func TestGenerateTypeDefinitions_SkipsInvalidTags(t *testing.T) { slots := map[string]string{ "H": "nav-bar", "C": "Nav-Bar", "F": "nav bar", } dts, err := GenerateTypeDefinitions(slots) require.NoError(t, err) assert.Contains(t, dts, `"nav-bar": NavBar;`) assert.NotContains(t, dts, "Nav-Bar") assert.NotContains(t, dts, "nav bar") assert.Equal(t, 1, strings.Count(dts, "extends HTMLElement")) }