v0.7.2 71ebe61

property_table_test.go RawHistoryFolder

1package css
2
3import (
4	"reflect"
5	"testing"
6)
7
8// Every row in docs/css.md has at least one accepted and one rejected example.
9// A valid example must override the row's initial; an invalid example must not.
10func TestDocumentedPropertyRows(t *testing.T) {
11	rows := []struct{ name, valid, invalid string }{
12		{"color", "red", "rgb(nope)"}, {"opacity", ".5", "2"},
13		{"background-color", "#abc", "#xyq"}, {"background", "red", "garbage"},
14		{"border-width", "1px 2px 3px 4px", "1px 2px 3px 4px 5px"},
15		{"border-style", "solid none", "dotted"}, {"border-color", "red blue", "invalid"},
16		{"border", "2px solid red", "2px dashed red"},
17		{"border-radius", "1px 2px 3px 4px", "2px / 1px"},
18		{"outline", "1px solid red", "1px dotted"},
19		{"outline-offset", "-2px", "1%"},
20		{"box-shadow", "inset 1px 2px 3px -4px red, 0 0 blue", "1px 2px -3px red"},
21		{"margin", "auto -1px 2% 3rem", "1px 2px 3px 4px 5px"},
22		{"padding", "1px 2px 3px 4px", "-1px"},
23		{"box-sizing", "border-box", "padding-box"},
24		{"display", "flex", "grid"},
25		{"flex-direction", "column", "diagonal"},
26		{"flex-wrap", "wrap", "reverse"},
27		{"flex", "2 3 10px", "2 nope"},
28		{"gap", "1px 2px", "1px 2px 3px"},
29		{"justify-content", "space-evenly", "between"},
30		{"overflow", "hidden auto", "clip"},
31		{"font-family", `"A B", serif`, "serif,,monospace"},
32		{"font-size", "120%", "-1px"},
33		{"font-weight", "bold", "550"},
34		{"font-style", "italic", "solid"},
35		{"line-height", "1.5", "-1px"},
36		{"text-align", "center", "justify"},
37		{"letter-spacing", "-1px", "1%"},
38		{"cursor", "pointer", "grab"},
39		{"accent-color", "red", "notacolor"},
40		{"--accent", "red", "var(--missing)"},
41	}
42	for _, side := range sideNames {
43		rows = append(rows,
44			struct{ name, valid, invalid string }{"border-" + side + "-width", "2px", "-1px"},
45			struct{ name, valid, invalid string }{"border-" + side + "-style", "solid", "dotted"},
46			struct{ name, valid, invalid string }{"border-" + side + "-color", "red", "notacolor"},
47			struct{ name, valid, invalid string }{"border-" + side, "2px solid red", "2px dashed red"},
48			struct{ name, valid, invalid string }{"margin-" + side, "-1em", "banana"},
49			struct{ name, valid, invalid string }{"padding-" + side, "2px", "-1px"},
50		)
51	}
52	for _, corner := range cornerNames {
53		rows = append(rows, struct{ name, valid, invalid string }{"border-" + corner + "-radius", "2%", "-1px"})
54	}
55	for _, name := range []string{"width", "height", "min-width", "min-height", "max-width", "max-height", "flex-basis"} {
56		rows = append(rows, struct{ name, valid, invalid string }{name, "2rem", "-1px"})
57	}
58	for _, name := range []string{"flex-grow", "flex-shrink"} {
59		rows = append(rows, struct{ name, valid, invalid string }{name, "2.5", "-1"})
60	}
61	for _, name := range []string{"row-gap", "column-gap"} {
62		rows = append(rows, struct{ name, valid, invalid string }{name, "2px", "-2px"})
63	}
64	for _, name := range []string{"align-items", "align-self"} {
65		rows = append(rows, struct{ name, valid, invalid string }{name, "center", "baseline"})
66	}
67	for _, name := range []string{"overflow-x", "overflow-y"} {
68		rows = append(rows, struct{ name, valid, invalid string }{name, "scroll", "clip"})
69	}
70	for _, name := range []string{"outline-width"} {
71		rows = append(rows, struct{ name, valid, invalid string }{name, "1px", "-1px"})
72	}
73	for _, name := range []string{"outline-style"} {
74		rows = append(rows, struct{ name, valid, invalid string }{name, "solid", "dashed"})
75	}
76	for _, name := range []string{"outline-color"} {
77		rows = append(rows, struct{ name, valid, invalid string }{name, "red", "nonsense"})
78	}
79	for _, r := range rows {
80		t.Run(r.name, func(t *testing.T) {
81			if r.name == "--accent" {
82				en := Compile(Sheet{}, Parse(`button{--accent:red;color:var(--accent)}`))
83				if en.Compute(&Element{Type: "button"}, nil).Style.Color != namedColors["red"] {
84					t.Fatal("custom property not resolved")
85				}
86				bad := Compile(Sheet{}, Parse(`button{--accent:var(--missing);color:var(--accent)}`))
87				if bad.Compute(&Element{Type: "button"}, nil).Style.Color != (Color{A: 1}) {
88					t.Fatal("invalid custom property not handled")
89				}
90				return
91			}
92			initial := Compile(Sheet{}, Sheet{}).Compute(&Element{Type: "button"}, nil).Style
93			valid := Compile(Sheet{}, Parse("button{"+r.name+":"+r.valid+"}")).Compute(&Element{Type: "button"}, nil).Style
94			invalid := Compile(Sheet{}, Parse("button{"+r.name+":"+r.invalid+"}")).Compute(&Element{Type: "button"}, nil).Style
95			if reflect.DeepEqual(*valid, *initial) {
96				t.Errorf("valid value %q did not alter style", r.valid)
97			}
98			if !reflect.DeepEqual(*invalid, *initial) {
99				t.Errorf("invalid value %q changed style", r.invalid)
100			}
101		})
102	}
103}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 12

↑↓ moveenter openesc close