Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@
"build": "npm run compile",
"package": "npm run build && npx vsce package",
"package-all": "npm run build && npx vsce package",
"test": "npx tsx --test tests/unit/*.test.ts"
"test": "npx tsx --tsconfig tsconfig.test.json --test tests/unit/*.test.ts"
},
"devDependencies": {
"@types/node": "^25.2.0",
Expand Down
2 changes: 1 addition & 1 deletion src/platform/cryptoShim.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
*/

// Determine runtime environment and export appropriate crypto implementation
const isBrowserRuntime = import.meta.env.VSCODE_BROWSER_EXT;
const isBrowserRuntime = import.meta.env?.VSCODE_BROWSER_EXT;

// In browser: use native Web Crypto API
// In Node.js: use the webcrypto module from Node's crypto package
Expand Down
30 changes: 30 additions & 0 deletions tests/mocks/vscode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
export const env = {
uriScheme: 'vscode',
appName: 'Code',
language: 'en-US'
};

export const Uri = {
parse: (value: string) => ({
toString: () => value,
path: value,
scheme: 'file'
}),
Comment on lines +8 to +12
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The path property in this mock for Uri.parse is incorrect. It returns the entire URI string, whereas it should return only the path component. For example, for a URI file:///foo/bar.txt, path should be /foo/bar.txt.

This is inconsistent with the file() mock and could cause issues in future tests that rely on uri.path. This becomes more important if getUriParts is changed to use uri.path as suggested in another comment.

Consider making the mock more accurate to prevent future issues.

Suggested change
parse: (value: string) => ({
toString: () => value,
path: value,
scheme: 'file'
}),
parse: (value: string) => ({
toString: () => value,
path: value.startsWith('file://') ? new URL(value).pathname : value,
scheme: 'file'
}),

file: (path: string) => ({
toString: () => `file://${path}`,
path,
scheme: 'file'
})
Comment on lines +13 to +17
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This mock for Uri.file doesn't handle Windows paths correctly. For a path like C:\\Users\\test.txt, toString() would produce file://C:\\Users\\test.txt, which is not a valid URI. A valid file URI for a Windows path should look like file:///C:/Users/test.txt.

While the current tests only use POSIX-style paths, making the mock cross-platform compatible would make it more robust for future tests.

  file: (path: string) => {
    // Handle Windows paths to create valid file URIs.
    const posixPath = path.replace(/\\/g, '/');
    const uriPath = /^[a-zA-Z]:\//.test(posixPath) ? `/${posixPath}` : posixPath;
    return {
      toString: () => `file://${uriPath}`,
      path: uriPath,
      scheme: 'file'
    };
  }

};

export enum ColorThemeKind {
Light = 1,
Dark = 2,
HighContrast = 3,
HighContrastLight = 4
}

export enum UIKind {
Desktop = 1,
Web = 2
}
56 changes: 56 additions & 0 deletions tests/unit/helpers.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { describe, it } from 'node:test';
import assert from 'node:assert';
import { getUriParts } from '../../src/helpers';
import * as vsc from 'vscode';

describe('getUriParts', () => {
it('should parse simple file path string', () => {
const parts = getUriParts('/home/user/test.txt');
assert.strictEqual(parts.dirname, '/home/user/');
assert.strictEqual(parts.filename, 'test.txt');
assert.strictEqual(parts.basename, 'test');
assert.strictEqual(parts.extname, '.txt');
});

it('should parse simple file path URI', () => {
const uri = vsc.Uri.file('/home/user/test.txt');
const parts = getUriParts(uri);
assert.strictEqual(parts.dirname, 'file:///home/user/'); // Regex matches from uri.toString() which returns file://...
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

This test reveals a correctness issue with the getUriParts implementation. The function's documentation states it "Extract[s] path components from a URI", but as your test and comment correctly note, it includes the URI scheme (file://) in the dirname when passed a vscode.Uri object. This is because it operates on uri.toString() instead of the uri.path property, which can lead to unexpected behavior.

To fix this, getUriParts should be modified to use the .path property when it receives a vscode.Uri object.

Here is a suggested change for src/helpers.ts:

export function getUriParts(uri: string | vsc.Uri): { /* ... */ } {
  const pathString = typeof uri === 'string' ? uri : uri.path;
  const match = pathString.match(uriPathPattern);
  // ... the rest of the function
}

With this change in getUriParts, this test assertion should be updated to expect '/home/user/'.

assert.strictEqual(parts.filename, 'test.txt');
assert.strictEqual(parts.basename, 'test');
assert.strictEqual(parts.extname, '.txt');
});

it('should parse file without extension', () => {
const parts = getUriParts('/home/user/makefile');
assert.strictEqual(parts.dirname, '/home/user/');
assert.strictEqual(parts.filename, 'makefile');
assert.strictEqual(parts.basename, 'makefile');
assert.strictEqual(parts.extname, '');
});

it('should parse file in root', () => {
const parts = getUriParts('/config.json');
assert.strictEqual(parts.dirname, '/');
assert.strictEqual(parts.filename, 'config.json');
assert.strictEqual(parts.basename, 'config');
assert.strictEqual(parts.extname, '.json');
});

it('should parse just filename', () => {
const parts = getUriParts('notes.md');
assert.strictEqual(parts.dirname, '');
assert.strictEqual(parts.filename, 'notes.md');
assert.strictEqual(parts.basename, 'notes');
assert.strictEqual(parts.extname, '.md');
});

it('should handle special characters and decoding', () => {
// We use string input to test decodeURIComponent logic independently of vsc.Uri mock
const parts = getUriParts('/path/to/file%20name.txt');
assert.strictEqual(parts.dirname, '/path/to/');
assert.strictEqual(parts.filename, 'file name.txt');
assert.strictEqual(parts.basename, 'file name');
assert.strictEqual(parts.extname, '.txt');
});
});
9 changes: 9 additions & 0 deletions tsconfig.test.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"baseUrl": ".",
"paths": {
"vscode": ["tests/mocks/vscode.ts"]
}
}
}