@@ -14,12 +14,151 @@ import '@react-native/fantom/src/setUpDefaultReactNativeEnvironment';
1414import * as Fantom from '@react-native/fantom' ;
1515import nullthrows from 'nullthrows' ;
1616import * as React from 'react' ;
17- import { View } from 'react-native' ;
17+ import { type PointerEvent , View } from 'react-native' ;
1818import * as FabricUIManager from 'react-native/Libraries/ReactNative/FabricUIManager' ;
1919
2020const UIManager = nullthrows ( FabricUIManager . getFabricUIManager ( ) ) ;
2121
2222describe ( 'Event Dispatching' , ( ) => {
23+ // The OSS renderer hasn't been synced yet to have these changes
24+ // TODO(next-major) Remove this condition
25+ if ( ! Fantom . getConstants ( ) . isOSS ) {
26+ it ( 'provides the native event timeStamp (camel case) when available' , ( ) => {
27+ const root = Fantom . createRoot ( ) ;
28+
29+ const ref = React . createRef < React . ElementRef < typeof View >> ( ) ;
30+
31+ const onPointerUp = jest . fn ( ( e : PointerEvent ) => {
32+ e . persist ( ) ;
33+ } ) ;
34+
35+ Fantom . runTask ( ( ) => {
36+ root . render ( < View ref = { ref } onPointerUp = { onPointerUp } /> ) ;
37+ } ) ;
38+
39+ expect ( onPointerUp ) . toHaveBeenCalledTimes ( 0 ) ;
40+
41+ const NATIVE_EVENT_TIMESTAMP = 1234 ;
42+
43+ Fantom . dispatchNativeEvent (
44+ ref ,
45+ 'onPointerUp' ,
46+ { x : 0 , y : 0 , timeStamp : NATIVE_EVENT_TIMESTAMP } ,
47+ {
48+ category : Fantom . NativeEventCategory . Discrete ,
49+ } ,
50+ ) ;
51+
52+ expect ( onPointerUp ) . toHaveBeenCalledTimes ( 1 ) ;
53+ expect ( onPointerUp . mock . calls [ 0 ] [ 0 ] . timeStamp ) . toBe (
54+ NATIVE_EVENT_TIMESTAMP ,
55+ ) ;
56+ } ) ;
57+
58+ it ( 'provides the native event timestamp (lower case) when available' , ( ) => {
59+ const root = Fantom . createRoot ( ) ;
60+
61+ const ref = React . createRef < React . ElementRef < typeof View >> ( ) ;
62+
63+ const onPointerUp = jest . fn ( ( e : PointerEvent ) => {
64+ e . persist ( ) ;
65+ } ) ;
66+
67+ Fantom . runTask ( ( ) => {
68+ root . render ( < View ref = { ref } onPointerUp = { onPointerUp } /> ) ;
69+ } ) ;
70+
71+ expect ( onPointerUp ) . toHaveBeenCalledTimes ( 0 ) ;
72+
73+ const NATIVE_EVENT_TIMESTAMP = 1234 ;
74+
75+ Fantom . dispatchNativeEvent (
76+ ref ,
77+ 'onPointerUp' ,
78+ { x : 0 , y : 0 , timestamp : NATIVE_EVENT_TIMESTAMP } ,
79+ {
80+ category : Fantom . NativeEventCategory . Discrete ,
81+ } ,
82+ ) ;
83+
84+ expect ( onPointerUp ) . toHaveBeenCalledTimes ( 1 ) ;
85+ expect ( onPointerUp . mock . calls [ 0 ] [ 0 ] . timeStamp ) . toBe (
86+ NATIVE_EVENT_TIMESTAMP ,
87+ ) ;
88+ } ) ;
89+
90+ it ( 'provides a default timeStamp when the native event timeStamp is NOT available' , ( ) => {
91+ const root = Fantom . createRoot ( ) ;
92+
93+ const ref = React . createRef < React . ElementRef < typeof View >> ( ) ;
94+
95+ const onPointerUp = jest . fn ( ( e : PointerEvent ) => {
96+ e . persist ( ) ;
97+ } ) ;
98+
99+ Fantom . runTask ( ( ) => {
100+ root . render ( < View ref = { ref } onPointerUp = { onPointerUp } /> ) ;
101+ } ) ;
102+
103+ expect ( onPointerUp ) . toHaveBeenCalledTimes ( 0 ) ;
104+
105+ const lowerBound = performance . now ( ) ;
106+
107+ Fantom . dispatchNativeEvent (
108+ ref ,
109+ 'onPointerUp' ,
110+ { x : 0 , y : 0 } ,
111+ {
112+ category : Fantom . NativeEventCategory . Discrete ,
113+ } ,
114+ ) ;
115+
116+ const upperBound = performance . now ( ) ;
117+
118+ expect ( onPointerUp ) . toHaveBeenCalledTimes ( 1 ) ;
119+ expect ( onPointerUp . mock . calls [ 0 ] [ 0 ] . timeStamp ) . toBeGreaterThanOrEqual (
120+ lowerBound ,
121+ ) ;
122+ expect ( onPointerUp . mock . calls [ 0 ] [ 0 ] . timeStamp ) . toBeLessThanOrEqual (
123+ upperBound ,
124+ ) ;
125+ } ) ;
126+
127+ it ( 'exposes dispatched events in the global scope' , ( ) => {
128+ const root = Fantom . createRoot ( ) ;
129+
130+ const ref = React . createRef < React . ElementRef < typeof View >> ( ) ;
131+
132+ let globalEventIsDispatchedEvent : boolean = false ;
133+
134+ const onPointerUp = jest . fn ( ( e : PointerEvent ) => {
135+ globalEventIsDispatchedEvent = global . event === e ;
136+ } ) ;
137+
138+ Fantom . runTask ( ( ) => {
139+ root . render ( < View ref = { ref } onPointerUp = { onPointerUp } /> ) ;
140+ } ) ;
141+
142+ const globalEventValueBeforeDispatch = { type : 'some-event' } ;
143+ global . event = globalEventValueBeforeDispatch ;
144+
145+ expect ( onPointerUp ) . toHaveBeenCalledTimes ( 0 ) ;
146+
147+ Fantom . dispatchNativeEvent (
148+ ref ,
149+ 'onPointerUp' ,
150+ { x : 0 , y : 0 } ,
151+ {
152+ category : Fantom . NativeEventCategory . Discrete ,
153+ } ,
154+ ) ;
155+
156+ expect ( onPointerUp ) . toHaveBeenCalledTimes ( 1 ) ;
157+ expect ( globalEventIsDispatchedEvent ) . toBe ( true ) ;
158+ expect ( global . event ) . toBe ( globalEventValueBeforeDispatch ) ;
159+ } ) ;
160+ }
161+
23162 it ( 'dispatches events with discrete priority' , ( ) => {
24163 const root = Fantom . createRoot ( ) ;
25164
0 commit comments