/** * The examples provided by Facebook are for non-commercial testing and * evaluation purposes only. * * Facebook reserves all rights not expressly granted. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #import #import #import #import "RCTEventDispatcher.h" @interface RCTTestEvent : NSObject @property (atomic, assign, readwrite) BOOL canCoalesce; @end @implementation RCTTestEvent { NSDictionary *_body; } @synthesize viewTag = _viewTag; @synthesize eventName = _eventName; - (instancetype)initWithViewTag:(NSNumber *)viewTag eventName:(NSString *)eventName body:(NSDictionary *)body { if (self = [super init]) { _viewTag = viewTag; _eventName = eventName; _body = body; _canCoalesce = YES; } return self; } - (id)coalesceWithEvent:(id)newEvent { return newEvent; } + (NSString *)moduleDotMethod { return @"RCTDeviceEventEmitter.emit"; } - (NSArray *)arguments { return @[_eventName, _body]; } @end @interface RCTEventDispatcherTests : XCTestCase @end @implementation RCTEventDispatcherTests { id _bridge; RCTEventDispatcher *_eventDispatcher; NSString *_eventName; NSDictionary *_body; RCTTestEvent *_testEvent; NSString *_JSMethod; } - (void)setUp { [super setUp]; _bridge = [OCMockObject mockForClass:[RCTBridge class]]; _eventDispatcher = [RCTEventDispatcher new]; [_eventDispatcher setValue:_bridge forKey:@"bridge"]; _eventName = RCTNormalizeInputEventName(@"sampleEvent"); _body = @{ @"foo": @"bar" }; _testEvent = [[RCTTestEvent alloc] initWithViewTag:nil eventName:_eventName body:_body]; _JSMethod = [[_testEvent class] moduleDotMethod]; } - (void)testLegacyEventsAreImmediatelyDispatched { [[_bridge expect] enqueueJSCall:_JSMethod args:[_testEvent arguments]]; [_eventDispatcher sendDeviceEventWithName:_eventName body:_body]; [_bridge verify]; } - (void)testNonCoalescingEventsAreImmediatelyDispatched { _testEvent.canCoalesce = NO; [[_bridge expect] enqueueJSCall:_JSMethod args:[_testEvent arguments]]; [_eventDispatcher sendEvent:_testEvent]; [_bridge verify]; } - (void)testCoalescedEventShouldBeDispatchedOnFrameUpdate { [_eventDispatcher sendEvent:_testEvent]; [_bridge verify]; [[_bridge expect] enqueueJSCall:@"RCTDeviceEventEmitter.emit" args:[_testEvent arguments]]; [(id)_eventDispatcher didUpdateFrame:nil]; [_bridge verify]; } - (void)testNonCoalescingEventForcesColescedEventsToBeImmediatelyDispatched { RCTTestEvent *nonCoalescingEvent = [[RCTTestEvent alloc] initWithViewTag:nil eventName:_eventName body:@{}]; nonCoalescingEvent.canCoalesce = NO; [_eventDispatcher sendEvent:_testEvent]; [[_bridge expect] enqueueJSCall:[[_testEvent class] moduleDotMethod] args:[_testEvent arguments]]; [[_bridge expect] enqueueJSCall:[[nonCoalescingEvent class] moduleDotMethod] args:[nonCoalescingEvent arguments]]; [_eventDispatcher sendEvent:nonCoalescingEvent]; [_bridge verify]; } - (void)testBasicCoalescingReturnsLastEvent { RCTTestEvent *ignoredEvent = [[RCTTestEvent alloc] initWithViewTag:nil eventName:_eventName body:@{ @"other": @"body" }]; [_eventDispatcher sendEvent:ignoredEvent]; [_eventDispatcher sendEvent:_testEvent]; [[_bridge expect] enqueueJSCall:@"RCTDeviceEventEmitter.emit" args:[_testEvent arguments]]; [(id)_eventDispatcher didUpdateFrame:nil]; [_bridge verify]; } - (void)testDifferentEventTypesDontCoalesce { NSString *firstEventName = RCTNormalizeInputEventName(@"firstEvent"); RCTTestEvent *firstEvent = [[RCTTestEvent alloc] initWithViewTag:nil eventName:firstEventName body:_body]; [_eventDispatcher sendEvent:firstEvent]; [_eventDispatcher sendEvent:_testEvent]; [[_bridge expect] enqueueJSCall:@"RCTDeviceEventEmitter.emit" args:[firstEvent arguments]]; [[_bridge expect] enqueueJSCall:@"RCTDeviceEventEmitter.emit" args:[_testEvent arguments]]; [(id)_eventDispatcher didUpdateFrame:nil]; [_bridge verify]; } @end