feat(html): expose deep clone helpers
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
a4d2341211
commit
d12408ffb9
4 changed files with 86 additions and 0 deletions
14
layout.go
14
layout.go
|
|
@ -42,6 +42,20 @@ type Layout struct {
|
|||
variantErr error
|
||||
}
|
||||
|
||||
// Clone returns a deep copy of the layout tree.
|
||||
// Example: next := layout.Clone().
|
||||
func (l *Layout) Clone() *Layout {
|
||||
if l == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
clone, ok := l.cloneNode().(*Layout)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return clone
|
||||
}
|
||||
|
||||
// layout.go: NewLayout creates a new Layout with the given variant string.
|
||||
// Example: page := NewLayout("HCF").
|
||||
// The variant determines which slots are rendered (e.g., "HLCRF", "HCF", "C").
|
||||
|
|
|
|||
|
|
@ -99,6 +99,34 @@ func TestLayout_FluentAPI(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestLayout_CloneReturnsIndependentCopy(t *testing.T) {
|
||||
original := NewLayout("HLCRF").
|
||||
H(Raw("header")).
|
||||
C(Raw("main")).
|
||||
F(Raw("footer"))
|
||||
|
||||
clone := original.Clone()
|
||||
if clone == nil {
|
||||
t.Fatal("Clone should return a layout")
|
||||
}
|
||||
if clone == original {
|
||||
t.Fatal("Clone should return a distinct layout instance")
|
||||
}
|
||||
|
||||
clone.H(Raw("cloned-header"))
|
||||
clone.C(Raw("cloned-main"))
|
||||
|
||||
originalGot := original.Render(NewContext())
|
||||
cloneGot := clone.Render(NewContext())
|
||||
|
||||
if strings.Contains(originalGot, "cloned-header") || strings.Contains(originalGot, "cloned-main") {
|
||||
t.Fatalf("Clone should not mutate original layout, got:\n%s", originalGot)
|
||||
}
|
||||
if !strings.Contains(cloneGot, "cloned-header") || !strings.Contains(cloneGot, "cloned-main") {
|
||||
t.Fatalf("Clone should preserve mutations on the copy, got:\n%s", cloneGot)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLayout_IgnoresInvalidSlots(t *testing.T) {
|
||||
ctx := NewContext()
|
||||
// "C" variant: populating L and R should have no effect
|
||||
|
|
|
|||
|
|
@ -28,6 +28,20 @@ func NewResponsive() *Responsive {
|
|||
}
|
||||
}
|
||||
|
||||
// Clone returns a deep copy of the responsive compositor.
|
||||
// Example: next := responsive.Clone().
|
||||
func (r *Responsive) Clone() *Responsive {
|
||||
if r == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
clone, ok := r.cloneNode().(*Responsive)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return clone
|
||||
}
|
||||
|
||||
func (r *Responsive) setAttr(key, value string) {
|
||||
if r == nil {
|
||||
return
|
||||
|
|
|
|||
|
|
@ -54,6 +54,36 @@ func TestResponsive_VariantOrder(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestResponsive_CloneReturnsIndependentCopy(t *testing.T) {
|
||||
original := NewResponsive().
|
||||
Variant("desktop", NewLayout("C").C(Raw("desktop"))).
|
||||
Variant("mobile", NewLayout("C").C(Raw("mobile")))
|
||||
|
||||
clone := original.Clone()
|
||||
if clone == nil {
|
||||
t.Fatal("Clone should return a responsive compositor")
|
||||
}
|
||||
if clone == original {
|
||||
t.Fatal("Clone should return a distinct responsive instance")
|
||||
}
|
||||
|
||||
clone.Variant("tablet", NewLayout("C").C(Raw("tablet")))
|
||||
clone.setAttr("class", "cloned-responsive")
|
||||
|
||||
originalGot := original.Render(NewContext())
|
||||
cloneGot := clone.Render(NewContext())
|
||||
|
||||
if strings.Contains(originalGot, "tablet") || strings.Contains(originalGot, "cloned-responsive") {
|
||||
t.Fatalf("Clone should not mutate original responsive compositor, got:\n%s", originalGot)
|
||||
}
|
||||
if !strings.Contains(cloneGot, `class="cloned-responsive"`) {
|
||||
t.Fatalf("Clone should preserve attributes on the copy, got:\n%s", cloneGot)
|
||||
}
|
||||
if !strings.Contains(cloneGot, `data-variant="tablet"`) {
|
||||
t.Fatalf("Clone should preserve new variants on the copy, got:\n%s", cloneGot)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResponsive_NestedPaths(t *testing.T) {
|
||||
ctx := NewContext()
|
||||
inner := NewLayout("HCF").H(Raw("ih")).C(Raw("ic")).F(Raw("if"))
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue