@@ -266,6 +266,200 @@ static Root SimulateLocationTransfer(Root original)
266266 }
267267 }
268268
269+ [ TestMethod ]
270+ public void ClonePreservesChildEditLevel ( )
271+ {
272+ // Arrange: Create a root with children and begin editing
273+ var root = CreateRoot ( ) ;
274+ var child = root . Children . AddNew ( ) ;
275+ child . Data = "original" ;
276+
277+ root . BeginEdit ( ) ;
278+
279+ // Make changes after BeginEdit
280+ child . Data = "modified" ;
281+
282+ // Verify edit levels before clone
283+ var rootEditLevel = ( ( Core . IUndoableObject ) root ) . EditLevel ;
284+ var childEditLevel = ( ( Core . IUndoableObject ) child ) . EditLevel ;
285+ var childListEditLevel = ( ( Core . IUndoableObject ) root . Children ) . EditLevel ;
286+
287+ Assert . AreEqual ( 1 , rootEditLevel , "Root EditLevel should be 1 before clone" ) ;
288+ Assert . AreEqual ( 1 , childEditLevel , "Child EditLevel should be 1 before clone" ) ;
289+ Assert . AreEqual ( 1 , childListEditLevel , "ChildList EditLevel should be 1 before clone" ) ;
290+
291+ // Act: Clone the object graph
292+ var clonedRoot = root . Clone ( ) ;
293+
294+ // Assert: Verify edit levels are preserved after clone
295+ var clonedRootEditLevel = ( ( Core . IUndoableObject ) clonedRoot ) . EditLevel ;
296+ var clonedChildEditLevel = ( ( Core . IUndoableObject ) clonedRoot . Children [ 0 ] ) . EditLevel ;
297+ var clonedChildListEditLevel = ( ( Core . IUndoableObject ) clonedRoot . Children ) . EditLevel ;
298+
299+ Assert . AreEqual ( 1 , clonedRootEditLevel , "Cloned Root EditLevel should be 1" ) ;
300+ Assert . AreEqual ( 1 , clonedChildEditLevel , "Cloned Child EditLevel should be 1" ) ;
301+ Assert . AreEqual ( 1 , clonedChildListEditLevel , "Cloned ChildList EditLevel should be 1" ) ;
302+
303+ // Verify the modified data is preserved
304+ Assert . AreEqual ( "modified" , clonedRoot . Children [ 0 ] . Data , "Modified data should be preserved in clone" ) ;
305+ }
306+
307+ [ TestMethod ]
308+ public void ClonePreservesUndoStateForCancelEdit ( )
309+ {
310+ // Arrange: Create a root with children and begin editing
311+ var root = CreateRoot ( ) ;
312+ var child = root . Children . AddNew ( ) ;
313+ child . Data = "original" ;
314+
315+ root . BeginEdit ( ) ;
316+
317+ // Make changes after BeginEdit
318+ child . Data = "modified" ;
319+
320+ // Act: Clone the object graph
321+ var clonedRoot = root . Clone ( ) ;
322+
323+ // Cancel edit on the clone - this should restore the original value
324+ clonedRoot . CancelEdit ( ) ;
325+
326+ // Assert: The cloned child should revert to original value
327+ Assert . AreEqual ( "original" , clonedRoot . Children [ 0 ] . Data , "CancelEdit on clone should restore original value" ) ;
328+ Assert . AreEqual ( 0 , ( ( Core . IUndoableObject ) clonedRoot ) . EditLevel , "Root EditLevel should be 0 after CancelEdit" ) ;
329+ }
330+
331+ [ TestMethod ]
332+ public void ClonePreservesUndoStateForApplyEdit ( )
333+ {
334+ // Arrange: Create a root with children and begin editing
335+ var root = CreateRoot ( ) ;
336+ var child = root . Children . AddNew ( ) ;
337+ child . Data = "original" ;
338+
339+ root . BeginEdit ( ) ;
340+
341+ // Make changes after BeginEdit
342+ child . Data = "modified" ;
343+
344+ // Act: Clone the object graph
345+ var clonedRoot = root . Clone ( ) ;
346+
347+ // Apply edit on the clone
348+ clonedRoot . ApplyEdit ( ) ;
349+
350+ // Assert: The cloned child should keep the modified value
351+ Assert . AreEqual ( "modified" , clonedRoot . Children [ 0 ] . Data , "ApplyEdit on clone should keep modified value" ) ;
352+ Assert . AreEqual ( 0 , ( ( Core . IUndoableObject ) clonedRoot ) . EditLevel , "Root EditLevel should be 0 after ApplyEdit" ) ;
353+
354+ // Should be able to save without errors
355+ Assert . IsTrue ( clonedRoot . IsDirty , "Clone should be dirty" ) ;
356+ clonedRoot = clonedRoot . Save ( ) ;
357+ Assert . IsFalse ( clonedRoot . IsDirty , "Clone should not be dirty after save" ) ;
358+ }
359+
360+ [ TestMethod ]
361+ public void ClonePreservesMultiLevelUndo ( )
362+ {
363+ // Arrange: Create a root with children
364+ var root = CreateRoot ( ) ;
365+ var child = root . Children . AddNew ( ) ;
366+ child . Data = "level0" ;
367+
368+ // First level of editing
369+ root . BeginEdit ( ) ;
370+ child . Data = "level1" ;
371+
372+ // Second level of editing
373+ root . BeginEdit ( ) ;
374+ child . Data = "level2" ;
375+
376+ // Verify edit level is 2 before clone
377+ Assert . AreEqual ( 2 , ( ( Core . IUndoableObject ) root ) . EditLevel , "Root EditLevel should be 2" ) ;
378+ Assert . AreEqual ( 2 , ( ( Core . IUndoableObject ) child ) . EditLevel , "Child EditLevel should be 2" ) ;
379+
380+ // Act: Clone the object graph
381+ var clonedRoot = root . Clone ( ) ;
382+ var clonedChild = clonedRoot . Children [ 0 ] ;
383+
384+ // Assert: Edit levels preserved
385+ Assert . AreEqual ( 2 , ( ( Core . IUndoableObject ) clonedRoot ) . EditLevel , "Cloned Root EditLevel should be 2" ) ;
386+ Assert . AreEqual ( 2 , ( ( Core . IUndoableObject ) clonedChild ) . EditLevel , "Cloned Child EditLevel should be 2" ) ;
387+
388+ // Verify multi-level undo works
389+ Assert . AreEqual ( "level2" , clonedChild . Data , "Should be at level2" ) ;
390+
391+ clonedRoot . CancelEdit ( ) ;
392+ Assert . AreEqual ( "level1" , clonedChild . Data , "After first CancelEdit should be at level1" ) ;
393+ Assert . AreEqual ( 1 , ( ( Core . IUndoableObject ) clonedRoot ) . EditLevel , "EditLevel should be 1" ) ;
394+
395+ clonedRoot . CancelEdit ( ) ;
396+ Assert . AreEqual ( "level0" , clonedChild . Data , "After second CancelEdit should be at level0" ) ;
397+ Assert . AreEqual ( 0 , ( ( Core . IUndoableObject ) clonedRoot ) . EditLevel , "EditLevel should be 0" ) ;
398+ }
399+
400+ [ TestMethod ]
401+ public void ClonePreservesChildAddedDuringEdit ( )
402+ {
403+ // Arrange: Create a root and begin editing before adding child
404+ var root = CreateRoot ( ) ;
405+
406+ root . BeginEdit ( ) ;
407+
408+ // Add child after BeginEdit - child should have EditLevelAdded = 1
409+ var child = root . Children . AddNew ( ) ;
410+ child . Data = "new child" ;
411+
412+ // Act: Clone the object graph
413+ var clonedRoot = root . Clone ( ) ;
414+
415+ // Assert: Clone should have the child
416+ Assert . AreEqual ( 1 , clonedRoot . Children . Count , "Clone should have 1 child" ) ;
417+ Assert . AreEqual ( "new child" , clonedRoot . Children [ 0 ] . Data , "Clone should have child data" ) ;
418+
419+ // Cancel edit should remove the child (it was added after BeginEdit)
420+ clonedRoot . CancelEdit ( ) ;
421+ Assert . AreEqual ( 0 , clonedRoot . Children . Count , "After CancelEdit, child added during edit should be removed" ) ;
422+ }
423+
424+ [ TestMethod ]
425+ public void ClonePreservesChildEditLevelWhenUsingBindingSource ( )
426+ {
427+ // Arrange: Create a root with children and begin editing
428+ var root = CreateRoot ( ) ;
429+ var child = root . Children . AddNew ( ) ;
430+ child . Data = "original" ;
431+
432+ ( ( System . ComponentModel . IEditableObject ) root ) . BeginEdit ( ) ;
433+ ( ( System . ComponentModel . IEditableObject ) child ) . BeginEdit ( ) ;
434+
435+ // Make changes after BeginEdit
436+ child . Data = "modified" ;
437+
438+ // Verify edit levels before clone
439+ var rootEditLevel = ( ( Core . IUndoableObject ) root ) . EditLevel ;
440+ var childEditLevel = ( ( Core . IUndoableObject ) child ) . EditLevel ;
441+ var childListEditLevel = ( ( Core . IUndoableObject ) root . Children ) . EditLevel ;
442+
443+ Assert . AreEqual ( 1 , rootEditLevel , "Root EditLevel should be 1 before clone" ) ;
444+ Assert . AreEqual ( 1 , childEditLevel , "Child EditLevel should be 1 before clone" ) ;
445+ Assert . AreEqual ( 0 , childListEditLevel , "ChildList EditLevel should be 0 before clone" ) ;
446+
447+ // Act: Clone the object graph
448+ var clonedRoot = root . Clone ( ) ;
449+
450+ // Assert: Verify edit levels are preserved after clone
451+ var clonedRootEditLevel = ( ( Core . IUndoableObject ) clonedRoot ) . EditLevel ;
452+ var clonedChildEditLevel = ( ( Core . IUndoableObject ) clonedRoot . Children [ 0 ] ) . EditLevel ;
453+ var clonedChildListEditLevel = ( ( Core . IUndoableObject ) clonedRoot . Children ) . EditLevel ;
454+
455+ Assert . AreEqual ( 1 , clonedRootEditLevel , "Cloned Root EditLevel should be 1" ) ;
456+ Assert . AreEqual ( 1 , clonedChildEditLevel , "Cloned Child EditLevel should be 1" ) ;
457+ Assert . AreEqual ( 0 , clonedChildListEditLevel , "Cloned ChildList EditLevel should be 0" ) ;
458+
459+ // Verify the modified data is preserved
460+ Assert . AreEqual ( "modified" , clonedRoot . Children [ 0 ] . Data , "Modified data should be preserved in clone" ) ;
461+ }
462+
269463 private Root CreateRoot ( )
270464 {
271465 IDataPortal < Root > dataPortal = _testDIContext . CreateDataPortal < Root > ( ) ;
0 commit comments