Use case-insensitive path comparison on Windows
This commit is contained in:
committed by
Koen Vlaswinkel
parent
477b32662f
commit
6bf19eb52f
@@ -21,6 +21,7 @@ import { DisposableObject } from "./pure/disposable-object";
|
||||
import { Logger, extLogger } from "./common";
|
||||
import { getErrorMessage } from "./pure/helpers-pure";
|
||||
import { QueryRunner } from "./queryRunner";
|
||||
import { pathsEqual } from "./pure/files";
|
||||
|
||||
/**
|
||||
* databases.ts
|
||||
@@ -523,7 +524,11 @@ export class DatabaseItemImpl implements DatabaseItem {
|
||||
// database for /one/two/three/test.ql is at /one/two/three/three.testproj
|
||||
const testdir = dirname(testPath);
|
||||
const testdirbase = basename(testdir);
|
||||
return databasePath == join(testdir, `${testdirbase}.testproj`);
|
||||
return pathsEqual(
|
||||
databasePath,
|
||||
join(testdir, `${testdirbase}.testproj`),
|
||||
process.platform,
|
||||
);
|
||||
}
|
||||
} catch {
|
||||
// No information available for test path - assume database is unaffected.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { pathExists, stat, readdir } from "fs-extra";
|
||||
import { join } from "path";
|
||||
import { join, resolve } from "path";
|
||||
|
||||
/**
|
||||
* Recursively finds all .ql files in this set of Uris.
|
||||
@@ -50,3 +50,20 @@ export async function getDirectoryNamesInsidePath(
|
||||
|
||||
return dirNames;
|
||||
}
|
||||
|
||||
export function pathsEqual(
|
||||
path1: string,
|
||||
path2: string,
|
||||
platform: NodeJS.Platform,
|
||||
): boolean {
|
||||
// On Windows, "C:/", "C:\", and "c:/" are all equivalent. We need
|
||||
// to normalize the paths to ensure they all get resolved to the
|
||||
// same format. On Windows, we also need to do the comparison
|
||||
// case-insensitively.
|
||||
path1 = resolve(path1);
|
||||
path2 = resolve(path2);
|
||||
if (platform === "win32") {
|
||||
return path1.toLowerCase() === path2.toLowerCase();
|
||||
}
|
||||
return path1 === path2;
|
||||
}
|
||||
|
||||
53
extensions/ql-vscode/test/matchers/toEqualPath.ts
Normal file
53
extensions/ql-vscode/test/matchers/toEqualPath.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { expect } from "@jest/globals";
|
||||
import type { MatcherFunction } from "expect";
|
||||
import { pathsEqual } from "../../src/pure/files";
|
||||
|
||||
// eslint-disable-next-line func-style -- We need to have access to this and specify the type of the function
|
||||
const toEqualPath: MatcherFunction<[expectedPath: unknown]> = function (
|
||||
actual,
|
||||
expectedPath,
|
||||
) {
|
||||
if (typeof actual !== "string" || typeof expectedPath !== "string") {
|
||||
throw new Error("These must be of type string!");
|
||||
}
|
||||
|
||||
const pass = pathsEqual(actual, expectedPath, process.platform);
|
||||
if (pass) {
|
||||
return {
|
||||
message: () =>
|
||||
// eslint-disable-next-line @typescript-eslint/no-invalid-this
|
||||
`expected ${this.utils.printReceived(
|
||||
actual,
|
||||
// eslint-disable-next-line @typescript-eslint/no-invalid-this
|
||||
)} to equal path ${this.utils.printExpected(expectedPath)}`,
|
||||
pass: true,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
message: () =>
|
||||
// eslint-disable-next-line @typescript-eslint/no-invalid-this
|
||||
`expected ${this.utils.printReceived(
|
||||
actual,
|
||||
// eslint-disable-next-line @typescript-eslint/no-invalid-this
|
||||
)} to equal path ${this.utils.printExpected(expectedPath)}`,
|
||||
pass: false,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
expect.extend({
|
||||
toEqualPath,
|
||||
});
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace -- We need to extend this global declaration
|
||||
namespace jest {
|
||||
interface AsymmetricMatchers {
|
||||
toEqualPath(expectedPath: string): void;
|
||||
}
|
||||
|
||||
interface Matchers<R> {
|
||||
toEqualPath(expectedPath: string): R;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import { join } from "path";
|
||||
import {
|
||||
gatherQlFiles,
|
||||
getDirectoryNamesInsidePath,
|
||||
pathsEqual,
|
||||
} from "../../../src/pure/files";
|
||||
|
||||
describe("files", () => {
|
||||
@@ -100,3 +101,90 @@ describe("files", () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("pathsEqual", () => {
|
||||
const testCases: Array<{
|
||||
path1: string;
|
||||
path2: string;
|
||||
platform: NodeJS.Platform;
|
||||
expected: boolean;
|
||||
}> = [
|
||||
{
|
||||
path1:
|
||||
"/home/github/projects/vscode-codeql-starter/codeql-custom-queries-javascript/example.ql",
|
||||
path2:
|
||||
"/home/github/projects/vscode-codeql-starter/codeql-custom-queries-javascript/example.ql",
|
||||
platform: "linux",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
path1:
|
||||
"/HOME/github/projects/vscode-codeql-starter/codeql-custom-queries-javascript/example.ql",
|
||||
path2:
|
||||
"/home/github/projects/vscode-codeql-starter/codeql-custom-queries-javascript/example.ql",
|
||||
platform: "linux",
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
path1:
|
||||
"/home/github/projects/vscode-codeql-starter/codeql-custom-queries-javascript/example.ql",
|
||||
path2:
|
||||
"\\home\\github\\projects\\vscode-codeql-starter\\codeql-custom-queries-javascript\\example.ql",
|
||||
platform: "linux",
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
path1:
|
||||
"C:/Users/github/projects/vscode-codeql-starter/codeql-custom-queries-javascript/example.ql",
|
||||
path2:
|
||||
"C:/Users/github/projects/vscode-codeql-starter/codeql-custom-queries-javascript/example.ql",
|
||||
platform: "win32",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
path1:
|
||||
"C:/Users/github/projects/vscode-codeql-starter/codeql-custom-queries-javascript/example.ql",
|
||||
path2:
|
||||
"c:/Users/github/projects/vscode-codeql-starter/codeql-custom-queries-javascript/example.ql",
|
||||
platform: "win32",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
path1:
|
||||
"C:/Users/github/projects/vscode-codeql-starter/codeql-custom-queries-javascript/example.ql",
|
||||
path2:
|
||||
"D:/Users/github/projects/vscode-codeql-starter/codeql-custom-queries-javascript/example.ql",
|
||||
platform: "win32",
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
path1:
|
||||
"C:/Users/github/projects/vscode-codeql-starter/codeql-custom-queries-javascript/example.ql",
|
||||
path2:
|
||||
"C:\\Users\\github\\projects\\vscode-codeql-starter\\codeql-custom-queries-javascript\\example.ql",
|
||||
platform: "win32",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
path1:
|
||||
"C:/Users/github/projects/vscode-codeql-starter/codeql-custom-queries-javascript/example.ql",
|
||||
path2:
|
||||
"D:\\Users\\github\\projects\\vscode-codeql-starter\\codeql-custom-queries-javascript\\example.ql",
|
||||
platform: "win32",
|
||||
expected: false,
|
||||
},
|
||||
];
|
||||
|
||||
test.each(testCases)(
|
||||
"$path1 and $path2 are equal on $platform = $expected",
|
||||
({ path1, path2, platform, expected }) => {
|
||||
if (platform !== process.platform) {
|
||||
// We're using the platform-specific path.resolve, so we can't really run
|
||||
// these tests on all platforms.
|
||||
return;
|
||||
}
|
||||
|
||||
expect(pathsEqual(path1, path2, platform)).toEqual(expected);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
@@ -6,6 +6,8 @@ import { QLTestDiscovery } from "../../../src/qltest-discovery";
|
||||
import { DirectoryResult } from "tmp-promise";
|
||||
import * as tmp from "tmp-promise";
|
||||
|
||||
import "../../matchers/toEqualPath";
|
||||
|
||||
describe("qltest-discovery", () => {
|
||||
describe("discoverTests", () => {
|
||||
let directory: DirectoryResult;
|
||||
@@ -50,30 +52,30 @@ describe("qltest-discovery", () => {
|
||||
|
||||
it("should run discovery", async () => {
|
||||
const result = await (qlTestDiscover as any).discover();
|
||||
expect(result.watchPath).toBe(baseDir);
|
||||
expect(result.testDirectory.path).toBe(baseDir);
|
||||
expect(result.watchPath).toEqualPath(baseDir);
|
||||
expect(result.testDirectory.path).toEqualPath(baseDir);
|
||||
expect(result.testDirectory.name).toBe("My tests");
|
||||
|
||||
let children = result.testDirectory.children;
|
||||
expect(children.length).toBe(1);
|
||||
|
||||
expect(children[0].path).toBe(cDir);
|
||||
expect(children[0].path).toEqualPath(cDir);
|
||||
expect(children[0].name).toBe("c");
|
||||
|
||||
children = children[0].children;
|
||||
expect(children.length).toBe(3);
|
||||
|
||||
expect(children[0].path).toBe(dFile);
|
||||
expect(children[0].path).toEqualPath(dFile);
|
||||
expect(children[0].name).toBe("d.ql");
|
||||
expect(children[1].path).toBe(eFile);
|
||||
expect(children[1].path).toEqualPath(eFile);
|
||||
expect(children[1].name).toBe("e.ql");
|
||||
|
||||
// A merged foler
|
||||
expect(children[2].path).toBe(hDir);
|
||||
expect(children[2].path).toEqualPath(hDir);
|
||||
expect(children[2].name).toBe("f / g / h");
|
||||
|
||||
children = children[2].children;
|
||||
expect(children[0].path).toBe(iFile);
|
||||
expect(children[0].path).toEqualPath(iFile);
|
||||
expect(children[0].name).toBe("i.ql");
|
||||
});
|
||||
|
||||
@@ -81,8 +83,8 @@ describe("qltest-discovery", () => {
|
||||
await fs.remove(baseDir);
|
||||
|
||||
const result = await (qlTestDiscover as any).discover();
|
||||
expect(result.watchPath).toBe(baseDir);
|
||||
expect(result.testDirectory.path).toBe(baseDir);
|
||||
expect(result.watchPath).toEqualPath(baseDir);
|
||||
expect(result.testDirectory.path).toEqualPath(baseDir);
|
||||
expect(result.testDirectory.name).toBe("My tests");
|
||||
|
||||
expect(result.testDirectory.children.length).toBe(0);
|
||||
|
||||
Reference in New Issue
Block a user