Skip to content

Commit

Permalink
[TypeSpecValidation] bug fix: drive letter inconsistency for windows (#…
Browse files Browse the repository at this point in the history
…27002)

- Fixes #26557
  • Loading branch information
ckairen authored and arifibrahim4 committed Feb 26, 2024
1 parent 620e2ab commit 8c0a0df
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 15 deletions.
10 changes: 7 additions & 3 deletions eng/tools/typespec-validation/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { access } from "fs/promises";
import { exec } from "child_process";
import path from "path";
import defaultPath, { PlatformPath } from "path";

export async function runCmd(cmd: string, cwd: string) {
console.log(`run command:${cmd}`);
Expand All @@ -22,6 +22,10 @@ export async function checkFileExists(file: string) {
.catch(() => false);
}

export function normalizePath(folder: string) {
return path.resolve(folder).split(path.sep).join("/");
export function normalizePath(folder: string, path: PlatformPath = defaultPath) {
return path
.resolve(folder)
.split(path.sep)
.join("/")
.replace(/^([a-z]):/, (_match, driveLetter) => driveLetter.toUpperCase() + ":");
}
68 changes: 68 additions & 0 deletions eng/tools/typespec-validation/test/npm-prefix.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { NpmPrefixRule } from "../src/rules/npm-prefix.js";
import { IGitOperation, TsvTestHost } from "./tsv-test-host.js";
import { strict as assert } from "node:assert";
import path from "path";

describe("npm-prefix", function () {
it("should succeed if node returns inconsistent drive letter capitalization", async function () {
let host = new TsvTestHost(path.win32);
host.runCmd = async (cmd: string, _cwd: string): Promise<[Error | null, string, string]> => {
if (cmd.includes("npm prefix")) {
return [null, `C:${path.sep}Git${path.sep}azure-rest-api-specs`, ""];
} else {
return [null, "", ""];
}
};
host.gitOperation = (_folder: string): IGitOperation => {
return {
status: () => {
return Promise.resolve({
modified: [],
isClean: () => true,
});
},
diff: () => {
return Promise.resolve("");
},
revparse: () => {
return Promise.resolve("c:/Git/azure-rest-api-specs");
},
};
};

const result = await new NpmPrefixRule().execute(host, TsvTestHost.folder);

assert(result.success);
});

it("should fail if npm prefix mismatch", async function () {
let host = new TsvTestHost();
host.runCmd = async (cmd: string, _cwd: string): Promise<[Error | null, string, string]> => {
if (cmd.includes("npm prefix")) {
return [null, "/Git/azure-rest-api-specs/specification/foo", ""];
} else {
return [null, "", ""];
}
};
host.gitOperation = (_folder: string): IGitOperation => {
return {
status: () => {
return Promise.resolve({
modified: [],
isClean: () => true,
});
},
diff: () => {
return Promise.resolve("");
},
revparse: () => {
return Promise.resolve("/Git/azure-rest-api-specs");
},
};
};

const result = await new NpmPrefixRule().execute(host, TsvTestHost.folder);

assert(!result.success);
});
});
11 changes: 10 additions & 1 deletion eng/tools/typespec-validation/test/tsv-test-host.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
import { IGitOperation, TsvHost } from "../src/tsv-host.js";
import { normalizePath } from "../src/utils.js";
import defaultPath, { PlatformPath } from "path";

export { IGitOperation } from "../src/tsv-host.js";

export class TsvTestHost implements TsvHost {
path: PlatformPath;

constructor(path: PlatformPath = defaultPath) {
this.path = path;
}

static get folder() {
return "specification/foo/Foo";
}
Expand Down Expand Up @@ -36,7 +45,7 @@ export class TsvTestHost implements TsvHost {
}

normalizePath(folder: string): string {
return normalizePath(folder);
return normalizePath(folder, this.path);
}

async readTspConfig(_folder: string): Promise<string> {
Expand Down
27 changes: 16 additions & 11 deletions eng/tools/typespec-validation/test/util.test.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
import { TsvTestHost } from "./tsv-test-host.js";
import { normalizePath } from "../src/utils.js";
import { strict as assert } from "node:assert";
import process from "process";
import path from "path";

describe("normalize", function () {
it("should succeed if normalized . and normalized cwd matches", async function () {
let host = new TsvTestHost();
const dotResult = host.normalizePath(".");
const cwdResult = host.normalizePath(process.cwd());
const dotResult = normalizePath(".");
const cwdResult = normalizePath(process.cwd());
assert(dotResult === cwdResult);
});

it("should succeed if /foo/bar/ is normalized", async function () {
let host = new TsvTestHost();
const result = host.normalizePath("/foo/bar/").replace(/^[a-zA-Z]:/g, "");
assert(result === "/foo/bar");
const result = normalizePath("/foo/bar/", path.posix);
assert.equal(result, "/foo/bar");
});

it("should succeed if /foo/bar is normalized", async function () {
let host = new TsvTestHost();
const result = host.normalizePath("/foo/bar").replace(/^[a-zA-Z]:/g, "");
assert(result === "/foo/bar");
it("should normalize windows drive letter", async function () {
const lowerResult = normalizePath("c:\\foo\\bar", path.win32);
const upperResult = normalizePath("C:\\foo\\bar", path.win32);
assert.equal(lowerResult, upperResult);
});

it("should distinguish different windows drive letters", async function () {
const lowerResult = normalizePath("c:\\foo\\bar", path.win32);
const upperResult = normalizePath("d:\\foo\\bar", path.win32);
assert.notEqual(lowerResult, upperResult);
});
});

0 comments on commit 8c0a0df

Please sign in to comment.