@@ -548,4 +548,140 @@ describe("assessIntegrateRepo", () => {
548548 expect ( a . retarget ?. alreadyOnTarget ) . toBe ( 3 ) ;
549549 expect ( a . retarget ?. reason ) . toBe ( "branch-merged" ) ;
550550 } ) ;
551+
552+ // ── fully-merged (no new work) ──
553+
554+ test ( "fully-merged in rebase mode with behind > 0 returns will-operate with retarget (replayCount=0)" , async ( ) => {
555+ const status = makeRepo ( {
556+ base : {
557+ remote : "origin" ,
558+ ref : "main" ,
559+ configuredRef : null ,
560+ resolvedVia : "remote" ,
561+ ahead : 5 ,
562+ behind : 3 ,
563+ merge : { kind : "merge" } ,
564+ baseMergedIntoDefault : null ,
565+ } ,
566+ } ) ;
567+ const a = await assessIntegrateRepo ( status , DIR , "feature" , [ ] , defaultOptions ( { mode : "rebase" } ) , mockDeps ( ) ) ;
568+ expect ( a . outcome ) . toBe ( "will-operate" ) ;
569+ expect ( a . retarget ?. replayCount ) . toBe ( 0 ) ;
570+ expect ( a . retarget ?. alreadyOnTarget ) . toBe ( 5 ) ;
571+ expect ( a . retarget ?. reason ) . toBe ( "branch-merged" ) ;
572+ expect ( a . behind ) . toBe ( 3 ) ;
573+ expect ( a . ahead ) . toBe ( 0 ) ;
574+ } ) ;
575+
576+ test ( "fully-merged squash in rebase mode with behind > 0 returns will-operate with retarget" , async ( ) => {
577+ const status = makeRepo ( {
578+ base : {
579+ remote : "origin" ,
580+ ref : "main" ,
581+ configuredRef : null ,
582+ resolvedVia : "remote" ,
583+ ahead : 3 ,
584+ behind : 2 ,
585+ merge : { kind : "squash" } ,
586+ baseMergedIntoDefault : null ,
587+ } ,
588+ } ) ;
589+ const a = await assessIntegrateRepo ( status , DIR , "feature" , [ ] , defaultOptions ( { mode : "rebase" } ) , mockDeps ( ) ) ;
590+ expect ( a . outcome ) . toBe ( "will-operate" ) ;
591+ expect ( a . retarget ?. replayCount ) . toBe ( 0 ) ;
592+ expect ( a . retarget ?. alreadyOnTarget ) . toBe ( 3 ) ;
593+ expect ( a . retarget ?. reason ) . toBe ( "branch-merged" ) ;
594+ } ) ;
595+
596+ test ( "fully-merged in merge mode with behind > 0 returns will-operate (standard merge)" , async ( ) => {
597+ const status = makeRepo ( {
598+ base : {
599+ remote : "origin" ,
600+ ref : "main" ,
601+ configuredRef : null ,
602+ resolvedVia : "remote" ,
603+ ahead : 5 ,
604+ behind : 3 ,
605+ merge : { kind : "merge" } ,
606+ baseMergedIntoDefault : null ,
607+ } ,
608+ } ) ;
609+ const a = await assessIntegrateRepo ( status , DIR , "feature" , [ ] , defaultOptions ( { mode : "merge" } ) , mockDeps ( ) ) ;
610+ expect ( a . outcome ) . toBe ( "will-operate" ) ;
611+ expect ( a . behind ) . toBe ( 3 ) ;
612+ expect ( a . ahead ) . toBe ( 5 ) ;
613+ expect ( a . retarget ) . toBeUndefined ( ) ;
614+ } ) ;
615+
616+ test ( "fully-merged with behind=0 and ahead=0 returns up-to-date" , async ( ) => {
617+ const status = makeRepo ( {
618+ base : {
619+ remote : "origin" ,
620+ ref : "main" ,
621+ configuredRef : null ,
622+ resolvedVia : "remote" ,
623+ ahead : 0 ,
624+ behind : 0 ,
625+ merge : { kind : "merge" } ,
626+ baseMergedIntoDefault : null ,
627+ } ,
628+ } ) ;
629+ const a = await assessIntegrateRepo ( status , DIR , "feature" , [ ] , defaultOptions ( { mode : "rebase" } ) , mockDeps ( ) ) ;
630+ expect ( a . outcome ) . toBe ( "up-to-date" ) ;
631+ } ) ;
632+
633+ test ( "fully-merged in merge mode with behind=0 returns up-to-date" , async ( ) => {
634+ const status = makeRepo ( {
635+ base : {
636+ remote : "origin" ,
637+ ref : "main" ,
638+ configuredRef : null ,
639+ resolvedVia : "remote" ,
640+ ahead : 3 ,
641+ behind : 0 ,
642+ merge : { kind : "squash" } ,
643+ baseMergedIntoDefault : null ,
644+ } ,
645+ } ) ;
646+ const a = await assessIntegrateRepo ( status , DIR , "feature" , [ ] , defaultOptions ( { mode : "merge" } ) , mockDeps ( ) ) ;
647+ expect ( a . outcome ) . toBe ( "up-to-date" ) ;
648+ } ) ;
649+
650+ test ( "fully-merged with dirty worktree and no autostash returns skip (dirty)" , async ( ) => {
651+ const status = makeRepo ( {
652+ base : {
653+ remote : "origin" ,
654+ ref : "main" ,
655+ configuredRef : null ,
656+ resolvedVia : "remote" ,
657+ ahead : 3 ,
658+ behind : 2 ,
659+ merge : { kind : "merge" } ,
660+ baseMergedIntoDefault : null ,
661+ } ,
662+ local : { staged : 1 , modified : 0 , untracked : 0 , conflicts : 0 } ,
663+ } ) ;
664+ const a = await assessIntegrateRepo ( status , DIR , "feature" , [ ] , defaultOptions ( { autostash : false } ) , mockDeps ( ) ) ;
665+ expect ( a . outcome ) . toBe ( "skip" ) ;
666+ expect ( a . skipFlag ) . toBe ( "dirty" ) ;
667+ } ) ;
668+
669+ test ( "fully-merged with dirty worktree and autostash returns will-operate with needsStash" , async ( ) => {
670+ const status = makeRepo ( {
671+ base : {
672+ remote : "origin" ,
673+ ref : "main" ,
674+ configuredRef : null ,
675+ resolvedVia : "remote" ,
676+ ahead : 3 ,
677+ behind : 2 ,
678+ merge : { kind : "merge" } ,
679+ baseMergedIntoDefault : null ,
680+ } ,
681+ local : { staged : 1 , modified : 0 , untracked : 0 , conflicts : 0 } ,
682+ } ) ;
683+ const a = await assessIntegrateRepo ( status , DIR , "feature" , [ ] , defaultOptions ( { autostash : true } ) , mockDeps ( ) ) ;
684+ expect ( a . outcome ) . toBe ( "will-operate" ) ;
685+ expect ( a . needsStash ) . toBe ( true ) ;
686+ } ) ;
551687} ) ;
0 commit comments