tinyrelayfile
tinyrelay/internal/views/views_test.go/

internal/views/views_test.go raw
1package views
2
3import (
4 "crypto/sha256"
5 "encoding/hex"
6 "strings"
7 "testing"
8)
9
10func TestBlocksFindFencesInOrderWithLanguages(t *testing.T) {
11 content := "Intro\n\n```mermaid\ngraph TD;\n A-->B;\n```\n\nText\n\n~~~\nplain\n~~~\n\n ```` Python extra\nprint(1)\n```\nstill python\n````\n\n```dot\n"
12 blocks := Blocks(content)
13 if len(blocks) != 4 {
14 t.Fatalf("blocks = %+v", blocks)
15 }
16 for i, want := range []Block{
17 {0, "mermaid", "graph TD;\n A-->B;"},
18 {1, "", "plain"},
19 {2, "python", "print(1)\n```\nstill python"},
20 {3, "dot", ""},
21 } {
22 if blocks[i] != want {
23 t.Errorf("block %d = %+v, want %+v", i, blocks[i], want)
24 }
25 }
26 matched := Matching(blocks, []string{"mermaid", "dot"})
27 if len(matched) != 2 || matched[0].Index != 0 || matched[1].Index != 3 {
28 t.Fatalf("matching = %+v", matched)
29 }
30 if got := Matching(blocks, []string{"go"}); got != nil {
31 t.Fatalf("unexpected match %+v", got)
32 }
33}
34
35func TestFenceHelpersRejectShortAndMixedFences(t *testing.T) {
36 if _, _, ok := OpenFence("``"); ok {
37 t.Fatal("two backticks opened a fence")
38 }
39 if _, _, ok := OpenFence("text ```"); ok {
40 t.Fatal("fence in the middle of a line opened a fence")
41 }
42 marker, lang, ok := OpenFence("~~~~ Mermaid title")
43 if !ok || marker != "~~~~" || lang != "mermaid" {
44 t.Fatalf("open = %q %q %v", marker, lang, ok)
45 }
46 if ClosesFence("~~~", marker) || ClosesFence("````", marker) || !ClosesFence(" ~~~~~ ", marker) {
47 t.Fatal("closing fence rules")
48 }
49}
50
51func TestHashCoversLanguageAndSource(t *testing.T) {
52 sum := sha256.Sum256([]byte("mermaid\ngraph TD"))
53 if Hash("mermaid", "graph TD") != hex.EncodeToString(sum[:]) {
54 t.Fatal("hash differs from sha256(lang + newline + source)")
55 }
56 if Hash("mermaid", "graph TD") == Hash("dot", "graph TD") {
57 t.Fatal("language is not part of the hash")
58 }
59 if Blocks("```mermaid\na\n```")[0].Source != Blocks("```mermaid\r\na\r\n```")[0].Source {
60 t.Fatal("line endings change the source")
61 }
62}
63
64func TestFigureEmbedsTheArtifactWithTheCodeAsFallback(t *testing.T) {
65 got := Figure("diagrams", "mermaid", "graph TD;\n A-->B & <C>;")
66 hash := Hash("mermaid", "graph TD;\n A-->B & <C>;")
67 want := `<figure data-view="diagrams"><view-artifact><img src="/views/diagrams/` + hash + `" alt="Rendered mermaid block"><details><summary>Source</summary><pre><code data-lang="mermaid">graph TD;` + "\n" + ` A--&gt;B &amp; &lt;C&gt;;</code></pre></details></view-artifact></figure>` + "\n"
68 if got != want {
69 t.Fatalf("figure =\n%s\nwant\n%s", got, want)
70 }
71 if strings.Contains(got, "class=") {
72 t.Fatal("figure carries a class attribute")
73 }
74}
75
76func TestRendererPicksTheFirstViewForALanguage(t *testing.T) {
77 r := NewRenderer([]View{{Name: "first", Languages: []string{"mermaid"}}, {Name: "second", Languages: []string{"Mermaid", "dot"}}})
78 if html, ok := r.Block("MERMAID", "x"); !ok || !strings.Contains(html, `data-view="first"`) {
79 t.Fatalf("mermaid = %q %v", html, ok)
80 }
81 if html, ok := r.Block("dot", "x"); !ok || !strings.Contains(html, `data-view="second"`) {
82 t.Fatalf("dot = %q %v", html, ok)
83 }
84 if _, ok := r.Block("go", "x"); ok {
85 t.Fatal("go rendered")
86 }
87 if _, ok := (Renderer{}).Block("mermaid", "x"); ok {
88 t.Fatal("empty renderer rendered")
89 }
90}

About

ownerc01503e8035f
visibilitypublic
headd730679639bf

Maintainers

  • c01503e8035f owner
  • ba1b5beed5b5 agent hermes

Clone

  • https://012.run/npub1cq2s86qrtadf36eqq3epm38wmhdynrrcwxf84eldk3f94dkv7ttsrulrz5/tinyrelay.git

Refs