@@ -771,3 +771,145 @@ x-sync: sync extension
771771 require .NoError (t , err )
772772 require .Equal (t , expectedYAML , string (actualYAML ))
773773}
774+
775+ func TestSync_ExtensionModification_Success (t * testing.T ) {
776+ // Create a model with initial extensions
777+ highModel := tests.TestPrimitiveHighModel {
778+ StringField : "model with extensions" ,
779+ BoolField : true ,
780+ IntField : 42 ,
781+ Float64Field : 3.14 ,
782+ }
783+
784+ // Initialize extensions
785+ highModel .Extensions = & extensions.Extensions {}
786+ highModel .Extensions .Init ()
787+ highModel .Extensions .Set ("x-version" , testutils .CreateStringYamlNode ("1.0" , 1 , 1 ))
788+ highModel .Extensions .Set ("x-author" , testutils .CreateStringYamlNode ("developer" , 1 , 1 ))
789+
790+ // Perform initial sync
791+ resultNode , err := marshaller .SyncValue (context .Background (), & highModel , highModel .GetCore (), highModel .GetRootNode (), false )
792+ require .NoError (t , err )
793+ require .NotNil (t , resultNode )
794+
795+ // Verify initial extensions were synced
796+ coreModel := highModel .GetCore ()
797+ require .NotNil (t , coreModel .Extensions )
798+
799+ versionExt , ok := coreModel .Extensions .Get ("x-version" )
800+ require .True (t , ok )
801+ require .Equal (t , "1.0" , versionExt .Value .Value )
802+
803+ authorExt , ok := coreModel .Extensions .Get ("x-author" )
804+ require .True (t , ok )
805+ require .Equal (t , "developer" , authorExt .Value .Value )
806+
807+ // Modify extensions: update existing, add new, remove one
808+ highModel .Extensions .Set ("x-version" , testutils .CreateStringYamlNode ("2.0" , 1 , 1 )) // Update
809+ highModel .Extensions .Set ("x-status" , testutils .CreateStringYamlNode ("active" , 1 , 1 )) // Add new
810+ highModel .Extensions .Delete ("x-author" ) // Remove
811+
812+ // Sync the changes
813+ resultNode , err = marshaller .SyncValue (context .Background (), & highModel , highModel .GetCore (), highModel .GetRootNode (), false )
814+ require .NoError (t , err )
815+ require .NotNil (t , resultNode )
816+
817+ // Verify extensions were updated correctly
818+ updatedVersionExt , ok := coreModel .Extensions .Get ("x-version" )
819+ require .True (t , ok )
820+ require .Equal (t , "2.0" , updatedVersionExt .Value .Value )
821+
822+ statusExt , ok := coreModel .Extensions .Get ("x-status" )
823+ require .True (t , ok )
824+ require .Equal (t , "active" , statusExt .Value .Value )
825+
826+ // Verify removed extension is gone
827+ _ , ok = coreModel .Extensions .Get ("x-author" )
828+ require .False (t , ok )
829+
830+ // Verify the core model's RootNode contains the correct YAML
831+ expectedYAML := `stringField: model with extensions
832+ boolField: true
833+ intField: 42
834+ float64Field: 3.14
835+ x-version: "2.0"
836+ x-status: active
837+ `
838+
839+ actualYAML , err := yaml .Marshal (coreModel .GetRootNode ())
840+ require .NoError (t , err )
841+ require .Equal (t , expectedYAML , string (actualYAML ))
842+ }
843+
844+ func TestSync_ExtensionReplacement_Success (t * testing.T ) {
845+ // Create a model with extensions that will be completely replaced
846+ highModel := tests.TestPrimitiveHighModel {
847+ StringField : "model for replacement" ,
848+ BoolField : false ,
849+ IntField : 100 ,
850+ Float64Field : 1.5 ,
851+ }
852+
853+ // Initialize with original extensions
854+ highModel .Extensions = & extensions.Extensions {}
855+ highModel .Extensions .Init ()
856+ highModel .Extensions .Set ("x-original-id" , testutils .CreateStringYamlNode ("orig-123" , 1 , 1 ))
857+ highModel .Extensions .Set ("x-legacy-flag" , testutils .CreateStringYamlNode ("true" , 1 , 1 ))
858+ highModel .Extensions .Set ("x-deprecated" , testutils .CreateStringYamlNode ("soon" , 1 , 1 ))
859+
860+ // Perform initial sync
861+ resultNode , err := marshaller .SyncValue (context .Background (), & highModel , highModel .GetCore (), highModel .GetRootNode (), false )
862+ require .NoError (t , err )
863+ require .NotNil (t , resultNode )
864+
865+ // Verify initial state
866+ coreModel := highModel .GetCore ()
867+ require .NotNil (t , coreModel .Extensions )
868+ require .Equal (t , 3 , coreModel .Extensions .Len ())
869+
870+ // Replace with completely new extensions (simulating workflow replacement scenario)
871+ newExtensions := & extensions.Extensions {}
872+ newExtensions .Init ()
873+ newExtensions .Set ("x-new-id" , testutils .CreateStringYamlNode ("new-456" , 1 , 1 ))
874+ newExtensions .Set ("x-modern-flag" , testutils .CreateStringYamlNode ("enabled" , 1 , 1 ))
875+
876+ // Replace the extensions entirely
877+ highModel .Extensions = newExtensions
878+
879+ // Sync the replacement
880+ resultNode , err = marshaller .SyncValue (context .Background (), & highModel , highModel .GetCore (), highModel .GetRootNode (), false )
881+ require .NoError (t , err )
882+ require .NotNil (t , resultNode )
883+
884+ // Verify all old extensions are gone and new ones are present
885+ require .Equal (t , 2 , coreModel .Extensions .Len ())
886+
887+ newIdExt , ok := coreModel .Extensions .Get ("x-new-id" )
888+ require .True (t , ok )
889+ require .Equal (t , "new-456" , newIdExt .Value .Value )
890+
891+ modernFlagExt , ok := coreModel .Extensions .Get ("x-modern-flag" )
892+ require .True (t , ok )
893+ require .Equal (t , "enabled" , modernFlagExt .Value .Value )
894+
895+ // Verify old extensions are completely removed
896+ _ , ok = coreModel .Extensions .Get ("x-original-id" )
897+ require .False (t , ok )
898+ _ , ok = coreModel .Extensions .Get ("x-legacy-flag" )
899+ require .False (t , ok )
900+ _ , ok = coreModel .Extensions .Get ("x-deprecated" )
901+ require .False (t , ok )
902+
903+ // Verify the core model's RootNode contains only new extensions
904+ expectedYAML := `stringField: model for replacement
905+ boolField: false
906+ intField: 100
907+ float64Field: 1.5
908+ x-new-id: new-456
909+ x-modern-flag: enabled
910+ `
911+
912+ actualYAML , err := yaml .Marshal (coreModel .GetRootNode ())
913+ require .NoError (t , err )
914+ require .Equal (t , expectedYAML , string (actualYAML ))
915+ }
0 commit comments