catch mid colors outside of WCAG AA
This commit is contained in:
parent
f72c7a357b
commit
df33164b08
28 changed files with 135 additions and 96 deletions
|
@ -3,7 +3,7 @@ package authmiddleware_test
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"git.sapphic.engineer/roleypoly/v4/authmiddleware"
|
||||
"git.sapphic.engineer/roleypoly/v4/auth/authmiddleware"
|
||||
"git.sapphic.engineer/roleypoly/v4/discord/clientmock"
|
||||
"git.sapphic.engineer/roleypoly/v4/types"
|
||||
"git.sapphic.engineer/roleypoly/v4/types/fixtures"
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
package authmiddleware
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"git.sapphic.engineer/roleypoly/v4/types"
|
||||
"github.com/goccy/go-json"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/gofiber/fiber/v3/middleware/session"
|
||||
)
|
||||
|
|
|
@ -2,16 +2,16 @@ package authmiddleware_test
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"git.sapphic.engineer/roleypoly/v4/authmiddleware"
|
||||
"git.sapphic.engineer/roleypoly/v4/auth/authmiddleware"
|
||||
"git.sapphic.engineer/roleypoly/v4/discord"
|
||||
"git.sapphic.engineer/roleypoly/v4/discord/clientmock"
|
||||
"git.sapphic.engineer/roleypoly/v4/roleypoly"
|
||||
"git.sapphic.engineer/roleypoly/v4/types"
|
||||
"github.com/goccy/go-json"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/gofiber/fiber/v3/middleware/session"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
|
|
@ -3,7 +3,7 @@ package authmiddleware_test
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"git.sapphic.engineer/roleypoly/v4/authmiddleware"
|
||||
"git.sapphic.engineer/roleypoly/v4/auth/authmiddleware"
|
||||
"git.sapphic.engineer/roleypoly/v4/discord/clientmock"
|
||||
"git.sapphic.engineer/roleypoly/v4/types/fixtures"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
package auth
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
pkgs ? import <nixpkgs> {},
|
||||
vendorHash ? "sha256-ilEuRNE61UN22Jm6Yyv80S6VdRa1mB6J/Pde1x/DgEk=",
|
||||
vendorHash ? "sha256-19z+/CD45jtKSCOooCQaVX4YvMFSp+aDaUIXlLMPLkA=",
|
||||
}:
|
||||
rec {
|
||||
default = roleypoly;
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
package discord
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/goccy/go-json"
|
||||
)
|
||||
|
||||
const DiscordBaseUrl = "https://discord.com/api/v10"
|
||||
|
|
1
go.mod
1
go.mod
|
@ -3,7 +3,6 @@ module git.sapphic.engineer/roleypoly/v4
|
|||
go 1.24.1
|
||||
|
||||
require (
|
||||
github.com/goccy/go-json v0.10.5
|
||||
github.com/gofiber/fiber/v3 v3.0.0-beta.4
|
||||
github.com/gofiber/template/html/v2 v2.1.3
|
||||
github.com/stretchr/testify v1.10.0
|
||||
|
|
2
go.sum
2
go.sum
|
@ -5,8 +5,6 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
|||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
|
||||
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
|
||||
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
||||
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||
github.com/gofiber/fiber/v3 v3.0.0-beta.4 h1:KzDSavvhG7m81NIsmnu5l3ZDbVS4feCidl4xlIfu6V0=
|
||||
github.com/gofiber/fiber/v3 v3.0.0-beta.4/go.mod h1:/WFUoHRkZEsGHyy2+fYcdqi109IVOFbVwxv1n1RU+kk=
|
||||
github.com/gofiber/schema v1.2.0 h1:j+ZRrNnUa/0ZuWrn/6kAtAufEr4jCJ+JuTURAMxNSZg=
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"bytes"
|
||||
"crypto/ed25519"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
|
@ -11,7 +12,6 @@ import (
|
|||
"git.sapphic.engineer/roleypoly/v4/discord"
|
||||
"git.sapphic.engineer/roleypoly/v4/interactions"
|
||||
"git.sapphic.engineer/roleypoly/v4/roleypoly"
|
||||
"github.com/goccy/go-json"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/gofiber/fiber/v3/middleware/session"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"crypto"
|
||||
"crypto/ed25519"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
|
@ -13,7 +14,6 @@ import (
|
|||
"git.sapphic.engineer/roleypoly/v4/discord/clientmock"
|
||||
"git.sapphic.engineer/roleypoly/v4/interactions"
|
||||
"git.sapphic.engineer/roleypoly/v4/types/fixtures"
|
||||
"github.com/goccy/go-json"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
|
|
@ -3,9 +3,9 @@ package interactions_test
|
|||
import (
|
||||
"crypto/ed25519"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/goccy/go-json"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
|
2
justfile
2
justfile
|
@ -18,7 +18,7 @@ fmt:
|
|||
go fmt ./...
|
||||
|
||||
prettier:
|
||||
prettier -w -c **/*.{css,html,json,md}
|
||||
prettier -w -c "**/*.{css,json,md}"
|
||||
|
||||
tidy:
|
||||
go mod tidy
|
||||
|
|
|
@ -40,9 +40,8 @@ func Role(category *types.Category, role *types.Role, selected bool) Presentable
|
|||
}
|
||||
|
||||
type PresentableRoleColors struct {
|
||||
Main string
|
||||
Alt string
|
||||
IsDark bool
|
||||
Main string
|
||||
Alt string
|
||||
}
|
||||
|
||||
func GetColors(roleColor uint32) PresentableRoleColors {
|
||||
|
@ -52,8 +51,7 @@ func GetColors(roleColor uint32) PresentableRoleColors {
|
|||
altR, altG, altB := utils.AltColor(r, g, b)
|
||||
|
||||
return PresentableRoleColors{
|
||||
Main: utils.RgbToString(r, g, b),
|
||||
Alt: utils.RgbToString(altR, altG, altB),
|
||||
IsDark: utils.IsDarkColor(r, g, b),
|
||||
Main: utils.RgbToString(r, g, b),
|
||||
Alt: utils.RgbToString(altR, altG, altB),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ func TestRole(t *testing.T) {
|
|||
assert.Equal(t, fixtures.RoleWithDarkColor.Name, r.Name)
|
||||
assert.Equal(t, presentation.InputCheckbox, r.InputType)
|
||||
assert.Equal(t, "#a20000", r.Colors.Main)
|
||||
assert.True(t, r.Colors.IsDark)
|
||||
assert.True(t, r.Selected)
|
||||
|
||||
r = presentation.Role(&fixtures.CategorySingle, &fixtures.RoleWithDarkColor, false)
|
||||
|
@ -22,12 +21,11 @@ func TestRole(t *testing.T) {
|
|||
assert.False(t, r.Selected)
|
||||
|
||||
r = presentation.Role(&fixtures.CategorySingle, &fixtures.RoleWithLightColor, true)
|
||||
assert.False(t, r.Colors.IsDark)
|
||||
assert.True(t, r.Selected)
|
||||
}
|
||||
|
||||
func TestGetColors(t *testing.T) {
|
||||
c := presentation.GetColors(0xa20000)
|
||||
assert.Equal(t, "#a20000", c.Main)
|
||||
assert.True(t, c.IsDark)
|
||||
assert.Equal(t, "#ffd8d8", c.Alt)
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/goccy/go-json"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/gofiber/fiber/v3/middleware/csrf"
|
||||
"github.com/gofiber/fiber/v3/middleware/session"
|
||||
|
@ -26,8 +25,6 @@ func CreateFiberApp() *fiber.App {
|
|||
viewEngine := html.NewFileSystem(http.FS(templates.FS), ".html")
|
||||
|
||||
app := fiber.New(fiber.Config{
|
||||
JSONEncoder: json.Marshal,
|
||||
JSONDecoder: json.Unmarshal,
|
||||
Views: viewEngine,
|
||||
ViewsLayout: "layouts/main",
|
||||
})
|
||||
|
|
4
static/images/x.svg
Normal file
4
static/images/x.svg
Normal file
|
@ -0,0 +1,4 @@
|
|||
<svg width="16" height="16" viewbox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect fill="#000" width="2" height="10" x="7" y="3" style="transform: rotate(45deg); transform-origin: center;"/>
|
||||
<rect fill="#000" width="2" height="10" x="7" y="3" style="transform: rotate(-45deg); transform-origin: center;"/>
|
||||
</svg>
|
After Width: | Height: | Size: 323 B |
|
@ -41,8 +41,8 @@ body {
|
|||
border: 2px solid var(--role-color);
|
||||
border-radius: 3px;
|
||||
user-select: none;
|
||||
padding: 0.217rem; /* this is silly number pls ignore :3 (^noe) */
|
||||
gap: 0.215rem;
|
||||
padding: 0.369rem; /* this is silly number pls ignore :3 (^noe) */
|
||||
gap: 0.269rem;
|
||||
cursor: pointer;
|
||||
transition: all 0.35s ease-in-out;
|
||||
|
||||
|
@ -84,6 +84,7 @@ body {
|
|||
|
||||
label {
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
&:has(input:checked) {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<div
|
||||
class="role"
|
||||
style="--role-color: {{.Colors.Main}}; --contrast-color: {{.Colors.Alt}};"
|
||||
data-testid="role-{{.ID}}"
|
||||
data-testid="{{$for}}"
|
||||
>
|
||||
<input type="{{.InputType}}" id="{{$for}}" {{if eq .InputType
|
||||
"radio"}}name="category_group_{{.CategoryID}}"{{end}} />
|
||||
|
|
|
@ -35,9 +35,9 @@ func TestRole(t *testing.T) {
|
|||
assert.Contains(t, html, "--role-color: #a20000;", "role color is set")
|
||||
assert.Contains(t, html, `type="checkbox"`, "multi has input type=checkbox")
|
||||
assert.Contains(t, html, fmt.Sprintf("--contrast-color: %s;", utils.RgbToString(utils.AltColor(162, 0, 0))), "contrast color is set")
|
||||
assert.Contains(t, html, fmt.Sprintf(`id="%s"`, roleInputID(c, r)), "input has ID attr")
|
||||
assert.Contains(t, html, fmt.Sprintf(`for="%s"`, roleInputID(c, r)), "label has for attr")
|
||||
assert.NotContains(t, html, fmt.Sprintf(`name="%s"`, roleInputName(c)), "multi has no name attr")
|
||||
assert.Contains(t, html, fmt.Sprintf(`id="%s"`, utils.RoleInputID(c, r)), "input has ID attr")
|
||||
assert.Contains(t, html, fmt.Sprintf(`for="%s"`, utils.RoleInputID(c, r)), "label has for attr")
|
||||
assert.NotContains(t, html, fmt.Sprintf(`name="%s"`, utils.RoleInputName(c)), "multi has no name attr")
|
||||
// TODO: selected?
|
||||
|
||||
c = &fixtures.CategorySingle
|
||||
|
@ -45,14 +45,7 @@ func TestRole(t *testing.T) {
|
|||
html = renderRole(t, c, r, true)
|
||||
assert.Contains(t, html, `type="radio"`, "single has input type=radio")
|
||||
assert.Contains(t, html, fmt.Sprintf("--contrast-color: %s;", utils.RgbToString(utils.AltColor(0xff, 0xaa, 0x88))), "contrast color")
|
||||
assert.Contains(t, html, fmt.Sprintf(`name="%s"`, roleInputName(c)), "single has name attr")
|
||||
assert.Contains(t, html, fmt.Sprintf(`name="%s"`, utils.RoleInputName(c)), "single has name attr")
|
||||
}
|
||||
|
||||
// TODO: these can probably be string utils that are injected as functions into template
|
||||
func roleInputID(c *types.Category, r *types.Role) string {
|
||||
return fmt.Sprintf("category-%s_role-%s", c.ID, r.ID)
|
||||
}
|
||||
|
||||
func roleInputName(c *types.Category) string {
|
||||
return fmt.Sprintf("category_group_%s", c.ID)
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<title>{{ .HeadTitle }}</title>
|
||||
<link rel="preconnect" href="https://fonts.bunny.net" />
|
||||
<link
|
||||
href="https://fonts.bunny.net/css?family=atkinson-hyperlegible:400,400i"
|
||||
href="https://fonts.bunny.net/css?family=atkinson-hyperlegible:400,400i,600,600i"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<link rel="stylesheet" href="/static/main.css" />
|
||||
|
|
14
templates/testing/templates.go
Normal file
14
templates/testing/templates.go
Normal file
|
@ -0,0 +1,14 @@
|
|||
// Package testing provides test helpers that support fiber templates
|
||||
package testing
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
|
||||
"git.sapphic.engineer/roleypoly/v4/templates"
|
||||
)
|
||||
|
||||
var (
|
||||
Templates = template.Must(template.ParseFS(templates.FS, "*.html")).Funcs(template.FuncMap{
|
||||
"embed": func() {},
|
||||
})
|
||||
)
|
7
templates/testing/templates_test.go
Normal file
7
templates/testing/templates_test.go
Normal file
|
@ -0,0 +1,7 @@
|
|||
package testing_test
|
||||
|
||||
// func Test(t *testing.T) {
|
||||
|
||||
// }
|
||||
|
||||
// TODO: test the template tester
|
|
@ -7,10 +7,10 @@
|
|||
<div class="container">
|
||||
<div class="cat-multi">
|
||||
{{ template "components/role" .TestRole }} {{ template "components/role"
|
||||
.TestRole2 }}
|
||||
.TestRole2 }} {{ template "components/role" .TestRole3 }}
|
||||
</div>
|
||||
<div class="cat-single">
|
||||
{{ template "components/role" .TestRole3 }} {{ template "components/role"
|
||||
.TestRole4 }}
|
||||
{{ template "components/role" .TestRole4 }} {{ template "components/role"
|
||||
.TestRole5 }} {{ template "components/role" .TestRole6 }}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -40,9 +40,11 @@ func (t *TestingController) TestTemplate(c fiber.Ctx) error {
|
|||
cat2 := fixtures.Category(fixtures.CategorySingle)
|
||||
return c.Render("tests/"+which, fiber.Map{
|
||||
"TestRole": presentation.Role(cat1, &fixtures.RoleWithDarkColor, false),
|
||||
"TestRole2": presentation.Role(cat1, &fixtures.RoleWithLightColor, true),
|
||||
"TestRole3": presentation.Role(cat2, &fixtures.RoleWithDarkColor, false),
|
||||
"TestRole4": presentation.Role(cat2, &fixtures.RoleWithLightColor, true),
|
||||
"TestRole2": presentation.Role(cat1, &fixtures.RoleWithDarkMediumColor, false),
|
||||
"TestRole3": presentation.Role(cat1, &fixtures.RoleWithLightColor, true),
|
||||
"TestRole4": presentation.Role(cat1, &fixtures.RoleWithDarkColor, false),
|
||||
"TestRole5": presentation.Role(cat2, &fixtures.RoleWithLightColor, true),
|
||||
"TestRole6": presentation.Role(cat1, &fixtures.RoleWithLightMediumColor, false),
|
||||
}, "layouts/main")
|
||||
}
|
||||
|
||||
|
|
|
@ -5,17 +5,31 @@ import "git.sapphic.engineer/roleypoly/v4/types"
|
|||
var (
|
||||
RoleWithDarkColor = types.Role{
|
||||
ID: "dark-color",
|
||||
Name: "role with dark color",
|
||||
Name: "dark",
|
||||
Color: 0xa20000,
|
||||
Permissions: 0,
|
||||
Position: 10,
|
||||
}
|
||||
RoleWithDarkMediumColor = types.Role{
|
||||
ID: "dark-medium-color",
|
||||
Name: "dark medium",
|
||||
Color: 0xeb5e4b,
|
||||
Permissions: 0,
|
||||
Position: 11,
|
||||
}
|
||||
RoleWithLightMediumColor = types.Role{
|
||||
ID: "light-medium-color",
|
||||
Name: "light medium",
|
||||
Color: 0xfa8373,
|
||||
Permissions: 0,
|
||||
Position: 11,
|
||||
}
|
||||
RoleWithLightColor = types.Role{
|
||||
ID: "light-color",
|
||||
Name: "role with light color",
|
||||
Name: "light",
|
||||
Color: 0xffaa88,
|
||||
Permissions: 0,
|
||||
Position: 10,
|
||||
Position: 12,
|
||||
}
|
||||
RoleWithoutColor = types.Role{
|
||||
ID: "without-color",
|
||||
|
|
|
@ -2,6 +2,7 @@ package utils
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
)
|
||||
|
||||
|
@ -11,11 +12,10 @@ const (
|
|||
Pblue float64 = 0.114
|
||||
)
|
||||
|
||||
func IsDarkColor(r, g, b uint8) bool {
|
||||
lum := Luminance(r, g, b)
|
||||
|
||||
return lum <= 130
|
||||
}
|
||||
var (
|
||||
DarkAltFallback = []uint8{0x1c, 0x10, 0x10}
|
||||
LightAltFallback = []uint8{0xf2, 0xef, 0xef}
|
||||
)
|
||||
|
||||
func IntToRgb(color uint32) (uint8, uint8, uint8) {
|
||||
b := color % 256
|
||||
|
@ -30,11 +30,30 @@ func RgbToString(r, g, b uint8) string {
|
|||
}
|
||||
|
||||
func AltColor(r, g, b uint8) (uint8, uint8, uint8) {
|
||||
l1 := Luminance(r, g, b)
|
||||
isDark := l1 <= 0.5098
|
||||
|
||||
brightnessAmount := -0.6
|
||||
if IsDarkColor(r, g, b) {
|
||||
if isDark { // color is dark
|
||||
brightnessAmount = 0.85
|
||||
}
|
||||
return Brighten(r, g, b, brightnessAmount)
|
||||
|
||||
r2, g2, b2 := Brighten(r, g, b, brightnessAmount)
|
||||
|
||||
l2 := Luminance(r2, g2, b2)
|
||||
ratio := WCAGRatio(l1, l2)
|
||||
|
||||
log.Printf("isDark=%v, ratio: %f, l1(%f)=%s, l2(%f)=%s", isDark, ratio, l1, RgbToString(r, g, b), l2, RgbToString(r2, g2, b2))
|
||||
|
||||
if ratio >= 3 {
|
||||
return r2, g2, b2
|
||||
}
|
||||
|
||||
if isDark {
|
||||
return LightAltFallback[0], LightAltFallback[1], LightAltFallback[2]
|
||||
} else {
|
||||
return DarkAltFallback[0], DarkAltFallback[1], DarkAltFallback[3]
|
||||
}
|
||||
}
|
||||
|
||||
func Brighten(r, g, b uint8, amount float64) (uint8, uint8, uint8) {
|
||||
|
@ -53,18 +72,23 @@ func multiply(i uint8, amount float64) uint8 {
|
|||
)
|
||||
}
|
||||
|
||||
func sRGB(c uint8) float64 {
|
||||
cf := float64(c) / 255
|
||||
if cf <= 0.03928 {
|
||||
return cf / 12.92
|
||||
} else {
|
||||
return math.Pow((cf+0.055)/1.055, 2.4)
|
||||
}
|
||||
}
|
||||
|
||||
func Luminance(r, g, b uint8) float64 {
|
||||
rC := Pred * math.Pow(float64(r), 2)
|
||||
gC := Pgreen * math.Pow(float64(g), 2)
|
||||
bC := Pblue * math.Pow(float64(b), 2)
|
||||
rC := Pred * math.Pow(sRGB(r), 2)
|
||||
gC := Pgreen * math.Pow(sRGB(g), 2)
|
||||
bC := Pblue * math.Pow(sRGB(b), 2)
|
||||
|
||||
return math.Sqrt(rC + gC + bC)
|
||||
}
|
||||
|
||||
func WCAGRatio(l1, l2 float64) float64 {
|
||||
if l1 < l2 {
|
||||
return (l1 + 0.05) / (l2 + 0.05)
|
||||
} else {
|
||||
return (l2 + 0.05) / (l1 + 0.05)
|
||||
}
|
||||
return (math.Max(l1, l2) + 0.05) / (math.Min(l1, l2) + 0.05)
|
||||
}
|
||||
|
|
|
@ -8,8 +8,7 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
WCAGAAA float64 = 0.14285714285714285
|
||||
WCAGAA float64 = 0.25
|
||||
WCAGAA float64 = 3
|
||||
)
|
||||
|
||||
func TestIntToRgb(t *testing.T) {
|
||||
|
@ -19,38 +18,20 @@ func TestIntToRgb(t *testing.T) {
|
|||
assert.Equal(t, uint8(0x56), b, "blue")
|
||||
}
|
||||
|
||||
func TestIsDarkColor(t *testing.T) {
|
||||
isDark := utils.IsDarkColor(0, 0, 0)
|
||||
assert.True(t, isDark)
|
||||
|
||||
isLight := utils.IsDarkColor(255, 255, 255)
|
||||
assert.False(t, isLight)
|
||||
|
||||
isQuestionable := utils.IsDarkColor(0x88, 0x88, 0x88)
|
||||
assert.False(t, isQuestionable)
|
||||
|
||||
isReallyQuestionable := utils.IsDarkColor(0x00, 0x88, 0x00)
|
||||
assert.True(t, isReallyQuestionable)
|
||||
}
|
||||
|
||||
func TestBrighten(t *testing.T) {
|
||||
r, g, b := utils.Brighten(0, 0, 0, 0.1)
|
||||
assert.Equal(t, uint8(0x19), r)
|
||||
assert.Equal(t, uint8(0x19), g)
|
||||
assert.Equal(t, uint8(0x19), b)
|
||||
// assert.LessOrEqual(t, WCAGAA, utils.WCAGRatio(
|
||||
// utils.Luminance(0, 0, 0),
|
||||
// utils.Luminance(r, g, b),
|
||||
// ))
|
||||
|
||||
r, g, b = utils.Brighten(0x88, 0x88, 0x88, -0.1)
|
||||
assert.Equal(t, uint8(0x88-0x19-1), r)
|
||||
assert.Equal(t, uint8(0x88-0x19-1), g)
|
||||
assert.Equal(t, uint8(0x88-0x19-1), b)
|
||||
// assert.LessOrEqual(t, WCAGAA, utils.WCAGRatio(
|
||||
// utils.Luminance(0x88, 0x88, 0x88),
|
||||
// utils.Luminance(r, g, b),
|
||||
// ))
|
||||
assert.GreaterOrEqual(t, utils.WCAGRatio(
|
||||
utils.Luminance(0x88, 0x88, 0x88),
|
||||
utils.Luminance(r, g, b),
|
||||
), WCAGAA)
|
||||
}
|
||||
|
||||
func TestRgbToString(t *testing.T) {
|
||||
|
@ -59,12 +40,21 @@ func TestRgbToString(t *testing.T) {
|
|||
|
||||
func TestAltColor(t *testing.T) {
|
||||
r, g, b := utils.AltColor(0xa2, 0xc2, 0x42)
|
||||
assert.Equal(t, uint8(0x09), r, "red")
|
||||
assert.Equal(t, uint8(0x29), g, "green")
|
||||
assert.Equal(t, uint8(0x00), b, "blue")
|
||||
assert.Equal(t, uint8(0xf2), r, "red")
|
||||
assert.Equal(t, uint8(0xef), g, "green")
|
||||
assert.Equal(t, uint8(0xef), b, "blue")
|
||||
assert.GreaterOrEqual(t, utils.WCAGRatio(
|
||||
utils.Luminance(0xa2, 0xc2, 0x42),
|
||||
utils.Luminance(r, g, b),
|
||||
), WCAGAA)
|
||||
|
||||
r, g, b = utils.AltColor(0xa2, 0x15, 0x18)
|
||||
assert.Equal(t, uint8(0xff), r, "red")
|
||||
assert.Equal(t, uint8(0xed), g, "green")
|
||||
assert.Equal(t, uint8(0xf0), b, "blue")
|
||||
assert.Equal(t, uint8(0xff), r, "red2")
|
||||
assert.Equal(t, uint8(0xed), g, "green2")
|
||||
assert.Equal(t, uint8(0xf0), b, "blue2")
|
||||
assert.GreaterOrEqual(t, utils.WCAGRatio(
|
||||
utils.Luminance(0xa2, 0x15, 0x18),
|
||||
utils.Luminance(r, g, b),
|
||||
), WCAGAA)
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue