070959e133
landing-page-staging / Deploy landing page to staging (push) Has been skipped
landing-page-ci / Validate landing page (push) Failing after 4s
visual-baseline / Capture visual baselines (push) Has been cancelled
bake-plugin-previews / Bake plugin previews (push) Has been cancelled
80 lines
3.1 KiB
TypeScript
80 lines
3.1 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import {
|
|
buildWindowsFolderDialogCommand,
|
|
parseLinuxFolderDialogResult,
|
|
parseFolderDialogStdout,
|
|
} from '../src/native-folder-dialog.js';
|
|
|
|
function dialogError(message: string, code: string | number): Error & { code: string | number } {
|
|
const err = new Error(message) as Error & { code: string | number };
|
|
err.code = code;
|
|
return err;
|
|
}
|
|
|
|
describe('native folder dialog helpers', () => {
|
|
it('builds the Windows folder picker command with STA mode', () => {
|
|
const command = buildWindowsFolderDialogCommand();
|
|
|
|
expect(command.command).toBe('powershell.exe');
|
|
expect(command.args).toContain('-NoProfile');
|
|
expect(command.args).toContain('-Sta');
|
|
expect(command.args).toContain('-Command');
|
|
});
|
|
|
|
it('creates a topmost owner form for the Windows dialog', () => {
|
|
const script = buildWindowsFolderDialogCommand().args[3] ?? '';
|
|
|
|
expect(script).toContain('$owner = New-Object System.Windows.Forms.Form;');
|
|
expect(script).toContain('$owner.TopMost = $true;');
|
|
expect(script).toContain('$owner.ShowInTaskbar = $true;');
|
|
expect(script).toContain("$owner.StartPosition = 'CenterScreen';");
|
|
});
|
|
|
|
it('passes the owner form into the Windows folder picker', () => {
|
|
const script = buildWindowsFolderDialogCommand().args[3] ?? '';
|
|
|
|
expect(script).toContain('$dialog = New-Object System.Windows.Forms.FolderBrowserDialog;');
|
|
expect(script).toContain('$dialog.ShowNewFolderButton = $true;');
|
|
expect(script).toContain('$dialog.ShowDialog($owner)');
|
|
expect(script).toContain('$owner.Dispose();');
|
|
});
|
|
|
|
it('parses a selected folder path from stdout', () => {
|
|
expect(parseFolderDialogStdout(null, 'C:\\Users\\Ada\\Project\r\n')).toBe('C:\\Users\\Ada\\Project');
|
|
});
|
|
|
|
it('returns null when the dialog is cancelled', () => {
|
|
expect(parseFolderDialogStdout(null, '\r\n')).toBeNull();
|
|
});
|
|
|
|
it('returns null when the native dialog command fails', () => {
|
|
expect(parseFolderDialogStdout(new Error('cancelled'), 'C:\\Users\\Ada\\Project\r\n')).toBeNull();
|
|
});
|
|
|
|
it('parses a selected Linux folder path from stdout', () => {
|
|
expect(parseLinuxFolderDialogResult(null, '/home/ada/project\n', '')).toBe('/home/ada/project');
|
|
});
|
|
|
|
it('keeps Linux cancel quiet even when zenity emits GTK warnings on stderr', () => {
|
|
const err = dialogError('Command failed: zenity', 1);
|
|
|
|
expect(parseLinuxFolderDialogResult(err, '', '(zenity:123): Gtk-WARNING **: Theme parsing error\n')).toBeNull();
|
|
});
|
|
|
|
it('throws for Linux folder picker display failures', () => {
|
|
const err = dialogError('Command failed: zenity', 1);
|
|
|
|
expect(() => parseLinuxFolderDialogResult(err, '', 'Gtk-WARNING **: cannot open display: :99')).toThrow(
|
|
'Could not open folder picker: Gtk-WARNING **: cannot open display: :99',
|
|
);
|
|
});
|
|
|
|
it('throws a stable message when zenity is missing', () => {
|
|
const err = dialogError('spawn zenity ENOENT', 'ENOENT');
|
|
|
|
expect(() => parseLinuxFolderDialogResult(err, '', '')).toThrow(
|
|
'Could not open folder picker: zenity is not installed',
|
|
);
|
|
});
|
|
});
|