Merge pull request #2330 from github/yer-a-sorted-database-query

Select latest database when creating skeleton query
This commit is contained in:
Elena Tanasoiu
2023-04-19 12:22:30 +01:00
committed by GitHub
2 changed files with 193 additions and 99 deletions

View File

@@ -253,11 +253,19 @@ export class SkeletonQueryWizard {
} }
private async selectOrDownloadDatabase() { private async selectOrDownloadDatabase() {
if (this.language === undefined) {
throw new Error("Language is undefined");
}
if (this.qlPackStoragePath === undefined) { if (this.qlPackStoragePath === undefined) {
throw new Error("QL Pack storage path is undefined"); throw new Error("QL Pack storage path is undefined");
} }
const existingDatabaseItem = await this.findExistingDatabaseItem(); const existingDatabaseItem =
await SkeletonQueryWizard.findExistingDatabaseItem(
this.language,
this.databaseManager.databaseItems,
);
if (existingDatabaseItem) { if (existingDatabaseItem) {
// select the found database // select the found database
@@ -268,59 +276,68 @@ export class SkeletonQueryWizard {
} }
} }
public async findDatabaseItemByNwo( public static async findDatabaseItemByNwo(
language: string, language: string,
databaseNwo: string, databaseNwo: string,
databaseItems: readonly DatabaseItem[], databaseItems: readonly DatabaseItem[],
): Promise<DatabaseItem | undefined> { ): Promise<DatabaseItem | undefined> {
const dbItems = databaseItems || []; const dbs = databaseItems.filter(
const dbs = dbItems.filter( (db) => db.language === language && db.name === databaseNwo,
(db) =>
db.language === language &&
db.name === databaseNwo &&
db.error === undefined,
); );
if (dbs.length === 0) { return dbs.pop();
return undefined;
}
return dbs[0];
} }
public async findDatabaseItemByLanguage( public static async findDatabaseItemByLanguage(
language: string, language: string,
databaseItems: readonly DatabaseItem[], databaseItems: readonly DatabaseItem[],
): Promise<DatabaseItem | undefined> { ): Promise<DatabaseItem | undefined> {
const dbItems = databaseItems || []; const dbs = databaseItems.filter((db) => db.language === language);
const dbs = dbItems.filter(
(db) => db.language === language && db.error === undefined, return dbs.pop();
);
if (dbs.length === 0) {
return undefined;
}
return dbs[0];
} }
private async findExistingDatabaseItem() { public static async findExistingDatabaseItem(
if (this.language === undefined) { language: string,
throw new Error("Language is undefined"); databaseItems: readonly DatabaseItem[],
} ): Promise<DatabaseItem | undefined> {
const defaultDatabaseNwo = QUERY_LANGUAGE_TO_DATABASE_REPO[language];
const defaultDatabaseNwo = QUERY_LANGUAGE_TO_DATABASE_REPO[this.language]; const dbItems = await SkeletonQueryWizard.sortDatabaseItemsByDateAdded(
databaseItems,
);
const defaultDatabaseItem = await this.findDatabaseItemByNwo( const defaultDatabaseItem = await SkeletonQueryWizard.findDatabaseItemByNwo(
this.language, language,
defaultDatabaseNwo, defaultDatabaseNwo,
this.databaseManager.databaseItems, dbItems,
); );
if (defaultDatabaseItem !== undefined) { if (defaultDatabaseItem !== undefined) {
return defaultDatabaseItem; return defaultDatabaseItem;
} }
return await this.findDatabaseItemByLanguage( return await SkeletonQueryWizard.findDatabaseItemByLanguage(
this.language, language,
this.databaseManager.databaseItems, dbItems,
); );
} }
public static async sortDatabaseItemsByDateAdded(
databaseItems: readonly DatabaseItem[],
) {
const validDbItems = databaseItems.filter((db) => db.error === undefined);
return validDbItems.sort((a, b) => {
if (a.dateAdded === undefined) {
return -1;
}
if (b.dateAdded === undefined) {
return 1;
}
return a.dateAdded - b.dateAdded;
});
}
} }

View File

@@ -320,7 +320,7 @@ describe("SkeletonQueryWizard", () => {
jest.spyOn(mockDbItem, "name", "get").mockReturnValue("mock-name"); jest.spyOn(mockDbItem, "name", "get").mockReturnValue("mock-name");
const databaseItem = await wizard.findDatabaseItemByNwo( const databaseItem = await SkeletonQueryWizard.findDatabaseItemByNwo(
mockDbItem.language, mockDbItem.language,
mockDbItem.name, mockDbItem.name,
[mockDbItem, mockDbItem2], [mockDbItem, mockDbItem2],
@@ -330,37 +330,6 @@ describe("SkeletonQueryWizard", () => {
JSON.stringify(mockDbItem), JSON.stringify(mockDbItem),
); );
}); });
it("should ignore databases with errors", async () => {
const mockDbItem = createMockDB(dir, {
language: "ruby",
dateAdded: 123,
} as FullDatabaseOptions);
const mockDbItem2 = createMockDB(dir, {
language: "javascript",
} as FullDatabaseOptions);
const mockDbItem3 = createMockDB(dir, {
language: "ruby",
dateAdded: 345,
} as FullDatabaseOptions);
jest.spyOn(mockDbItem, "name", "get").mockReturnValue("mock-name");
jest.spyOn(mockDbItem3, "name", "get").mockReturnValue(mockDbItem.name);
jest
.spyOn(mockDbItem, "error", "get")
.mockReturnValue(asError("database go boom!"));
const databaseItem = await wizard.findDatabaseItemByNwo(
mockDbItem.language,
mockDbItem.name,
[mockDbItem, mockDbItem2, mockDbItem3],
);
expect(JSON.stringify(databaseItem)).toEqual(
JSON.stringify(mockDbItem3),
);
});
}); });
describe("when the item doesn't exist", () => { describe("when the item doesn't exist", () => {
@@ -368,7 +337,7 @@ describe("SkeletonQueryWizard", () => {
const mockDbItem = createMockDB(dir); const mockDbItem = createMockDB(dir);
const mockDbItem2 = createMockDB(dir); const mockDbItem2 = createMockDB(dir);
const databaseItem = await wizard.findDatabaseItemByNwo( const databaseItem = await SkeletonQueryWizard.findDatabaseItemByNwo(
"ruby", "ruby",
"mock-nwo", "mock-nwo",
[mockDbItem, mockDbItem2], [mockDbItem, mockDbItem2],
@@ -389,39 +358,14 @@ describe("SkeletonQueryWizard", () => {
language: "javascript", language: "javascript",
} as FullDatabaseOptions); } as FullDatabaseOptions);
const databaseItem = await wizard.findDatabaseItemByLanguage("ruby", [ const databaseItem =
mockDbItem, await SkeletonQueryWizard.findDatabaseItemByLanguage("ruby", [
mockDbItem2, mockDbItem,
]); mockDbItem2,
]);
expect(databaseItem).toEqual(mockDbItem); expect(databaseItem).toEqual(mockDbItem);
}); });
it("should ignore databases with errors", async () => {
const mockDbItem = createMockDB(dir, {
language: "ruby",
} as FullDatabaseOptions);
const mockDbItem2 = createMockDB(dir, {
language: "javascript",
} as FullDatabaseOptions);
const mockDbItem3 = createMockDB(dir, {
language: "ruby",
} as FullDatabaseOptions);
jest
.spyOn(mockDbItem, "error", "get")
.mockReturnValue(asError("database go boom!"));
const databaseItem = await wizard.findDatabaseItemByLanguage("ruby", [
mockDbItem,
mockDbItem2,
mockDbItem3,
]);
expect(JSON.stringify(databaseItem)).toEqual(
JSON.stringify(mockDbItem3),
);
});
}); });
describe("when the item doesn't exist", () => { describe("when the item doesn't exist", () => {
@@ -429,10 +373,11 @@ describe("SkeletonQueryWizard", () => {
const mockDbItem = createMockDB(dir); const mockDbItem = createMockDB(dir);
const mockDbItem2 = createMockDB(dir); const mockDbItem2 = createMockDB(dir);
const databaseItem = await wizard.findDatabaseItemByLanguage("ruby", [ const databaseItem =
mockDbItem, await SkeletonQueryWizard.findDatabaseItemByLanguage("ruby", [
mockDbItem2, mockDbItem,
]); mockDbItem2,
]);
expect(databaseItem).toBeUndefined(); expect(databaseItem).toBeUndefined();
}); });
@@ -550,4 +495,136 @@ describe("SkeletonQueryWizard", () => {
}); });
}); });
}); });
describe("sortDatabaseItemsByDateAdded", () => {
describe("should return a sorted list", () => {
it("should sort the items by dateAdded", async () => {
const mockDbItem = createMockDB(dir, {
dateAdded: 678,
} as FullDatabaseOptions);
const mockDbItem2 = createMockDB(dir, {
dateAdded: 123,
} as FullDatabaseOptions);
const mockDbItem3 = createMockDB(dir, {
dateAdded: undefined,
} as FullDatabaseOptions);
const mockDbItem4 = createMockDB(dir, {
dateAdded: 345,
} as FullDatabaseOptions);
const sortedList =
await SkeletonQueryWizard.sortDatabaseItemsByDateAdded([
mockDbItem,
mockDbItem2,
mockDbItem3,
mockDbItem4,
]);
expect(sortedList).toEqual([
mockDbItem3,
mockDbItem2,
mockDbItem4,
mockDbItem,
]);
});
it("should ignore databases with errors", async () => {
const mockDbItem = createMockDB(dir, {
dateAdded: 678,
} as FullDatabaseOptions);
const mockDbItem2 = createMockDB(dir, {
dateAdded: undefined,
} as FullDatabaseOptions);
const mockDbItem3 = createMockDB(dir, {
dateAdded: 345,
} as FullDatabaseOptions);
const mockDbItem4 = createMockDB(dir, {
dateAdded: 123,
} as FullDatabaseOptions);
jest
.spyOn(mockDbItem, "error", "get")
.mockReturnValue(asError("database go boom!"));
const sortedList =
await SkeletonQueryWizard.sortDatabaseItemsByDateAdded([
mockDbItem,
mockDbItem2,
mockDbItem3,
mockDbItem4,
]);
expect(sortedList).toEqual([mockDbItem2, mockDbItem4, mockDbItem3]);
});
});
});
describe("findExistingDatabaseItem", () => {
describe("when there are multiple items with the same name", () => {
it("should choose the latest one", async () => {
const mockDbItem = createMockDB(dir, {
language: "javascript",
dateAdded: 456,
} as FullDatabaseOptions);
const mockDbItem2 = createMockDB(dir, {
language: "ruby",
dateAdded: 789,
} as FullDatabaseOptions);
const mockDbItem3 = createMockDB(dir, {
language: "javascript",
dateAdded: 123,
} as FullDatabaseOptions);
const mockDbItem4 = createMockDB(dir, {
language: "javascript",
dateAdded: undefined,
} as FullDatabaseOptions);
jest
.spyOn(mockDbItem, "name", "get")
.mockReturnValue(QUERY_LANGUAGE_TO_DATABASE_REPO["javascript"]);
jest
.spyOn(mockDbItem2, "name", "get")
.mockReturnValue(QUERY_LANGUAGE_TO_DATABASE_REPO["javascript"]);
const databaseItem = await SkeletonQueryWizard.findExistingDatabaseItem(
"javascript",
[mockDbItem, mockDbItem2, mockDbItem3, mockDbItem4],
);
expect(JSON.stringify(databaseItem)).toEqual(
JSON.stringify(mockDbItem),
);
});
});
describe("when there are multiple items with the same language", () => {
it("should choose the latest one", async () => {
const mockDbItem = createMockDB(dir, {
language: "ruby",
dateAdded: 789,
} as FullDatabaseOptions);
const mockDbItem2 = createMockDB(dir, {
language: "javascript",
dateAdded: 456,
} as FullDatabaseOptions);
const mockDbItem3 = createMockDB(dir, {
language: "ruby",
dateAdded: 123,
} as FullDatabaseOptions);
const mockDbItem4 = createMockDB(dir, {
language: "javascript",
dateAdded: undefined,
} as FullDatabaseOptions);
const databaseItem = await SkeletonQueryWizard.findExistingDatabaseItem(
"javascript",
[mockDbItem, mockDbItem2, mockDbItem3, mockDbItem4],
);
expect(JSON.stringify(databaseItem)).toEqual(
JSON.stringify(mockDbItem2),
);
});
});
});
}); });