Selkie.git | t/ | 03-theme.rakutest
use Test;
use lib 'lib';
use Selkie::Theme;
use Selkie::Style;
plan 9;
sub minimal-theme() {
Selkie::Theme.new(
base => Selkie::Style.new(fg => 0xFFFFFF, bg => 0x000000),
border => Selkie::Style.new(fg => 0x444444),
border-focused => Selkie::Style.new(fg => 0x00FF00, bold => True),
text => Selkie::Style.new(fg => 0xEEEEEE),
text-dim => Selkie::Style.new(fg => 0x888888),
text-highlight => Selkie::Style.new(fg => 0xFFFFFF, bold => True),
input => Selkie::Style.new(fg => 0xEEEEEE, bg => 0x111111),
input-focused => Selkie::Style.new(fg => 0xFFFFFF, bg => 0x222222),
input-placeholder => Selkie::Style.new(fg => 0x666666, italic => True),
scrollbar-track => Selkie::Style.new(fg => 0x333333),
scrollbar-thumb => Selkie::Style.new(fg => 0x00FF00),
divider => Selkie::Style.new(fg => 0x555555),
tab-active => Selkie::Style.new(fg => 0xFFFFFF, bg => 0x00FF00, bold => True),
tab-inactive => Selkie::Style.new(fg => 0x888888),
);
}
subtest "default theme construction" => {
plan 1;
my $t = Selkie::Theme.default;
ok $t.defined, "default theme created";
};
subtest "default theme has all required slots" => {
plan 14;
my $t = Selkie::Theme.default;
ok $t.base.defined, "base defined";
ok $t.border.defined, "border defined";
ok $t.border-focused.defined, "border-focused defined";
ok $t.text.defined, "text defined";
ok $t.text-dim.defined, "text-dim defined";
ok $t.text-highlight.defined, "text-highlight defined";
ok $t.input.defined, "input defined";
ok $t.input-focused.defined, "input-focused defined";
ok $t.input-placeholder.defined, "input-placeholder defined";
ok $t.scrollbar-track.defined, "scrollbar-track defined";
ok $t.scrollbar-thumb.defined, "scrollbar-thumb defined";
ok $t.divider.defined, "divider defined";
ok $t.tab-active.defined, "tab-active defined";
ok $t.tab-inactive.defined, "tab-inactive defined";
};
subtest "defaulted production UI slots are available" => {
plan 14;
my $t = Selkie::Theme.default;
ok $t.control-focused.defined, "control-focused defined";
ok $t.selection.defined, "selection defined";
ok $t.dropdown.defined, "dropdown defined";
ok $t.dropdown-highlight.defined, "dropdown-highlight defined";
ok $t.overlay-title.defined, "overlay-title defined";
ok $t.overlay-key.defined, "overlay-key defined";
ok $t.modal-backdrop.defined, "modal-backdrop defined";
ok $t.toast.defined, "toast defined";
ok $t.password-empty.defined, "password-empty defined";
ok $t.password-weak.defined, "password-weak defined";
ok $t.password-fair.defined, "password-fair defined";
ok $t.password-good.defined, "password-good defined";
ok $t.password-strong.defined, "password-strong defined";
ok $t.password-very-strong.defined, "password-very-strong defined";
};
subtest "default theme colors are set" => {
plan 4;
my $t = Selkie::Theme.default;
ok $t.base.fg.defined, "base has fg";
ok $t.base.bg.defined, "base has bg";
ok $t.text.fg.defined, "text has fg";
ok $t.border-focused.fg.defined, "border-focused has fg";
};
subtest "custom slot - missing key returns base" => {
plan 1;
my $t = Selkie::Theme.default;
is $t.slot("nonexistent").fg, $t.base.fg, "missing slot returns base style";
};
subtest "custom slot - set and retrieve" => {
plan 1;
my $custom = Selkie::Style.new(fg => 0x123456);
my $t = Selkie::Theme.default;
$t.custom<my-slot> = $custom;
is $t.slot("my-slot").fg, 0x123456, "custom slot retrieved";
};
subtest "slot resolves built-in theme slots before custom fallback" => {
plan 7;
my $t = Selkie::Theme.default;
is $t.slot("overlay-title").fg, $t.overlay-title.fg, "overlay-title resolved";
is $t.slot("control-focused").bg, $t.control-focused.bg, "control-focused resolved";
is $t.slot("selection").bg, $t.selection.bg, "selection resolved";
is $t.slot("dropdown").bg, $t.dropdown.bg, "dropdown resolved";
is $t.slot("dropdown-highlight").fg, $t.dropdown-highlight.fg, "dropdown-highlight resolved";
is $t.slot("graph-line").fg, $t.graph-line.fg, "graph-line resolved";
is $t.slot("password-good").fg, $t.password-good.fg, "password-good resolved";
};
subtest "custom theme without defaulted slots keeps compatible defaults" => {
plan 12;
my $t = minimal-theme;
is $t.dropdown.fg, 0xEEEEEE, "dropdown derives fg from input";
is $t.dropdown.bg, 0x111111, "dropdown derives bg from input";
is $t.dropdown-highlight.fg, 0xFFFFFF, "dropdown-highlight derives fg from text-highlight";
is $t.dropdown-highlight.bg, 0x111111, "dropdown-highlight keeps dropdown bg";
ok $t.dropdown-highlight.bold, "dropdown-highlight keeps highlight bold";
is $t.password-empty.fg, 0x888888, "empty band derives from text-dim";
is $t.password-weak.fg, 0xE06060, "weak band default";
is $t.password-fair.fg, 0xE0A040, "fair band default";
is $t.password-good.fg, 0xE0E040, "good band default";
is $t.password-strong.fg, 0x80E060, "strong band default";
is $t.password-very-strong.fg, 0x40E080, "very strong band default";
is $t.slot("password-empty").fg, 0x888888, "password slot lookup works";
};
subtest "default theme border-focused is bold" => {
plan 1;
my $t = Selkie::Theme.default;
ok $t.border-focused.bold, "border-focused is bold";
};