Skip to content
quarry Artifact [88fec33370]
Login

Artifact [88fec33370]

Artifact 88fec3337027e0fb5e8c1d28d77eca8933f43d553238163c61023da00d9c31ea:


package highlight

import (
	"strings"
	"testing"
)

// The window carries only the lines asked for. Chroma emits a span per
// token, so a whole-file render of build.c was 40,083 DOM nodes; a
// screenful is a hundred or so.
func TestWindowHoldsOnlyItsLines(t *testing.T) {
	var b strings.Builder
	for i := 0; i < 500; i++ {
		b.WriteString("int line")
		b.WriteString(strings.Repeat("x", 1))
		b.WriteString(" = 1;\n")
	}
	src := []byte(b.String())

	html, total, ok := Window(src, "", "a.c", 0, 50)
	if !ok {
		t.Fatal("window declined a C file")
	}
	if n := strings.Count(html, "\n"); n > 60 {
		t.Errorf("window emitted %d lines, want ~50", n)
	}
	// Reaching the end reports the total; stopping early does not
	// pretend to know it.
	if total != 0 {
		t.Errorf("a window that stopped early reported total=%d, want 0", total)
	}
	if _, total, _ = Window(src, "", "a.c", 0, 10000); total != 501 {
		t.Errorf("total = %d, want 501", total)
	}
}

// A window opening inside a block comment must still be coloured as a
// comment. This is why lexing starts at byte zero even though only the
// window is emitted — highlighting a slice in isolation would call the
// comment body ordinary code.
func TestWindowKeepsLexerContext(t *testing.T) {
	src := []byte("int a = 1;\n/* opening a long comment\n" +
		strings.Repeat("still inside the comment\n", 40) +
		"*/\nint b = 2;\n")

	html, _, ok := Window(src, "", "a.c", 20, 5)
	if !ok {
		t.Fatal("window declined")
	}
	// chroma's comment classes begin with "c" (c, c1, cm, ...). The
	// window sits deep inside the comment, so its content must carry
	// one of them rather than being lexed as bare text.
	if !strings.Contains(html, "class=\"c") {
		t.Errorf("a window inside a block comment lost its context:\n%s", html)
	}
}

// Windows must tile: consecutive windows reproduce the file's lines in
// order, with nothing dropped or repeated.
func TestWindowsTile(t *testing.T) {
	var b strings.Builder
	for i := 0; i < 30; i++ {
		b.WriteString("x := ")
		b.WriteString(strings.Repeat("9", i%5+1))
		b.WriteString("\n")
	}
	src := []byte(b.String())

	var joined string
	for from := 0; from < 30; from += 7 {
		html, _, ok := Window(src, "", "a.go", from, 7)
		if !ok {
			t.Fatalf("window at %d declined", from)
		}
		joined += html
	}
	text := strip(joined)
	if want := string(src); strings.TrimSpace(text) != strings.TrimSpace(want) {
		t.Errorf("tiled windows do not reproduce the file:\ngot:  %q\nwant: %q",
			text, want)
	}
}

// strip removes tags, leaving the text a reader would see.
func strip(html string) string {
	var out strings.Builder
	depth := 0
	for _, r := range html {
		switch {
		case r == '<':
			depth++
		case r == '>':
			depth--
		case depth == 0:
			out.WriteRune(r)
		}
	}
	return strings.ReplaceAll(out.String(), "&#34;", "\"")
}