cat / 012
clone

a spreadsheet for the terminal: lotus 1-2-3 looks, google sheets keys and formulas, one go binary

main
012 / internal / ui / theme / rules_test.go
rules_test.go 2.8K
1package theme23import (4 "image/color"5 "testing"67 "github.com/charmbracelet/x/ansi"89 "src.rest/cat/012/internal/sheet"10)1112// In the terminal theme, rule fills and text colors on them read on13// both reference palettes: the fill's ink stands in where a text color14// wouldn't.15func TestRuleColorsReadOnReferencePalettes(t *testing.T) {16 for _, dark := range []bool{true, false} {17 th := New(dark)18 for _, c := range sheet.Colors()[1:] {19 for _, text := range sheet.Colors() {20 s := th.Rule(sheet.RuleStyle{Fill: c, Text: text})21 fg := reference(dark, s.GetForeground().(ansi.BasicColor))22 bg := reference(dark, s.GetBackground().(ansi.BasicColor))23 // The reference palettes' own colors fall a little short24 // of 4.5 in places: black on the light green is 4.29, as25 // for Precedent.26 if r := contrast(fg, bg); r < 4.25 {27 t.Errorf("dark %v: %s text on %s fill: %.2f", dark, text.Title(), c.Title(), r)28 }29 }30 }31 }32}3334// Every scheme's rule colors read: text colors on the screen and fills35// with their text (TestEveryThemeReadable checks the roles), and every36// shade of every color scale.37func TestColorScalesReadable(t *testing.T) {38 xterm := func(i int) color.Color { return reference(true, ansi.BasicColor(i)) }39 for _, p := range append(Builtins(), Palette{}) {40 th := New(true)41 if p.Background != nil {42 th = FromPalette(p)43 }44 for _, from := range sheet.Colors()[1:] {45 for _, to := range sheet.Colors()[1:] {46 for step := 0; step <= scaleSteps; step += 4 {47 s := th.ScaleFill(from, to, float64(step)/scaleSteps, xterm).Style48 requireContrast(t, p.Name, "color scale", s.GetForeground(), s.GetBackground(), minText)49 }50 }51 }52 }53}5455func TestScaleFillBlends(t *testing.T) {56 p, _ := Lookup("Dracula", "")57 th := FromPalette(p)58 none := func(int) color.Color { return color.Black }59 lo := th.ScaleFill(sheet.ColorRed, sheet.ColorGreen, 0, none).Style.GetBackground()60 hi := th.ScaleFill(sheet.ColorRed, sheet.ColorGreen, 1, none).Style.GetBackground()61 mid := th.ScaleFill(sheet.ColorRed, sheet.ColorGreen, 0.5, none).Style.GetBackground()62 same := func(a, b color.Color) bool {63 ar, ag, ab, _ := a.RGBA()64 br, bg, bb, _ := b.RGBA()65 return ar>>8 == br>>8 && ag>>8 == bg>>8 && ab>>8 == bb>>866 }67 if !same(lo, p.ANSI[1]) || !same(hi, p.ANSI[2]) || same(mid, lo) || same(mid, hi) {68 t.Errorf("scale %v %v %v, scheme's red %v green %v", lo, mid, hi, p.ANSI[1], p.ANSI[2])69 }70 // A shade's codes draw what its style does.71 for _, s := range []Shade{th.ScaleFill(sheet.ColorRed, sheet.ColorGreen, 0.5, none), th.RuleShade(sheet.RuleStyle{Fill: sheet.ColorBlue, Text: sheet.ColorYellow})} {72 if s.Open == "" || s.Wrap(" 12 ") != s.Style.Render(" 12 ") {73 t.Errorf("wrap %q, render %q", s.Wrap(" 12 "), s.Style.Render(" 12 "))74 }75 }76 if len(th.scales) != 3 {77 t.Errorf("%d shades kept", len(th.scales))78 }79}