Skip to content

Commit f8d0f68

Browse files
committed
Move functions into class so they can be mocked
We'd like to add test coverage for the openDatabase function (which is public). At the moment, this relies on `resolveDatabaseContents` which is just a standalone function. This means we're unable to mock it using Jest. So let's move it into its own class. This method in turn depends on a `resolveDatabase` function, which we've also moved into the new class. The only usages I could find for there functions were from within the `databases.ts` file.
1 parent 235fb83 commit f8d0f68

1 file changed

Lines changed: 57 additions & 53 deletions

File tree

extensions/ql-vscode/src/databases.ts

Lines changed: 57 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -154,67 +154,69 @@ export async function findSourceArchive(
154154
return undefined;
155155
}
156156

157-
async function resolveDatabase(
158-
databasePath: string,
159-
): Promise<DatabaseContents> {
160-
const name = basename(databasePath);
161-
162-
// Look for dataset and source archive.
163-
const datasetUri = await findDataset(databasePath);
164-
const sourceArchiveUri = await findSourceArchive(databasePath);
165-
166-
return {
167-
kind: DatabaseKind.Database,
168-
name,
169-
datasetUri,
170-
sourceArchiveUri,
171-
};
172-
}
173-
174157
/** Gets the relative paths of all `.dbscheme` files in the given directory. */
175158
async function getDbSchemeFiles(dbDirectory: string): Promise<string[]> {
176159
return await glob("*.dbscheme", { cwd: dbDirectory });
177160
}
178161

179-
async function resolveDatabaseContents(
180-
uri: vscode.Uri,
181-
): Promise<DatabaseContents> {
182-
if (uri.scheme !== "file") {
183-
throw new Error(
184-
`Database URI scheme '${uri.scheme}' not supported; only 'file' URIs are supported.`,
185-
);
186-
}
187-
const databasePath = uri.fsPath;
188-
if (!(await pathExists(databasePath))) {
189-
throw new InvalidDatabaseError(
190-
`Database '${databasePath}' does not exist.`,
191-
);
192-
}
162+
export class DatabaseResolver {
163+
public static async resolveDatabaseContents(
164+
uri: vscode.Uri,
165+
): Promise<DatabaseContents> {
166+
if (uri.scheme !== "file") {
167+
throw new Error(
168+
`Database URI scheme '${uri.scheme}' not supported; only 'file' URIs are supported.`,
169+
);
170+
}
171+
const databasePath = uri.fsPath;
172+
if (!(await pathExists(databasePath))) {
173+
throw new InvalidDatabaseError(
174+
`Database '${databasePath}' does not exist.`,
175+
);
176+
}
193177

194-
const contents = await resolveDatabase(databasePath);
178+
const contents = await this.resolveDatabase(databasePath);
195179

196-
if (contents === undefined) {
197-
throw new InvalidDatabaseError(
198-
`'${databasePath}' is not a valid database.`,
199-
);
180+
if (contents === undefined) {
181+
throw new InvalidDatabaseError(
182+
`'${databasePath}' is not a valid database.`,
183+
);
184+
}
185+
186+
// Look for a single dbscheme file within the database.
187+
// This should be found in the dataset directory, regardless of the form of database.
188+
const dbPath = contents.datasetUri.fsPath;
189+
const dbSchemeFiles = await getDbSchemeFiles(dbPath);
190+
if (dbSchemeFiles.length === 0) {
191+
throw new InvalidDatabaseError(
192+
`Database '${databasePath}' does not contain a CodeQL dbscheme under '${dbPath}'.`,
193+
);
194+
} else if (dbSchemeFiles.length > 1) {
195+
throw new InvalidDatabaseError(
196+
`Database '${databasePath}' contains multiple CodeQL dbschemes under '${dbPath}'.`,
197+
);
198+
} else {
199+
contents.dbSchemeUri = vscode.Uri.file(resolve(dbPath, dbSchemeFiles[0]));
200+
}
201+
return contents;
200202
}
201203

202-
// Look for a single dbscheme file within the database.
203-
// This should be found in the dataset directory, regardless of the form of database.
204-
const dbPath = contents.datasetUri.fsPath;
205-
const dbSchemeFiles = await getDbSchemeFiles(dbPath);
206-
if (dbSchemeFiles.length === 0) {
207-
throw new InvalidDatabaseError(
208-
`Database '${databasePath}' does not contain a CodeQL dbscheme under '${dbPath}'.`,
209-
);
210-
} else if (dbSchemeFiles.length > 1) {
211-
throw new InvalidDatabaseError(
212-
`Database '${databasePath}' contains multiple CodeQL dbschemes under '${dbPath}'.`,
213-
);
214-
} else {
215-
contents.dbSchemeUri = vscode.Uri.file(resolve(dbPath, dbSchemeFiles[0]));
204+
public static async resolveDatabase(
205+
databasePath: string,
206+
): Promise<DatabaseContents> {
207+
const name = basename(databasePath);
208+
209+
// Look for dataset and source archive.
210+
const datasetUri = await findDataset(databasePath);
211+
const sourceArchiveUri = await findSourceArchive(databasePath);
212+
213+
return {
214+
kind: DatabaseKind.Database,
215+
name,
216+
datasetUri,
217+
sourceArchiveUri,
218+
};
216219
}
217-
return contents;
218220
}
219221

220222
/** An item in the list of available databases */
@@ -370,7 +372,9 @@ export class DatabaseItemImpl implements DatabaseItem {
370372
public async refresh(): Promise<void> {
371373
try {
372374
try {
373-
this._contents = await resolveDatabaseContents(this.databaseUri);
375+
this._contents = await DatabaseResolver.resolveDatabaseContents(
376+
this.databaseUri,
377+
);
374378
this._error = undefined;
375379
} catch (e) {
376380
this._contents = undefined;
@@ -602,7 +606,7 @@ export class DatabaseManager extends DisposableObject {
602606
uri: vscode.Uri,
603607
displayName?: string,
604608
): Promise<DatabaseItem> {
605-
const contents = await resolveDatabaseContents(uri);
609+
const contents = await DatabaseResolver.resolveDatabaseContents(uri);
606610
// Ignore the source archive for QLTest databases by default.
607611
const isQLTestDatabase = extname(uri.fsPath) === ".testproj";
608612
const fullOptions: FullDatabaseOptions = {

0 commit comments

Comments
 (0)