@@ -442,6 +442,74 @@ void TestArchivePatchCoreSupportsCustomBundlePatchEntry() {
442442 ExpectEq (plan.merge_source_subdir , " " , " custom bundle patch merge subdir mismatch" );
443443}
444444
445+ void TestArchivePatchCoreHarmonyBundlePatchFromPackage () {
446+ PatchManifest manifest;
447+ manifest.copies .push_back (CopyOperation{" assets/a.png" , " assets/b.png" });
448+
449+ pushy::archive_patch::ArchivePatchPlan plan;
450+ Status status = pushy::archive_patch::BuildArchivePatchPlan (
451+ pushy::archive_patch::ArchivePatchType::kPatchFromPackage ,
452+ manifest,
453+ {" __diff.json" , " bundle.harmony.js.patch" , " assets/new.png" },
454+ &plan,
455+ " bundle.harmony.js.patch" );
456+ Expect (status.ok , status.message );
457+ Expect (plan.enable_merge , " harmony package plan should enable merge" );
458+ ExpectEq (plan.merge_source_subdir , " assets" , " harmony package merge subdir should be assets" );
459+
460+ // ppk variant uses empty merge subdir
461+ pushy::archive_patch::ArchivePatchPlan ppk_plan;
462+ status = pushy::archive_patch::BuildArchivePatchPlan (
463+ pushy::archive_patch::ArchivePatchType::kPatchFromPpk ,
464+ manifest,
465+ {" __diff.json" , " bundle.harmony.js.patch" , " assets/new.png" },
466+ &ppk_plan,
467+ " bundle.harmony.js.patch" );
468+ Expect (status.ok , status.message );
469+ Expect (ppk_plan.enable_merge , " harmony ppk plan should enable merge" );
470+ ExpectEq (ppk_plan.merge_source_subdir , " " , " harmony ppk merge subdir should be empty" );
471+ }
472+
473+ void TestStateCoreRollbackToEmptyVersion () {
474+ State state;
475+ state.current_version = " current" ;
476+ state.last_version = " " ;
477+ state.first_time = false ;
478+ state.first_time_ok = true ;
479+
480+ State rolled = pushy::state::Rollback (state);
481+ Expect (rolled.current_version .empty (), " rollback with empty last should clear current" );
482+ Expect (rolled.last_version .empty (), " last_version should remain empty" );
483+ ExpectEq (rolled.rolled_back_version , " current" , " rolled_back_version should record original" );
484+ Expect (!rolled.first_time , " first_time should be false after rollback" );
485+ Expect (rolled.first_time_ok , " first_time_ok should be true after rollback" );
486+ }
487+
488+ void TestStateCoreResolveLaunchNoCurrentVersion () {
489+ State state;
490+ state.current_version = " " ;
491+ state.first_time = false ;
492+ state.first_time_ok = true ;
493+
494+ LaunchDecision decision = pushy::state::ResolveLaunchState (state, false , true );
495+ Expect (decision.load_version .empty (), " empty current should yield empty load_version" );
496+ Expect (!decision.did_rollback , " should not rollback when no current version" );
497+ Expect (!decision.consumed_first_time , " should not consume first_time when no current version" );
498+ }
499+
500+ void TestStateCoreSwitchToSameVersion () {
501+ State state;
502+ state.package_version = " 1.0.0" ;
503+ state.current_version = " same_hash" ;
504+ state.last_version = " old_hash" ;
505+
506+ State switched = pushy::state::SwitchVersion (state, " same_hash" );
507+ ExpectEq (switched.current_version , " same_hash" , " current should remain same_hash" );
508+ ExpectEq (switched.last_version , " old_hash" , " last_version should not change when switching to same" );
509+ Expect (switched.first_time , " first_time should be set even when switching to same" );
510+ Expect (!switched.first_time_ok , " first_time_ok should be false" );
511+ }
512+
445513} // namespace
446514
447515int main () {
@@ -457,6 +525,10 @@ int main() {
457525 {" ArchivePatchCoreBuildPlanAndCopyGroups" , TestArchivePatchCoreBuildPlanAndCopyGroups},
458526 {" ArchivePatchCoreRejectsMissingEntries" , TestArchivePatchCoreRejectsMissingEntries},
459527 {" ArchivePatchCoreSupportsCustomBundlePatchEntry" , TestArchivePatchCoreSupportsCustomBundlePatchEntry},
528+ {" ArchivePatchCoreHarmonyBundlePatchFromPackage" , TestArchivePatchCoreHarmonyBundlePatchFromPackage},
529+ {" StateCoreRollbackToEmptyVersion" , TestStateCoreRollbackToEmptyVersion},
530+ {" StateCoreResolveLaunchNoCurrentVersion" , TestStateCoreResolveLaunchNoCurrentVersion},
531+ {" StateCoreSwitchToSameVersion" , TestStateCoreSwitchToSameVersion},
460532 };
461533
462534 for (const auto & test : tests) {
0 commit comments