Skip to content

Commit 8f99b70

Browse files
committed
[identity] src/build testing
1 parent 8f1c9d4 commit 8f99b70

File tree

60 files changed

+283
-168
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+283
-168
lines changed

common/tools/dev-tool/src/commands/admin/migrate-tests.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -160,11 +160,6 @@ async function updatePackageJson(projectFolder: string, packageName: string): Pr
160160
delete packageJson.scripts["build:node"];
161161
delete packageJson.scripts["minify"];
162162

163-
packageJson.scripts["test:node:esm"] = "dev-tool run test:vitest --esm";
164-
if (packageJson.scripts["test:node"].includes("--no-test-proxy")) {
165-
packageJson.scripts["test:node:esm"] += " --no-test-proxy";
166-
}
167-
168163
if (
169164
packageName.startsWith("@azure-tests/perf-") ||
170165
packageName === "@azure/dev-tool" ||

common/tools/dev-tool/src/commands/run/build-test.ts

Lines changed: 98 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22
// Licensed under the MIT License.
33

44
import path from "node:path";
5-
import { cpSync, existsSync, mkdirSync, readdirSync, statSync, writeFileSync } from "node:fs";
5+
import { cpSync, existsSync, mkdirSync, readdirSync, writeFileSync } from "node:fs";
6+
import { stat } from "node:fs/promises";
67
import { leafCommand, makeCommandInfo } from "../../framework/command";
78
import { createPrinter } from "../../util/printer";
89
import { resolveProject } from "../../util/resolveProject";
9-
import { resolveConfig } from "../../util/resolveTsConfig";
10+
import { type Config, resolveConfig } from "../../util/resolveTsConfig";
1011
import { spawnSync } from "node:child_process";
1112

1213
const log = createPrinter("build-test");
@@ -22,11 +23,59 @@ export const commandInfo = makeCommandInfo("build-test", "build a package for te
2223
default: "tsconfig.browser.config.json",
2324
description: "path to the browser config file",
2425
},
26+
"node-config": {
27+
kind: "string",
28+
default: "tsconfig.test.node.json",
29+
description: "path to the node config file",
30+
},
2531
});
2632

33+
async function validateConfigFile(configPath: string): Promise<boolean> {
34+
try {
35+
const configStat = await stat(configPath);
36+
if (!configStat.isFile()) {
37+
log.error(`The path ${configPath} is not a file.`);
38+
return false;
39+
}
40+
return true;
41+
} catch (error) {
42+
return false;
43+
}
44+
}
45+
46+
async function findAndRunTypeScriptConfig(
47+
config: string,
48+
fallbackConfig: string,
49+
): Promise<boolean> {
50+
const configsToTry = [config, fallbackConfig];
51+
52+
for (const config of configsToTry) {
53+
if (await validateConfigFile(config)) {
54+
if (!(await runTypeScript(config))) {
55+
return false;
56+
}
57+
log.info(`Typechecking succeeded using ${config}`);
58+
return true;
59+
}
60+
}
61+
62+
log.error(
63+
`No valid TypeScript config found. Please provide a valid config file using --node-config or ensure ${config} or ${fallbackConfig} exists.`,
64+
);
65+
return false;
66+
}
67+
2768
export default leafCommand(commandInfo, async (options) => {
2869
const browserTest = options["browser-test"];
2970
const browserConfig = options["browser-config"];
71+
const nodeConfig = options["node-config"];
72+
const defaultConfig = "tsconfig.test.json";
73+
74+
if (!browserTest) {
75+
if (!(await findAndRunTypeScriptConfig(nodeConfig, defaultConfig))) {
76+
return false;
77+
}
78+
}
3079

3180
const info = await resolveProject(process.cwd());
3281

@@ -73,15 +122,8 @@ export default leafCommand(commandInfo, async (options) => {
73122
}
74123

75124
if (browserTest) {
76-
// Test for valid file
77-
if (!existsSync(browserConfig)) {
78-
log.error(`The file ${browserConfig} does not exist.`);
79-
return false;
80-
}
81-
82-
const browserConfigStat = statSync(browserConfig);
83-
if (!browserConfigStat.isFile()) {
84-
log.error(`The file ${browserConfig} does not exist.`);
125+
if (!(await validateConfigFile(browserConfig))) {
126+
log.error(`The browser config file ${browserConfig} does not exist.`);
85127
return false;
86128
}
87129

@@ -93,6 +135,21 @@ export default leafCommand(commandInfo, async (options) => {
93135
return true;
94136
});
95137

138+
async function runTypeScript(tsConfig: string): Promise<boolean> {
139+
const res = spawnSync(`tsc -p ${tsConfig}`, [], {
140+
stdio: "inherit",
141+
shell: true,
142+
cwd: process.cwd(),
143+
});
144+
145+
if (res.status || res.signal) {
146+
log.error(`TypeScript compilation failed for ${tsConfig}:`, res);
147+
return false;
148+
}
149+
150+
return true;
151+
}
152+
96153
async function compileForEnvironment(
97154
type: string,
98155
tsConfig: string,
@@ -116,6 +173,12 @@ async function compileForEnvironment(
116173
mkdirSync(browserTestPath, { recursive: true });
117174
}
118175

176+
// Check if the TypeScript config uses package name imports or "internal" paths
177+
const shouldSkipOverrides = hasPackageOrInternalPaths(tsConfigJSON);
178+
if (shouldSkipOverrides) {
179+
log.info("Detected package name or internal path mappings, skipping file overrides");
180+
}
181+
119182
// Create import map
120183
const imports: Record<string, string> = {};
121184
for (const [key, value] of importMap.entries()) {
@@ -128,25 +191,38 @@ async function compileForEnvironment(
128191
};
129192
writeFileSync(path.join(browserTestPath, "package.json"), JSON.stringify(packageJson, null, 2));
130193

131-
const res = spawnSync(`tsc -p ${tsConfig}`, [], {
132-
stdio: "inherit",
133-
shell: true,
134-
cwd: process.cwd(),
135-
});
136-
137-
if (res.status || res.signal) {
138-
log.error(res);
194+
if (!(await runTypeScript(tsConfig))) {
139195
return false;
140196
}
141197

142-
for (const [override, original] of overrideMap.entries()) {
143-
log.info(`Replacing for : ${original} => ${override}`);
144-
copyOverrides(type, outputPath, original);
198+
// Only apply overrides if not using package name or internal path imports
199+
if (!shouldSkipOverrides) {
200+
for (const [override, original] of overrideMap.entries()) {
201+
log.info(`Replacing for : ${original} => ${override}`);
202+
copyOverrides(type, outputPath, original);
203+
}
145204
}
146205

147206
return true;
148207
}
149208

209+
function hasPackageOrInternalPaths(tsConfig: Config): boolean {
210+
const paths = tsConfig?.compilerOptions?.paths;
211+
if (!paths || typeof paths !== "object") {
212+
return false;
213+
}
214+
215+
const pathKeys = Object.keys(paths);
216+
217+
// Check for package name imports (e.g., @azure/identity, @azure/identity/*)
218+
const hasPackageImports = pathKeys.some((key) => key.startsWith("@") && key.includes("/"));
219+
220+
// Check for internal path imports (e.g., internal/*)
221+
const hasInternalImports = pathKeys.some((key) => key.startsWith("internal/"));
222+
223+
return hasPackageImports || hasInternalImports;
224+
}
225+
150226
function copyOverrides(type: string, rootDir: string, filePath: string): void {
151227
const fileParsed = path.parse(filePath);
152228
const fileToReplace = path.join(process.cwd(), path.normalize(fileParsed.dir));

eng/pipelines/run-for-all-packages.yml

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,5 @@ stages:
4444
displayName: "Build All Packages"
4545
4646
- script: |
47-
node common/scripts/install-run-rush.js test -t @azure/identity -t @azure/app-configuration -t @azure/event-hubs -p 1 --verbose
47+
node common/scripts/install-run-rush.js test -t @azure/identity -t @azure/app-configuration -t @azure/event-hubs -t @azure/storage-blob -t @azure-rest/synapse-access-control -p 1 --verbose
4848
displayName: "Run Unit Tests for Selected Packages"
49-
50-
- script: |
51-
node common/scripts/install-run-rush.js test:node:esm --only @azure/app-configuration --only @azure/storage-blob --only @azure-rest/synapse-access-control -p 1 --verbose
52-
displayName: "Run Node ESM Tests for Selected Packages"

sdk/identity/identity/eslint.config.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export default azsdkEslint.config([
55
{
66
rules: {
77
"@azure/azure-sdk/ts-naming-options": "warn",
8+
"@typescript-eslint/ban-ts-comment": "warn"
89
},
910
},
1011
]);

sdk/identity/identity/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,7 @@
3131
"pack": "npm pack 2>&1",
3232
"test": "npm run test:node && npm run test:browser",
3333
"test:browser": "npm run clean && dev-tool run build-package && dev-tool run build-test && dev-tool run test:vitest --browser",
34-
"test:node": "dev-tool run test:vitest",
35-
"test:node:esm": "dev-tool run test:vitest --esm",
34+
"test:node": "dev-tool run build-test --no-browser-test && dev-tool run test:vitest",
3635
"test:node:managed-identity": "dev-tool run test:vitest -- --test-timeout 180000 --config ./vitest.managed-identity.config.ts",
3736
"test:node:no-timeouts": "dev-tool run test:vitest -- --test-timeout=0",
3837
"update-snippets": "dev-tool run update-snippets"

sdk/identity/identity/src/errors.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ export const CredentialUnavailableErrorName = "CredentialUnavailableError";
7676
*/
7777
export class CredentialUnavailableError extends Error {
7878
constructor(message?: string, options?: { cause?: unknown }) {
79-
// @ts-expect-error - TypeScript does not recognize this until we use ES2022 as the target; however, all our major runtimes do support the `cause` property
79+
// @ts-ignore - TypeScript does not recognize this until we use ES2022 as the target; however, all our major runtimes do support the `cause` property
8080
super(message, options);
8181
this.name = CredentialUnavailableErrorName;
8282
}
@@ -143,7 +143,7 @@ export class AuthenticationError extends Error {
143143

144144
super(
145145
`${errorResponse.error} Status code: ${statusCode}\nMore details:\n${errorResponse.errorDescription},`,
146-
// @ts-expect-error - TypeScript does not recognize this until we use ES2022 as the target; however, all our major runtimes do support the `cause` property
146+
// @ts-ignore - TypeScript does not recognize this until we use ES2022 as the target; however, all our major runtimes do support the `cause` property
147147
options,
148148
);
149149
this.statusCode = statusCode;
@@ -234,7 +234,7 @@ export class AuthenticationRequiredError extends Error {
234234
) {
235235
super(
236236
options.message,
237-
// @ts-expect-error - TypeScript does not recognize this until we use ES2022 as the target; however, all our major runtimes do support the `cause` property
237+
// @ts-ignore - TypeScript does not recognize this until we use ES2022 as the target; however, all our major runtimes do support the `cause` property
238238
options.cause ? { cause: options.cause } : undefined,
239239
);
240240
this.scopes = options.scopes;

sdk/identity/identity/test/authTestUtils.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT License.
33

4-
import type { AuthenticationError } from "../src/index.js";
5-
import { AzureAuthorityHosts } from "../src/index.js";
4+
import type { AuthenticationError } from "@azure/identity";
5+
import { AzureAuthorityHosts } from "@azure/identity";
66
import { assert } from "vitest";
77

88
/**

sdk/identity/identity/test/httpRequestsCommon.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT License.
3-
import type { AccessToken, GetTokenOptions, TokenCredential } from "../src/index.js";
3+
import type { AccessToken, GetTokenOptions, TokenCredential } from "@azure/identity";
44
import type { AzureLogLevel, AzureLogger } from "@azure/logger";
55
import type { RawHttpHeaders, RestError } from "@azure/core-rest-pipeline";
66

sdk/identity/identity/test/internal/logger.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT License.
33

4-
import type { AccessToken, GetTokenOptions, TokenCredential } from "../../src/index.js";
5-
import type { CredentialLogger } from "../../src/util/logging.js";
4+
import type { AccessToken, GetTokenOptions, TokenCredential } from "@azure/identity";
5+
import type { CredentialLogger } from "internal/util/logging.js";
66
import {
77
credentialLogger,
88
credentialLoggerInstance,
99
formatError,
1010
formatSuccess,
11-
} from "../../src/util/logging.js";
11+
} from "internal/util/logging.js";
1212
import { describe, it, assert } from "vitest";
1313

1414
describe("Identity logging utilities", function () {

sdk/identity/identity/test/internal/node/azureCliCredential.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT License.
3-
import { AzureCliCredential } from "../../../src/credentials/azureCliCredential.js";
3+
import { AzureCliCredential } from "internal/credentials/azureCliCredential.js";
44
import type { GetTokenOptions } from "@azure/core-auth";
55
import child_process from "node:child_process";
66
import { describe, it, assert, expect, vi, beforeEach, afterEach } from "vitest";

0 commit comments

Comments
 (0)