| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349 |
- package diffview_test
- import (
- _ "embed"
- "fmt"
- "strings"
- "testing"
- "github.com/alecthomas/chroma/v2/styles"
- "github.com/charmbracelet/crush/internal/ui/diffview"
- "github.com/charmbracelet/x/ansi"
- "github.com/charmbracelet/x/exp/golden"
- )
- //go:embed testdata/TestDefault.before
- var TestDefaultBefore string
- //go:embed testdata/TestDefault.after
- var TestDefaultAfter string
- //go:embed testdata/TestMultipleHunks.before
- var TestMultipleHunksBefore string
- //go:embed testdata/TestMultipleHunks.after
- var TestMultipleHunksAfter string
- //go:embed testdata/TestNarrow.before
- var TestNarrowBefore string
- //go:embed testdata/TestNarrow.after
- var TestNarrowAfter string
- //go:embed testdata/TestTabs.before
- var TestTabsBefore string
- //go:embed testdata/TestTabs.after
- var TestTabsAfter string
- //go:embed testdata/TestLineBreakIssue.before
- var TestLineBreakIssueBefore string
- //go:embed testdata/TestLineBreakIssue.after
- var TestLineBreakIssueAfter string
- type (
- TestFunc func(dv *diffview.DiffView) *diffview.DiffView
- TestFuncs map[string]TestFunc
- )
- var (
- UnifiedFunc = func(dv *diffview.DiffView) *diffview.DiffView {
- return dv.Unified()
- }
- SplitFunc = func(dv *diffview.DiffView) *diffview.DiffView {
- return dv.Split()
- }
- DefaultFunc = func(dv *diffview.DiffView) *diffview.DiffView {
- return dv.
- Before("main.go", TestDefaultBefore).
- After("main.go", TestDefaultAfter)
- }
- NoLineNumbersFunc = func(dv *diffview.DiffView) *diffview.DiffView {
- return dv.
- Before("main.go", TestDefaultBefore).
- After("main.go", TestDefaultAfter).
- LineNumbers(false)
- }
- MultipleHunksFunc = func(dv *diffview.DiffView) *diffview.DiffView {
- return dv.
- Before("main.go", TestMultipleHunksBefore).
- After("main.go", TestMultipleHunksAfter)
- }
- CustomContextLinesFunc = func(dv *diffview.DiffView) *diffview.DiffView {
- return dv.
- Before("main.go", TestMultipleHunksBefore).
- After("main.go", TestMultipleHunksAfter).
- ContextLines(4)
- }
- NarrowFunc = func(dv *diffview.DiffView) *diffview.DiffView {
- return dv.
- Before("text.txt", TestNarrowBefore).
- After("text.txt", TestNarrowAfter)
- }
- SmallWidthFunc = func(dv *diffview.DiffView) *diffview.DiffView {
- return dv.
- Before("main.go", TestMultipleHunksBefore).
- After("main.go", TestMultipleHunksAfter).
- Width(40)
- }
- LargeWidthFunc = func(dv *diffview.DiffView) *diffview.DiffView {
- return dv.
- Before("main.go", TestMultipleHunksBefore).
- After("main.go", TestMultipleHunksAfter).
- Width(120)
- }
- NoSyntaxHighlightFunc = func(dv *diffview.DiffView) *diffview.DiffView {
- return dv.
- Before("main.go", TestMultipleHunksBefore).
- After("main.go", TestMultipleHunksAfter).
- ChromaStyle(nil)
- }
- LightModeFunc = func(dv *diffview.DiffView) *diffview.DiffView {
- return dv.
- Style(diffview.DefaultLightStyle()).
- ChromaStyle(styles.Get("catppuccin-latte"))
- }
- DarkModeFunc = func(dv *diffview.DiffView) *diffview.DiffView {
- return dv.
- Style(diffview.DefaultDarkStyle()).
- ChromaStyle(styles.Get("catppuccin-macchiato"))
- }
- LayoutFuncs = TestFuncs{
- "Unified": UnifiedFunc,
- "Split": SplitFunc,
- }
- BehaviorFuncs = TestFuncs{
- "Default": DefaultFunc,
- "NoLineNumbers": NoLineNumbersFunc,
- "MultipleHunks": MultipleHunksFunc,
- "CustomContextLines": CustomContextLinesFunc,
- "Narrow": NarrowFunc,
- "SmallWidth": SmallWidthFunc,
- "LargeWidth": LargeWidthFunc,
- "NoSyntaxHighlight": NoSyntaxHighlightFunc,
- }
- ThemeFuncs = TestFuncs{
- "LightMode": LightModeFunc,
- "DarkMode": DarkModeFunc,
- }
- )
- func TestDiffView(t *testing.T) {
- for layoutName, layoutFunc := range LayoutFuncs {
- t.Run(layoutName, func(t *testing.T) {
- for behaviorName, behaviorFunc := range BehaviorFuncs {
- t.Run(behaviorName, func(t *testing.T) {
- for themeName, themeFunc := range ThemeFuncs {
- t.Run(themeName, func(t *testing.T) {
- t.Parallel()
- dv := diffview.New()
- dv = layoutFunc(dv)
- dv = themeFunc(dv)
- dv = behaviorFunc(dv)
- output := dv.String()
- golden.RequireEqual(t, []byte(output))
- switch behaviorName {
- case "SmallWidth":
- assertLineWidth(t, 40, output)
- case "LargeWidth":
- assertLineWidth(t, 120, output)
- }
- })
- }
- })
- }
- })
- }
- }
- func TestDiffViewTabs(t *testing.T) {
- t.Parallel()
- for layoutName, layoutFunc := range LayoutFuncs {
- t.Run(layoutName, func(t *testing.T) {
- t.Parallel()
- dv := diffview.New().
- Before("main.go", TestTabsBefore).
- After("main.go", TestTabsAfter).
- Style(diffview.DefaultLightStyle()).
- ChromaStyle(styles.Get("catppuccin-latte"))
- dv = layoutFunc(dv)
- output := dv.String()
- golden.RequireEqual(t, []byte(output))
- })
- }
- }
- func TestDiffViewLineBreakIssue(t *testing.T) {
- t.Parallel()
- for layoutName, layoutFunc := range LayoutFuncs {
- t.Run(layoutName, func(t *testing.T) {
- t.Parallel()
- dv := diffview.New().
- Before("index.js", TestLineBreakIssueBefore).
- After("index.js", TestLineBreakIssueAfter).
- Style(diffview.DefaultLightStyle()).
- ChromaStyle(styles.Get("catppuccin-latte"))
- dv = layoutFunc(dv)
- output := dv.String()
- golden.RequireEqual(t, []byte(output))
- })
- }
- }
- func TestDiffViewWidth(t *testing.T) {
- for layoutName, layoutFunc := range LayoutFuncs {
- t.Run(layoutName, func(t *testing.T) {
- for width := 1; width <= 110; width++ {
- if layoutName == "Unified" && width > 60 {
- continue
- }
- t.Run(fmt.Sprintf("WidthOf%03d", width), func(t *testing.T) {
- t.Parallel()
- dv := diffview.New().
- Before("main.go", TestMultipleHunksBefore).
- After("main.go", TestMultipleHunksAfter).
- Width(width).
- Style(diffview.DefaultLightStyle()).
- ChromaStyle(styles.Get("catppuccin-latte"))
- dv = layoutFunc(dv)
- output := dv.String()
- golden.RequireEqual(t, []byte(output))
- assertLineWidth(t, width, output)
- })
- }
- })
- }
- }
- func TestDiffViewHeight(t *testing.T) {
- for layoutName, layoutFunc := range LayoutFuncs {
- t.Run(layoutName, func(t *testing.T) {
- for height := 1; height <= 20; height++ {
- t.Run(fmt.Sprintf("HeightOf%03d", height), func(t *testing.T) {
- t.Parallel()
- dv := diffview.New().
- Before("main.go", TestMultipleHunksBefore).
- After("main.go", TestMultipleHunksAfter).
- Height(height).
- Style(diffview.DefaultLightStyle()).
- ChromaStyle(styles.Get("catppuccin-latte"))
- dv = layoutFunc(dv)
- output := dv.String()
- golden.RequireEqual(t, []byte(output))
- })
- }
- })
- }
- }
- func TestDiffViewXOffset(t *testing.T) {
- for layoutName, layoutFunc := range LayoutFuncs {
- t.Run(layoutName, func(t *testing.T) {
- for xOffset := range 21 {
- t.Run(fmt.Sprintf("XOffsetOf%02d", xOffset), func(t *testing.T) {
- t.Parallel()
- dv := diffview.New().
- Before("main.go", TestDefaultBefore).
- After("main.go", TestDefaultAfter).
- Style(diffview.DefaultLightStyle()).
- ChromaStyle(styles.Get("catppuccin-latte")).
- Width(60).
- XOffset(xOffset)
- dv = layoutFunc(dv)
- output := dv.String()
- golden.RequireEqual(t, []byte(output))
- assertLineWidth(t, 60, output)
- })
- }
- })
- }
- }
- func TestDiffViewYOffset(t *testing.T) {
- for layoutName, layoutFunc := range LayoutFuncs {
- t.Run(layoutName, func(t *testing.T) {
- for yOffset := range 17 {
- t.Run(fmt.Sprintf("YOffsetOf%02d", yOffset), func(t *testing.T) {
- t.Parallel()
- dv := diffview.New().
- Before("main.go", TestMultipleHunksBefore).
- After("main.go", TestMultipleHunksAfter).
- Style(diffview.DefaultLightStyle()).
- ChromaStyle(styles.Get("catppuccin-latte")).
- Height(5).
- YOffset(yOffset)
- dv = layoutFunc(dv)
- output := dv.String()
- golden.RequireEqual(t, []byte(output))
- })
- }
- })
- }
- }
- func TestDiffViewYOffsetInfinite(t *testing.T) {
- for layoutName, layoutFunc := range LayoutFuncs {
- t.Run(layoutName, func(t *testing.T) {
- for yOffset := range 17 {
- t.Run(fmt.Sprintf("YOffsetOf%02d", yOffset), func(t *testing.T) {
- t.Parallel()
- dv := diffview.New().
- Before("main.go", TestMultipleHunksBefore).
- After("main.go", TestMultipleHunksAfter).
- Style(diffview.DefaultLightStyle()).
- ChromaStyle(styles.Get("catppuccin-latte")).
- Height(5).
- YOffset(yOffset).
- InfiniteYScroll(true)
- dv = layoutFunc(dv)
- output := dv.String()
- golden.RequireEqual(t, []byte(output))
- })
- }
- })
- }
- }
- func assertLineWidth(t *testing.T, expected int, output string) {
- var lineWidth int
- for line := range strings.SplitSeq(output, "\n") {
- lineWidth = max(lineWidth, ansi.StringWidth(line))
- }
- if lineWidth != expected {
- t.Errorf("expected output width to be == %d, got %d", expected, lineWidth)
- }
- }
- func assertHeight(t *testing.T, expected int, output string) {
- output = strings.TrimSuffix(output, "\n")
- lines := strings.Count(output, "\n") + 1
- if lines != expected {
- t.Errorf("expected output height to be == %d, got %d", expected, lines)
- }
- }
|