Download
80 lines 2.1 KiBGoModified 2026-10-27 raw
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
package highlight

import (
	"strings"
	"testing"

	"github.com/alecthomas/chroma/v2"
)

// TestRepoLexers loads each bundled lexer the way repo-render.yaml does,
// with no lexer_dirs, and checks a small sample lands in the expected
// token classes.
func TestRepoLexers(t *testing.T) {
	cases := []struct {
		name    string
		glob    string
		src     string
		keyword string
		str     string
		comment string
	}{
		{
			name:    "tomo",
			glob:    "*.tm",
			src:     "# greet\nfunc main()\n    say(\"Hi $name\")\n",
			keyword: "func", str: "Hi ", comment: "# greet",
		},
		{
			name:    "bp",
			glob:    "*.bp",
			src:     "# a rule\nGreeting: \"hello\" __ @who=word\n",
			keyword: "__", str: "\"hello\"", comment: "# a rule",
		},
		{
			name:    "nomsu",
			glob:    "*.nom",
			src:     "### say hi\nif (yes):\n    say \"Hello \\$name\"\n",
			keyword: "if", str: "Hello ", comment: "### say hi",
		},
	}
	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			r, err := New(nil, []Custom{{Name: tc.name, Globs: []string{tc.glob}}}, "github")
			if err != nil {
				t.Fatal(err)
			}
			lx := r.ByPath("x" + tc.glob[1:])
			if r.IsPlain(lx) || Name(lx) == "" {
				t.Fatalf("%s: glob %s did not resolve to the custom lexer", tc.name, tc.glob)
			}
			it, err := lx.Tokenise(nil, tc.src)
			if err != nil {
				t.Fatal(err)
			}
			toks := it.Tokens()
			want := map[string]string{tc.keyword: "k", tc.str: "s", tc.comment: "c"}
			for value, cls := range want {
				// Tokens are coalesced, so the sample may be part of a larger token.
				got, ok := classOf(toks, value)
				if !ok {
					t.Errorf("%s: no token containing %q; tokens: %v", tc.name, value, toks)
					continue
				}
				if !strings.HasPrefix(got, cls) {
					t.Errorf("%s: token containing %q has class %q, want %s*", tc.name, value, got, cls)
				}
			}
		})
	}
}

// classOf returns the CSS class of the first token whose value contains s.
func classOf(toks []chroma.Token, s string) (string, bool) {
	for _, tok := range toks {
		if strings.Contains(tok.Value, s) {
			return class(tok.Type), true
		}
	}
	return "", false
}