2026-03-26 11:15:24 +00:00
|
|
|
//go:build !js
|
|
|
|
|
|
2026-02-17 20:49:45 +00:00
|
|
|
package codegen
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
|
)
|
|
|
|
|
|
2026-03-26 11:15:24 +00:00
|
|
|
func TestGenerateClass_ValidTag(t *testing.T) {
|
2026-02-17 20:49:45 +00:00
|
|
|
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")
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-26 11:15:24 +00:00
|
|
|
func TestGenerateClass_InvalidTag(t *testing.T) {
|
2026-02-17 20:49:45 +00:00
|
|
|
_, err := GenerateClass("invalid", "C")
|
|
|
|
|
assert.Error(t, err, "custom element names must contain a hyphen")
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-26 11:15:24 +00:00
|
|
|
func TestGenerateRegistration_DefinesCustomElement(t *testing.T) {
|
2026-02-17 20:49:45 +00:00
|
|
|
js := GenerateRegistration("photo-grid", "PhotoGrid")
|
|
|
|
|
assert.Contains(t, js, "customElements.define")
|
|
|
|
|
assert.Contains(t, js, `"photo-grid"`)
|
|
|
|
|
assert.Contains(t, js, "PhotoGrid")
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-26 11:15:24 +00:00
|
|
|
func TestTagToClassName_KebabCase(t *testing.T) {
|
2026-02-17 20:49:45 +00:00
|
|
|
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)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-26 11:15:24 +00:00
|
|
|
func TestGenerateBundle_DeduplicatesRegistrations(t *testing.T) {
|
2026-02-17 20:49:45 +00:00
|
|
|
slots := map[string]string{
|
|
|
|
|
"H": "nav-bar",
|
|
|
|
|
"C": "main-content",
|
2026-03-26 11:15:24 +00:00
|
|
|
"F": "nav-bar",
|
2026-02-17 20:49:45 +00:00
|
|
|
}
|
|
|
|
|
js, err := GenerateBundle(slots)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
assert.Contains(t, js, "NavBar")
|
|
|
|
|
assert.Contains(t, js, "MainContent")
|
2026-03-26 15:24:16 +00:00
|
|
|
assert.Equal(t, 2, countSubstr(js, "extends HTMLElement"))
|
|
|
|
|
assert.Equal(t, 2, countSubstr(js, "customElements.define"))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func countSubstr(s, substr string) int {
|
|
|
|
|
if substr == "" {
|
|
|
|
|
return len(s) + 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
count := 0
|
|
|
|
|
for i := 0; i <= len(s)-len(substr); {
|
|
|
|
|
j := indexSubstr(s[i:], substr)
|
|
|
|
|
if j < 0 {
|
|
|
|
|
return count
|
|
|
|
|
}
|
|
|
|
|
count++
|
|
|
|
|
i += j + len(substr)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return count
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func indexSubstr(s, substr string) int {
|
|
|
|
|
if substr == "" {
|
|
|
|
|
return 0
|
|
|
|
|
}
|
|
|
|
|
if len(substr) > len(s) {
|
|
|
|
|
return -1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for i := 0; i <= len(s)-len(substr); i++ {
|
|
|
|
|
if s[i:i+len(substr)] == substr {
|
|
|
|
|
return i
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return -1
|
2026-02-17 20:49:45 +00:00
|
|
|
}
|