Skip to content
quarry Artifact [1e25822c38]
Login

Artifact [1e25822c38]

Artifact 1e25822c3893786a70fd5f0d36b02fc8a82a560e465bec3315b573063fc6382b:


package web

import (
	"regexp"
	"strings"
	"testing"
)

// icRule is the one global svg.ic rule, as served.
func icRule(t *testing.T) string {
	t.Helper()
	re := regexp.MustCompile(`(?s)(^|[};])\s*\.ic\s*\{([^}]*)\}`)
	for _, m := range re.FindAllStringSubmatch(sheet, -1) {
		// The base rule is the one that sets fill; the scoped ones
		// (.cbtn .ic and friends) only resize.
		if strings.Contains(m[2], "fill") {
			return m[2]
		}
	}
	t.Fatal("no base .ic rule in the served stylesheet")
	return ""
}

// The base icon rule centres itself in a flex host.
//
// vertical-align does NOTHING to a flex item, and about half of these
// icons sit in one. Hosts that say align-items:center came out right
// anyway; hosts that say align-items:baseline did not, because an SVG
// has no baseline — the browser synthesises one from its bottom margin
// edge, standing the whole icon ON the text baseline.
//
// Measured in Chrome against the deployed stylesheet: the ticket,
// landing and sqlite state tabs each sat exactly -2.00px high (icon
// centre against the adjacent text's glyph box), and exactly 0.00 with
// align-self. Both declarations are kept: align-self covers the flex
// hosts, vertical-align covers the block and table-cell ones, where
// align-self does not apply.
func TestTheIconRuleAlignsItselfInAFlexHost(t *testing.T) {
	body := icRule(t)
	for _, want := range []string{"align-self", "vertical-align"} {
		if !strings.Contains(body, want) {
			t.Errorf("FAIL: the base .ic rule does not set %s: %s", want, strings.TrimSpace(body))
			continue
		}
		t.Logf("ok: .ic sets %s", want)
	}
}

// A flex host that aligns on the BASELINE is the case that breaks, so
// the stylesheet is allowed to keep writing them — but any rule that
// re-declares align-self on an icon has to answer for itself, because
// putting it back to auto or baseline reintroduces the 2px lift with
// nothing to say why.
func TestNoScopedRuleUndoesTheIconAlignment(t *testing.T) {
	re := regexp.MustCompile(`(?s)([^};{]*\.ic[^{]*)\{([^}]*)\}`)
	for _, m := range re.FindAllStringSubmatch(sheet, -1) {
		decl := m[2]
		if !strings.Contains(decl, "align-self") || strings.Contains(decl, "fill") {
			continue
		}
		if strings.Contains(decl, "align-self:auto") || strings.Contains(decl, "align-self:baseline") {
			t.Errorf("FAIL: %s puts an icon back on the baseline: %s",
				strings.TrimSpace(m[1]), strings.TrimSpace(decl))
		}
	}
	t.Log("ok: no scoped .ic rule returns an icon to baseline alignment")
}