@@ -537,3 +537,61 @@ fn test_var_with_renamed_funcs() {
537
537
538
538
obj. free ( ) ;
539
539
}
540
+
541
+ // ----------------------------------------------------------------------------------------------------------------------------------------------
542
+
543
+ #[ derive( GodotClass ) ]
544
+ #[ class( init, base=Node ) ]
545
+ struct Duplicator {
546
+ // #[export] would also make tests pass, but #[export(storage)] additionally hides the properties from the editor.
547
+ // See https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_exports.html#export-storage.
548
+ #[ export( storage) ]
549
+ int_export : i32 ,
550
+
551
+ // Low-level #[var] should also work.
552
+ #[ var( usage_flags = [ STORAGE ] ) ]
553
+ int_var : i32 ,
554
+
555
+ // Not copied because not marked as serialize ("storage").
556
+ #[ var]
557
+ int_ignored : i32 ,
558
+
559
+ #[ export( storage) ]
560
+ optional_node : Option < Gd < Node > > ,
561
+
562
+ #[ export( storage) ]
563
+ oneditor_node : OnEditor < Gd < Node > > ,
564
+ }
565
+
566
+ #[ itest]
567
+ fn test_duplicate_retains_properties ( ) {
568
+ let optional_node = Node :: new_alloc ( ) ;
569
+ let oneditor_node = Node :: new_alloc ( ) ;
570
+
571
+ // Set up original node.
572
+ let mut original = Duplicator :: new_alloc ( ) ;
573
+ {
574
+ let mut original = original. bind_mut ( ) ;
575
+ original. int_export = 5 ;
576
+ original. int_var = 7 ;
577
+ original. int_ignored = 9 ; // Will not be copied.
578
+ original. optional_node = Some ( optional_node. clone ( ) ) ;
579
+ original. oneditor_node . init ( oneditor_node. clone ( ) ) ;
580
+ }
581
+
582
+ // Create duplicate and verify all properties are copied correctly.
583
+ let duplicated: Gd < Duplicator > = original. duplicate ( ) . unwrap ( ) . cast ( ) ;
584
+ {
585
+ let duplicated = duplicated. bind ( ) ;
586
+ assert_eq ! ( duplicated. int_export, 5 ) ;
587
+ assert_eq ! ( duplicated. int_var, 7 ) ;
588
+ assert_eq ! ( duplicated. int_ignored, 0 ) ; // Not copied.
589
+ assert_eq ! ( duplicated. optional_node. as_ref( ) . unwrap( ) , & optional_node) ;
590
+ assert_eq ! ( & * duplicated. oneditor_node, & oneditor_node) ;
591
+ }
592
+
593
+ optional_node. free ( ) ;
594
+ oneditor_node. free ( ) ;
595
+ duplicated. free ( ) ;
596
+ original. free ( ) ;
597
+ }
0 commit comments