Skip to content
Open
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
3 changes: 2 additions & 1 deletion python_files/vscode_pytest/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

if TYPE_CHECKING:
from pluggy import Result
from pytest_describe.plugin import DescribeBlock as DescribeBlockType
from typing_extensions import NotRequired

USES_PYTEST_DESCRIBE = False
Expand Down Expand Up @@ -873,7 +874,7 @@ def create_session_node(session: pytest.Session) -> TestNode:
}


def create_class_node(class_module: Any) -> TestNode:
def create_class_node(class_module: pytest.Class | DescribeBlockType) -> TestNode:
"""Creates a class node from a pytest class object.

Keyword arguments:
Expand Down
13 changes: 13 additions & 0 deletions src/client/common/platform/fs-paths.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,19 @@ export function normCasePath(filePath: string): string {
return normCase(nodepath.normalize(filePath));
}

/**
* Returns true if the given path is absolute on either POSIX or Windows.
*
* Node's `path.isAbsolute` is platform-dependent, so a POSIX path like `/foo`
* is not recognized as absolute on Windows, and a Windows path like `C:\foo`
* is not recognized as absolute on POSIX. Use this helper when the path could
* have been produced on a different OS than the one currently running (e.g.
* paths received in a JSON payload from a Python subprocess).
*/
export function isAbsolutePath(value: string): boolean {
return nodepath.posix.isAbsolute(value) || nodepath.win32.isAbsolute(value);
}

export function normCase(s: string): string {
return getOSType() === OSType.Windows ? s.toUpperCase() : s;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@ import { createErrorTestItem } from './testItemUtilities';
import { buildErrorNodeOptions, populateTestTree } from './utils';
import { TestItemIndex } from './testItemIndex';
import { PROJECT_ID_SEPARATOR } from './projectUtils';

function isAbsolutePath(value: string): boolean {
return /^([a-zA-Z]:[\\/]|\\\\)/.test(value) || value.startsWith('/');
}
import { isAbsolutePath } from '../../../common/platform/fs-paths';

function joinWithBase(base: string, relativePath: string): string {
if (!base || isAbsolutePath(relativePath)) {
Expand Down
27 changes: 26 additions & 1 deletion src/test/common/platform/fs-paths.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import { expect } from 'chai';
import * as path from 'path';
import * as TypeMoq from 'typemoq';
import { FileSystemPathUtils } from '../../../client/common/platform/fs-paths';
import { FileSystemPathUtils, isAbsolutePath } from '../../../client/common/platform/fs-paths';
import { getNamesAndValues } from '../../../client/common/utils/enum';
import { OSType } from '../../../client/common/utils/platform';

Expand Down Expand Up @@ -112,3 +112,28 @@ suite('FileSystem - Path Utils', () => {
});
});
});

suite('FileSystem - isAbsolutePath', () => {
test('Recognizes POSIX absolute paths', () => {
expect(isAbsolutePath('/foo/bar')).to.equal(true);
expect(isAbsolutePath('/')).to.equal(true);
});

test('Recognizes Windows drive-letter absolute paths', () => {
expect(isAbsolutePath('C:\\foo\\bar')).to.equal(true);
expect(isAbsolutePath('c:/foo/bar')).to.equal(true);
expect(isAbsolutePath('Z:\\')).to.equal(true);
});

test('Recognizes Windows UNC absolute paths', () => {
expect(isAbsolutePath('\\\\server\\share\\foo')).to.equal(true);
});

test('Rejects relative paths', () => {
expect(isAbsolutePath('foo/bar')).to.equal(false);
expect(isAbsolutePath('./foo')).to.equal(false);
expect(isAbsolutePath('../foo')).to.equal(false);
expect(isAbsolutePath('foo\\bar')).to.equal(false);
expect(isAbsolutePath('')).to.equal(false);
});
});
Loading