9 "github.com/alecthomas/chroma/v2/styles"
10 "github.com/charmbracelet/crush/internal/ui/diffview"
11 "github.com/charmbracelet/x/ansi"
12 "github.com/charmbracelet/x/exp/golden"
15//go:embed testdata/TestDefault.before
16var TestDefaultBefore string
18//go:embed testdata/TestDefault.after
19var TestDefaultAfter string
21//go:embed testdata/TestMultipleHunks.before
22var TestMultipleHunksBefore string
24//go:embed testdata/TestMultipleHunks.after
25var TestMultipleHunksAfter string
27//go:embed testdata/TestNarrow.before
28var TestNarrowBefore string
30//go:embed testdata/TestNarrow.after
31var TestNarrowAfter string
33//go:embed testdata/TestTabs.before
34var TestTabsBefore string
36//go:embed testdata/TestTabs.after
37var TestTabsAfter string
39//go:embed testdata/TestLineBreakIssue.before
40var TestLineBreakIssueBefore string
42//go:embed testdata/TestLineBreakIssue.after
43var TestLineBreakIssueAfter string
46 TestFunc func(dv *diffview.DiffView) *diffview.DiffView
47 TestFuncs map[string]TestFunc
51 UnifiedFunc = func(dv *diffview.DiffView) *diffview.DiffView {
54 SplitFunc = func(dv *diffview.DiffView) *diffview.DiffView {
58 DefaultFunc = func(dv *diffview.DiffView) *diffview.DiffView {
60 Before("main.go", TestDefaultBefore).
61 After("main.go", TestDefaultAfter)
63 NoLineNumbersFunc = func(dv *diffview.DiffView) *diffview.DiffView {
65 Before("main.go", TestDefaultBefore).
66 After("main.go", TestDefaultAfter).
69 MultipleHunksFunc = func(dv *diffview.DiffView) *diffview.DiffView {
71 Before("main.go", TestMultipleHunksBefore).
72 After("main.go", TestMultipleHunksAfter)
74 CustomContextLinesFunc = func(dv *diffview.DiffView) *diffview.DiffView {
76 Before("main.go", TestMultipleHunksBefore).
77 After("main.go", TestMultipleHunksAfter).
80 NarrowFunc = func(dv *diffview.DiffView) *diffview.DiffView {
82 Before("text.txt", TestNarrowBefore).
83 After("text.txt", TestNarrowAfter)
85 SmallWidthFunc = func(dv *diffview.DiffView) *diffview.DiffView {
87 Before("main.go", TestMultipleHunksBefore).
88 After("main.go", TestMultipleHunksAfter).
91 LargeWidthFunc = func(dv *diffview.DiffView) *diffview.DiffView {
93 Before("main.go", TestMultipleHunksBefore).
94 After("main.go", TestMultipleHunksAfter).
97 NoSyntaxHighlightFunc = func(dv *diffview.DiffView) *diffview.DiffView {
99 Before("main.go", TestMultipleHunksBefore).
100 After("main.go", TestMultipleHunksAfter).
104 LightModeFunc = func(dv *diffview.DiffView) *diffview.DiffView {
106 Style(diffview.DefaultLightStyle()).
107 ChromaStyle(styles.Get("catppuccin-latte"))
109 DarkModeFunc = func(dv *diffview.DiffView) *diffview.DiffView {
111 Style(diffview.DefaultDarkStyle()).
112 ChromaStyle(styles.Get("catppuccin-macchiato"))
115 LayoutFuncs = TestFuncs{
116 "Unified": UnifiedFunc,
119 BehaviorFuncs = TestFuncs{
120 "Default": DefaultFunc,
121 "NoLineNumbers": NoLineNumbersFunc,
122 "MultipleHunks": MultipleHunksFunc,
123 "CustomContextLines": CustomContextLinesFunc,
124 "Narrow": NarrowFunc,
125 "SmallWidth": SmallWidthFunc,
126 "LargeWidth": LargeWidthFunc,
127 "NoSyntaxHighlight": NoSyntaxHighlightFunc,
129 ThemeFuncs = TestFuncs{
130 "LightMode": LightModeFunc,
131 "DarkMode": DarkModeFunc,
135func TestDiffView(t *testing.T) {
136 for layoutName, layoutFunc := range LayoutFuncs {
137 t.Run(layoutName, func(t *testing.T) {
138 for behaviorName, behaviorFunc := range BehaviorFuncs {
139 t.Run(behaviorName, func(t *testing.T) {
140 for themeName, themeFunc := range ThemeFuncs {
141 t.Run(themeName, func(t *testing.T) {
147 dv = behaviorFunc(dv)
149 output := dv.String()
150 golden.RequireEqual(t, []byte(output))
152 switch behaviorName {
154 assertLineWidth(t, 40, output)
156 assertLineWidth(t, 120, output)
166func TestDiffViewTabs(t *testing.T) {
169 for layoutName, layoutFunc := range LayoutFuncs {
170 t.Run(layoutName, func(t *testing.T) {
173 dv := diffview.New().
174 Before("main.go", TestTabsBefore).
175 After("main.go", TestTabsAfter).
176 Style(diffview.DefaultLightStyle()).
177 ChromaStyle(styles.Get("catppuccin-latte"))
180 output := dv.String()
181 golden.RequireEqual(t, []byte(output))
186func TestDiffViewLineBreakIssue(t *testing.T) {
189 for layoutName, layoutFunc := range LayoutFuncs {
190 t.Run(layoutName, func(t *testing.T) {
193 dv := diffview.New().
194 Before("index.js", TestLineBreakIssueBefore).
195 After("index.js", TestLineBreakIssueAfter).
196 Style(diffview.DefaultLightStyle()).
197 ChromaStyle(styles.Get("catppuccin-latte"))
200 output := dv.String()
201 golden.RequireEqual(t, []byte(output))
206func TestDiffViewWidth(t *testing.T) {
207 for layoutName, layoutFunc := range LayoutFuncs {
208 t.Run(layoutName, func(t *testing.T) {
209 for width := 1; width <= 110; width++ {
210 if layoutName == "Unified" && width > 60 {
214 t.Run(fmt.Sprintf("WidthOf%03d", width), func(t *testing.T) {
217 dv := diffview.New().
218 Before("main.go", TestMultipleHunksBefore).
219 After("main.go", TestMultipleHunksAfter).
221 Style(diffview.DefaultLightStyle()).
222 ChromaStyle(styles.Get("catppuccin-latte"))
225 output := dv.String()
226 golden.RequireEqual(t, []byte(output))
228 assertLineWidth(t, width, output)
235func TestDiffViewHeight(t *testing.T) {
236 for layoutName, layoutFunc := range LayoutFuncs {
237 t.Run(layoutName, func(t *testing.T) {
238 for height := 1; height <= 20; height++ {
239 t.Run(fmt.Sprintf("HeightOf%03d", height), func(t *testing.T) {
242 dv := diffview.New().
243 Before("main.go", TestMultipleHunksBefore).
244 After("main.go", TestMultipleHunksAfter).
246 Style(diffview.DefaultLightStyle()).
247 ChromaStyle(styles.Get("catppuccin-latte"))
250 output := dv.String()
251 golden.RequireEqual(t, []byte(output))
258func TestDiffViewXOffset(t *testing.T) {
259 for layoutName, layoutFunc := range LayoutFuncs {
260 t.Run(layoutName, func(t *testing.T) {
261 for xOffset := range 21 {
262 t.Run(fmt.Sprintf("XOffsetOf%02d", xOffset), func(t *testing.T) {
265 dv := diffview.New().
266 Before("main.go", TestDefaultBefore).
267 After("main.go", TestDefaultAfter).
268 Style(diffview.DefaultLightStyle()).
269 ChromaStyle(styles.Get("catppuccin-latte")).
274 output := dv.String()
275 golden.RequireEqual(t, []byte(output))
277 assertLineWidth(t, 60, output)
284func TestDiffViewYOffset(t *testing.T) {
285 for layoutName, layoutFunc := range LayoutFuncs {
286 t.Run(layoutName, func(t *testing.T) {
287 for yOffset := range 17 {
288 t.Run(fmt.Sprintf("YOffsetOf%02d", yOffset), func(t *testing.T) {
291 dv := diffview.New().
292 Before("main.go", TestMultipleHunksBefore).
293 After("main.go", TestMultipleHunksAfter).
294 Style(diffview.DefaultLightStyle()).
295 ChromaStyle(styles.Get("catppuccin-latte")).
300 output := dv.String()
301 golden.RequireEqual(t, []byte(output))
308func TestDiffViewYOffsetInfinite(t *testing.T) {
309 for layoutName, layoutFunc := range LayoutFuncs {
310 t.Run(layoutName, func(t *testing.T) {
311 for yOffset := range 17 {
312 t.Run(fmt.Sprintf("YOffsetOf%02d", yOffset), func(t *testing.T) {
315 dv := diffview.New().
316 Before("main.go", TestMultipleHunksBefore).
317 After("main.go", TestMultipleHunksAfter).
318 Style(diffview.DefaultLightStyle()).
319 ChromaStyle(styles.Get("catppuccin-latte")).
322 InfiniteYScroll(true)
325 output := dv.String()
326 golden.RequireEqual(t, []byte(output))
333func assertLineWidth(t *testing.T, expected int, output string) {
335 for line := range strings.SplitSeq(output, "\n") {
336 lineWidth = max(lineWidth, ansi.StringWidth(line))
338 if lineWidth != expected {
339 t.Errorf("expected output width to be == %d, got %d", expected, lineWidth)
343func assertHeight(t *testing.T, expected int, output string) {
344 output = strings.TrimSuffix(output, "\n")
345 lines := strings.Count(output, "\n") + 1
346 if lines != expected {
347 t.Errorf("expected output height to be == %d, got %d", expected, lines)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list