@@ -432,4 +432,81 @@ describe('comment commands', () => {
432432 ] ) ;
433433 expect ( result [ 0 ] ?. moves [ 0 ] ?. [ 1 ] ?. comment ) . toBeUndefined ( ) ;
434434 } ) ;
435+
436+ // Group 1: Blue color code
437+ it ( 'parses [%csl] with all six color codes' , ( ) => {
438+ const pgn = '1. e4 { [%csl Ye4,Rd4,Ga1,Bh1,Oe1,Cb1] } e5 1-0' ;
439+ const result = parse ( pgn ) ;
440+ expect ( result [ 0 ] ?. moves [ 0 ] ?. [ 1 ] ?. squares ) . toEqual ( [
441+ { color : 'Y' , square : 'e4' } ,
442+ { color : 'R' , square : 'd4' } ,
443+ { color : 'G' , square : 'a1' } ,
444+ { color : 'B' , square : 'h1' } ,
445+ { color : 'O' , square : 'e1' } ,
446+ { color : 'C' , square : 'b1' } ,
447+ ] ) ;
448+ } ) ;
449+
450+ it ( 'parses [%cal] with all six color codes' , ( ) => {
451+ const pgn = '1. e4 { [%cal Ye4e8,Rd4a4,Ga1h8,Bh1c7,Oc1c7,Ch1h7] } e5 1-0' ;
452+ const result = parse ( pgn ) ;
453+ expect ( result [ 0 ] ?. moves [ 0 ] ?. [ 1 ] ?. arrows ) . toEqual ( [
454+ { color : 'Y' , from : 'e4' , to : 'e8' } ,
455+ { color : 'R' , from : 'd4' , to : 'a4' } ,
456+ { color : 'G' , from : 'a1' , to : 'h8' } ,
457+ { color : 'B' , from : 'h1' , to : 'c7' } ,
458+ { color : 'O' , from : 'c1' , to : 'c7' } ,
459+ { color : 'C' , from : 'h1' , to : 'h7' } ,
460+ ] ) ;
461+ } ) ;
462+
463+ // Group 2: Both cal and csl empty simultaneously
464+ it ( 'strips both empty [%csl ] and [%cal ] with no output' , ( ) => {
465+ const pgn = '1. e4 { [%csl ][%cal ] } e5 1-0' ;
466+ const result = parse ( pgn ) ;
467+ expect ( result [ 0 ] ?. moves [ 0 ] ?. [ 1 ] ?. squares ) . toBeUndefined ( ) ;
468+ expect ( result [ 0 ] ?. moves [ 0 ] ?. [ 1 ] ?. arrows ) . toBeUndefined ( ) ;
469+ expect ( result [ 0 ] ?. moves [ 0 ] ?. [ 1 ] ?. comment ) . toBeUndefined ( ) ;
470+ } ) ;
471+
472+ // Group 3: Extra whitespace inside command brackets
473+ it ( 'handles extra whitespace inside [%csl] and [%cal] brackets' , ( ) => {
474+ const pgn = '1. e4 { [%csl Rd4 ] [%cal Ye4e8 , Gd1d3] } e5 1-0' ;
475+ const result = parse ( pgn ) ;
476+ expect ( result [ 0 ] ?. moves [ 0 ] ?. [ 1 ] ?. squares ) . toEqual ( [
477+ { color : 'R' , square : 'd4' } ,
478+ ] ) ;
479+ expect ( result [ 0 ] ?. moves [ 0 ] ?. [ 1 ] ?. arrows ) . toEqual ( [
480+ { color : 'Y' , from : 'e4' , to : 'e8' } ,
481+ { color : 'G' , from : 'd1' , to : 'd3' } ,
482+ ] ) ;
483+ expect ( result [ 0 ] ?. moves [ 0 ] ?. [ 1 ] ?. comment ) . toBeUndefined ( ) ;
484+ } ) ;
485+
486+ // Group 4: Text immediately after ] with no space
487+ it ( 'parses command followed immediately by text without leading space' , ( ) => {
488+ const pgn = '1. e4 { [%cal Ye4e8] comment } e5 1-0' ;
489+ const result = parse ( pgn ) ;
490+ expect ( result [ 0 ] ?. moves [ 0 ] ?. [ 1 ] ?. arrows ) . toEqual ( [
491+ { color : 'Y' , from : 'e4' , to : 'e8' } ,
492+ ] ) ;
493+ expect ( result [ 0 ] ?. moves [ 0 ] ?. [ 1 ] ?. comment ) . toBe ( 'comment' ) ;
494+ } ) ;
495+
496+ // Group 5: Sub-second clock with 1 fractional digit
497+ it ( 'parses [%clk] with 1-digit fractional seconds' , ( ) => {
498+ const pgn = '1. e4 { [%clk 0:00:59.8] } e5 1-0' ;
499+ const result = parse ( pgn ) ;
500+ expect ( result [ 0 ] ?. moves [ 0 ] ?. [ 1 ] ?. clock ) . toBe ( 59.8 ) ;
501+ } ) ;
502+
503+ // Group 6: Unknown time commands left in comment
504+ it ( 'leaves [%egt], [%emt], [%mct] in comment as unknown commands' , ( ) => {
505+ const pgn = '1. e4 { [%clk 0:10:10] [%egt 0:10:10] [%emt 0:08:08] } e5 1-0' ;
506+ const result = parse ( pgn ) ;
507+ expect ( result [ 0 ] ?. moves [ 0 ] ?. [ 1 ] ?. clock ) . toBe ( 610 ) ;
508+ expect ( result [ 0 ] ?. moves [ 0 ] ?. [ 1 ] ?. comment ) . toBe (
509+ '[%egt 0:10:10] [%emt 0:08:08]' ,
510+ ) ;
511+ } ) ;
435512} ) ;
0 commit comments