@@ -12,6 +12,7 @@ import {
1212 JOIFirstQualRoundProvider ,
1313 Typical90Provider ,
1414 TessokuBookProvider ,
15+ MathAndAlgorithmProvider ,
1516 ContestTableProviderGroup ,
1617 prepareContestProviderPresets ,
1718} from '$lib/utils/contest_table_provider' ;
@@ -32,6 +33,8 @@ vi.mock('$lib/utils/contest', () => ({
3233 return ContestType . TYPICAL90 ;
3334 } else if ( contestId === 'tessoku-book' ) {
3435 return ContestType . TESSOKU_BOOK ;
36+ } else if ( contestId === 'math-and-algorithm' ) {
37+ return ContestType . MATH_AND_ALGORITHM ;
3538 }
3639
3740 return ContestType . OTHERS ;
@@ -552,6 +555,157 @@ describe('ContestTableProviderBase and implementations', () => {
552555 } ) ;
553556 } ) ;
554557
558+ describe ( 'MathAndAlgorithm provider' , ( ) => {
559+ test ( 'expects to filter tasks to include only math-and-algorithm contest' , ( ) => {
560+ const provider = new MathAndAlgorithmProvider ( ContestType . MATH_AND_ALGORITHM ) ;
561+ const mixedTasks = [
562+ { contest_id : 'abc123' , task_id : 'abc123_a' , task_table_index : 'A' } ,
563+ {
564+ contest_id : 'math-and-algorithm' ,
565+ task_id : 'math_and_algorithm_a' ,
566+ task_table_index : '001' ,
567+ } ,
568+ { contest_id : 'math-and-algorithm' , task_id : 'typical90_o' , task_table_index : '101' } ,
569+ { contest_id : 'math-and-algorithm' , task_id : 'arc117_c' , task_table_index : '102' } ,
570+ ] ;
571+ const filtered = provider . filter ( mixedTasks as TaskResults ) ;
572+
573+ expect ( filtered ?. every ( ( task ) => task . contest_id === 'math-and-algorithm' ) ) . toBe ( true ) ;
574+ expect ( filtered ) . not . toContainEqual ( expect . objectContaining ( { contest_id : 'abc123' } ) ) ;
575+ } ) ;
576+
577+ test ( 'expects to get correct metadata' , ( ) => {
578+ const provider = new MathAndAlgorithmProvider ( ContestType . MATH_AND_ALGORITHM ) ;
579+ const metadata = provider . getMetadata ( ) ;
580+
581+ expect ( metadata . title ) . toBe ( 'アルゴリズムと数学' ) ;
582+ expect ( metadata . abbreviationName ) . toBe ( 'math-and-algorithm' ) ;
583+ } ) ;
584+
585+ test ( 'expects to get correct display configuration' , ( ) => {
586+ const provider = new MathAndAlgorithmProvider ( ContestType . MATH_AND_ALGORITHM ) ;
587+ const displayConfig = provider . getDisplayConfig ( ) ;
588+
589+ expect ( displayConfig . isShownHeader ) . toBe ( false ) ;
590+ expect ( displayConfig . isShownRoundLabel ) . toBe ( false ) ;
591+ expect ( displayConfig . roundLabelWidth ) . toBe ( '' ) ;
592+ expect ( displayConfig . tableBodyCellsWidth ) . toBe (
593+ 'w-1/2 xs:w-1/3 sm:w-1/4 md:w-1/5 lg:w-1/6 2xl:w-1/7 px-1 py-2' ,
594+ ) ;
595+ expect ( displayConfig . isShownTaskIndex ) . toBe ( true ) ;
596+ } ) ;
597+
598+ test ( 'expects to format contest round label correctly' , ( ) => {
599+ const provider = new MathAndAlgorithmProvider ( ContestType . MATH_AND_ALGORITHM ) ;
600+ const label = provider . getContestRoundLabel ( 'math-and-algorithm' ) ;
601+
602+ expect ( label ) . toBe ( '' ) ;
603+ } ) ;
604+
605+ test ( 'expects to generate correct table structure with mixed problem sources' , ( ) => {
606+ const provider = new MathAndAlgorithmProvider ( ContestType . MATH_AND_ALGORITHM ) ;
607+ const tasks = [
608+ {
609+ contest_id : 'math-and-algorithm' ,
610+ task_id : 'math_and_algorithm_a' ,
611+ task_table_index : '001' ,
612+ } ,
613+ { contest_id : 'math-and-algorithm' , task_id : 'dp_a' , task_table_index : '028' } ,
614+ { contest_id : 'math-and-algorithm' , task_id : 'abc168_c' , task_table_index : '036' } ,
615+ { contest_id : 'math-and-algorithm' , task_id : 'arc117_c' , task_table_index : '102' } ,
616+ ] ;
617+ const table = provider . generateTable ( tasks as TaskResults ) ;
618+
619+ expect ( table ) . toHaveProperty ( 'math-and-algorithm' ) ;
620+ expect ( table [ 'math-and-algorithm' ] ) . toHaveProperty ( '028' ) ;
621+ expect ( table [ 'math-and-algorithm' ] [ '028' ] ) . toEqual (
622+ expect . objectContaining ( { task_id : 'dp_a' } ) ,
623+ ) ;
624+ } ) ;
625+
626+ test ( 'expects to get contest round IDs correctly' , ( ) => {
627+ const provider = new MathAndAlgorithmProvider ( ContestType . MATH_AND_ALGORITHM ) ;
628+ const tasks = [
629+ { contest_id : 'math-and-algorithm' , task_id : 'arc117_c' , task_table_index : '102' } ,
630+ { contest_id : 'math-and-algorithm' , task_id : 'typical90_o' , task_table_index : '101' } ,
631+ ] ;
632+ const roundIds = provider . getContestRoundIds ( tasks as TaskResults ) ;
633+
634+ expect ( roundIds ) . toEqual ( [ 'math-and-algorithm' ] ) ;
635+ } ) ;
636+
637+ test ( 'expects to get header IDs for tasks correctly in ascending order' , ( ) => {
638+ const provider = new MathAndAlgorithmProvider ( ContestType . MATH_AND_ALGORITHM ) ;
639+ const tasks = [
640+ {
641+ contest_id : 'math-and-algorithm' ,
642+ task_id : 'math_and_algorithm_a' ,
643+ task_table_index : '001' ,
644+ } ,
645+ { contest_id : 'math-and-algorithm' , task_id : 'arc117_c' , task_table_index : '102' } ,
646+ { contest_id : 'math-and-algorithm' , task_id : 'dp_a' , task_table_index : '028' } ,
647+ { contest_id : 'math-and-algorithm' , task_id : 'abc168_c' , task_table_index : '036' } ,
648+ ] ;
649+ const headerIds = provider . getHeaderIdsForTask ( tasks as TaskResults ) ;
650+
651+ expect ( headerIds ) . toEqual ( [ '001' , '028' , '036' , '102' ] ) ;
652+ } ) ;
653+
654+ test ( 'expects to maintain proper sort order with numeric indices' , ( ) => {
655+ const provider = new MathAndAlgorithmProvider ( ContestType . MATH_AND_ALGORITHM ) ;
656+ const tasks = [
657+ { contest_id : 'math-and-algorithm' , task_id : 'typical90_bz' , task_table_index : '045' } ,
658+ { contest_id : 'math-and-algorithm' , task_id : 'abc168_c' , task_table_index : '036' } ,
659+ ] ;
660+ const headerIds = provider . getHeaderIdsForTask ( tasks as TaskResults ) ;
661+
662+ expect ( headerIds ) . toEqual ( [ '036' , '045' ] ) ;
663+ } ) ;
664+
665+ test ( 'expects to handle section boundaries correctly (001-104)' , ( ) => {
666+ const provider = new MathAndAlgorithmProvider ( ContestType . MATH_AND_ALGORITHM ) ;
667+ const tasks = [
668+ {
669+ contest_id : 'math-and-algorithm' ,
670+ task_id : 'math_and_algorithm_a' ,
671+ task_table_index : '001' ,
672+ } ,
673+ {
674+ contest_id : 'math-and-algorithm' ,
675+ task_id : 'math_and_algorithm_bx' ,
676+ task_table_index : '104' ,
677+ } ,
678+ ] ;
679+ const headerIds = provider . getHeaderIdsForTask ( tasks as TaskResults ) ;
680+
681+ expect ( headerIds ) . toEqual ( [ '001' , '104' ] ) ;
682+ } ) ;
683+
684+ test ( 'expects to handle empty task results' , ( ) => {
685+ const provider = new MathAndAlgorithmProvider ( ContestType . MATH_AND_ALGORITHM ) ;
686+ const filtered = provider . filter ( [ ] as TaskResults ) ;
687+
688+ expect ( filtered ) . toEqual ( [ ] as TaskResults ) ;
689+ } ) ;
690+
691+ test ( 'expects to handle task results with different contest types' , ( ) => {
692+ const provider = new MathAndAlgorithmProvider ( ContestType . MATH_AND_ALGORITHM ) ;
693+ const mixedTasks = [
694+ {
695+ contest_id : 'math-and-algorithm' ,
696+ task_id : 'math_and_algorithm_a' ,
697+ task_table_index : '001' ,
698+ } ,
699+ { contest_id : 'math-and-algorithm' , task_id : 'arc117_c' , task_table_index : '102' } ,
700+ { contest_id : 'typical90' , task_id : 'typical90_a' , task_table_index : 'A' } ,
701+ ] ;
702+ const filtered = provider . filter ( mixedTasks as TaskResults ) ;
703+
704+ expect ( filtered ) . toHaveLength ( 2 ) ;
705+ expect ( filtered ?. every ( ( task ) => task . contest_id === 'math-and-algorithm' ) ) . toBe ( true ) ;
706+ } ) ;
707+ } ) ;
708+
555709 describe . each ( [
556710 {
557711 providerClass : EDPCProvider ,
0 commit comments