@@ -654,6 +654,61 @@ describe("Edit Command History", () => {
654654 } ) ;
655655 } ) ;
656656
657+ describe ( "canUndo / canRedo getters" , ( ) => {
658+ it ( "are both false on a freshly loaded edit (load is not a command)" , ( ) => {
659+ expect ( getCommandState ( edit ) . index ) . toBe ( - 1 ) ;
660+ expect ( edit . canUndo ) . toBe ( false ) ;
661+ expect ( edit . canRedo ) . toBe ( false ) ;
662+ } ) ;
663+
664+ it ( "canUndo turns true after a command; canRedo stays false" , async ( ) => {
665+ await edit . executeEditCommand ( new TestCommand ( ) ) ;
666+ expect ( edit . canUndo ) . toBe ( true ) ;
667+ expect ( edit . canRedo ) . toBe ( false ) ;
668+ } ) ;
669+
670+ it ( "undo turns canRedo on and, back at the start, canUndo off" , async ( ) => {
671+ await edit . executeEditCommand ( new TestCommand ( ) ) ;
672+ await edit . undo ( ) ;
673+ expect ( edit . canUndo ) . toBe ( false ) ;
674+ expect ( edit . canRedo ) . toBe ( true ) ;
675+ } ) ;
676+
677+ it ( "redo turns canUndo back on and, at the end, canRedo off" , async ( ) => {
678+ await edit . executeEditCommand ( new TestCommand ( ) ) ;
679+ await edit . undo ( ) ;
680+ await edit . redo ( ) ;
681+ expect ( edit . canUndo ) . toBe ( true ) ;
682+ expect ( edit . canRedo ) . toBe ( false ) ;
683+ } ) ;
684+
685+ it ( "both are true mid-stack" , async ( ) => {
686+ await edit . executeEditCommand ( new TestCommand ( ) ) ;
687+ await edit . executeEditCommand ( new TestCommand ( ) ) ;
688+ await edit . undo ( ) ;
689+ expect ( edit . canUndo ) . toBe ( true ) ;
690+ expect ( edit . canRedo ) . toBe ( true ) ;
691+ } ) ;
692+
693+ it ( "a new command after undo truncates redo (canRedo false)" , async ( ) => {
694+ await edit . executeEditCommand ( new TestCommand ( ) ) ;
695+ await edit . executeEditCommand ( new TestCommand ( ) ) ;
696+ await edit . undo ( ) ;
697+ await edit . executeEditCommand ( new TestCommand ( ) ) ;
698+ expect ( edit . canUndo ) . toBe ( true ) ;
699+ expect ( edit . canRedo ) . toBe ( false ) ;
700+ } ) ;
701+
702+ it ( "track the underlying commandIndex bounds" , async ( ) => {
703+ await edit . executeEditCommand ( new TestCommand ( ) ) ;
704+ await edit . executeEditCommand ( new TestCommand ( ) ) ;
705+ await edit . undo ( ) ;
706+ const { history, index } = getCommandState ( edit ) ;
707+ expect ( edit . canUndo ) . toBe ( index >= 0 ) ;
708+ expect ( edit . canRedo ) . toBe ( index < history . length - 1 ) ;
709+ } ) ;
710+ } ) ;
711+
657712 describe ( "state restoration" , ( ) => {
658713 it ( "undo restores previous state via command.undo()" , async ( ) => {
659714 // Use a command that tracks state changes
0 commit comments