153 lines
4.4 KiB
TypeScript
153 lines
4.4 KiB
TypeScript
describe('BangDream song meta rank summary', () => {
|
|
it('matches full meta ranking entries for a single song', async () => {
|
|
jest.resetModules();
|
|
jest.doMock(
|
|
'@/modules/qqbot/plugins/bangdream/src/application/catalog/bangdream-catalog-cache',
|
|
() => ({
|
|
__esModule: true,
|
|
default: createCatalogFixture(),
|
|
}),
|
|
);
|
|
|
|
const { Server } =
|
|
await import('@/modules/qqbot/plugins/bangdream/src/domain/catalog/server.model');
|
|
const songModule =
|
|
await import('@/modules/qqbot/plugins/bangdream/src/domain/song/song.model');
|
|
const { Song, getMetaRanking } = songModule;
|
|
const getSongMetaRankSummary = (
|
|
songModule as typeof songModule & {
|
|
getSongMetaRankSummary?: (
|
|
song: InstanceType<typeof Song>,
|
|
withFever: boolean,
|
|
server: typeof Server.cn,
|
|
) => {
|
|
entries: Array<{ difficulty: number; meta: number; rank: number }>;
|
|
maxMeta: number;
|
|
};
|
|
}
|
|
).getSongMetaRankSummary;
|
|
|
|
const song = new Song(243);
|
|
const fullRanking = getMetaRanking(true, Server.cn);
|
|
expect(typeof getSongMetaRankSummary).toBe('function');
|
|
const summary = getSongMetaRankSummary(song, true, Server.cn);
|
|
|
|
expect(summary.maxMeta).toBe(fullRanking[0].meta);
|
|
expect(summary.entries).toEqual(
|
|
fullRanking
|
|
.filter((entry) => entry.songId === 243)
|
|
.map(({ difficulty, meta, rank }) => ({ difficulty, meta, rank })),
|
|
);
|
|
});
|
|
|
|
it('caches jacket image decoding within a song instance', async () => {
|
|
const getJacketImageBuffer = jest
|
|
.fn<Promise<Buffer>, [unknown]>()
|
|
.mockResolvedValue(Buffer.from('fake-png'));
|
|
const loadImage = jest.fn(async () => ({
|
|
height: 1,
|
|
width: 1,
|
|
}));
|
|
|
|
jest.resetModules();
|
|
jest.doMock(
|
|
'@/modules/qqbot/plugins/bangdream/src/application/catalog/bangdream-catalog-cache',
|
|
() => ({
|
|
__esModule: true,
|
|
default: createCatalogFixture(),
|
|
}),
|
|
);
|
|
jest.doMock(
|
|
'@/modules/qqbot/plugins/bangdream/src/domain/song/song-resource.repository',
|
|
() => ({
|
|
songResourceRepository: {
|
|
getChart: jest.fn(),
|
|
getDetail: jest.fn(),
|
|
getJacketImageBuffer,
|
|
getJacketImagePath: jest.fn(),
|
|
getSongRip: jest.fn(),
|
|
resolveJacketImageUrl: jest.fn(),
|
|
},
|
|
}),
|
|
);
|
|
jest.doMock('skia-canvas', () => ({
|
|
loadImage,
|
|
}));
|
|
|
|
const { Song } =
|
|
await import('@/modules/qqbot/plugins/bangdream/src/domain/song/song.model');
|
|
|
|
const song = new Song(243);
|
|
const first = await song.getSongJacketImage();
|
|
const second = await song.getSongJacketImage();
|
|
|
|
expect(first).toBe(second);
|
|
expect(getJacketImageBuffer).toHaveBeenCalledTimes(1);
|
|
expect(loadImage).toHaveBeenCalledTimes(1);
|
|
});
|
|
});
|
|
|
|
/**
|
|
* 创建 BangDream 插件对象或配置。
|
|
*/
|
|
function createCatalogFixture() {
|
|
return {
|
|
meta: {
|
|
100: createMeta({ 1: 90, 2: 60 }),
|
|
243: createMeta({ 1: 50, 2: 70 }),
|
|
300: createMeta({ 1: 100, 2: 100 }),
|
|
400: createMeta({ 1: 70, 2: 70 }),
|
|
},
|
|
songs: {
|
|
100: createSong({ id: 100, publishedCn: true }),
|
|
243: createSong({ id: 243, publishedCn: true }),
|
|
300: createSong({ id: 300, publishedCn: false }),
|
|
400: createSong({ id: 400, publishedCn: true }),
|
|
},
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 创建 BangDream 插件对象或配置。
|
|
* @param { id, publishedCn, } - 解构的歌曲测试元数据,用于构造包含 ID 和国服发布时间的 SongMetaSummary 断言样本。
|
|
*/
|
|
function createSong({ id, publishedCn }: { id: number; publishedCn: boolean }) {
|
|
return {
|
|
bandId: 1,
|
|
bpm: {
|
|
1: [{ bpm: 120, end: 1, start: 0 }],
|
|
2: [{ bpm: 140, end: 1, start: 0 }],
|
|
},
|
|
closedAt: [],
|
|
difficulty: {
|
|
1: { playLevel: 20 },
|
|
2: { playLevel: 25 },
|
|
},
|
|
jacketImage: [`song-${id}`],
|
|
length: 120,
|
|
musicTitle: [`Song ${id}`, null, null, `歌曲 ${id}`, null],
|
|
nickname: null,
|
|
notes: {
|
|
1: 500,
|
|
2: 700,
|
|
},
|
|
publishedAt: [null, null, null, publishedCn ? 1 : null, null],
|
|
tag: 'normal',
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 创建 BangDream 插件对象或配置。
|
|
* @param values - 配置值字典;驱动 `Object.fromEntries()` 的 BangDream步骤。
|
|
*/
|
|
function createMeta(values: Record<number, number>) {
|
|
return Object.fromEntries(
|
|
Object.entries(values).map(([difficulty, value]) => [
|
|
difficulty,
|
|
{
|
|
7: [0, value, 0, value],
|
|
},
|
|
]),
|
|
);
|
|
}
|