Skip to content

Commit ee4ab7f

Browse files
authored
Merge pull request #3137 from AtCoder-NoviSteps/#3135
chore: Update button label in contest table (#3135)
2 parents 6187558 + c123199 commit ee4ab7f

File tree

3 files changed

+130
-18
lines changed

3 files changed

+130
-18
lines changed

docs/guides/how-to-add-contest-table-provider.md

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,59 @@ describe('MyNewProvider', () => {
324324
});
325325
```
326326

327+
### prepareContestProviderPresets() のテスト
328+
329+
Provider クラスのテスト完了後、`prepareContestProviderPresets()` から返されるグループ(`ContestTableProviderGroup`)の動作を検証します。
330+
331+
**テスト項目**:
332+
333+
1. **グループ名の確認**
334+
335+
```typescript
336+
const group = prepareContestProviderPresets().MyNewProvider();
337+
expect(group.getGroupName()).toBe('Expected Group Name');
338+
```
339+
340+
2. **グループメタデータの確認**`buttonLabel``ariaLabel`
341+
342+
```typescript
343+
expect(group.getMetadata()).toEqual({
344+
buttonLabel: 'Button Label',
345+
ariaLabel: 'ARIA Label',
346+
});
347+
```
348+
349+
3. **プロバイダー数の確認**
350+
- **単一プロバイダーグループ**: `getSize()` が 1 を返す
351+
- **複数プロバイダーグループ**: `getSize()` が複数を返す(例:ACL は 3)
352+
353+
4. **プロバイダーインスタンス型の確認**
354+
- **単一プロバイダー**:
355+
```typescript
356+
expect(group.getProvider(ContestType.MY_NEW)).toBeInstanceOf(MyNewProvider);
357+
```
358+
- **複数プロバイダー**(セクション指定あり):
359+
```typescript
360+
expect(group.getProvider(ContestType.TESSOKU_BOOK, 'examples')).toBeInstanceOf(
361+
TessokuBookForExamplesProvider,
362+
);
363+
expect(group.getProvider(ContestType.TESSOKU_BOOK, 'practicals')).toBeInstanceOf(
364+
TessokuBookForPracticalsProvider,
365+
);
366+
```
367+
368+
**セクション識別子の指定**:
369+
370+
複数プロバイダーを含むグループでは、`getProvider()` の第2引数にセクション識別子を渡します。セクション定数は `src/lib/types/contest_table_provider.ts` で定義されています:
371+
372+
- `TESSOKU_SECTIONS`: `examples``practicals``challenges`
373+
- `JOI_SECOND_QUAL_ROUND_SECTIONS`: `'2020Onwards'``from2006To2019`
374+
- `JOI_FINAL_ROUND_SECTIONS`: `semiFinal`
375+
376+
詳細な実装例は [単体テストファイル](../src/test/lib/utils/contest_table_provider.test.ts) を参照してください。
377+
378+
---
379+
327380
### モックデータ準備
328381

329382
**ステップ1: データソース確認**
@@ -479,4 +532,4 @@ describe('CustomProvider with unique config', () => {
479532

480533
---
481534

482-
**最終更新**: 2026-02-01
535+
**最終更新**: 2026-02-05

src/lib/utils/contest_table_provider.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1278,7 +1278,7 @@ export const prepareContestProviderPresets = () => {
12781278
*/
12791279
Acl: () =>
12801280
new ContestTableProviderGroup(`AtCoder Library Contests`, {
1281-
buttonLabel: 'ACL',
1281+
buttonLabel: 'AtCoder Library (ACL)',
12821282
ariaLabel: 'Filter ACL Contests',
12831283
}).addProviders(
12841284
new ACLPracticeProvider(ContestType.ACL_PRACTICE),
@@ -1293,8 +1293,8 @@ export const prepareContestProviderPresets = () => {
12931293
}).addProvider(new JOIFirstQualRoundProvider(ContestType.JOI)),
12941294

12951295
JOISecondQualAndSemiFinalRound: () =>
1296-
new ContestTableProviderGroup(`JOI 二次予選・予選(旧形式)・本選`, {
1297-
buttonLabel: 'JOI 二次予選・予選(旧形式)・本選',
1296+
new ContestTableProviderGroup(`JOI 二次予選・本選`, {
1297+
buttonLabel: 'JOI 二次予選・本選',
12981298
ariaLabel: 'Filter JOI Second Qual Round',
12991299
}).addProviders(
13001300
new JOISecondQualRound2020OnwardsProvider(ContestType.JOI),

src/test/lib/utils/contest_table_provider.test.ts

Lines changed: 73 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2937,20 +2937,6 @@ describe('prepareContestProviderPresets', () => {
29372937
expect(group.getProvider(ContestType.ABC)).toBeInstanceOf(ABC212ToABC318Provider);
29382938
});
29392939

2940-
test('expects to create DPs preset correctly', () => {
2941-
const group = prepareContestProviderPresets().dps();
2942-
2943-
expect(group.getGroupName()).toBe('EDPC・TDPC・FPS 24');
2944-
expect(group.getMetadata()).toEqual({
2945-
buttonLabel: 'EDPC・TDPC・FPS 24',
2946-
ariaLabel: 'EDPC and TDPC and FPS 24 contests',
2947-
});
2948-
expect(group.getSize()).toBe(3);
2949-
expect(group.getProvider(ContestType.EDPC)).toBeInstanceOf(EDPCProvider);
2950-
expect(group.getProvider(ContestType.TDPC)).toBeInstanceOf(TDPCProvider);
2951-
expect(group.getProvider(ContestType.FPS_24)).toBeInstanceOf(FPS24Provider);
2952-
});
2953-
29542940
test('expects to create Typical90 preset correctly', () => {
29552941
const group = prepareContestProviderPresets().Typical90();
29562942

@@ -2983,14 +2969,87 @@ describe('prepareContestProviderPresets', () => {
29832969
);
29842970
});
29852971

2972+
test('expects to create DPs preset correctly', () => {
2973+
const group = prepareContestProviderPresets().dps();
2974+
2975+
expect(group.getGroupName()).toBe('EDPC・TDPC・FPS 24');
2976+
expect(group.getMetadata()).toEqual({
2977+
buttonLabel: 'EDPC・TDPC・FPS 24',
2978+
ariaLabel: 'EDPC and TDPC and FPS 24 contests',
2979+
});
2980+
expect(group.getSize()).toBe(3);
2981+
expect(group.getProvider(ContestType.EDPC)).toBeInstanceOf(EDPCProvider);
2982+
expect(group.getProvider(ContestType.TDPC)).toBeInstanceOf(TDPCProvider);
2983+
expect(group.getProvider(ContestType.FPS_24)).toBeInstanceOf(FPS24Provider);
2984+
});
2985+
2986+
test('expects to create ACL preset correctly with 3 providers', () => {
2987+
const group = prepareContestProviderPresets().Acl();
2988+
2989+
expect(group.getGroupName()).toBe('AtCoder Library Contests');
2990+
expect(group.getMetadata()).toEqual({
2991+
buttonLabel: 'AtCoder Library (ACL)',
2992+
ariaLabel: 'Filter ACL Contests',
2993+
});
2994+
expect(group.getSize()).toBe(3);
2995+
expect(group.getProvider(ContestType.ACL_PRACTICE)).toBeInstanceOf(ACLPracticeProvider);
2996+
expect(group.getProvider(ContestType.ABC_LIKE)).toBeInstanceOf(ACLBeginnerProvider);
2997+
expect(group.getProvider(ContestType.ARC_LIKE)).toBeInstanceOf(ACLProvider);
2998+
});
2999+
3000+
test('expects to create JOI First Qual Round preset correctly with 1 provider', () => {
3001+
const group = prepareContestProviderPresets().JOIFirstQualRound();
3002+
3003+
expect(group.getGroupName()).toBe('JOI 一次予選');
3004+
expect(group.getMetadata()).toEqual({
3005+
buttonLabel: 'JOI 一次予選',
3006+
ariaLabel: 'Filter JOI First Qualifying Round',
3007+
});
3008+
expect(group.getSize()).toBe(1);
3009+
expect(group.getProvider(ContestType.JOI)).toBeInstanceOf(JOIFirstQualRoundProvider);
3010+
});
3011+
3012+
test('expects to create JOI Second Qual and Semi-Final Round preset correctly with 3 providers', () => {
3013+
const group = prepareContestProviderPresets().JOISecondQualAndSemiFinalRound();
3014+
3015+
expect(group.getGroupName()).toBe('JOI 二次予選・本選');
3016+
expect(group.getMetadata()).toEqual({
3017+
buttonLabel: 'JOI 二次予選・本選',
3018+
ariaLabel: 'Filter JOI Second Qual Round',
3019+
});
3020+
expect(group.getSize()).toBe(3);
3021+
expect(group.getProvider(ContestType.JOI, '2020Onwards')).toBeInstanceOf(
3022+
JOISecondQualRound2020OnwardsProvider,
3023+
);
3024+
expect(group.getProvider(ContestType.JOI, 'from2006To2019')).toBeInstanceOf(
3025+
JOIQualRoundFrom2006To2019Provider,
3026+
);
3027+
expect(group.getProvider(ContestType.JOI, 'semiFinal')).toBeInstanceOf(
3028+
JOISemiFinalRoundProvider,
3029+
);
3030+
});
3031+
29863032
test('expects to verify all presets are functions', () => {
29873033
const presets = prepareContestProviderPresets();
29883034

29893035
expect(typeof presets.ABS).toBe('function');
29903036
expect(typeof presets.ABC319Onwards).toBe('function');
29913037
expect(typeof presets.ABC212ToABC318).toBe('function');
3038+
expect(typeof presets.ABC126ToABC211).toBe('function');
3039+
expect(typeof presets.ABC042ToABC125).toBe('function');
3040+
expect(typeof presets.ARC104Onwards).toBe('function');
3041+
expect(typeof presets.ARC058ToARC103).toBe('function');
3042+
expect(typeof presets.AGC001Onwards).toBe('function');
3043+
expect(typeof presets.ABCLike).toBe('function');
3044+
expect(typeof presets.ABC001ToABC041).toBe('function');
3045+
expect(typeof presets.ARC001ToARC057).toBe('function');
29923046
expect(typeof presets.Typical90).toBe('function');
3047+
expect(typeof presets.TessokuBook).toBe('function');
3048+
expect(typeof presets.MathAndAlgorithm).toBe('function');
29933049
expect(typeof presets.dps).toBe('function');
3050+
expect(typeof presets.Acl).toBe('function');
3051+
expect(typeof presets.JOIFirstQualRound).toBe('function');
3052+
expect(typeof presets.JOISecondQualAndSemiFinalRound).toBe('function');
29943053
});
29953054

29963055
test('expects each preset to create independent instances', () => {

0 commit comments

Comments
 (0)