9 "github.com/charmbracelet/x/ansi"
10 "github.com/charmbracelet/x/exp/golden"
11 "github.com/opencode-ai/opencode/internal/exp/diffview"
14//go:embed testdata/TestDefault.before
15var TestDefaultBefore string
17//go:embed testdata/TestDefault.after
18var TestDefaultAfter string
20//go:embed testdata/TestMultipleHunks.before
21var TestMultipleHunksBefore string
23//go:embed testdata/TestMultipleHunks.after
24var TestMultipleHunksAfter string
26//go:embed testdata/TestNarrow.before
27var TestNarrowBefore string
29//go:embed testdata/TestNarrow.after
30var TestNarrowAfter string
32//go:embed testdata/TestTabs.before
33var TestTabsBefore string
35//go:embed testdata/TestTabs.after
36var TestTabsAfter string
39 TestFunc func(dv *diffview.DiffView) *diffview.DiffView
40 TestFuncs map[string]TestFunc
44 UnifiedFunc = func(dv *diffview.DiffView) *diffview.DiffView {
47 SplitFunc = func(dv *diffview.DiffView) *diffview.DiffView {
51 DefaultFunc = func(dv *diffview.DiffView) *diffview.DiffView {
53 Before("main.go", TestDefaultBefore).
54 After("main.go", TestDefaultAfter)
56 NoLineNumbersFunc = func(dv *diffview.DiffView) *diffview.DiffView {
58 Before("main.go", TestDefaultBefore).
59 After("main.go", TestDefaultAfter).
62 MultipleHunksFunc = func(dv *diffview.DiffView) *diffview.DiffView {
64 Before("main.go", TestMultipleHunksBefore).
65 After("main.go", TestMultipleHunksAfter)
67 CustomContextLinesFunc = func(dv *diffview.DiffView) *diffview.DiffView {
69 Before("main.go", TestMultipleHunksBefore).
70 After("main.go", TestMultipleHunksAfter).
73 NarrowFunc = func(dv *diffview.DiffView) *diffview.DiffView {
75 Before("text.txt", TestNarrowBefore).
76 After("text.txt", TestNarrowAfter)
78 SmallWidthFunc = func(dv *diffview.DiffView) *diffview.DiffView {
80 Before("main.go", TestMultipleHunksBefore).
81 After("main.go", TestMultipleHunksAfter).
84 LargeWidthFunc = func(dv *diffview.DiffView) *diffview.DiffView {
86 Before("main.go", TestMultipleHunksBefore).
87 After("main.go", TestMultipleHunksAfter).
91 LightModeFunc = func(dv *diffview.DiffView) *diffview.DiffView {
92 return dv.Style(diffview.DefaultLightStyle)
94 DarkModeFunc = func(dv *diffview.DiffView) *diffview.DiffView {
95 return dv.Style(diffview.DefaultDarkStyle)
98 LayoutFuncs = TestFuncs{
99 "Unified": UnifiedFunc,
102 BehaviorFuncs = TestFuncs{
103 "Default": DefaultFunc,
104 "NoLineNumbers": NoLineNumbersFunc,
105 "MultipleHunks": MultipleHunksFunc,
106 "CustomContextLines": CustomContextLinesFunc,
107 "Narrow": NarrowFunc,
108 "SmallWidth": SmallWidthFunc,
109 "LargeWidth": LargeWidthFunc,
111 ThemeFuncs = TestFuncs{
112 "LightMode": LightModeFunc,
113 "DarkMode": DarkModeFunc,
117func TestDiffView(t *testing.T) {
118 for layoutName, layoutFunc := range LayoutFuncs {
119 t.Run(layoutName, func(t *testing.T) {
120 for behaviorName, behaviorFunc := range BehaviorFuncs {
121 t.Run(behaviorName, func(t *testing.T) {
122 for themeName, themeFunc := range ThemeFuncs {
123 t.Run(themeName, func(t *testing.T) {
126 dv = behaviorFunc(dv)
129 output := dv.String()
130 golden.RequireEqual(t, []byte(output))
132 switch behaviorName {
134 assertLineWidth(t, 40, output)
136 assertLineWidth(t, 120, output)
146func TestDiffViewTabs(t *testing.T) {
147 for layoutName, layoutFunc := range LayoutFuncs {
148 t.Run(layoutName, func(t *testing.T) {
149 dv := diffview.New().
150 Before("main.go", TestTabsBefore).
151 After("main.go", TestTabsAfter).
152 Style(diffview.DefaultLightStyle)
155 output := dv.String()
156 golden.RequireEqual(t, []byte(output))
161func TestDiffViewWidth(t *testing.T) {
162 for layoutName, layoutFunc := range LayoutFuncs {
163 t.Run(layoutName, func(t *testing.T) {
164 for width := 1; width <= 110; width++ {
165 if layoutName == "Unified" && width > 60 {
169 t.Run(fmt.Sprintf("WidthOf%03d", width), func(t *testing.T) {
170 dv := diffview.New().
171 Before("main.go", TestMultipleHunksBefore).
172 After("main.go", TestMultipleHunksAfter).
174 Style(diffview.DefaultLightStyle)
177 output := dv.String()
178 golden.RequireEqual(t, []byte(output))
180 assertLineWidth(t, width, output)
187func TestDiffViewHeight(t *testing.T) {
188 for layoutName, layoutFunc := range LayoutFuncs {
189 t.Run(layoutName, func(t *testing.T) {
190 for height := 1; height <= 20; height++ {
191 t.Run(fmt.Sprintf("HeightOf%03d", height), func(t *testing.T) {
192 dv := diffview.New().
193 Before("main.go", TestMultipleHunksBefore).
194 After("main.go", TestMultipleHunksAfter).
196 Style(diffview.DefaultLightStyle)
199 output := dv.String()
200 golden.RequireEqual(t, []byte(output))
202 assertHeight(t, height, output)
209func TestDiffViewXOffset(t *testing.T) {
210 for layoutName, layoutFunc := range LayoutFuncs {
211 t.Run(layoutName, func(t *testing.T) {
212 for xOffset := range 21 {
213 t.Run(fmt.Sprintf("XOffsetOf%02d", xOffset), func(t *testing.T) {
214 dv := diffview.New().
215 Before("main.go", TestDefaultBefore).
216 After("main.go", TestDefaultAfter).
217 Style(diffview.DefaultLightStyle).
222 output := dv.String()
223 golden.RequireEqual(t, []byte(output))
225 assertLineWidth(t, 60, output)
232func TestDiffViewYOffset(t *testing.T) {
233 for layoutName, layoutFunc := range LayoutFuncs {
234 t.Run(layoutName, func(t *testing.T) {
235 for yOffset := range 17 {
236 t.Run(fmt.Sprintf("YOffsetOf%02d", yOffset), func(t *testing.T) {
237 dv := diffview.New().
238 Before("main.go", TestMultipleHunksBefore).
239 After("main.go", TestMultipleHunksAfter).
240 Style(diffview.DefaultLightStyle).
245 output := dv.String()
246 golden.RequireEqual(t, []byte(output))
248 assertHeight(t, 5, output)
255func assertLineWidth(t *testing.T, expected int, output string) {
257 for line := range strings.SplitSeq(output, "\n") {
258 lineWidth = max(lineWidth, ansi.StringWidth(line))
260 if lineWidth != expected {
261 t.Errorf("expected output width to be == %d, got %d", expected, lineWidth)
265func assertHeight(t *testing.T, expected int, output string) {
266 output = strings.TrimSuffix(output, "\n")
267 lines := strings.Count(output, "\n") + 1
268 if lines != expected {
269 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