GitRoot
craft your forge, build your project, grow your community freely
1// SPDX-FileCopyrightText: 2025 Romain Maneschi <romain@gitroot.dev>
2//
3// SPDX-License-Identifier: EUPL-1.2
4
5package main
6
7import (
8 "strings"
9 "testing"
10 "time"
11
12 "gitroot.dev/libs/golang/plugin/model"
13 "gitroot.dev/libs/golang/plugin/test"
14)
15
16type finalizeCall struct {
17 fp string
18 htmlContent string
19 htmlShouldContains []string
20}
21
22func TestRender(t *testing.T) {
23 w := worktree{lines: []gitWorktreeLine{{
24 FullPath: "file",
25 LastEdited: time.Now(),
26 Message: "Mon joli file",
27 hasBeenUpdated: true,
28 }, {
29 FullPath: "dir/file2",
30 LastEdited: time.Now(),
31 Message: "Mon joli file2",
32 hasBeenUpdated: true,
33 }, {
34 FullPath: "dir/dir2/dir3/file3",
35 LastEdited: time.Now(),
36 Message: "Mon joli file3",
37 hasBeenUpdated: true,
38 }, {
39 FullPath: "dir4/file4",
40 LastEdited: time.Now(),
41 Message: "Mon joli file4",
42 hasBeenUpdated: true,
43 }}}
44 expected := []finalizeCall{{
45 fp: "worktree/file.html",
46 htmlShouldContains: []string{
47 "<pre>Binary</pre>",
48 },
49 }, {
50 fp: "worktree/dir/file2.html",
51 htmlShouldContains: []string{
52 "<pre>Binary</pre>",
53 },
54 }, {
55 fp: "worktree/dir/dir2/dir3/file3.html",
56 htmlShouldContains: []string{
57 "<pre>Binary</pre>",
58 },
59 }, {
60 fp: "worktree/dir/dir2/dir3/index.html",
61 htmlShouldContains: []string{
62 "<a href=\"worktree\">worktree</a>", "<a href=\"worktree/dir\">dir</a>", "<a href=\"worktree/dir/dir2\">dir2</a>", "dir3",
63 "<a href=\"worktree/dir/dir2/dir3/file3.html\">file3</a>",
64 },
65 }, {
66 fp: "worktree/dir/dir2/index.html",
67 htmlShouldContains: []string{
68 "<a href=\"worktree\">worktree</a>", "<a href=\"worktree/dir\">dir</a>", "dir2",
69 "<a href=\"worktree/dir/dir2/dir3/index.html\">dir3</a>",
70 },
71 }, {
72 fp: "worktree/dir/index.html",
73 htmlShouldContains: []string{
74 "<a href=\"worktree\">worktree</a>", "dir",
75 "<a href=\"worktree/dir/dir2/index.html\">dir2</a>", "<a href=\"worktree/dir/file2.html\">file2</a>",
76 },
77 }, {
78 fp: "worktree/dir4/file4.html",
79 htmlShouldContains: []string{
80 "<pre>Binary</pre>",
81 },
82 }, {
83 fp: "worktree/dir4/index.html",
84 htmlShouldContains: []string{
85 "<a href=\"worktree\">worktree</a>", "dir4",
86 "<a href=\"worktree/dir4/file4.html\">file4</a>",
87 },
88 }, {
89 fp: "worktree/index.html",
90 htmlShouldContains: []string{
91 "worktree",
92 "<a href=\"worktree/dir/index.html\">dir</a>", "<a href=\"worktree/dir4/index.html\">dir4</a>", "<a href=\"worktree/file.html\">file</a>",
93 },
94 }}
95 called := make([]finalizeCall, 0)
96 w.renderHtml("", "worktree", func(fp, htmlContent string) {
97 called = append(called, finalizeCall{fp: fp, htmlContent: htmlContent})
98 })
99 if len(called) != len(expected) {
100 t.Errorf("Should be called %d times but was %d\n%#v", len(expected), len(called), called)
101 }
102 for i, exp := range expected {
103 if called[i].fp != exp.fp {
104 t.Errorf("called[%d].fp should be %s but was %s", i, exp.fp, called[i].fp)
105 }
106 for _, shouldContains := range exp.htmlShouldContains {
107 if _, after, found := strings.Cut(called[i].htmlContent, shouldContains); found {
108 called[i].htmlContent = after
109 } else {
110 t.Errorf("%s should contains %s but was %s", exp.fp, shouldContains, called[i].htmlContent)
111 }
112 }
113 }
114}
115
116func TestRenderWithOnlyTopModified(t *testing.T) {
117 fakeServer := test.NewFakeServer(t, test.Override{})
118 fakeServer.ModifyContent("README.txt", "hello")
119 fakeServer.ModifyContent("dir/README.txt", "hello")
120 fakeServer.ModifyContent("dir/README2.txt", "hello")
121
122 p := &Plugin{
123 server: fakeServer,
124 }
125 p.Init("repo", false, `{"generateGitWorktree": true, "defaultBranch": "main"}`)
126 p.StartCommit(model.Commit{Branch: "main"})
127 p.AddFile(model.File{Path: "README.txt"})
128 p.AddFile(model.File{Path: "dir/README.txt"})
129 p.AddFile(model.File{Path: "dir/README2.txt"})
130 p.Finish()
131 if fakeServer.NbCall.ModifyWebContent != 11 {
132 t.Fatalf("not called %d", fakeServer.NbCall.ModifyWebContent)
133 }
134
135 p = &Plugin{
136 server: fakeServer,
137 }
138 p.Init("repo", false, `{"generateGitWorktree": true, "defaultBranch": "main"}`)
139 p.StartCommit(model.Commit{Branch: "main"})
140 p.ModFile(model.File{Path: "README.txt"})
141 p.Finish()
142 if fakeServer.NbCall.ModifyWebContent != 11+3 {
143 t.Fatalf("not called %d", fakeServer.NbCall.ModifyWebContent)
144 }
145
146 p = &Plugin{
147 server: fakeServer,
148 }
149 p.Init("repo", false, `{"generateGitWorktree": true, "defaultBranch": "main"}`)
150 p.StartCommit(model.Commit{Branch: "main"})
151 p.ModFile(model.File{Path: "dir/README.txt"})
152 p.Finish()
153 if fakeServer.NbCall.ModifyWebContent != 11+3+4 {
154 t.Fatalf("not called %d", fakeServer.NbCall.ModifyWebContent)
155 }
156}
157
158func TestIcon(t *testing.T) {
159 if ok := getIcon(".yml"); ok == "📄" {
160 t.Fatalf("icon markdown not found")
161 }
162}
163
164func TestEmoji(t *testing.T) {
165 loadEmojis()
166 if res := replaceEmoji(".yml"); res != ".yml" {
167 t.Fatalf("bad emoji for '.yml'")
168 }
169 if res := replaceEmoji(":fire:"); res != "🔥" {
170 t.Fatalf("bad emoji for ':fire:' %s", res)
171 }
172 if res := replaceEmoji("New release :rocket: :tada:"); res != "New release 🚀 🎉" {
173 t.Fatalf("bad emoji for 'New release :rocket: :tada:' %s", res)
174 }
175}