Some checks failed
ci / go (push) Has been cancelled
ci / admin-ui (push) Has been cancelled
ci / runtime-sdk (push) Has been cancelled
ci / helm (push) Has been cancelled
ci / openapi (push) Has been cancelled
ci / container (push) Has been cancelled
ci / release-config (push) Has been cancelled
ci / shared styling (push) Has been cancelled
ci / security (push) Has been cancelled
ci / all green (push) Has been cancelled
82 lines
3.5 KiB
Go
82 lines
3.5 KiB
Go
package tokenengine
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/urpi/go-bananas/internal/domain"
|
|
)
|
|
|
|
// The aggregate contract is consumed two ways: as a stylesheet the application
|
|
// links, which can only be styled from :root, and as a stylesheet a control adopts
|
|
// into its own shadow root, where :root matches nothing because a stylesheet in the
|
|
// document does not select into a shadow tree. The bare selector forms are what make
|
|
// the second use possible, and a palette preview depends on them, so their absence is
|
|
// a silent failure: the selector still lists every palette and every preview renders
|
|
// in whatever the host's fallbacks happen to be.
|
|
|
|
// assertSelectorPair asserts that a selector list contains both halves of a pair as
|
|
// distinct comma-separated entries.
|
|
//
|
|
// The assertion is on the joined pair rather than on each half alone, because one half
|
|
// cannot tell the two forms apart: the string `[data-theme="acme"][data-mode="light"]`
|
|
// occurs inside `:root[data-theme="acme"][data-mode="light"]`, so a bare Contains
|
|
// reports a bare selector as present when only the rooted form was emitted. Joining
|
|
// them is what discriminates, because in the rooted-only list the two halves are
|
|
// separated by `:root`.
|
|
func assertSelectorPair(t *testing.T, css, want string) {
|
|
t.Helper()
|
|
if !strings.Contains(css, want) {
|
|
t.Errorf("contract does not emit %q as a pair of entries, so a palette preview cannot adopt it", want)
|
|
}
|
|
}
|
|
|
|
func TestContractEmitsBareSelectorsForPreviewScope(t *testing.T) {
|
|
theme := testTheme()
|
|
theme.Slug = "acme"
|
|
theme.DefaultAppearance = domain.AppearanceDark
|
|
css := ContractAll([]*domain.Theme{theme})
|
|
|
|
// The palette on its own, so a preview that declares no appearance still adopts
|
|
// the designer's choice.
|
|
assertSelectorPair(t, css, `[data-theme="acme"], [data-bananas-theme="acme"]`)
|
|
|
|
// Each appearance, in both attribute conventions.
|
|
assertSelectorPair(t, css, `[data-theme="acme"][data-mode="light"], [data-bananas-theme="acme"][data-bananas-appearance="light"]`)
|
|
assertSelectorPair(t, css, `[data-theme="acme"][data-mode="dark"], [data-bananas-theme="acme"][data-bananas-appearance="dark"]`)
|
|
|
|
// The rooted forms have to survive: every application that links the contract
|
|
// rather than adopting it styles itself from :root.
|
|
assertSelectorPair(t, css, `:root[data-theme="acme"], :root[data-bananas-theme="acme"]`)
|
|
assertSelectorPair(t, css, `:root[data-theme="acme"][data-mode="light"], :root[data-bananas-theme="acme"][data-bananas-appearance="light"]`)
|
|
}
|
|
|
|
// TestContractBareSelectorsCarryTheSameValues guards against the two forms drifting
|
|
// apart, which would mean a preview shows a different palette from the one applying
|
|
// to the page. Both forms are emitted from the same declarations, so this is a
|
|
// statement that the pairing is not an accident worth breaking.
|
|
func TestContractBareSelectorsCarryTheSameValues(t *testing.T) {
|
|
css := ContractAll([]*domain.Theme{testTheme()})
|
|
|
|
for _, want := range []string{
|
|
`--bn-bg: #ffffff;`,
|
|
`--bn-text: #0f172a;`,
|
|
`--bn-accent: #4f46e5;`,
|
|
} {
|
|
if !strings.Contains(css, want) {
|
|
t.Errorf("contract no longer emits %q", want)
|
|
}
|
|
}
|
|
}
|
|
|
|
// TestContractLegacyAliasesStillExist protects the compatibility promise: an
|
|
// application that already uses the unprefixed names must keep working.
|
|
func TestContractLegacyAliasesStillExist(t *testing.T) {
|
|
css := ContractAll([]*domain.Theme{testTheme()})
|
|
|
|
for legacy := range legacyAliases {
|
|
if !strings.Contains(css, "--"+legacy+":") {
|
|
t.Errorf("legacy alias --%s is no longer emitted", legacy)
|
|
}
|
|
}
|
|
}
|