From bb21eafc111208de03fcf34ff715c0cc5f595cde Mon Sep 17 00:00:00 2001 From: Kato Hiroki Date: Wed, 31 Dec 2025 12:51:40 +0000 Subject: [PATCH 1/2] breaking: Remove ABC latest 20 rounds from contest table (#3000) --- .../remove-abc-latest-20-rounds/plan.md | 106 +++++++++++++ src/lib/stores/active_contest_type.svelte.ts | 15 +- src/lib/utils/contest_table_provider.ts | 45 ------ .../stores/active_contest_type.svelte.test.ts | 22 +-- .../lib/utils/contest_table_provider.test.ts | 141 +++++------------- 5 files changed, 163 insertions(+), 166 deletions(-) create mode 100644 docs/dev-notes/2025-12-31/remove-abc-latest-20-rounds/plan.md diff --git a/docs/dev-notes/2025-12-31/remove-abc-latest-20-rounds/plan.md b/docs/dev-notes/2025-12-31/remove-abc-latest-20-rounds/plan.md new file mode 100644 index 000000000..f6da98636 --- /dev/null +++ b/docs/dev-notes/2025-12-31/remove-abc-latest-20-rounds/plan.md @@ -0,0 +1,106 @@ +# **ABCLatest20RoundsProvider の削除計画** + +## **目的** + +`ABCLatest20RoundsProvider` を削除し、関連するコードやテストを整理することで、コードベースの簡素化とメンテナンス性の向上を図る。 + +## ** 理由** + +- ABC 319 〜 に完全に包含されている +- X 公式アカウントでのアンケートで、「ABC 最新 20 回」を日常的に使っているユーザは投票数の約1/4程度 +- 当初の目的であった初回表示の負荷軽減対策には、「ABS」をデフォルトで表示することで対応 + +--- + +## **削除対象** + +### 1. `src/lib/utils/contest_table_provider.ts` + +- **行167**: `export class ABCLatest20RoundsProvider extends ContestTableProviderBase {` を削除。 +- **行1086**: `.addProvider(new ABCLatest20RoundsProvider(ContestType.ABC)),` を削除。 +- **行1244**: `abcLatest20Rounds: prepareContestProviderPresets().ABCLatest20Rounds(),` を削除。 + +### 2. `src/test/lib/utils/contest_table_provider.test.ts` + +- **`describe('ABC providers', () => {` 内の以下を削除**: + ```typescript + { + providerClass: ABCLatest20RoundsProvider, + label: 'Latest 20 rounds', + displayConfig: { + roundLabelWidth: 'xl:w-16', + tableBodyCellsWidth: 'w-1/2 xs:w-1/3 sm:w-1/4 md:w-1/5 lg:w-1/6 px-1 py-1', + }, + }, + ``` +- **`describe('ABC Latest 20 Rounds', () => {` のテスト全体を削除**。 +- **行349, 357, 374, 382**: `ABCLatest20RoundsProvider` に関連するテストを削除。 +- **行2425, 2437, 2466, 2512, 2526, 2604**: `ABCLatest20RoundsProvider` を `ABSProvider` に置き換え。 + +### 3. `src/lib/stores/active_contest_type.svelte.ts` + +- **行16**: コメント内の `'abcLatest20Rounds'` を `'abs'` に変更。 +- **行21**: `'abcLatest20Rounds'` を `'abs'` に変更。 +- **行28**: コメント内の `'abcLatest20Rounds'` を `'abs'` に変更。 +- **行30**: コンストラクタのデフォルト値 `'abcLatest20Rounds'` を `'abs'` に変更。 +- **行79**: コメント内の `'abcLatest20Rounds'` を `'abs'` に変更。 +- **行82**: `this.storage.value = 'abcLatest20Rounds';` を `this.storage.value = 'abs';` に変更。 + +### 4. `src/test/lib/stores/active_contest_type.svelte.test.ts` + +- **行44**: `expect(store.get()).toBe('abcLatest20Rounds');` を `expect(store.get()).toBe('abs');` に変更。 +- **行48**: 同上。 +- **行64**: `expect(store.isSame('abcLatest20Rounds' as ContestTableProviderGroups)).toBe(true);` を `expect(store.isSame('abs' as ContestTableProviderGroups)).toBe(true);` に変更。 +- **行70**: 同上。 +- **行75**: 同上。 +- **行86**: `expect(store.get()).toBe('abcLatest20Rounds');` を `expect(store.get()).toBe('abs');` に変更。 +- **行93**: 同上。 +- **行101**: `expect(newStore.get()).toBe('abcLatest20Rounds');` を `expect(newStore.get()).toBe('abs');` に変更。 +- **行108**: 同上。 +- **行115**: `'abcLatest20Rounds' as ContestTableProviderGroups` を `'abs' as ContestTableProviderGroups` に変更。 +- **行138**: `expect(activeContestTypeStore.get()).toBe('abcLatest20Rounds');` を `expect(activeContestTypeStore.get()).toBe('abs');` に変更。 + +### 5. ドキュメントの更新 + +- **`/usr/src/app/docs/dev-notes/2025-11-01/add_and_refactoring_tests_for_contest_table_provider/plan.md`** + - **行516**: `- ABCLatest20RoundsProvider テストの generateTable 検証を追加` を削除。 + +--- + +## **影響範囲** + +1. **`src/lib/utils/contest_table_provider.ts`** + - 他のプロバイダーやロジックに影響を与えないか確認済み。 + +2. **`src/test/lib/utils/contest_table_provider.test.ts`** + - 削除対象のテストが他のテストケースに依存していないことを確認済み。 + +3. **テストカバレッジ** + - 削除前後でテストカバレッジを比較し、削除が他のテストに影響を与えないことを確認済み。 + +4. **ドキュメント** + - 関連するドキュメントを特定し、更新箇所を明確化。 + +--- + +## **次のステップ** + +1. **コードの修正** + - 上記の削除対象箇所を修正。 + +2. **テストの実行** + - 修正後にテストを再実行し、他の箇所に影響がないことを確認。 + +3. **ドキュメントの更新** + - 削除に伴う変更をドキュメントに反映。 + +## 教訓 + +1. **削除対象の影響範囲を明確化する** + - 削除対象が他のコードやテストに与える影響を事前に洗い出し、計画に反映する。 + +2. **テストカバレッジの維持** + - 削除後もテストカバレッジが低下しないよう、必要に応じて代替テストを追加する。 + +3. **ドキュメントの更新を徹底する** + - 削除に伴う変更をドキュメントに反映し、後続の開発者が変更内容を正確に把握できるようにする。 diff --git a/src/lib/stores/active_contest_type.svelte.ts b/src/lib/stores/active_contest_type.svelte.ts index dd3d5d5d8..1b06d1603 100644 --- a/src/lib/stores/active_contest_type.svelte.ts +++ b/src/lib/stores/active_contest_type.svelte.ts @@ -13,21 +13,18 @@ import { * * The store uses the ContestTableProviderGroups type which represents * different contest table configurations or data providers, - * with a default value of 'abcLatest20Rounds'. + * with a default value of 'abs'. */ export class ActiveContestTypeStore { - private storage = useLocalStorage( - 'contest_table_providers', - 'abcLatest20Rounds', - ); + private storage = useLocalStorage('contest_table_providers', 'abs'); /** * Creates an instance with the specified contest type. * * @param defaultContestType - The default contest type to initialize. - * Defaults to 'abcLatest20Rounds'. + * Defaults to 'abs'. */ - constructor(defaultContestType: ContestTableProviderGroups = 'abcLatest20Rounds') { + constructor(defaultContestType: ContestTableProviderGroups = 'abs') { if (!this.isValidContestType(this.storage.value)) { this.storage.value = defaultContestType; } @@ -76,10 +73,10 @@ export class ActiveContestTypeStore { /** * Resets the active contest type to the default value. - * Sets the internal value to 'abcLatest20Rounds'. + * Sets the internal value to 'abs'. */ reset(): void { - this.storage.value = 'abcLatest20Rounds'; + this.storage.value = 'abs'; } } diff --git a/src/lib/utils/contest_table_provider.ts b/src/lib/utils/contest_table_provider.ts index b4ae74256..c3f6c191e 100644 --- a/src/lib/utils/contest_table_provider.ts +++ b/src/lib/utils/contest_table_provider.ts @@ -164,41 +164,6 @@ export class ABSProvider extends ContestTableProviderBase { } } -export class ABCLatest20RoundsProvider extends ContestTableProviderBase { - filter(taskResults: TaskResults): TaskResults { - const taskResultsOnlyABC = taskResults.filter(this.setFilterCondition()); - - const CONTEST_ROUND_COUNT = 20; - const latest20ContestIds = Array.from( - new Set(taskResultsOnlyABC.map((taskResult: TaskResult) => taskResult.contest_id)), - ) - .sort() - .reverse() - .slice(0, CONTEST_ROUND_COUNT); - - return taskResultsOnlyABC.filter((task: TaskResult) => - latest20ContestIds.includes(task.contest_id), - ); - } - - protected setFilterCondition(): (taskResult: TaskResult) => boolean { - // Note: Narrow down taskResults in advance to reduce time to display. - return (task: TaskResult) => classifyContest(task.contest_id) === ContestType.ABC; - } - - getMetadata(): ContestTableMetaData { - return { - title: 'AtCoder Beginner Contest 最新 20 回', - abbreviationName: 'abcLatest20Rounds', - }; - } - - getContestRoundLabel(contestId: string): string { - const contestNameLabel = getContestNameLabel(contestId); - return contestNameLabel.replace('ABC ', ''); - } -} - // ABC319 〜 (2023/09/09 〜 ) // 7 tasks per contest export class ABC319OnwardsProvider extends ContestTableProviderBase { @@ -1076,15 +1041,6 @@ export const prepareContestProviderPresets = () => { ariaLabel: 'Filter AtCoder Beginners Selection', }).addProvider(new ABSProvider(ContestType.ABS)), - /** - * Single group for ABC latest 20 rounds - */ - ABCLatest20Rounds: () => - new ContestTableProviderGroup(`ABC Latest 20 Rounds`, { - buttonLabel: 'ABC 最新 20 回', - ariaLabel: 'Filter ABC latest 20 rounds', - }).addProvider(new ABCLatest20RoundsProvider(ContestType.ABC)), - /** * Single group for ABC 319 onwards */ @@ -1241,7 +1197,6 @@ export const prepareContestProviderPresets = () => { export const contestTableProviderGroups = { abs: prepareContestProviderPresets().ABS(), - abcLatest20Rounds: prepareContestProviderPresets().ABCLatest20Rounds(), abc319Onwards: prepareContestProviderPresets().ABC319Onwards(), fromAbc212ToAbc318: prepareContestProviderPresets().ABC212ToABC318(), fromAbc126ToAbc211: prepareContestProviderPresets().ABC126ToABC211(), diff --git a/src/test/lib/stores/active_contest_type.svelte.test.ts b/src/test/lib/stores/active_contest_type.svelte.test.ts index f5ba4c206..3e389eb78 100644 --- a/src/test/lib/stores/active_contest_type.svelte.test.ts +++ b/src/test/lib/stores/active_contest_type.svelte.test.ts @@ -41,11 +41,11 @@ describe('ActiveContestTypeStore', () => { }); test('expects to initialize with default value', () => { - expect(store.get()).toBe('abcLatest20Rounds'); + expect(store.get()).toBe('abs'); }); test('expects to return the current value when calling get()', () => { - expect(store.get()).toBe('abcLatest20Rounds'); + expect(store.get()).toBe('abs'); // Change the value and verify get() returns the new value store.set('abc319Onwards' as ContestTableProviderGroups); @@ -61,18 +61,18 @@ describe('ActiveContestTypeStore', () => { }); test('expects to correctly determine if contest type is the same with isSame()', () => { - expect(store.isSame('abcLatest20Rounds' as ContestTableProviderGroups)).toBe(true); + expect(store.isSame('abs' as ContestTableProviderGroups)).toBe(true); expect(store.isSame('abc319Onwards' as ContestTableProviderGroups)).toBe(false); expect(store.isSame('fromAbc212ToAbc318' as ContestTableProviderGroups)).toBe(false); store.set('abc319Onwards' as ContestTableProviderGroups); expect(store.isSame('abc319Onwards' as ContestTableProviderGroups)).toBe(true); - expect(store.isSame('abcLatest20Rounds' as ContestTableProviderGroups)).toBe(false); + expect(store.isSame('abs' as ContestTableProviderGroups)).toBe(false); expect(store.isSame('fromAbc212ToAbc318' as ContestTableProviderGroups)).toBe(false); store.set('fromAbc212ToAbc318' as ContestTableProviderGroups); expect(store.isSame('fromAbc212ToAbc318' as ContestTableProviderGroups)).toBe(true); - expect(store.isSame('abcLatest20Rounds' as ContestTableProviderGroups)).toBe(false); + expect(store.isSame('abs' as ContestTableProviderGroups)).toBe(false); expect(store.isSame('abc319Onwards' as ContestTableProviderGroups)).toBe(false); }); @@ -83,14 +83,14 @@ describe('ActiveContestTypeStore', () => { // Call reset and verify it goes back to default store.reset(); - expect(store.get()).toBe('abcLatest20Rounds'); + expect(store.get()).toBe('abs'); // Change to a different value and reset again to verify consistency store.set('fromAbc212ToAbc318' as ContestTableProviderGroups); expect(store.get()).toBe('fromAbc212ToAbc318'); store.reset(); - expect(store.get()).toBe('abcLatest20Rounds'); + expect(store.get()).toBe('abs'); }); test('expects to reset to default when initialized with invalid localStorage key', () => { @@ -98,21 +98,21 @@ describe('ActiveContestTypeStore', () => { mockStorage['contest_table_providers'] = JSON.stringify('invalidContestType'); const newStore = new ActiveContestTypeStore(); - expect(newStore.get()).toBe('abcLatest20Rounds'); + expect(newStore.get()).toBe('abs'); }); test('expects to reset to default when initialized with null', () => { mockStorage['contest_table_providers'] = JSON.stringify(null); const newStore = new ActiveContestTypeStore(); - expect(newStore.get()).toBe('abcLatest20Rounds'); + expect(newStore.get()).toBe('abs'); }); test('expects to handle multiple contest type changes', () => { const types: ContestTableProviderGroups[] = [ 'abc319Onwards' as ContestTableProviderGroups, 'fromAbc212ToAbc318' as ContestTableProviderGroups, - 'abcLatest20Rounds' as ContestTableProviderGroups, + 'abs' as ContestTableProviderGroups, ]; types.forEach((type) => { @@ -135,6 +135,6 @@ describe('Active contest type store in SSR', () => { }); test('handles SSR gracefully', () => { - expect(activeContestTypeStore.get()).toBe('abcLatest20Rounds'); + expect(activeContestTypeStore.get()).toBe('abs'); }); }); diff --git a/src/test/lib/utils/contest_table_provider.test.ts b/src/test/lib/utils/contest_table_provider.test.ts index dbae93291..93b66ff4e 100644 --- a/src/test/lib/utils/contest_table_provider.test.ts +++ b/src/test/lib/utils/contest_table_provider.test.ts @@ -5,7 +5,6 @@ import type { TaskResult, TaskResults } from '$lib/types/task'; import { ABSProvider, - ABCLatest20RoundsProvider, ABC319OnwardsProvider, ABC212ToABC318Provider, ABC126ToABC211Provider, @@ -142,14 +141,6 @@ describe('ContestTableProviderBase and implementations', () => { describe('ABC providers', () => { describe.each([ - { - providerClass: ABCLatest20RoundsProvider, - label: 'Latest 20 rounds', - displayConfig: { - roundLabelWidth: 'xl:w-16', - tableBodyCellsWidth: 'w-1/2 xs:w-1/3 sm:w-1/4 md:w-1/5 lg:w-1/6 px-1 py-1', - }, - }, { providerClass: ABC319OnwardsProvider, label: '319 onwards', @@ -352,57 +343,6 @@ describe('ContestTableProviderBase and implementations', () => { }); }); - // ABC Latest 20 Round only - describe('ABC Latest 20 Rounds', () => { - test('expects to filter tasks to include only ABC contests', () => { - const provider = new ABCLatest20RoundsProvider(ContestType.ABC); - const filtered = provider.filter(mockTaskResults); - - expect(filtered?.every((task) => task.contest_id.startsWith('abc'))).toBe(true); - expect(filtered).not.toContainEqual(expect.objectContaining({ contest_id: 'arc100' })); - }); - - test('expects to limit results to the latest 20 rounds', () => { - const provider = new ABCLatest20RoundsProvider(ContestType.ABC); - const taskResults = [...mockTaskResults]; - const filtered = provider.filter(taskResults); - const uniqueContests = new Set(filtered.map((task) => task.contest_id)); - - expect(uniqueContests.size).toBe(20); - - const contestRounds = Array.from(uniqueContests) - .map((id) => getContestRound(id)) - .sort((a, b) => b - a); - const latestRound = Math.max(...contestRounds); - const expectedRounds = Array.from({ length: 20 }, (_, i) => latestRound - i); - - expect(contestRounds).toEqual(expectedRounds); - }); - - test('expects to get correct metadata', () => { - const provider = new ABCLatest20RoundsProvider(ContestType.ABC); - const metadata = provider.getMetadata(); - - expect(metadata.title).toBe('AtCoder Beginner Contest 最新 20 回'); - expect(metadata.abbreviationName).toBe('abcLatest20Rounds'); - }); - - test('expects to handle task results with different contest types', () => { - const provider = new ABCLatest20RoundsProvider(ContestType.ABC); - const mockMixedTasks = [ - { contest_id: 'abc378', task_id: 'abc378_a', task_table_index: 'A' }, - { contest_id: 'dp', task_id: 'dp_a', task_table_index: 'A' }, - { contest_id: 'abc397', task_id: 'abc397_a', task_table_index: 'A' }, - { contest_id: 'typical90', task_id: 'typical90_a', task_table_index: '001' }, - { contest_id: 'arc100', task_id: 'arc100_a', task_table_index: 'A' }, - ]; - const filtered = provider.filter(mockMixedTasks as TaskResults); - - expect(filtered.every((task) => task.contest_id.startsWith('abc'))).toBe(true); - expect(filtered).not.toContainEqual(expect.objectContaining({ contest_id: 'dp' })); - }); - }); - // ABC 319 Onwards only describe('ABC 319 Onwards', () => { test('expects to filter tasks to include only ABC319 and later', () => { @@ -703,6 +643,7 @@ describe('ContestTableProviderBase and implementations', () => { }); }); + // ABC001 to ABC 041 describe('ABC 001 to ABC 041', () => { test('expects to filter tasks within ABC001-41 range', () => { const provider = new ABC001ToABC041Provider(ContestType.ABC); @@ -2430,23 +2371,21 @@ describe('ContestTableProviderBase and implementations', () => { describe('Common provider functionality', () => { test('expects to get contest round IDs correctly', () => { - const provider = new ABCLatest20RoundsProvider(ContestType.ABC); + const provider = new ABSProvider(ContestType.ABS); // Use a subset of the mock data that covers the relevant contest IDs - const filtered = mockTaskResults.filter((task) => - ['abc397', 'abc319', 'abc318'].includes(task.contest_id), - ); + const filtered = taskResultsForABS.filter((task) => ['abs'].includes(task.contest_id)); const roundIds = provider.getContestRoundIds(filtered); - expect(roundIds).toEqual(['abc397', 'abc319', 'abc318']); + expect(roundIds).toEqual(['abs']); }); test('expects to get header IDs for tasks correctly', () => { - const provider = new ABCLatest20RoundsProvider(ContestType.ABC); - const filtered = mockTaskResults.filter((task) => task.contest_id === 'abc319'); + const provider = new ABSProvider(ContestType.ABS); + const filtered = taskResultsForABS.filter((task) => task.contest_id === 'abs'); const headerIds = provider.getHeaderIdsForTask(filtered); - expect(headerIds).toEqual(['A', 'B', 'C', 'D', 'E', 'F', 'G']); + expect(headerIds).toEqual(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K']); }); }); }); @@ -2467,16 +2406,16 @@ describe('ContestTableProviderGroup', () => { }); test('expects to add a single provider correctly', () => { - const group = new ContestTableProviderGroup('ABC Latest 20 Rounds', { - buttonLabel: 'ABC 最新 20 回', - ariaLabel: 'Filter ABC latest 20 rounds', + const group = new ContestTableProviderGroup('AtCoder Beginners Selection', { + buttonLabel: 'ABS', + ariaLabel: 'Filter AtCoder Beginners Selection', }); - const provider = new ABCLatest20RoundsProvider(ContestType.ABC); + const provider = new ABSProvider(ContestType.ABS); group.addProvider(provider); expect(group.getSize()).toBe(1); - expect(group.getProvider(ContestType.ABC)).toBe(provider); + expect(group.getProvider(ContestType.ABS)).toBe(provider); expect(group.getProvider(ContestType.OTHERS)).toBeUndefined(); }); @@ -2517,10 +2456,10 @@ describe('ContestTableProviderGroup', () => { buttonLabel: '初心者向けセット', ariaLabel: 'Filter contests for beginner', }); - const abcProvider = new ABCLatest20RoundsProvider(ContestType.ABC); + const absProvider = new ABSProvider(ContestType.ABS); const edpcProvider = new EDPCProvider(ContestType.EDPC); - const result = group.addProvider(abcProvider).addProvider(edpcProvider); + const result = group.addProvider(absProvider).addProvider(edpcProvider); expect(result).toBe(group); expect(group.getSize()).toBe(2); @@ -2531,7 +2470,7 @@ describe('ContestTableProviderGroup', () => { buttonLabel: 'コンテストテーブルに関する統計情報', ariaLabel: 'Statistics for contest table', }); - const abcProvider = new ABCLatest20RoundsProvider(ContestType.ABC); + const abcProvider = new ABSProvider(ContestType.ABC); const edpcProvider = new EDPCProvider(ContestType.EDPC); group.addProvider(abcProvider); @@ -2592,29 +2531,29 @@ describe('ContestTableProviderGroup', () => { group.addProviders(examplesProvider, practicalsProvider, challengesProvider); expect(group.getSize()).toBe(3); - expect(group.getProvider(ContestType.TESSOKU_BOOK, TESSOKU_SECTIONS.EXAMPLES)).toBe( - examplesProvider, - ); - expect(group.getProvider(ContestType.TESSOKU_BOOK, TESSOKU_SECTIONS.PRACTICALS)).toBe( - practicalsProvider, - ); - expect(group.getProvider(ContestType.TESSOKU_BOOK, TESSOKU_SECTIONS.CHALLENGES)).toBe( - challengesProvider, + expect(group.getProvider(ContestType.TESSOKU_BOOK, TESSOKU_SECTIONS.EXAMPLES)).toBeInstanceOf( + TessokuBookForExamplesProvider, ); + expect( + group.getProvider(ContestType.TESSOKU_BOOK, TESSOKU_SECTIONS.PRACTICALS), + ).toBeInstanceOf(TessokuBookForPracticalsProvider); + expect( + group.getProvider(ContestType.TESSOKU_BOOK, TESSOKU_SECTIONS.CHALLENGES), + ).toBeInstanceOf(TessokuBookForChallengesProvider); }); test('expects backward compatibility for getProvider without section', () => { - const group = new ContestTableProviderGroup('ABC Latest 20 Rounds', { - buttonLabel: 'ABC 最新 20 回', - ariaLabel: 'Filter ABC latest 20 rounds', + const group = new ContestTableProviderGroup('AtCoder Beginners Selection', { + buttonLabel: 'ABS', + ariaLabel: 'Filter AtCoder Beginners Selection', }); - const abcProvider = new ABCLatest20RoundsProvider(ContestType.ABC); - group.addProvider(abcProvider); + const absProvider = new ABSProvider(ContestType.ABS); + group.addProvider(absProvider); // Get provider without section should work with simple key - expect(group.getProvider(ContestType.ABC)).toBe(abcProvider); - expect(group.getProvider(ContestType.ABC, undefined)).toBe(abcProvider); + expect(group.getProvider(ContestType.ABS)).toBe(absProvider); + expect(group.getProvider(ContestType.ABS, undefined)).toBe(absProvider); }); test('expects getProvider with non-existent section to return undefined', () => { @@ -2638,16 +2577,16 @@ describe('ContestTableProviderGroup', () => { }); describe('prepareContestProviderPresets', () => { - test('expects to create ABCLatest20Rounds preset correctly', () => { - const group = prepareContestProviderPresets().ABCLatest20Rounds(); + test('expects to create ABS preset correctly', () => { + const group = prepareContestProviderPresets().ABS(); - expect(group.getGroupName()).toBe('ABC Latest 20 Rounds'); + expect(group.getGroupName()).toBe('AtCoder Beginners Selection'); expect(group.getMetadata()).toEqual({ - buttonLabel: 'ABC 最新 20 回', - ariaLabel: 'Filter ABC latest 20 rounds', + buttonLabel: 'ABS', + ariaLabel: 'Filter AtCoder Beginners Selection', }); expect(group.getSize()).toBe(1); - expect(group.getProvider(ContestType.ABC)).toBeInstanceOf(ABCLatest20RoundsProvider); + expect(group.getProvider(ContestType.ABS)).toBeInstanceOf(ABSProvider); }); test('expects to create ABC319Onwards preset correctly', () => { @@ -2723,7 +2662,7 @@ describe('prepareContestProviderPresets', () => { test('expects to verify all presets are functions', () => { const presets = prepareContestProviderPresets(); - expect(typeof presets.ABCLatest20Rounds).toBe('function'); + expect(typeof presets.ABS).toBe('function'); expect(typeof presets.ABC319Onwards).toBe('function'); expect(typeof presets.ABC212ToABC318).toBe('function'); expect(typeof presets.Typical90).toBe('function'); @@ -2732,11 +2671,11 @@ describe('prepareContestProviderPresets', () => { test('expects each preset to create independent instances', () => { const presets = prepareContestProviderPresets(); - const group1 = presets.ABCLatest20Rounds(); - const group2 = presets.ABCLatest20Rounds(); + const group1 = presets.ABS(); + const group2 = presets.ABS(); expect(group1).not.toBe(group2); expect(group1.getGroupName()).toBe(group2.getGroupName()); - expect(group1.getProvider(ContestType.ABC)).not.toBe(group2.getProvider(ContestType.ABC)); + expect(group1.getProvider(ContestType.ABS)).not.toBe(group2.getProvider(ContestType.ABS)); }); }); From fc48d8a90443688c1829309bdafa31dd626f21cc Mon Sep 17 00:00:00 2001 From: Kato Hiroki Date: Wed, 31 Dec 2025 12:59:43 +0000 Subject: [PATCH 2/2] chore(docs): Remove old descriptions (#3000) --- .../add_and_refactoring_tests_for_contest_table_provider/plan.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/dev-notes/2025-11-01/add_and_refactoring_tests_for_contest_table_provider/plan.md b/docs/dev-notes/2025-11-01/add_and_refactoring_tests_for_contest_table_provider/plan.md index 608337066..356cc5a19 100644 --- a/docs/dev-notes/2025-11-01/add_and_refactoring_tests_for_contest_table_provider/plan.md +++ b/docs/dev-notes/2025-11-01/add_and_refactoring_tests_for_contest_table_provider/plan.md @@ -513,7 +513,6 @@ describe.each([ **ターゲット**: -- `ABCLatest20RoundsProvider` テストの `generateTable` 検証を追加 - `ABC319Onwards` と `ABC212to318` のテストもTypical90 同等レベルに **期間**: 2-3 日