From 29f4479362f0878f70038e6347e584ce7ecb73c2 Mon Sep 17 00:00:00 2001 From: Drew Smirnoff Date: Sun, 4 Jan 2026 18:30:42 +0400 Subject: [PATCH] fix(view): test --- view/html_test.go | 353 +++++++--------------------------------------- 1 file changed, 48 insertions(+), 305 deletions(-) diff --git a/view/html_test.go b/view/html_test.go index 1b8cd1041566a0ac21de3c376fc982d9f4113288..b8b10900859c2535149a7d2a4ba2f29a718af888 100644 --- a/view/html_test.go +++ b/view/html_test.go @@ -98,105 +98,72 @@ func TestMarkdownToHTML(t *testing.T) { } } -func TestHyperlinkSupported(t *testing.T) { +func TestGhosttySupported(t *testing.T) { + // Save original environment variables + origTerm := os.Getenv("TERM") + origTermProgram := os.Getenv("TERM_PROGRAM") + origGhosttyResources := os.Getenv("GHOSTTY_RESOURCES_DIR") + + // Restore environment variables after test + defer func() { + os.Setenv("TERM", origTerm) + os.Setenv("TERM_PROGRAM", origTermProgram) + os.Setenv("GHOSTTY_RESOURCES_DIR", origGhosttyResources) + }() + testCases := []struct { - name string - term string - termProgram string - vteVersion string - kittyWindowID string - ghosttyResources string - weztermExecutable string - expected bool + name string + term string + termProgram string + ghosttyResourcesDir string + expected bool }{ { - name: "Kitty terminal", - term: "xterm-kitty", - expected: true, + name: "No Ghostty environment variables", + term: "xterm", + termProgram: "", + ghosttyResourcesDir: "", + expected: false, }, { - name: "Ghostty terminal", - term: "ghostty", - expected: true, + name: "TERM contains ghostty", + term: "xterm-ghostty", + termProgram: "", + ghosttyResourcesDir: "", + expected: true, }, { - name: "WezTerm terminal", - term: "wezterm", - expected: true, - }, - { - name: "Alacritty terminal", - term: "alacritty", - expected: true, - }, - { - name: "iTerm2 via TERM_PROGRAM", - term: "xterm-256color", - termProgram: "iTerm.app", - expected: true, - }, - { - name: "VTE-based terminal", - term: "xterm-256color", - vteVersion: "0.64.2", - expected: true, + name: "TERM_PROGRAM is ghostty", + term: "xterm", + termProgram: "ghostty", + ghosttyResourcesDir: "", + expected: true, }, { - name: "Kitty via env var", - term: "xterm-256color", - kittyWindowID: "1", - expected: true, + name: "GHOSTTY_RESOURCES_DIR is set", + term: "xterm", + termProgram: "", + ghosttyResourcesDir: "/usr/share/ghostty", + expected: true, }, { - name: "Ghostty via env var", - term: "xterm-256color", - ghosttyResources: "/opt/ghostty", - expected: true, - }, - { - name: "WezTerm via env var", - term: "xterm-256color", - weztermExecutable: "/usr/bin/wezterm", - expected: true, - }, - { - name: "Unsupported terminal", - term: "xterm", - expected: false, + name: "Multiple Ghostty indicators", + term: "ghostty", + termProgram: "ghostty", + ghosttyResourcesDir: "/usr/share/ghostty", + expected: true, }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - // Save original env vars - origTerm := os.Getenv("TERM") - origTermProgram := os.Getenv("TERM_PROGRAM") - origVteVersion := os.Getenv("VTE_VERSION") - origKittyWindowID := os.Getenv("KITTY_WINDOW_ID") - origGhosttyResources := os.Getenv("GHOSTTY_RESOURCES_DIR") - origWeztermExecutable := os.Getenv("WEZTERM_EXECUTABLE") - - // Set test env vars os.Setenv("TERM", tc.term) os.Setenv("TERM_PROGRAM", tc.termProgram) - os.Setenv("VTE_VERSION", tc.vteVersion) - os.Setenv("KITTY_WINDOW_ID", tc.kittyWindowID) - os.Setenv("GHOSTTY_RESOURCES_DIR", tc.ghosttyResources) - os.Setenv("WEZTERM_EXECUTABLE", tc.weztermExecutable) - - // Test the function - result := hyperlinkSupported() - - // Restore original env vars - os.Setenv("TERM", origTerm) - os.Setenv("TERM_PROGRAM", origTermProgram) - os.Setenv("VTE_VERSION", origVteVersion) - os.Setenv("KITTY_WINDOW_ID", origKittyWindowID) - os.Setenv("GHOSTTY_RESOURCES_DIR", origGhosttyResources) - os.Setenv("WEZTERM_EXECUTABLE", origWeztermExecutable) + os.Setenv("GHOSTTY_RESOURCES_DIR", tc.ghosttyResourcesDir) + result := ghosttySupported() if result != tc.expected { - t.Errorf("Expected %v, got %v", tc.expected, result) + t.Errorf("Expected %t, got %t", tc.expected, result) } }) } @@ -361,8 +328,9 @@ func TestImageProtocolSupported(t *testing.T) { tc.clearAllEnv() tc.setupEnv() + result := imageProtocolSupported() if result != tc.expected { - t.Errorf("Expected %q, got %q", tc.expected, result) + t.Errorf("Expected %t, got %t", tc.expected, result) } }) } @@ -728,228 +696,3 @@ func TestProcessBody(t *testing.T) { }) } } - -func TestProcessBodyWithHyperlinkSupport(t *testing.T) { - h1Style := lipgloss.NewStyle() - h2Style := lipgloss.NewStyle() - bodyStyle := lipgloss.NewStyle() - - testCases := []struct { - name string - input string - hyperlinkSupported bool - expectedContains []string - expectedNotContains []string - }{ - { - name: "Link with hyperlink support", - input: `Click here`, - hyperlinkSupported: true, - expectedContains: []string{"\x1b]8;;https://example.com\x07Click here\x1b]8;;\x07"}, - expectedNotContains: []string{""}, - }, - { - name: "Link without hyperlink support", - input: `Click here`, - hyperlinkSupported: false, - expectedContains: []string{"Click here "}, - expectedNotContains: []string{"\x1b]8;;"}, - }, - { - name: "Image with hyperlink support", - input: `Test image`, - hyperlinkSupported: true, - expectedContains: []string{"\x1b]8;;https://example.com/image.png\x07", "[Click here to view image: Test image]"}, - expectedNotContains: []string{""}, - }, - { - name: "Image without hyperlink support", - input: `Test image`, - hyperlinkSupported: false, - expectedContains: []string{"[Image: Test image, https://example.com/image.png]"}, - expectedNotContains: []string{"\x1b]8;;", "[Click here to view image:"}, - }, - { - name: "Markdown link with hyperlink support", - input: `[Visit our site](https://example.com)`, - hyperlinkSupported: true, - expectedContains: []string{"\x1b]8;;https://example.com\x07Visit our site\x1b]8;;\x07"}, - expectedNotContains: []string{""}, - }, - { - name: "Markdown link without hyperlink support", - input: `[Visit our site](https://example.com)`, - hyperlinkSupported: false, - expectedContains: []string{"Visit our site "}, - expectedNotContains: []string{"\x1b]8;;"}, - }, - { - name: "Markdown image with hyperlink support", - input: `![Beautiful sunset](https://example.com/sunset.jpg)`, - hyperlinkSupported: true, - expectedContains: []string{"\x1b]8;;https://example.com/sunset.jpg\x07", "[Click here to view image: Beautiful sunset]"}, - expectedNotContains: []string{""}, - }, - { - name: "Markdown image without hyperlink support", - input: `![Beautiful sunset](https://example.com/sunset.jpg)`, - hyperlinkSupported: false, - expectedContains: []string{"[Image: Beautiful sunset, https://example.com/sunset.jpg]"}, - expectedNotContains: []string{"\x1b]8;;", "[Click here to view image:"}, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - // Save original env vars - origTerm := os.Getenv("TERM") - origTermProgram := os.Getenv("TERM_PROGRAM") - origVteVersion := os.Getenv("VTE_VERSION") - origKittyWindowID := os.Getenv("KITTY_WINDOW_ID") - origGhosttyResources := os.Getenv("GHOSTTY_RESOURCES_DIR") - origWeztermExecutable := os.Getenv("WEZTERM_EXECUTABLE") - - // Set env to control hyperlink support - if tc.hyperlinkSupported { - os.Setenv("TERM", "xterm-kitty") - } else { - // Clear all environment variables that could indicate hyperlink support - os.Setenv("TERM", "xterm") - os.Unsetenv("TERM_PROGRAM") - os.Unsetenv("VTE_VERSION") - os.Unsetenv("KITTY_WINDOW_ID") - os.Unsetenv("GHOSTTY_RESOURCES_DIR") - os.Unsetenv("WEZTERM_EXECUTABLE") - } - - processed, err := ProcessBody(tc.input, h1Style, h2Style, bodyStyle) - - // Restore original env vars - os.Setenv("TERM", origTerm) - os.Setenv("TERM_PROGRAM", origTermProgram) - os.Setenv("VTE_VERSION", origVteVersion) - os.Setenv("KITTY_WINDOW_ID", origKittyWindowID) - os.Setenv("GHOSTTY_RESOURCES_DIR", origGhosttyResources) - os.Setenv("WEZTERM_EXECUTABLE", origWeztermExecutable) - - if err != nil { - t.Fatalf("ProcessBody() failed: %v", err) - } - - // Check that expected strings are present - for _, expected := range tc.expectedContains { - if !strings.Contains(processed, expected) { - t.Errorf("Expected processed body to contain %q, but it didn't.\nProcessed: %q", expected, processed) - } - } - - // Check that unexpected strings are not present - for _, notExpected := range tc.expectedNotContains { - if strings.Contains(processed, notExpected) { - t.Errorf("Expected processed body to NOT contain %q, but it did.\nProcessed: %q", notExpected, processed) - } - } - }) - } -} - -func TestImageAndLinkFallbackBehavior(t *testing.T) { - h1Style := lipgloss.NewStyle() - h2Style := lipgloss.NewStyle() - bodyStyle := lipgloss.NewStyle() - - testCases := []struct { - name string - input string - hyperlinkSupported bool - imageProtocolSupported bool - expectedContains []string - expectedNotContains []string - }{ - { - name: "Full support - both image protocol and hyperlinks", - input: `Test image and link`, - hyperlinkSupported: true, - imageProtocolSupported: true, - expectedContains: []string{"\x1b]8;;https://example.com\x07link\x1b]8;;\x07", "\x1b]8;;https://example.com/image.png\x07", "[Click here to view image: Test image]"}, - expectedNotContains: []string{"", "[Image:"}, - }, - { - name: "Hyperlink support only - no image protocol", - input: `Test image and link`, - hyperlinkSupported: true, - imageProtocolSupported: false, - expectedContains: []string{"\x1b]8;;https://example.com\x07link\x1b]8;;\x07", "\x1b]8;;https://example.com/image.png\x07", "[Click here to view image: Test image]"}, - expectedNotContains: []string{"", "[Image:"}, - }, - { - name: "No support - plain text fallback", - input: `Test image and link`, - hyperlinkSupported: false, - imageProtocolSupported: false, - expectedContains: []string{"link ", "[Image: Test image, https://example.com/image.png]"}, - expectedNotContains: []string{"\x1b]8;;", "[Click here to view image:"}, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - // Save original env vars - origTerm := os.Getenv("TERM") - origTermProgram := os.Getenv("TERM_PROGRAM") - origVteVersion := os.Getenv("VTE_VERSION") - origKittyWindowID := os.Getenv("KITTY_WINDOW_ID") - origGhosttyResources := os.Getenv("GHOSTTY_RESOURCES_DIR") - origWeztermExecutable := os.Getenv("WEZTERM_EXECUTABLE") - - // Set environment for hyperlink support - if tc.hyperlinkSupported { - os.Setenv("TERM", "xterm-kitty") - } else { - os.Setenv("TERM", "xterm") - os.Unsetenv("TERM_PROGRAM") - os.Unsetenv("VTE_VERSION") - os.Unsetenv("KITTY_WINDOW_ID") - os.Unsetenv("GHOSTTY_RESOURCES_DIR") - os.Unsetenv("WEZTERM_EXECUTABLE") - } - - // Set environment for image protocol support - if tc.imageProtocolSupported && !tc.hyperlinkSupported { - // This case shouldn't happen in practice, but test it anyway - os.Setenv("KITTY_WINDOW_ID", "1") - } else if !tc.imageProtocolSupported { - os.Unsetenv("KITTY_WINDOW_ID") - os.Unsetenv("GHOSTTY_RESOURCES_DIR") - } - - processed, err := ProcessBody(tc.input, h1Style, h2Style, bodyStyle) - - // Restore original env vars - os.Setenv("TERM", origTerm) - os.Setenv("TERM_PROGRAM", origTermProgram) - os.Setenv("VTE_VERSION", origVteVersion) - os.Setenv("KITTY_WINDOW_ID", origKittyWindowID) - os.Setenv("GHOSTTY_RESOURCES_DIR", origGhosttyResources) - os.Setenv("WEZTERM_EXECUTABLE", origWeztermExecutable) - - if err != nil { - t.Fatalf("ProcessBody() failed: %v", err) - } - - // Check that expected strings are present - for _, expected := range tc.expectedContains { - if !strings.Contains(processed, expected) { - t.Errorf("Expected processed body to contain %q, but it didn't.\nProcessed: %q", expected, processed) - } - } - - // Check that unexpected strings are not present - for _, notExpected := range tc.expectedNotContains { - if strings.Contains(processed, notExpected) { - t.Errorf("Expected processed body to NOT contain %q, but it did.\nProcessed: %q", notExpected, processed) - } - } - }) - } -}