@@ -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: `<a href="https://example.com">Click here</a>`,
- hyperlinkSupported: true,
- expectedContains: []string{"\x1b]8;;https://example.com\x07Click here\x1b]8;;\x07"},
- expectedNotContains: []string{"<https://example.com>"},
- },
- {
- name: "Link without hyperlink support",
- input: `<a href="https://example.com">Click here</a>`,
- hyperlinkSupported: false,
- expectedContains: []string{"Click here <https://example.com>"},
- expectedNotContains: []string{"\x1b]8;;"},
- },
- {
- name: "Image with hyperlink support",
- input: `<img src="https://example.com/image.png" alt="Test image">`,
- hyperlinkSupported: true,
- expectedContains: []string{"\x1b]8;;https://example.com/image.png\x07", "[Click here to view image: Test image]"},
- expectedNotContains: []string{"<https://example.com/image.png>"},
- },
- {
- name: "Image without hyperlink support",
- input: `<img src="https://example.com/image.png" alt="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{"<https://example.com>"},
- },
- {
- name: "Markdown link without hyperlink support",
- input: `[Visit our site](https://example.com)`,
- hyperlinkSupported: false,
- expectedContains: []string{"Visit our site <https://example.com>"},
- expectedNotContains: []string{"\x1b]8;;"},
- },
- {
- name: "Markdown image with hyperlink support",
- input: ``,
- hyperlinkSupported: true,
- expectedContains: []string{"\x1b]8;;https://example.com/sunset.jpg\x07", "[Click here to view image: Beautiful sunset]"},
- expectedNotContains: []string{"<https://example.com/sunset.jpg>"},
- },
- {
- name: "Markdown image without hyperlink support",
- input: ``,
- 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: `<img src="https://example.com/image.png" alt="Test image"> and <a href="https://example.com">link</a>`,
- 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{"<https://example.com>", "[Image:"},
- },
- {
- name: "Hyperlink support only - no image protocol",
- input: `<img src="https://example.com/image.png" alt="Test image"> and <a href="https://example.com">link</a>`,
- 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{"<https://example.com>", "[Image:"},
- },
- {
- name: "No support - plain text fallback",
- input: `<img src="https://example.com/image.png" alt="Test image"> and <a href="https://example.com">link</a>`,
- hyperlinkSupported: false,
- imageProtocolSupported: false,
- expectedContains: []string{"link <https://example.com>", "[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)
- }
- }
- })
- }
-}