Skip to content

Commit 8017cc1

Browse files
committed
test(native-utils): enhance executable selection tests with error handling
- Updated `selectExecutable.spec.ts` to include additional tests for error handling in `validateBinaryPaths`, covering scenarios for permission denied, directory errors, file not found, and generic access errors. - Added assertions to ensure accurate reporting of error types and valid paths, improving test coverage and reliability. - Adjusted imports to include `validateBinaryPaths` alongside `selectExecutable` for comprehensive testing.
1 parent 849f11b commit 8017cc1

2 files changed

Lines changed: 86 additions & 2 deletions

File tree

packages/native-utils/test/electronVersion.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
import type { NormalizedPackageJson, NormalizedReadResult } from '@wdio/native-types';
12
import { describe, expect, it, vi } from 'vitest';
23
import { getElectronVersion } from '../src/electronVersion.js';
3-
import type { NormalizedPackageJson, NormalizedReadResult } from '../src/package.js';
44
import { findPnpmCatalogVersion } from '../src/pnpm.js';
55

66
vi.mock('../src/pnpm', async () => {

packages/native-utils/test/selectExecutable.spec.ts

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
import assert from 'node:assert';
12
import fs from 'node:fs/promises';
23
import { describe, expect, it, vi } from 'vitest';
3-
import { selectExecutable } from '../src/selectExecutable.js';
4+
import { selectExecutable, validateBinaryPaths } from '../src/selectExecutable.js';
45
import { mockBinaryPath } from './testUtils.js';
56

67
/**
@@ -70,4 +71,87 @@ describe('selectExecutable', () => {
7071
'No executable binary found, checked:',
7172
);
7273
});
74+
75+
it('should report EACCES error with PERMISSION_DENIED type', async () => {
76+
const eaccesError = new Error('EACCES: permission denied') as NodeJS.ErrnoException;
77+
eaccesError.code = 'EACCES';
78+
vi.mocked(fs.access).mockRejectedValue(eaccesError);
79+
80+
const result = await validateBinaryPaths(['/path/to/binary']);
81+
82+
assert(!result.ok);
83+
expect(result.error.attempts).toHaveLength(1);
84+
expect(result.error.attempts[0].valid).toBe(false);
85+
expect(result.error.attempts[0].error?.type).toBe('PERMISSION_DENIED');
86+
expect(result.error.attempts[0].error?.code).toBe('EACCES');
87+
});
88+
89+
it('should report EISDIR error with IS_DIRECTORY type', async () => {
90+
const eisdirError = new Error('EISDIR: illegal operation on a directory') as NodeJS.ErrnoException;
91+
eisdirError.code = 'EISDIR';
92+
vi.mocked(fs.access).mockRejectedValue(eisdirError);
93+
94+
const result = await validateBinaryPaths(['/path/to/directory']);
95+
96+
assert(!result.ok);
97+
expect(result.error.attempts).toHaveLength(1);
98+
expect(result.error.attempts[0].valid).toBe(false);
99+
expect(result.error.attempts[0].error?.type).toBe('IS_DIRECTORY');
100+
expect(result.error.attempts[0].error?.code).toBe('EISDIR');
101+
});
102+
103+
it('should report ENOENT error with FILE_NOT_FOUND type', async () => {
104+
const enoentError = new Error('ENOENT: no such file or directory') as NodeJS.ErrnoException;
105+
enoentError.code = 'ENOENT';
106+
vi.mocked(fs.access).mockRejectedValue(enoentError);
107+
108+
const result = await validateBinaryPaths(['/nonexistent/path']);
109+
110+
assert(!result.ok);
111+
expect(result.error.attempts).toHaveLength(1);
112+
expect(result.error.attempts[0].error?.type).toBe('FILE_NOT_FOUND');
113+
expect(result.error.attempts[0].error?.code).toBe('ENOENT');
114+
});
115+
116+
it('should report generic access error for unknown error codes', async () => {
117+
const genericError = new Error('some other error') as NodeJS.ErrnoException;
118+
genericError.code = 'EUNKNOWN';
119+
vi.mocked(fs.access).mockRejectedValue(genericError);
120+
121+
const result = await validateBinaryPaths(['/path/to/binary']);
122+
123+
assert(!result.ok);
124+
expect(result.error.attempts[0].error?.type).toBe('ACCESS_ERROR');
125+
});
126+
127+
it('should report NOT_EXECUTABLE for permission-related error messages', async () => {
128+
const permError = new Error('not executable') as NodeJS.ErrnoException;
129+
vi.mocked(fs.access).mockRejectedValue(permError);
130+
131+
const result = await validateBinaryPaths(['/path/to/binary']);
132+
133+
assert(!result.ok);
134+
expect(result.error.attempts[0].error?.type).toBe('NOT_EXECUTABLE');
135+
});
136+
137+
it('should return first valid path when some paths fail', async () => {
138+
let callCount = 0;
139+
vi.mocked(fs.access).mockImplementation(async () => {
140+
callCount++;
141+
if (callCount === 1) {
142+
const error = new Error('ENOENT') as NodeJS.ErrnoException;
143+
error.code = 'ENOENT';
144+
throw error;
145+
}
146+
// Second call succeeds
147+
});
148+
149+
const result = await validateBinaryPaths(['/bad/path', '/good/path']);
150+
151+
assert(result.ok);
152+
expect(result.value.validPath).toBe('/good/path');
153+
expect(result.value.attempts).toHaveLength(2);
154+
expect(result.value.attempts[0].valid).toBe(false);
155+
expect(result.value.attempts[1].valid).toBe(true);
156+
});
73157
});

0 commit comments

Comments
 (0)