@@ -578,3 +578,155 @@ fn cancel_emitted_events_on_capture() {
578578 // Assert that the node is not being hovvered as the event was can cancelled
579579 assert ! ( !nodes_state. is_hovered( 0 ) ) ;
580580}
581+
582+ #[ test]
583+ fn touch_released_event ( ) {
584+ let mut test_measurer = TestMeasurer :: default ( ) ;
585+ let mut nodes_state = NodesState :: default ( ) ;
586+
587+ test_measurer. add ( 0 , None , 0 , Area :: new ( ( 0. , 0. ) . into ( ) , ( 100. , 100. ) . into ( ) ) ) ;
588+ test_measurer. listen_to ( 0 , EventName :: TouchReleased ) ;
589+
590+ let processed_events = test_measurer. run (
591+ & mut vec ! [ TestSourceEvent :: TouchReleased {
592+ cursor: ( 25. , 25. ) . into( ) ,
593+ } ] ,
594+ & mut nodes_state,
595+ None ,
596+ ) ;
597+
598+ // Assert a TouchReleased event is emitted when touch is released inside the node
599+ assert_eq ! (
600+ processed_events. emmitable_events. first( ) ,
601+ Some ( & TestEmmitableEvent {
602+ key: 0 ,
603+ name: EventName :: TouchReleased ,
604+ source: EventName :: TouchReleased
605+ } )
606+ ) ;
607+ // Apply the processed events
608+ TestExecutor :: without_handler ( ) . run ( & mut nodes_state, processed_events) ;
609+ }
610+
611+ #[ test]
612+ fn touch_released_outside_node ( ) {
613+ let mut test_measurer = TestMeasurer :: default ( ) ;
614+ let mut nodes_state = NodesState :: default ( ) ;
615+
616+ test_measurer. add ( 0 , None , 0 , Area :: new ( ( 0. , 0. ) . into ( ) , ( 100. , 100. ) . into ( ) ) ) ;
617+ test_measurer. listen_to ( 0 , EventName :: TouchReleased ) ;
618+
619+ let processed_events = test_measurer. run (
620+ & mut vec ! [ TestSourceEvent :: TouchReleased {
621+ cursor: ( 600. , 700. ) . into( ) ,
622+ } ] ,
623+ & mut nodes_state,
624+ None ,
625+ ) ;
626+
627+ // Assert no event is emitted when touch is released outside the node
628+ assert ! ( processed_events. emmitable_events. is_empty( ) ) ;
629+ // Apply the processed events
630+ TestExecutor :: without_handler ( ) . run ( & mut nodes_state, processed_events) ;
631+ }
632+
633+ #[ test]
634+ fn touch_released_without_listener ( ) {
635+ let mut test_measurer = TestMeasurer :: default ( ) ;
636+ let mut nodes_state = NodesState :: default ( ) ;
637+
638+ test_measurer. add ( 0 , None , 0 , Area :: new ( ( 0. , 0. ) . into ( ) , ( 100. , 100. ) . into ( ) ) ) ;
639+ // No listener registered for TouchReleased
640+
641+ let processed_events = test_measurer. run (
642+ & mut vec ! [ TestSourceEvent :: TouchReleased {
643+ cursor: ( 25. , 25. ) . into( ) ,
644+ } ] ,
645+ & mut nodes_state,
646+ None ,
647+ ) ;
648+
649+ // Assert no event is emitted without a listener
650+ assert ! ( processed_events. emmitable_events. is_empty( ) ) ;
651+ // Apply the processed events
652+ TestExecutor :: without_handler ( ) . run ( & mut nodes_state, processed_events) ;
653+ }
654+
655+ #[ test]
656+ fn touch_released_after_mouse_down ( ) {
657+ let mut test_measurer = TestMeasurer :: default ( ) ;
658+ let mut nodes_state = NodesState :: default ( ) ;
659+
660+ test_measurer. add ( 0 , None , 0 , Area :: new ( ( 0. , 0. ) . into ( ) , ( 100. , 100. ) . into ( ) ) ) ;
661+ test_measurer. listen_to ( 0 , EventName :: MouseDown ) ;
662+ test_measurer. listen_to ( 0 , EventName :: TouchReleased ) ;
663+
664+ // First press down on the node
665+ let processed_events = test_measurer. run (
666+ & mut vec ! [ TestSourceEvent :: MouseDown {
667+ cursor: ( 25. , 25. ) . into( ) ,
668+ } ] ,
669+ & mut nodes_state,
670+ None ,
671+ ) ;
672+ TestExecutor :: without_handler ( ) . run ( & mut nodes_state, processed_events) ;
673+ assert ! ( nodes_state. is_pressed( 0 ) ) ;
674+
675+ // Then release via touch
676+ let processed_events = test_measurer. run (
677+ & mut vec ! [ TestSourceEvent :: TouchReleased {
678+ cursor: ( 25. , 25. ) . into( ) ,
679+ } ] ,
680+ & mut nodes_state,
681+ None ,
682+ ) ;
683+
684+ assert_eq ! (
685+ processed_events. emmitable_events. first( ) ,
686+ Some ( & TestEmmitableEvent {
687+ key: 0 ,
688+ name: EventName :: TouchReleased ,
689+ source: EventName :: TouchReleased
690+ } )
691+ ) ;
692+ TestExecutor :: without_handler ( ) . run ( & mut nodes_state, processed_events) ;
693+ }
694+
695+ #[ test]
696+ fn touch_released_multiple_nodes ( ) {
697+ let mut test_measurer = TestMeasurer :: default ( ) ;
698+ let mut nodes_state = NodesState :: default ( ) ;
699+
700+ // Two non-overlapping nodes
701+ test_measurer. add ( 0 , None , 0 , Area :: new ( ( 0. , 0. ) . into ( ) , ( 100. , 100. ) . into ( ) ) ) ;
702+ test_measurer. listen_to ( 0 , EventName :: TouchReleased ) ;
703+
704+ test_measurer. add (
705+ 1 ,
706+ None ,
707+ 0 ,
708+ Area :: new ( ( 200. , 200. ) . into ( ) , ( 100. , 100. ) . into ( ) ) ,
709+ ) ;
710+ test_measurer. listen_to ( 1 , EventName :: TouchReleased ) ;
711+
712+ // Touch released inside node 1 only
713+ let processed_events = test_measurer. run (
714+ & mut vec ! [ TestSourceEvent :: TouchReleased {
715+ cursor: ( 250. , 250. ) . into( ) ,
716+ } ] ,
717+ & mut nodes_state,
718+ None ,
719+ ) ;
720+
721+ // Only node 1 should receive the event
722+ assert_eq ! ( processed_events. emmitable_events. len( ) , 1 ) ;
723+ assert_eq ! (
724+ processed_events. emmitable_events. first( ) ,
725+ Some ( & TestEmmitableEvent {
726+ key: 1 ,
727+ name: EventName :: TouchReleased ,
728+ source: EventName :: TouchReleased
729+ } )
730+ ) ;
731+ TestExecutor :: without_handler ( ) . run ( & mut nodes_state, processed_events) ;
732+ }
0 commit comments