|
|
@@ -1,7 +1,15 @@
|
|
|
+import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"
|
|
|
import * as vscode from "vscode"
|
|
|
import { userInfo } from "os"
|
|
|
import { getShell } from "../shell"
|
|
|
|
|
|
+// Mock vscode module
|
|
|
+vi.mock("vscode", () => ({
|
|
|
+ workspace: {
|
|
|
+ getConfiguration: vi.fn(),
|
|
|
+ },
|
|
|
+}))
|
|
|
+
|
|
|
// Mock the os module
|
|
|
vi.mock("os", () => ({
|
|
|
userInfo: vi.fn(() => ({ shell: null })),
|
|
|
@@ -74,6 +82,56 @@ describe("Shell Detection Tests", () => {
|
|
|
expect(getShell()).toBe("C:\\Program Files\\PowerShell\\7\\pwsh.exe")
|
|
|
})
|
|
|
|
|
|
+ it("should handle array path from VSCode terminal profile", () => {
|
|
|
+ // Mock VSCode configuration with array path
|
|
|
+ const mockConfig = {
|
|
|
+ get: vi.fn((key: string) => {
|
|
|
+ if (key === "defaultProfile.windows") return "PowerShell"
|
|
|
+ if (key === "profiles.windows") {
|
|
|
+ return {
|
|
|
+ PowerShell: {
|
|
|
+ // VSCode API may return path as an array
|
|
|
+ path: ["C:\\Program Files\\PowerShell\\7\\pwsh.exe", "pwsh.exe"],
|
|
|
+ },
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return undefined
|
|
|
+ }),
|
|
|
+ }
|
|
|
+
|
|
|
+ vi.mocked(vscode.workspace.getConfiguration).mockReturnValue(mockConfig as any)
|
|
|
+
|
|
|
+ const result = getShell()
|
|
|
+ // Should use the first element of the array
|
|
|
+ expect(result).toBe("C:\\Program Files\\PowerShell\\7\\pwsh.exe")
|
|
|
+ })
|
|
|
+
|
|
|
+ it("should handle empty array path and fall back to defaults", () => {
|
|
|
+ // Mock VSCode configuration with empty array path
|
|
|
+ const mockConfig = {
|
|
|
+ get: vi.fn((key: string) => {
|
|
|
+ if (key === "defaultProfile.windows") return "Custom"
|
|
|
+ if (key === "profiles.windows") {
|
|
|
+ return {
|
|
|
+ Custom: {
|
|
|
+ path: [], // Empty array
|
|
|
+ },
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return undefined
|
|
|
+ }),
|
|
|
+ }
|
|
|
+
|
|
|
+ vi.mocked(vscode.workspace.getConfiguration).mockReturnValue(mockConfig as any)
|
|
|
+
|
|
|
+ // Mock environment variable
|
|
|
+ process.env.COMSPEC = "C:\\Windows\\System32\\cmd.exe"
|
|
|
+
|
|
|
+ const result = getShell()
|
|
|
+ // Should fall back to cmd.exe
|
|
|
+ expect(result).toBe("C:\\Windows\\System32\\cmd.exe")
|
|
|
+ })
|
|
|
+
|
|
|
it("uses PowerShell 7 path if source is 'PowerShell' but no explicit path", () => {
|
|
|
mockVsCodeConfig("windows", "PowerShell", {
|
|
|
PowerShell: { source: "PowerShell" },
|
|
|
@@ -152,6 +210,29 @@ describe("Shell Detection Tests", () => {
|
|
|
expect(getShell()).toBe("/usr/local/bin/fish")
|
|
|
})
|
|
|
|
|
|
+ it("should handle array path from VSCode terminal profile", () => {
|
|
|
+ // Mock VSCode configuration with array path
|
|
|
+ const mockConfig = {
|
|
|
+ get: vi.fn((key: string) => {
|
|
|
+ if (key === "defaultProfile.osx") return "zsh"
|
|
|
+ if (key === "profiles.osx") {
|
|
|
+ return {
|
|
|
+ zsh: {
|
|
|
+ path: ["/opt/homebrew/bin/zsh", "/bin/zsh"],
|
|
|
+ },
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return undefined
|
|
|
+ }),
|
|
|
+ }
|
|
|
+
|
|
|
+ vi.mocked(vscode.workspace.getConfiguration).mockReturnValue(mockConfig as any)
|
|
|
+
|
|
|
+ const result = getShell()
|
|
|
+ // Should use the first element of the array
|
|
|
+ expect(result).toBe("/opt/homebrew/bin/zsh")
|
|
|
+ })
|
|
|
+
|
|
|
it("falls back to userInfo().shell if no VS Code config is available", () => {
|
|
|
vscode.workspace.getConfiguration = () => ({ get: () => undefined }) as any
|
|
|
vi.mocked(userInfo).mockReturnValue({ shell: "/opt/homebrew/bin/zsh" } as any)
|
|
|
@@ -185,6 +266,29 @@ describe("Shell Detection Tests", () => {
|
|
|
expect(getShell()).toBe("/usr/bin/fish")
|
|
|
})
|
|
|
|
|
|
+ it("should handle array path from VSCode terminal profile", () => {
|
|
|
+ // Mock VSCode configuration with array path
|
|
|
+ const mockConfig = {
|
|
|
+ get: vi.fn((key: string) => {
|
|
|
+ if (key === "defaultProfile.linux") return "bash"
|
|
|
+ if (key === "profiles.linux") {
|
|
|
+ return {
|
|
|
+ bash: {
|
|
|
+ path: ["/usr/local/bin/bash", "/bin/bash"],
|
|
|
+ },
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return undefined
|
|
|
+ }),
|
|
|
+ }
|
|
|
+
|
|
|
+ vi.mocked(vscode.workspace.getConfiguration).mockReturnValue(mockConfig as any)
|
|
|
+
|
|
|
+ const result = getShell()
|
|
|
+ // Should use the first element of the array
|
|
|
+ expect(result).toBe("/usr/local/bin/bash")
|
|
|
+ })
|
|
|
+
|
|
|
it("falls back to userInfo().shell if no VS Code config is available", () => {
|
|
|
vscode.workspace.getConfiguration = () => ({ get: () => undefined }) as any
|
|
|
vi.mocked(userInfo).mockReturnValue({ shell: "/usr/bin/zsh" } as any)
|
|
|
@@ -281,6 +385,57 @@ describe("Shell Detection Tests", () => {
|
|
|
expect(getShell()).toBe("/bin/bash")
|
|
|
})
|
|
|
|
|
|
+ it("should validate array shell paths and use first allowed", () => {
|
|
|
+ Object.defineProperty(process, "platform", { value: "win32" })
|
|
|
+
|
|
|
+ const mockConfig = {
|
|
|
+ get: vi.fn((key: string) => {
|
|
|
+ if (key === "defaultProfile.windows") return "PowerShell"
|
|
|
+ if (key === "profiles.windows") {
|
|
|
+ return {
|
|
|
+ PowerShell: {
|
|
|
+ path: ["C:\\Program Files\\PowerShell\\7\\pwsh.exe", "pwsh"],
|
|
|
+ },
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return undefined
|
|
|
+ }),
|
|
|
+ }
|
|
|
+
|
|
|
+ vi.mocked(vscode.workspace.getConfiguration).mockReturnValue(mockConfig as any)
|
|
|
+
|
|
|
+ const result = getShell()
|
|
|
+ // Should return the first allowed shell from the array
|
|
|
+ expect(result).toBe("C:\\Program Files\\PowerShell\\7\\pwsh.exe")
|
|
|
+ })
|
|
|
+
|
|
|
+ it("should reject non-allowed shell paths and fall back to safe defaults", () => {
|
|
|
+ Object.defineProperty(process, "platform", { value: "win32" })
|
|
|
+
|
|
|
+ const mockConfig = {
|
|
|
+ get: vi.fn((key: string) => {
|
|
|
+ if (key === "defaultProfile.windows") return "Malicious"
|
|
|
+ if (key === "profiles.windows") {
|
|
|
+ return {
|
|
|
+ Malicious: {
|
|
|
+ path: "C:\\malicious\\shell.exe",
|
|
|
+ },
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return undefined
|
|
|
+ }),
|
|
|
+ }
|
|
|
+
|
|
|
+ vi.mocked(vscode.workspace.getConfiguration).mockReturnValue(mockConfig as any)
|
|
|
+
|
|
|
+ // Mock environment to provide a fallback
|
|
|
+ process.env.COMSPEC = "C:\\Windows\\System32\\cmd.exe"
|
|
|
+
|
|
|
+ const result = getShell()
|
|
|
+ // Should fall back to safe default (cmd.exe)
|
|
|
+ expect(result).toBe("C:\\Windows\\System32\\cmd.exe")
|
|
|
+ })
|
|
|
+
|
|
|
it("should validate shells from VS Code config", () => {
|
|
|
Object.defineProperty(process, "platform", { value: "darwin" })
|
|
|
mockVsCodeConfig("osx", "MyCustomShell", {
|